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