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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../../include/fxge/fx_ge.h"
8 #include "../../../include/fxcodec/fx_codec.h"
10 const FX_BYTE g_GammaRamp[256] = {
11 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
12 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
13 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
14 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13,
15 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20,
16 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
17 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41,
18 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54,
19 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
20 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88,
21 90, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109,
22 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133,
23 134, 136, 138, 139, 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159,
24 161, 163, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 184, 186, 188,
25 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220,
26 222, 224, 226, 229, 231, 233, 235, 237, 239, 242, 244, 246, 248, 250, 253, 255,
28 const FX_BYTE g_GammaInverse[256] = {
29 0, 13, 22, 28, 34, 38, 42, 46, 50, 53, 56, 59, 61, 64, 66, 69,
30 71, 73, 75, 77, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 96, 98,
31 99, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 115, 117, 118, 119,
32 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
33 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151,
34 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
35 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
36 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
37 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
38 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
39 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
40 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
41 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
42 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
43 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
44 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
46 const FX_BYTE _color_sqrt[256] = {
47 0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26, 0x29, 0x2C, 0x2F, 0x32,
48 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56,
49 0x57, 0x59, 0x5B, 0x5C, 0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
50 0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
51 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
52 0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
53 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8,
54 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4,
55 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
56 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9,
57 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3,
58 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD,
59 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6,
60 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE,
61 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
62 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
64 int _BLEND(int blend_mode, int back_color, int src_color)
67 case FXDIB_BLEND_NORMAL:
69 case FXDIB_BLEND_MULTIPLY:
70 return src_color * back_color / 255;
71 case FXDIB_BLEND_SCREEN:
72 return src_color + back_color - src_color * back_color / 255;
73 case FXDIB_BLEND_OVERLAY:
74 return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color);
75 case FXDIB_BLEND_DARKEN:
76 return src_color < back_color ? src_color : back_color;
77 case FXDIB_BLEND_LIGHTEN:
78 return src_color > back_color ? src_color : back_color;
79 case FXDIB_BLEND_COLORDODGE: {
80 if (src_color == 255) {
83 int result = back_color * 255 / (255 - src_color);
89 case FXDIB_BLEND_COLORBURN: {
93 int result = (255 - back_color) * 255 / src_color;
99 case FXDIB_BLEND_HARDLIGHT:
100 if (src_color < 128) {
101 return (src_color * back_color * 2) / 255;
103 return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255);
104 case FXDIB_BLEND_SOFTLIGHT: {
105 if (src_color < 128) {
106 return back_color - (255 - 2 * src_color) * back_color * (255 - back_color) / 255 / 255;
108 return back_color + (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) / 255;
110 case FXDIB_BLEND_DIFFERENCE:
111 return back_color < src_color ? src_color - back_color : back_color - src_color;
112 case FXDIB_BLEND_EXCLUSION:
113 return back_color + src_color - 2 * back_color * src_color / 255;
122 static inline int _Lum(_RGB color)
124 return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
126 static _RGB _ClipColor(_RGB color)
130 if (color.green < n) {
133 if (color.blue < n) {
137 if (color.green > x) {
140 if (color.blue > x) {
144 color.red = l + ((color.red - l) * l / (l - n));
145 color.green = l + ((color.green - l) * l / (l - n));
146 color.blue = l + ((color.blue - l) * l / (l - n));
149 color.red = l + ((color.red - l) * (255 - l) / (x - l));
150 color.green = l + ((color.green - l) * (255 - l) / (x - l));
151 color.blue = l + ((color.blue - l) * (255 - l) / (x - l));
155 static _RGB _SetLum(_RGB color, int l)
157 int d = l - _Lum(color);
161 return _ClipColor(color);
163 static int _Sat(_RGB color)
166 if (color.green < n) {
169 if (color.blue < n) {
173 if (color.green > x) {
176 if (color.blue > x) {
181 static _RGB _SetSat(_RGB color, int s)
183 int* max = &color.red;
184 int* mid = &color.red;
185 int* min = &color.red;
186 if (color.green > *max) {
189 if (color.blue > *max) {
192 if (color.green < *min) {
195 if (color.blue < *min) {
204 if (max == &color.red) {
205 if (min == &color.green) {
210 } else if (max == &color.green) {
211 if (min == &color.red) {
217 if (min == &color.green) {
224 *mid = (*mid - *min) * s / (*max - *min);
230 void _RGB_Blend(int blend_mode, FX_LPCBYTE src_scan, FX_BYTE* dest_scan, int results[3])
232 _RGB src, back, result;
233 src.red = src_scan[2];
234 src.green = src_scan[1];
235 src.blue = src_scan[0];
236 back.red = dest_scan[2];
237 back.green = dest_scan[1];
238 back.blue = dest_scan[0];
239 switch (blend_mode) {
240 case FXDIB_BLEND_HUE:
241 result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back));
243 case FXDIB_BLEND_SATURATION:
244 result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back));
246 case FXDIB_BLEND_COLOR:
247 result = _SetLum(src, _Lum(back));
249 case FXDIB_BLEND_LUMINOSITY:
250 result = _SetLum(back, _Lum(src));
253 results[0] = result.blue;
254 results[1] = result.green;
255 results[2] = result.red;
257 inline void _CompositeRow_Argb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, FX_LPCBYTE clip_scan)
260 for (int col = 0; col < pixel_count; col ++) {
261 int src_alpha = *src_scan;
263 src_alpha = clip_scan[col] * src_alpha / 255;
265 FX_BYTE back_alpha = *dest_scan;
267 *dest_scan = src_alpha;
268 } else if (src_alpha) {
269 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
275 void _CompositeRow_Rgba2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_alpha_scan, int pixel_count, FX_LPCBYTE clip_scan)
277 for (int col = 0; col < pixel_count; col ++) {
278 int src_alpha = *src_alpha_scan++;
280 src_alpha = clip_scan[col] * src_alpha / 255;
282 FX_BYTE back_alpha = *dest_scan;
284 *dest_scan = src_alpha;
285 } else if (src_alpha) {
286 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
291 void _CompositeRow_Rgb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan)
294 for (int i = 0; i < width; i ++) {
295 *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan);
300 FXSYS_memset8(dest_scan, 0xff, width);
303 void _CompositeRow_Argb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
304 FX_LPCBYTE src_alpha_scan, FX_LPBYTE dst_alpha_scan, void* pIccTransform)
306 ICodec_IccModule* pIccModule = NULL;
308 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
311 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
313 if (src_alpha_scan) {
314 for (int col = 0; col < pixel_count; col ++) {
315 FX_BYTE back_alpha = *dst_alpha_scan;
316 if (back_alpha == 0) {
317 int src_alpha = *src_alpha_scan++;
319 src_alpha = clip_scan[col] * src_alpha / 255;
323 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
325 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
327 *dst_alpha_scan = src_alpha;
334 FX_BYTE src_alpha = *src_alpha_scan++;
336 src_alpha = clip_scan[col] * src_alpha / 255;
338 if (src_alpha == 0) {
344 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
345 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
348 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
350 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
352 if (bNonseparableBlend) {
353 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
355 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
356 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
362 for (int col = 0; col < pixel_count; col ++) {
363 FX_BYTE back_alpha = *dst_alpha_scan;
364 if (back_alpha == 0) {
365 int src_alpha = src_scan[3];
367 src_alpha = clip_scan[col] * src_alpha / 255;
371 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
373 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
375 *dst_alpha_scan = src_alpha;
382 FX_BYTE src_alpha = src_scan[3];
384 src_alpha = clip_scan[col] * src_alpha / 255;
386 if (src_alpha == 0) {
392 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
393 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
396 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
398 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
400 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
407 if (src_alpha_scan) {
408 for (int col = 0; col < pixel_count; col ++) {
409 FX_BYTE back_alpha = *dst_alpha_scan;
410 if (back_alpha == 0) {
411 int src_alpha = *src_alpha_scan++;
413 src_alpha = clip_scan[col] * src_alpha / 255;
417 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
419 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
421 *dst_alpha_scan = src_alpha;
428 FX_BYTE src_alpha = *src_alpha_scan++;
430 src_alpha = clip_scan[col] * src_alpha / 255;
432 if (src_alpha == 0) {
438 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
439 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
442 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
444 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
446 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
452 for (int col = 0; col < pixel_count; col ++) {
453 FX_BYTE back_alpha = *dst_alpha_scan;
454 if (back_alpha == 0) {
455 int src_alpha = src_scan[3];
457 src_alpha = clip_scan[col] * src_alpha / 255;
461 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
463 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
465 *dst_alpha_scan = src_alpha;
472 FX_BYTE src_alpha = src_scan[3];
474 src_alpha = clip_scan[col] * src_alpha / 255;
476 if (src_alpha == 0) {
482 *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
483 int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
486 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
488 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
490 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
496 inline void _CompositeRow_Argb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count,
497 int blend_type, FX_LPCBYTE clip_scan,
498 FX_LPCBYTE src_alpha_scan, void* pIccTransform)
500 ICodec_IccModule* pIccModule = NULL;
503 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
506 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
508 if (src_alpha_scan) {
509 for (int col = 0; col < pixel_count; col ++) {
510 int src_alpha = *src_alpha_scan++;
512 src_alpha = clip_scan[col] * src_alpha / 255;
516 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
518 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
520 if (bNonseparableBlend) {
521 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
523 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
524 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
530 for (int col = 0; col < pixel_count; col ++) {
531 int src_alpha = src_scan[3];
533 src_alpha = clip_scan[col] * src_alpha / 255;
537 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
539 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
541 if (bNonseparableBlend) {
542 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
544 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
545 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
552 if (src_alpha_scan) {
553 for (int col = 0; col < pixel_count; col ++) {
554 int src_alpha = *src_alpha_scan++;
556 src_alpha = clip_scan[col] * src_alpha / 255;
560 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
562 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
564 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
570 for (int col = 0; col < pixel_count; col ++) {
571 int src_alpha = src_scan[3];
573 src_alpha = clip_scan[col] * src_alpha / 255;
577 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
579 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
581 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
587 inline void _CompositeRow_Rgb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
588 int blend_type, FX_LPCBYTE clip_scan,
591 ICodec_IccModule* pIccModule = NULL;
594 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
597 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
599 for (int col = 0; col < pixel_count; col ++) {
601 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
603 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
605 if (bNonseparableBlend) {
606 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
608 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
609 if (clip_scan && clip_scan[col] < 255) {
610 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
619 for (int col = 0; col < pixel_count; col ++) {
621 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
623 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
625 if (clip_scan && clip_scan[col] < 255) {
626 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
634 void _CompositeRow_Rgb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
635 int blend_type, FX_LPCBYTE clip_scan,
636 FX_LPBYTE dest_alpha_scan, void* pIccTransform)
638 ICodec_IccModule* pIccModule = NULL;
640 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
644 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
645 for (int col = 0; col < pixel_count; col ++) {
646 int back_alpha = *dest_alpha_scan;
647 if (back_alpha == 0) {
649 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
651 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
660 src_alpha = clip_scan[col];
662 if (src_alpha == 0) {
668 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
669 *dest_alpha_scan++ = dest_alpha;
670 int alpha_ratio = src_alpha * 255 / dest_alpha;
673 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
675 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
677 if (bNonseparableBlend) {
678 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
680 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
681 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
687 for (int col = 0; col < pixel_count; col ++) {
690 src_alpha = clip_scan[col];
692 if (src_alpha == 255) {
694 pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
696 *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
699 *dest_alpha_scan++ = 255;
703 if (src_alpha == 0) {
709 int back_alpha = *dest_alpha_scan;
710 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
711 *dest_alpha_scan++ = dest_alpha;
712 int alpha_ratio = src_alpha * 255 / dest_alpha;
715 pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
717 gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
719 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
724 void _CompositeRow_Argb2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
725 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
727 int blended_colors[3];
728 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
729 if (dest_alpha_scan == NULL) {
730 if (src_alpha_scan == NULL) {
731 FX_BYTE back_alpha = 0;
732 for (int col = 0; col < pixel_count; col ++) {
733 back_alpha = dest_scan[3];
734 if (back_alpha == 0) {
736 int src_alpha = clip_scan[col] * src_scan[3] / 255;
737 FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) | (src_alpha << 24));
739 FXARGB_COPY(dest_scan, src_scan);
746 if (clip_scan == NULL) {
747 src_alpha = src_scan[3];
749 src_alpha = clip_scan[col] * src_scan[3] / 255;
751 if (src_alpha == 0) {
756 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
757 dest_scan[3] = dest_alpha;
758 int alpha_ratio = src_alpha * 255 / dest_alpha;
759 if (bNonseparableBlend) {
760 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
762 for (int color = 0; color < 3; color ++) {
764 int blended = bNonseparableBlend ? blended_colors[color] :
765 _BLEND(blend_type, *dest_scan, *src_scan);
766 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
767 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
769 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
778 for (int col = 0; col < pixel_count; col ++) {
779 FX_BYTE back_alpha = dest_scan[3];
780 if (back_alpha == 0) {
782 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
783 FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2], src_scan[1], *src_scan));
785 FXARGB_SETDIB(dest_scan, FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2], src_scan[1], *src_scan));
793 if (clip_scan == NULL) {
794 src_alpha = *src_alpha_scan ++;
796 src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
798 if (src_alpha == 0) {
803 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
804 dest_scan[3] = dest_alpha;
805 int alpha_ratio = src_alpha * 255 / dest_alpha;
806 if (bNonseparableBlend) {
807 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
809 for (int color = 0; color < 3; color ++) {
811 int blended = bNonseparableBlend ? blended_colors[color] :
812 _BLEND(blend_type, *dest_scan, *src_scan);
813 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
814 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
816 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
825 if (src_alpha_scan) {
826 for (int col = 0; col < pixel_count; col ++) {
827 FX_BYTE back_alpha = *dest_alpha_scan;
828 if (back_alpha == 0) {
830 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
831 *dest_alpha_scan = src_alpha;
832 *dest_scan++ = *src_scan++;
833 *dest_scan++ = *src_scan++;
834 *dest_scan++ = *src_scan++;
836 *dest_alpha_scan = *src_alpha_scan;
837 *dest_scan++ = *src_scan++;
838 *dest_scan++ = *src_scan++;
839 *dest_scan++ = *src_scan++;
846 if (clip_scan == NULL) {
847 src_alpha = *src_alpha_scan ++;
849 src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
851 if (src_alpha == 0) {
857 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
858 *dest_alpha_scan ++ = dest_alpha;
859 int alpha_ratio = src_alpha * 255 / dest_alpha;
860 if (bNonseparableBlend) {
861 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
863 for (int color = 0; color < 3; color ++) {
865 int blended = bNonseparableBlend ? blended_colors[color] :
866 _BLEND(blend_type, *dest_scan, *src_scan);
867 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
868 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
870 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
877 for (int col = 0; col < pixel_count; col ++) {
878 FX_BYTE back_alpha = *dest_alpha_scan;
879 if (back_alpha == 0) {
881 int src_alpha = clip_scan[col] * src_scan[3] / 255;
882 *dest_alpha_scan = src_alpha;
883 *dest_scan++ = *src_scan++;
884 *dest_scan++ = *src_scan++;
885 *dest_scan++ = *src_scan++;
887 *dest_alpha_scan = src_scan[3];
888 *dest_scan++ = *src_scan++;
889 *dest_scan++ = *src_scan++;
890 *dest_scan++ = *src_scan++;
897 if (clip_scan == NULL) {
898 src_alpha = src_scan[3];
900 src_alpha = clip_scan[col] * src_scan[3] / 255;
902 if (src_alpha == 0) {
908 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
909 *dest_alpha_scan++ = dest_alpha;
910 int alpha_ratio = src_alpha * 255 / dest_alpha;
911 if (bNonseparableBlend) {
912 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
914 for (int color = 0; color < 3; color ++) {
916 int blended = bNonseparableBlend ? blended_colors[color] :
917 _BLEND(blend_type, *dest_scan, *src_scan);
918 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
919 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
921 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
931 void _CompositeRow_Rgb2Argb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
932 FX_LPBYTE dest_alpha_scan)
934 int blended_colors[3];
935 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
936 int src_gap = src_Bpp - 3;
937 if (dest_alpha_scan == NULL) {
938 for (int col = 0; col < width; col ++) {
939 FX_BYTE back_alpha = dest_scan[3];
940 if (back_alpha == 0) {
942 FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
944 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
951 if (bNonseparableBlend) {
952 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
954 for (int color = 0; color < 3; color ++) {
955 int src_color = *src_scan;
956 int blended = bNonseparableBlend ? blended_colors[color] :
957 _BLEND(blend_type, *dest_scan, src_color);
958 *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
966 for (int col = 0; col < width; col ++) {
967 FX_BYTE back_alpha = *dest_alpha_scan;
968 if (back_alpha == 0) {
969 *dest_scan++ = *src_scan++;
970 *dest_scan++ = *src_scan++;
971 *dest_scan++ = *src_scan++;
972 *dest_alpha_scan++ = 0xff;
976 *dest_alpha_scan++ = 0xff;
977 if (bNonseparableBlend) {
978 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
980 for (int color = 0; color < 3; color ++) {
981 int src_color = *src_scan;
982 int blended = bNonseparableBlend ? blended_colors[color] :
983 _BLEND(blend_type, *dest_scan, src_color);
984 *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
992 inline void _CompositeRow_Rgb2Argb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
993 FX_LPBYTE dest_alpha_scan)
995 int blended_colors[3];
996 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
997 int src_gap = src_Bpp - 3;
998 if (dest_alpha_scan == NULL) {
999 for (int col = 0; col < width; col ++) {
1000 int src_alpha = *clip_scan ++;
1001 FX_BYTE back_alpha = dest_scan[3];
1002 if (back_alpha == 0) {
1003 *dest_scan++ = *src_scan++;
1004 *dest_scan++ = *src_scan++;
1005 *dest_scan++ = *src_scan++;
1006 src_scan += src_gap;
1010 if (src_alpha == 0) {
1012 src_scan += src_Bpp;
1015 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1016 dest_scan[3] = dest_alpha;
1017 int alpha_ratio = src_alpha * 255 / dest_alpha;
1018 if (bNonseparableBlend) {
1019 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1021 for (int color = 0; color < 3; color ++) {
1022 int src_color = *src_scan;
1023 int blended = bNonseparableBlend ? blended_colors[color] :
1024 _BLEND(blend_type, *dest_scan, src_color);
1025 blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
1026 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1031 src_scan += src_gap;
1034 for (int col = 0; col < width; col ++) {
1035 int src_alpha = *clip_scan ++;
1036 FX_BYTE back_alpha = *dest_alpha_scan;
1037 if (back_alpha == 0) {
1038 *dest_scan++ = *src_scan++;
1039 *dest_scan++ = *src_scan++;
1040 *dest_scan++ = *src_scan++;
1041 src_scan += src_gap;
1045 if (src_alpha == 0) {
1048 src_scan += src_Bpp;
1051 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1052 *dest_alpha_scan++ = dest_alpha;
1053 int alpha_ratio = src_alpha * 255 / dest_alpha;
1054 if (bNonseparableBlend) {
1055 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1057 for (int color = 0; color < 3; color ++) {
1058 int src_color = *src_scan;
1059 int blended = bNonseparableBlend ? blended_colors[color] :
1060 _BLEND(blend_type, *dest_scan, src_color);
1061 blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
1062 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1066 src_scan += src_gap;
1070 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
1071 FX_LPBYTE dest_alpha_scan)
1073 int src_gap = src_Bpp - 3;
1074 if (dest_alpha_scan == NULL) {
1075 for (int col = 0; col < width; col ++) {
1076 int src_alpha = clip_scan[col];
1077 if (src_alpha == 255) {
1078 *dest_scan++ = *src_scan++;
1079 *dest_scan++ = *src_scan++;
1080 *dest_scan++ = *src_scan++;
1082 src_scan += src_gap;
1085 if (src_alpha == 0) {
1087 src_scan += src_Bpp;
1090 int back_alpha = dest_scan[3];
1091 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1092 dest_scan[3] = dest_alpha;
1093 int alpha_ratio = src_alpha * 255 / dest_alpha;
1094 for (int color = 0; color < 3; color ++) {
1095 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
1100 src_scan += src_gap;
1103 for (int col = 0; col < width; col ++) {
1104 int src_alpha = clip_scan[col];
1105 if (src_alpha == 255) {
1106 *dest_scan++ = *src_scan++;
1107 *dest_scan++ = *src_scan++;
1108 *dest_scan++ = *src_scan++;
1109 *dest_alpha_scan++ = 255;
1110 src_scan += src_gap;
1113 if (src_alpha == 0) {
1116 src_scan += src_Bpp;
1119 int back_alpha = *dest_alpha_scan;
1120 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1121 *dest_alpha_scan ++ = dest_alpha;
1122 int alpha_ratio = src_alpha * 255 / dest_alpha;
1123 for (int color = 0; color < 3; color ++) {
1124 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
1128 src_scan += src_gap;
1132 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
1133 FX_LPBYTE dest_alpha_scan)
1135 if (dest_alpha_scan == NULL) {
1136 for (int col = 0; col < width; col ++) {
1138 FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
1140 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
1143 src_scan += src_Bpp;
1146 int src_gap = src_Bpp - 3;
1147 for (int col = 0; col < width; col ++) {
1148 *dest_scan++ = *src_scan++;
1149 *dest_scan++ = *src_scan++;
1150 *dest_scan++ = *src_scan++;
1151 *dest_alpha_scan++ = 0xff;
1152 src_scan += src_gap;
1156 inline void _CompositeRow_Argb2Rgb_Blend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
1157 FX_LPCBYTE src_alpha_scan)
1159 int blended_colors[3];
1160 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1161 int dest_gap = dest_Bpp - 3;
1162 if (src_alpha_scan == NULL) {
1163 for (int col = 0; col < width; col ++) {
1166 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1168 src_alpha = src_scan[3];
1170 if (src_alpha == 0) {
1171 dest_scan += dest_Bpp;
1175 if (bNonseparableBlend) {
1176 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1178 for (int color = 0; color < 3; color ++) {
1179 int back_color = *dest_scan;
1180 int blended = bNonseparableBlend ? blended_colors[color] :
1181 _BLEND(blend_type, back_color, *src_scan);
1182 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1186 dest_scan += dest_gap;
1190 for (int col = 0; col < width; col ++) {
1193 src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1195 src_alpha = *src_alpha_scan++;
1197 if (src_alpha == 0) {
1198 dest_scan += dest_Bpp;
1202 if (bNonseparableBlend) {
1203 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1205 for (int color = 0; color < 3; color ++) {
1206 int back_color = *dest_scan;
1207 int blended = bNonseparableBlend ? blended_colors[color] :
1208 _BLEND(blend_type, back_color, *src_scan);
1209 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1213 dest_scan += dest_gap;
1217 inline void _CompositeRow_Argb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
1218 FX_LPCBYTE src_alpha_scan)
1220 int dest_gap = dest_Bpp - 3;
1221 if (src_alpha_scan == NULL) {
1222 for (int col = 0; col < width; col ++) {
1225 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1227 src_alpha = src_scan[3];
1229 if (src_alpha == 255) {
1230 *dest_scan++ = *src_scan++;
1231 *dest_scan++ = *src_scan++;
1232 *dest_scan++ = *src_scan++;
1233 dest_scan += dest_gap;
1237 if (src_alpha == 0) {
1238 dest_scan += dest_Bpp;
1242 for (int color = 0; color < 3; color ++) {
1243 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1247 dest_scan += dest_gap;
1251 for (int col = 0; col < width; col ++) {
1254 src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1256 src_alpha = *src_alpha_scan++;
1258 if (src_alpha == 255) {
1259 *dest_scan++ = *src_scan++;
1260 *dest_scan++ = *src_scan++;
1261 *dest_scan++ = *src_scan++;
1262 dest_scan += dest_gap;
1265 if (src_alpha == 0) {
1266 dest_scan += dest_Bpp;
1270 for (int color = 0; color < 3; color ++) {
1271 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1275 dest_scan += dest_gap;
1279 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
1281 int blended_colors[3];
1282 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1283 int dest_gap = dest_Bpp - 3;
1284 int src_gap = src_Bpp - 3;
1285 for (int col = 0; col < width; col ++) {
1286 if (bNonseparableBlend) {
1287 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1289 for (int color = 0; color < 3; color ++) {
1290 int back_color = *dest_scan;
1291 int src_color = *src_scan;
1292 int blended = bNonseparableBlend ? blended_colors[color] :
1293 _BLEND(blend_type, back_color, src_color);
1294 *dest_scan = blended;
1298 dest_scan += dest_gap;
1299 src_scan += src_gap;
1302 inline void _CompositeRow_Rgb2Rgb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
1304 int blended_colors[3];
1305 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1306 int dest_gap = dest_Bpp - 3;
1307 int src_gap = src_Bpp - 3;
1308 for (int col = 0; col < width; col ++) {
1309 FX_BYTE src_alpha = *clip_scan ++;
1310 if (src_alpha == 0) {
1311 dest_scan += dest_Bpp;
1312 src_scan += src_Bpp;
1315 if (bNonseparableBlend) {
1316 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
1318 for (int color = 0; color < 3; color ++) {
1319 int src_color = *src_scan;
1320 int back_color = *dest_scan;
1321 int blended = bNonseparableBlend ? blended_colors[color] :
1322 _BLEND(blend_type, back_color, src_color);
1323 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1327 dest_scan += dest_gap;
1328 src_scan += src_gap;
1331 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
1333 if (dest_Bpp == src_Bpp) {
1334 FXSYS_memcpy32(dest_scan, src_scan, width * dest_Bpp);
1337 for (int col = 0; col < width; col ++) {
1338 dest_scan[0] = src_scan[0];
1339 dest_scan[1] = src_scan[1];
1340 dest_scan[2] = src_scan[2];
1341 dest_scan += dest_Bpp;
1342 src_scan += src_Bpp;
1345 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
1347 for (int col = 0; col < width; col ++) {
1348 int src_alpha = clip_scan[col];
1349 if (src_alpha == 255) {
1350 dest_scan[0] = src_scan[0];
1351 dest_scan[1] = src_scan[1];
1352 dest_scan[2] = src_scan[2];
1353 } else if (src_alpha) {
1354 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1357 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1360 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
1361 dest_scan += dest_Bpp - 2;
1362 src_scan += src_Bpp - 2;
1365 dest_scan += dest_Bpp;
1366 src_scan += src_Bpp;
1369 void _CompositeRow_Argb2Argb_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
1370 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1372 FX_LPBYTE dp = src_cache_scan;
1373 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1374 if (src_alpha_scan) {
1375 if (dest_alpha_scan == NULL) {
1376 for (int col = 0; col < pixel_count; col ++) {
1377 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1378 dp[3] = *src_alpha_scan++;
1382 src_alpha_scan = NULL;
1384 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count);
1387 if (dest_alpha_scan == NULL) {
1388 for (int col = 0; col < pixel_count; col ++) {
1389 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1390 dp[3] = src_scan[3];
1395 int blended_colors[3];
1396 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1397 for (int col = 0; col < pixel_count; col ++) {
1398 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1399 FX_BYTE back_alpha = *dest_alpha_scan;
1400 if (back_alpha == 0) {
1402 int src_alpha = clip_scan[col] * src_scan[3] / 255;
1403 *dest_alpha_scan = src_alpha;
1404 *dest_scan++ = *src_cache_scan++;
1405 *dest_scan++ = *src_cache_scan++;
1406 *dest_scan++ = *src_cache_scan++;
1408 *dest_alpha_scan = src_scan[3];
1409 *dest_scan++ = *src_cache_scan++;
1410 *dest_scan++ = *src_cache_scan++;
1411 *dest_scan++ = *src_cache_scan++;
1418 if (clip_scan == NULL) {
1419 src_alpha = src_scan[3];
1421 src_alpha = clip_scan[col] * src_scan[3] / 255;
1424 if (src_alpha == 0) {
1426 src_cache_scan += 3;
1430 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1431 *dest_alpha_scan ++ = dest_alpha;
1432 int alpha_ratio = src_alpha * 255 / dest_alpha;
1433 if (bNonseparableBlend) {
1434 _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
1436 for (int color = 0; color < 3; color ++) {
1438 int blended = bNonseparableBlend ? blended_colors[color] :
1439 _BLEND(blend_type, *dest_scan, *src_cache_scan);
1440 blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha);
1441 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
1443 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio);
1452 _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type, clip_scan, dest_alpha_scan, src_alpha_scan);
1454 void _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
1455 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1457 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1459 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1461 FX_LPBYTE dp = src_cache_scan;
1462 for (int col = 0; col < width; col ++) {
1463 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1468 _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, 3, dest_alpha_scan);
1470 inline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
1471 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1473 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1475 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1477 FX_LPBYTE dp = src_cache_scan;
1478 for (int col = 0; col < width; col ++) {
1479 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1484 _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, 3, clip_scan, dest_alpha_scan);
1486 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
1487 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1489 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1491 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1493 FX_LPBYTE dp = src_cache_scan;
1494 for (int col = 0; col < width; col ++) {
1495 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1500 _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3, clip_scan, dest_alpha_scan);
1502 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
1503 FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1505 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1507 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1509 FX_LPBYTE dp = src_cache_scan;
1510 for (int col = 0; col < width; col ++) {
1511 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1516 _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3, dest_alpha_scan);
1518 inline void _CompositeRow_Argb2Rgb_Blend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
1519 FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1521 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1522 if (src_alpha_scan) {
1523 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1525 int blended_colors[3];
1526 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1527 int dest_gap = dest_Bpp - 3;
1528 for (int col = 0; col < width; col ++) {
1529 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1532 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1534 src_alpha = src_scan[3];
1537 if (src_alpha == 0) {
1538 dest_scan += dest_Bpp;
1539 src_cache_scan += 3;
1542 if (bNonseparableBlend) {
1543 _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
1545 for (int color = 0; color < 3; color ++) {
1546 int back_color = *dest_scan;
1547 int blended = bNonseparableBlend ? blended_colors[color] :
1548 _BLEND(blend_type, back_color, *src_cache_scan);
1549 *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
1553 dest_scan += dest_gap;
1557 _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, clip_scan, src_alpha_scan);
1559 inline void _CompositeRow_Argb2Rgb_NoBlend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
1560 FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
1562 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1563 if (src_alpha_scan) {
1564 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1566 int dest_gap = dest_Bpp - 3;
1567 for (int col = 0; col < width; col ++) {
1568 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
1571 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1573 src_alpha = src_scan[3];
1576 if (src_alpha == 255) {
1577 *dest_scan++ = *src_cache_scan++;
1578 *dest_scan++ = *src_cache_scan++;
1579 *dest_scan++ = *src_cache_scan++;
1580 dest_scan += dest_gap;
1583 if (src_alpha == 0) {
1584 dest_scan += dest_Bpp;
1585 src_cache_scan += 3;
1588 for (int color = 0; color < 3; color ++) {
1589 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha);
1593 dest_scan += dest_gap;
1597 _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp, clip_scan, src_alpha_scan);
1599 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp,
1600 FX_LPBYTE src_cache_scan, void* pIccTransform)
1602 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1604 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1606 FX_LPBYTE dp = src_cache_scan;
1607 for (int col = 0; col < width; col ++) {
1608 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1613 _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3);
1615 inline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
1616 FX_LPBYTE src_cache_scan, void* pIccTransform)
1618 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1620 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1622 FX_LPBYTE dp = src_cache_scan;
1623 for (int col = 0; col < width; col ++) {
1624 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1629 _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3, clip_scan);
1631 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp,
1632 FX_LPBYTE src_cache_scan, void* pIccTransform)
1634 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1636 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1638 FX_LPBYTE dp = src_cache_scan;
1639 for (int col = 0; col < width; col ++) {
1640 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1645 _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width, dest_Bpp, 3);
1647 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
1648 FX_LPBYTE src_cache_scan, void* pIccTransform)
1650 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
1652 pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
1654 FX_LPBYTE dp = src_cache_scan;
1655 for (int col = 0; col < width; col ++) {
1656 pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
1661 _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp, 3, clip_scan);
1663 inline void _CompositeRow_8bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
1664 int blend_type, FX_LPCBYTE clip_scan,
1665 FX_LPCBYTE src_alpha_scan)
1667 if (src_alpha_scan) {
1669 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1671 for (int col = 0; col < pixel_count; col ++) {
1672 FX_BYTE gray = pPalette[*src_scan];
1673 int src_alpha = *src_alpha_scan++;
1675 src_alpha = clip_scan[col] * src_alpha / 255;
1677 if (bNonseparableBlend) {
1678 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1680 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1682 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
1691 for (int col = 0; col < pixel_count; col ++) {
1692 FX_BYTE gray = pPalette[*src_scan];
1693 int src_alpha = *src_alpha_scan++;
1695 src_alpha = clip_scan[col] * src_alpha / 255;
1698 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
1707 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1709 for (int col = 0; col < pixel_count; col ++) {
1710 FX_BYTE gray = pPalette[*src_scan];
1711 if (bNonseparableBlend) {
1712 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1714 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1715 if (clip_scan && clip_scan[col] < 255) {
1716 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1725 for (int col = 0; col < pixel_count; col ++) {
1726 FX_BYTE gray = pPalette[*src_scan];
1727 if (clip_scan && clip_scan[col] < 255) {
1728 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1737 inline void _CompositeRow_8bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
1738 int blend_type, FX_LPCBYTE clip_scan,
1739 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
1741 if (src_alpha_scan) {
1743 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1745 for (int col = 0; col < pixel_count; col ++) {
1746 FX_BYTE gray = pPalette[*src_scan];
1748 FX_BYTE back_alpha = *dest_alpha_scan;
1749 if (back_alpha == 0) {
1750 int src_alpha = *src_alpha_scan ++;
1752 src_alpha = clip_scan[col] * src_alpha / 255;
1756 *dest_alpha_scan = src_alpha;
1762 FX_BYTE src_alpha = *src_alpha_scan++;
1764 src_alpha = clip_scan[col] * src_alpha / 255;
1766 if (src_alpha == 0) {
1771 *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1772 int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
1773 if (bNonseparableBlend) {
1774 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1776 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1777 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1783 for (int col = 0; col < pixel_count; col ++) {
1784 FX_BYTE gray = pPalette[*src_scan];
1786 FX_BYTE back_alpha = *dest_alpha_scan;
1787 if (back_alpha == 0) {
1788 int src_alpha = *src_alpha_scan ++;
1790 src_alpha = clip_scan[col] * src_alpha / 255;
1794 *dest_alpha_scan = src_alpha;
1800 FX_BYTE src_alpha = *src_alpha_scan++;
1802 src_alpha = clip_scan[col] * src_alpha / 255;
1804 if (src_alpha == 0) {
1809 *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1810 int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
1812 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1817 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1819 for (int col = 0; col < pixel_count; col ++) {
1820 FX_BYTE gray = pPalette[*src_scan];
1822 if (clip_scan == NULL || clip_scan[col] == 255) {
1823 *dest_scan++ = gray;
1824 *dest_alpha_scan++ = 255;
1827 int src_alpha = clip_scan[col];
1828 if (src_alpha == 0) {
1833 int back_alpha = *dest_alpha_scan;
1834 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1835 *dest_alpha_scan ++ = dest_alpha;
1836 int alpha_ratio = src_alpha * 255 / dest_alpha;
1837 if (bNonseparableBlend) {
1838 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1840 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1841 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1846 for (int col = 0; col < pixel_count; col ++) {
1847 FX_BYTE gray = pPalette[*src_scan];
1849 if (clip_scan == NULL || clip_scan[col] == 255) {
1850 *dest_scan++ = gray;
1851 *dest_alpha_scan++ = 255;
1854 int src_alpha = clip_scan[col];
1855 if (src_alpha == 0) {
1860 int back_alpha = *dest_alpha_scan;
1861 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1862 *dest_alpha_scan ++ = dest_alpha;
1863 int alpha_ratio = src_alpha * 255 / dest_alpha;
1864 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1869 inline void _CompositeRow_1bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
1870 FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
1872 int reset_gray = pPalette[0];
1873 int set_gray = pPalette[1];
1875 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1877 for (int col = 0; col < pixel_count; col ++) {
1878 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1879 if (bNonseparableBlend) {
1880 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1882 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1883 if (clip_scan && clip_scan[col] < 255) {
1884 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1892 for (int col = 0; col < pixel_count; col ++) {
1893 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1894 if (clip_scan && clip_scan[col] < 255) {
1895 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
1902 inline void _CompositeRow_1bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
1903 FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
1904 FX_LPBYTE dest_alpha_scan)
1906 int reset_gray = pPalette[0];
1907 int set_gray = pPalette[1];
1909 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
1911 for (int col = 0; col < pixel_count; col ++) {
1912 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1913 if (clip_scan == NULL || clip_scan[col] == 255) {
1914 *dest_scan++ = gray;
1915 *dest_alpha_scan ++ = 255;
1918 int src_alpha = clip_scan[col];
1919 if (src_alpha == 0) {
1924 int back_alpha = *dest_alpha_scan;
1925 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1926 *dest_alpha_scan ++ = dest_alpha;
1927 int alpha_ratio = src_alpha * 255 / dest_alpha;
1928 if (bNonseparableBlend) {
1929 blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
1931 gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
1932 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1937 for (int col = 0; col < pixel_count; col ++) {
1938 FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
1939 if (clip_scan == NULL || clip_scan[col] == 255) {
1940 *dest_scan++ = gray;
1941 *dest_alpha_scan ++ = 255;
1944 int src_alpha = clip_scan[col];
1945 if (src_alpha == 0) {
1950 int back_alpha = *dest_alpha_scan;
1951 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1952 *dest_alpha_scan ++ = dest_alpha;
1953 int alpha_ratio = src_alpha * 255 / dest_alpha;
1954 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
1958 inline void _CompositeRow_8bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_DWORD* pPalette, int pixel_count,
1959 int DestBpp, FX_LPCBYTE clip_scan,
1960 FX_LPCBYTE src_alpha_scan)
1962 if (src_alpha_scan) {
1963 int dest_gap = DestBpp - 3;
1965 for (int col = 0; col < pixel_count; col ++) {
1966 argb = pPalette[*src_scan];
1967 int src_r = FXARGB_R(argb);
1968 int src_g = FXARGB_G(argb);
1969 int src_b = FXARGB_B(argb);
1971 FX_BYTE src_alpha = 0;
1973 src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
1975 src_alpha = *src_alpha_scan++;
1977 if (src_alpha == 255) {
1978 *dest_scan++ = src_b;
1979 *dest_scan++ = src_g;
1980 *dest_scan++ = src_r;
1981 dest_scan += dest_gap;
1984 if (src_alpha == 0) {
1985 dest_scan += DestBpp;
1988 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
1990 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
1992 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
1994 dest_scan += dest_gap;
1998 for (int col = 0; col < pixel_count; col ++) {
1999 argb = pPalette[*src_scan];
2000 int src_r = FXARGB_R(argb);
2001 int src_g = FXARGB_G(argb);
2002 int src_b = FXARGB_B(argb);
2003 if (clip_scan && clip_scan[col] < 255) {
2004 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
2006 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
2008 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
2011 *dest_scan++ = src_b;
2012 *dest_scan++ = src_g;
2013 *dest_scan++ = src_r;
2022 inline void _CompositeRow_1bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
2023 FX_DWORD* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
2025 int reset_r, reset_g, reset_b;
2026 int set_r, set_g, set_b;
2027 reset_r = FXARGB_R(pPalette[0]);
2028 reset_g = FXARGB_G(pPalette[0]);
2029 reset_b = FXARGB_B(pPalette[0]);
2030 set_r = FXARGB_R(pPalette[1]);
2031 set_g = FXARGB_G(pPalette[1]);
2032 set_b = FXARGB_B(pPalette[1]);
2033 for (int col = 0; col < pixel_count; col ++) {
2034 int src_r, src_g, src_b;
2035 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2044 if (clip_scan && clip_scan[col] < 255) {
2045 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
2047 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
2049 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
2052 *dest_scan++ = src_b;
2053 *dest_scan++ = src_g;
2054 *dest_scan++ = src_r;
2061 inline void _CompositeRow_8bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
2062 FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2063 FX_LPCBYTE src_alpha_scan)
2065 if (src_alpha_scan) {
2066 for (int col = 0; col < width; col ++) {
2067 FX_ARGB argb = pPalette[*src_scan];
2069 int src_r = FXARGB_R(argb);
2070 int src_g = FXARGB_G(argb);
2071 int src_b = FXARGB_B(argb);
2072 FX_BYTE back_alpha = dest_scan[3];
2073 if (back_alpha == 0) {
2075 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
2076 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2078 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b));
2085 if (clip_scan == NULL) {
2086 src_alpha = *src_alpha_scan ++;
2088 src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
2090 if (src_alpha == 0) {
2094 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2095 dest_scan[3] = dest_alpha;
2096 int alpha_ratio = src_alpha * 255 / dest_alpha;
2097 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2099 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2101 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2106 for (int col = 0; col < width; col ++) {
2107 FX_ARGB argb = pPalette[*src_scan];
2108 int src_r = FXARGB_R(argb);
2109 int src_g = FXARGB_G(argb);
2110 int src_b = FXARGB_B(argb);
2111 if (clip_scan == NULL || clip_scan[col] == 255) {
2112 *dest_scan++ = src_b;
2113 *dest_scan++ = src_g;
2114 *dest_scan++ = src_r;
2119 int src_alpha = clip_scan[col];
2120 if (src_alpha == 0) {
2125 int back_alpha = dest_scan[3];
2126 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2127 dest_scan[3] = dest_alpha;
2128 int alpha_ratio = src_alpha * 255 / dest_alpha;
2129 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2131 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2133 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2139 void _CompositeRow_8bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
2140 FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2141 FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
2143 if (src_alpha_scan) {
2144 for (int col = 0; col < width; col ++) {
2145 FX_ARGB argb = pPalette[*src_scan];
2147 int src_r = FXARGB_R(argb);
2148 int src_g = FXARGB_G(argb);
2149 int src_b = FXARGB_B(argb);
2150 FX_BYTE back_alpha = *dest_alpha_scan;
2151 if (back_alpha == 0) {
2153 int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
2154 *dest_alpha_scan ++ = src_alpha;
2156 *dest_alpha_scan ++ = *src_alpha_scan;
2158 *dest_scan ++ = src_b;
2159 *dest_scan ++ = src_g;
2160 *dest_scan ++ = src_r;
2165 if (clip_scan == NULL) {
2166 src_alpha = *src_alpha_scan++;
2168 src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
2170 if (src_alpha == 0) {
2175 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2176 *dest_alpha_scan ++ = dest_alpha;
2177 int alpha_ratio = src_alpha * 255 / dest_alpha;
2178 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2180 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2182 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2186 for (int col = 0; col < width; col ++) {
2187 FX_ARGB argb = pPalette[*src_scan];
2188 int src_r = FXARGB_R(argb);
2189 int src_g = FXARGB_G(argb);
2190 int src_b = FXARGB_B(argb);
2191 if (clip_scan == NULL || clip_scan[col] == 255) {
2192 *dest_scan++ = src_b;
2193 *dest_scan++ = src_g;
2194 *dest_scan++ = src_r;
2195 *dest_alpha_scan++ = 255;
2199 int src_alpha = clip_scan[col];
2200 if (src_alpha == 0) {
2206 int back_alpha = *dest_alpha_scan;
2207 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2208 *dest_alpha_scan ++ = dest_alpha;
2209 int alpha_ratio = src_alpha * 255 / dest_alpha;
2210 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2212 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2214 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2219 inline void _CompositeRow_1bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
2220 FX_DWORD* pPalette, FX_LPCBYTE clip_scan)
2222 int reset_r, reset_g, reset_b;
2223 int set_r, set_g, set_b;
2224 reset_r = FXARGB_R(pPalette[0]);
2225 reset_g = FXARGB_G(pPalette[0]);
2226 reset_b = FXARGB_B(pPalette[0]);
2227 set_r = FXARGB_R(pPalette[1]);
2228 set_g = FXARGB_G(pPalette[1]);
2229 set_b = FXARGB_B(pPalette[1]);
2230 for (int col = 0; col < width; col ++) {
2231 int src_r, src_g, src_b;
2232 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2241 if (clip_scan == NULL || clip_scan[col] == 255) {
2242 *dest_scan++ = src_b;
2243 *dest_scan++ = src_g;
2244 *dest_scan++ = src_r;
2248 int src_alpha = clip_scan[col];
2249 if (src_alpha == 0) {
2253 int back_alpha = dest_scan[3];
2254 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2255 dest_scan[3] = dest_alpha;
2256 int alpha_ratio = src_alpha * 255 / dest_alpha;
2257 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2259 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2261 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2266 void _CompositeRow_1bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
2267 FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
2268 FX_LPBYTE dest_alpha_scan)
2270 int reset_r, reset_g, reset_b;
2271 int set_r, set_g, set_b;
2272 reset_r = FXARGB_R(pPalette[0]);
2273 reset_g = FXARGB_G(pPalette[0]);
2274 reset_b = FXARGB_B(pPalette[0]);
2275 set_r = FXARGB_R(pPalette[1]);
2276 set_g = FXARGB_G(pPalette[1]);
2277 set_b = FXARGB_B(pPalette[1]);
2278 for (int col = 0; col < width; col ++) {
2279 int src_r, src_g, src_b;
2280 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
2289 if (clip_scan == NULL || clip_scan[col] == 255) {
2290 *dest_scan++ = src_b;
2291 *dest_scan++ = src_g;
2292 *dest_scan++ = src_r;
2293 *dest_alpha_scan++ = 255;
2296 int src_alpha = clip_scan[col];
2297 if (src_alpha == 0) {
2302 int back_alpha = *dest_alpha_scan;
2303 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2304 *dest_alpha_scan ++ = dest_alpha;
2305 int alpha_ratio = src_alpha * 255 / dest_alpha;
2306 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2308 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2310 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2314 void _CompositeRow_ByteMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2315 int blend_type, FX_LPCBYTE clip_scan)
2317 for (int col = 0; col < pixel_count; col ++) {
2320 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2322 src_alpha = mask_alpha * src_scan[col] / 255;
2324 FX_BYTE back_alpha = dest_scan[3];
2325 if (back_alpha == 0) {
2326 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2330 if (src_alpha == 0) {
2334 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2335 dest_scan[3] = dest_alpha;
2336 int alpha_ratio = src_alpha * 255 / dest_alpha;
2337 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2338 int blended_colors[3];
2339 FX_BYTE src_scan[3];
2340 src_scan[0] = src_b;
2341 src_scan[1] = src_g;
2342 src_scan[2] = src_r;
2343 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2344 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2346 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2348 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2349 } else if (blend_type) {
2350 int blended = _BLEND(blend_type, *dest_scan, src_b);
2351 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2352 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2354 blended = _BLEND(blend_type, *dest_scan, src_g);
2355 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2356 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2358 blended = _BLEND(blend_type, *dest_scan, src_r);
2359 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2360 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2362 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2364 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2366 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2371 void _CompositeRow_ByteMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2372 int blend_type, FX_LPCBYTE clip_scan,
2373 FX_LPBYTE dest_alpha_scan)
2375 for (int col = 0; col < pixel_count; col ++) {
2378 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2380 src_alpha = mask_alpha * src_scan[col] / 255;
2382 FX_BYTE back_alpha = *dest_alpha_scan;
2383 if (back_alpha == 0) {
2384 *dest_scan ++ = src_b;
2385 *dest_scan ++ = src_g;
2386 *dest_scan ++ = src_r;
2387 *dest_alpha_scan ++ = src_alpha;
2390 if (src_alpha == 0) {
2395 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2396 *dest_alpha_scan ++ = dest_alpha;
2397 int alpha_ratio = src_alpha * 255 / dest_alpha;
2398 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2399 int blended_colors[3];
2400 FX_BYTE src_scan[3];
2401 src_scan[0] = src_b;
2402 src_scan[1] = src_g;
2403 src_scan[2] = src_r;
2404 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2405 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2407 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2409 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2411 } else if (blend_type) {
2412 int blended = _BLEND(blend_type, *dest_scan, src_b);
2413 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2414 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2416 blended = _BLEND(blend_type, *dest_scan, src_g);
2417 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2418 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2420 blended = _BLEND(blend_type, *dest_scan, src_r);
2421 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2422 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2425 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2427 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2429 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2434 void _CompositeRow_ByteMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
2435 int blend_type, int Bpp, FX_LPCBYTE clip_scan)
2437 for (int col = 0; col < pixel_count; col ++) {
2440 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2442 src_alpha = mask_alpha * src_scan[col] / 255;
2444 if (src_alpha == 0) {
2448 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2449 int blended_colors[3];
2450 FX_BYTE src_scan[3];
2451 src_scan[0] = src_b;
2452 src_scan[1] = src_g;
2453 src_scan[2] = src_r;
2454 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2455 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
2457 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
2459 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
2460 } else if (blend_type) {
2461 int blended = _BLEND(blend_type, *dest_scan, src_b);
2462 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2464 blended = _BLEND(blend_type, *dest_scan, src_g);
2465 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2467 blended = _BLEND(blend_type, *dest_scan, src_r);
2468 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2470 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
2472 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
2474 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
2476 dest_scan += Bpp - 2;
2479 void _CompositeRow_ByteMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int pixel_count,
2480 FX_LPCBYTE clip_scan)
2482 for (int col = 0; col < pixel_count; col ++) {
2485 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2487 src_alpha = mask_alpha * src_scan[col] / 255;
2489 FX_BYTE back_alpha = *dest_scan;
2491 *dest_scan = src_alpha;
2492 } else if (src_alpha) {
2493 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2498 void _CompositeRow_ByteMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2499 int pixel_count, FX_LPCBYTE clip_scan)
2501 for (int col = 0; col < pixel_count; col ++) {
2504 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2506 src_alpha = mask_alpha * src_scan[col] / 255;
2509 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
2514 void _CompositeRow_ByteMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2515 int pixel_count, FX_LPCBYTE clip_scan,
2516 FX_LPBYTE dest_alpha_scan)
2518 for (int col = 0; col < pixel_count; col ++) {
2521 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
2523 src_alpha = mask_alpha * src_scan[col] / 255;
2525 FX_BYTE back_alpha = *dest_alpha_scan;
2526 if (back_alpha == 0) {
2527 *dest_scan ++ = src_gray;
2528 *dest_alpha_scan ++ = src_alpha;
2531 if (src_alpha == 0) {
2536 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2537 *dest_alpha_scan++ = dest_alpha;
2538 int alpha_ratio = src_alpha * 255 / dest_alpha;
2539 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
2543 void _CompositeRow_BitMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2544 int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
2546 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2547 FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
2548 for (int col = 0; col < pixel_count; col ++) {
2549 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2550 FXARGB_SETDIB(dest_scan, argb);
2556 for (int col = 0; col < pixel_count; col ++) {
2557 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2563 src_alpha = mask_alpha * clip_scan[col] / 255;
2565 src_alpha = mask_alpha;
2567 FX_BYTE back_alpha = dest_scan[3];
2568 if (back_alpha == 0) {
2569 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
2573 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2574 dest_scan[3] = dest_alpha;
2575 int alpha_ratio = src_alpha * 255 / dest_alpha;
2576 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2577 int blended_colors[3];
2578 FX_BYTE src_scan[3];
2579 src_scan[0] = src_b;
2580 src_scan[1] = src_g;
2581 src_scan[2] = src_r;
2582 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2583 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2585 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2587 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2588 } else if (blend_type) {
2589 int blended = _BLEND(blend_type, *dest_scan, src_b);
2590 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2591 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2593 blended = _BLEND(blend_type, *dest_scan, src_g);
2594 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2595 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2597 blended = _BLEND(blend_type, *dest_scan, src_r);
2598 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2599 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2601 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2603 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2605 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2610 void _CompositeRow_BitMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2611 int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
2612 FX_LPBYTE dest_alpha_scan)
2614 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2615 for (int col = 0; col < pixel_count; col ++) {
2616 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2617 dest_scan[0] = src_b;
2618 dest_scan[1] = src_g;
2619 dest_scan[2] = src_r;
2620 *dest_alpha_scan = mask_alpha;
2627 for (int col = 0; col < pixel_count; col ++) {
2628 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2635 src_alpha = mask_alpha * clip_scan[col] / 255;
2637 src_alpha = mask_alpha;
2639 FX_BYTE back_alpha = dest_scan[3];
2640 if (back_alpha == 0) {
2641 *dest_scan ++ = src_b;
2642 *dest_scan ++ = src_g;
2643 *dest_scan ++ = src_r;
2644 *dest_alpha_scan ++ = mask_alpha;
2647 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2648 *dest_alpha_scan ++ = dest_alpha;
2649 int alpha_ratio = src_alpha * 255 / dest_alpha;
2650 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2651 int blended_colors[3];
2652 FX_BYTE src_scan[3];
2653 src_scan[0] = src_b;
2654 src_scan[1] = src_g;
2655 src_scan[2] = src_r;
2656 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2657 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
2659 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
2661 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
2663 } else if (blend_type) {
2664 int blended = _BLEND(blend_type, *dest_scan, src_b);
2665 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
2666 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2668 blended = _BLEND(blend_type, *dest_scan, src_g);
2669 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
2670 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2672 blended = _BLEND(blend_type, *dest_scan, src_r);
2673 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
2674 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
2677 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
2679 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
2681 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
2686 void _CompositeRow_BitMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
2687 int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
2689 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
2690 for (int col = 0; col < pixel_count; col ++) {
2691 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2692 dest_scan[2] = src_r;
2693 dest_scan[1] = src_g;
2694 dest_scan[0] = src_b;
2700 for (int col = 0; col < pixel_count; col ++) {
2701 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2707 src_alpha = mask_alpha * clip_scan[col] / 255;
2709 src_alpha = mask_alpha;
2711 if (src_alpha == 0) {
2715 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
2716 int blended_colors[3];
2717 FX_BYTE src_scan[3];
2718 src_scan[0] = src_b;
2719 src_scan[1] = src_g;
2720 src_scan[2] = src_r;
2721 _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
2722 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
2724 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
2726 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
2727 } else if (blend_type) {
2728 int blended = _BLEND(blend_type, *dest_scan, src_b);
2729 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2731 blended = _BLEND(blend_type, *dest_scan, src_g);
2732 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2734 blended = _BLEND(blend_type, *dest_scan, src_r);
2735 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
2737 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
2739 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
2741 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
2743 dest_scan += Bpp - 2;
2746 void _CompositeRow_BitMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_left,
2747 int pixel_count, FX_LPCBYTE clip_scan)
2749 for (int col = 0; col < pixel_count; col ++) {
2750 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2756 src_alpha = mask_alpha * clip_scan[col] / 255;
2758 src_alpha = mask_alpha;
2760 FX_BYTE back_alpha = *dest_scan;
2762 *dest_scan = src_alpha;
2763 } else if (src_alpha) {
2764 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2769 void _CompositeRow_BitMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2770 int src_left, int pixel_count, FX_LPCBYTE clip_scan)
2772 for (int col = 0; col < pixel_count; col ++) {
2773 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2779 src_alpha = mask_alpha * clip_scan[col] / 255;
2781 src_alpha = mask_alpha;
2784 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
2789 void _CompositeRow_BitMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
2790 int src_left, int pixel_count, FX_LPCBYTE clip_scan,
2791 FX_LPBYTE dest_alpha_scan)
2793 for (int col = 0; col < pixel_count; col ++) {
2794 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2801 src_alpha = mask_alpha * clip_scan[col] / 255;
2803 src_alpha = mask_alpha;
2805 FX_BYTE back_alpha = *dest_alpha_scan;
2806 if (back_alpha == 0) {
2807 *dest_scan ++ = src_gray;
2808 *dest_alpha_scan ++ = src_alpha;
2811 if (src_alpha == 0) {
2816 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2817 *dest_alpha_scan++ = dest_alpha;
2818 int alpha_ratio = src_alpha * 255 / dest_alpha;
2819 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
2823 void _CompositeRow_Argb2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
2825 int blended_colors[3];
2826 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2827 for (int col = 0; col < pixel_count; col ++) {
2828 FX_BYTE back_alpha = dest_scan[3];
2829 if (back_alpha == 0) {
2831 int src_alpha = clip_scan[col] * src_scan[3] / 255;
2832 dest_scan[3] = src_alpha;
2833 dest_scan[0] = src_scan[2];
2834 dest_scan[1] = src_scan[1];
2835 dest_scan[2] = src_scan[0];
2837 FXARGB_RGBORDERCOPY(dest_scan, src_scan);
2844 if (clip_scan == NULL) {
2845 src_alpha = src_scan[3];
2847 src_alpha = clip_scan[col] * src_scan[3] / 255;
2849 if (src_alpha == 0) {
2854 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
2855 dest_scan[3] = dest_alpha;
2856 int alpha_ratio = src_alpha * 255 / dest_alpha;
2857 if (bNonseparableBlend) {
2858 FX_BYTE dest_scan_o[3];
2859 dest_scan_o[0] = dest_scan[2];
2860 dest_scan_o[1] = dest_scan[1];
2861 dest_scan_o[2] = dest_scan[0];
2862 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2864 for (int color = 0; color < 3; color ++) {
2865 int index = 2 - color;
2867 int blended = bNonseparableBlend ? blended_colors[color] :
2868 _BLEND(blend_type, dest_scan[index], *src_scan);
2869 blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
2870 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
2872 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio);
2880 void _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp)
2882 int blended_colors[3];
2883 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2884 int src_gap = src_Bpp - 3;
2885 for (int col = 0; col < width; col ++) {
2886 FX_BYTE back_alpha = dest_scan[3];
2887 if (back_alpha == 0) {
2889 FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
2891 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
2894 src_scan += src_Bpp;
2897 dest_scan[3] = 0xff;
2898 if (bNonseparableBlend) {
2899 FX_BYTE dest_scan_o[3];
2900 dest_scan_o[0] = dest_scan[2];
2901 dest_scan_o[1] = dest_scan[1];
2902 dest_scan_o[2] = dest_scan[0];
2903 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2905 for (int color = 0; color < 3; color ++) {
2906 int index = 2 - color;
2907 int src_color = FX_GAMMA(*src_scan);
2908 int blended = bNonseparableBlend ? blended_colors[color] :
2909 _BLEND(blend_type, dest_scan[index], src_color);
2910 dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
2914 src_scan += src_gap;
2917 inline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan)
2919 int blended_colors[3];
2920 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2921 for (int col = 0; col < width; col ++) {
2924 src_alpha = src_scan[3] * (*clip_scan++) / 255;
2926 src_alpha = src_scan[3];
2928 if (src_alpha == 0) {
2929 dest_scan += dest_Bpp;
2933 if (bNonseparableBlend) {
2934 FX_BYTE dest_scan_o[3];
2935 dest_scan_o[0] = dest_scan[2];
2936 dest_scan_o[1] = dest_scan[1];
2937 dest_scan_o[2] = dest_scan[0];
2938 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2940 for (int color = 0; color < 3; color ++) {
2941 int index = 2 - color;
2942 int back_color = FX_GAMMA(dest_scan[index]);
2943 int blended = bNonseparableBlend ? blended_colors[color] :
2944 _BLEND(blend_type, back_color, *src_scan);
2945 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
2948 dest_scan += dest_Bpp;
2952 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp)
2954 for (int col = 0; col < width; col ++) {
2956 FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
2958 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
2961 src_scan += src_Bpp;
2964 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
2966 int blended_colors[3];
2967 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
2968 int src_gap = src_Bpp - 3;
2969 for (int col = 0; col < width; col ++) {
2970 if (bNonseparableBlend) {
2971 FX_BYTE dest_scan_o[3];
2972 dest_scan_o[0] = dest_scan[2];
2973 dest_scan_o[1] = dest_scan[1];
2974 dest_scan_o[2] = dest_scan[0];
2975 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
2977 for (int color = 0; color < 3; color ++) {
2978 int index = 2 - color;
2979 int back_color = FX_GAMMA(dest_scan[index]);
2980 int src_color = FX_GAMMA(*src_scan);
2981 int blended = bNonseparableBlend ? blended_colors[color] :
2982 _BLEND(blend_type, back_color, src_color);
2983 dest_scan[index] = FX_GAMMA_INVERSE(blended);
2986 dest_scan += dest_Bpp;
2987 src_scan += src_gap;
2990 inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan)
2992 for (int col = 0; col < width; col ++) {
2995 src_alpha = src_scan[3] * (*clip_scan++) / 255;
2997 src_alpha = src_scan[3];
2999 if (src_alpha == 255) {
3000 dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++);
3001 dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++);
3002 dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++);
3003 dest_scan += dest_Bpp;
3007 if (src_alpha == 0) {
3008 dest_scan += dest_Bpp;
3012 for (int color = 0; color < 3; color ++) {
3013 int index = 2 - color;
3014 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha));
3017 dest_scan += dest_Bpp;
3021 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
3023 for (int col = 0; col < width; col ++) {
3024 dest_scan[2] = src_scan[0];
3025 dest_scan[1] = src_scan[1];
3026 dest_scan[0] = src_scan[2];
3027 dest_scan += dest_Bpp;
3028 src_scan += src_Bpp;
3031 inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan)
3033 int blended_colors[3];
3034 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
3035 int src_gap = src_Bpp - 3;
3036 for (int col = 0; col < width; col ++) {
3037 int src_alpha = *clip_scan ++;
3038 FX_BYTE back_alpha = dest_scan[3];
3039 if (back_alpha == 0) {
3040 dest_scan[2] = FX_GAMMA(*src_scan++);
3041 dest_scan[1] = FX_GAMMA(*src_scan++);
3042 dest_scan[0] = FX_GAMMA(*src_scan++);
3043 src_scan += src_gap;
3047 if (src_alpha == 0) {
3049 src_scan += src_Bpp;
3052 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3053 dest_scan[3] = dest_alpha;
3054 int alpha_ratio = src_alpha * 255 / dest_alpha;
3055 if (bNonseparableBlend) {
3056 FX_BYTE dest_scan_o[3];
3057 dest_scan_o[0] = dest_scan[2];
3058 dest_scan_o[1] = dest_scan[1];
3059 dest_scan_o[2] = dest_scan[0];
3060 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3062 for (int color = 0; color < 3; color ++) {
3063 int index = 2 - color;
3064 int src_color = FX_GAMMA(*src_scan);
3065 int blended = bNonseparableBlend ? blended_colors[color] :
3066 _BLEND(blend_type, dest_scan[index], src_color);
3067 blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
3068 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
3072 src_scan += src_gap;
3075 inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
3077 int blended_colors[3];
3078 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
3079 int src_gap = src_Bpp - 3;
3080 for (int col = 0; col < width; col ++) {
3081 FX_BYTE src_alpha = *clip_scan ++;
3082 if (src_alpha == 0) {
3083 dest_scan += dest_Bpp;
3084 src_scan += src_Bpp;
3087 if (bNonseparableBlend) {
3088 FX_BYTE dest_scan_o[3];
3089 dest_scan_o[0] = dest_scan[2];
3090 dest_scan_o[1] = dest_scan[1];
3091 dest_scan_o[2] = dest_scan[0];
3092 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3094 for (int color = 0; color < 3; color ++) {
3095 int index = 2 - color;
3096 int src_color = FX_GAMMA(*src_scan);
3097 int back_color = FX_GAMMA(dest_scan[index]);
3098 int blended = bNonseparableBlend ? blended_colors[color] :
3099 _BLEND(blend_type, back_color, src_color);
3100 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3103 dest_scan += dest_Bpp;
3104 src_scan += src_gap;
3107 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan)
3109 int src_gap = src_Bpp - 3;
3110 for (int col = 0; col < width; col ++) {
3111 int src_alpha = clip_scan[col];
3112 if (src_alpha == 255) {
3113 dest_scan[2] = FX_GAMMA(*src_scan++);
3114 dest_scan[1] = FX_GAMMA(*src_scan++);
3115 dest_scan[0] = FX_GAMMA(*src_scan++);
3118 src_scan += src_gap;
3121 if (src_alpha == 0) {
3123 src_scan += src_Bpp;
3126 int back_alpha = dest_scan[3];
3127 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3128 dest_scan[3] = dest_alpha;
3129 int alpha_ratio = src_alpha * 255 / dest_alpha;
3130 for (int color = 0; color < 3; color ++) {
3131 int index = 2 - color;
3132 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio);
3136 src_scan += src_gap;
3139 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
3141 for (int col = 0; col < width; col ++) {
3142 int src_alpha = clip_scan[col];
3143 if (src_alpha == 255) {
3144 dest_scan[2] = src_scan[0];
3145 dest_scan[1] = src_scan[1];
3146 dest_scan[0] = src_scan[2];
3147 } else if (src_alpha) {
3148 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha));
3150 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha));
3152 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha));
3153 dest_scan += dest_Bpp;
3154 src_scan += src_Bpp - 2;
3157 dest_scan += dest_Bpp;
3158 src_scan += src_Bpp;
3161 inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_ARGB* pPalette, int pixel_count,
3162 int DestBpp, FX_LPCBYTE clip_scan)
3164 for (int col = 0; col < pixel_count; col ++) {
3165 FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101;
3166 int src_r = FXARGB_R(argb);
3167 int src_g = FXARGB_G(argb);
3168 int src_b = FXARGB_B(argb);
3169 if (clip_scan && clip_scan[col] < 255) {
3170 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
3171 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
3172 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
3174 dest_scan[2] = src_b;
3175 dest_scan[1] = src_g;
3176 dest_scan[0] = src_r;
3178 dest_scan += DestBpp;
3182 inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
3183 FX_ARGB* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
3185 int reset_r, reset_g, reset_b;
3186 int set_r, set_g, set_b;
3188 reset_r = FXARGB_R(pPalette[0]);
3189 reset_g = FXARGB_G(pPalette[0]);
3190 reset_b = FXARGB_B(pPalette[0]);
3191 set_r = FXARGB_R(pPalette[1]);
3192 set_g = FXARGB_G(pPalette[1]);
3193 set_b = FXARGB_B(pPalette[1]);
3195 reset_r = reset_g = reset_b = 0;
3196 set_r = set_g = set_b = 255;
3198 for (int col = 0; col < pixel_count; col ++) {
3199 int src_r, src_g, src_b;
3200 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
3209 if (clip_scan && clip_scan[col] < 255) {
3210 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
3211 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
3212 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
3214 dest_scan[2] = src_b;
3215 dest_scan[1] = src_g;
3216 dest_scan[0] = src_r;
3218 dest_scan += DestBpp;
3221 inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
3222 FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
3224 for (int col = 0; col < width; col ++) {
3225 int src_r, src_g, src_b;
3227 FX_ARGB argb = pPalette[*src_scan];
3228 src_r = FXARGB_R(argb);
3229 src_g = FXARGB_G(argb);
3230 src_b = FXARGB_B(argb);
3232 src_r = src_g = src_b = *src_scan;
3234 if (clip_scan == NULL || clip_scan[col] == 255) {
3235 dest_scan[2] = FX_GAMMA(src_b);
3236 dest_scan[1] = FX_GAMMA(src_g);
3237 dest_scan[0] = FX_GAMMA(src_r);
3243 int src_alpha = clip_scan[col];
3244 if (src_alpha == 0) {
3249 int back_alpha = dest_scan[3];
3250 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3251 dest_scan[3] = dest_alpha;
3252 int alpha_ratio = src_alpha * 255 / dest_alpha;
3253 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
3254 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
3255 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
3260 inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
3261 FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
3263 int reset_r, reset_g, reset_b;
3264 int set_r, set_g, set_b;
3266 reset_r = FXARGB_R(pPalette[0]);
3267 reset_g = FXARGB_G(pPalette[0]);
3268 reset_b = FXARGB_B(pPalette[0]);
3269 set_r = FXARGB_R(pPalette[1]);
3270 set_g = FXARGB_G(pPalette[1]);
3271 set_b = FXARGB_B(pPalette[1]);
3273 reset_r = reset_g = reset_b = 0;
3274 set_r = set_g = set_b = 255;
3276 for (int col = 0; col < width; col ++) {
3277 int src_r, src_g, src_b;
3278 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
3287 if (clip_scan == NULL || clip_scan[col] == 255) {
3288 dest_scan[2] = FX_GAMMA(src_b);
3289 dest_scan[1] = FX_GAMMA(src_g);
3290 dest_scan[0] = FX_GAMMA(src_r);
3295 int src_alpha = clip_scan[col];
3296 if (src_alpha == 0) {
3300 int back_alpha = dest_scan[3];
3301 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3302 dest_scan[3] = dest_alpha;
3303 int alpha_ratio = src_alpha * 255 / dest_alpha;
3304 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
3305 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
3306 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
3310 void _CompositeRow_ByteMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
3311 int blend_type, FX_LPCBYTE clip_scan)
3313 for (int col = 0; col < pixel_count; col ++) {
3316 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
3318 src_alpha = mask_alpha * src_scan[col] / 255;
3320 FX_BYTE back_alpha = dest_scan[3];
3321 if (back_alpha == 0) {
3322 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
3326 if (src_alpha == 0) {
3330 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3331 dest_scan[3] = dest_alpha;
3332 int alpha_ratio = src_alpha * 255 / dest_alpha;
3333 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3334 int blended_colors[3];
3335 FX_BYTE src_scan[3];
3336 FX_BYTE dest_scan_o[3];
3337 src_scan[0] = src_b;
3338 src_scan[1] = src_g;
3339 src_scan[2] = src_r;
3340 dest_scan_o[0] = dest_scan[2];
3341 dest_scan_o[1] = dest_scan[1];
3342 dest_scan_o[2] = dest_scan[0];
3343 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3344 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
3345 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
3346 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
3347 } else if (blend_type) {
3348 int blended = _BLEND(blend_type, dest_scan[2], src_b);
3349 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
3350 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
3351 blended = _BLEND(blend_type, dest_scan[1], src_g);
3352 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
3353 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
3354 blended = _BLEND(blend_type, dest_scan[0], src_r);
3355 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
3356 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
3358 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
3359 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
3360 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
3365 void _CompositeRow_ByteMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
3366 int blend_type, int Bpp, FX_LPCBYTE clip_scan)
3368 for (int col = 0; col < pixel_count; col ++) {
3371 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
3373 src_alpha = mask_alpha * src_scan[col] / 255;
3375 if (src_alpha == 0) {
3379 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3380 int blended_colors[3];
3381 FX_BYTE src_scan[3];
3382 FX_BYTE dest_scan_o[3];
3383 src_scan[0] = src_b;
3384 src_scan[1] = src_g;
3385 src_scan[2] = src_r;
3386 dest_scan_o[0] = dest_scan[2];
3387 dest_scan_o[1] = dest_scan[1];
3388 dest_scan_o[2] = dest_scan[0];
3389 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3390 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
3391 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
3392 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
3393 } else if (blend_type) {
3394 int blended = _BLEND(blend_type, dest_scan[2], src_b);
3395 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha);
3396 blended = _BLEND(blend_type, dest_scan[1], src_g);
3397 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha);
3398 blended = _BLEND(blend_type, dest_scan[0], src_r);
3399 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha);
3401 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha);
3402 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha);
3403 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha);
3408 void _CompositeRow_BitMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
3409 int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
3411 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
3412 FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
3413 for (int col = 0; col < pixel_count; col ++) {
3414 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
3415 FXARGB_SETRGBORDERDIB(dest_scan, argb);
3421 for (int col = 0; col < pixel_count; col ++) {
3422 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
3428 src_alpha = mask_alpha * clip_scan[col] / 255;
3430 src_alpha = mask_alpha;
3432 FX_BYTE back_alpha = dest_scan[3];
3433 if (back_alpha == 0) {
3434 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
3438 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
3439 dest_scan[3] = dest_alpha;
3440 int alpha_ratio = src_alpha * 255 / dest_alpha;
3441 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3442 int blended_colors[3];
3443 FX_BYTE src_scan[3];
3444 FX_BYTE dest_scan_o[3];
3445 src_scan[0] = src_b;
3446 src_scan[1] = src_g;
3447 src_scan[2] = src_r;
3448 dest_scan_o[0] = dest_scan[2];
3449 dest_scan_o[1] = dest_scan[1];
3450 dest_scan_o[2] = dest_scan[0];
3451 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3452 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
3453 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
3454 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
3455 } else if (blend_type) {
3456 int blended = _BLEND(blend_type, dest_scan[2], src_b);
3457 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
3458 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
3459 blended = _BLEND(blend_type, dest_scan[1], src_g);
3460 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
3461 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
3462 blended = _BLEND(blend_type, dest_scan[0], src_r);
3463 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
3464 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
3466 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
3467 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
3468 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
3473 void _CompositeRow_BitMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
3474 int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
3476 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
3477 for (int col = 0; col < pixel_count; col ++) {
3478 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
3479 dest_scan[2] = src_b;
3480 dest_scan[1] = src_g;
3481 dest_scan[0] = src_r;
3487 for (int col = 0; col < pixel_count; col ++) {
3488 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
3494 src_alpha = mask_alpha * clip_scan[col] / 255;
3496 src_alpha = mask_alpha;
3498 if (src_alpha == 0) {
3502 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
3503 int blended_colors[3];
3504 FX_BYTE src_scan[3];
3505 FX_BYTE dest_scan_o[3];
3506 src_scan[0] = src_b;
3507 src_scan[1] = src_g;
3508 src_scan[2] = src_r;
3509 dest_scan_o[0] = dest_scan[2];
3510 dest_scan_o[1] = dest_scan[1];
3511 dest_scan_o[2] = dest_scan[0];
3512 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
3513 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
3514 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
3515 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
3516 } else if (blend_type) {
3517 int back_color = FX_GAMMA(dest_scan[2]);
3518 int blended = _BLEND(blend_type, back_color, src_b);
3519 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3520 back_color = FX_GAMMA(dest_scan[1]);
3521 blended = _BLEND(blend_type, back_color, src_g);
3522 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3523 back_color = FX_GAMMA(dest_scan[0]);
3524 blended = _BLEND(blend_type, back_color, src_r);
3525 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
3527 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha));
3528 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha));
3529 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha));
3534 inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, int alpha_flag, FX_DWORD mask_color, int& mask_alpha,
3535 int& mask_red, int& mask_green, int& mask_blue, int& mask_black,
3536 void* icc_module, void* pIccTransform)
3538 ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
3539 if (alpha_flag >> 8) {
3540 mask_alpha = alpha_flag & 0xff;
3541 mask_red = FXSYS_GetCValue(mask_color);
3542 mask_green = FXSYS_GetMValue(mask_color);
3543 mask_blue = FXSYS_GetYValue(mask_color);
3544 mask_black = FXSYS_GetKValue(mask_color);
3546 mask_alpha = FXARGB_A(mask_color);
3547 mask_red = FXARGB_R(mask_color);
3548 mask_green = FXARGB_G(mask_color);
3549 mask_blue = FXARGB_B(mask_color);
3551 if (dest_format == FXDIB_8bppMask) {
3554 if ((dest_format & 0xff) == 8) {
3555 if (pIccTransform) {
3556 mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
3557 FX_LPBYTE gray_p = (FX_LPBYTE)&mask_color;
3558 pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1);
3559 mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0];
3561 if (alpha_flag >> 8) {
3563 AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black,
3565 mask_red = FXRGB2GRAY(r, g, b);
3567 mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue);
3569 if (dest_format & 0x0400) {
3570 mask_red = FX_CCOLOR(mask_red);
3574 FX_LPBYTE mask_color_p = (FX_LPBYTE)&mask_color;
3575 mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
3576 if (pIccTransform) {
3577 pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, 1);
3578 mask_red = mask_color_p[2];
3579 mask_green = mask_color_p[1];
3580 mask_blue = mask_color_p[0];
3581 } else if (alpha_flag >> 8) {
3582 AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], mask_color_p[3],
3583 mask_color_p[2], mask_color_p[1], mask_color_p[0]);
3584 mask_red = mask_color_p[2];
3585 mask_green = mask_color_p[1];
3586 mask_blue = mask_color_p[0];
3591 inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, FXDIB_Format dest_format,
3592 FX_DWORD*& pDestPalette, FX_DWORD* pSrcPalette,
3593 void* icc_module, void* pIccTransform)
3595 ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
3596 FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE;
3597 FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE;
3598 pDestPalette = NULL;
3599 if (pIccTransform) {
3601 if ((dest_format & 0xff) == 8) {
3602 int pal_count = 1 << (src_format & 0xff);
3603 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3607 pDestPalette = (FX_DWORD*)gray_pal;
3608 for (int i = 0; i < pal_count; i ++) {
3609 FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
3610 pIccModule->TranslateScanline(pIccTransform, gray_pal, (FX_LPCBYTE)&color, 1);
3614 int palsize = 1 << (src_format & 0xff);
3615 pDestPalette = FX_Alloc(FX_DWORD, palsize);
3616 if (!pDestPalette) {
3619 for (int i = 0; i < palsize; i ++) {
3620 FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
3621 pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&color, (FX_LPCBYTE)&color, 1);
3622 pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
3626 int pal_count = 1 << (src_format & 0xff);
3627 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3631 if (pal_count == 2) {
3635 for (int i = 0; i < pal_count; i++) {
3639 if ((dest_format & 0xff) == 8) {
3640 pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, pal_count);
3641 pDestPalette = (FX_DWORD*)gray_pal;
3643 pDestPalette = FX_Alloc(FX_DWORD, pal_count);
3644 if (!pDestPalette) {
3648 for (int i = 0; i < pal_count; i ++) {
3649 pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&pDestPalette[i], &gray_pal[i], 1);
3650 pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) : FXARGB_TODIB(pDestPalette[i]);
3657 if ((dest_format & 0xff) == 8) {
3658 int pal_count = 1 << (src_format & 0xff);
3659 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3663 pDestPalette = (FX_DWORD*)gray_pal;
3665 for (int i = 0; i < pal_count; i ++) {
3666 FX_CMYK cmyk = pSrcPalette[i];
3668 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3670 *gray_pal ++ = FXRGB2GRAY(r, g, b);
3673 for (int i = 0; i < pal_count; i ++) {
3674 FX_ARGB argb = pSrcPalette[i];
3675 *gray_pal ++ = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
3678 int palsize = 1 << (src_format & 0xff);
3679 pDestPalette = FX_Alloc(FX_DWORD, palsize);
3680 if (!pDestPalette) {
3683 if (isDstCmyk == isSrcCmyk) {
3684 FXSYS_memcpy32(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD));
3686 for (int i = 0; i < palsize; i ++) {
3687 FX_CMYK cmyk = pSrcPalette[i];
3689 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3691 pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
3696 if ((dest_format & 0xff) == 8) {
3697 int pal_count = 1 << (src_format & 0xff);
3698 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
3702 if (pal_count == 2) {
3706 for (int i = 0; i < pal_count; i++) {
3710 pDestPalette = (FX_DWORD*)gray_pal;
3712 int palsize = 1 << (src_format & 0xff);
3713 pDestPalette = FX_Alloc(FX_DWORD, palsize);
3714 if (!pDestPalette) {
3718 pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000;
3719 pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff;
3721 for (int i = 0; i < palsize; i++) {
3722 pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101);
3725 if (isSrcCmyk != isDstCmyk) {
3726 for (int i = 0; i < palsize; i ++) {
3727 FX_CMYK cmyk = pDestPalette[i];
3729 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
3731 pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
3738 CFX_ScanlineCompositor::CFX_ScanlineCompositor()
3740 m_pSrcPalette = NULL;
3741 m_pCacheScanline = NULL;
3743 m_bRgbByteOrder = FALSE;
3744 m_BlendType = FXDIB_BLEND_NORMAL;
3746 CFX_ScanlineCompositor::~CFX_ScanlineCompositor()
3748 if (m_pSrcPalette) {
3749 FX_Free(m_pSrcPalette);
3751 if (m_pCacheScanline) {
3752 FX_Free(m_pCacheScanline);
3755 FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, FXDIB_Format src_format, FX_INT32 width, FX_DWORD* pSrcPalette,
3756 FX_DWORD mask_color, int blend_type, FX_BOOL bClip, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
3758 m_SrcFormat = src_format;
3759 m_DestFormat = dest_format;
3760 m_BlendType = blend_type;
3761 m_bRgbByteOrder = bRgbByteOrder;
3762 ICodec_IccModule* pIccModule = NULL;
3763 if (CFX_GEModule::Get()->GetCodecModule()) {
3764 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
3766 if (pIccModule == NULL) {
3767 pIccTransform = NULL;
3769 m_pIccTransform = pIccTransform;
3770 if ((dest_format & 0xff) == 1) {
3773 if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) {
3774 return _ScanlineCompositor_InitSourceMask(dest_format, alpha_flag, mask_color,
3775 m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack,
3776 pIccModule, pIccTransform);
3778 if (pIccTransform == NULL && (~src_format & 0x0400) && (dest_format & 0x0400)) {
3781 if ((m_SrcFormat & 0xff) <= 8) {
3782 if (dest_format == FXDIB_8bppMask) {
3785 _ScanlineCompositor_InitSourcePalette(src_format, dest_format, m_pSrcPalette, pSrcPalette,
3786 pIccModule, pIccTransform);
3787 m_Transparency = (dest_format == FXDIB_Argb ? 1 : 0)
3788 + (dest_format & 0x0200 ? 2 : 0)
3789 + (dest_format & 0x0400 ? 4 : 0)
3790 + ((src_format & 0xff) == 1 ? 8 : 0);
3793 m_Transparency = (src_format & 0x0200 ? 0 : 1)
3794 + (dest_format & 0x0200 ? 0 : 2)
3795 + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0)
3797 + (src_format & 0x0400 ? 16 : 0)
3798 + (dest_format & 0x0400 ? 32 : 0)
3799 + (pIccTransform ? 64 : 0);
3802 void CFX_ScanlineCompositor::CompositeRgbBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
3803 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
3805 int src_Bpp = (m_SrcFormat & 0xff) >> 3;
3806 int dest_Bpp = (m_DestFormat & 0xff) >> 3;
3807 if (m_bRgbByteOrder) {
3808 switch (m_Transparency) {
3813 _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, clip_scan);
3816 _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp);
3820 _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
3823 _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
3826 _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp);
3830 _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, clip_scan);
3833 _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
3836 _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
3839 _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
3842 _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp, clip_scan);
3845 _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
3850 if (m_DestFormat == FXDIB_8bppMask) {
3851 if (m_SrcFormat & 0x0200) {
3852 if (m_SrcFormat == FXDIB_Argb) {
3853 _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan);
3855 _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan);
3858 _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
3860 } else if ((m_DestFormat & 0xff) == 8) {
3861 if (m_DestFormat & 0x0400) {
3862 for (int i = 0; i < width; i ++) {
3863 *dest_scan = ~*dest_scan;
3867 if (m_SrcFormat & 0x0200) {
3868 if (m_DestFormat & 0x0200) {
3869 _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, dst_extra_alpha, m_pIccTransform);
3871 _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, m_pIccTransform);
3874 if (m_DestFormat & 0x0200) {
3875 _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, dst_extra_alpha, m_pIccTransform);
3877 _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, m_pIccTransform);
3880 if (m_DestFormat & 0x0400) {
3881 for (int i = 0; i < width; i ++) {
3882 *dest_scan = ~*dest_scan;
3887 int dest_Size = width * dest_Bpp + 4;
3888 if (dest_Size > m_CacheSize) {
3889 m_pCacheScanline = FX_Realloc(FX_BYTE, m_pCacheScanline, dest_Size);
3890 if (!m_pCacheScanline) {
3893 m_CacheSize = dest_Size;
3895 switch (m_Transparency) {
3900 _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, clip_scan,
3901 dst_extra_alpha, src_extra_alpha);
3908 _CompositeRow_Argb2Argb_Transform(dest_scan, src_scan, width, m_BlendType, clip_scan,
3909 dst_extra_alpha, src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3913 _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, src_Bpp,
3917 _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp,
3918 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3921 _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
3925 _CompositeRow_Rgb2Argb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
3926 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3929 _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp,
3933 _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, src_Bpp,
3934 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3937 _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, clip_scan,
3941 _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(dest_scan, src_scan, width, src_Bpp, clip_scan,
3942 dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
3946 _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
3951 _CompositeRow_Argb2Rgb_Blend_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
3952 src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3956 _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, clip_scan,
3961 _CompositeRow_Argb2Rgb_NoBlend_Transform(dest_scan, src_scan, width, dest_Bpp, clip_scan,
3962 src_extra_alpha, m_pCacheScanline, m_pIccTransform);
3965 _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
3968 _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
3969 m_pCacheScanline, m_pIccTransform);
3972 _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
3975 _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan,
3976 m_pCacheScanline, m_pIccTransform);
3979 _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
3982 _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp,
3983 m_pCacheScanline, m_pIccTransform);
3986 _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
3989 _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan,
3990 m_pCacheScanline, m_pIccTransform);
3995 void CFX_ScanlineCompositor::CompositePalBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
3996 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
3998 if (m_bRgbByteOrder) {
3999 if (m_SrcFormat == FXDIB_1bppRgb) {
4000 if (m_DestFormat == FXDIB_8bppRgb) {
4002 } else if(m_DestFormat == FXDIB_Argb) {
4003 _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
4005 _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4008 if (m_DestFormat == FXDIB_8bppRgb) {
4010 } else if (m_DestFormat == FXDIB_Argb) {
4011 _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, m_pSrcPalette, clip_scan);
4013 _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4018 if (m_DestFormat == FXDIB_8bppMask) {
4019 _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
4021 } else if ((m_DestFormat & 0xff) == 8) {
4022 if (m_Transparency & 8) {
4023 if (m_DestFormat & 0x0200) {
4024 _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, dst_extra_alpha);
4026 _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan);
4029 if (m_DestFormat & 0x0200)
4030 _CompositeRow_8bppPal2Graya(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
4031 dst_extra_alpha, src_extra_alpha);
4033 _CompositeRow_8bppPal2Gray(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
4037 switch (m_Transparency) {
4039 _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, m_pSrcPalette, clip_scan,
4043 _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
4046 _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
4050 _CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
4053 _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
4057 _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan,
4064 void CFX_ScanlineCompositor::CompositeByteMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
4065 FX_LPBYTE dst_extra_alpha)
4067 if (m_DestFormat == FXDIB_8bppMask) {
4068 _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, clip_scan);
4069 } else if ((m_DestFormat & 0xff) == 8) {
4070 if (m_DestFormat & 0x0200) {
4071 _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan, dst_extra_alpha);
4073 _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan);
4075 } else if (m_bRgbByteOrder) {
4076 if (m_DestFormat == FXDIB_Argb)
4077 _CompositeRow_ByteMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4078 width, m_BlendType, clip_scan);
4080 _CompositeRow_ByteMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4081 width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4083 } else if (m_DestFormat == FXDIB_Argb)
4084 _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4085 width, m_BlendType, clip_scan);
4086 else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
4087 _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4088 width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4089 else if (m_DestFormat == FXDIB_Rgba)
4090 _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4091 width, m_BlendType, clip_scan, dst_extra_alpha);
4093 void CFX_ScanlineCompositor::CompositeBitMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
4094 FX_LPBYTE dst_extra_alpha)
4096 if (m_DestFormat == FXDIB_8bppMask) {
4097 _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width, clip_scan);
4098 } else if ((m_DestFormat & 0xff) == 8) {
4099 if (m_DestFormat & 0x0200)
4100 _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan,
4103 _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan);
4105 } else if (m_bRgbByteOrder) {
4106 if (m_DestFormat == FXDIB_Argb)
4107 _CompositeRow_BitMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4108 src_left, width, m_BlendType, clip_scan);
4110 _CompositeRow_BitMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4111 src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4113 } else if (m_DestFormat == FXDIB_Argb)
4114 _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4115 src_left, width, m_BlendType, clip_scan);
4116 else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
4117 _CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
4118 src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
4120 FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, int dest_top, int width, int height,
4121 const CFX_DIBSource* pSrcBitmap, int src_left, int src_top,
4122 int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, void* pIccTransform)
4124 if (m_pBuffer == NULL) {
4127 ASSERT(!pSrcBitmap->IsAlphaMask());
4129 if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) {
4132 GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
4133 src_left, src_top, pClipRgn);
4134 if (width == 0 || height == 0) {
4137 const CFX_DIBitmap* pClipMask = NULL;
4139 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4140 ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
4141 pClipMask = pClipRgn->GetMask();
4142 clip_box = pClipRgn->GetBox();
4144 CFX_ScanlineCompositor compositor;
4145 if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, pSrcBitmap->GetPalette(), 0, blend_type,
4146 pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) {
4149 int dest_Bpp = m_bpp / 8;
4150 int src_Bpp = pSrcBitmap->GetBPP() / 8;
4151 FX_BOOL bRgb = FALSE;
4152 FX_BOOL bCmyk = FALSE;
4154 if (pSrcBitmap->IsCmykImage()) {
4160 CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask;
4161 for (int row = 0; row < height; row ++) {
4162 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
4163 FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp;
4164 FX_LPCBYTE src_scan_extra_alpha = pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left : NULL;
4165 FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
4166 FX_LPCBYTE clip_scan = NULL;
4168 clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
4171 compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
4173 compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
4178 FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, int dest_top, int width, int height,
4179 const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top,
4180 int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
4182 if (m_pBuffer == NULL) {
4185 ASSERT(pMask->IsAlphaMask());
4187 if (!pMask->IsAlphaMask() || m_bpp < 8) {
4190 GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, pClipRgn);
4191 if (width == 0 || height == 0) {
4194 int src_alpha = (FX_BYTE)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
4195 if (src_alpha == 0) {
4198 const CFX_DIBitmap* pClipMask = NULL;
4200 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4201 ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
4202 pClipMask = pClipRgn->GetMask();
4203 clip_box = pClipRgn->GetBox();
4205 int src_bpp = pMask->GetBPP();
4206 int Bpp = GetBPP() / 8;
4207 CFX_ScanlineCompositor compositor;
4208 if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, pIccTransform)) {
4211 for (int row = 0; row < height; row ++) {
4212 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
4213 FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
4214 FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
4215 FX_LPCBYTE clip_scan = NULL;
4217 clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
4220 compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, clip_scan, dst_scan_extra_alpha);
4222 compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, clip_scan, dst_scan_extra_alpha);
4227 FX_BOOL CFX_DIBitmap::CompositeRect(int left, int top, int width, int height, FX_DWORD color, int alpha_flag, void* pIccTransform)
4229 if (m_pBuffer == NULL) {
4232 int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
4233 if (src_alpha == 0) {
4236 FX_RECT rect(left, top, left + width, top + height);
4237 rect.Intersect(0, 0, m_Width, m_Height);
4238 if (rect.IsEmpty()) {
4241 width = rect.Width();
4243 if (alpha_flag >> 8) {
4244 dst_color = FXCMYK_TODIB(color);
4246 dst_color = FXARGB_TODIB(color);
4248 FX_LPBYTE color_p = (FX_LPBYTE)&dst_color;
4251 if (!IsAlphaMask()) {
4252 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
4253 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
4254 pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1);
4256 if (alpha_flag >> 8) {
4258 AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3],
4260 gray = FXRGB2GRAY(r, g, b);
4262 gray = (FX_BYTE)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]);
4265 if (IsCmykImage()) {
4269 for (int row = rect.top; row < rect.bottom; row ++) {
4270 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left;
4271 if (src_alpha == 255) {
4272 FXSYS_memset8(dest_scan, gray, width);
4274 for (int col = 0; col < width; col ++) {
4275 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
4280 } else if (m_bpp == 1) {
4281 ASSERT(!IsCmykImage() && (FX_BYTE)(alpha_flag >> 8) == 0);
4282 int left_shift = rect.left % 8;
4283 int right_shift = rect.right % 8;
4284 int width = rect.right / 8 - rect.left / 8;
4286 if (m_pPalette == NULL) {
4287 index = ((FX_BYTE)color == 0xff) ? 1 : 0;
4289 for (int i = 0; i < 2; i ++)
4290 if (m_pPalette[i] == color) {
4294 for (int row = rect.top; row < rect.bottom; row ++) {
4295 FX_BYTE* dest_scan_top = (FX_BYTE*)GetScanline(row) + rect.left / 8;
4296 FX_BYTE* dest_scan_top_r = (FX_BYTE*)GetScanline(row) + rect.right / 8;
4297 FX_BYTE left_flag = *dest_scan_top & (255 << (8 - left_shift));
4298 FX_BYTE right_flag = *dest_scan_top_r & (255 >> right_shift);
4300 FXSYS_memset8(dest_scan_top + 1, index ? 255 : 0, width - 1);
4302 *dest_scan_top &= left_flag;
4303 *dest_scan_top_r &= right_flag;
4305 *dest_scan_top |= ~left_flag;
4306 *dest_scan_top_r |= ~right_flag;
4310 *dest_scan_top &= left_flag | right_flag;
4312 *dest_scan_top |= ~(left_flag | right_flag);
4318 ASSERT(m_bpp >= 24);
4322 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) {
4323 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
4324 pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
4326 if (alpha_flag >> 8 && !IsCmykImage())
4327 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color),
4328 color_p[2], color_p[1], color_p[0]);
4329 else if (!(alpha_flag >> 8) && IsCmykImage()) {
4333 if(!IsCmykImage()) {
4334 color_p[3] = (FX_BYTE)src_alpha;
4336 int Bpp = m_bpp / 8;
4337 FX_BOOL bAlpha = HasAlpha();
4338 FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE;
4339 if (src_alpha == 255) {
4340 for (int row = rect.top; row < rect.bottom; row ++) {
4341 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
4342 FX_LPBYTE dest_scan_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left : NULL;
4343 if (dest_scan_alpha) {
4344 FXSYS_memset8(dest_scan_alpha, 0xff, width);
4347 FX_DWORD* scan = (FX_DWORD*)dest_scan;
4348 for (int col = 0; col < width; col ++) {
4349 *scan ++ = dst_color;
4352 for (int col = 0; col < width; col ++) {
4353 *dest_scan ++ = color_p[0];
4354 *dest_scan ++ = color_p[1];
4355 *dest_scan ++ = color_p[2];
4361 for (int row = rect.top; row < rect.bottom; row ++) {
4362 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
4365 for (int col = 0; col < width; col ++) {
4366 FX_BYTE back_alpha = dest_scan[3];
4367 if (back_alpha == 0) {
4368 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], color_p[1], color_p[0]));
4372 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
4373 int alpha_ratio = src_alpha * 255 / dest_alpha;
4374 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio);
4376 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio);
4378 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio);
4380 *dest_scan++ = dest_alpha;
4383 FX_LPBYTE dest_scan_alpha = (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left;
4384 for (int col = 0; col < width; col ++) {
4385 FX_BYTE back_alpha = *dest_scan_alpha;
4386 if (back_alpha == 0) {
4387 *dest_scan_alpha++ = src_alpha;
4388 FXSYS_memcpy32(dest_scan, color_p, Bpp);
4392 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
4393 *dest_scan_alpha ++ = dest_alpha;
4394 int alpha_ratio = src_alpha * 255 / dest_alpha;
4395 for(int comps = 0; comps < Bpp; comps ++) {
4396 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio);
4402 for (int col = 0; col < width; col ++) {
4403 for(int comps = 0; comps < Bpp; comps ++) {
4405 *dest_scan ++ = 255;
4408 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
4416 CFX_BitmapComposer::CFX_BitmapComposer()
4418 m_pScanlineV = NULL;
4419 m_pScanlineAlphaV = NULL;
4420 m_pClipScanV = NULL;
4421 m_pAddClipScan = NULL;
4422 m_bRgbByteOrder = FALSE;
4423 m_BlendType = FXDIB_BLEND_NORMAL;
4425 CFX_BitmapComposer::~CFX_BitmapComposer()
4428 FX_Free(m_pScanlineV);
4430 if (m_pScanlineAlphaV) {
4431 FX_Free(m_pScanlineAlphaV);
4434 FX_Free(m_pClipScanV);
4436 if (m_pAddClipScan) {
4437 FX_Free(m_pAddClipScan);
4440 void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, const CFX_ClipRgn* pClipRgn, int bitmap_alpha,
4441 FX_DWORD mask_color, FX_RECT& dest_rect, FX_BOOL bVertical,
4442 FX_BOOL bFlipX, FX_BOOL bFlipY, FX_BOOL bRgbByteOrder,
4443 int alpha_flag, void* pIccTransform, int blend_type)
4446 m_pClipRgn = pClipRgn;
4447 m_DestLeft = dest_rect.left;
4448 m_DestTop = dest_rect.top;
4449 m_DestWidth = dest_rect.Width();
4450 m_DestHeight = dest_rect.Height();
4451 m_BitmapAlpha = bitmap_alpha;
4452 m_MaskColor = mask_color;
4454 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
4455 m_pClipMask = pClipRgn->GetMask();
4457 m_bVertical = bVertical;
4460 m_AlphaFlag = alpha_flag;
4461 m_pIccTransform = pIccTransform;
4462 m_bRgbByteOrder = bRgbByteOrder;
4463 m_BlendType = blend_type;
4465 FX_BOOL CFX_BitmapComposer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette)
4467 m_SrcFormat = src_format;
4468 if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, m_MaskColor, FXDIB_BLEND_NORMAL,
4469 m_pClipMask != NULL || (m_BitmapAlpha < 255), m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) {
4473 m_pScanlineV = FX_Alloc(FX_BYTE, m_pBitmap->GetBPP() / 8 * width + 4);
4474 if (!m_pScanlineV) {
4477 m_pClipScanV = FX_Alloc(FX_BYTE, m_pBitmap->GetHeight());
4478 if (!m_pClipScanV) {
4481 if (m_pBitmap->m_pAlphaMask) {
4482 m_pScanlineAlphaV = FX_Alloc(FX_BYTE, width + 4);
4483 if (!m_pScanlineAlphaV) {
4488 if (m_BitmapAlpha < 255) {
4489 m_pAddClipScan = FX_Alloc(FX_BYTE, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth());
4490 if (!m_pAddClipScan) {
4496 void CFX_BitmapComposer::DoCompose(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int dest_width, FX_LPCBYTE clip_scan,
4497 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
4499 if (m_BitmapAlpha < 255) {
4501 for (int i = 0; i < dest_width; i ++) {
4502 m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255;
4505 FXSYS_memset8(m_pAddClipScan, m_BitmapAlpha, dest_width);
4507 clip_scan = m_pAddClipScan;
4509 if (m_SrcFormat == FXDIB_8bppMask) {
4510 m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, clip_scan, dst_extra_alpha);
4511 } else if ((m_SrcFormat & 0xff) == 8) {
4512 m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
4514 m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
4517 void CFX_BitmapComposer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
4520 ComposeScanlineV(line, scanline, scan_extra_alpha);
4523 FX_LPCBYTE clip_scan = NULL;
4525 clip_scan = m_pClipMask->GetBuffer() + (m_DestTop + line - m_pClipRgn->GetBox().top) *
4526 m_pClipMask->GetPitch() + (m_DestLeft - m_pClipRgn->GetBox().left);
4527 FX_LPBYTE dest_scan = (FX_LPBYTE)m_pBitmap->GetScanline(line + m_DestTop) +
4528 m_DestLeft * m_pBitmap->GetBPP() / 8;
4529 FX_LPBYTE dest_alpha_scan = m_pBitmap->m_pAlphaMask ?
4530 (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + m_DestLeft : NULL;
4531 DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, dest_alpha_scan);
4533 void CFX_BitmapComposer::ComposeScanlineV(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
4536 int Bpp = m_pBitmap->GetBPP() / 8;
4537 int dest_pitch = m_pBitmap->GetPitch();
4538 int dest_alpha_pitch = m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
4539 int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
4540 FX_LPBYTE dest_buf = m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
4541 FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
4542 m_pBitmap->m_pAlphaMask->GetBuffer() + dest_x + m_DestTop * dest_alpha_pitch : NULL;
4544 dest_buf += dest_pitch * (m_DestHeight - 1);
4545 dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
4547 int y_step = dest_pitch;
4548 int y_alpha_step = dest_alpha_pitch;
4551 y_alpha_step = -y_alpha_step;
4553 FX_LPBYTE src_scan = m_pScanlineV;
4554 FX_LPBYTE dest_scan = dest_buf;
4555 for (i = 0; i < m_DestHeight; i ++) {
4556 for (int j = 0; j < Bpp; j ++) {
4557 *src_scan++ = dest_scan[j];
4559 dest_scan += y_step;
4561 FX_LPBYTE src_alpha_scan = m_pScanlineAlphaV;
4562 FX_LPBYTE dest_alpha_scan = dest_alpha_buf;
4563 if (dest_alpha_scan) {
4564 for (i = 0; i < m_DestHeight; i ++) {
4565 *src_alpha_scan++ = *dest_alpha_scan;
4566 dest_alpha_scan += y_alpha_step;
4569 FX_LPBYTE clip_scan = NULL;
4571 clip_scan = m_pClipScanV;
4572 int clip_pitch = m_pClipMask->GetPitch();
4573 FX_LPCBYTE src_clip = m_pClipMask->GetBuffer() + (m_DestTop - m_pClipRgn->GetBox().top) *
4574 clip_pitch + (dest_x - m_pClipRgn->GetBox().left);
4576 src_clip += clip_pitch * (m_DestHeight - 1);
4577 clip_pitch = -clip_pitch;
4579 for (i = 0; i < m_DestHeight; i ++) {
4580 clip_scan[i] = *src_clip;
4581 src_clip += clip_pitch;
4584 DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, m_pScanlineAlphaV);
4585 src_scan = m_pScanlineV;
4586 dest_scan = dest_buf;
4587 for (i = 0; i < m_DestHeight; i ++) {
4588 for (int j = 0; j < Bpp; j ++) {
4589 dest_scan[j] = *src_scan++;
4591 dest_scan += y_step;
4593 src_alpha_scan = m_pScanlineAlphaV;
4594 dest_alpha_scan = dest_alpha_buf;
4595 if (dest_alpha_scan) {
4596 for (i = 0; i < m_DestHeight; i ++) {
4597 *dest_alpha_scan = *src_alpha_scan++;
4598 dest_alpha_scan += y_alpha_step;