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 }; 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 }; 122 static inline int _Lum(_RGB color) 123 { 124 return (color.red * 30 + color.green * 59 + color.blue * 11) / 100; 125 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 2952 inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp) 2953 { 2954 int src_gap = src_Bpp - 3; 2955 for (int col = 0; col < width; col ++) { 2956 if (src_Bpp == 4) { 2957 FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); 2958 } else { 2959 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0])); 2960 } 2961 dest_scan += 4; 2962 src_scan += src_Bpp; 2963 } 2964 } 2965 inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp) 2966 { 2967 int blended_colors[3]; 2968 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; 2969 int src_gap = src_Bpp - 3; 2970 for (int col = 0; col < width; col ++) { 2971 if (bNonseparableBlend) { 2972 FX_BYTE dest_scan_o[3]; 2973 dest_scan_o[0] = dest_scan[2]; 2974 dest_scan_o[1] = dest_scan[1]; 2975 dest_scan_o[2] = dest_scan[0]; 2976 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); 2977 } 2978 for (int color = 0; color < 3; color ++) { 2979 int index = 2 - color; 2980 int back_color = FX_GAMMA(dest_scan[index]); 2981 int src_color = FX_GAMMA(*src_scan); 2982 int blended = bNonseparableBlend ? blended_colors[color] : 2983 _BLEND(blend_type, back_color, src_color); 2984 dest_scan[index] = FX_GAMMA_INVERSE(blended); 2985 src_scan ++; 2986 } 2987 dest_scan += dest_Bpp; 2988 src_scan += src_gap; 2989 } 2990 } 2991 inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan) 2992 { 2993 for (int col = 0; col < width; col ++) { 2994 FX_BYTE src_alpha; 2995 if (clip_scan) { 2996 src_alpha = src_scan[3] * (*clip_scan++) / 255; 2997 } else { 2998 src_alpha = src_scan[3]; 2999 } 3000 if (src_alpha == 255) { 3001 dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++); 3002 dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++); 3003 dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++); 3004 dest_scan += dest_Bpp; 3005 src_scan ++; 3006 continue; 3007 } 3008 if (src_alpha == 0) { 3009 dest_scan += dest_Bpp; 3010 src_scan += 4; 3011 continue; 3012 } 3013 for (int color = 0; color < 3; color ++) { 3014 int index = 2 - color; 3015 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha)); 3016 src_scan ++; 3017 } 3018 dest_scan += dest_Bpp; 3019 src_scan ++; 3020 } 3021 } 3022 inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp) 3023 { 3024 for (int col = 0; col < width; col ++) { 3025 dest_scan[2] = src_scan[0]; 3026 dest_scan[1] = src_scan[1]; 3027 dest_scan[0] = src_scan[2]; 3028 dest_scan += dest_Bpp; 3029 src_scan += src_Bpp; 3030 } 3031 } 3032 inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan) 3033 { 3034 int blended_colors[3]; 3035 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; 3036 int src_gap = src_Bpp - 3; 3037 for (int col = 0; col < width; col ++) { 3038 int src_alpha = *clip_scan ++; 3039 FX_BYTE back_alpha = dest_scan[3]; 3040 if (back_alpha == 0) { 3041 dest_scan[2] = FX_GAMMA(*src_scan++); 3042 dest_scan[1] = FX_GAMMA(*src_scan++); 3043 dest_scan[0] = FX_GAMMA(*src_scan++); 3044 src_scan += src_gap; 3045 dest_scan += 4; 3046 continue; 3047 } 3048 if (src_alpha == 0) { 3049 dest_scan += 4; 3050 src_scan += src_Bpp; 3051 continue; 3052 } 3053 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 3054 dest_scan[3] = dest_alpha; 3055 int alpha_ratio = src_alpha * 255 / dest_alpha; 3056 if (bNonseparableBlend) { 3057 FX_BYTE dest_scan_o[3]; 3058 dest_scan_o[0] = dest_scan[2]; 3059 dest_scan_o[1] = dest_scan[1]; 3060 dest_scan_o[2] = dest_scan[0]; 3061 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); 3062 } 3063 for (int color = 0; color < 3; color ++) { 3064 int index = 2 - color; 3065 int src_color = FX_GAMMA(*src_scan); 3066 int blended = bNonseparableBlend ? blended_colors[color] : 3067 _BLEND(blend_type, dest_scan[index], src_color); 3068 blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); 3069 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio); 3070 src_scan ++; 3071 } 3072 dest_scan += 4; 3073 src_scan += src_gap; 3074 } 3075 } 3076 inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan) 3077 { 3078 int blended_colors[3]; 3079 FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; 3080 int src_gap = src_Bpp - 3; 3081 for (int col = 0; col < width; col ++) { 3082 FX_BYTE src_alpha = *clip_scan ++; 3083 if (src_alpha == 0) { 3084 dest_scan += dest_Bpp; 3085 src_scan += src_Bpp; 3086 continue; 3087 } 3088 if (bNonseparableBlend) { 3089 FX_BYTE dest_scan_o[3]; 3090 dest_scan_o[0] = dest_scan[2]; 3091 dest_scan_o[1] = dest_scan[1]; 3092 dest_scan_o[2] = dest_scan[0]; 3093 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); 3094 } 3095 for (int color = 0; color < 3; color ++) { 3096 int index = 2 - color; 3097 int src_color = FX_GAMMA(*src_scan); 3098 int back_color = FX_GAMMA(dest_scan[index]); 3099 int blended = bNonseparableBlend ? blended_colors[color] : 3100 _BLEND(blend_type, back_color, src_color); 3101 dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); 3102 src_scan ++; 3103 } 3104 dest_scan += dest_Bpp; 3105 src_scan += src_gap; 3106 } 3107 } 3108 inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan) 3109 { 3110 int src_gap = src_Bpp - 3; 3111 for (int col = 0; col < width; col ++) { 3112 int src_alpha = clip_scan[col]; 3113 if (src_alpha == 255) { 3114 dest_scan[2] = FX_GAMMA(*src_scan++); 3115 dest_scan[1] = FX_GAMMA(*src_scan++); 3116 dest_scan[0] = FX_GAMMA(*src_scan++); 3117 dest_scan[3] = 255; 3118 dest_scan += 4; 3119 src_scan += src_gap; 3120 continue; 3121 } 3122 if (src_alpha == 0) { 3123 dest_scan += 4; 3124 src_scan += src_Bpp; 3125 continue; 3126 } 3127 int back_alpha = dest_scan[3]; 3128 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 3129 dest_scan[3] = dest_alpha; 3130 int alpha_ratio = src_alpha * 255 / dest_alpha; 3131 for (int color = 0; color < 3; color ++) { 3132 int index = 2 - color; 3133 dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio); 3134 src_scan ++; 3135 } 3136 dest_scan += 4; 3137 src_scan += src_gap; 3138 } 3139 } 3140 inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan) 3141 { 3142 for (int col = 0; col < width; col ++) { 3143 int src_alpha = clip_scan[col]; 3144 if (src_alpha == 255) { 3145 dest_scan[2] = src_scan[0]; 3146 dest_scan[1] = src_scan[1]; 3147 dest_scan[0] = src_scan[2]; 3148 } else if (src_alpha) { 3149 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha)); 3150 src_scan ++; 3151 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha)); 3152 src_scan ++; 3153 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha)); 3154 dest_scan += dest_Bpp; 3155 src_scan += src_Bpp - 2; 3156 continue; 3157 } 3158 dest_scan += dest_Bpp; 3159 src_scan += src_Bpp; 3160 } 3161 } 3162 inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_ARGB* pPalette, int pixel_count, 3163 int DestBpp, FX_LPCBYTE clip_scan) 3164 { 3165 for (int col = 0; col < pixel_count; col ++) { 3166 FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101; 3167 int src_r = FXARGB_R(argb); 3168 int src_g = FXARGB_G(argb); 3169 int src_b = FXARGB_B(argb); 3170 if (clip_scan && clip_scan[col] < 255) { 3171 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]); 3172 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]); 3173 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]); 3174 } else { 3175 dest_scan[2] = src_b; 3176 dest_scan[1] = src_g; 3177 dest_scan[0] = src_r; 3178 } 3179 dest_scan += DestBpp; 3180 src_scan ++; 3181 } 3182 } 3183 inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, 3184 FX_ARGB* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan) 3185 { 3186 int reset_r, reset_g, reset_b; 3187 int set_r, set_g, set_b; 3188 if (pPalette) { 3189 reset_r = FXARGB_R(pPalette[0]); 3190 reset_g = FXARGB_G(pPalette[0]); 3191 reset_b = FXARGB_B(pPalette[0]); 3192 set_r = FXARGB_R(pPalette[1]); 3193 set_g = FXARGB_G(pPalette[1]); 3194 set_b = FXARGB_B(pPalette[1]); 3195 } else { 3196 reset_r = reset_g = reset_b = 0; 3197 set_r = set_g = set_b = 255; 3198 } 3199 for (int col = 0; col < pixel_count; col ++) { 3200 int src_r, src_g, src_b; 3201 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { 3202 src_r = set_r; 3203 src_g = set_g; 3204 src_b = set_b; 3205 } else { 3206 src_r = reset_r; 3207 src_g = reset_g; 3208 src_b = reset_b; 3209 } 3210 if (clip_scan && clip_scan[col] < 255) { 3211 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]); 3212 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]); 3213 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]); 3214 } else { 3215 dest_scan[2] = src_b; 3216 dest_scan[1] = src_g; 3217 dest_scan[0] = src_r; 3218 } 3219 dest_scan += DestBpp; 3220 } 3221 } 3222 inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, 3223 FX_ARGB* pPalette, FX_LPCBYTE clip_scan) 3224 { 3225 for (int col = 0; col < width; col ++) { 3226 int src_r, src_g, src_b; 3227 if (pPalette) { 3228 FX_ARGB argb = pPalette[*src_scan]; 3229 src_r = FXARGB_R(argb); 3230 src_g = FXARGB_G(argb); 3231 src_b = FXARGB_B(argb); 3232 } else { 3233 src_r = src_g = src_b = *src_scan; 3234 } 3235 if (clip_scan == NULL || clip_scan[col] == 255) { 3236 dest_scan[2] = FX_GAMMA(src_b); 3237 dest_scan[1] = FX_GAMMA(src_g); 3238 dest_scan[0] = FX_GAMMA(src_r); 3239 dest_scan[3] = 255; 3240 src_scan ++; 3241 dest_scan += 4; 3242 continue; 3243 } 3244 int src_alpha = clip_scan[col]; 3245 if (src_alpha == 0) { 3246 dest_scan += 4; 3247 src_scan ++; 3248 continue; 3249 } 3250 int back_alpha = dest_scan[3]; 3251 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 3252 dest_scan[3] = dest_alpha; 3253 int alpha_ratio = src_alpha * 255 / dest_alpha; 3254 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio); 3255 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio); 3256 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio); 3257 dest_scan += 4; 3258 src_scan ++; 3259 } 3260 } 3261 inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, 3262 FX_ARGB* pPalette, FX_LPCBYTE clip_scan) 3263 { 3264 int reset_r, reset_g, reset_b; 3265 int set_r, set_g, set_b; 3266 if (pPalette) { 3267 reset_r = FXARGB_R(pPalette[0]); 3268 reset_g = FXARGB_G(pPalette[0]); 3269 reset_b = FXARGB_B(pPalette[0]); 3270 set_r = FXARGB_R(pPalette[1]); 3271 set_g = FXARGB_G(pPalette[1]); 3272 set_b = FXARGB_B(pPalette[1]); 3273 } else { 3274 reset_r = reset_g = reset_b = 0; 3275 set_r = set_g = set_b = 255; 3276 } 3277 for (int col = 0; col < width; col ++) { 3278 int src_r, src_g, src_b; 3279 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { 3280 src_r = set_r; 3281 src_g = set_g; 3282 src_b = set_b; 3283 } else { 3284 src_r = reset_r; 3285 src_g = reset_g; 3286 src_b = reset_b; 3287 } 3288 if (clip_scan == NULL || clip_scan[col] == 255) { 3289 dest_scan[2] = FX_GAMMA(src_b); 3290 dest_scan[1] = FX_GAMMA(src_g); 3291 dest_scan[0] = FX_GAMMA(src_r); 3292 dest_scan[3] = 255; 3293 dest_scan += 4; 3294 continue; 3295 } 3296 int src_alpha = clip_scan[col]; 3297 if (src_alpha == 0) { 3298 dest_scan += 4; 3299 continue; 3300 } 3301 int back_alpha = dest_scan[3]; 3302 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 3303 dest_scan[3] = dest_alpha; 3304 int alpha_ratio = src_alpha * 255 / dest_alpha; 3305 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio); 3306 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio); 3307 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio); 3308 dest_scan += 4; 3309 } 3310 } 3311 void _CompositeRow_ByteMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count, 3312 int blend_type, FX_LPCBYTE clip_scan) 3313 { 3314 for (int col = 0; col < pixel_count; col ++) { 3315 int src_alpha; 3316 if (clip_scan) { 3317 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; 3318 } else { 3319 src_alpha = mask_alpha * src_scan[col] / 255; 3320 } 3321 FX_BYTE back_alpha = dest_scan[3]; 3322 if (back_alpha == 0) { 3323 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); 3324 dest_scan += 4; 3325 continue; 3326 } 3327 if (src_alpha == 0) { 3328 dest_scan += 4; 3329 continue; 3330 } 3331 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 3332 dest_scan[3] = dest_alpha; 3333 int alpha_ratio = src_alpha * 255 / dest_alpha; 3334 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { 3335 int blended_colors[3]; 3336 FX_BYTE src_scan[3]; 3337 FX_BYTE dest_scan_o[3]; 3338 src_scan[0] = src_b; 3339 src_scan[1] = src_g; 3340 src_scan[2] = src_r; 3341 dest_scan_o[0] = dest_scan[2]; 3342 dest_scan_o[1] = dest_scan[1]; 3343 dest_scan_o[2] = dest_scan[0]; 3344 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); 3345 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio); 3346 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio); 3347 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio); 3348 } else if (blend_type) { 3349 int blended = _BLEND(blend_type, dest_scan[2], src_b); 3350 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); 3351 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio); 3352 blended = _BLEND(blend_type, dest_scan[1], src_g); 3353 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); 3354 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio); 3355 blended = _BLEND(blend_type, dest_scan[0], src_r); 3356 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); 3357 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio); 3358 } else { 3359 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio); 3360 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio); 3361 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio); 3362 } 3363 dest_scan += 4; 3364 } 3365 } 3366 void _CompositeRow_ByteMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count, 3367 int blend_type, int Bpp, FX_LPCBYTE clip_scan) 3368 { 3369 for (int col = 0; col < pixel_count; col ++) { 3370 int src_alpha; 3371 if (clip_scan) { 3372 src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; 3373 } else { 3374 src_alpha = mask_alpha * src_scan[col] / 255; 3375 } 3376 if (src_alpha == 0) { 3377 dest_scan += Bpp; 3378 continue; 3379 } 3380 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { 3381 int blended_colors[3]; 3382 FX_BYTE src_scan[3]; 3383 FX_BYTE dest_scan_o[3]; 3384 src_scan[0] = src_b; 3385 src_scan[1] = src_g; 3386 src_scan[2] = src_r; 3387 dest_scan_o[0] = dest_scan[2]; 3388 dest_scan_o[1] = dest_scan[1]; 3389 dest_scan_o[2] = dest_scan[0]; 3390 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); 3391 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha); 3392 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha); 3393 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha); 3394 } else if (blend_type) { 3395 int blended = _BLEND(blend_type, dest_scan[2], src_b); 3396 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha); 3397 blended = _BLEND(blend_type, dest_scan[1], src_g); 3398 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha); 3399 blended = _BLEND(blend_type, dest_scan[0], src_r); 3400 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha); 3401 } else { 3402 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha); 3403 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha); 3404 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha); 3405 } 3406 dest_scan += Bpp; 3407 } 3408 } 3409 void _CompositeRow_BitMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, 3410 int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan) 3411 { 3412 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) { 3413 FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b); 3414 for (int col = 0; col < pixel_count; col ++) { 3415 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { 3416 FXARGB_SETRGBORDERDIB(dest_scan, argb); 3417 } 3418 dest_scan += 4; 3419 } 3420 return; 3421 } 3422 for (int col = 0; col < pixel_count; col ++) { 3423 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { 3424 dest_scan += 4; 3425 continue; 3426 } 3427 int src_alpha; 3428 if (clip_scan) { 3429 src_alpha = mask_alpha * clip_scan[col] / 255; 3430 } else { 3431 src_alpha = mask_alpha; 3432 } 3433 FX_BYTE back_alpha = dest_scan[3]; 3434 if (back_alpha == 0) { 3435 FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); 3436 dest_scan += 4; 3437 continue; 3438 } 3439 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 3440 dest_scan[3] = dest_alpha; 3441 int alpha_ratio = src_alpha * 255 / dest_alpha; 3442 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { 3443 int blended_colors[3]; 3444 FX_BYTE src_scan[3]; 3445 FX_BYTE dest_scan_o[3]; 3446 src_scan[0] = src_b; 3447 src_scan[1] = src_g; 3448 src_scan[2] = src_r; 3449 dest_scan_o[0] = dest_scan[2]; 3450 dest_scan_o[1] = dest_scan[1]; 3451 dest_scan_o[2] = dest_scan[0]; 3452 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); 3453 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio); 3454 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio); 3455 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio); 3456 } else if (blend_type) { 3457 int blended = _BLEND(blend_type, dest_scan[2], src_b); 3458 blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); 3459 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio); 3460 blended = _BLEND(blend_type, dest_scan[1], src_g); 3461 blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); 3462 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio); 3463 blended = _BLEND(blend_type, dest_scan[0], src_r); 3464 blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); 3465 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio); 3466 } else { 3467 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio); 3468 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio); 3469 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio); 3470 } 3471 dest_scan += 4; 3472 } 3473 } 3474 void _CompositeRow_BitMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, 3475 int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan) 3476 { 3477 if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) { 3478 for (int col = 0; col < pixel_count; col ++) { 3479 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { 3480 dest_scan[2] = src_b; 3481 dest_scan[1] = src_g; 3482 dest_scan[0] = src_r; 3483 } 3484 dest_scan += Bpp; 3485 } 3486 return; 3487 } 3488 for (int col = 0; col < pixel_count; col ++) { 3489 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { 3490 dest_scan += Bpp; 3491 continue; 3492 } 3493 int src_alpha; 3494 if (clip_scan) { 3495 src_alpha = mask_alpha * clip_scan[col] / 255; 3496 } else { 3497 src_alpha = mask_alpha; 3498 } 3499 if (src_alpha == 0) { 3500 dest_scan += Bpp; 3501 continue; 3502 } 3503 if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { 3504 int blended_colors[3]; 3505 FX_BYTE src_scan[3]; 3506 FX_BYTE dest_scan_o[3]; 3507 src_scan[0] = src_b; 3508 src_scan[1] = src_g; 3509 src_scan[2] = src_r; 3510 dest_scan_o[0] = dest_scan[2]; 3511 dest_scan_o[1] = dest_scan[1]; 3512 dest_scan_o[2] = dest_scan[0]; 3513 _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); 3514 dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha); 3515 dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha); 3516 dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha); 3517 } else if (blend_type) { 3518 int back_color = FX_GAMMA(dest_scan[2]); 3519 int blended = _BLEND(blend_type, back_color, src_b); 3520 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); 3521 back_color = FX_GAMMA(dest_scan[1]); 3522 blended = _BLEND(blend_type, back_color, src_g); 3523 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); 3524 back_color = FX_GAMMA(dest_scan[0]); 3525 blended = _BLEND(blend_type, back_color, src_r); 3526 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); 3527 } else { 3528 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha)); 3529 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha)); 3530 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha)); 3531 } 3532 dest_scan += Bpp; 3533 } 3534 } 3535 inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, int alpha_flag, FX_DWORD mask_color, int& mask_alpha, 3536 int& mask_red, int& mask_green, int& mask_blue, int& mask_black, 3537 void* icc_module, void* pIccTransform) 3538 { 3539 ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module; 3540 if (alpha_flag >> 8) { 3541 mask_alpha = alpha_flag & 0xff; 3542 mask_red = FXSYS_GetCValue(mask_color); 3543 mask_green = FXSYS_GetMValue(mask_color); 3544 mask_blue = FXSYS_GetYValue(mask_color); 3545 mask_black = FXSYS_GetKValue(mask_color); 3546 } else { 3547 mask_alpha = FXARGB_A(mask_color); 3548 mask_red = FXARGB_R(mask_color); 3549 mask_green = FXARGB_G(mask_color); 3550 mask_blue = FXARGB_B(mask_color); 3551 } 3552 if (dest_format == FXDIB_8bppMask) { 3553 return TRUE; 3554 } 3555 if ((dest_format & 0xff) == 8) { 3556 if (pIccTransform) { 3557 mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color); 3558 FX_LPBYTE gray_p = (FX_LPBYTE)&mask_color; 3559 pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1); 3560 mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0]; 3561 } else { 3562 if (alpha_flag >> 8) { 3563 FX_BYTE r, g, b; 3564 AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black, 3565 r, g, b); 3566 mask_red = FXRGB2GRAY(r, g, b); 3567 } else { 3568 mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue); 3569 } 3570 if (dest_format & 0x0400) { 3571 mask_red = FX_CCOLOR(mask_red); 3572 } 3573 } 3574 } else { 3575 FX_LPBYTE mask_color_p = (FX_LPBYTE)&mask_color; 3576 mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color); 3577 if (pIccTransform) { 3578 pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, 1); 3579 mask_red = mask_color_p[2]; 3580 mask_green = mask_color_p[1]; 3581 mask_blue = mask_color_p[0]; 3582 } else if (alpha_flag >> 8) { 3583 AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], mask_color_p[3], 3584 mask_color_p[2], mask_color_p[1], mask_color_p[0]); 3585 mask_red = mask_color_p[2]; 3586 mask_green = mask_color_p[1]; 3587 mask_blue = mask_color_p[0]; 3588 } 3589 } 3590 return TRUE; 3591 } 3592 inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, FXDIB_Format dest_format, 3593 FX_DWORD*& pDestPalette, FX_DWORD* pSrcPalette, 3594 void* icc_module, void* pIccTransform) 3595 { 3596 ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module; 3597 FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE; 3598 FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE; 3599 pDestPalette = NULL; 3600 if (pIccTransform) { 3601 if (pSrcPalette) { 3602 if ((dest_format & 0xff) == 8) { 3603 int pal_count = 1 << (src_format & 0xff); 3604 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count); 3605 if (!gray_pal) { 3606 return; 3607 } 3608 pDestPalette = (FX_DWORD*)gray_pal; 3609 for (int i = 0; i < pal_count; i ++) { 3610 FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]); 3611 pIccModule->TranslateScanline(pIccTransform, gray_pal, (FX_LPCBYTE)&color, 1); 3612 gray_pal ++; 3613 } 3614 } else { 3615 int palsize = 1 << (src_format & 0xff); 3616 pDestPalette = FX_Alloc(FX_DWORD, palsize); 3617 if (!pDestPalette) { 3618 return; 3619 } 3620 for (int i = 0; i < palsize; i ++) { 3621 FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]); 3622 pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&color, (FX_LPCBYTE)&color, 1); 3623 pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); 3624 } 3625 } 3626 } else { 3627 int pal_count = 1 << (src_format & 0xff); 3628 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count); 3629 if (!gray_pal) { 3630 return; 3631 } 3632 if (pal_count == 2) { 3633 gray_pal[0] = 0; 3634 gray_pal[1] = 255; 3635 } else { 3636 for (int i = 0; i < pal_count; i++) { 3637 gray_pal[i] = i; 3638 } 3639 } 3640 if ((dest_format & 0xff) == 8) { 3641 pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, pal_count); 3642 pDestPalette = (FX_DWORD*)gray_pal; 3643 } else { 3644 pDestPalette = FX_Alloc(FX_DWORD, pal_count); 3645 if (!pDestPalette) { 3646 FX_Free(gray_pal); 3647 return; 3648 } 3649 for (int i = 0; i < pal_count; i ++) { 3650 pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&pDestPalette[i], &gray_pal[i], 1); 3651 pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) : FXARGB_TODIB(pDestPalette[i]); 3652 } 3653 FX_Free(gray_pal); 3654 } 3655 } 3656 } else { 3657 if (pSrcPalette) { 3658 if ((dest_format & 0xff) == 8) { 3659 int pal_count = 1 << (src_format & 0xff); 3660 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count); 3661 if (!gray_pal) { 3662 return; 3663 } 3664 pDestPalette = (FX_DWORD*)gray_pal; 3665 if (isSrcCmyk) { 3666 for (int i = 0; i < pal_count; i ++) { 3667 FX_CMYK cmyk = pSrcPalette[i]; 3668 FX_BYTE r, g, b; 3669 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), 3670 r, g, b); 3671 *gray_pal ++ = FXRGB2GRAY(r, g, b); 3672 } 3673 } else 3674 for (int i = 0; i < pal_count; i ++) { 3675 FX_ARGB argb = pSrcPalette[i]; 3676 *gray_pal ++ = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); 3677 } 3678 } else { 3679 int palsize = 1 << (src_format & 0xff); 3680 pDestPalette = FX_Alloc(FX_DWORD, palsize); 3681 if (!pDestPalette) { 3682 return; 3683 } 3684 if (isDstCmyk == isSrcCmyk) { 3685 FXSYS_memcpy32(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD)); 3686 } else { 3687 for (int i = 0; i < palsize; i ++) { 3688 FX_CMYK cmyk = pSrcPalette[i]; 3689 FX_BYTE r, g, b; 3690 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), 3691 r, g, b); 3692 pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b); 3693 } 3694 } 3695 } 3696 } else { 3697 if ((dest_format & 0xff) == 8) { 3698 int pal_count = 1 << (src_format & 0xff); 3699 FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count); 3700 if (!gray_pal) { 3701 return; 3702 } 3703 if (pal_count == 2) { 3704 gray_pal[0] = 0; 3705 gray_pal[1] = 255; 3706 } else { 3707 for (int i = 0; i < pal_count; i++) { 3708 gray_pal[i] = i; 3709 } 3710 } 3711 pDestPalette = (FX_DWORD*)gray_pal; 3712 } else { 3713 int palsize = 1 << (src_format & 0xff); 3714 pDestPalette = FX_Alloc(FX_DWORD, palsize); 3715 if (!pDestPalette) { 3716 return; 3717 } 3718 if (palsize == 2) { 3719 pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000; 3720 pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff; 3721 } else { 3722 for (int i = 0; i < palsize; i++) { 3723 pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101); 3724 } 3725 } 3726 if (isSrcCmyk != isDstCmyk) { 3727 for (int i = 0; i < palsize; i ++) { 3728 FX_CMYK cmyk = pDestPalette[i]; 3729 FX_BYTE r, g, b; 3730 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), 3731 r, g, b); 3732 pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b); 3733 } 3734 } 3735 } 3736 } 3737 } 3738 } 3739 CFX_ScanlineCompositor::CFX_ScanlineCompositor() 3740 { 3741 m_pSrcPalette = NULL; 3742 m_pCacheScanline = NULL; 3743 m_CacheSize = 0; 3744 m_bRgbByteOrder = FALSE; 3745 m_BlendType = FXDIB_BLEND_NORMAL; 3746 } 3747 CFX_ScanlineCompositor::~CFX_ScanlineCompositor() 3748 { 3749 if (m_pSrcPalette) { 3750 FX_Free(m_pSrcPalette); 3751 } 3752 if (m_pCacheScanline) { 3753 FX_Free(m_pCacheScanline); 3754 } 3755 } 3756 FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, FXDIB_Format src_format, FX_INT32 width, FX_DWORD* pSrcPalette, 3757 FX_DWORD mask_color, int blend_type, FX_BOOL bClip, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform) 3758 { 3759 m_SrcFormat = src_format; 3760 m_DestFormat = dest_format; 3761 m_BlendType = blend_type; 3762 m_bRgbByteOrder = bRgbByteOrder; 3763 ICodec_IccModule* pIccModule = NULL; 3764 if (CFX_GEModule::Get()->GetCodecModule()) { 3765 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); 3766 } 3767 if (pIccModule == NULL) { 3768 pIccTransform = NULL; 3769 } 3770 m_pIccTransform = pIccTransform; 3771 if ((dest_format & 0xff) == 1) { 3772 return FALSE; 3773 } 3774 if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) { 3775 return _ScanlineCompositor_InitSourceMask(dest_format, alpha_flag, mask_color, 3776 m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack, 3777 pIccModule, pIccTransform); 3778 } 3779 if (pIccTransform == NULL && (~src_format & 0x0400) && (dest_format & 0x0400)) { 3780 return FALSE; 3781 } 3782 if ((m_SrcFormat & 0xff) <= 8) { 3783 if (dest_format == FXDIB_8bppMask) { 3784 return TRUE; 3785 } 3786 _ScanlineCompositor_InitSourcePalette(src_format, dest_format, m_pSrcPalette, pSrcPalette, 3787 pIccModule, pIccTransform); 3788 m_Transparency = (dest_format == FXDIB_Argb ? 1 : 0) 3789 + (dest_format & 0x0200 ? 2 : 0) 3790 + (dest_format & 0x0400 ? 4 : 0) 3791 + ((src_format & 0xff) == 1 ? 8 : 0); 3792 return TRUE; 3793 } 3794 m_Transparency = (src_format & 0x0200 ? 0 : 1) 3795 + (dest_format & 0x0200 ? 0 : 2) 3796 + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0) 3797 + (bClip ? 8 : 0) 3798 + (src_format & 0x0400 ? 16 : 0) 3799 + (dest_format & 0x0400 ? 32 : 0) 3800 + (pIccTransform ? 64 : 0); 3801 return TRUE; 3802 } 3803 void CFX_ScanlineCompositor::CompositeRgbBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan, 3804 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha) 3805 { 3806 int src_Bpp = (m_SrcFormat & 0xff) >> 3; 3807 int dest_Bpp = (m_DestFormat & 0xff) >> 3; 3808 int dest_Size = width * dest_Bpp + 4; 3809 if (m_bRgbByteOrder) { 3810 switch (m_Transparency) { 3811 case 0: 3812 case 4: 3813 case 8: 3814 case 12: 3815 _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, clip_scan); 3816 break; 3817 case 1: 3818 _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp); 3819 break; 3820 case 2: 3821 case 10: 3822 _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan); 3823 break; 3824 case 3: 3825 _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp); 3826 break; 3827 case 5: 3828 _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp); 3829 break; 3830 case 6: 3831 case 14: 3832 _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, clip_scan); 3833 break; 3834 case 7: 3835 _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp); 3836 break; 3837 case 9: 3838 _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan); 3839 break; 3840 case 11: 3841 _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan); 3842 break; 3843 case 13: 3844 _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp, clip_scan); 3845 break; 3846 case 15: 3847 _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan); 3848 break; 3849 } 3850 return; 3851 } 3852 if (m_DestFormat == FXDIB_8bppMask) { 3853 if (m_SrcFormat & 0x0200) { 3854 if (m_SrcFormat == FXDIB_Argb) { 3855 _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan); 3856 } else { 3857 _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan); 3858 } 3859 } else { 3860 _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan); 3861 } 3862 } else if ((m_DestFormat & 0xff) == 8) { 3863 if (m_DestFormat & 0x0400) { 3864 for (int i = 0; i < width; i ++) { 3865 *dest_scan = ~*dest_scan; 3866 dest_scan++; 3867 } 3868 } 3869 if (m_SrcFormat & 0x0200) { 3870 if (m_DestFormat & 0x0200) { 3871 _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, dst_extra_alpha, m_pIccTransform); 3872 } else { 3873 _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, m_pIccTransform); 3874 } 3875 } else { 3876 if (m_DestFormat & 0x0200) { 3877 _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, dst_extra_alpha, m_pIccTransform); 3878 } else { 3879 _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, m_pIccTransform); 3880 } 3881 } 3882 if (m_DestFormat & 0x0400) { 3883 for (int i = 0; i < width; i ++) { 3884 *dest_scan = ~*dest_scan; 3885 dest_scan++; 3886 } 3887 } 3888 } else { 3889 if (dest_Size > m_CacheSize) { 3890 m_pCacheScanline = FX_Realloc(FX_BYTE, m_pCacheScanline, dest_Size); 3891 if (!m_pCacheScanline) { 3892 return; 3893 } 3894 m_CacheSize = dest_Size; 3895 } 3896 switch (m_Transparency) { 3897 case 0: 3898 case 4: 3899 case 8: 3900 case 4+8: { 3901 _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, clip_scan, 3902 dst_extra_alpha, src_extra_alpha); 3903 } 3904 break; 3905 case 64: 3906 case 4+64: 3907 case 8+64: 3908 case 4+8+64: { 3909 _CompositeRow_Argb2Argb_Transform(dest_scan, src_scan, width, m_BlendType, clip_scan, 3910 dst_extra_alpha, src_extra_alpha, m_pCacheScanline, m_pIccTransform); 3911 } 3912 break; 3913 case 1: 3914 _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, src_Bpp, 3915 dst_extra_alpha); 3916 break; 3917 case 1+64: 3918 _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, 3919 dst_extra_alpha, m_pCacheScanline, m_pIccTransform); 3920 break; 3921 case 1+8: 3922 _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan, 3923 dst_extra_alpha); 3924 break; 3925 case 1+8+64: 3926 _CompositeRow_Rgb2Argb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan, 3927 dst_extra_alpha, m_pCacheScanline, m_pIccTransform); 3928 break; 3929 case 1+4: 3930 _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp, 3931 dst_extra_alpha); 3932 break; 3933 case 1+4+64: 3934 _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, src_Bpp, 3935 dst_extra_alpha, m_pCacheScanline, m_pIccTransform); 3936 break; 3937 case 1+4+8: 3938 _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, clip_scan, 3939 dst_extra_alpha); 3940 break; 3941 case 1+4+8+64: 3942 _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(dest_scan, src_scan, width, src_Bpp, clip_scan, 3943 dst_extra_alpha, m_pCacheScanline, m_pIccTransform); 3944 break; 3945 case 2: 3946 case 2+8: 3947 _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan, 3948 src_extra_alpha); 3949 break; 3950 case 2+64: 3951 case 2+8+64: 3952 _CompositeRow_Argb2Rgb_Blend_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan, 3953 src_extra_alpha, m_pCacheScanline, m_pIccTransform); 3954 break; 3955 case 2+4: 3956 case 2+4+8: 3957 _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, clip_scan, 3958 src_extra_alpha); 3959 break; 3960 case 2+4+64: 3961 case 2+4+8+64: 3962 _CompositeRow_Argb2Rgb_NoBlend_Transform(dest_scan, src_scan, width, dest_Bpp, clip_scan, 3963 src_extra_alpha, m_pCacheScanline, m_pIccTransform); 3964 break; 3965 case 1+2: 3966 _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp); 3967 break; 3968 case 1+2+64: 3969 _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, 3970 m_pCacheScanline, m_pIccTransform); 3971 break; 3972 case 1+2+8: 3973 _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan); 3974 break; 3975 case 1+2+8+64: 3976 _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan, 3977 m_pCacheScanline, m_pIccTransform); 3978 break; 3979 case 1+2+4: 3980 _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp, src_Bpp); 3981 break; 3982 case 1+2+4+64: 3983 _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, 3984 m_pCacheScanline, m_pIccTransform); 3985 break; 3986 case 1+2+4+8: 3987 _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan); 3988 break; 3989 case 1+2+4+8+64: 3990 _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan, 3991 m_pCacheScanline, m_pIccTransform); 3992 break; 3993 } 3994 } 3995 } 3996 void CFX_ScanlineCompositor::CompositePalBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan, 3997 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha) 3998 { 3999 if (m_bRgbByteOrder) { 4000 if (m_SrcFormat == FXDIB_1bppRgb) { 4001 if (m_DestFormat == FXDIB_8bppRgb) { 4002 return; 4003 } else if(m_DestFormat == FXDIB_Argb) { 4004 _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan); 4005 } else { 4006 _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan); 4007 } 4008 } else { 4009 if (m_DestFormat == FXDIB_8bppRgb) { 4010 return; 4011 } else if (m_DestFormat == FXDIB_Argb) { 4012 _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, m_pSrcPalette, clip_scan); 4013 } else { 4014 _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan); 4015 } 4016 } 4017 return; 4018 } 4019 if (m_DestFormat == FXDIB_8bppMask) { 4020 _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan); 4021 return; 4022 } else if ((m_DestFormat & 0xff) == 8) { 4023 if (m_Transparency & 8) { 4024 if (m_DestFormat & 0x0200) { 4025 _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, dst_extra_alpha); 4026 } else { 4027 _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan); 4028 } 4029 } else { 4030 if (m_DestFormat & 0x0200) 4031 _CompositeRow_8bppPal2Graya(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, 4032 dst_extra_alpha, src_extra_alpha); 4033 else 4034 _CompositeRow_8bppPal2Gray(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, 4035 src_extra_alpha); 4036 } 4037 } else { 4038 switch (m_Transparency) { 4039 case 1+2: 4040 _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, m_pSrcPalette, clip_scan, 4041 src_extra_alpha); 4042 break; 4043 case 1+2+8: 4044 _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan); 4045 break; 4046 case 0: 4047 _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan, 4048 src_extra_alpha); 4049 break; 4050 case 0+8: 4051 _CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan); 4052 break; 4053 case 0+2: 4054 _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan, 4055 src_extra_alpha); 4056 break; 4057 case 0+2+8: 4058 _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan, 4059 dst_extra_alpha); 4060 break; 4061 break; 4062 } 4063 } 4064 } 4065 void CFX_ScanlineCompositor::CompositeByteMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan, 4066 FX_LPBYTE dst_extra_alpha) 4067 { 4068 if (m_DestFormat == FXDIB_8bppMask) { 4069 _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, clip_scan); 4070 } else if ((m_DestFormat & 0xff) == 8) { 4071 if (m_DestFormat & 0x0200) { 4072 _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan, dst_extra_alpha); 4073 } else { 4074 _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan); 4075 } 4076 } else if (m_bRgbByteOrder) { 4077 if (m_DestFormat == FXDIB_Argb) 4078 _CompositeRow_ByteMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4079 width, m_BlendType, clip_scan); 4080 else 4081 _CompositeRow_ByteMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4082 width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); 4083 return; 4084 } else if (m_DestFormat == FXDIB_Argb) 4085 _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4086 width, m_BlendType, clip_scan); 4087 else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32) 4088 _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4089 width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); 4090 else if (m_DestFormat == FXDIB_Rgba) 4091 _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4092 width, m_BlendType, clip_scan, dst_extra_alpha); 4093 } 4094 void CFX_ScanlineCompositor::CompositeBitMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan, 4095 FX_LPBYTE dst_extra_alpha) 4096 { 4097 if (m_DestFormat == FXDIB_8bppMask) { 4098 _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width, clip_scan); 4099 } else if ((m_DestFormat & 0xff) == 8) { 4100 if (m_DestFormat & 0x0200) 4101 _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan, 4102 dst_extra_alpha); 4103 else { 4104 _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan); 4105 } 4106 } else if (m_bRgbByteOrder) { 4107 if (m_DestFormat == FXDIB_Argb) 4108 _CompositeRow_BitMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4109 src_left, width, m_BlendType, clip_scan); 4110 else 4111 _CompositeRow_BitMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4112 src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); 4113 return; 4114 } else if (m_DestFormat == FXDIB_Argb) 4115 _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4116 src_left, width, m_BlendType, clip_scan); 4117 else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32) 4118 _CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, 4119 src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); 4120 } 4121 FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, int dest_top, int width, int height, 4122 const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, 4123 int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, void* pIccTransform) 4124 { 4125 if (m_pBuffer == NULL) { 4126 return FALSE; 4127 } 4128 ASSERT(!pSrcBitmap->IsAlphaMask()); 4129 ASSERT(m_bpp >= 8); 4130 if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) { 4131 return FALSE; 4132 } 4133 GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), 4134 src_left, src_top, pClipRgn); 4135 if (width == 0 || height == 0) { 4136 return TRUE; 4137 } 4138 const CFX_DIBitmap* pClipMask = NULL; 4139 FX_RECT clip_box; 4140 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { 4141 ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF); 4142 pClipMask = pClipRgn->GetMask(); 4143 clip_box = pClipRgn->GetBox(); 4144 } 4145 CFX_ScanlineCompositor compositor; 4146 if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, pSrcBitmap->GetPalette(), 0, blend_type, 4147 pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) { 4148 return FALSE; 4149 } 4150 int dest_Bpp = m_bpp / 8; 4151 int src_Bpp = pSrcBitmap->GetBPP() / 8; 4152 FX_BOOL bRgb = FALSE; 4153 FX_BOOL bCmyk = FALSE; 4154 if (src_Bpp > 1) { 4155 if (pSrcBitmap->IsCmykImage()) { 4156 bCmyk = TRUE; 4157 } else { 4158 bRgb = TRUE; 4159 } 4160 } 4161 CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask; 4162 for (int row = 0; row < height; row ++) { 4163 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp; 4164 FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp; 4165 FX_LPCBYTE src_scan_extra_alpha = pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left : NULL; 4166 FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL; 4167 FX_LPCBYTE clip_scan = NULL; 4168 if (pClipMask) { 4169 clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left); 4170 } 4171 if (bRgb) { 4172 compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha); 4173 } else { 4174 compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha); 4175 } 4176 } 4177 return TRUE; 4178 } 4179 FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, int dest_top, int width, int height, 4180 const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top, 4181 int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform) 4182 { 4183 if (m_pBuffer == NULL) { 4184 return FALSE; 4185 } 4186 ASSERT(pMask->IsAlphaMask()); 4187 ASSERT(m_bpp >= 8); 4188 if (!pMask->IsAlphaMask() || m_bpp < 8) { 4189 return FALSE; 4190 } 4191 GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, pClipRgn); 4192 if (width == 0 || height == 0) { 4193 return TRUE; 4194 } 4195 int src_alpha = (FX_BYTE)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color); 4196 if (src_alpha == 0) { 4197 return TRUE; 4198 } 4199 const CFX_DIBitmap* pClipMask = NULL; 4200 FX_RECT clip_box; 4201 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { 4202 ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF); 4203 pClipMask = pClipRgn->GetMask(); 4204 clip_box = pClipRgn->GetBox(); 4205 } 4206 int src_bpp = pMask->GetBPP(); 4207 int Bpp = GetBPP() / 8; 4208 CFX_ScanlineCompositor compositor; 4209 if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, pIccTransform)) { 4210 return FALSE; 4211 } 4212 for (int row = 0; row < height; row ++) { 4213 FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp; 4214 FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row); 4215 FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL; 4216 FX_LPCBYTE clip_scan = NULL; 4217 if (pClipMask) { 4218 clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left); 4219 } 4220 if (src_bpp == 1) { 4221 compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, clip_scan, dst_scan_extra_alpha); 4222 } else { 4223 compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, clip_scan, dst_scan_extra_alpha); 4224 } 4225 } 4226 return TRUE; 4227 } 4228 FX_BOOL CFX_DIBitmap::CompositeRect(int left, int top, int width, int height, FX_DWORD color, int alpha_flag, void* pIccTransform) 4229 { 4230 if (m_pBuffer == NULL) { 4231 return FALSE; 4232 } 4233 int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color); 4234 if (src_alpha == 0) { 4235 return TRUE; 4236 } 4237 FX_RECT rect(left, top, left + width, top + height); 4238 rect.Intersect(0, 0, m_Width, m_Height); 4239 if (rect.IsEmpty()) { 4240 return TRUE; 4241 } 4242 width = rect.Width(); 4243 FX_DWORD dst_color; 4244 if (alpha_flag >> 8) { 4245 dst_color = FXCMYK_TODIB(color); 4246 } else { 4247 dst_color = FXARGB_TODIB(color); 4248 } 4249 FX_LPBYTE color_p = (FX_LPBYTE)&dst_color; 4250 if (m_bpp == 8) { 4251 FX_BYTE gray = 255; 4252 if (!IsAlphaMask()) { 4253 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { 4254 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); 4255 pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1); 4256 } else { 4257 if (alpha_flag >> 8) { 4258 FX_BYTE r, g, b; 4259 AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3], 4260 r, g, b); 4261 gray = FXRGB2GRAY(r, g, b); 4262 } else { 4263 gray = (FX_BYTE)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]); 4264 } 4265 } 4266 if (IsCmykImage()) { 4267 gray = ~gray; 4268 } 4269 } 4270 for (int row = rect.top; row < rect.bottom; row ++) { 4271 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left; 4272 if (src_alpha == 255) { 4273 FXSYS_memset8(dest_scan, gray, width); 4274 } else 4275 for (int col = 0; col < width; col ++) { 4276 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); 4277 dest_scan ++; 4278 } 4279 } 4280 return TRUE; 4281 } else if (m_bpp == 1) { 4282 ASSERT(!IsCmykImage() && (FX_BYTE)(alpha_flag >> 8) == 0); 4283 int left_shift = rect.left % 8; 4284 int right_shift = rect.right % 8; 4285 int width = rect.right / 8 - rect.left / 8; 4286 int index = 0; 4287 if (m_pPalette == NULL) { 4288 index = ((FX_BYTE)color == 0xff) ? 1 : 0; 4289 } else { 4290 for (int i = 0; i < 2; i ++) 4291 if (m_pPalette[i] == color) { 4292 index = i; 4293 } 4294 } 4295 for (int row = rect.top; row < rect.bottom; row ++) { 4296 FX_BYTE* dest_scan_top = (FX_BYTE*)GetScanline(row) + rect.left / 8; 4297 FX_BYTE* dest_scan_top_r = (FX_BYTE*)GetScanline(row) + rect.right / 8; 4298 FX_BYTE left_flag = *dest_scan_top & (255 << (8 - left_shift)); 4299 FX_BYTE right_flag = *dest_scan_top_r & (255 >> right_shift); 4300 if (width) { 4301 FXSYS_memset8(dest_scan_top + 1, index ? 255 : 0, width - 1); 4302 if (!index) { 4303 *dest_scan_top &= left_flag; 4304 *dest_scan_top_r &= right_flag; 4305 } else { 4306 *dest_scan_top |= ~left_flag; 4307 *dest_scan_top_r |= ~right_flag; 4308 } 4309 } else { 4310 if (!index) { 4311 *dest_scan_top &= left_flag | right_flag; 4312 } else { 4313 *dest_scan_top |= ~(left_flag | right_flag); 4314 } 4315 } 4316 } 4317 return TRUE; 4318 } 4319 ASSERT(m_bpp >= 24); 4320 if (m_bpp < 24) { 4321 return FALSE; 4322 } 4323 if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) { 4324 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); 4325 pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); 4326 } else { 4327 if (alpha_flag >> 8 && !IsCmykImage()) 4328 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), 4329 color_p[2], color_p[1], color_p[0]); 4330 else if (!(alpha_flag >> 8) && IsCmykImage()) { 4331 return FALSE; 4332 } 4333 } 4334 if(!IsCmykImage()) { 4335 color_p[3] = (FX_BYTE)src_alpha; 4336 } 4337 int Bpp = m_bpp / 8; 4338 FX_BOOL bAlpha = HasAlpha(); 4339 FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE; 4340 if (src_alpha == 255) { 4341 for (int row = rect.top; row < rect.bottom; row ++) { 4342 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp; 4343 FX_LPBYTE dest_scan_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left : NULL; 4344 if (dest_scan_alpha) { 4345 FXSYS_memset8(dest_scan_alpha, 0xff, width); 4346 } 4347 if (Bpp == 4) { 4348 FX_DWORD* scan = (FX_DWORD*)dest_scan; 4349 for (int col = 0; col < width; col ++) { 4350 *scan ++ = dst_color; 4351 } 4352 } else { 4353 for (int col = 0; col < width; col ++) { 4354 *dest_scan ++ = color_p[0]; 4355 *dest_scan ++ = color_p[1]; 4356 *dest_scan ++ = color_p[2]; 4357 } 4358 } 4359 } 4360 return TRUE; 4361 } 4362 for (int row = rect.top; row < rect.bottom; row ++) { 4363 FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp; 4364 if (bAlpha) { 4365 if (bArgb) { 4366 for (int col = 0; col < width; col ++) { 4367 FX_BYTE back_alpha = dest_scan[3]; 4368 if (back_alpha == 0) { 4369 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], color_p[1], color_p[0])); 4370 dest_scan += 4; 4371 continue; 4372 } 4373 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 4374 int alpha_ratio = src_alpha * 255 / dest_alpha; 4375 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio); 4376 dest_scan ++; 4377 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio); 4378 dest_scan ++; 4379 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio); 4380 dest_scan ++; 4381 *dest_scan++ = dest_alpha; 4382 } 4383 } else { 4384 FX_LPBYTE dest_scan_alpha = (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left; 4385 for (int col = 0; col < width; col ++) { 4386 FX_BYTE back_alpha = *dest_scan_alpha; 4387 if (back_alpha == 0) { 4388 *dest_scan_alpha++ = src_alpha; 4389 FXSYS_memcpy32(dest_scan, color_p, Bpp); 4390 dest_scan += Bpp; 4391 continue; 4392 } 4393 FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; 4394 *dest_scan_alpha ++ = dest_alpha; 4395 int alpha_ratio = src_alpha * 255 / dest_alpha; 4396 for(int comps = 0; comps < Bpp; comps ++) { 4397 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio); 4398 dest_scan ++; 4399 } 4400 } 4401 } 4402 } else { 4403 for (int col = 0; col < width; col ++) { 4404 for(int comps = 0; comps < Bpp; comps ++) { 4405 if (comps == 3) { 4406 *dest_scan ++ = 255; 4407 continue; 4408 } 4409 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha); 4410 dest_scan ++; 4411 } 4412 } 4413 } 4414 } 4415 return TRUE; 4416 } 4417 CFX_BitmapComposer::CFX_BitmapComposer() 4418 { 4419 m_pScanlineV = NULL; 4420 m_pScanlineAlphaV = NULL; 4421 m_pClipScanV = NULL; 4422 m_pAddClipScan = NULL; 4423 m_bRgbByteOrder = FALSE; 4424 m_BlendType = FXDIB_BLEND_NORMAL; 4425 } 4426 CFX_BitmapComposer::~CFX_BitmapComposer() 4427 { 4428 if (m_pScanlineV) { 4429 FX_Free(m_pScanlineV); 4430 } 4431 if (m_pScanlineAlphaV) { 4432 FX_Free(m_pScanlineAlphaV); 4433 } 4434 if (m_pClipScanV) { 4435 FX_Free(m_pClipScanV); 4436 } 4437 if (m_pAddClipScan) { 4438 FX_Free(m_pAddClipScan); 4439 } 4440 } 4441 void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, const CFX_ClipRgn* pClipRgn, int bitmap_alpha, 4442 FX_DWORD mask_color, FX_RECT& dest_rect, FX_BOOL bVertical, 4443 FX_BOOL bFlipX, FX_BOOL bFlipY, FX_BOOL bRgbByteOrder, 4444 int alpha_flag, void* pIccTransform, int blend_type) 4445 { 4446 m_pBitmap = pDest; 4447 m_pClipRgn = pClipRgn; 4448 m_DestLeft = dest_rect.left; 4449 m_DestTop = dest_rect.top; 4450 m_DestWidth = dest_rect.Width(); 4451 m_DestHeight = dest_rect.Height(); 4452 m_BitmapAlpha = bitmap_alpha; 4453 m_MaskColor = mask_color; 4454 m_pClipMask = NULL; 4455 if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { 4456 m_pClipMask = pClipRgn->GetMask(); 4457 } 4458 m_bVertical = bVertical; 4459 m_bFlipX = bFlipX; 4460 m_bFlipY = bFlipY; 4461 m_AlphaFlag = alpha_flag; 4462 m_pIccTransform = pIccTransform; 4463 m_bRgbByteOrder = bRgbByteOrder; 4464 m_BlendType = blend_type; 4465 } 4466 FX_BOOL CFX_BitmapComposer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette) 4467 { 4468 m_SrcFormat = src_format; 4469 if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, m_MaskColor, FXDIB_BLEND_NORMAL, 4470 m_pClipMask != NULL || (m_BitmapAlpha < 255), m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) { 4471 return FALSE; 4472 } 4473 if (m_bVertical) { 4474 m_pScanlineV = FX_Alloc(FX_BYTE, m_pBitmap->GetBPP() / 8 * width + 4); 4475 if (!m_pScanlineV) { 4476 return FALSE; 4477 } 4478 m_pClipScanV = FX_Alloc(FX_BYTE, m_pBitmap->GetHeight()); 4479 if (!m_pClipScanV) { 4480 return FALSE; 4481 } 4482 if (m_pBitmap->m_pAlphaMask) { 4483 m_pScanlineAlphaV = FX_Alloc(FX_BYTE, width + 4); 4484 if (!m_pScanlineAlphaV) { 4485 return FALSE; 4486 } 4487 } 4488 } 4489 if (m_BitmapAlpha < 255) { 4490 m_pAddClipScan = FX_Alloc(FX_BYTE, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth()); 4491 if (!m_pAddClipScan) { 4492 return FALSE; 4493 } 4494 } 4495 return TRUE; 4496 } 4497 void CFX_BitmapComposer::DoCompose(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int dest_width, FX_LPCBYTE clip_scan, 4498 FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha) 4499 { 4500 if (m_BitmapAlpha < 255) { 4501 if (clip_scan) { 4502 for (int i = 0; i < dest_width; i ++) { 4503 m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255; 4504 } 4505 } else { 4506 FXSYS_memset8(m_pAddClipScan, m_BitmapAlpha, dest_width); 4507 } 4508 clip_scan = m_pAddClipScan; 4509 } 4510 if (m_SrcFormat == FXDIB_8bppMask) { 4511 m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, clip_scan, dst_extra_alpha); 4512 } else if ((m_SrcFormat & 0xff) == 8) { 4513 m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha); 4514 } else { 4515 m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha); 4516 } 4517 } 4518 void CFX_BitmapComposer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha) 4519 { 4520 if (m_bVertical) { 4521 ComposeScanlineV(line, scanline, scan_extra_alpha); 4522 return; 4523 } 4524 FX_LPCBYTE clip_scan = NULL; 4525 if (m_pClipMask) 4526 clip_scan = m_pClipMask->GetBuffer() + (m_DestTop + line - m_pClipRgn->GetBox().top) * 4527 m_pClipMask->GetPitch() + (m_DestLeft - m_pClipRgn->GetBox().left); 4528 FX_LPBYTE dest_scan = (FX_LPBYTE)m_pBitmap->GetScanline(line + m_DestTop) + 4529 m_DestLeft * m_pBitmap->GetBPP() / 8; 4530 FX_LPBYTE dest_alpha_scan = m_pBitmap->m_pAlphaMask ? 4531 (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + m_DestLeft : NULL; 4532 DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, dest_alpha_scan); 4533 } 4534 void CFX_BitmapComposer::ComposeScanlineV(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha) 4535 { 4536 int i; 4537 int Bpp = m_pBitmap->GetBPP() / 8; 4538 int dest_pitch = m_pBitmap->GetPitch(); 4539 int dest_alpha_pitch = m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0; 4540 int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line); 4541 FX_LPBYTE dest_buf = m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch; 4542 FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ? 4543 m_pBitmap->m_pAlphaMask->GetBuffer() + dest_x + m_DestTop * dest_alpha_pitch : NULL; 4544 if (m_bFlipY) { 4545 dest_buf += dest_pitch * (m_DestHeight - 1); 4546 dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1); 4547 } 4548 int y_step = dest_pitch; 4549 int y_alpha_step = dest_alpha_pitch; 4550 if (m_bFlipY) { 4551 y_step = -y_step; 4552 y_alpha_step = -y_alpha_step; 4553 } 4554 FX_LPBYTE src_scan = m_pScanlineV; 4555 FX_LPBYTE dest_scan = dest_buf; 4556 for (i = 0; i < m_DestHeight; i ++) { 4557 for (int j = 0; j < Bpp; j ++) { 4558 *src_scan++ = dest_scan[j]; 4559 } 4560 dest_scan += y_step; 4561 } 4562 FX_LPBYTE src_alpha_scan = m_pScanlineAlphaV; 4563 FX_LPBYTE dest_alpha_scan = dest_alpha_buf; 4564 if (dest_alpha_scan) { 4565 for (i = 0; i < m_DestHeight; i ++) { 4566 *src_alpha_scan++ = *dest_alpha_scan; 4567 dest_alpha_scan += y_alpha_step; 4568 } 4569 } 4570 FX_LPBYTE clip_scan = NULL; 4571 if (m_pClipMask) { 4572 clip_scan = m_pClipScanV; 4573 int clip_pitch = m_pClipMask->GetPitch(); 4574 FX_LPCBYTE src_clip = m_pClipMask->GetBuffer() + (m_DestTop - m_pClipRgn->GetBox().top) * 4575 clip_pitch + (dest_x - m_pClipRgn->GetBox().left); 4576 if (m_bFlipY) { 4577 src_clip += clip_pitch * (m_DestHeight - 1); 4578 clip_pitch = -clip_pitch; 4579 } 4580 for (i = 0; i < m_DestHeight; i ++) { 4581 clip_scan[i] = *src_clip; 4582 src_clip += clip_pitch; 4583 } 4584 } 4585 DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, m_pScanlineAlphaV); 4586 src_scan = m_pScanlineV; 4587 dest_scan = dest_buf; 4588 for (i = 0; i < m_DestHeight; i ++) { 4589 for (int j = 0; j < Bpp; j ++) { 4590 dest_scan[j] = *src_scan++; 4591 } 4592 dest_scan += y_step; 4593 } 4594 src_alpha_scan = m_pScanlineAlphaV; 4595 dest_alpha_scan = dest_alpha_buf; 4596 if (dest_alpha_scan) { 4597 for (i = 0; i < m_DestHeight; i ++) { 4598 *dest_alpha_scan = *src_alpha_scan++; 4599 dest_alpha_scan += y_alpha_step; 4600 } 4601 } 4602 } 4603