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