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