1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../../include/fxge/fx_ge.h"
8 #include "../../../include/fxcodec/fx_codec.h"
9 #include "dib_int.h"
10 const FX_BYTE g_GammaRamp[256] = {
11 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
12 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
13 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
14 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13,
15 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20,
16 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
17 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41,
18 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54,
19 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
20 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88,
21 90, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109,
22 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133,
23 134, 136, 138, 139, 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159,
24 161, 163, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 184, 186, 188,
25 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220,
26 222, 224, 226, 229, 231, 233, 235, 237, 239, 242, 244, 246, 248, 250, 253, 255,
27 };
28 const FX_BYTE g_GammaInverse[256] = {
29 0, 13, 22, 28, 34, 38, 42, 46, 50, 53, 56, 59, 61, 64, 66, 69,
30 71, 73, 75, 77, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 96, 98,
31 99, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 115, 117, 118, 119,
32 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
33 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151,
34 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
35 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
36 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
37 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
38 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
39 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
40 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
41 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
42 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
43 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
44 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
45 };
46 const FX_BYTE _color_sqrt[256] = {
47 0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26, 0x29, 0x2C, 0x2F, 0x32,
48 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56,
49 0x57, 0x59, 0x5B, 0x5C, 0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
50 0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
51 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
52 0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
53 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8,
54 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4,
55 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
56 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9,
57 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3,
58 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD,
59 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6,
60 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE,
61 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
62 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
63 };
_BLEND(int blend_mode,int back_color,int src_color)64 int _BLEND(int blend_mode, int back_color, int src_color)
65 {
66 switch (blend_mode) {
67 case FXDIB_BLEND_NORMAL:
68 return src_color;
69 case FXDIB_BLEND_MULTIPLY:
70 return src_color * back_color / 255;
71 case FXDIB_BLEND_SCREEN:
72 return src_color + back_color - src_color * back_color / 255;
73 case FXDIB_BLEND_OVERLAY:
74 return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color);
75 case FXDIB_BLEND_DARKEN:
76 return src_color < back_color ? src_color : back_color;
77 case FXDIB_BLEND_LIGHTEN:
78 return src_color > back_color ? src_color : back_color;
79 case FXDIB_BLEND_COLORDODGE: {
80 if (src_color == 255) {
81 return src_color;
82 }
83 int result = back_color * 255 / (255 - src_color);
84 if (result > 255) {
85 return 255;
86 }
87 return result;
88 }
89 case FXDIB_BLEND_COLORBURN: {
90 if (src_color == 0) {
91 return src_color;
92 }
93 int result = (255 - back_color) * 255 / src_color;
94 if (result > 255) {
95 result = 255;
96 }
97 return 255 - result;
98 }
99 case FXDIB_BLEND_HARDLIGHT:
100 if (src_color < 128) {
101 return (src_color * back_color * 2) / 255;
102 }
103 return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255);
104 case FXDIB_BLEND_SOFTLIGHT: {
105 if (src_color < 128) {
106 return back_color - (255 - 2 * src_color) * back_color * (255 - back_color) / 255 / 255;
107 }
108 return back_color + (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) / 255;
109 }
110 case FXDIB_BLEND_DIFFERENCE:
111 return back_color < src_color ? src_color - back_color : back_color - src_color;
112 case FXDIB_BLEND_EXCLUSION:
113 return back_color + src_color - 2 * back_color * src_color / 255;
114 }
115 return src_color;
116 }
117 struct _RGB {
118 int red;
119 int green;
120 int blue;
121 };
_Lum(_RGB color)122 static inline int _Lum(_RGB color)
123 {
124 return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
125 }
_ClipColor(_RGB color)126 static _RGB _ClipColor(_RGB color)
127 {
128 int l = _Lum(color);
129 int n = color.red;
130 if (color.green < n) {
131 n = color.green;
132 }
133 if (color.blue < n) {
134 n = color.blue;
135 }
136 int x = color.red;
137 if (color.green > x) {
138 x = color.green;
139 }
140 if (color.blue > x) {
141 x = color.blue;
142 }
143 if (n < 0) {
144 color.red = l + ((color.red - l) * l / (l - n));
145 color.green = l + ((color.green - l) * l / (l - n));
146 color.blue = l + ((color.blue - l) * l / (l - n));
147 }
148 if (x > 255) {
149 color.red = l + ((color.red - l) * (255 - l) / (x - l));
150 color.green = l + ((color.green - l) * (255 - l) / (x - l));
151 color.blue = l + ((color.blue - l) * (255 - l) / (x - l));
152 }
153 return color;
154 }
_SetLum(_RGB color,int l)155 static _RGB _SetLum(_RGB color, int l)
156 {
157 int d = l - _Lum(color);
158 color.red += d;
159 color.green += d;
160 color.blue += d;
161 return _ClipColor(color);
162 }
_Sat(_RGB color)163 static int _Sat(_RGB color)
164 {
165 int n = color.red;
166 if (color.green < n) {
167 n = color.green;
168 }
169 if (color.blue < n) {
170 n = color.blue;
171 }
172 int x = color.red;
173 if (color.green > x) {
174 x = color.green;
175 }
176 if (color.blue > x) {
177 x = color.blue;
178 }
179 return x - n;
180 }
_SetSat(_RGB color,int s)181 static _RGB _SetSat(_RGB color, int s)
182 {
183 int* max = &color.red;
184 int* mid = &color.red;
185 int* min = &color.red;
186 if (color.green > *max) {
187 max = &color.green;
188 }
189 if (color.blue > *max) {
190 max = &color.blue;
191 }
192 if (color.green < *min) {
193 min = &color.green;
194 }
195 if (color.blue < *min) {
196 min = &color.blue;
197 }
198 if (*max == *min) {
199 color.red = 0;
200 color.green = 0;
201 color.blue = 0;
202 return color;
203 }
204 if (max == &color.red) {
205 if (min == &color.green) {
206 mid = &color.blue;
207 } else {
208 mid = &color.green;
209 }
210 } else if (max == &color.green) {
211 if (min == &color.red) {
212 mid = &color.blue;
213 } else {
214 mid = &color.red;
215 }
216 } else {
217 if (min == &color.green) {
218 mid = &color.red;
219 } else {
220 mid = &color.green;
221 }
222 }
223 if (*max > *min) {
224 *mid = (*mid - *min) * s / (*max - *min);
225 *max = s;
226 *min = 0;
227 }
228 return color;
229 }
_RGB_Blend(int blend_mode,FX_LPCBYTE src_scan,FX_BYTE * dest_scan,int results[3])230 void _RGB_Blend(int blend_mode, FX_LPCBYTE src_scan, FX_BYTE* dest_scan, int results[3])
231 {
232 _RGB src, back, result;
233 src.red = src_scan[2];
234 src.green = src_scan[1];
235 src.blue = src_scan[0];
236 back.red = dest_scan[2];
237 back.green = dest_scan[1];
238 back.blue = dest_scan[0];
239 switch (blend_mode) {
240 case FXDIB_BLEND_HUE:
241 result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back));
242 break;
243 case FXDIB_BLEND_SATURATION:
244 result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back));
245 break;
246 case FXDIB_BLEND_COLOR:
247 result = _SetLum(src, _Lum(back));
248 break;
249 case FXDIB_BLEND_LUMINOSITY:
250 result = _SetLum(back, _Lum(src));
251 break;
252 }
253 results[0] = result.blue;
254 results[1] = result.green;
255 results[2] = result.red;
256 }
_CompositeRow_Argb2Mask(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int pixel_count,FX_LPCBYTE clip_scan)257 inline void _CompositeRow_Argb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, FX_LPCBYTE clip_scan)
258 {
259 src_scan += 3;
260 for (int col = 0; col < pixel_count; col ++) {
261 int src_alpha = *src_scan;
262 if (clip_scan) {
263 src_alpha = clip_scan[col] * src_alpha / 255;
264 }
265 FX_BYTE back_alpha = *dest_scan;
266 if (!back_alpha) {
267 *dest_scan = src_alpha;
268 } else if (src_alpha) {
269 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
270 }
271 dest_scan ++;
272 src_scan += 4;
273 }
274 }
_CompositeRow_Rgba2Mask(FX_LPBYTE dest_scan,FX_LPCBYTE src_alpha_scan,int pixel_count,FX_LPCBYTE clip_scan)275 void _CompositeRow_Rgba2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_alpha_scan, int pixel_count, FX_LPCBYTE clip_scan)
276 {
277 for (int col = 0; col < pixel_count; col ++) {
278 int src_alpha = *src_alpha_scan++;
279 if (clip_scan) {
280 src_alpha = clip_scan[col] * src_alpha / 255;
281 }
282 FX_BYTE back_alpha = *dest_scan;
283 if (!back_alpha) {
284 *dest_scan = src_alpha;
285 } else if (src_alpha) {
286 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
287 }
288 dest_scan ++;
289 }
290 }
_CompositeRow_Rgb2Mask(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,FX_LPCBYTE clip_scan)291 void _CompositeRow_Rgb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan)
292 {
293 if (clip_scan) {
294 for (int i = 0; i < width; i ++) {
295 *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan);
296 dest_scan ++;
297 clip_scan ++;
298 }
299 } else {
300 FXSYS_memset8(dest_scan, 0xff, width);
301 }
302 }
_CompositeRow_Argb2Graya(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan,FX_LPBYTE dst_alpha_scan,void * pIccTransform)303 void _CompositeRow_Argb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
304 FX_LPCBYTE src_alpha_scan, FX_LPBYTE dst_alpha_scan, void* pIccTransform)
305 {
306 ICodec_IccModule* pIccModule = NULL;
307 if (pIccTransform) {
308 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
309 }
310 if (blend_type) {
311 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
312 int blended_color;
313 if (src_alpha_scan) {
314 for (int col = 0; col < pixel_count; col ++) {
315 FX_BYTE back_alpha = *dst_alpha_scan;
316 if (back_alpha == 0) {
317 int src_alpha = *src_alpha_scan++;
318 if (clip_scan) {
319 src_alpha = clip_scan[col] * src_alpha / 255;
320 }
321 if (src_alpha) {
322 if (pIccTransform) {
323 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
324 } else {
325 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
326 }
327 *dst_alpha_scan = src_alpha;
328 }
329 dest_scan ++;
330 dst_alpha_scan ++;
331 src_scan += 3;
332 continue;
333 }
334 FX_BYTE src_alpha = *src_alpha_scan++;
335 if (clip_scan) {
336 src_alpha = clip_scan[col] * src_alpha / 255;
337 }
338 if (src_alpha == 0) {
339 dest_scan ++;
340 dst_alpha_scan ++;
341 src_scan += 3;
342 continue;
343 }
344 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
345 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
346 FX_BYTE gray;
347 if (pIccTransform) {
348 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
349 } else {
350 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
351 }
352 if (bNonseparableBlend) {
353 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
354 }
355 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
356 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
357 dest_scan ++;
358 dst_alpha_scan++;
359 src_scan += 3;
360 }
361 } else
362 for (int col = 0; col < pixel_count; col ++) {
363 FX_BYTE back_alpha = *dst_alpha_scan;
364 if (back_alpha == 0) {
365 int src_alpha = src_scan[3];
366 if (clip_scan) {
367 src_alpha = clip_scan[col] * src_alpha / 255;
368 }
369 if (src_alpha) {
370 if (pIccTransform) {
371 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
372 } else {
373 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
374 }
375 *dst_alpha_scan = src_alpha;
376 }
377 dest_scan ++;
378 dst_alpha_scan ++;
379 src_scan += 4;
380 continue;
381 }
382 FX_BYTE src_alpha = src_scan[3];
383 if (clip_scan) {
384 src_alpha = clip_scan[col] * src_alpha / 255;
385 }
386 if (src_alpha == 0) {
387 dest_scan ++;
388 dst_alpha_scan ++;
389 src_scan += 4;
390 continue;
391 }
392 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
393 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
394 FX_BYTE gray;
395 if (pIccTransform) {
396 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
397 } else {
398 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
399 }
400 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
401 dest_scan ++;
402 dst_alpha_scan++;
403 src_scan += 4;
404 }
405 return;
406 }
407 if (src_alpha_scan) {
408 for (int col = 0; col < pixel_count; col ++) {
409 FX_BYTE back_alpha = *dst_alpha_scan;
410 if (back_alpha == 0) {
411 int src_alpha = *src_alpha_scan++;
412 if (clip_scan) {
413 src_alpha = clip_scan[col] * src_alpha / 255;
414 }
415 if (src_alpha) {
416 if (pIccTransform) {
417 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
418 } else {
419 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
420 }
421 *dst_alpha_scan = src_alpha;
422 }
423 dest_scan ++;
424 dst_alpha_scan ++;
425 src_scan += 3;
426 continue;
427 }
428 FX_BYTE src_alpha = *src_alpha_scan++;
429 if (clip_scan) {
430 src_alpha = clip_scan[col] * src_alpha / 255;
431 }
432 if (src_alpha == 0) {
433 dest_scan ++;
434 dst_alpha_scan ++;
435 src_scan += 3;
436 continue;
437 }
438 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
439 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
440 FX_BYTE gray;
441 if (pIccTransform) {
442 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
443 } else {
444 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
445 }
446 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
447 dest_scan ++;
448 dst_alpha_scan++;
449 src_scan += 3;
450 }
451 } else
452 for (int col = 0; col < pixel_count; col ++) {
453 FX_BYTE back_alpha = *dst_alpha_scan;
454 if (back_alpha == 0) {
455 int src_alpha = src_scan[3];
456 if (clip_scan) {
457 src_alpha = clip_scan[col] * src_alpha / 255;
458 }
459 if (src_alpha) {
460 if (pIccTransform) {
461 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
462 } else {
463 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
464 }
465 *dst_alpha_scan = src_alpha;
466 }
467 dest_scan ++;
468 dst_alpha_scan ++;
469 src_scan += 4;
470 continue;
471 }
472 FX_BYTE src_alpha = src_scan[3];
473 if (clip_scan) {
474 src_alpha = clip_scan[col] * src_alpha / 255;
475 }
476 if (src_alpha == 0) {
477 dest_scan ++;
478 dst_alpha_scan ++;
479 src_scan += 4;
480 continue;
481 }
482 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
483 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
484 FX_BYTE gray;
485 if (pIccTransform) {
486 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
487 } else {
488 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
489 }
490 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
491 dest_scan ++;
492 dst_alpha_scan++;
493 src_scan += 4;
494 }
495 }
_CompositeRow_Argb2Gray(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan,void * pIccTransform)496 inline void _CompositeRow_Argb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count,
497 int blend_type, FX_LPCBYTE clip_scan,
498 FX_LPCBYTE src_alpha_scan, void* pIccTransform)
499 {
500 ICodec_IccModule* pIccModule = NULL;
501 FX_BYTE gray;
502 if (pIccTransform) {
503 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
504 }
505 if (blend_type) {
506 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
507 int blended_color;
508 if (src_alpha_scan) {
509 for (int col = 0; col < pixel_count; col ++) {
510 int src_alpha = *src_alpha_scan++;
511 if (clip_scan) {
512 src_alpha = clip_scan[col] * src_alpha / 255;
513 }
514 if (src_alpha) {
515 if (pIccTransform) {
516 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
517 } else {
518 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
519 }
520 if (bNonseparableBlend) {
521 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
522 }
523 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
524 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
525 }
526 dest_scan ++;
527 src_scan += 3;
528 }
529 } else
530 for (int col = 0; col < pixel_count; col ++) {
531 int src_alpha = src_scan[3];
532 if (clip_scan) {
533 src_alpha = clip_scan[col] * src_alpha / 255;
534 }
535 if (src_alpha) {
536 if (pIccTransform) {
537 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
538 } else {
539 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
540 }
541 if (bNonseparableBlend) {
542 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
543 }
544 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
545 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
546 }
547 dest_scan ++;
548 src_scan += 4;
549 }
550 return;
551 }
552 if (src_alpha_scan) {
553 for (int col = 0; col < pixel_count; col ++) {
554 int src_alpha = *src_alpha_scan++;
555 if (clip_scan) {
556 src_alpha = clip_scan[col] * src_alpha / 255;
557 }
558 if (src_alpha) {
559 if (pIccTransform) {
560 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
561 } else {
562 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
563 }
564 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
565 }
566 dest_scan ++;
567 src_scan += 3;
568 }
569 } else
570 for (int col = 0; col < pixel_count; col ++) {
571 int src_alpha = src_scan[3];
572 if (clip_scan) {
573 src_alpha = clip_scan[col] * src_alpha / 255;
574 }
575 if (src_alpha) {
576 if (pIccTransform) {
577 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
578 } else {
579 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
580 }
581 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
582 }
583 dest_scan ++;
584 src_scan += 4;
585 }
586 }
_CompositeRow_Rgb2Gray(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_Bpp,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,void * pIccTransform)587 inline void _CompositeRow_Rgb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
588 int blend_type, FX_LPCBYTE clip_scan,
589 void* pIccTransform)
590 {
591 ICodec_IccModule* pIccModule = NULL;
592 FX_BYTE gray;
593 if (pIccTransform) {
594 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
595 }
596 if (blend_type) {
597 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
598 int blended_color;
599 for (int col = 0; col < pixel_count; col ++) {
600 if (pIccTransform) {
601 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
602 } else {
603 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
604 }
605 if (bNonseparableBlend) {
606 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
607 }
608 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
609 if (clip_scan && clip_scan[col] < 255) {
610 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
611 } else {
612 *dest_scan = gray;
613 }
614 dest_scan ++;
615 src_scan += src_Bpp;
616 }
617 return;
618 }
619 for (int col = 0; col < pixel_count; col ++) {
620 if (pIccTransform) {
621 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
622 } else {
623 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
624 }
625 if (clip_scan && clip_scan[col] < 255) {
626 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
627 } else {
628 *dest_scan = gray;
629 }
630 dest_scan ++;
631 src_scan += src_Bpp;
632 }
633 }
_CompositeRow_Rgb2Graya(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_Bpp,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan,void * pIccTransform)634 void _CompositeRow_Rgb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
635 int blend_type, FX_LPCBYTE clip_scan,
636 FX_LPBYTE dest_alpha_scan, void* pIccTransform)
637 {
638 ICodec_IccModule* pIccModule = NULL;
639 if (pIccTransform) {
640 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
641 }
642 if (blend_type) {
643 int blended_color;
644 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
645 for (int col = 0; col < pixel_count; col ++) {
646 int back_alpha = *dest_alpha_scan;
647 if (back_alpha == 0) {
648 if (pIccTransform) {
649 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
650 } else {
651 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
652 }
653 dest_scan ++;
654 dest_alpha_scan++;
655 src_scan += src_Bpp;
656 continue;
657 }
658 int src_alpha = 255;
659 if (clip_scan) {
660 src_alpha = clip_scan[col];
661 }
662 if (src_alpha == 0) {
663 dest_scan ++;
664 dest_alpha_scan ++;
665 src_scan += src_Bpp;
666 continue;
667 }
668 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
669 *dest_alpha_scan++ = dest_alpha;
670 int alpha_ratio = src_alpha * 255 / dest_alpha;
671 FX_BYTE gray;
672 if (pIccTransform) {
673 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
674 } else {
675 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
676 }
677 if (bNonseparableBlend) {
678 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
679 }
680 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
681 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
682 dest_scan ++;
683 src_scan += src_Bpp;
684 }
685 return;
686 }
687 for (int col = 0; col < pixel_count; col ++) {
688 int src_alpha = 255;
689 if (clip_scan) {
690 src_alpha = clip_scan[col];
691 }
692 if (src_alpha == 255) {
693 if (pIccTransform) {
694 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
695 } else {
696 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
697 }
698 dest_scan ++;
699 *dest_alpha_scan++ = 255;
700 src_scan += src_Bpp;
701 continue;
702 }
703 if (src_alpha == 0) {
704 dest_scan ++;
705 dest_alpha_scan ++;
706 src_scan += src_Bpp;
707 continue;
708 }
709 int back_alpha = *dest_alpha_scan;
710 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
711 *dest_alpha_scan++ = dest_alpha;
712 int alpha_ratio = src_alpha * 255 / dest_alpha;
713 FX_BYTE gray;
714 if (pIccTransform) {
715 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
716 } else {
717 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
718 }
719 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
720 dest_scan ++;
721 src_scan += src_Bpp;
722 }
723 }
_CompositeRow_Argb2Argb(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan,FX_LPCBYTE src_alpha_scan)724 void _CompositeRow_Argb2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
725 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
726 {
727 int blended_colors[3];
728 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
729 if (dest_alpha_scan == NULL) {
730 if (src_alpha_scan == NULL) {
731 FX_BYTE back_alpha = 0;
732 for (int col = 0; col < pixel_count; col ++) {
733 back_alpha = dest_scan[3];
734 if (back_alpha == 0) {
735 if (clip_scan) {
736 int src_alpha = clip_scan[col] * src_scan[3] / 255;
737 FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) | (src_alpha << 24));
738 } else {
739 FXARGB_COPY(dest_scan, src_scan);
740 }
741 dest_scan += 4;
742 src_scan += 4;
743 continue;
744 }
745 FX_BYTE src_alpha;
746 if (clip_scan == NULL) {
747 src_alpha = src_scan[3];
748 } else {
749 src_alpha = clip_scan[col] * src_scan[3] / 255;
750 }
751 if (src_alpha == 0) {
752 dest_scan += 4;
753 src_scan += 4;
754 continue;
755 }
756 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
757 dest_scan[3] = dest_alpha;
758 int alpha_ratio = src_alpha * 255 / dest_alpha;
759 if (bNonseparableBlend) {
760 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
761 }
762 for (int color = 0; color < 3; color ++) {
763 if (blend_type) {
764 int blended = bNonseparableBlend ? blended_colors[color] :
765 _BLEND(blend_type, *dest_scan, *src_scan);
766 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
767 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
768 } else {
769 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
770 }
771 dest_scan ++;
772 src_scan ++;
773 }
774 dest_scan ++;
775 src_scan ++;
776 }
777 } else {
778 for (int col = 0; col < pixel_count; col ++) {
779 FX_BYTE back_alpha = dest_scan[3];
780 if (back_alpha == 0) {
781 if (clip_scan) {
782 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
783 FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2], src_scan[1], *src_scan));
784 } else {
785 FXARGB_SETDIB(dest_scan, FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2], src_scan[1], *src_scan));
786 }
787 dest_scan += 4;
788 src_scan += 3;
789 src_alpha_scan ++;
790 continue;
791 }
792 FX_BYTE src_alpha;
793 if (clip_scan == NULL) {
794 src_alpha = *src_alpha_scan ++;
795 } else {
796 src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
797 }
798 if (src_alpha == 0) {
799 dest_scan += 4;
800 src_scan += 3;
801 continue;
802 }
803 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
804 dest_scan[3] = dest_alpha;
805 int alpha_ratio = src_alpha * 255 / dest_alpha;
806 if (bNonseparableBlend) {
807 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
808 }
809 for (int color = 0; color < 3; color ++) {
810 if (blend_type) {
811 int blended = bNonseparableBlend ? blended_colors[color] :
812 _BLEND(blend_type, *dest_scan, *src_scan);
813 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
814 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
815 } else {
816 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
817 }
818 dest_scan ++;
819 src_scan ++;
820 }
821 dest_scan ++;
822 }
823 }
824 } else {
825 if (src_alpha_scan) {
826 for (int col = 0; col < pixel_count; col ++) {
827 FX_BYTE back_alpha = *dest_alpha_scan;
828 if (back_alpha == 0) {
829 if (clip_scan) {
830 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
831 *dest_alpha_scan = src_alpha;
832 *dest_scan++ = *src_scan++;
833 *dest_scan++ = *src_scan++;
834 *dest_scan++ = *src_scan++;
835 } else {
836 *dest_alpha_scan = *src_alpha_scan;
837 *dest_scan++ = *src_scan++;
838 *dest_scan++ = *src_scan++;
839 *dest_scan++ = *src_scan++;
840 }
841 dest_alpha_scan ++;
842 src_alpha_scan ++;
843 continue;
844 }
845 FX_BYTE src_alpha;
846 if (clip_scan == NULL) {
847 src_alpha = *src_alpha_scan ++;
848 } else {
849 src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
850 }
851 if (src_alpha == 0) {
852 dest_scan += 3;
853 src_scan += 3;
854 dest_alpha_scan ++;
855 continue;
856 }
857 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
858 *dest_alpha_scan ++ = dest_alpha;
859 int alpha_ratio = src_alpha * 255 / dest_alpha;
860 if (bNonseparableBlend) {
861 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
862 }
863 for (int color = 0; color < 3; color ++) {
864 if (blend_type) {
865 int blended = bNonseparableBlend ? blended_colors[color] :
866 _BLEND(blend_type, *dest_scan, *src_scan);
867 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
868 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
869 } else {
870 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
871 }
872 dest_scan ++;
873 src_scan ++;
874 }
875 }
876 } else {
877 for (int col = 0; col < pixel_count; col ++) {
878 FX_BYTE back_alpha = *dest_alpha_scan;
879 if (back_alpha == 0) {
880 if (clip_scan) {
881 int src_alpha = clip_scan[col] * src_scan[3] / 255;
882 *dest_alpha_scan = src_alpha;
883 *dest_scan++ = *src_scan++;
884 *dest_scan++ = *src_scan++;
885 *dest_scan++ = *src_scan++;
886 } else {
887 *dest_alpha_scan = src_scan[3];
888 *dest_scan++ = *src_scan++;
889 *dest_scan++ = *src_scan++;
890 *dest_scan++ = *src_scan++;
891 }
892 dest_alpha_scan ++;
893 src_scan ++;
894 continue;
895 }
896 FX_BYTE src_alpha;
897 if (clip_scan == NULL) {
898 src_alpha = src_scan[3];
899 } else {
900 src_alpha = clip_scan[col] * src_scan[3] / 255;
901 }
902 if (src_alpha == 0) {
903 dest_scan += 3;
904 src_scan += 4;
905 dest_alpha_scan ++;
906 continue;
907 }
908 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
909 *dest_alpha_scan++ = dest_alpha;
910 int alpha_ratio = src_alpha * 255 / dest_alpha;
911 if (bNonseparableBlend) {
912 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
913 }
914 for (int color = 0; color < 3; color ++) {
915 if (blend_type) {
916 int blended = bNonseparableBlend ? blended_colors[color] :
917 _BLEND(blend_type, *dest_scan, *src_scan);
918 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
919 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
920 } else {
921 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
922 }
923 dest_scan ++;
924 src_scan ++;
925 }
926 src_scan ++;
927 }
928 }
929 }
930 }
_CompositeRow_Rgb2Argb_Blend_NoClip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int src_Bpp,FX_LPBYTE dest_alpha_scan)931 void _CompositeRow_Rgb2Argb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
932 FX_LPBYTE dest_alpha_scan)
933 {
934 int blended_colors[3];
935 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
936 int src_gap = src_Bpp - 3;
937 if (dest_alpha_scan == NULL) {
938 for (int col = 0; col < width; col ++) {
939 FX_BYTE back_alpha = dest_scan[3];
940 if (back_alpha == 0) {
941 if (src_Bpp == 4) {
942 FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
943 } else {
944 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
945 }
946 dest_scan += 4;
947 src_scan += src_Bpp;
948 continue;
949 }
950 dest_scan[3] = 0xff;
951 if (bNonseparableBlend) {
952 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
953 }
954 for (int color = 0; color < 3; color ++) {
955 int src_color = *src_scan;
956 int blended = bNonseparableBlend ? blended_colors[color] :
957 _BLEND(blend_type, *dest_scan, src_color);
958 *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
959 dest_scan ++;
960 src_scan ++;
961 }
962 dest_scan ++;
963 src_scan += src_gap;
964 }
965 } else {
966 for (int col = 0; col < width; col ++) {
967 FX_BYTE back_alpha = *dest_alpha_scan;
968 if (back_alpha == 0) {
969 *dest_scan++ = *src_scan++;
970 *dest_scan++ = *src_scan++;
971 *dest_scan++ = *src_scan++;
972 *dest_alpha_scan++ = 0xff;
973 src_scan += src_gap;
974 continue;
975 }
976 *dest_alpha_scan++ = 0xff;
977 if (bNonseparableBlend) {
978 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
979 }
980 for (int color = 0; color < 3; color ++) {
981 int src_color = *src_scan;
982 int blended = bNonseparableBlend ? blended_colors[color] :
983 _BLEND(blend_type, *dest_scan, src_color);
984 *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
985 dest_scan ++;
986 src_scan ++;
987 }
988 src_scan += src_gap;
989 }
990 }
991 }
_CompositeRow_Rgb2Argb_Blend_Clip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int src_Bpp,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)992 inline void _CompositeRow_Rgb2Argb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
993 FX_LPBYTE dest_alpha_scan)
994 {
995 int blended_colors[3];
996 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
997 int src_gap = src_Bpp - 3;
998 if (dest_alpha_scan == NULL) {
999 for (int col = 0; col < width; col ++) {
1000 int src_alpha = *clip_scan ++;
1001 FX_BYTE back_alpha = dest_scan[3];
1002 if (back_alpha == 0) {
1003 *dest_scan++ = *src_scan++;
1004 *dest_scan++ = *src_scan++;
1005 *dest_scan++ = *src_scan++;
1006 src_scan += src_gap;
1007 dest_scan ++;
1008 continue;
1009 }
1010 if (src_alpha == 0) {
1011 dest_scan += 4;
1012 src_scan += src_Bpp;
1013 continue;
1014 }
1015 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1016 dest_scan[3] = dest_alpha;
1017 int alpha_ratio = src_alpha * 255 / dest_alpha;
1018 if (bNonseparableBlend) {
1019 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1020 }
1021 for (int color = 0; color < 3; color ++) {
1022 int src_color = *src_scan;
1023 int blended = bNonseparableBlend ? blended_colors[color] :
1024 _BLEND(blend_type, *dest_scan, src_color);
1025 blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
1026 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1027 dest_scan ++;
1028 src_scan ++;
1029 }
1030 dest_scan ++;
1031 src_scan += src_gap;
1032 }
1033 } else {
1034 for (int col = 0; col < width; col ++) {
1035 int src_alpha = *clip_scan ++;
1036 FX_BYTE back_alpha = *dest_alpha_scan;
1037 if (back_alpha == 0) {
1038 *dest_scan++ = *src_scan++;
1039 *dest_scan++ = *src_scan++;
1040 *dest_scan++ = *src_scan++;
1041 src_scan += src_gap;
1042 dest_alpha_scan++;
1043 continue;
1044 }
1045 if (src_alpha == 0) {
1046 dest_scan += 3;
1047 dest_alpha_scan++;
1048 src_scan += src_Bpp;
1049 continue;
1050 }
1051 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1052 *dest_alpha_scan++ = dest_alpha;
1053 int alpha_ratio = src_alpha * 255 / dest_alpha;
1054 if (bNonseparableBlend) {
1055 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1056 }
1057 for (int color = 0; color < 3; color ++) {
1058 int src_color = *src_scan;
1059 int blended = bNonseparableBlend ? blended_colors[color] :
1060 _BLEND(blend_type, *dest_scan, src_color);
1061 blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
1062 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1063 dest_scan ++;
1064 src_scan ++;
1065 }
1066 src_scan += src_gap;
1067 }
1068 }
1069 }
_CompositeRow_Rgb2Argb_NoBlend_Clip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int src_Bpp,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)1070 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
1071 FX_LPBYTE dest_alpha_scan)
1072 {
1073 int src_gap = src_Bpp - 3;
1074 if (dest_alpha_scan == NULL) {
1075 for (int col = 0; col < width; col ++) {
1076 int src_alpha = clip_scan[col];
1077 if (src_alpha == 255) {
1078 *dest_scan++ = *src_scan++;
1079 *dest_scan++ = *src_scan++;
1080 *dest_scan++ = *src_scan++;
1081 *dest_scan++ = 255;
1082 src_scan += src_gap;
1083 continue;
1084 }
1085 if (src_alpha == 0) {
1086 dest_scan += 4;
1087 src_scan += src_Bpp;
1088 continue;
1089 }
1090 int back_alpha = dest_scan[3];
1091 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1092 dest_scan[3] = dest_alpha;
1093 int alpha_ratio = src_alpha * 255 / dest_alpha;
1094 for (int color = 0; color < 3; color ++) {
1095 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
1096 dest_scan ++;
1097 src_scan ++;
1098 }
1099 dest_scan ++;
1100 src_scan += src_gap;
1101 }
1102 } else {
1103 for (int col = 0; col < width; col ++) {
1104 int src_alpha = clip_scan[col];
1105 if (src_alpha == 255) {
1106 *dest_scan++ = *src_scan++;
1107 *dest_scan++ = *src_scan++;
1108 *dest_scan++ = *src_scan++;
1109 *dest_alpha_scan++ = 255;
1110 src_scan += src_gap;
1111 continue;
1112 }
1113 if (src_alpha == 0) {
1114 dest_scan += 3;
1115 dest_alpha_scan ++;
1116 src_scan += src_Bpp;
1117 continue;
1118 }
1119 int back_alpha = *dest_alpha_scan;
1120 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1121 *dest_alpha_scan ++ = dest_alpha;
1122 int alpha_ratio = src_alpha * 255 / dest_alpha;
1123 for (int color = 0; color < 3; color ++) {
1124 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
1125 dest_scan ++;
1126 src_scan ++;
1127 }
1128 src_scan += src_gap;
1129 }
1130 }
1131 }
_CompositeRow_Rgb2Argb_NoBlend_NoClip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int src_Bpp,FX_LPBYTE dest_alpha_scan)1132 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
1133 FX_LPBYTE dest_alpha_scan)
1134 {
1135 if (dest_alpha_scan == NULL) {
1136 for (int col = 0; col < width; col ++) {
1137 if (src_Bpp == 4) {
1138 FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
1139 } else {
1140 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
1141 }
1142 dest_scan += 4;
1143 src_scan += src_Bpp;
1144 }
1145 } else {
1146 int src_gap = src_Bpp - 3;
1147 for (int col = 0; col < width; col ++) {
1148 *dest_scan++ = *src_scan++;
1149 *dest_scan++ = *src_scan++;
1150 *dest_scan++ = *src_scan++;
1151 *dest_alpha_scan++ = 0xff;
1152 src_scan += src_gap;
1153 }
1154 }
1155 }
_CompositeRow_Argb2Rgb_Blend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan)1156 inline void _CompositeRow_Argb2Rgb_Blend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
1157 FX_LPCBYTE src_alpha_scan)
1158 {
1159 int blended_colors[3];
1160 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1161 int dest_gap = dest_Bpp - 3;
1162 if (src_alpha_scan == NULL) {
1163 for (int col = 0; col < width; col ++) {
1164 FX_BYTE src_alpha;
1165 if (clip_scan) {
1166 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1167 } else {
1168 src_alpha = src_scan[3];
1169 }
1170 if (src_alpha == 0) {
1171 dest_scan += dest_Bpp;
1172 src_scan += 4;
1173 continue;
1174 }
1175 if (bNonseparableBlend) {
1176 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1177 }
1178 for (int color = 0; color < 3; color ++) {
1179 int back_color = *dest_scan;
1180 int blended = bNonseparableBlend ? blended_colors[color] :
1181 _BLEND(blend_type, back_color, *src_scan);
1182 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1183 dest_scan ++;
1184 src_scan ++;
1185 }
1186 dest_scan += dest_gap;
1187 src_scan ++;
1188 }
1189 } else {
1190 for (int col = 0; col < width; col ++) {
1191 FX_BYTE src_alpha;
1192 if (clip_scan) {
1193 src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1194 } else {
1195 src_alpha = *src_alpha_scan++;
1196 }
1197 if (src_alpha == 0) {
1198 dest_scan += dest_Bpp;
1199 src_scan += 3;
1200 continue;
1201 }
1202 if (bNonseparableBlend) {
1203 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1204 }
1205 for (int color = 0; color < 3; color ++) {
1206 int back_color = *dest_scan;
1207 int blended = bNonseparableBlend ? blended_colors[color] :
1208 _BLEND(blend_type, back_color, *src_scan);
1209 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1210 dest_scan ++;
1211 src_scan ++;
1212 }
1213 dest_scan += dest_gap;
1214 }
1215 }
1216 }
_CompositeRow_Argb2Rgb_NoBlend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan)1217 inline void _CompositeRow_Argb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
1218 FX_LPCBYTE src_alpha_scan)
1219 {
1220 int dest_gap = dest_Bpp - 3;
1221 if (src_alpha_scan == NULL) {
1222 for (int col = 0; col < width; col ++) {
1223 FX_BYTE src_alpha;
1224 if (clip_scan) {
1225 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1226 } else {
1227 src_alpha = src_scan[3];
1228 }
1229 if (src_alpha == 255) {
1230 *dest_scan++ = *src_scan++;
1231 *dest_scan++ = *src_scan++;
1232 *dest_scan++ = *src_scan++;
1233 dest_scan += dest_gap;
1234 src_scan ++;
1235 continue;
1236 }
1237 if (src_alpha == 0) {
1238 dest_scan += dest_Bpp;
1239 src_scan += 4;
1240 continue;
1241 }
1242 for (int color = 0; color < 3; color ++) {
1243 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1244 dest_scan ++;
1245 src_scan ++;
1246 }
1247 dest_scan += dest_gap;
1248 src_scan ++;
1249 }
1250 } else {
1251 for (int col = 0; col < width; col ++) {
1252 FX_BYTE src_alpha;
1253 if (clip_scan) {
1254 src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1255 } else {
1256 src_alpha = *src_alpha_scan++;
1257 }
1258 if (src_alpha == 255) {
1259 *dest_scan++ = *src_scan++;
1260 *dest_scan++ = *src_scan++;
1261 *dest_scan++ = *src_scan++;
1262 dest_scan += dest_gap;
1263 continue;
1264 }
1265 if (src_alpha == 0) {
1266 dest_scan += dest_Bpp;
1267 src_scan += 3;
1268 continue;
1269 }
1270 for (int color = 0; color < 3; color ++) {
1271 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1272 dest_scan ++;
1273 src_scan ++;
1274 }
1275 dest_scan += dest_gap;
1276 }
1277 }
1278 }
_CompositeRow_Rgb2Rgb_Blend_NoClip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,int src_Bpp)1279 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
1280 {
1281 int blended_colors[3];
1282 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1283 int dest_gap = dest_Bpp - 3;
1284 int src_gap = src_Bpp - 3;
1285 for (int col = 0; col < width; col ++) {
1286 if (bNonseparableBlend) {
1287 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1288 }
1289 for (int color = 0; color < 3; color ++) {
1290 int back_color = *dest_scan;
1291 int src_color = *src_scan;
1292 int blended = bNonseparableBlend ? blended_colors[color] :
1293 _BLEND(blend_type, back_color, src_color);
1294 *dest_scan = blended;
1295 dest_scan ++;
1296 src_scan ++;
1297 }
1298 dest_scan += dest_gap;
1299 src_scan += src_gap;
1300 }
1301 }
_CompositeRow_Rgb2Rgb_Blend_Clip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,int src_Bpp,FX_LPCBYTE clip_scan)1302 inline void _CompositeRow_Rgb2Rgb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
1303 {
1304 int blended_colors[3];
1305 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1306 int dest_gap = dest_Bpp - 3;
1307 int src_gap = src_Bpp - 3;
1308 for (int col = 0; col < width; col ++) {
1309 FX_BYTE src_alpha = *clip_scan ++;
1310 if (src_alpha == 0) {
1311 dest_scan += dest_Bpp;
1312 src_scan += src_Bpp;
1313 continue;
1314 }
1315 if (bNonseparableBlend) {
1316 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1317 }
1318 for (int color = 0; color < 3; color ++) {
1319 int src_color = *src_scan;
1320 int back_color = *dest_scan;
1321 int blended = bNonseparableBlend ? blended_colors[color] :
1322 _BLEND(blend_type, back_color, src_color);
1323 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1324 dest_scan ++;
1325 src_scan ++;
1326 }
1327 dest_scan += dest_gap;
1328 src_scan += src_gap;
1329 }
1330 }
_CompositeRow_Rgb2Rgb_NoBlend_NoClip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,int src_Bpp)1331 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
1332 {
1333 if (dest_Bpp == src_Bpp) {
1334 FXSYS_memcpy32(dest_scan, src_scan, width * dest_Bpp);
1335 return;
1336 }
1337 for (int col = 0; col < width; col ++) {
1338 dest_scan[0] = src_scan[0];
1339 dest_scan[1] = src_scan[1];
1340 dest_scan[2] = src_scan[2];
1341 dest_scan += dest_Bpp;
1342 src_scan += src_Bpp;
1343 }
1344 }
_CompositeRow_Rgb2Rgb_NoBlend_Clip(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,int src_Bpp,FX_LPCBYTE clip_scan)1345 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
1346 {
1347 for (int col = 0; col < width; col ++) {
1348 int src_alpha = clip_scan[col];
1349 if (src_alpha == 255) {
1350 dest_scan[0] = src_scan[0];
1351 dest_scan[1] = src_scan[1];
1352 dest_scan[2] = src_scan[2];
1353 } else if (src_alpha) {
1354 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1355 dest_scan ++;
1356 src_scan ++;
1357 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1358 dest_scan ++;
1359 src_scan ++;
1360 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1361 dest_scan += dest_Bpp - 2;
1362 src_scan += src_Bpp - 2;
1363 continue;
1364 }
1365 dest_scan += dest_Bpp;
1366 src_scan += src_Bpp;
1367 }
1368 }
_CompositeRow_Argb2Argb_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan,FX_LPCBYTE src_alpha_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1369 void _CompositeRow_Argb2Argb_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
1370 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1371 {
1372 FX_LPBYTE dp = src_cache_scan;
1373 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1374 if (src_alpha_scan) {
1375 if (dest_alpha_scan == NULL) {
1376 for (int col = 0; col < pixel_count; col ++) {
1377 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1378 dp[3] = *src_alpha_scan++;
1379 src_scan += 3;
1380 dp += 4;
1381 }
1382 src_alpha_scan = NULL;
1383 } else {
1384 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count);
1385 }
1386 } else {
1387 if (dest_alpha_scan == NULL) {
1388 for (int col = 0; col < pixel_count; col ++) {
1389 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1390 dp[3] = src_scan[3];
1391 src_scan += 4;
1392 dp += 4;
1393 }
1394 } else {
1395 int blended_colors[3];
1396 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1397 for (int col = 0; col < pixel_count; col ++) {
1398 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1399 FX_BYTE back_alpha = *dest_alpha_scan;
1400 if (back_alpha == 0) {
1401 if (clip_scan) {
1402 int src_alpha = clip_scan[col] * src_scan[3] / 255;
1403 *dest_alpha_scan = src_alpha;
1404 *dest_scan++ = *src_cache_scan++;
1405 *dest_scan++ = *src_cache_scan++;
1406 *dest_scan++ = *src_cache_scan++;
1407 } else {
1408 *dest_alpha_scan = src_scan[3];
1409 *dest_scan++ = *src_cache_scan++;
1410 *dest_scan++ = *src_cache_scan++;
1411 *dest_scan++ = *src_cache_scan++;
1412 }
1413 dest_alpha_scan ++;
1414 src_scan += 4;
1415 continue;
1416 }
1417 FX_BYTE src_alpha;
1418 if (clip_scan == NULL) {
1419 src_alpha = src_scan[3];
1420 } else {
1421 src_alpha = clip_scan[col] * src_scan[3] / 255;
1422 }
1423 src_scan += 4;
1424 if (src_alpha == 0) {
1425 dest_scan += 3;
1426 src_cache_scan += 3;
1427 dest_alpha_scan ++;
1428 continue;
1429 }
1430 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1431 *dest_alpha_scan ++ = dest_alpha;
1432 int alpha_ratio = src_alpha * 255 / dest_alpha;
1433 if (bNonseparableBlend) {
1434 _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
1435 }
1436 for (int color = 0; color < 3; color ++) {
1437 if (blend_type) {
1438 int blended = bNonseparableBlend ? blended_colors[color] :
1439 _BLEND(blend_type, *dest_scan, *src_cache_scan);
1440 blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha);
1441 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1442 } else {
1443 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio);
1444 }
1445 dest_scan ++;
1446 src_cache_scan ++;
1447 }
1448 }
1449 return;
1450 }
1451 }
1452 _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type, clip_scan, dest_alpha_scan, src_alpha_scan);
1453 }
_CompositeRow_Rgb2Argb_Blend_NoClip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int src_Bpp,FX_LPBYTE dest_alpha_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1454 void _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
1455 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1456 {
1457 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1458 if (src_Bpp == 3) {
1459 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1460 } else {
1461 FX_LPBYTE dp = src_cache_scan;
1462 for (int col = 0; col < width; col ++) {
1463 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1464 src_scan += 4;
1465 dp += 3;
1466 }
1467 }
1468 _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, 3, dest_alpha_scan);
1469 }
_CompositeRow_Rgb2Argb_Blend_Clip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int src_Bpp,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1470 inline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
1471 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1472 {
1473 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1474 if (src_Bpp == 3) {
1475 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1476 } else {
1477 FX_LPBYTE dp = src_cache_scan;
1478 for (int col = 0; col < width; col ++) {
1479 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1480 src_scan += 4;
1481 dp += 3;
1482 }
1483 }
1484 _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, 3, clip_scan, dest_alpha_scan);
1485 }
_CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int src_Bpp,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1486 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
1487 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1488 {
1489 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1490 if (src_Bpp == 3) {
1491 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1492 } else {
1493 FX_LPBYTE dp = src_cache_scan;
1494 for (int col = 0; col < width; col ++) {
1495 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1496 src_scan += 4;
1497 dp += 3;
1498 }
1499 }
1500 _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3, clip_scan, dest_alpha_scan);
1501 }
_CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int src_Bpp,FX_LPBYTE dest_alpha_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1502 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
1503 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1504 {
1505 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1506 if (src_Bpp == 3) {
1507 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1508 } else {
1509 FX_LPBYTE dp = src_cache_scan;
1510 for (int col = 0; col < width; col ++) {
1511 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1512 src_scan += 4;
1513 dp += 3;
1514 }
1515 }
1516 _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3, dest_alpha_scan);
1517 }
_CompositeRow_Argb2Rgb_Blend_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1518 inline void _CompositeRow_Argb2Rgb_Blend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
1519 FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1520 {
1521 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1522 if (src_alpha_scan) {
1523 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1524 } else {
1525 int blended_colors[3];
1526 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1527 int dest_gap = dest_Bpp - 3;
1528 for (int col = 0; col < width; col ++) {
1529 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1530 FX_BYTE src_alpha;
1531 if (clip_scan) {
1532 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1533 } else {
1534 src_alpha = src_scan[3];
1535 }
1536 src_scan += 4;
1537 if (src_alpha == 0) {
1538 dest_scan += dest_Bpp;
1539 src_cache_scan += 3;
1540 continue;
1541 }
1542 if (bNonseparableBlend) {
1543 _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
1544 }
1545 for (int color = 0; color < 3; color ++) {
1546 int back_color = *dest_scan;
1547 int blended = bNonseparableBlend ? blended_colors[color] :
1548 _BLEND(blend_type, back_color, *src_cache_scan);
1549 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1550 dest_scan ++;
1551 src_cache_scan ++;
1552 }
1553 dest_scan += dest_gap;
1554 }
1555 return;
1556 }
1557 _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, clip_scan, src_alpha_scan);
1558 }
_CompositeRow_Argb2Rgb_NoBlend_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1559 inline void _CompositeRow_Argb2Rgb_NoBlend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
1560 FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1561 {
1562 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1563 if (src_alpha_scan) {
1564 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1565 } else {
1566 int dest_gap = dest_Bpp - 3;
1567 for (int col = 0; col < width; col ++) {
1568 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1569 FX_BYTE src_alpha;
1570 if (clip_scan) {
1571 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1572 } else {
1573 src_alpha = src_scan[3];
1574 }
1575 src_scan += 4;
1576 if (src_alpha == 255) {
1577 *dest_scan++ = *src_cache_scan++;
1578 *dest_scan++ = *src_cache_scan++;
1579 *dest_scan++ = *src_cache_scan++;
1580 dest_scan += dest_gap;
1581 continue;
1582 }
1583 if (src_alpha == 0) {
1584 dest_scan += dest_Bpp;
1585 src_cache_scan += 3;
1586 continue;
1587 }
1588 for (int color = 0; color < 3; color ++) {
1589 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha);
1590 dest_scan ++;
1591 src_cache_scan ++;
1592 }
1593 dest_scan += dest_gap;
1594 }
1595 return;
1596 }
1597 _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp, clip_scan, src_alpha_scan);
1598 }
_CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,int src_Bpp,FX_LPBYTE src_cache_scan,void * pIccTransform)1599 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp,
1600 FX_LPBYTE src_cache_scan, void* pIccTransform)
1601 {
1602 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1603 if (src_Bpp == 3) {
1604 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1605 } else {
1606 FX_LPBYTE dp = src_cache_scan;
1607 for (int col = 0; col < width; col ++) {
1608 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1609 src_scan += 4;
1610 dp += 3;
1611 }
1612 }
1613 _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3);
1614 }
_CompositeRow_Rgb2Rgb_Blend_Clip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,int src_Bpp,FX_LPCBYTE clip_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1615 inline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
1616 FX_LPBYTE src_cache_scan, void* pIccTransform)
1617 {
1618 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1619 if (src_Bpp == 3) {
1620 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1621 } else {
1622 FX_LPBYTE dp = src_cache_scan;
1623 for (int col = 0; col < width; col ++) {
1624 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1625 src_scan += 4;
1626 dp += 3;
1627 }
1628 }
1629 _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3, clip_scan);
1630 }
_CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,int src_Bpp,FX_LPBYTE src_cache_scan,void * pIccTransform)1631 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp,
1632 FX_LPBYTE src_cache_scan, void* pIccTransform)
1633 {
1634 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1635 if (src_Bpp == 3) {
1636 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1637 } else {
1638 FX_LPBYTE dp = src_cache_scan;
1639 for (int col = 0; col < width; col ++) {
1640 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1641 src_scan += 4;
1642 dp += 3;
1643 }
1644 }
1645 _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width, dest_Bpp, 3);
1646 }
_CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,int src_Bpp,FX_LPCBYTE clip_scan,FX_LPBYTE src_cache_scan,void * pIccTransform)1647 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
1648 FX_LPBYTE src_cache_scan, void* pIccTransform)
1649 {
1650 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1651 if (src_Bpp == 3) {
1652 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1653 } else {
1654 FX_LPBYTE dp = src_cache_scan;
1655 for (int col = 0; col < width; col ++) {
1656 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1657 src_scan += 4;
1658 dp += 3;
1659 }
1660 }
1661 _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp, 3, clip_scan);
1662 }
_CompositeRow_8bppPal2Gray(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,FX_LPCBYTE pPalette,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan)1663 inline void _CompositeRow_8bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
1664 int blend_type, FX_LPCBYTE clip_scan,
1665 FX_LPCBYTE src_alpha_scan)
1666 {
1667 if (src_alpha_scan) {
1668 if (blend_type) {
1669 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1670 int blended_color;
1671 for (int col = 0; col < pixel_count; col ++) {
1672 FX_BYTE gray = pPalette[*src_scan];
1673 int src_alpha = *src_alpha_scan++;
1674 if (clip_scan) {
1675 src_alpha = clip_scan[col] * src_alpha / 255;
1676 }
1677 if (bNonseparableBlend) {
1678 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1679 }
1680 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1681 if (src_alpha) {
1682 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
1683 } else {
1684 *dest_scan = gray;
1685 }
1686 dest_scan ++;
1687 src_scan ++;
1688 }
1689 return;
1690 }
1691 for (int col = 0; col < pixel_count; col ++) {
1692 FX_BYTE gray = pPalette[*src_scan];
1693 int src_alpha = *src_alpha_scan++;
1694 if (clip_scan) {
1695 src_alpha = clip_scan[col] * src_alpha / 255;
1696 }
1697 if (src_alpha) {
1698 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
1699 } else {
1700 *dest_scan = gray;
1701 }
1702 dest_scan ++;
1703 src_scan ++;
1704 }
1705 } else {
1706 if (blend_type) {
1707 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1708 int blended_color;
1709 for (int col = 0; col < pixel_count; col ++) {
1710 FX_BYTE gray = pPalette[*src_scan];
1711 if (bNonseparableBlend) {
1712 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1713 }
1714 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1715 if (clip_scan && clip_scan[col] < 255) {
1716 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1717 } else {
1718 *dest_scan = gray;
1719 }
1720 dest_scan ++;
1721 src_scan ++;
1722 }
1723 return;
1724 }
1725 for (int col = 0; col < pixel_count; col ++) {
1726 FX_BYTE gray = pPalette[*src_scan];
1727 if (clip_scan && clip_scan[col] < 255) {
1728 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1729 } else {
1730 *dest_scan = gray;
1731 }
1732 dest_scan ++;
1733 src_scan ++;
1734 }
1735 }
1736 }
_CompositeRow_8bppPal2Graya(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,FX_LPCBYTE pPalette,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan,FX_LPCBYTE src_alpha_scan)1737 inline void _CompositeRow_8bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
1738 int blend_type, FX_LPCBYTE clip_scan,
1739 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
1740 {
1741 if (src_alpha_scan) {
1742 if (blend_type) {
1743 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1744 int blended_color;
1745 for (int col = 0; col < pixel_count; col ++) {
1746 FX_BYTE gray = pPalette[*src_scan];
1747 src_scan ++;
1748 FX_BYTE back_alpha = *dest_alpha_scan;
1749 if (back_alpha == 0) {
1750 int src_alpha = *src_alpha_scan ++;
1751 if (clip_scan) {
1752 src_alpha = clip_scan[col] * src_alpha / 255;
1753 }
1754 if (src_alpha) {
1755 *dest_scan = gray;
1756 *dest_alpha_scan = src_alpha;
1757 }
1758 dest_scan ++;
1759 dest_alpha_scan ++;
1760 continue;
1761 }
1762 FX_BYTE src_alpha = *src_alpha_scan++;
1763 if (clip_scan) {
1764 src_alpha = clip_scan[col] * src_alpha / 255;
1765 }
1766 if (src_alpha == 0) {
1767 dest_scan ++;
1768 dest_alpha_scan ++;
1769 continue;
1770 }
1771 *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1772 int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
1773 if (bNonseparableBlend) {
1774 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1775 }
1776 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1777 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1778 dest_alpha_scan ++;
1779 dest_scan ++;
1780 }
1781 return;
1782 }
1783 for (int col = 0; col < pixel_count; col ++) {
1784 FX_BYTE gray = pPalette[*src_scan];
1785 src_scan ++;
1786 FX_BYTE back_alpha = *dest_alpha_scan;
1787 if (back_alpha == 0) {
1788 int src_alpha = *src_alpha_scan ++;
1789 if (clip_scan) {
1790 src_alpha = clip_scan[col] * src_alpha / 255;
1791 }
1792 if (src_alpha) {
1793 *dest_scan = gray;
1794 *dest_alpha_scan = src_alpha;
1795 }
1796 dest_scan ++;
1797 dest_alpha_scan ++;
1798 continue;
1799 }
1800 FX_BYTE src_alpha = *src_alpha_scan++;
1801 if (clip_scan) {
1802 src_alpha = clip_scan[col] * src_alpha / 255;
1803 }
1804 if (src_alpha == 0) {
1805 dest_scan ++;
1806 dest_alpha_scan ++;
1807 continue;
1808 }
1809 *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1810 int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
1811 dest_alpha_scan ++;
1812 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1813 dest_scan ++;
1814 }
1815 } else {
1816 if (blend_type) {
1817 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1818 int blended_color;
1819 for (int col = 0; col < pixel_count; col ++) {
1820 FX_BYTE gray = pPalette[*src_scan];
1821 src_scan ++;
1822 if (clip_scan == NULL || clip_scan[col] == 255) {
1823 *dest_scan++ = gray;
1824 *dest_alpha_scan++ = 255;
1825 continue;
1826 }
1827 int src_alpha = clip_scan[col];
1828 if (src_alpha == 0) {
1829 dest_scan ++;
1830 dest_alpha_scan ++;
1831 continue;
1832 }
1833 int back_alpha = *dest_alpha_scan;
1834 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1835 *dest_alpha_scan ++ = dest_alpha;
1836 int alpha_ratio = src_alpha * 255 / dest_alpha;
1837 if (bNonseparableBlend) {
1838 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1839 }
1840 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1841 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1842 dest_scan ++;
1843 }
1844 return;
1845 }
1846 for (int col = 0; col < pixel_count; col ++) {
1847 FX_BYTE gray = pPalette[*src_scan];
1848 src_scan ++;
1849 if (clip_scan == NULL || clip_scan[col] == 255) {
1850 *dest_scan++ = gray;
1851 *dest_alpha_scan++ = 255;
1852 continue;
1853 }
1854 int src_alpha = clip_scan[col];
1855 if (src_alpha == 0) {
1856 dest_scan ++;
1857 dest_alpha_scan ++;
1858 continue;
1859 }
1860 int back_alpha = *dest_alpha_scan;
1861 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1862 *dest_alpha_scan ++ = dest_alpha;
1863 int alpha_ratio = src_alpha * 255 / dest_alpha;
1864 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1865 dest_scan ++;
1866 }
1867 }
1868 }
_CompositeRow_1bppPal2Gray(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,FX_LPCBYTE pPalette,int pixel_count,int blend_type,FX_LPCBYTE clip_scan)1869 inline void _CompositeRow_1bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
1870 FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
1871 {
1872 int reset_gray = pPalette[0];
1873 int set_gray = pPalette[1];
1874 if (blend_type) {
1875 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1876 int blended_color;
1877 for (int col = 0; col < pixel_count; col ++) {
1878 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1879 if (bNonseparableBlend) {
1880 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1881 }
1882 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1883 if (clip_scan && clip_scan[col] < 255) {
1884 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1885 } else {
1886 *dest_scan = gray;
1887 }
1888 dest_scan ++;
1889 }
1890 return;
1891 }
1892 for (int col = 0; col < pixel_count; col ++) {
1893 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1894 if (clip_scan && clip_scan[col] < 255) {
1895 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1896 } else {
1897 *dest_scan = gray;
1898 }
1899 dest_scan ++;
1900 }
1901 }
_CompositeRow_1bppPal2Graya(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,FX_LPCBYTE pPalette,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)1902 inline void _CompositeRow_1bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
1903 FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
1904 FX_LPBYTE dest_alpha_scan)
1905 {
1906 int reset_gray = pPalette[0];
1907 int set_gray = pPalette[1];
1908 if (blend_type) {
1909 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1910 int blended_color;
1911 for (int col = 0; col < pixel_count; col ++) {
1912 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1913 if (clip_scan == NULL || clip_scan[col] == 255) {
1914 *dest_scan++ = gray;
1915 *dest_alpha_scan ++ = 255;
1916 continue;
1917 }
1918 int src_alpha = clip_scan[col];
1919 if (src_alpha == 0) {
1920 dest_scan ++;
1921 dest_alpha_scan ++;
1922 continue;
1923 }
1924 int back_alpha = *dest_alpha_scan;
1925 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1926 *dest_alpha_scan ++ = dest_alpha;
1927 int alpha_ratio = src_alpha * 255 / dest_alpha;
1928 if (bNonseparableBlend) {
1929 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1930 }
1931 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1932 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1933 dest_scan ++;
1934 }
1935 return;
1936 }
1937 for (int col = 0; col < pixel_count; col ++) {
1938 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1939 if (clip_scan == NULL || clip_scan[col] == 255) {
1940 *dest_scan++ = gray;
1941 *dest_alpha_scan ++ = 255;
1942 continue;
1943 }
1944 int src_alpha = clip_scan[col];
1945 if (src_alpha == 0) {
1946 dest_scan ++;
1947 dest_alpha_scan ++;
1948 continue;
1949 }
1950 int back_alpha = *dest_alpha_scan;
1951 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1952 *dest_alpha_scan ++ = dest_alpha;
1953 int alpha_ratio = src_alpha * 255 / dest_alpha;
1954 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1955 dest_scan ++;
1956 }
1957 }
_CompositeRow_8bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,FX_DWORD * pPalette,int pixel_count,int DestBpp,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan)1958 inline void _CompositeRow_8bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_DWORD* pPalette, int pixel_count,
1959 int DestBpp, FX_LPCBYTE clip_scan,
1960 FX_LPCBYTE src_alpha_scan)
1961 {
1962 if (src_alpha_scan) {
1963 int dest_gap = DestBpp - 3;
1964 FX_ARGB argb = 0;
1965 for (int col = 0; col < pixel_count; col ++) {
1966 argb = pPalette[*src_scan];
1967 int src_r = FXARGB_R(argb);
1968 int src_g = FXARGB_G(argb);
1969 int src_b = FXARGB_B(argb);
1970 src_scan ++;
1971 FX_BYTE src_alpha = 0;
1972 if (clip_scan) {
1973 src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1974 } else {
1975 src_alpha = *src_alpha_scan++;
1976 }
1977 if (src_alpha == 255) {
1978 *dest_scan++ = src_b;
1979 *dest_scan++ = src_g;
1980 *dest_scan++ = src_r;
1981 dest_scan += dest_gap;
1982 continue;
1983 }
1984 if (src_alpha == 0) {
1985 dest_scan += DestBpp;
1986 continue;
1987 }
1988 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
1989 dest_scan ++;
1990 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
1991 dest_scan ++;
1992 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
1993 dest_scan ++;
1994 dest_scan += dest_gap;
1995 }
1996 } else {
1997 FX_ARGB argb = 0;
1998 for (int col = 0; col < pixel_count; col ++) {
1999 argb = pPalette[*src_scan];
2000 int src_r = FXARGB_R(argb);
2001 int src_g = FXARGB_G(argb);
2002 int src_b = FXARGB_B(argb);
2003 if (clip_scan && clip_scan[col] < 255) {
2004 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
2005 dest_scan ++;
2006 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
2007 dest_scan ++;
2008 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
2009 dest_scan ++;
2010 } else {
2011 *dest_scan++ = src_b;
2012 *dest_scan++ = src_g;
2013 *dest_scan++ = src_r;
2014 }
2015 if (DestBpp == 4) {
2016 dest_scan++;
2017 }
2018 src_scan ++;
2019 }
2020 }
2021 }
_CompositeRow_1bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,FX_DWORD * pPalette,int pixel_count,int DestBpp,FX_LPCBYTE clip_scan)2022 inline void _CompositeRow_1bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
2023 FX_DWORD* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
2024 {
2025 int reset_r, reset_g, reset_b;
2026 int set_r, set_g, set_b;
2027 reset_r = FXARGB_R(pPalette[0]);
2028 reset_g = FXARGB_G(pPalette[0]);
2029 reset_b = FXARGB_B(pPalette[0]);
2030 set_r = FXARGB_R(pPalette[1]);
2031 set_g = FXARGB_G(pPalette[1]);
2032 set_b = FXARGB_B(pPalette[1]);
2033 for (int col = 0; col < pixel_count; col ++) {
2034 int src_r, src_g, src_b;
2035 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2036 src_r = set_r;
2037 src_g = set_g;
2038 src_b = set_b;
2039 } else {
2040 src_r = reset_r;
2041 src_g = reset_g;
2042 src_b = reset_b;
2043 }
2044 if (clip_scan && clip_scan[col] < 255) {
2045 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
2046 dest_scan ++;
2047 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
2048 dest_scan ++;
2049 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
2050 dest_scan ++;
2051 } else {
2052 *dest_scan++ = src_b;
2053 *dest_scan++ = src_g;
2054 *dest_scan++ = src_r;
2055 }
2056 if (DestBpp == 4) {
2057 dest_scan++;
2058 }
2059 }
2060 }
_CompositeRow_8bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,FX_DWORD * pPalette,FX_LPCBYTE clip_scan,FX_LPCBYTE src_alpha_scan)2061 inline void _CompositeRow_8bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
2062 FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2063 FX_LPCBYTE src_alpha_scan)
2064 {
2065 if (src_alpha_scan) {
2066 for (int col = 0; col < width; col ++) {
2067 FX_ARGB argb = pPalette[*src_scan];
2068 src_scan ++;
2069 int src_r = FXARGB_R(argb);
2070 int src_g = FXARGB_G(argb);
2071 int src_b = FXARGB_B(argb);
2072 FX_BYTE back_alpha = dest_scan[3];
2073 if (back_alpha == 0) {
2074 if (clip_scan) {
2075 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
2076 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2077 } else {
2078 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b));
2079 }
2080 dest_scan += 4;
2081 src_alpha_scan ++;
2082 continue;
2083 }
2084 FX_BYTE src_alpha;
2085 if (clip_scan == NULL) {
2086 src_alpha = *src_alpha_scan ++;
2087 } else {
2088 src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
2089 }
2090 if (src_alpha == 0) {
2091 dest_scan += 4;
2092 continue;
2093 }
2094 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2095 dest_scan[3] = dest_alpha;
2096 int alpha_ratio = src_alpha * 255 / dest_alpha;
2097 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2098 dest_scan ++;
2099 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2100 dest_scan ++;
2101 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2102 dest_scan ++;
2103 dest_scan ++;
2104 }
2105 } else
2106 for (int col = 0; col < width; col ++) {
2107 FX_ARGB argb = pPalette[*src_scan];
2108 int src_r = FXARGB_R(argb);
2109 int src_g = FXARGB_G(argb);
2110 int src_b = FXARGB_B(argb);
2111 if (clip_scan == NULL || clip_scan[col] == 255) {
2112 *dest_scan++ = src_b;
2113 *dest_scan++ = src_g;
2114 *dest_scan++ = src_r;
2115 *dest_scan++ = 255;
2116 src_scan ++;
2117 continue;
2118 }
2119 int src_alpha = clip_scan[col];
2120 if (src_alpha == 0) {
2121 dest_scan += 4;
2122 src_scan ++;
2123 continue;
2124 }
2125 int back_alpha = dest_scan[3];
2126 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2127 dest_scan[3] = dest_alpha;
2128 int alpha_ratio = src_alpha * 255 / dest_alpha;
2129 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2130 dest_scan ++;
2131 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2132 dest_scan ++;
2133 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2134 dest_scan ++;
2135 dest_scan ++;
2136 src_scan ++;
2137 }
2138 }
_CompositeRow_8bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,FX_DWORD * pPalette,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan,FX_LPCBYTE src_alpha_scan)2139 void _CompositeRow_8bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
2140 FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2141 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
2142 {
2143 if (src_alpha_scan) {
2144 for (int col = 0; col < width; col ++) {
2145 FX_ARGB argb = pPalette[*src_scan];
2146 src_scan ++;
2147 int src_r = FXARGB_R(argb);
2148 int src_g = FXARGB_G(argb);
2149 int src_b = FXARGB_B(argb);
2150 FX_BYTE back_alpha = *dest_alpha_scan;
2151 if (back_alpha == 0) {
2152 if (clip_scan) {
2153 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
2154 *dest_alpha_scan ++ = src_alpha;
2155 } else {
2156 *dest_alpha_scan ++ = *src_alpha_scan;
2157 }
2158 *dest_scan ++ = src_b;
2159 *dest_scan ++ = src_g;
2160 *dest_scan ++ = src_r;
2161 src_alpha_scan ++;
2162 continue;
2163 }
2164 FX_BYTE src_alpha;
2165 if (clip_scan == NULL) {
2166 src_alpha = *src_alpha_scan++;
2167 } else {
2168 src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
2169 }
2170 if (src_alpha == 0) {
2171 dest_scan += 3;
2172 dest_alpha_scan ++;
2173 continue;
2174 }
2175 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2176 *dest_alpha_scan ++ = dest_alpha;
2177 int alpha_ratio = src_alpha * 255 / dest_alpha;
2178 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2179 dest_scan ++;
2180 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2181 dest_scan ++;
2182 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2183 dest_scan ++;
2184 }
2185 } else
2186 for (int col = 0; col < width; col ++) {
2187 FX_ARGB argb = pPalette[*src_scan];
2188 int src_r = FXARGB_R(argb);
2189 int src_g = FXARGB_G(argb);
2190 int src_b = FXARGB_B(argb);
2191 if (clip_scan == NULL || clip_scan[col] == 255) {
2192 *dest_scan++ = src_b;
2193 *dest_scan++ = src_g;
2194 *dest_scan++ = src_r;
2195 *dest_alpha_scan++ = 255;
2196 src_scan ++;
2197 continue;
2198 }
2199 int src_alpha = clip_scan[col];
2200 if (src_alpha == 0) {
2201 dest_scan += 3;
2202 dest_alpha_scan ++;
2203 src_scan ++;
2204 continue;
2205 }
2206 int back_alpha = *dest_alpha_scan;
2207 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2208 *dest_alpha_scan ++ = dest_alpha;
2209 int alpha_ratio = src_alpha * 255 / dest_alpha;
2210 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2211 dest_scan ++;
2212 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2213 dest_scan ++;
2214 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2215 dest_scan ++;
2216 src_scan ++;
2217 }
2218 }
_CompositeRow_1bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,int width,FX_DWORD * pPalette,FX_LPCBYTE clip_scan)2219 inline void _CompositeRow_1bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
2220 FX_DWORD* pPalette, FX_LPCBYTE clip_scan)
2221 {
2222 int reset_r, reset_g, reset_b;
2223 int set_r, set_g, set_b;
2224 reset_r = FXARGB_R(pPalette[0]);
2225 reset_g = FXARGB_G(pPalette[0]);
2226 reset_b = FXARGB_B(pPalette[0]);
2227 set_r = FXARGB_R(pPalette[1]);
2228 set_g = FXARGB_G(pPalette[1]);
2229 set_b = FXARGB_B(pPalette[1]);
2230 for (int col = 0; col < width; col ++) {
2231 int src_r, src_g, src_b;
2232 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2233 src_r = set_r;
2234 src_g = set_g;
2235 src_b = set_b;
2236 } else {
2237 src_r = reset_r;
2238 src_g = reset_g;
2239 src_b = reset_b;
2240 }
2241 if (clip_scan == NULL || clip_scan[col] == 255) {
2242 *dest_scan++ = src_b;
2243 *dest_scan++ = src_g;
2244 *dest_scan++ = src_r;
2245 *dest_scan++ = 255;
2246 continue;
2247 }
2248 int src_alpha = clip_scan[col];
2249 if (src_alpha == 0) {
2250 dest_scan += 4;
2251 continue;
2252 }
2253 int back_alpha = dest_scan[3];
2254 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2255 dest_scan[3] = dest_alpha;
2256 int alpha_ratio = src_alpha * 255 / dest_alpha;
2257 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2258 dest_scan ++;
2259 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2260 dest_scan ++;
2261 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2262 dest_scan ++;
2263 dest_scan ++;
2264 }
2265 }
_CompositeRow_1bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,int width,FX_DWORD * pPalette,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)2266 void _CompositeRow_1bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
2267 FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2268 FX_LPBYTE dest_alpha_scan)
2269 {
2270 int reset_r, reset_g, reset_b;
2271 int set_r, set_g, set_b;
2272 reset_r = FXARGB_R(pPalette[0]);
2273 reset_g = FXARGB_G(pPalette[0]);
2274 reset_b = FXARGB_B(pPalette[0]);
2275 set_r = FXARGB_R(pPalette[1]);
2276 set_g = FXARGB_G(pPalette[1]);
2277 set_b = FXARGB_B(pPalette[1]);
2278 for (int col = 0; col < width; col ++) {
2279 int src_r, src_g, src_b;
2280 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2281 src_r = set_r;
2282 src_g = set_g;
2283 src_b = set_b;
2284 } else {
2285 src_r = reset_r;
2286 src_g = reset_g;
2287 src_b = reset_b;
2288 }
2289 if (clip_scan == NULL || clip_scan[col] == 255) {
2290 *dest_scan++ = src_b;
2291 *dest_scan++ = src_g;
2292 *dest_scan++ = src_r;
2293 *dest_alpha_scan++ = 255;
2294 continue;
2295 }
2296 int src_alpha = clip_scan[col];
2297 if (src_alpha == 0) {
2298 dest_scan += 3;
2299 dest_alpha_scan ++;
2300 continue;
2301 }
2302 int back_alpha = *dest_alpha_scan;
2303 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2304 *dest_alpha_scan ++ = dest_alpha;
2305 int alpha_ratio = src_alpha * 255 / dest_alpha;
2306 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2307 dest_scan ++;
2308 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2309 dest_scan ++;
2310 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2311 dest_scan ++;
2312 }
2313 }
_CompositeRow_ByteMask2Argb(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int pixel_count,int blend_type,FX_LPCBYTE clip_scan)2314 void _CompositeRow_ByteMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2315 int blend_type, FX_LPCBYTE clip_scan)
2316 {
2317 for (int col = 0; col < pixel_count; col ++) {
2318 int src_alpha;
2319 if (clip_scan) {
2320 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2321 } else {
2322 src_alpha = mask_alpha * src_scan[col] / 255;
2323 }
2324 FX_BYTE back_alpha = dest_scan[3];
2325 if (back_alpha == 0) {
2326 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2327 dest_scan += 4;
2328 continue;
2329 }
2330 if (src_alpha == 0) {
2331 dest_scan += 4;
2332 continue;
2333 }
2334 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2335 dest_scan[3] = dest_alpha;
2336 int alpha_ratio = src_alpha * 255 / dest_alpha;
2337 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2338 int blended_colors[3];
2339 FX_BYTE src_scan[3];
2340 src_scan[0] = src_b;
2341 src_scan[1] = src_g;
2342 src_scan[2] = src_r;
2343 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2344 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2345 dest_scan ++;
2346 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2347 dest_scan ++;
2348 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2349 } else if (blend_type) {
2350 int blended = _BLEND(blend_type, *dest_scan, src_b);
2351 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2352 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2353 dest_scan ++;
2354 blended = _BLEND(blend_type, *dest_scan, src_g);
2355 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2356 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2357 dest_scan ++;
2358 blended = _BLEND(blend_type, *dest_scan, src_r);
2359 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2360 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2361 } else {
2362 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2363 dest_scan ++;
2364 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2365 dest_scan ++;
2366 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2367 }
2368 dest_scan += 2;
2369 }
2370 }
_CompositeRow_ByteMask2Rgba(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)2371 void _CompositeRow_ByteMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2372 int blend_type, FX_LPCBYTE clip_scan,
2373 FX_LPBYTE dest_alpha_scan)
2374 {
2375 for (int col = 0; col < pixel_count; col ++) {
2376 int src_alpha;
2377 if (clip_scan) {
2378 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2379 } else {
2380 src_alpha = mask_alpha * src_scan[col] / 255;
2381 }
2382 FX_BYTE back_alpha = *dest_alpha_scan;
2383 if (back_alpha == 0) {
2384 *dest_scan ++ = src_b;
2385 *dest_scan ++ = src_g;
2386 *dest_scan ++ = src_r;
2387 *dest_alpha_scan ++ = src_alpha;
2388 continue;
2389 }
2390 if (src_alpha == 0) {
2391 dest_scan += 3;
2392 dest_alpha_scan ++;
2393 continue;
2394 }
2395 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2396 *dest_alpha_scan ++ = dest_alpha;
2397 int alpha_ratio = src_alpha * 255 / dest_alpha;
2398 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2399 int blended_colors[3];
2400 FX_BYTE src_scan[3];
2401 src_scan[0] = src_b;
2402 src_scan[1] = src_g;
2403 src_scan[2] = src_r;
2404 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2405 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2406 dest_scan ++;
2407 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2408 dest_scan ++;
2409 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2410 dest_scan ++;
2411 } else if (blend_type) {
2412 int blended = _BLEND(blend_type, *dest_scan, src_b);
2413 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2414 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2415 dest_scan ++;
2416 blended = _BLEND(blend_type, *dest_scan, src_g);
2417 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2418 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2419 dest_scan ++;
2420 blended = _BLEND(blend_type, *dest_scan, src_r);
2421 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2422 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2423 dest_scan ++;
2424 } else {
2425 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2426 dest_scan ++;
2427 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2428 dest_scan ++;
2429 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2430 dest_scan ++;
2431 }
2432 }
2433 }
_CompositeRow_ByteMask2Rgb(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int pixel_count,int blend_type,int Bpp,FX_LPCBYTE clip_scan)2434 void _CompositeRow_ByteMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2435 int blend_type, int Bpp, FX_LPCBYTE clip_scan)
2436 {
2437 for (int col = 0; col < pixel_count; col ++) {
2438 int src_alpha;
2439 if (clip_scan) {
2440 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2441 } else {
2442 src_alpha = mask_alpha * src_scan[col] / 255;
2443 }
2444 if (src_alpha == 0) {
2445 dest_scan += Bpp;
2446 continue;
2447 }
2448 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2449 int blended_colors[3];
2450 FX_BYTE src_scan[3];
2451 src_scan[0] = src_b;
2452 src_scan[1] = src_g;
2453 src_scan[2] = src_r;
2454 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2455 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
2456 dest_scan ++;
2457 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
2458 dest_scan ++;
2459 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
2460 } else if (blend_type) {
2461 int blended = _BLEND(blend_type, *dest_scan, src_b);
2462 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2463 dest_scan ++;
2464 blended = _BLEND(blend_type, *dest_scan, src_g);
2465 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2466 dest_scan ++;
2467 blended = _BLEND(blend_type, *dest_scan, src_r);
2468 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2469 } else {
2470 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
2471 dest_scan ++;
2472 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
2473 dest_scan ++;
2474 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
2475 }
2476 dest_scan += Bpp - 2;
2477 }
2478 }
_CompositeRow_ByteMask2Mask(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int pixel_count,FX_LPCBYTE clip_scan)2479 void _CompositeRow_ByteMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int pixel_count,
2480 FX_LPCBYTE clip_scan)
2481 {
2482 for (int col = 0; col < pixel_count; col ++) {
2483 int src_alpha;
2484 if (clip_scan) {
2485 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2486 } else {
2487 src_alpha = mask_alpha * src_scan[col] / 255;
2488 }
2489 FX_BYTE back_alpha = *dest_scan;
2490 if (!back_alpha) {
2491 *dest_scan = src_alpha;
2492 } else if (src_alpha) {
2493 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2494 }
2495 dest_scan ++;
2496 }
2497 }
_CompositeRow_ByteMask2Gray(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_gray,int pixel_count,FX_LPCBYTE clip_scan)2498 void _CompositeRow_ByteMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2499 int pixel_count, FX_LPCBYTE clip_scan)
2500 {
2501 for (int col = 0; col < pixel_count; col ++) {
2502 int src_alpha;
2503 if (clip_scan) {
2504 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2505 } else {
2506 src_alpha = mask_alpha * src_scan[col] / 255;
2507 }
2508 if (src_alpha) {
2509 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
2510 }
2511 dest_scan ++;
2512 }
2513 }
_CompositeRow_ByteMask2Graya(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_gray,int pixel_count,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)2514 void _CompositeRow_ByteMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2515 int pixel_count, FX_LPCBYTE clip_scan,
2516 FX_LPBYTE dest_alpha_scan)
2517 {
2518 for (int col = 0; col < pixel_count; col ++) {
2519 int src_alpha;
2520 if (clip_scan) {
2521 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2522 } else {
2523 src_alpha = mask_alpha * src_scan[col] / 255;
2524 }
2525 FX_BYTE back_alpha = *dest_alpha_scan;
2526 if (back_alpha == 0) {
2527 *dest_scan ++ = src_gray;
2528 *dest_alpha_scan ++ = src_alpha;
2529 continue;
2530 }
2531 if (src_alpha == 0) {
2532 dest_scan ++;
2533 dest_alpha_scan ++;
2534 continue;
2535 }
2536 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2537 *dest_alpha_scan++ = dest_alpha;
2538 int alpha_ratio = src_alpha * 255 / dest_alpha;
2539 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
2540 dest_scan ++;
2541 }
2542 }
_CompositeRow_BitMask2Argb(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int src_left,int pixel_count,int blend_type,FX_LPCBYTE clip_scan)2543 void _CompositeRow_BitMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2544 int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
2545 {
2546 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2547 FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
2548 for (int col = 0; col < pixel_count; col ++) {
2549 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2550 FXARGB_SETDIB(dest_scan, argb);
2551 }
2552 dest_scan += 4;
2553 }
2554 return;
2555 }
2556 for (int col = 0; col < pixel_count; col ++) {
2557 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2558 dest_scan += 4;
2559 continue;
2560 }
2561 int src_alpha;
2562 if (clip_scan) {
2563 src_alpha = mask_alpha * clip_scan[col] / 255;
2564 } else {
2565 src_alpha = mask_alpha;
2566 }
2567 FX_BYTE back_alpha = dest_scan[3];
2568 if (back_alpha == 0) {
2569 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2570 dest_scan += 4;
2571 continue;
2572 }
2573 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2574 dest_scan[3] = dest_alpha;
2575 int alpha_ratio = src_alpha * 255 / dest_alpha;
2576 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2577 int blended_colors[3];
2578 FX_BYTE src_scan[3];
2579 src_scan[0] = src_b;
2580 src_scan[1] = src_g;
2581 src_scan[2] = src_r;
2582 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2583 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2584 dest_scan ++;
2585 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2586 dest_scan ++;
2587 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2588 } else if (blend_type) {
2589 int blended = _BLEND(blend_type, *dest_scan, src_b);
2590 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2591 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2592 dest_scan ++;
2593 blended = _BLEND(blend_type, *dest_scan, src_g);
2594 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2595 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2596 dest_scan ++;
2597 blended = _BLEND(blend_type, *dest_scan, src_r);
2598 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2599 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2600 } else {
2601 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2602 dest_scan ++;
2603 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2604 dest_scan ++;
2605 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2606 }
2607 dest_scan += 2;
2608 }
2609 }
_CompositeRow_BitMask2Rgba(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int src_left,int pixel_count,int blend_type,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)2610 void _CompositeRow_BitMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2611 int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
2612 FX_LPBYTE dest_alpha_scan)
2613 {
2614 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2615 for (int col = 0; col < pixel_count; col ++) {
2616 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2617 dest_scan[0] = src_b;
2618 dest_scan[1] = src_g;
2619 dest_scan[2] = src_r;
2620 *dest_alpha_scan = mask_alpha;
2621 }
2622 dest_scan += 3;
2623 dest_alpha_scan ++;
2624 }
2625 return;
2626 }
2627 for (int col = 0; col < pixel_count; col ++) {
2628 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2629 dest_scan += 3;
2630 dest_alpha_scan ++;
2631 continue;
2632 }
2633 int src_alpha;
2634 if (clip_scan) {
2635 src_alpha = mask_alpha * clip_scan[col] / 255;
2636 } else {
2637 src_alpha = mask_alpha;
2638 }
2639 FX_BYTE back_alpha = dest_scan[3];
2640 if (back_alpha == 0) {
2641 *dest_scan ++ = src_b;
2642 *dest_scan ++ = src_g;
2643 *dest_scan ++ = src_r;
2644 *dest_alpha_scan ++ = mask_alpha;
2645 continue;
2646 }
2647 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2648 *dest_alpha_scan ++ = dest_alpha;
2649 int alpha_ratio = src_alpha * 255 / dest_alpha;
2650 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2651 int blended_colors[3];
2652 FX_BYTE src_scan[3];
2653 src_scan[0] = src_b;
2654 src_scan[1] = src_g;
2655 src_scan[2] = src_r;
2656 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2657 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2658 dest_scan ++;
2659 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2660 dest_scan ++;
2661 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2662 dest_scan ++;
2663 } else if (blend_type) {
2664 int blended = _BLEND(blend_type, *dest_scan, src_b);
2665 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2666 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2667 dest_scan ++;
2668 blended = _BLEND(blend_type, *dest_scan, src_g);
2669 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2670 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2671 dest_scan ++;
2672 blended = _BLEND(blend_type, *dest_scan, src_r);
2673 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2674 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2675 dest_scan ++;
2676 } else {
2677 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2678 dest_scan ++;
2679 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2680 dest_scan ++;
2681 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2682 dest_scan ++;
2683 }
2684 }
2685 }
_CompositeRow_BitMask2Rgb(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int src_left,int pixel_count,int blend_type,int Bpp,FX_LPCBYTE clip_scan)2686 void _CompositeRow_BitMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2687 int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
2688 {
2689 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2690 for (int col = 0; col < pixel_count; col ++) {
2691 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2692 dest_scan[2] = src_r;
2693 dest_scan[1] = src_g;
2694 dest_scan[0] = src_b;
2695 }
2696 dest_scan += Bpp;
2697 }
2698 return;
2699 }
2700 for (int col = 0; col < pixel_count; col ++) {
2701 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2702 dest_scan += Bpp;
2703 continue;
2704 }
2705 int src_alpha;
2706 if (clip_scan) {
2707 src_alpha = mask_alpha * clip_scan[col] / 255;
2708 } else {
2709 src_alpha = mask_alpha;
2710 }
2711 if (src_alpha == 0) {
2712 dest_scan += Bpp;
2713 continue;
2714 }
2715 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2716 int blended_colors[3];
2717 FX_BYTE src_scan[3];
2718 src_scan[0] = src_b;
2719 src_scan[1] = src_g;
2720 src_scan[2] = src_r;
2721 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2722 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
2723 dest_scan ++;
2724 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
2725 dest_scan ++;
2726 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
2727 } else if (blend_type) {
2728 int blended = _BLEND(blend_type, *dest_scan, src_b);
2729 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2730 dest_scan++;
2731 blended = _BLEND(blend_type, *dest_scan, src_g);
2732 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2733 dest_scan++;
2734 blended = _BLEND(blend_type, *dest_scan, src_r);
2735 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2736 } else {
2737 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
2738 dest_scan ++;
2739 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
2740 dest_scan ++;
2741 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
2742 }
2743 dest_scan += Bpp - 2;
2744 }
2745 }
_CompositeRow_BitMask2Mask(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_left,int pixel_count,FX_LPCBYTE clip_scan)2746 void _CompositeRow_BitMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_left,
2747 int pixel_count, FX_LPCBYTE clip_scan)
2748 {
2749 for (int col = 0; col < pixel_count; col ++) {
2750 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2751 dest_scan ++;
2752 continue;
2753 }
2754 int src_alpha;
2755 if (clip_scan) {
2756 src_alpha = mask_alpha * clip_scan[col] / 255;
2757 } else {
2758 src_alpha = mask_alpha;
2759 }
2760 FX_BYTE back_alpha = *dest_scan;
2761 if (!back_alpha) {
2762 *dest_scan = src_alpha;
2763 } else if (src_alpha) {
2764 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2765 }
2766 dest_scan ++;
2767 }
2768 }
_CompositeRow_BitMask2Gray(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_gray,int src_left,int pixel_count,FX_LPCBYTE clip_scan)2769 void _CompositeRow_BitMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2770 int src_left, int pixel_count, FX_LPCBYTE clip_scan)
2771 {
2772 for (int col = 0; col < pixel_count; col ++) {
2773 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2774 dest_scan ++;
2775 continue;
2776 }
2777 int src_alpha;
2778 if (clip_scan) {
2779 src_alpha = mask_alpha * clip_scan[col] / 255;
2780 } else {
2781 src_alpha = mask_alpha;
2782 }
2783 if (src_alpha) {
2784 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
2785 }
2786 dest_scan ++;
2787 }
2788 }
_CompositeRow_BitMask2Graya(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_gray,int src_left,int pixel_count,FX_LPCBYTE clip_scan,FX_LPBYTE dest_alpha_scan)2789 void _CompositeRow_BitMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2790 int src_left, int pixel_count, FX_LPCBYTE clip_scan,
2791 FX_LPBYTE dest_alpha_scan)
2792 {
2793 for (int col = 0; col < pixel_count; col ++) {
2794 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2795 dest_scan ++;
2796 dest_alpha_scan ++;
2797 continue;
2798 }
2799 int src_alpha;
2800 if (clip_scan) {
2801 src_alpha = mask_alpha * clip_scan[col] / 255;
2802 } else {
2803 src_alpha = mask_alpha;
2804 }
2805 FX_BYTE back_alpha = *dest_alpha_scan;
2806 if (back_alpha == 0) {
2807 *dest_scan ++ = src_gray;
2808 *dest_alpha_scan ++ = src_alpha;
2809 continue;
2810 }
2811 if (src_alpha == 0) {
2812 dest_scan ++;
2813 dest_alpha_scan ++;
2814 continue;
2815 }
2816 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2817 *dest_alpha_scan++ = dest_alpha;
2818 int alpha_ratio = src_alpha * 255 / dest_alpha;
2819 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
2820 dest_scan ++;
2821 }
2822 }
_CompositeRow_Argb2Argb_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int pixel_count,int blend_type,FX_LPCBYTE clip_scan)2823 void _CompositeRow_Argb2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
2824 {
2825 int blended_colors[3];
2826 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2827 for (int col = 0; col < pixel_count; col ++) {
2828 FX_BYTE back_alpha = dest_scan[3];
2829 if (back_alpha == 0) {
2830 if (clip_scan) {
2831 int src_alpha = clip_scan[col] * src_scan[3] / 255;
2832 dest_scan[3] = src_alpha;
2833 dest_scan[0] = src_scan[2];
2834 dest_scan[1] = src_scan[1];
2835 dest_scan[2] = src_scan[0];
2836 } else {
2837 FXARGB_RGBORDERCOPY(dest_scan, src_scan);
2838 }
2839 dest_scan += 4;
2840 src_scan += 4;
2841 continue;
2842 }
2843 FX_BYTE src_alpha;
2844 if (clip_scan == NULL) {
2845 src_alpha = src_scan[3];
2846 } else {
2847 src_alpha = clip_scan[col] * src_scan[3] / 255;
2848 }
2849 if (src_alpha == 0) {
2850 dest_scan += 4;
2851 src_scan += 4;
2852 continue;
2853 }
2854 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2855 dest_scan[3] = dest_alpha;
2856 int alpha_ratio = src_alpha * 255 / dest_alpha;
2857 if (bNonseparableBlend) {
2858 FX_BYTE dest_scan_o[3];
2859 dest_scan_o[0] = dest_scan[2];
2860 dest_scan_o[1] = dest_scan[1];
2861 dest_scan_o[2] = dest_scan[0];
2862 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2863 }
2864 for (int color = 0; color < 3; color ++) {
2865 int index = 2 - color;
2866 if (blend_type) {
2867 int blended = bNonseparableBlend ? blended_colors[color] :
2868 _BLEND(blend_type, dest_scan[index], *src_scan);
2869 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
2870 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
2871 } else {
2872 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio);
2873 }
2874 src_scan ++;
2875 }
2876 dest_scan += 4;
2877 src_scan++;
2878 }
2879 }
_CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int src_Bpp)2880 void _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp)
2881 {
2882 int blended_colors[3];
2883 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2884 int src_gap = src_Bpp - 3;
2885 for (int col = 0; col < width; col ++) {
2886 FX_BYTE back_alpha = dest_scan[3];
2887 if (back_alpha == 0) {
2888 if (src_Bpp == 4) {
2889 FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
2890 } else {
2891 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
2892 }
2893 dest_scan += 4;
2894 src_scan += src_Bpp;
2895 continue;
2896 }
2897 dest_scan[3] = 0xff;
2898 if (bNonseparableBlend) {
2899 FX_BYTE dest_scan_o[3];
2900 dest_scan_o[0] = dest_scan[2];
2901 dest_scan_o[1] = dest_scan[1];
2902 dest_scan_o[2] = dest_scan[0];
2903 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2904 }
2905 for (int color = 0; color < 3; color ++) {
2906 int index = 2 - color;
2907 int src_color = FX_GAMMA(*src_scan);
2908 int blended = bNonseparableBlend ? blended_colors[color] :
2909 _BLEND(blend_type, dest_scan[index], src_color);
2910 dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
2911 src_scan ++;
2912 }
2913 dest_scan += 4;
2914 src_scan += src_gap;
2915 }
2916 }
_CompositeRow_Argb2Rgb_Blend_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,FX_LPCBYTE clip_scan)2917 inline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan)
2918 {
2919 int blended_colors[3];
2920 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2921 for (int col = 0; col < width; col ++) {
2922 FX_BYTE src_alpha;
2923 if (clip_scan) {
2924 src_alpha = src_scan[3] * (*clip_scan++) / 255;
2925 } else {
2926 src_alpha = src_scan[3];
2927 }
2928 if (src_alpha == 0) {
2929 dest_scan += dest_Bpp;
2930 src_scan += 4;
2931 continue;
2932 }
2933 if (bNonseparableBlend) {
2934 FX_BYTE dest_scan_o[3];
2935 dest_scan_o[0] = dest_scan[2];
2936 dest_scan_o[1] = dest_scan[1];
2937 dest_scan_o[2] = dest_scan[0];
2938 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2939 }
2940 for (int color = 0; color < 3; color ++) {
2941 int index = 2 - color;
2942 int back_color = FX_GAMMA(dest_scan[index]);
2943 int blended = bNonseparableBlend ? blended_colors[color] :
2944 _BLEND(blend_type, back_color, *src_scan);
2945 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
2946 src_scan ++;
2947 }
2948 dest_scan += dest_Bpp;
2949 src_scan ++;
2950 }
2951 }
_CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int src_Bpp)2952 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp)
2953 {
2954 int src_gap = src_Bpp - 3;
2955 for (int col = 0; col < width; col ++) {
2956 if (src_Bpp == 4) {
2957 FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
2958 } else {
2959 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
2960 }
2961 dest_scan += 4;
2962 src_scan += src_Bpp;
2963 }
2964 }
_CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,int src_Bpp)2965 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
2966 {
2967 int blended_colors[3];
2968 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2969 int src_gap = src_Bpp - 3;
2970 for (int col = 0; col < width; col ++) {
2971 if (bNonseparableBlend) {
2972 FX_BYTE dest_scan_o[3];
2973 dest_scan_o[0] = dest_scan[2];
2974 dest_scan_o[1] = dest_scan[1];
2975 dest_scan_o[2] = dest_scan[0];
2976 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2977 }
2978 for (int color = 0; color < 3; color ++) {
2979 int index = 2 - color;
2980 int back_color = FX_GAMMA(dest_scan[index]);
2981 int src_color = FX_GAMMA(*src_scan);
2982 int blended = bNonseparableBlend ? blended_colors[color] :
2983 _BLEND(blend_type, back_color, src_color);
2984 dest_scan[index] = FX_GAMMA_INVERSE(blended);
2985 src_scan ++;
2986 }
2987 dest_scan += dest_Bpp;
2988 src_scan += src_gap;
2989 }
2990 }
_CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,FX_LPCBYTE clip_scan)2991 inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan)
2992 {
2993 for (int col = 0; col < width; col ++) {
2994 FX_BYTE src_alpha;
2995 if (clip_scan) {
2996 src_alpha = src_scan[3] * (*clip_scan++) / 255;
2997 } else {
2998 src_alpha = src_scan[3];
2999 }
3000 if (src_alpha == 255) {
3001 dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++);
3002 dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++);
3003 dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++);
3004 dest_scan += dest_Bpp;
3005 src_scan ++;
3006 continue;
3007 }
3008 if (src_alpha == 0) {
3009 dest_scan += dest_Bpp;
3010 src_scan += 4;
3011 continue;
3012 }
3013 for (int color = 0; color < 3; color ++) {
3014 int index = 2 - color;
3015 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha));
3016 src_scan ++;
3017 }
3018 dest_scan += dest_Bpp;
3019 src_scan ++;
3020 }
3021 }
_CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,int src_Bpp)3022 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
3023 {
3024 for (int col = 0; col < width; col ++) {
3025 dest_scan[2] = src_scan[0];
3026 dest_scan[1] = src_scan[1];
3027 dest_scan[0] = src_scan[2];
3028 dest_scan += dest_Bpp;
3029 src_scan += src_Bpp;
3030 }
3031 }
_CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int src_Bpp,FX_LPCBYTE clip_scan)3032 inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan)
3033 {
3034 int blended_colors[3];
3035 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
3036 int src_gap = src_Bpp - 3;
3037 for (int col = 0; col < width; col ++) {
3038 int src_alpha = *clip_scan ++;
3039 FX_BYTE back_alpha = dest_scan[3];
3040 if (back_alpha == 0) {
3041 dest_scan[2] = FX_GAMMA(*src_scan++);
3042 dest_scan[1] = FX_GAMMA(*src_scan++);
3043 dest_scan[0] = FX_GAMMA(*src_scan++);
3044 src_scan += src_gap;
3045 dest_scan += 4;
3046 continue;
3047 }
3048 if (src_alpha == 0) {
3049 dest_scan += 4;
3050 src_scan += src_Bpp;
3051 continue;
3052 }
3053 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3054 dest_scan[3] = dest_alpha;
3055 int alpha_ratio = src_alpha * 255 / dest_alpha;
3056 if (bNonseparableBlend) {
3057 FX_BYTE dest_scan_o[3];
3058 dest_scan_o[0] = dest_scan[2];
3059 dest_scan_o[1] = dest_scan[1];
3060 dest_scan_o[2] = dest_scan[0];
3061 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3062 }
3063 for (int color = 0; color < 3; color ++) {
3064 int index = 2 - color;
3065 int src_color = FX_GAMMA(*src_scan);
3066 int blended = bNonseparableBlend ? blended_colors[color] :
3067 _BLEND(blend_type, dest_scan[index], src_color);
3068 blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
3069 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
3070 src_scan ++;
3071 }
3072 dest_scan += 4;
3073 src_scan += src_gap;
3074 }
3075 }
_CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int blend_type,int dest_Bpp,int src_Bpp,FX_LPCBYTE clip_scan)3076 inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
3077 {
3078 int blended_colors[3];
3079 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
3080 int src_gap = src_Bpp - 3;
3081 for (int col = 0; col < width; col ++) {
3082 FX_BYTE src_alpha = *clip_scan ++;
3083 if (src_alpha == 0) {
3084 dest_scan += dest_Bpp;
3085 src_scan += src_Bpp;
3086 continue;
3087 }
3088 if (bNonseparableBlend) {
3089 FX_BYTE dest_scan_o[3];
3090 dest_scan_o[0] = dest_scan[2];
3091 dest_scan_o[1] = dest_scan[1];
3092 dest_scan_o[2] = dest_scan[0];
3093 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3094 }
3095 for (int color = 0; color < 3; color ++) {
3096 int index = 2 - color;
3097 int src_color = FX_GAMMA(*src_scan);
3098 int back_color = FX_GAMMA(dest_scan[index]);
3099 int blended = bNonseparableBlend ? blended_colors[color] :
3100 _BLEND(blend_type, back_color, src_color);
3101 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3102 src_scan ++;
3103 }
3104 dest_scan += dest_Bpp;
3105 src_scan += src_gap;
3106 }
3107 }
_CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int src_Bpp,FX_LPCBYTE clip_scan)3108 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan)
3109 {
3110 int src_gap = src_Bpp - 3;
3111 for (int col = 0; col < width; col ++) {
3112 int src_alpha = clip_scan[col];
3113 if (src_alpha == 255) {
3114 dest_scan[2] = FX_GAMMA(*src_scan++);
3115 dest_scan[1] = FX_GAMMA(*src_scan++);
3116 dest_scan[0] = FX_GAMMA(*src_scan++);
3117 dest_scan[3] = 255;
3118 dest_scan += 4;
3119 src_scan += src_gap;
3120 continue;
3121 }
3122 if (src_alpha == 0) {
3123 dest_scan += 4;
3124 src_scan += src_Bpp;
3125 continue;
3126 }
3127 int back_alpha = dest_scan[3];
3128 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3129 dest_scan[3] = dest_alpha;
3130 int alpha_ratio = src_alpha * 255 / dest_alpha;
3131 for (int color = 0; color < 3; color ++) {
3132 int index = 2 - color;
3133 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio);
3134 src_scan ++;
3135 }
3136 dest_scan += 4;
3137 src_scan += src_gap;
3138 }
3139 }
_CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,int dest_Bpp,int src_Bpp,FX_LPCBYTE clip_scan)3140 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
3141 {
3142 for (int col = 0; col < width; col ++) {
3143 int src_alpha = clip_scan[col];
3144 if (src_alpha == 255) {
3145 dest_scan[2] = src_scan[0];
3146 dest_scan[1] = src_scan[1];
3147 dest_scan[0] = src_scan[2];
3148 } else if (src_alpha) {
3149 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha));
3150 src_scan ++;
3151 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha));
3152 src_scan ++;
3153 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha));
3154 dest_scan += dest_Bpp;
3155 src_scan += src_Bpp - 2;
3156 continue;
3157 }
3158 dest_scan += dest_Bpp;
3159 src_scan += src_Bpp;
3160 }
3161 }
_CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,FX_ARGB * pPalette,int pixel_count,int DestBpp,FX_LPCBYTE clip_scan)3162 inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_ARGB* pPalette, int pixel_count,
3163 int DestBpp, FX_LPCBYTE clip_scan)
3164 {
3165 for (int col = 0; col < pixel_count; col ++) {
3166 FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101;
3167 int src_r = FXARGB_R(argb);
3168 int src_g = FXARGB_G(argb);
3169 int src_b = FXARGB_B(argb);
3170 if (clip_scan && clip_scan[col] < 255) {
3171 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
3172 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
3173 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
3174 } else {
3175 dest_scan[2] = src_b;
3176 dest_scan[1] = src_g;
3177 dest_scan[0] = src_r;
3178 }
3179 dest_scan += DestBpp;
3180 src_scan ++;
3181 }
3182 }
_CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,FX_ARGB * pPalette,int pixel_count,int DestBpp,FX_LPCBYTE clip_scan)3183 inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
3184 FX_ARGB* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
3185 {
3186 int reset_r, reset_g, reset_b;
3187 int set_r, set_g, set_b;
3188 if (pPalette) {
3189 reset_r = FXARGB_R(pPalette[0]);
3190 reset_g = FXARGB_G(pPalette[0]);
3191 reset_b = FXARGB_B(pPalette[0]);
3192 set_r = FXARGB_R(pPalette[1]);
3193 set_g = FXARGB_G(pPalette[1]);
3194 set_b = FXARGB_B(pPalette[1]);
3195 } else {
3196 reset_r = reset_g = reset_b = 0;
3197 set_r = set_g = set_b = 255;
3198 }
3199 for (int col = 0; col < pixel_count; col ++) {
3200 int src_r, src_g, src_b;
3201 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
3202 src_r = set_r;
3203 src_g = set_g;
3204 src_b = set_b;
3205 } else {
3206 src_r = reset_r;
3207 src_g = reset_g;
3208 src_b = reset_b;
3209 }
3210 if (clip_scan && clip_scan[col] < 255) {
3211 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
3212 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
3213 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
3214 } else {
3215 dest_scan[2] = src_b;
3216 dest_scan[1] = src_g;
3217 dest_scan[0] = src_r;
3218 }
3219 dest_scan += DestBpp;
3220 }
3221 }
_CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,FX_ARGB * pPalette,FX_LPCBYTE clip_scan)3222 inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
3223 FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
3224 {
3225 for (int col = 0; col < width; col ++) {
3226 int src_r, src_g, src_b;
3227 if (pPalette) {
3228 FX_ARGB argb = pPalette[*src_scan];
3229 src_r = FXARGB_R(argb);
3230 src_g = FXARGB_G(argb);
3231 src_b = FXARGB_B(argb);
3232 } else {
3233 src_r = src_g = src_b = *src_scan;
3234 }
3235 if (clip_scan == NULL || clip_scan[col] == 255) {
3236 dest_scan[2] = FX_GAMMA(src_b);
3237 dest_scan[1] = FX_GAMMA(src_g);
3238 dest_scan[0] = FX_GAMMA(src_r);
3239 dest_scan[3] = 255;
3240 src_scan ++;
3241 dest_scan += 4;
3242 continue;
3243 }
3244 int src_alpha = clip_scan[col];
3245 if (src_alpha == 0) {
3246 dest_scan += 4;
3247 src_scan ++;
3248 continue;
3249 }
3250 int back_alpha = dest_scan[3];
3251 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3252 dest_scan[3] = dest_alpha;
3253 int alpha_ratio = src_alpha * 255 / dest_alpha;
3254 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
3255 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
3256 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
3257 dest_scan += 4;
3258 src_scan ++;
3259 }
3260 }
_CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,int width,FX_ARGB * pPalette,FX_LPCBYTE clip_scan)3261 inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
3262 FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
3263 {
3264 int reset_r, reset_g, reset_b;
3265 int set_r, set_g, set_b;
3266 if (pPalette) {
3267 reset_r = FXARGB_R(pPalette[0]);
3268 reset_g = FXARGB_G(pPalette[0]);
3269 reset_b = FXARGB_B(pPalette[0]);
3270 set_r = FXARGB_R(pPalette[1]);
3271 set_g = FXARGB_G(pPalette[1]);
3272 set_b = FXARGB_B(pPalette[1]);
3273 } else {
3274 reset_r = reset_g = reset_b = 0;
3275 set_r = set_g = set_b = 255;
3276 }
3277 for (int col = 0; col < width; col ++) {
3278 int src_r, src_g, src_b;
3279 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
3280 src_r = set_r;
3281 src_g = set_g;
3282 src_b = set_b;
3283 } else {
3284 src_r = reset_r;
3285 src_g = reset_g;
3286 src_b = reset_b;
3287 }
3288 if (clip_scan == NULL || clip_scan[col] == 255) {
3289 dest_scan[2] = FX_GAMMA(src_b);
3290 dest_scan[1] = FX_GAMMA(src_g);
3291 dest_scan[0] = FX_GAMMA(src_r);
3292 dest_scan[3] = 255;
3293 dest_scan += 4;
3294 continue;
3295 }
3296 int src_alpha = clip_scan[col];
3297 if (src_alpha == 0) {
3298 dest_scan += 4;
3299 continue;
3300 }
3301 int back_alpha = dest_scan[3];
3302 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3303 dest_scan[3] = dest_alpha;
3304 int alpha_ratio = src_alpha * 255 / dest_alpha;
3305 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
3306 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
3307 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
3308 dest_scan += 4;
3309 }
3310 }
_CompositeRow_ByteMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int pixel_count,int blend_type,FX_LPCBYTE clip_scan)3311 void _CompositeRow_ByteMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
3312 int blend_type, FX_LPCBYTE clip_scan)
3313 {
3314 for (int col = 0; col < pixel_count; col ++) {
3315 int src_alpha;
3316 if (clip_scan) {
3317 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
3318 } else {
3319 src_alpha = mask_alpha * src_scan[col] / 255;
3320 }
3321 FX_BYTE back_alpha = dest_scan[3];
3322 if (back_alpha == 0) {
3323 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
3324 dest_scan += 4;
3325 continue;
3326 }
3327 if (src_alpha == 0) {
3328 dest_scan += 4;
3329 continue;
3330 }
3331 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3332 dest_scan[3] = dest_alpha;
3333 int alpha_ratio = src_alpha * 255 / dest_alpha;
3334 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3335 int blended_colors[3];
3336 FX_BYTE src_scan[3];
3337 FX_BYTE dest_scan_o[3];
3338 src_scan[0] = src_b;
3339 src_scan[1] = src_g;
3340 src_scan[2] = src_r;
3341 dest_scan_o[0] = dest_scan[2];
3342 dest_scan_o[1] = dest_scan[1];
3343 dest_scan_o[2] = dest_scan[0];
3344 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3345 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
3346 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
3347 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
3348 } else if (blend_type) {
3349 int blended = _BLEND(blend_type, dest_scan[2], src_b);
3350 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
3351 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
3352 blended = _BLEND(blend_type, dest_scan[1], src_g);
3353 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
3354 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
3355 blended = _BLEND(blend_type, dest_scan[0], src_r);
3356 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
3357 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
3358 } else {
3359 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
3360 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
3361 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
3362 }
3363 dest_scan += 4;
3364 }
3365 }
_CompositeRow_ByteMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int pixel_count,int blend_type,int Bpp,FX_LPCBYTE clip_scan)3366 void _CompositeRow_ByteMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
3367 int blend_type, int Bpp, FX_LPCBYTE clip_scan)
3368 {
3369 for (int col = 0; col < pixel_count; col ++) {
3370 int src_alpha;
3371 if (clip_scan) {
3372 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
3373 } else {
3374 src_alpha = mask_alpha * src_scan[col] / 255;
3375 }
3376 if (src_alpha == 0) {
3377 dest_scan += Bpp;
3378 continue;
3379 }
3380 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3381 int blended_colors[3];
3382 FX_BYTE src_scan[3];
3383 FX_BYTE dest_scan_o[3];
3384 src_scan[0] = src_b;
3385 src_scan[1] = src_g;
3386 src_scan[2] = src_r;
3387 dest_scan_o[0] = dest_scan[2];
3388 dest_scan_o[1] = dest_scan[1];
3389 dest_scan_o[2] = dest_scan[0];
3390 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3391 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
3392 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
3393 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
3394 } else if (blend_type) {
3395 int blended = _BLEND(blend_type, dest_scan[2], src_b);
3396 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha);
3397 blended = _BLEND(blend_type, dest_scan[1], src_g);
3398 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha);
3399 blended = _BLEND(blend_type, dest_scan[0], src_r);
3400 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha);
3401 } else {
3402 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha);
3403 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha);
3404 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha);
3405 }
3406 dest_scan += Bpp;
3407 }
3408 }
_CompositeRow_BitMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int src_left,int pixel_count,int blend_type,FX_LPCBYTE clip_scan)3409 void _CompositeRow_BitMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
3410 int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
3411 {
3412 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
3413 FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
3414 for (int col = 0; col < pixel_count; col ++) {
3415 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
3416 FXARGB_SETRGBORDERDIB(dest_scan, argb);
3417 }
3418 dest_scan += 4;
3419 }
3420 return;
3421 }
3422 for (int col = 0; col < pixel_count; col ++) {
3423 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
3424 dest_scan += 4;
3425 continue;
3426 }
3427 int src_alpha;
3428 if (clip_scan) {
3429 src_alpha = mask_alpha * clip_scan[col] / 255;
3430 } else {
3431 src_alpha = mask_alpha;
3432 }
3433 FX_BYTE back_alpha = dest_scan[3];
3434 if (back_alpha == 0) {
3435 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
3436 dest_scan += 4;
3437 continue;
3438 }
3439 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3440 dest_scan[3] = dest_alpha;
3441 int alpha_ratio = src_alpha * 255 / dest_alpha;
3442 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3443 int blended_colors[3];
3444 FX_BYTE src_scan[3];
3445 FX_BYTE dest_scan_o[3];
3446 src_scan[0] = src_b;
3447 src_scan[1] = src_g;
3448 src_scan[2] = src_r;
3449 dest_scan_o[0] = dest_scan[2];
3450 dest_scan_o[1] = dest_scan[1];
3451 dest_scan_o[2] = dest_scan[0];
3452 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3453 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
3454 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
3455 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
3456 } else if (blend_type) {
3457 int blended = _BLEND(blend_type, dest_scan[2], src_b);
3458 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
3459 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
3460 blended = _BLEND(blend_type, dest_scan[1], src_g);
3461 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
3462 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
3463 blended = _BLEND(blend_type, dest_scan[0], src_r);
3464 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
3465 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
3466 } else {
3467 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
3468 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
3469 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
3470 }
3471 dest_scan += 4;
3472 }
3473 }
_CompositeRow_BitMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int mask_alpha,int src_r,int src_g,int src_b,int src_left,int pixel_count,int blend_type,int Bpp,FX_LPCBYTE clip_scan)3474 void _CompositeRow_BitMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
3475 int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
3476 {
3477 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
3478 for (int col = 0; col < pixel_count; col ++) {
3479 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
3480 dest_scan[2] = src_b;
3481 dest_scan[1] = src_g;
3482 dest_scan[0] = src_r;
3483 }
3484 dest_scan += Bpp;
3485 }
3486 return;
3487 }
3488 for (int col = 0; col < pixel_count; col ++) {
3489 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
3490 dest_scan += Bpp;
3491 continue;
3492 }
3493 int src_alpha;
3494 if (clip_scan) {
3495 src_alpha = mask_alpha * clip_scan[col] / 255;
3496 } else {
3497 src_alpha = mask_alpha;
3498 }
3499 if (src_alpha == 0) {
3500 dest_scan += Bpp;
3501 continue;
3502 }
3503 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3504 int blended_colors[3];
3505 FX_BYTE src_scan[3];
3506 FX_BYTE dest_scan_o[3];
3507 src_scan[0] = src_b;
3508 src_scan[1] = src_g;
3509 src_scan[2] = src_r;
3510 dest_scan_o[0] = dest_scan[2];
3511 dest_scan_o[1] = dest_scan[1];
3512 dest_scan_o[2] = dest_scan[0];
3513 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3514 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
3515 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
3516 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
3517 } else if (blend_type) {
3518 int back_color = FX_GAMMA(dest_scan[2]);
3519 int blended = _BLEND(blend_type, back_color, src_b);
3520 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3521 back_color = FX_GAMMA(dest_scan[1]);
3522 blended = _BLEND(blend_type, back_color, src_g);
3523 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3524 back_color = FX_GAMMA(dest_scan[0]);
3525 blended = _BLEND(blend_type, back_color, src_r);
3526 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3527 } else {
3528 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha));
3529 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha));
3530 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha));
3531 }
3532 dest_scan += Bpp;
3533 }
3534 }
_ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format,int alpha_flag,FX_DWORD mask_color,int & mask_alpha,int & mask_red,int & mask_green,int & mask_blue,int & mask_black,void * icc_module,void * pIccTransform)3535 inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, int alpha_flag, FX_DWORD mask_color, int& mask_alpha,
3536 int& mask_red, int& mask_green, int& mask_blue, int& mask_black,
3537 void* icc_module, void* pIccTransform)
3538 {
3539 ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
3540 if (alpha_flag >> 8) {
3541 mask_alpha = alpha_flag & 0xff;
3542 mask_red = FXSYS_GetCValue(mask_color);
3543 mask_green = FXSYS_GetMValue(mask_color);
3544 mask_blue = FXSYS_GetYValue(mask_color);
3545 mask_black = FXSYS_GetKValue(mask_color);
3546 } else {
3547 mask_alpha = FXARGB_A(mask_color);
3548 mask_red = FXARGB_R(mask_color);
3549 mask_green = FXARGB_G(mask_color);
3550 mask_blue = FXARGB_B(mask_color);
3551 }
3552 if (dest_format == FXDIB_8bppMask) {
3553 return TRUE;
3554 }
3555 if ((dest_format & 0xff) == 8) {
3556 if (pIccTransform) {
3557 mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
3558 FX_LPBYTE gray_p = (FX_LPBYTE)&mask_color;
3559 pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1);
3560 mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0];
3561 } else {
3562 if (alpha_flag >> 8) {
3563 FX_BYTE r, g, b;
3564 AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black,
3565 r, g, b);
3566 mask_red = FXRGB2GRAY(r, g, b);
3567 } else {
3568 mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue);
3569 }
3570 if (dest_format & 0x0400) {
3571 mask_red = FX_CCOLOR(mask_red);
3572 }
3573 }
3574 } else {
3575 FX_LPBYTE mask_color_p = (FX_LPBYTE)&mask_color;
3576 mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
3577 if (pIccTransform) {
3578 pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, 1);
3579 mask_red = mask_color_p[2];
3580 mask_green = mask_color_p[1];
3581 mask_blue = mask_color_p[0];
3582 } else if (alpha_flag >> 8) {
3583 AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], mask_color_p[3],
3584 mask_color_p[2], mask_color_p[1], mask_color_p[0]);
3585 mask_red = mask_color_p[2];
3586 mask_green = mask_color_p[1];
3587 mask_blue = mask_color_p[0];
3588 }
3589 }
3590 return TRUE;
3591 }
_ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format,FXDIB_Format dest_format,FX_DWORD * & pDestPalette,FX_DWORD * pSrcPalette,void * icc_module,void * pIccTransform)3592 inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, FXDIB_Format dest_format,
3593 FX_DWORD*& pDestPalette, FX_DWORD* pSrcPalette,
3594 void* icc_module, void* pIccTransform)
3595 {
3596 ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
3597 FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE;
3598 FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE;
3599 pDestPalette = NULL;
3600 if (pIccTransform) {
3601 if (pSrcPalette) {
3602 if ((dest_format & 0xff) == 8) {
3603 int pal_count = 1 << (src_format & 0xff);
3604 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3605 if (!gray_pal) {
3606 return;
3607 }
3608 pDestPalette = (FX_DWORD*)gray_pal;
3609 for (int i = 0; i < pal_count; i ++) {
3610 FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
3611 pIccModule->TranslateScanline(pIccTransform, gray_pal, (FX_LPCBYTE)&color, 1);
3612 gray_pal ++;
3613 }
3614 } else {
3615 int palsize = 1 << (src_format & 0xff);
3616 pDestPalette = FX_Alloc(FX_DWORD, palsize);
3617 if (!pDestPalette) {
3618 return;
3619 }
3620 for (int i = 0; i < palsize; i ++) {
3621 FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
3622 pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&color, (FX_LPCBYTE)&color, 1);
3623 pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
3624 }
3625 }
3626 } else {
3627 int pal_count = 1 << (src_format & 0xff);
3628 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3629 if (!gray_pal) {
3630 return;
3631 }
3632 if (pal_count == 2) {
3633 gray_pal[0] = 0;
3634 gray_pal[1] = 255;
3635 } else {
3636 for (int i = 0; i < pal_count; i++) {
3637 gray_pal[i] = i;
3638 }
3639 }
3640 if ((dest_format & 0xff) == 8) {
3641 pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, pal_count);
3642 pDestPalette = (FX_DWORD*)gray_pal;
3643 } else {
3644 pDestPalette = FX_Alloc(FX_DWORD, pal_count);
3645 if (!pDestPalette) {
3646 FX_Free(gray_pal);
3647 return;
3648 }
3649 for (int i = 0; i < pal_count; i ++) {
3650 pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&pDestPalette[i], &gray_pal[i], 1);
3651 pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) : FXARGB_TODIB(pDestPalette[i]);
3652 }
3653 FX_Free(gray_pal);
3654 }
3655 }
3656 } else {
3657 if (pSrcPalette) {
3658 if ((dest_format & 0xff) == 8) {
3659 int pal_count = 1 << (src_format & 0xff);
3660 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3661 if (!gray_pal) {
3662 return;
3663 }
3664 pDestPalette = (FX_DWORD*)gray_pal;
3665 if (isSrcCmyk) {
3666 for (int i = 0; i < pal_count; i ++) {
3667 FX_CMYK cmyk = pSrcPalette[i];
3668 FX_BYTE r, g, b;
3669 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3670 r, g, b);
3671 *gray_pal ++ = FXRGB2GRAY(r, g, b);
3672 }
3673 } else
3674 for (int i = 0; i < pal_count; i ++) {
3675 FX_ARGB argb = pSrcPalette[i];
3676 *gray_pal ++ = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
3677 }
3678 } else {
3679 int palsize = 1 << (src_format & 0xff);
3680 pDestPalette = FX_Alloc(FX_DWORD, palsize);
3681 if (!pDestPalette) {
3682 return;
3683 }
3684 if (isDstCmyk == isSrcCmyk) {
3685 FXSYS_memcpy32(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD));
3686 } else {
3687 for (int i = 0; i < palsize; i ++) {
3688 FX_CMYK cmyk = pSrcPalette[i];
3689 FX_BYTE r, g, b;
3690 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3691 r, g, b);
3692 pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
3693 }
3694 }
3695 }
3696 } else {
3697 if ((dest_format & 0xff) == 8) {
3698 int pal_count = 1 << (src_format & 0xff);
3699 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3700 if (!gray_pal) {
3701 return;
3702 }
3703 if (pal_count == 2) {
3704 gray_pal[0] = 0;
3705 gray_pal[1] = 255;
3706 } else {
3707 for (int i = 0; i < pal_count; i++) {
3708 gray_pal[i] = i;
3709 }
3710 }
3711 pDestPalette = (FX_DWORD*)gray_pal;
3712 } else {
3713 int palsize = 1 << (src_format & 0xff);
3714 pDestPalette = FX_Alloc(FX_DWORD, palsize);
3715 if (!pDestPalette) {
3716 return;
3717 }
3718 if (palsize == 2) {
3719 pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000;
3720 pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff;
3721 } else {
3722 for (int i = 0; i < palsize; i++) {
3723 pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101);
3724 }
3725 }
3726 if (isSrcCmyk != isDstCmyk) {
3727 for (int i = 0; i < palsize; i ++) {
3728 FX_CMYK cmyk = pDestPalette[i];
3729 FX_BYTE r, g, b;
3730 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3731 r, g, b);
3732 pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
3733 }
3734 }
3735 }
3736 }
3737 }
3738 }
CFX_ScanlineCompositor()3739 CFX_ScanlineCompositor::CFX_ScanlineCompositor()
3740 {
3741 m_pSrcPalette = NULL;
3742 m_pCacheScanline = NULL;
3743 m_CacheSize = 0;
3744 m_bRgbByteOrder = FALSE;
3745 m_BlendType = FXDIB_BLEND_NORMAL;
3746 }
~CFX_ScanlineCompositor()3747 CFX_ScanlineCompositor::~CFX_ScanlineCompositor()
3748 {
3749 if (m_pSrcPalette) {
3750 FX_Free(m_pSrcPalette);
3751 }
3752 if (m_pCacheScanline) {
3753 FX_Free(m_pCacheScanline);
3754 }
3755 }
Init(FXDIB_Format dest_format,FXDIB_Format src_format,FX_INT32 width,FX_DWORD * pSrcPalette,FX_DWORD mask_color,int blend_type,FX_BOOL bClip,FX_BOOL bRgbByteOrder,int alpha_flag,void * pIccTransform)3756 FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, FXDIB_Format src_format, FX_INT32 width, FX_DWORD* pSrcPalette,
3757 FX_DWORD mask_color, int blend_type, FX_BOOL bClip, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
3758 {
3759 m_SrcFormat = src_format;
3760 m_DestFormat = dest_format;
3761 m_BlendType = blend_type;
3762 m_bRgbByteOrder = bRgbByteOrder;
3763 ICodec_IccModule* pIccModule = NULL;
3764 if (CFX_GEModule::Get()->GetCodecModule()) {
3765 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
3766 }
3767 if (pIccModule == NULL) {
3768 pIccTransform = NULL;
3769 }
3770 m_pIccTransform = pIccTransform;
3771 if ((dest_format & 0xff) == 1) {
3772 return FALSE;
3773 }
3774 if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) {
3775 return _ScanlineCompositor_InitSourceMask(dest_format, alpha_flag, mask_color,
3776 m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack,
3777 pIccModule, pIccTransform);
3778 }
3779 if (pIccTransform == NULL && (~src_format & 0x0400) && (dest_format & 0x0400)) {
3780 return FALSE;
3781 }
3782 if ((m_SrcFormat & 0xff) <= 8) {
3783 if (dest_format == FXDIB_8bppMask) {
3784 return TRUE;
3785 }
3786 _ScanlineCompositor_InitSourcePalette(src_format, dest_format, m_pSrcPalette, pSrcPalette,
3787 pIccModule, pIccTransform);
3788 m_Transparency = (dest_format == FXDIB_Argb ? 1 : 0)
3789 + (dest_format & 0x0200 ? 2 : 0)
3790 + (dest_format & 0x0400 ? 4 : 0)
3791 + ((src_format & 0xff) == 1 ? 8 : 0);
3792 return TRUE;
3793 }
3794 m_Transparency = (src_format & 0x0200 ? 0 : 1)
3795 + (dest_format & 0x0200 ? 0 : 2)
3796 + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0)
3797 + (bClip ? 8 : 0)
3798 + (src_format & 0x0400 ? 16 : 0)
3799 + (dest_format & 0x0400 ? 32 : 0)
3800 + (pIccTransform ? 64 : 0);
3801 return TRUE;
3802 }
CompositeRgbBitmapLine(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,FX_LPCBYTE clip_scan,FX_LPCBYTE src_extra_alpha,FX_LPBYTE dst_extra_alpha)3803 void CFX_ScanlineCompositor::CompositeRgbBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
3804 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
3805 {
3806 int src_Bpp = (m_SrcFormat & 0xff) >> 3;
3807 int dest_Bpp = (m_DestFormat & 0xff) >> 3;
3808 int dest_Size = width * dest_Bpp + 4;
3809 if (m_bRgbByteOrder) {
3810 switch (m_Transparency) {
3811 case 0:
3812 case 4:
3813 case 8:
3814 case 12:
3815 _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, clip_scan);
3816 break;
3817 case 1:
3818 _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp);
3819 break;
3820 case 2:
3821 case 10:
3822 _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
3823 break;
3824 case 3:
3825 _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
3826 break;
3827 case 5:
3828 _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp);
3829 break;
3830 case 6:
3831 case 14:
3832 _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, clip_scan);
3833 break;
3834 case 7:
3835 _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
3836 break;
3837 case 9:
3838 _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
3839 break;
3840 case 11:
3841 _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
3842 break;
3843 case 13:
3844 _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp, clip_scan);
3845 break;
3846 case 15:
3847 _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
3848 break;
3849 }
3850 return;
3851 }
3852 if (m_DestFormat == FXDIB_8bppMask) {
3853 if (m_SrcFormat & 0x0200) {
3854 if (m_SrcFormat == FXDIB_Argb) {
3855 _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan);
3856 } else {
3857 _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan);
3858 }
3859 } else {
3860 _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
3861 }
3862 } else if ((m_DestFormat & 0xff) == 8) {
3863 if (m_DestFormat & 0x0400) {
3864 for (int i = 0; i < width; i ++) {
3865 *dest_scan = ~*dest_scan;
3866 dest_scan++;
3867 }
3868 }
3869 if (m_SrcFormat & 0x0200) {
3870 if (m_DestFormat & 0x0200) {
3871 _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, dst_extra_alpha, m_pIccTransform);
3872 } else {
3873 _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, m_pIccTransform);
3874 }
3875 } else {
3876 if (m_DestFormat & 0x0200) {
3877 _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, dst_extra_alpha, m_pIccTransform);
3878 } else {
3879 _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, m_pIccTransform);
3880 }
3881 }
3882 if (m_DestFormat & 0x0400) {
3883 for (int i = 0; i < width; i ++) {
3884 *dest_scan = ~*dest_scan;
3885 dest_scan++;
3886 }
3887 }
3888 } else {
3889 if (dest_Size > m_CacheSize) {
3890 m_pCacheScanline = FX_Realloc(FX_BYTE, m_pCacheScanline, dest_Size);
3891 if (!m_pCacheScanline) {
3892 return;
3893 }
3894 m_CacheSize = dest_Size;
3895 }
3896 switch (m_Transparency) {
3897 case 0:
3898 case 4:
3899 case 8:
3900 case 4+8: {
3901 _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, clip_scan,
3902 dst_extra_alpha, src_extra_alpha);
3903 }
3904 break;
3905 case 64:
3906 case 4+64:
3907 case 8+64:
3908 case 4+8+64: {
3909 _CompositeRow_Argb2Argb_Transform(dest_scan, src_scan, width, m_BlendType, clip_scan,
3910 dst_extra_alpha, src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3911 }
3912 break;
3913 case 1:
3914 _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, src_Bpp,
3915 dst_extra_alpha);
3916 break;
3917 case 1+64:
3918 _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp,
3919 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3920 break;
3921 case 1+8:
3922 _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
3923 dst_extra_alpha);
3924 break;
3925 case 1+8+64:
3926 _CompositeRow_Rgb2Argb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
3927 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3928 break;
3929 case 1+4:
3930 _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp,
3931 dst_extra_alpha);
3932 break;
3933 case 1+4+64:
3934 _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, src_Bpp,
3935 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3936 break;
3937 case 1+4+8:
3938 _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, clip_scan,
3939 dst_extra_alpha);
3940 break;
3941 case 1+4+8+64:
3942 _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(dest_scan, src_scan, width, src_Bpp, clip_scan,
3943 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3944 break;
3945 case 2:
3946 case 2+8:
3947 _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
3948 src_extra_alpha);
3949 break;
3950 case 2+64:
3951 case 2+8+64:
3952 _CompositeRow_Argb2Rgb_Blend_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
3953 src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3954 break;
3955 case 2+4:
3956 case 2+4+8:
3957 _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, clip_scan,
3958 src_extra_alpha);
3959 break;
3960 case 2+4+64:
3961 case 2+4+8+64:
3962 _CompositeRow_Argb2Rgb_NoBlend_Transform(dest_scan, src_scan, width, dest_Bpp, clip_scan,
3963 src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3964 break;
3965 case 1+2:
3966 _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
3967 break;
3968 case 1+2+64:
3969 _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
3970 m_pCacheScanline, m_pIccTransform);
3971 break;
3972 case 1+2+8:
3973 _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
3974 break;
3975 case 1+2+8+64:
3976 _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan,
3977 m_pCacheScanline, m_pIccTransform);
3978 break;
3979 case 1+2+4:
3980 _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
3981 break;
3982 case 1+2+4+64:
3983 _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp,
3984 m_pCacheScanline, m_pIccTransform);
3985 break;
3986 case 1+2+4+8:
3987 _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
3988 break;
3989 case 1+2+4+8+64:
3990 _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan,
3991 m_pCacheScanline, m_pIccTransform);
3992 break;
3993 }
3994 }
3995 }
CompositePalBitmapLine(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,int width,FX_LPCBYTE clip_scan,FX_LPCBYTE src_extra_alpha,FX_LPBYTE dst_extra_alpha)3996 void CFX_ScanlineCompositor::CompositePalBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
3997 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
3998 {
3999 if (m_bRgbByteOrder) {
4000 if (m_SrcFormat == FXDIB_1bppRgb) {
4001 if (m_DestFormat == FXDIB_8bppRgb) {
4002 return;
4003 } else if(m_DestFormat == FXDIB_Argb) {
4004 _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
4005 } else {
4006 _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4007 }
4008 } else {
4009 if (m_DestFormat == FXDIB_8bppRgb) {
4010 return;
4011 } else if (m_DestFormat == FXDIB_Argb) {
4012 _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, m_pSrcPalette, clip_scan);
4013 } else {
4014 _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4015 }
4016 }
4017 return;
4018 }
4019 if (m_DestFormat == FXDIB_8bppMask) {
4020 _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
4021 return;
4022 } else if ((m_DestFormat & 0xff) == 8) {
4023 if (m_Transparency & 8) {
4024 if (m_DestFormat & 0x0200) {
4025 _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, dst_extra_alpha);
4026 } else {
4027 _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan);
4028 }
4029 } else {
4030 if (m_DestFormat & 0x0200)
4031 _CompositeRow_8bppPal2Graya(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
4032 dst_extra_alpha, src_extra_alpha);
4033 else
4034 _CompositeRow_8bppPal2Gray(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
4035 src_extra_alpha);
4036 }
4037 } else {
4038 switch (m_Transparency) {
4039 case 1+2:
4040 _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, m_pSrcPalette, clip_scan,
4041 src_extra_alpha);
4042 break;
4043 case 1+2+8:
4044 _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
4045 break;
4046 case 0:
4047 _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
4048 src_extra_alpha);
4049 break;
4050 case 0+8:
4051 _CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4052 break;
4053 case 0+2:
4054 _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
4055 src_extra_alpha);
4056 break;
4057 case 0+2+8:
4058 _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan,
4059 dst_extra_alpha);
4060 break;
4061 break;
4062 }
4063 }
4064 }
CompositeByteMaskLine(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int width,FX_LPCBYTE clip_scan,FX_LPBYTE dst_extra_alpha)4065 void CFX_ScanlineCompositor::CompositeByteMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
4066 FX_LPBYTE dst_extra_alpha)
4067 {
4068 if (m_DestFormat == FXDIB_8bppMask) {
4069 _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, clip_scan);
4070 } else if ((m_DestFormat & 0xff) == 8) {
4071 if (m_DestFormat & 0x0200) {
4072 _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan, dst_extra_alpha);
4073 } else {
4074 _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan);
4075 }
4076 } else if (m_bRgbByteOrder) {
4077 if (m_DestFormat == FXDIB_Argb)
4078 _CompositeRow_ByteMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4079 width, m_BlendType, clip_scan);
4080 else
4081 _CompositeRow_ByteMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4082 width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4083 return;
4084 } else if (m_DestFormat == FXDIB_Argb)
4085 _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4086 width, m_BlendType, clip_scan);
4087 else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
4088 _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4089 width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4090 else if (m_DestFormat == FXDIB_Rgba)
4091 _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4092 width, m_BlendType, clip_scan, dst_extra_alpha);
4093 }
CompositeBitMaskLine(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int src_left,int width,FX_LPCBYTE clip_scan,FX_LPBYTE dst_extra_alpha)4094 void CFX_ScanlineCompositor::CompositeBitMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
4095 FX_LPBYTE dst_extra_alpha)
4096 {
4097 if (m_DestFormat == FXDIB_8bppMask) {
4098 _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width, clip_scan);
4099 } else if ((m_DestFormat & 0xff) == 8) {
4100 if (m_DestFormat & 0x0200)
4101 _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan,
4102 dst_extra_alpha);
4103 else {
4104 _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan);
4105 }
4106 } else if (m_bRgbByteOrder) {
4107 if (m_DestFormat == FXDIB_Argb)
4108 _CompositeRow_BitMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4109 src_left, width, m_BlendType, clip_scan);
4110 else
4111 _CompositeRow_BitMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4112 src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4113 return;
4114 } else if (m_DestFormat == FXDIB_Argb)
4115 _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4116 src_left, width, m_BlendType, clip_scan);
4117 else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
4118 _CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4119 src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4120 }
CompositeBitmap(int dest_left,int dest_top,int width,int height,const CFX_DIBSource * pSrcBitmap,int src_left,int src_top,int blend_type,const CFX_ClipRgn * pClipRgn,FX_BOOL bRgbByteOrder,void * pIccTransform)4121 FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, int dest_top, int width, int height,
4122 const CFX_DIBSource* pSrcBitmap, int src_left, int src_top,
4123 int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, void* pIccTransform)
4124 {
4125 if (m_pBuffer == NULL) {
4126 return FALSE;
4127 }
4128 ASSERT(!pSrcBitmap->IsAlphaMask());
4129 ASSERT(m_bpp >= 8);
4130 if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) {
4131 return FALSE;
4132 }
4133 GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
4134 src_left, src_top, pClipRgn);
4135 if (width == 0 || height == 0) {
4136 return TRUE;
4137 }
4138 const CFX_DIBitmap* pClipMask = NULL;
4139 FX_RECT clip_box;
4140 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4141 ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
4142 pClipMask = pClipRgn->GetMask();
4143 clip_box = pClipRgn->GetBox();
4144 }
4145 CFX_ScanlineCompositor compositor;
4146 if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, pSrcBitmap->GetPalette(), 0, blend_type,
4147 pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) {
4148 return FALSE;
4149 }
4150 int dest_Bpp = m_bpp / 8;
4151 int src_Bpp = pSrcBitmap->GetBPP() / 8;
4152 FX_BOOL bRgb = FALSE;
4153 FX_BOOL bCmyk = FALSE;
4154 if (src_Bpp > 1) {
4155 if (pSrcBitmap->IsCmykImage()) {
4156 bCmyk = TRUE;
4157 } else {
4158 bRgb = TRUE;
4159 }
4160 }
4161 CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask;
4162 for (int row = 0; row < height; row ++) {
4163 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
4164 FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp;
4165 FX_LPCBYTE src_scan_extra_alpha = pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left : NULL;
4166 FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
4167 FX_LPCBYTE clip_scan = NULL;
4168 if (pClipMask) {
4169 clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
4170 }
4171 if (bRgb) {
4172 compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
4173 } else {
4174 compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
4175 }
4176 }
4177 return TRUE;
4178 }
CompositeMask(int dest_left,int dest_top,int width,int height,const CFX_DIBSource * pMask,FX_DWORD color,int src_left,int src_top,int blend_type,const CFX_ClipRgn * pClipRgn,FX_BOOL bRgbByteOrder,int alpha_flag,void * pIccTransform)4179 FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, int dest_top, int width, int height,
4180 const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top,
4181 int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
4182 {
4183 if (m_pBuffer == NULL) {
4184 return FALSE;
4185 }
4186 ASSERT(pMask->IsAlphaMask());
4187 ASSERT(m_bpp >= 8);
4188 if (!pMask->IsAlphaMask() || m_bpp < 8) {
4189 return FALSE;
4190 }
4191 GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, pClipRgn);
4192 if (width == 0 || height == 0) {
4193 return TRUE;
4194 }
4195 int src_alpha = (FX_BYTE)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
4196 if (src_alpha == 0) {
4197 return TRUE;
4198 }
4199 const CFX_DIBitmap* pClipMask = NULL;
4200 FX_RECT clip_box;
4201 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4202 ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
4203 pClipMask = pClipRgn->GetMask();
4204 clip_box = pClipRgn->GetBox();
4205 }
4206 int src_bpp = pMask->GetBPP();
4207 int Bpp = GetBPP() / 8;
4208 CFX_ScanlineCompositor compositor;
4209 if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, pIccTransform)) {
4210 return FALSE;
4211 }
4212 for (int row = 0; row < height; row ++) {
4213 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
4214 FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
4215 FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
4216 FX_LPCBYTE clip_scan = NULL;
4217 if (pClipMask) {
4218 clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
4219 }
4220 if (src_bpp == 1) {
4221 compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, clip_scan, dst_scan_extra_alpha);
4222 } else {
4223 compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, clip_scan, dst_scan_extra_alpha);
4224 }
4225 }
4226 return TRUE;
4227 }
CompositeRect(int left,int top,int width,int height,FX_DWORD color,int alpha_flag,void * pIccTransform)4228 FX_BOOL CFX_DIBitmap::CompositeRect(int left, int top, int width, int height, FX_DWORD color, int alpha_flag, void* pIccTransform)
4229 {
4230 if (m_pBuffer == NULL) {
4231 return FALSE;
4232 }
4233 int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
4234 if (src_alpha == 0) {
4235 return TRUE;
4236 }
4237 FX_RECT rect(left, top, left + width, top + height);
4238 rect.Intersect(0, 0, m_Width, m_Height);
4239 if (rect.IsEmpty()) {
4240 return TRUE;
4241 }
4242 width = rect.Width();
4243 FX_DWORD dst_color;
4244 if (alpha_flag >> 8) {
4245 dst_color = FXCMYK_TODIB(color);
4246 } else {
4247 dst_color = FXARGB_TODIB(color);
4248 }
4249 FX_LPBYTE color_p = (FX_LPBYTE)&dst_color;
4250 if (m_bpp == 8) {
4251 FX_BYTE gray = 255;
4252 if (!IsAlphaMask()) {
4253 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
4254 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
4255 pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1);
4256 } else {
4257 if (alpha_flag >> 8) {
4258 FX_BYTE r, g, b;
4259 AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3],
4260 r, g, b);
4261 gray = FXRGB2GRAY(r, g, b);
4262 } else {
4263 gray = (FX_BYTE)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]);
4264 }
4265 }
4266 if (IsCmykImage()) {
4267 gray = ~gray;
4268 }
4269 }
4270 for (int row = rect.top; row < rect.bottom; row ++) {
4271 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left;
4272 if (src_alpha == 255) {
4273 FXSYS_memset8(dest_scan, gray, width);
4274 } else
4275 for (int col = 0; col < width; col ++) {
4276 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
4277 dest_scan ++;
4278 }
4279 }
4280 return TRUE;
4281 } else if (m_bpp == 1) {
4282 ASSERT(!IsCmykImage() && (FX_BYTE)(alpha_flag >> 8) == 0);
4283 int left_shift = rect.left % 8;
4284 int right_shift = rect.right % 8;
4285 int width = rect.right / 8 - rect.left / 8;
4286 int index = 0;
4287 if (m_pPalette == NULL) {
4288 index = ((FX_BYTE)color == 0xff) ? 1 : 0;
4289 } else {
4290 for (int i = 0; i < 2; i ++)
4291 if (m_pPalette[i] == color) {
4292 index = i;
4293 }
4294 }
4295 for (int row = rect.top; row < rect.bottom; row ++) {
4296 FX_BYTE* dest_scan_top = (FX_BYTE*)GetScanline(row) + rect.left / 8;
4297 FX_BYTE* dest_scan_top_r = (FX_BYTE*)GetScanline(row) + rect.right / 8;
4298 FX_BYTE left_flag = *dest_scan_top & (255 << (8 - left_shift));
4299 FX_BYTE right_flag = *dest_scan_top_r & (255 >> right_shift);
4300 if (width) {
4301 FXSYS_memset8(dest_scan_top + 1, index ? 255 : 0, width - 1);
4302 if (!index) {
4303 *dest_scan_top &= left_flag;
4304 *dest_scan_top_r &= right_flag;
4305 } else {
4306 *dest_scan_top |= ~left_flag;
4307 *dest_scan_top_r |= ~right_flag;
4308 }
4309 } else {
4310 if (!index) {
4311 *dest_scan_top &= left_flag | right_flag;
4312 } else {
4313 *dest_scan_top |= ~(left_flag | right_flag);
4314 }
4315 }
4316 }
4317 return TRUE;
4318 }
4319 ASSERT(m_bpp >= 24);
4320 if (m_bpp < 24) {
4321 return FALSE;
4322 }
4323 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) {
4324 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
4325 pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
4326 } else {
4327 if (alpha_flag >> 8 && !IsCmykImage())
4328 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color),
4329 color_p[2], color_p[1], color_p[0]);
4330 else if (!(alpha_flag >> 8) && IsCmykImage()) {
4331 return FALSE;
4332 }
4333 }
4334 if(!IsCmykImage()) {
4335 color_p[3] = (FX_BYTE)src_alpha;
4336 }
4337 int Bpp = m_bpp / 8;
4338 FX_BOOL bAlpha = HasAlpha();
4339 FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE;
4340 if (src_alpha == 255) {
4341 for (int row = rect.top; row < rect.bottom; row ++) {
4342 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
4343 FX_LPBYTE dest_scan_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left : NULL;
4344 if (dest_scan_alpha) {
4345 FXSYS_memset8(dest_scan_alpha, 0xff, width);
4346 }
4347 if (Bpp == 4) {
4348 FX_DWORD* scan = (FX_DWORD*)dest_scan;
4349 for (int col = 0; col < width; col ++) {
4350 *scan ++ = dst_color;
4351 }
4352 } else {
4353 for (int col = 0; col < width; col ++) {
4354 *dest_scan ++ = color_p[0];
4355 *dest_scan ++ = color_p[1];
4356 *dest_scan ++ = color_p[2];
4357 }
4358 }
4359 }
4360 return TRUE;
4361 }
4362 for (int row = rect.top; row < rect.bottom; row ++) {
4363 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
4364 if (bAlpha) {
4365 if (bArgb) {
4366 for (int col = 0; col < width; col ++) {
4367 FX_BYTE back_alpha = dest_scan[3];
4368 if (back_alpha == 0) {
4369 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], color_p[1], color_p[0]));
4370 dest_scan += 4;
4371 continue;
4372 }
4373 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
4374 int alpha_ratio = src_alpha * 255 / dest_alpha;
4375 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio);
4376 dest_scan ++;
4377 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio);
4378 dest_scan ++;
4379 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio);
4380 dest_scan ++;
4381 *dest_scan++ = dest_alpha;
4382 }
4383 } else {
4384 FX_LPBYTE dest_scan_alpha = (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left;
4385 for (int col = 0; col < width; col ++) {
4386 FX_BYTE back_alpha = *dest_scan_alpha;
4387 if (back_alpha == 0) {
4388 *dest_scan_alpha++ = src_alpha;
4389 FXSYS_memcpy32(dest_scan, color_p, Bpp);
4390 dest_scan += Bpp;
4391 continue;
4392 }
4393 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
4394 *dest_scan_alpha ++ = dest_alpha;
4395 int alpha_ratio = src_alpha * 255 / dest_alpha;
4396 for(int comps = 0; comps < Bpp; comps ++) {
4397 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio);
4398 dest_scan ++;
4399 }
4400 }
4401 }
4402 } else {
4403 for (int col = 0; col < width; col ++) {
4404 for(int comps = 0; comps < Bpp; comps ++) {
4405 if (comps == 3) {
4406 *dest_scan ++ = 255;
4407 continue;
4408 }
4409 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
4410 dest_scan ++;
4411 }
4412 }
4413 }
4414 }
4415 return TRUE;
4416 }
CFX_BitmapComposer()4417 CFX_BitmapComposer::CFX_BitmapComposer()
4418 {
4419 m_pScanlineV = NULL;
4420 m_pScanlineAlphaV = NULL;
4421 m_pClipScanV = NULL;
4422 m_pAddClipScan = NULL;
4423 m_bRgbByteOrder = FALSE;
4424 m_BlendType = FXDIB_BLEND_NORMAL;
4425 }
~CFX_BitmapComposer()4426 CFX_BitmapComposer::~CFX_BitmapComposer()
4427 {
4428 if (m_pScanlineV) {
4429 FX_Free(m_pScanlineV);
4430 }
4431 if (m_pScanlineAlphaV) {
4432 FX_Free(m_pScanlineAlphaV);
4433 }
4434 if (m_pClipScanV) {
4435 FX_Free(m_pClipScanV);
4436 }
4437 if (m_pAddClipScan) {
4438 FX_Free(m_pAddClipScan);
4439 }
4440 }
Compose(CFX_DIBitmap * pDest,const CFX_ClipRgn * pClipRgn,int bitmap_alpha,FX_DWORD mask_color,FX_RECT & dest_rect,FX_BOOL bVertical,FX_BOOL bFlipX,FX_BOOL bFlipY,FX_BOOL bRgbByteOrder,int alpha_flag,void * pIccTransform,int blend_type)4441 void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, const CFX_ClipRgn* pClipRgn, int bitmap_alpha,
4442 FX_DWORD mask_color, FX_RECT& dest_rect, FX_BOOL bVertical,
4443 FX_BOOL bFlipX, FX_BOOL bFlipY, FX_BOOL bRgbByteOrder,
4444 int alpha_flag, void* pIccTransform, int blend_type)
4445 {
4446 m_pBitmap = pDest;
4447 m_pClipRgn = pClipRgn;
4448 m_DestLeft = dest_rect.left;
4449 m_DestTop = dest_rect.top;
4450 m_DestWidth = dest_rect.Width();
4451 m_DestHeight = dest_rect.Height();
4452 m_BitmapAlpha = bitmap_alpha;
4453 m_MaskColor = mask_color;
4454 m_pClipMask = NULL;
4455 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4456 m_pClipMask = pClipRgn->GetMask();
4457 }
4458 m_bVertical = bVertical;
4459 m_bFlipX = bFlipX;
4460 m_bFlipY = bFlipY;
4461 m_AlphaFlag = alpha_flag;
4462 m_pIccTransform = pIccTransform;
4463 m_bRgbByteOrder = bRgbByteOrder;
4464 m_BlendType = blend_type;
4465 }
SetInfo(int width,int height,FXDIB_Format src_format,FX_DWORD * pSrcPalette)4466 FX_BOOL CFX_BitmapComposer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette)
4467 {
4468 m_SrcFormat = src_format;
4469 if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, m_MaskColor, FXDIB_BLEND_NORMAL,
4470 m_pClipMask != NULL || (m_BitmapAlpha < 255), m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) {
4471 return FALSE;
4472 }
4473 if (m_bVertical) {
4474 m_pScanlineV = FX_Alloc(FX_BYTE, m_pBitmap->GetBPP() / 8 * width + 4);
4475 if (!m_pScanlineV) {
4476 return FALSE;
4477 }
4478 m_pClipScanV = FX_Alloc(FX_BYTE, m_pBitmap->GetHeight());
4479 if (!m_pClipScanV) {
4480 return FALSE;
4481 }
4482 if (m_pBitmap->m_pAlphaMask) {
4483 m_pScanlineAlphaV = FX_Alloc(FX_BYTE, width + 4);
4484 if (!m_pScanlineAlphaV) {
4485 return FALSE;
4486 }
4487 }
4488 }
4489 if (m_BitmapAlpha < 255) {
4490 m_pAddClipScan = FX_Alloc(FX_BYTE, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth());
4491 if (!m_pAddClipScan) {
4492 return FALSE;
4493 }
4494 }
4495 return TRUE;
4496 }
DoCompose(FX_LPBYTE dest_scan,FX_LPCBYTE src_scan,int dest_width,FX_LPCBYTE clip_scan,FX_LPCBYTE src_extra_alpha,FX_LPBYTE dst_extra_alpha)4497 void CFX_BitmapComposer::DoCompose(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int dest_width, FX_LPCBYTE clip_scan,
4498 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
4499 {
4500 if (m_BitmapAlpha < 255) {
4501 if (clip_scan) {
4502 for (int i = 0; i < dest_width; i ++) {
4503 m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255;
4504 }
4505 } else {
4506 FXSYS_memset8(m_pAddClipScan, m_BitmapAlpha, dest_width);
4507 }
4508 clip_scan = m_pAddClipScan;
4509 }
4510 if (m_SrcFormat == FXDIB_8bppMask) {
4511 m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, clip_scan, dst_extra_alpha);
4512 } else if ((m_SrcFormat & 0xff) == 8) {
4513 m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
4514 } else {
4515 m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
4516 }
4517 }
ComposeScanline(int line,FX_LPCBYTE scanline,FX_LPCBYTE scan_extra_alpha)4518 void CFX_BitmapComposer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
4519 {
4520 if (m_bVertical) {
4521 ComposeScanlineV(line, scanline, scan_extra_alpha);
4522 return;
4523 }
4524 FX_LPCBYTE clip_scan = NULL;
4525 if (m_pClipMask)
4526 clip_scan = m_pClipMask->GetBuffer() + (m_DestTop + line - m_pClipRgn->GetBox().top) *
4527 m_pClipMask->GetPitch() + (m_DestLeft - m_pClipRgn->GetBox().left);
4528 FX_LPBYTE dest_scan = (FX_LPBYTE)m_pBitmap->GetScanline(line + m_DestTop) +
4529 m_DestLeft * m_pBitmap->GetBPP() / 8;
4530 FX_LPBYTE dest_alpha_scan = m_pBitmap->m_pAlphaMask ?
4531 (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + m_DestLeft : NULL;
4532 DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, dest_alpha_scan);
4533 }
ComposeScanlineV(int line,FX_LPCBYTE scanline,FX_LPCBYTE scan_extra_alpha)4534 void CFX_BitmapComposer::ComposeScanlineV(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
4535 {
4536 int i;
4537 int Bpp = m_pBitmap->GetBPP() / 8;
4538 int dest_pitch = m_pBitmap->GetPitch();
4539 int dest_alpha_pitch = m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
4540 int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
4541 FX_LPBYTE dest_buf = m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
4542 FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
4543 m_pBitmap->m_pAlphaMask->GetBuffer() + dest_x + m_DestTop * dest_alpha_pitch : NULL;
4544 if (m_bFlipY) {
4545 dest_buf += dest_pitch * (m_DestHeight - 1);
4546 dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
4547 }
4548 int y_step = dest_pitch;
4549 int y_alpha_step = dest_alpha_pitch;
4550 if (m_bFlipY) {
4551 y_step = -y_step;
4552 y_alpha_step = -y_alpha_step;
4553 }
4554 FX_LPBYTE src_scan = m_pScanlineV;
4555 FX_LPBYTE dest_scan = dest_buf;
4556 for (i = 0; i < m_DestHeight; i ++) {
4557 for (int j = 0; j < Bpp; j ++) {
4558 *src_scan++ = dest_scan[j];
4559 }
4560 dest_scan += y_step;
4561 }
4562 FX_LPBYTE src_alpha_scan = m_pScanlineAlphaV;
4563 FX_LPBYTE dest_alpha_scan = dest_alpha_buf;
4564 if (dest_alpha_scan) {
4565 for (i = 0; i < m_DestHeight; i ++) {
4566 *src_alpha_scan++ = *dest_alpha_scan;
4567 dest_alpha_scan += y_alpha_step;
4568 }
4569 }
4570 FX_LPBYTE clip_scan = NULL;
4571 if (m_pClipMask) {
4572 clip_scan = m_pClipScanV;
4573 int clip_pitch = m_pClipMask->GetPitch();
4574 FX_LPCBYTE src_clip = m_pClipMask->GetBuffer() + (m_DestTop - m_pClipRgn->GetBox().top) *
4575 clip_pitch + (dest_x - m_pClipRgn->GetBox().left);
4576 if (m_bFlipY) {
4577 src_clip += clip_pitch * (m_DestHeight - 1);
4578 clip_pitch = -clip_pitch;
4579 }
4580 for (i = 0; i < m_DestHeight; i ++) {
4581 clip_scan[i] = *src_clip;
4582 src_clip += clip_pitch;
4583 }
4584 }
4585 DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, m_pScanlineAlphaV);
4586 src_scan = m_pScanlineV;
4587 dest_scan = dest_buf;
4588 for (i = 0; i < m_DestHeight; i ++) {
4589 for (int j = 0; j < Bpp; j ++) {
4590 dest_scan[j] = *src_scan++;
4591 }
4592 dest_scan += y_step;
4593 }
4594 src_alpha_scan = m_pScanlineAlphaV;
4595 dest_alpha_scan = dest_alpha_buf;
4596 if (dest_alpha_scan) {
4597 for (i = 0; i < m_DestHeight; i ++) {
4598 *dest_alpha_scan = *src_alpha_scan++;
4599 dest_alpha_scan += y_alpha_step;
4600 }
4601 }
4602 }
4603