7#include "core/fxge/dib/cfx_scanlinecompositor.h"
13#include "core/fxge/dib/blend.h"
14#include "core/fxge/dib/fx_dib.h"
15#include "third_party/base/check.h"
16#include "third_party/base/check_op.h"
20#define FXDIB_ALPHA_UNION(dest, src) ((dest) + (src) - (dest) * (src) / 255
)
21#define FXARGB_RGBORDERCOPY(dest, src)
22 *((dest) + 3
) = *((src) + 3
), *(dest) = *((src) + 2
),
23 *((dest) + 1
) = *((src) + 1
), *((dest) + 2
) = *((src))
34 return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
37RGB ClipColor(RGB color) {
39 int n =
std::min(color.red,
std::min(color.green, color.blue));
40 int x =
std::max(color.red,
std::max(color.green, color.blue));
42 color.red = l + ((color.red - l) * l / (l - n));
43 color.green = l + ((color.green - l) * l / (l - n));
44 color.blue = l + ((color.blue - l) * l / (l - n));
47 color.red = l + ((color.red - l) * (255 - l) / (x - l));
48 color.green = l + ((color.green - l) * (255 - l) / (x - l));
49 color.blue = l + ((color.blue - l) * (255 - l) / (x - l));
54RGB SetLum(RGB color,
int l) {
55 int d = l - Lum(color);
59 return ClipColor(color);
63 return std::max(color.red,
std::max(color.green, color.blue)) -
64 std::min(color.red,
std::min(color.green, color.blue));
67RGB SetSat(RGB color,
int s) {
68 int min =
std::min(color.red,
std::min(color.green, color.blue));
69 int max =
std::max(color.red,
std::max(color.green, color.blue));
73 color.red = (color.red - min) * s / (max - min);
74 color.green = (color.green - min) * s / (max - min);
75 color.blue = (color.blue - min) * s / (max - min);
80 const uint8_t* src_scan,
81 const uint8_t* dest_scan,
83 RGB result = {0, 0, 0};
85 src.red = src_scan[2];
86 src.green = src_scan[1];
87 src.blue = src_scan[0];
89 back.red = dest_scan[2];
90 back.green = dest_scan[1];
91 back.blue = dest_scan[0];
94 result = SetLum(SetSat(src, Sat(back)), Lum(back));
97 result = SetLum(SetSat(back, Sat(src)), Lum(back));
100 result = SetLum(src, Lum(back));
103 result = SetLum(back, Lum(src));
108 results[0] = result.blue;
109 results[1] = result.green;
110 results[2] = result.red;
113int GetAlpha(uint8_t src_alpha,
const uint8_t* clip_scan,
int col) {
114 return clip_scan ? clip_scan[col] * src_alpha / 255 : src_alpha;
117int GetAlphaWithSrc(uint8_t src_alpha,
118 const uint8_t* clip_scan,
119 const uint8_t* src_scan,
121 int result = src_alpha * src_scan[col];
123 result *= clip_scan[col];
129void CompositeRow_AlphaToMask(pdfium::span<uint8_t> dest_span,
130 pdfium::span<
const uint8_t> src_span,
132 pdfium::span<
const uint8_t> clip_span,
134 uint8_t* dest_scan = dest_span.data();
135 const uint8_t* src_scan = src_span.data();
136 const uint8_t* clip_scan = clip_span.data();
137 src_scan += stride - 1;
138 for (
int col = 0; col < pixel_count; ++col) {
139 int src_alpha = GetAlpha(*src_scan, clip_scan, col);
140 uint8_t back_alpha = *dest_scan;
142 *dest_scan = src_alpha;
144 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
150void CompositeRow_Rgb2Mask(pdfium::span<uint8_t> dest_span,
152 pdfium::span<
const uint8_t> clip_span) {
153 uint8_t* dest_scan = dest_span.data();
154 const uint8_t* clip_scan = clip_span.data();
156 memset(dest_scan, 0xff, width);
159 for (
int i = 0; i < width; ++i) {
166bool IsNonSeparableBlendMode(
BlendMode mode) {
178uint8_t GetGray(
const uint8_t* src_scan) {
179 return FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
182uint8_t GetGrayWithBlend(
const uint8_t* src_scan,
183 const uint8_t* dest_scan,
185 uint8_t gray = GetGray(src_scan);
186 if (IsNonSeparableBlendMode(blend_type))
189 gray =
Blend(blend_type
, *dest_scan
, gray
);
193void CompositeRow_Argb2Gray(pdfium::span<uint8_t> dest_span,
194 pdfium::span<
const uint8_t> src_span,
197 pdfium::span<
const uint8_t> clip_span) {
198 uint8_t* dest_scan = dest_span.data();
199 const uint8_t* src_scan = src_span.data();
200 const uint8_t* clip_scan = clip_span.data();
201 constexpr size_t kOffset = 4;
202 for (
int col = 0; col < pixel_count; ++col) {
203 int src_alpha = GetAlpha(src_scan[3], clip_scan, col);
205 uint8_t gray = GetGrayWithBlend(src_scan, dest_scan, blend_type);
213void CompositeRow_Rgb2Gray(pdfium::span<uint8_t> dest_span,
214 pdfium::span<
const uint8_t> src_span,
218 pdfium::span<
const uint8_t> clip_span) {
219 uint8_t* dest_scan = dest_span.data();
220 const uint8_t* src_scan = src_span.data();
221 const uint8_t* clip_scan = clip_span.data();
222 for (
int col = 0; col < pixel_count; ++col) {
223 uint8_t gray = GetGrayWithBlend(src_scan, dest_scan, blend_type);
224 if (clip_scan && clip_scan[col] < 255)
233void CompositeRow_Argb2Argb(pdfium::span<uint8_t> dest_span,
234 pdfium::span<
const uint8_t> src_span,
237 pdfium::span<
const uint8_t> clip_span) {
238 uint8_t* dest_scan = dest_span.data();
239 const uint8_t* src_scan = src_span.data();
240 const uint8_t* clip_scan = clip_span.data();
241 int blended_colors[3];
242 constexpr size_t kOffset = 4;
243 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
244 for (
int col = 0; col < pixel_count; ++col) {
245 uint8_t back_alpha = dest_scan[3];
246 uint8_t src_alpha = GetAlpha(src_scan[3], clip_scan, col);
247 if (back_alpha == 0) {
252 memcpy(dest_scan, src_scan, 4);
254 dest_scan += kOffset;
258 if (src_alpha == 0) {
259 dest_scan += kOffset;
263 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
264 dest_scan[3] = dest_alpha;
265 int alpha_ratio = src_alpha * 255 / dest_alpha;
266 if (bNonseparableBlend)
267 RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
268 for (
int color = 0; color < 3; ++color) {
270 int blended = bNonseparableBlend
271 ? blended_colors[color]
272 :
Blend(blend_type
, *dest_scan
, *src_scan
);
286void CompositeRow_Rgb2Argb_Blend_NoClip(pdfium::span<uint8_t> dest_span,
287 pdfium::span<
const uint8_t> src_span,
291 uint8_t* dest_scan = dest_span.data();
292 const uint8_t* src_scan = src_span.data();
293 int blended_colors[3];
294 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
295 int src_gap = src_Bpp - 3;
296 for (
int col = 0; col < width; ++col) {
297 uint8_t* dest_alpha = &dest_scan[3];
298 uint8_t back_alpha = *dest_alpha;
299 if (back_alpha == 0) {
311 if (bNonseparableBlend)
312 RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
313 for (
int color = 0; color < 3; ++color) {
314 int src_color = *src_scan;
315 int blended = bNonseparableBlend
316 ? blended_colors[color]
317 :
Blend(blend_type
, *dest_scan
, src_color
);
327void CompositeRow_Rgb2Argb_Blend_Clip(pdfium::span<uint8_t> dest_span,
328 pdfium::span<
const uint8_t> src_span,
332 pdfium::span<
const uint8_t> clip_span) {
333 uint8_t* dest_scan = dest_span.data();
334 const uint8_t* src_scan = src_span.data();
335 const uint8_t* clip_scan = clip_span.data();
336 int blended_colors[3];
337 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
338 int src_gap = src_Bpp - 3;
339 for (
int col = 0; col < width; ++col) {
340 int src_alpha = *clip_scan++;
341 uint8_t back_alpha = dest_scan[3];
342 if (back_alpha == 0) {
343 memcpy(dest_scan, src_scan, 3);
349 if (src_alpha == 0) {
354 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
355 dest_scan[3] = dest_alpha;
356 int alpha_ratio = src_alpha * 255 / dest_alpha;
357 if (bNonseparableBlend)
358 RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
359 for (
int color = 0; color < 3; color++) {
360 int src_color = *src_scan;
361 int blended = bNonseparableBlend
362 ? blended_colors[color]
363 :
Blend(blend_type
, *dest_scan
, src_color
);
374void CompositeRow_Rgb2Argb_NoBlend_Clip(pdfium::span<uint8_t> dest_span,
375 pdfium::span<
const uint8_t> src_span,
378 pdfium::span<
const uint8_t> clip_span) {
379 uint8_t* dest_scan = dest_span.data();
380 const uint8_t* src_scan = src_span.data();
381 const uint8_t* clip_scan = clip_span.data();
382 int src_gap = src_Bpp - 3;
383 for (
int col = 0; col < width; col++) {
384 int src_alpha = clip_scan[col];
385 if (src_alpha == 255) {
386 memcpy(dest_scan, src_scan, 3);
392 if (src_alpha == 0) {
397 int back_alpha = dest_scan[3];
398 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
399 dest_scan[3] = dest_alpha;
400 int alpha_ratio = src_alpha * 255 / dest_alpha;
401 for (
int color = 0; color < 3; color++) {
411void CompositeRow_Rgb2Argb_NoBlend_NoClip(pdfium::span<uint8_t> dest_span,
412 pdfium::span<
const uint8_t> src_span,
415 uint8_t* dest_scan = dest_span.data();
416 const uint8_t* src_scan = src_span.data();
417 for (
int col = 0; col < width; col++) {
429void CompositeRow_Argb2Rgb_Blend(pdfium::span<uint8_t> dest_span,
430 pdfium::span<
const uint8_t> src_span,
434 pdfium::span<
const uint8_t> clip_span) {
435 uint8_t* dest_scan = dest_span.data();
436 const uint8_t* src_scan = src_span.data();
437 const uint8_t* clip_scan = clip_span.data();
438 int blended_colors[3];
439 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
440 int dest_gap = dest_Bpp - 3;
441 for (
int col = 0; col < width; col++) {
444 src_alpha = src_scan[3] * (*clip_scan++) / 255;
446 src_alpha = src_scan[3];
448 if (src_alpha == 0) {
449 dest_scan += dest_Bpp;
453 if (bNonseparableBlend) {
454 RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
456 for (
int color = 0; color < 3; color++) {
457 int back_color = *dest_scan;
458 int blended = bNonseparableBlend
459 ? blended_colors[color]
460 :
Blend(blend_type
, back_color
, *src_scan
);
465 dest_scan += dest_gap;
470void CompositeRow_Argb2Rgb_NoBlend(pdfium::span<uint8_t> dest_span,
471 pdfium::span<
const uint8_t> src_span,
474 pdfium::span<
const uint8_t> clip_span) {
475 uint8_t* dest_scan = dest_span.data();
476 const uint8_t* src_scan = src_span.data();
477 const uint8_t* clip_scan = clip_span.data();
478 int dest_gap = dest_Bpp - 3;
479 for (
int col = 0; col < width; col++) {
482 src_alpha = src_scan[3] * (*clip_scan++) / 255;
484 src_alpha = src_scan[3];
486 if (src_alpha == 255) {
487 memcpy(dest_scan, src_scan, 3);
488 dest_scan += dest_Bpp;
492 if (src_alpha == 0) {
493 dest_scan += dest_Bpp;
497 for (
int color = 0; color < 3; color++) {
502 dest_scan += dest_gap;
507void CompositeRow_Rgb2Rgb_Blend_NoClip(pdfium::span<uint8_t> dest_span,
508 pdfium::span<
const uint8_t> src_span,
513 uint8_t* dest_scan = dest_span.data();
514 const uint8_t* src_scan = src_span.data();
515 int blended_colors[3];
516 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
517 int dest_gap = dest_Bpp - 3;
518 int src_gap = src_Bpp - 3;
519 for (
int col = 0; col < width; col++) {
520 if (bNonseparableBlend) {
521 RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
523 for (
int color = 0; color < 3; color++) {
524 int back_color = *dest_scan;
525 int src_color = *src_scan;
526 int blended = bNonseparableBlend
527 ? blended_colors[color]
528 :
Blend(blend_type
, back_color
, src_color
);
529 *dest_scan = blended;
533 dest_scan += dest_gap;
538void CompositeRow_Rgb2Rgb_Blend_Clip(pdfium::span<uint8_t> dest_span,
539 pdfium::span<
const uint8_t> src_span,
544 pdfium::span<
const uint8_t> clip_span) {
545 uint8_t* dest_scan = dest_span.data();
546 const uint8_t* src_scan = src_span.data();
547 const uint8_t* clip_scan = clip_span.data();
548 int blended_colors[3];
549 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
550 int dest_gap = dest_Bpp - 3;
551 int src_gap = src_Bpp - 3;
552 for (
int col = 0; col < width; col++) {
553 uint8_t src_alpha = *clip_scan++;
554 if (src_alpha == 0) {
555 dest_scan += dest_Bpp;
559 if (bNonseparableBlend) {
560 RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
562 for (
int color = 0; color < 3; color++) {
563 int src_color = *src_scan;
564 int back_color = *dest_scan;
565 int blended = bNonseparableBlend
566 ? blended_colors[color]
567 :
Blend(blend_type
, back_color
, src_color
);
572 dest_scan += dest_gap;
577void CompositeRow_Rgb2Rgb_NoBlend_NoClip(pdfium::span<uint8_t> dest_span,
578 pdfium::span<
const uint8_t> src_span,
582 uint8_t* dest_scan = dest_span.data();
583 const uint8_t* src_scan = src_span.data();
584 if (dest_Bpp == src_Bpp) {
585 memcpy(dest_scan, src_scan, width * dest_Bpp);
588 for (
int col = 0; col < width; col++) {
589 memcpy(dest_scan, src_scan, 3);
590 dest_scan += dest_Bpp;
595void CompositeRow_Rgb2Rgb_NoBlend_Clip(pdfium::span<uint8_t> dest_span,
596 pdfium::span<
const uint8_t> src_span,
600 pdfium::span<
const uint8_t> clip_span) {
601 uint8_t* dest_scan = dest_span.data();
602 const uint8_t* src_scan = src_span.data();
603 const uint8_t* clip_scan = clip_span.data();
604 for (
int col = 0; col < width; col++) {
605 int src_alpha = clip_scan[col];
606 if (src_alpha == 255) {
607 memcpy(dest_scan, src_scan, 3);
608 }
else if (src_alpha) {
616 dest_scan += dest_Bpp - 2;
617 src_scan += src_Bpp - 2;
620 dest_scan += dest_Bpp;
625void CompositeRow_8bppPal2Gray(pdfium::span<uint8_t> dest_span,
626 pdfium::span<
const uint8_t> src_span,
627 pdfium::span<
const uint8_t> palette_span,
630 pdfium::span<
const uint8_t> clip_span) {
631 uint8_t* dest_scan = dest_span.data();
632 const uint8_t* src_scan = src_span.data();
633 const uint8_t* clip_scan = clip_span.data();
634 const uint8_t* pPalette = palette_span.data();
636 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
637 for (
int col = 0; col < pixel_count; col++) {
638 uint8_t gray = pPalette[*src_scan];
639 if (bNonseparableBlend)
642 gray =
Blend(blend_type
, *dest_scan
, gray
);
643 if (clip_scan && clip_scan[col] < 255)
652 for (
int col = 0; col < pixel_count; col++) {
653 uint8_t gray = pPalette[*src_scan];
654 if (clip_scan && clip_scan[col] < 255)
663void CompositeRow_1bppPal2Gray(pdfium::span<uint8_t> dest_span,
664 pdfium::span<
const uint8_t> src_span,
666 pdfium::span<
const uint8_t> src_palette,
669 pdfium::span<
const uint8_t> clip_span) {
670 uint8_t* dest_scan = dest_span.data();
671 const uint8_t* src_scan = src_span.data();
672 const uint8_t* clip_scan = clip_span.data();
673 int reset_gray = src_palette[0];
674 int set_gray = src_palette[1];
676 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
677 for (
int col = 0; col < pixel_count; col++) {
679 (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8)))
682 if (bNonseparableBlend)
685 gray =
Blend(blend_type
, *dest_scan
, gray
);
686 if (clip_scan && clip_scan[col] < 255) {
695 for (
int col = 0; col < pixel_count; col++) {
697 (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8)))
700 if (clip_scan && clip_scan[col] < 255) {
709void CompositeRow_8bppRgb2Rgb_NoBlend(pdfium::span<uint8_t> dest_span,
710 pdfium::span<
const uint8_t> src_span,
711 pdfium::span<
const uint32_t> palette_span,
714 pdfium::span<
const uint8_t> clip_span) {
715 uint8_t* dest_scan = dest_span.data();
716 const uint8_t* src_scan = src_span.data();
717 const uint8_t* clip_scan = clip_span.data();
718 const uint32_t* pPalette = palette_span.data();
720 for (
int col = 0; col < pixel_count; col++) {
721 argb = pPalette[*src_scan];
725 if (clip_scan && clip_scan[col] < 255) {
733 *dest_scan++ = src_b;
734 *dest_scan++ = src_g;
735 *dest_scan++ = src_r;
744void CompositeRow_1bppRgb2Rgb_NoBlend(pdfium::span<uint8_t> dest_span,
745 pdfium::span<
const uint8_t> src_span,
747 pdfium::span<
const uint32_t> src_palette,
750 pdfium::span<
const uint8_t> clip_span) {
751 uint8_t* dest_scan = dest_span.data();
752 const uint8_t* src_scan = src_span.data();
753 const uint8_t* clip_scan = clip_span.data();
754 int reset_r =
FXARGB_R(src_palette[0]);
755 int reset_g =
FXARGB_G(src_palette[0]);
756 int reset_b =
FXARGB_B(src_palette[0]);
757 int set_r =
FXARGB_R(src_palette[1]);
758 int set_g =
FXARGB_G(src_palette[1]);
759 int set_b =
FXARGB_B(src_palette[1]);
760 for (
int col = 0; col < pixel_count; col++) {
764 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
773 if (clip_scan && clip_scan[col] < 255) {
781 *dest_scan++ = src_b;
782 *dest_scan++ = src_g;
783 *dest_scan++ = src_r;
791void CompositeRow_8bppRgb2Argb_NoBlend(
792 pdfium::span<uint8_t> dest_span,
793 pdfium::span<
const uint8_t> src_span,
795 pdfium::span<
const uint32_t> palette_span,
796 pdfium::span<
const uint8_t> clip_span) {
797 uint8_t* dest_scan = dest_span.data();
798 const uint8_t* src_scan = src_span.data();
799 const uint8_t* clip_scan = clip_span.data();
800 const uint32_t* pPalette = palette_span.data();
801 for (
int col = 0; col < width; col++) {
802 FX_ARGB argb = pPalette[*src_scan];
806 if (!clip_scan || clip_scan[col] == 255) {
807 *dest_scan++ = src_b;
808 *dest_scan++ = src_g;
809 *dest_scan++ = src_r;
814 int src_alpha = clip_scan[col];
815 if (src_alpha == 0) {
820 int back_alpha = dest_scan[3];
821 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
822 dest_scan[3] = dest_alpha;
823 int alpha_ratio = src_alpha * 255 / dest_alpha;
835void CompositeRow_1bppRgb2Argb_NoBlend(pdfium::span<uint8_t> dest_span,
836 pdfium::span<
const uint8_t> src_span,
839 pdfium::span<
const uint32_t> src_palette,
840 pdfium::span<
const uint8_t> clip_span) {
841 uint8_t* dest_scan = dest_span.data();
842 const uint8_t* src_scan = src_span.data();
843 const uint8_t* clip_scan = clip_span.data();
844 int reset_r =
FXARGB_R(src_palette[0]);
845 int reset_g =
FXARGB_G(src_palette[0]);
846 int reset_b =
FXARGB_B(src_palette[0]);
847 int set_r =
FXARGB_R(src_palette[1]);
848 int set_g =
FXARGB_G(src_palette[1]);
849 int set_b =
FXARGB_B(src_palette[1]);
850 for (
int col = 0; col < width; col++) {
854 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
863 if (!clip_scan || clip_scan[col] == 255) {
864 *dest_scan++ = src_b;
865 *dest_scan++ = src_g;
866 *dest_scan++ = src_r;
870 int src_alpha = clip_scan[col];
871 if (src_alpha == 0) {
875 int back_alpha = dest_scan[3];
876 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
877 dest_scan[3] = dest_alpha;
878 int alpha_ratio = src_alpha * 255 / dest_alpha;
889void CompositeRow_ByteMask2Argb(pdfium::span<uint8_t> dest_span,
890 pdfium::span<
const uint8_t> src_span,
897 pdfium::span<
const uint8_t> clip_span) {
898 uint8_t* dest_scan = dest_span.data();
899 const uint8_t* src_scan = src_span.data();
900 const uint8_t* clip_scan = clip_span.data();
901 for (
int col = 0; col < pixel_count; col++) {
902 int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
903 uint8_t back_alpha = dest_scan[3];
904 if (back_alpha == 0) {
909 if (src_alpha == 0) {
913 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
914 dest_scan[3] = dest_alpha;
915 int alpha_ratio = src_alpha * 255 / dest_alpha;
916 if (IsNonSeparableBlendMode(blend_type)) {
917 int blended_colors[3];
918 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
919 static_cast<uint8_t>(src_g),
920 static_cast<uint8_t>(src_r)};
921 RGB_Blend(blend_type, scan, dest_scan, blended_colors);
931 int blended =
Blend(blend_type
, *dest_scan
, src_b
);
935 blended =
Blend(blend_type
, *dest_scan
, src_g
);
939 blended =
Blend(blend_type
, *dest_scan
, src_r
);
953void CompositeRow_ByteMask2Rgb(pdfium::span<uint8_t> dest_span,
954 pdfium::span<
const uint8_t> src_span,
962 pdfium::span<
const uint8_t> clip_span) {
963 uint8_t* dest_scan = dest_span.data();
964 const uint8_t* src_scan = src_span.data();
965 const uint8_t* clip_scan = clip_span.data();
966 for (
int col = 0; col < pixel_count; col++) {
967 int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
968 if (src_alpha == 0) {
972 if (IsNonSeparableBlendMode(blend_type)) {
973 int blended_colors[3];
974 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
975 static_cast<uint8_t>(src_g),
976 static_cast<uint8_t>(src_r)};
977 RGB_Blend(blend_type, scan, dest_scan, blended_colors);
984 int blended =
Blend(blend_type
, *dest_scan
, src_b
);
987 blended =
Blend(blend_type
, *dest_scan
, src_g
);
990 blended =
Blend(blend_type
, *dest_scan
, src_r
);
999 dest_scan += Bpp - 2;
1003void CompositeRow_ByteMask2Mask(pdfium::span<uint8_t> dest_span,
1004 pdfium::span<
const uint8_t> src_span,
1007 pdfium::span<
const uint8_t> clip_span) {
1008 uint8_t* dest_scan = dest_span.data();
1009 const uint8_t* src_scan = src_span.data();
1010 const uint8_t* clip_scan = clip_span.data();
1011 for (
int col = 0; col < pixel_count; col++) {
1012 int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
1013 uint8_t back_alpha = *dest_scan;
1015 *dest_scan = src_alpha;
1016 }
else if (src_alpha) {
1017 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1023void CompositeRow_ByteMask2Gray(pdfium::span<uint8_t> dest_span,
1024 pdfium::span<
const uint8_t> src_span,
1028 pdfium::span<
const uint8_t> clip_span) {
1029 uint8_t* dest_scan = dest_span.data();
1030 const uint8_t* src_scan = src_span.data();
1031 const uint8_t* clip_scan = clip_span.data();
1032 for (
int col = 0; col < pixel_count; col++) {
1033 int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
1041void CompositeRow_BitMask2Argb(pdfium::span<uint8_t> dest_span,
1042 pdfium::span<
const uint8_t> src_span,
1050 pdfium::span<
const uint8_t> clip_span) {
1051 uint8_t* dest_scan = dest_span.data();
1052 const uint8_t* src_scan = src_span.data();
1053 const uint8_t* clip_scan = clip_span.data();
1056 for (
int col = 0; col < pixel_count; col++) {
1057 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
1064 for (
int col = 0; col < pixel_count; col++) {
1065 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
1069 int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
1070 uint8_t back_alpha = dest_scan[3];
1071 if (back_alpha == 0) {
1076 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1077 dest_scan[3] = dest_alpha;
1078 int alpha_ratio = src_alpha * 255 / dest_alpha;
1079 if (IsNonSeparableBlendMode(blend_type)) {
1080 int blended_colors[3];
1081 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
1082 static_cast<uint8_t>(src_g),
1083 static_cast<uint8_t>(src_r)};
1084 RGB_Blend(blend_type, scan, dest_scan, blended_colors);
1094 int blended =
Blend(blend_type
, *dest_scan
, src_b
);
1098 blended =
Blend(blend_type
, *dest_scan
, src_g
);
1102 blended =
Blend(blend_type
, *dest_scan
, src_r
);
1116void CompositeRow_BitMask2Rgb(pdfium::span<uint8_t> dest_span,
1117 pdfium::span<
const uint8_t> src_span,
1126 pdfium::span<
const uint8_t> clip_span) {
1127 uint8_t* dest_scan = dest_span.data();
1128 const uint8_t* src_scan = src_span.data();
1129 const uint8_t* clip_scan = clip_span.data();
1131 for (
int col = 0; col < pixel_count; col++) {
1132 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
1133 dest_scan[2] = src_r;
1134 dest_scan[1] = src_g;
1135 dest_scan[0] = src_b;
1141 for (
int col = 0; col < pixel_count; col++) {
1142 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
1146 int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
1147 if (src_alpha == 0) {
1151 if (IsNonSeparableBlendMode(blend_type)) {
1152 int blended_colors[3];
1153 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
1154 static_cast<uint8_t>(src_g),
1155 static_cast<uint8_t>(src_r)};
1156 RGB_Blend(blend_type, scan, dest_scan, blended_colors);
1163 int blended =
Blend(blend_type
, *dest_scan
, src_b
);
1166 blended =
Blend(blend_type
, *dest_scan
, src_g
);
1169 blended =
Blend(blend_type
, *dest_scan
, src_r
);
1178 dest_scan += Bpp - 2;
1182void CompositeRow_BitMask2Mask(pdfium::span<uint8_t> dest_span,
1183 pdfium::span<
const uint8_t> src_span,
1187 pdfium::span<
const uint8_t> clip_span) {
1188 uint8_t* dest_scan = dest_span.data();
1189 const uint8_t* src_scan = src_span.data();
1190 const uint8_t* clip_scan = clip_span.data();
1191 for (
int col = 0; col < pixel_count; col++) {
1192 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
1196 int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
1197 uint8_t back_alpha = *dest_scan;
1199 *dest_scan = src_alpha;
1200 }
else if (src_alpha) {
1201 *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1207void CompositeRow_BitMask2Gray(pdfium::span<uint8_t> dest_span,
1208 pdfium::span<
const uint8_t> src_span,
1213 pdfium::span<
const uint8_t> clip_span) {
1214 uint8_t* dest_scan = dest_span.data();
1215 const uint8_t* src_scan = src_span.data();
1216 const uint8_t* clip_scan = clip_span.data();
1217 for (
int col = 0; col < pixel_count; col++) {
1218 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
1222 int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
1230void CompositeRow_Argb2Argb_RgbByteOrder(
1231 pdfium::span<uint8_t> dest_span,
1232 pdfium::span<
const uint8_t> src_span,
1235 pdfium::span<
const uint8_t> clip_span) {
1236 uint8_t* dest_scan = dest_span.data();
1237 const uint8_t* src_scan = src_span.data();
1238 const uint8_t* clip_scan = clip_span.data();
1239 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
1240 int blended_colors[3];
1241 for (
int col = 0; col < pixel_count; col++) {
1242 uint8_t back_alpha = dest_scan[3];
1243 if (back_alpha == 0) {
1245 int src_alpha = clip_scan[col] * src_scan[3] / 255;
1247 dest_scan[3] = src_alpha;
1255 uint8_t src_alpha = GetAlpha(src_scan[3], clip_scan, col);
1256 if (src_alpha == 0) {
1261 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1262 dest_scan[3] = dest_alpha;
1263 int alpha_ratio = src_alpha * 255 / dest_alpha;
1264 if (bNonseparableBlend) {
1265 uint8_t dest_scan_o[3];
1267 RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
1269 for (
int color = 0; color < 3; color++) {
1270 int index = 2 - color;
1272 int blended = bNonseparableBlend
1273 ? blended_colors[color]
1274 :
Blend(blend_type
, dest_scan[index]
, *src_scan
);
1289void CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(
1290 pdfium::span<uint8_t> dest_span,
1291 pdfium::span<
const uint8_t> src_span,
1295 uint8_t* dest_scan = dest_span.data();
1296 const uint8_t* src_scan = src_span.data();
1297 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
1298 int src_gap = src_Bpp - 3;
1299 int blended_colors[3];
1300 for (
int col = 0; col < width; col++) {
1301 uint8_t back_alpha = dest_scan[3];
1302 if (back_alpha == 0) {
1310 src_scan += src_Bpp;
1313 dest_scan[3] = 0xff;
1314 if (bNonseparableBlend) {
1315 uint8_t dest_scan_o[3];
1317 RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
1319 for (
int color = 0; color < 3; color++) {
1320 int index = 2 - color;
1321 int src_color = *src_scan;
1322 int blended = bNonseparableBlend
1323 ? blended_colors[color]
1324 :
Blend(blend_type
, dest_scan[index]
, src_color
);
1329 src_scan += src_gap;
1333void CompositeRow_Argb2Rgb_Blend_RgbByteOrder(
1334 pdfium::span<uint8_t> dest_span,
1335 pdfium::span<
const uint8_t> src_span,
1339 pdfium::span<
const uint8_t> clip_span) {
1340 int blended_colors[3];
1341 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
1342 uint8_t* dest_scan = dest_span.data();
1343 const uint8_t* src_scan = src_span.data();
1344 const uint8_t* clip_scan = clip_span.data();
1345 for (
int col = 0; col < width; col++) {
1348 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1350 src_alpha = src_scan[3];
1352 if (src_alpha == 0) {
1353 dest_scan += dest_Bpp;
1357 if (bNonseparableBlend) {
1358 uint8_t dest_scan_o[3];
1360 RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
1362 for (
int color = 0; color < 3; color++) {
1363 int index = 2 - color;
1364 int back_color = dest_scan[index];
1365 int blended = bNonseparableBlend
1366 ? blended_colors[color]
1367 :
Blend(blend_type
, back_color
, *src_scan
);
1371 dest_scan += dest_Bpp;
1376void CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(
1377 pdfium::span<uint8_t> dest_span,
1378 pdfium::span<
const uint8_t> src_span,
1381 uint8_t* dest_scan = dest_span.data();
1382 const uint8_t* src_scan = src_span.data();
1383 for (
int col = 0; col < width; col++) {
1391 src_scan += src_Bpp;
1395void CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(
1396 pdfium::span<uint8_t> dest_span,
1397 pdfium::span<
const uint8_t> src_span,
1402 int blended_colors[3];
1403 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
1404 uint8_t* dest_scan = dest_span.data();
1405 const uint8_t* src_scan = src_span.data();
1406 int src_gap = src_Bpp - 3;
1407 for (
int col = 0; col < width; col++) {
1408 if (bNonseparableBlend) {
1409 uint8_t dest_scan_o[3];
1411 RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
1413 for (
int color = 0; color < 3; color++) {
1414 int index = 2 - color;
1415 int back_color = dest_scan[index];
1416 int src_color = *src_scan;
1417 int blended = bNonseparableBlend
1418 ? blended_colors[color]
1419 :
Blend(blend_type
, back_color
, src_color
);
1420 dest_scan[index] = blended;
1423 dest_scan += dest_Bpp;
1424 src_scan += src_gap;
1428void CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(
1429 pdfium::span<uint8_t> dest_span,
1430 pdfium::span<
const uint8_t> src_span,
1433 pdfium::span<
const uint8_t> clip_span) {
1434 uint8_t* dest_scan = dest_span.data();
1435 const uint8_t* src_scan = src_span.data();
1436 const uint8_t* clip_scan = clip_span.data();
1437 for (
int col = 0; col < width; col++) {
1440 src_alpha = src_scan[3] * (*clip_scan++) / 255;
1442 src_alpha = src_scan[3];
1444 if (src_alpha == 255) {
1446 dest_scan += dest_Bpp;
1450 if (src_alpha == 0) {
1451 dest_scan += dest_Bpp;
1455 for (
int color = 0; color < 3; color++) {
1456 int index = 2 - color;
1461 dest_scan += dest_Bpp;
1466void CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(
1467 pdfium::span<uint8_t> dest_span,
1468 pdfium::span<
const uint8_t> src_span,
1472 uint8_t* dest_scan = dest_span.data();
1473 const uint8_t* src_scan = src_span.data();
1474 for (
int col = 0; col < width; col++) {
1476 dest_scan += dest_Bpp;
1477 src_scan += src_Bpp;
1481void CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(
1482 pdfium::span<uint8_t> dest_span,
1483 pdfium::span<
const uint8_t> src_span,
1487 pdfium::span<
const uint8_t> clip_span) {
1488 uint8_t* dest_scan = dest_span.data();
1489 const uint8_t* src_scan = src_span.data();
1490 const uint8_t* clip_scan = clip_span.data();
1491 int blended_colors[3];
1492 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
1493 int src_gap = src_Bpp - 3;
1494 for (
int col = 0; col < width; col++) {
1495 int src_alpha = *clip_scan++;
1496 uint8_t back_alpha = dest_scan[3];
1497 if (back_alpha == 0) {
1499 src_scan += src_Bpp;
1503 if (src_alpha == 0) {
1505 src_scan += src_Bpp;
1508 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1509 dest_scan[3] = dest_alpha;
1510 int alpha_ratio = src_alpha * 255 / dest_alpha;
1511 if (bNonseparableBlend) {
1512 uint8_t dest_scan_o[3];
1514 RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
1516 for (
int color = 0; color < 3; color++) {
1517 int index = 2 - color;
1518 int src_color = *src_scan;
1519 int blended = bNonseparableBlend
1520 ? blended_colors[color]
1521 :
Blend(blend_type
, dest_scan[index]
, src_color
);
1528 src_scan += src_gap;
1532void CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(
1533 pdfium::span<uint8_t> dest_span,
1534 pdfium::span<
const uint8_t> src_span,
1539 pdfium::span<
const uint8_t> clip_span) {
1540 uint8_t* dest_scan = dest_span.data();
1541 const uint8_t* src_scan = src_span.data();
1542 const uint8_t* clip_scan = clip_span.data();
1543 int blended_colors[3];
1544 bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
1545 int src_gap = src_Bpp - 3;
1546 for (
int col = 0; col < width; col++) {
1547 uint8_t src_alpha = *clip_scan++;
1548 if (src_alpha == 0) {
1549 dest_scan += dest_Bpp;
1550 src_scan += src_Bpp;
1553 if (bNonseparableBlend) {
1554 uint8_t dest_scan_o[3];
1556 RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
1558 for (
int color = 0; color < 3; color++) {
1559 int index = 2 - color;
1560 int src_color = *src_scan;
1561 int back_color = dest_scan[index];
1562 int blended = bNonseparableBlend
1563 ? blended_colors[color]
1564 :
Blend(blend_type
, back_color
, src_color
);
1568 dest_scan += dest_Bpp;
1569 src_scan += src_gap;
1573void CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(
1574 pdfium::span<uint8_t> dest_span,
1575 pdfium::span<
const uint8_t> src_span,
1578 pdfium::span<
const uint8_t> clip_span) {
1579 uint8_t* dest_scan = dest_span.data();
1580 const uint8_t* src_scan = src_span.data();
1581 const uint8_t* clip_scan = clip_span.data();
1582 int src_gap = src_Bpp - 3;
1583 for (
int col = 0; col < width; col++) {
1584 int src_alpha = clip_scan[col];
1585 if (src_alpha == 255) {
1589 src_scan += src_Bpp;
1592 if (src_alpha == 0) {
1594 src_scan += src_Bpp;
1597 int back_alpha = dest_scan[3];
1598 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1599 dest_scan[3] = dest_alpha;
1600 int alpha_ratio = src_alpha * 255 / dest_alpha;
1601 for (
int color = 0; color < 3; color++) {
1602 int index = 2 - color;
1608 src_scan += src_gap;
1612void CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(
1613 pdfium::span<uint8_t> dest_span,
1614 pdfium::span<
const uint8_t> src_span,
1618 pdfium::span<
const uint8_t> clip_span) {
1619 uint8_t* dest_scan = dest_span.data();
1620 const uint8_t* src_scan = src_span.data();
1621 const uint8_t* clip_scan = clip_span.data();
1622 for (
int col = 0; col < width; col++) {
1623 int src_alpha = clip_scan[col];
1624 if (src_alpha == 255) {
1626 }
else if (src_alpha) {
1632 dest_scan += dest_Bpp;
1633 src_scan += src_Bpp - 2;
1636 dest_scan += dest_Bpp;
1637 src_scan += src_Bpp;
1641void CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(
1642 pdfium::span<uint8_t> dest_span,
1643 pdfium::span<
const uint8_t> src_span,
1644 const FX_ARGB* pPalette,
1647 pdfium::span<
const uint8_t> clip_span) {
1648 uint8_t* dest_scan = dest_span.data();
1649 const uint8_t* src_scan = src_span.data();
1650 const uint8_t* clip_scan = clip_span.data();
1651 for (
int col = 0; col < pixel_count; col++) {
1652 FX_ARGB argb = pPalette ? pPalette[*src_scan]
1657 if (clip_scan && clip_scan[col] < 255) {
1662 dest_scan[2] = src_b;
1663 dest_scan[1] = src_g;
1664 dest_scan[0] = src_r;
1666 dest_scan += DestBpp;
1671void CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(
1672 pdfium::span<uint8_t> dest_span,
1673 pdfium::span<
const uint8_t> src_span,
1675 pdfium::span<
const FX_ARGB> src_palette,
1678 pdfium::span<
const uint8_t> clip_span) {
1679 uint8_t* dest_scan = dest_span.data();
1680 const uint8_t* src_scan = src_span.data();
1681 const uint8_t* clip_scan = clip_span.data();
1688 if (!src_palette.empty()) {
1689 reset_r =
FXARGB_R(src_palette[0]);
1690 reset_g =
FXARGB_G(src_palette[0]);
1691 reset_b =
FXARGB_B(src_palette[0]);
1696 reset_r = reset_g = reset_b = 0;
1697 set_r = set_g = set_b = 255;
1699 for (
int col = 0; col < pixel_count; col++) {
1703 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
1712 if (clip_scan && clip_scan[col] < 255) {
1717 dest_scan[2] = src_b;
1718 dest_scan[1] = src_g;
1719 dest_scan[0] = src_r;
1721 dest_scan += DestBpp;
1725void CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(
1726 pdfium::span<uint8_t> dest_span,
1727 pdfium::span<
const uint8_t> src_span,
1729 const FX_ARGB* pPalette,
1730 pdfium::span<
const uint8_t> clip_span) {
1731 uint8_t* dest_scan = dest_span.data();
1732 const uint8_t* src_scan = src_span.data();
1733 const uint8_t* clip_scan = clip_span.data();
1734 for (
int col = 0; col < width; col++) {
1739 FX_ARGB argb = pPalette[*src_scan];
1744 src_r = src_g = src_b = *src_scan;
1746 if (!clip_scan || clip_scan[col] == 255) {
1747 dest_scan[2] = src_b;
1748 dest_scan[1] = src_g;
1749 dest_scan[0] = src_r;
1755 int src_alpha = clip_scan[col];
1756 if (src_alpha == 0) {
1761 int back_alpha = dest_scan[3];
1762 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1763 dest_scan[3] = dest_alpha;
1764 int alpha_ratio = src_alpha * 255 / dest_alpha;
1773void CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(
1774 pdfium::span<uint8_t> dest_span,
1775 pdfium::span<
const uint8_t> src_span,
1778 pdfium::span<
const FX_ARGB> src_palette,
1779 pdfium::span<
const uint8_t> clip_span) {
1780 uint8_t* dest_scan = dest_span.data();
1781 const uint8_t* src_scan = src_span.data();
1782 const uint8_t* clip_scan = clip_span.data();
1789 if (!src_palette.empty()) {
1790 reset_r =
FXARGB_R(src_palette[0]);
1791 reset_g =
FXARGB_G(src_palette[0]);
1792 reset_b =
FXARGB_B(src_palette[0]);
1797 reset_r = reset_g = reset_b = 0;
1798 set_r = set_g = set_b = 255;
1800 for (
int col = 0; col < width; col++) {
1804 if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
1813 if (!clip_scan || clip_scan[col] == 255) {
1814 dest_scan[2] = src_b;
1815 dest_scan[1] = src_g;
1816 dest_scan[0] = src_r;
1821 int src_alpha = clip_scan[col];
1822 if (src_alpha == 0) {
1826 int back_alpha = dest_scan[3];
1827 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1828 dest_scan[3] = dest_alpha;
1829 int alpha_ratio = src_alpha * 255 / dest_alpha;
1837void CompositeRow_ByteMask2Argb_RgbByteOrder(
1838 pdfium::span<uint8_t> dest_span,
1839 pdfium::span<
const uint8_t> src_span,
1846 pdfium::span<
const uint8_t> clip_span) {
1847 uint8_t* dest_scan = dest_span.data();
1848 const uint8_t* src_scan = src_span.data();
1849 const uint8_t* clip_scan = clip_span.data();
1850 for (
int col = 0; col < pixel_count; col++) {
1851 int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
1852 uint8_t back_alpha = dest_scan[3];
1853 if (back_alpha == 0) {
1859 if (src_alpha == 0) {
1863 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1864 dest_scan[3] = dest_alpha;
1865 int alpha_ratio = src_alpha * 255 / dest_alpha;
1866 if (IsNonSeparableBlendMode(blend_type)) {
1867 int blended_colors[3];
1868 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
1869 static_cast<uint8_t>(src_g),
1870 static_cast<uint8_t>(src_r)};
1871 uint8_t dest_scan_o[3];
1873 RGB_Blend(blend_type, scan, dest_scan_o, blended_colors);
1881 int blended =
Blend(blend_type
, dest_scan[2]
, src_b
);
1884 blended =
Blend(blend_type
, dest_scan[1]
, src_g
);
1887 blended =
Blend(blend_type
, dest_scan[0]
, src_r
);
1899void CompositeRow_ByteMask2Rgb_RgbByteOrder(
1900 pdfium::span<uint8_t> dest_span,
1901 pdfium::span<
const uint8_t> src_span,
1909 pdfium::span<
const uint8_t> clip_span) {
1910 uint8_t* dest_scan = dest_span.data();
1911 const uint8_t* src_scan = src_span.data();
1912 const uint8_t* clip_scan = clip_span.data();
1913 for (
int col = 0; col < pixel_count; col++) {
1914 int src_alpha = GetAlphaWithSrc(mask_alpha, clip_scan, src_scan, col);
1915 if (src_alpha == 0) {
1919 if (IsNonSeparableBlendMode(blend_type)) {
1920 int blended_colors[3];
1921 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
1922 static_cast<uint8_t>(src_g),
1923 static_cast<uint8_t>(src_r)};
1924 uint8_t dest_scan_o[3];
1926 RGB_Blend(blend_type, scan, dest_scan_o, blended_colors);
1934 int blended =
Blend(blend_type
, dest_scan[2]
, src_b
);
1936 blended =
Blend(blend_type
, dest_scan[1]
, src_g
);
1938 blended =
Blend(blend_type
, dest_scan[0]
, src_r
);
1949void CompositeRow_BitMask2Argb_RgbByteOrder(
1950 pdfium::span<uint8_t> dest_span,
1951 pdfium::span<
const uint8_t> src_span,
1959 pdfium::span<
const uint8_t> clip_span) {
1960 uint8_t* dest_scan = dest_span.data();
1961 const uint8_t* src_scan = src_span.data();
1962 const uint8_t* clip_scan = clip_span.data();
1965 for (
int col = 0; col < pixel_count; col++) {
1966 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
1973 for (
int col = 0; col < pixel_count; col++) {
1974 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
1978 int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
1979 uint8_t back_alpha = dest_scan[3];
1980 if (back_alpha == 0) {
1986 uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
1987 dest_scan[3] = dest_alpha;
1988 int alpha_ratio = src_alpha * 255 / dest_alpha;
1989 if (IsNonSeparableBlendMode(blend_type)) {
1990 int blended_colors[3];
1991 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
1992 static_cast<uint8_t>(src_g),
1993 static_cast<uint8_t>(src_r)};
1994 uint8_t dest_scan_o[3];
1996 RGB_Blend(blend_type, scan, dest_scan_o, blended_colors);
2004 int blended =
Blend(blend_type
, dest_scan[2]
, src_b
);
2007 blended =
Blend(blend_type
, dest_scan[1]
, src_g
);
2010 blended =
Blend(blend_type
, dest_scan[0]
, src_r
);
2022void CompositeRow_BitMask2Rgb_RgbByteOrder(
2023 pdfium::span<uint8_t> dest_span,
2024 pdfium::span<
const uint8_t> src_span,
2033 pdfium::span<
const uint8_t> clip_span) {
2034 uint8_t* dest_scan = dest_span.data();
2035 const uint8_t* src_scan = src_span.data();
2036 const uint8_t* clip_scan = clip_span.data();
2038 for (
int col = 0; col < pixel_count; col++) {
2039 if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
2040 dest_scan[2] = src_b;
2041 dest_scan[1] = src_g;
2042 dest_scan[0] = src_r;
2048 for (
int col = 0; col < pixel_count; col++) {
2049 if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
2053 int src_alpha = GetAlpha(mask_alpha, clip_scan, col);
2054 if (src_alpha == 0) {
2058 if (IsNonSeparableBlendMode(blend_type)) {
2059 int blended_colors[3];
2060 uint8_t scan[3] = {
static_cast<uint8_t>(src_b),
2061 static_cast<uint8_t>(src_g),
2062 static_cast<uint8_t>(src_r)};
2063 uint8_t dest_scan_o[3];
2065 RGB_Blend(blend_type, scan, dest_scan_o, blended_colors);
2073 int back_color = dest_scan[2];
2074 int blended =
Blend(blend_type
, back_color
, src_b
);
2076 back_color = dest_scan[1];
2077 blended =
Blend(blend_type
, back_color
, src_g
);
2079 back_color = dest_scan[0];
2080 blended =
Blend(blend_type
, back_color
, src_r
);
2099 pdfium::span<
const uint32_t> src_palette,
2100 uint32_t mask_color,
2103 bool bRgbByteOrder) {
2104 m_SrcFormat = src_format;
2105 m_DestFormat = dest_format;
2106 m_BlendType = blend_type;
2107 m_bRgbByteOrder = bRgbByteOrder;
2121 InitSourceMask(mask_color);
2127 InitSourcePalette(src_palette);
2133 m_MaskAlpha =
FXARGB_A(mask_color);
2135 m_MaskGreen =
FXARGB_G(mask_color);
2141 m_MaskRed =
FXRGB2GRAY(m_MaskRed, m_MaskGreen, m_MaskBlue);
2145 pdfium::span<
const uint32_t> src_palette) {
2148 m_SrcPalette.Reset();
2150 const size_t pal_count =
static_cast<size_t>(1)
2151 << GetBppFromFormat(m_SrcFormat);
2153 if (!src_palette.empty()) {
2155 pdfium::span<uint8_t> gray_pal = m_SrcPalette.Make8BitPalette(pal_count);
2156 for (size_t i = 0; i < pal_count; ++i) {
2157 FX_ARGB argb = src_palette[i];
2163 pdfium::span<uint32_t> pPalette = m_SrcPalette.Make32BitPalette(pal_count);
2164 for (size_t i = 0; i < pal_count; ++i)
2165 pPalette[i] = src_palette[i];
2169 pdfium::span<uint8_t> gray_pal = m_SrcPalette.Make8BitPalette(pal_count);
2170 if (pal_count == 2) {
2174 for (size_t i = 0; i < pal_count; ++i)
2179 pdfium::span<uint32_t> pPalette = m_SrcPalette.Make32BitPalette(pal_count);
2180 if (pal_count == 2) {
2181 pPalette[0] = 0xff000000;
2182 pPalette[1] = 0xffffffff;
2184 for (size_t i = 0; i < pal_count; ++i) {
2185 uint32_t v =
static_cast<uint32_t>(i);
2192 pdfium::span<uint8_t> dest_scan,
2193 pdfium::span<
const uint8_t> src_scan,
2195 pdfium::span<
const uint8_t> clip_scan)
const {
2196 DCHECK(m_SrcFormat == FXDIB_Format::kRgb ||
2197 m_SrcFormat == FXDIB_Format::kRgb32 ||
2198 m_SrcFormat == FXDIB_Format::kArgb);
2202 if (m_bRgbByteOrder) {
2205 CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width,
2206 m_BlendType, clip_scan);
2210 CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width,
2211 dest_Bpp, clip_scan);
2214 CompositeRow_Argb2Rgb_Blend_RgbByteOrder(
2215 dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
2222 CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(
2223 dest_scan, src_scan, width, src_Bpp, clip_scan);
2226 CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan,
2231 CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(
2232 dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
2235 CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(
2236 dest_scan, src_scan, width, m_BlendType, src_Bpp);
2242 CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(
2243 dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
2246 CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(
2247 dest_scan, src_scan, width, dest_Bpp, src_Bpp);
2251 CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width,
2252 m_BlendType, dest_Bpp,
2253 src_Bpp, clip_scan);
2256 CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(
2257 dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
2263 CompositeRow_AlphaToMask(dest_scan, src_scan, width, clip_scan, 4);
2265 CompositeRow_Rgb2Mask(dest_scan, width, clip_scan);
2272 CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType,
2275 CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType,
2286 CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType,
2291 CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp,
2295 CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType,
2296 dest_Bpp, clip_scan);
2303 CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp,
2307 CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp);
2311 CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType,
2312 src_Bpp, clip_scan);
2315 CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType,
2322 CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp,
2323 src_Bpp, clip_scan);
2326 CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp,
2331 CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType,
2332 dest_Bpp, src_Bpp, clip_scan);
2335 CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType,
2340 pdfium::span<uint8_t> dest_scan,
2341 pdfium::span<
const uint8_t> src_scan,
2344 pdfium::span<
const uint8_t> clip_scan)
const {
2345 DCHECK(m_SrcFormat == FXDIB_Format::k1bppRgb ||
2346 m_SrcFormat == FXDIB_Format::k8bppRgb);
2348 if (m_bRgbByteOrder) {
2354 CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(
2355 dest_scan, src_scan, src_left, width,
2356 m_SrcPalette.Get32BitPalette(), clip_scan);
2358 CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(
2359 dest_scan, src_scan, src_left, m_SrcPalette.Get32BitPalette(),
2360 width, GetCompsFromFormat(m_DestFormat), clip_scan);
2367 CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(
2368 dest_scan, src_scan, width, m_SrcPalette.Get32BitPalette().data(),
2371 CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(
2372 dest_scan, src_scan, m_SrcPalette.Get32BitPalette().data(), width,
2373 GetCompsFromFormat(m_DestFormat), clip_scan);
2380 CompositeRow_Rgb2Mask(dest_scan, width, clip_scan);
2386 CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left,
2387 m_SrcPalette.Get8BitPalette(), width,
2388 m_BlendType, clip_scan);
2391 CompositeRow_8bppPal2Gray(dest_scan, src_scan,
2392 m_SrcPalette.Get8BitPalette(), width, m_BlendType,
2402 CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width,
2403 m_SrcPalette.Get32BitPalette(),
2407 CompositeRow_8bppRgb2Argb_NoBlend(
2408 dest_scan, src_scan, width, m_SrcPalette.Get32BitPalette(), clip_scan);
2413 CompositeRow_8bppRgb2Rgb_NoBlend(
2414 dest_scan, src_scan, m_SrcPalette.Get32BitPalette(), width,
2415 GetCompsFromFormat(m_DestFormat), clip_scan);
2419 CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left,
2420 m_SrcPalette.Get32BitPalette(), width,
2421 GetCompsFromFormat(m_DestFormat), clip_scan);
2425 pdfium::span<uint8_t> dest_scan,
2426 pdfium::span<
const uint8_t> src_scan,
2428 pdfium::span<
const uint8_t> clip_scan)
const {
2430 CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width,
2435 CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
2443 if (m_bRgbByteOrder) {
2445 CompositeRow_ByteMask2Argb_RgbByteOrder(
2446 dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
2447 width, m_BlendType, clip_scan);
2449 CompositeRow_ByteMask2Rgb_RgbByteOrder(
2450 dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
2457 CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
2458 m_MaskGreen, m_MaskBlue, width, m_BlendType,
2465 CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
2466 m_MaskGreen, m_MaskBlue, width, m_BlendType,
2475 pdfium::span<uint8_t> dest_scan,
2476 pdfium::span<
const uint8_t> src_scan,
2479 pdfium::span<
const uint8_t> clip_scan)
const {
2481 CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width,
2487 CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
2488 src_left, width, clip_scan);
2495 if (m_bRgbByteOrder) {
2497 CompositeRow_BitMask2Argb_RgbByteOrder(
2498 dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
2499 src_left, width, m_BlendType, clip_scan);
2501 CompositeRow_BitMask2Rgb_RgbByteOrder(
2502 dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
2510 CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
2511 m_MaskGreen, m_MaskBlue, src_left, width,
2512 m_BlendType, clip_scan);
2518 CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed,
2519 m_MaskGreen, m_MaskBlue, src_left, width,
2540 m_Width =
sizeof(uint8_t);
2541 m_nElements = nElements;
2542 m_pData.reset(
reinterpret_cast<uint32_t*>(FX_Alloc(uint8_t, m_nElements)));
2543 return {
reinterpret_cast<uint8_t*>(m_pData.get()), m_nElements};
2548 m_Width =
sizeof(uint32_t);
2549 m_nElements = nElements;
2550 m_pData.reset(FX_Alloc(uint32_t, m_nElements));
2551 return {m_pData.get(), m_nElements};
2556 CHECK(!m_pData || m_Width ==
sizeof(uint8_t));
2557 return {
reinterpret_cast<
const uint8_t*>(m_pData.get()), m_nElements};
2562 CHECK(!m_pData || m_Width ==
sizeof(uint32_t));
2563 return {m_pData.get(), m_nElements};
#define FXDIB_ALPHA_UNION(dest, src)
#define FXARGB_RGBORDERCOPY(dest, src)
void CompositeByteMaskLine(pdfium::span< uint8_t > dest_scan, pdfium::span< const uint8_t > src_scan, int width, pdfium::span< const uint8_t > clip_scan) const
void CompositePalBitmapLine(pdfium::span< uint8_t > dest_scan, pdfium::span< const uint8_t > src_scan, int src_left, int width, pdfium::span< const uint8_t > clip_scan) const
bool Init(FXDIB_Format dest_format, FXDIB_Format src_format, pdfium::span< const uint32_t > src_palette, uint32_t mask_color, BlendMode blend_type, bool bClip, bool bRgbByteOrder)
void CompositeRgbBitmapLine(pdfium::span< uint8_t > dest_scan, pdfium::span< const uint8_t > src_scan, int width, pdfium::span< const uint8_t > clip_scan) const
~CFX_ScanlineCompositor()
void CompositeBitMaskLine(pdfium::span< uint8_t > dest_scan, pdfium::span< const uint8_t > src_scan, int src_left, int width, pdfium::span< const uint8_t > clip_scan) const
#define FXRGB2GRAY(r, g, b)
#define FXARGB_SETRGBORDERDIB(p, argb)
void ReverseCopy3Bytes(uint8_t *dest, const uint8_t *src)
constexpr FX_ARGB ArgbEncode(uint32_t a, uint32_t r, uint32_t g, uint32_t b)
#define FXARGB_SETDIB(p, argb)
int GetBppFromFormat(FXDIB_Format format)
int GetCompsFromFormat(FXDIB_Format format)
#define FXDIB_ALPHA_MERGE(backdrop, source, source_alpha)
int Blend(BlendMode blend_mode, int back_color, int src_color)