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