Replace buggy CompositeRowBgraPremul2BgraPremul() with Skia calls The existing CompositeRowBgraPremul2BgraPremul() has a lot of bugs. Instead of trying to fix it, throw it all away and use Skia for blending. Skia already has an optimized pipeline for doing blending, so this is simpler and faster. Update ScanlineCompositorTest expectations with the values from the new code. Now the straight and pre-multiplied test expectations are roughly the same, modulo rounding issues. Bug: 514846121 Change-Id: Ia189d3d3df7a3d7a4670ddde6f5476c9d84e9c3f Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/151711 Reviewed-by: Andy Phan <andyphan@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/dib/cfx_scanlinecompositor.cpp b/core/fxge/dib/cfx_scanlinecompositor.cpp index 8b29fb0..936ee83 100644 --- a/core/fxge/dib/cfx_scanlinecompositor.cpp +++ b/core/fxge/dib/cfx_scanlinecompositor.cpp
@@ -19,6 +19,16 @@ #include "core/fxge/dib/blend.h" #include "core/fxge/dib/fx_dib.h" +#if defined(PDF_USE_SKIA) +#include <type_traits> + +#include "third_party/skia/include/core/SkBlendMode.h" // nogncheck +#include "third_party/skia/include/core/SkCanvas.h" // nogncheck +#include "third_party/skia/include/core/SkImage.h" // nogncheck +#include "third_party/skia/include/core/SkPaint.h" // nogncheck +#include "third_party/skia/include/core/SkPixmap.h" // nogncheck +#endif + using fxge::Blend; using GrayWithAlpha = CFX_ScanlineCompositor::GrayWithAlpha; @@ -150,17 +160,6 @@ output.red = AlphaMerge(output.red, input.red, alpha); } -#if defined(PDF_USE_SKIA) -template <typename T, typename U> -void AlphaMergeToDestPremul(const T& input, U& output) { - const int in_alpha = 255 - input.alpha; - const int out_alpha = 255 - output.alpha; - output.blue = (output.blue * in_alpha + input.blue * out_alpha) / 255; - output.green = (output.green * in_alpha + input.green * out_alpha) / 255; - output.red = (output.red * in_alpha + input.red * out_alpha) / 255; -} -#endif // defined(PDF_USE_SKIA) - template <typename T, typename U> void AlphaMergeToSource(const T& input, U& output, uint8_t alpha) { output.blue = AlphaMerge(input.blue, output.blue, alpha); @@ -659,113 +658,40 @@ } #if defined(PDF_USE_SKIA) -// Returns false when no further work is required by the caller. Otherwise, -// returns true and the caller needs to call one of the -// CompositePixelBgraPremul2BgraPremul*Blend() functions. -template <typename DestPixelStruct> -uint8_t CompositePixelBgraPremul2BgraPremulCommon( - const FX_BGRA_STRUCT<uint8_t>& input, - DestPixelStruct& output) { - if (output.alpha != 0) { - return true; - } - - output.blue = input.blue; - output.green = input.green; - output.red = input.red; - output.alpha = input.alpha; - return false; -} - -template <typename DestPixelStruct> -void CompositePixelBgraPremul2BgraPremulNonSeparableBlend( - const FX_BGRA_STRUCT<uint8_t>& input, - DestPixelStruct& output, - BlendMode blend_type) { - if (!CompositePixelBgraPremul2BgraPremulCommon(input, output)) { - return; - } - - FX_BGRA_STRUCT<uint8_t> input_for_blend; - input_for_blend.blue = input.blue * output.alpha / 255; - input_for_blend.green = input.green * output.alpha / 255; - input_for_blend.red = input.red * output.alpha / 255; - DestPixelStruct output_for_blend; - output_for_blend.blue = output.blue * input.alpha / 255; - output_for_blend.green = output.green * input.alpha / 255; - output_for_blend.red = output.red * input.alpha / 255; - FX_RGB_STRUCT<int> blended_color = - RgbBlend(blend_type, input_for_blend, output_for_blend); - - AlphaMergeToDestPremul(input, output); - output.blue += blended_color.blue; - output.green += blended_color.green; - output.red += blended_color.red; - output.alpha = AlphaUnion(output.alpha, input.alpha); -} - -template <typename DestPixelStruct> -void CompositePixelBgraPremul2BgraPremulBlend( - const FX_BGRA_STRUCT<uint8_t>& input, - DestPixelStruct& output, - BlendMode blend_type) { - if (!CompositePixelBgraPremul2BgraPremulCommon(input, output)) { - return; - } - - FX_BGR_STRUCT<int> blended_color = { - .blue = Blend(blend_type, input.blue * output.alpha / 255, - output.blue * input.alpha / 255), - .green = Blend(blend_type, input.green * output.alpha / 255, - output.green * input.alpha / 255), - .red = Blend(blend_type, input.red * output.alpha / 255, - output.red * input.alpha / 255), - }; - - AlphaMergeToDestPremul(input, output); - output.blue += blended_color.blue; - output.green += blended_color.green; - output.red += blended_color.red; - output.alpha = AlphaUnion(output.alpha, input.alpha); -} - -template <typename DestPixelStruct> -void CompositePixelBgraPremul2BgraPremulNoBlend( - const FX_BGRA_STRUCT<uint8_t>& input, - DestPixelStruct& output) { - if (!CompositePixelBgraPremul2BgraPremulCommon(input, output)) { - return; - } - - const int in_alpha = 255 - input.alpha; - output.blue = input.blue + output.blue * in_alpha / 255; - output.green = input.green + output.green * in_alpha / 255; - output.red = input.red + output.red * in_alpha / 255; - output.alpha = AlphaUnion(output.alpha, input.alpha); -} - template <typename DestPixelStruct> void CompositeRowBgraPremul2BgraPremul( pdfium::span<const FX_BGRA_STRUCT<uint8_t>> src_span, pdfium::span<DestPixelStruct> dest_span, BlendMode blend_type) { - const bool non_separable_blend = IsNonSeparableBlendMode(blend_type); - if (non_separable_blend) { - for (auto [input, output] : fxcrt::Zip(src_span, dest_span)) { - CompositePixelBgraPremul2BgraPremulNonSeparableBlend(input, output, - blend_type); - } + if (src_span.empty()) { return; } - if (blend_type != BlendMode::kNormal) { - for (auto [input, output] : fxcrt::Zip(src_span, dest_span)) { - CompositePixelBgraPremul2BgraPremulBlend(input, output, blend_type); - } - return; + + SkColorType dest_color_type; + if constexpr (std::is_same_v<DestPixelStruct, FX_BGRA_STRUCT<uint8_t>>) { + dest_color_type = kBGRA_8888_SkColorType; + } else { + static_assert(std::is_same_v<DestPixelStruct, FX_RGBA_STRUCT<uint8_t>>); + dest_color_type = kRGBA_8888_SkColorType; } - for (auto [input, output] : fxcrt::Zip(src_span, dest_span)) { - CompositePixelBgraPremul2BgraPremulNoBlend(input, output); - } + + const int width = static_cast<int>(src_span.size()); + SkImageInfo src_info = SkImageInfo::Make( + width, /*height=*/1, kBGRA_8888_SkColorType, kPremul_SkAlphaType); + SkImageInfo dest_info = SkImageInfo::Make( + width, /*height=*/1, dest_color_type, kPremul_SkAlphaType); + + SkPixmap src_pixmap(src_info, src_span.data(), src_info.minRowBytes()); + sk_sp<SkImage> src_image = + SkImages::RasterFromPixmap(src_pixmap, nullptr, nullptr); + + std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect( + dest_info, dest_span.data(), dest_info.minRowBytes()); + CHECK(canvas); + + SkPaint paint; + paint.setBlendMode(GetSkiaBlendMode(blend_type)); + canvas->drawImage(src_image, 0, 0, SkSamplingOptions(), &paint); } #endif // defined(PDF_USE_SKIA)
diff --git a/core/fxge/dib/cfx_scanlinecompositor_unittest.cpp b/core/fxge/dib/cfx_scanlinecompositor_unittest.cpp index 42682d3..6b78d29 100644 --- a/core/fxge/dib/cfx_scanlinecompositor_unittest.cpp +++ b/core/fxge/dib/cfx_scanlinecompositor_unittest.cpp
@@ -8,6 +8,7 @@ #include <array> +#include "build/build_config.h" #include "core/fxcrt/span.h" #include "core/fxcrt/stl_util.h" #include "core/fxge/dib/fx_dib.h" @@ -480,10 +481,16 @@ {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 253, .green = 98, .red = 0, .alpha = 161}, - {.blue = 253, .green = 98, .red = 0, .alpha = 222}, - {.blue = 253, .green = 98, .red = 0, .alpha = 222}, - {.blue = 253, .green = 98, .red = 0, .alpha = 244}, +#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64) + {.blue = 255, .green = 99, .red = 0, .alpha = 161}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, +#else + {.blue = 255, .green = 98, .red = 0, .alpha = 160}, + {.blue = 255, .green = 99, .red = 0, .alpha = 221}, + {.blue = 255, .green = 99, .red = 0, .alpha = 221}, +#endif + {.blue = 255, .green = 99, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { @@ -491,10 +498,16 @@ {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 100, .green = 0, .red = 255, .alpha = 255}, - {.blue = 156, .green = 36, .red = 158, .alpha = 161}, - {.blue = 113, .green = 9, .red = 229, .alpha = 222}, - {.blue = 183, .green = 53, .red = 114, .alpha = 222}, - {.blue = 126, .green = 16, .red = 209, .alpha = 244}, +#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64) + {.blue = 158, .green = 38, .red = 158, .alpha = 161}, + {.blue = 114, .green = 9, .red = 229, .alpha = 222}, + {.blue = 184, .green = 53, .red = 114, .alpha = 222}, +#else + {.blue = 157, .green = 36, .red = 159, .alpha = 160}, + {.blue = 114, .green = 9, .red = 230, .alpha = 221}, + {.blue = 184, .green = 54, .red = 115, .alpha = 221}, +#endif + {.blue = 126, .green = 17, .red = 209, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { @@ -502,16 +515,20 @@ {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 0, .green = 255, .red = 100, .alpha = 255}, - {.blue = 95, .green = 194, .red = 61, .alpha = 161}, - {.blue = 24, .green = 238, .red = 89, .alpha = 222}, - {.blue = 138, .green = 168, .red = 44, .alpha = 222}, - {.blue = 44, .green = 225, .red = 81, .alpha = 244}, +#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64) + {.blue = 96, .green = 196, .red = 61, .alpha = 161}, + {.blue = 25, .green = 238, .red = 89, .alpha = 222}, + {.blue = 140, .green = 168, .red = 44, .alpha = 222}, +#else + {.blue = 95, .green = 196, .red = 62, .alpha = 160}, + {.blue = 24, .green = 240, .red = 90, .alpha = 221}, + {.blue = 139, .green = 169, .red = 45, .alpha = 221}, +#endif + {.blue = 45, .green = 227, .red = 81, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } -#if !defined(NDEBUG) -// TODO(crbug.com/514846121): Should pass in release mode as well. TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulScreen) { CFX_ScanlineCompositor compositor; ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgraPremul, @@ -521,44 +538,41 @@ /*blend_type=*/BlendMode::kScreen, /*bRgbByteOrder=*/false)); - // TODO(crbug.com/514846121): Blue and green values are wrong. static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 161, .red = 0, .alpha = 255}, - {.blue = 51, .green = 121, .red = 0, .alpha = 161}, - {.blue = 22, .green = 128, .red = 0, .alpha = 222}, - {.blue = 22, .green = 128, .red = 0, .alpha = 222}, - {.blue = 49, .green = 147, .red = 0, .alpha = 244}, + {.blue = 255, .green = 114, .red = 0, .alpha = 161}, + {.blue = 255, .green = 120, .red = 0, .alpha = 222}, + {.blue = 255, .green = 120, .red = 0, .alpha = 222}, + {.blue = 255, .green = 138, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); - // TODO(crbug.com/514846121): Some blue values are wrong. static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 255, .alpha = 255}, - {.blue = 215, .green = 60, .red = 156, .alpha = 161}, - {.blue = 191, .green = 43, .red = 228, .alpha = 222}, - {.blue = 5, .green = 88, .red = 113, .alpha = 222}, - {.blue = 249, .green = 80, .red = 207, .alpha = 244}, + {.blue = 196, .green = 61, .red = 158, .alpha = 161}, + {.blue = 168, .green = 44, .red = 229, .alpha = 222}, + {.blue = 238, .green = 89, .red = 114, .alpha = 222}, + {.blue = 227, .green = 81, .red = 209, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); - // TODO(crbug.com/514846121): Some green values are wrong. + static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 255, .red = 100, .alpha = 255}, - {.blue = 156, .green = 215, .red = 60, .alpha = 161}, - {.blue = 113, .green = 5, .red = 88, .alpha = 222}, - {.blue = 228, .green = 191, .red = 43, .alpha = 222}, - {.blue = 207, .green = 249, .red = 80, .alpha = 244}, + {.blue = 158, .green = 196, .red = 61, .alpha = 161}, + {.blue = 114, .green = 238, .red = 89, .alpha = 222}, + {.blue = 229, .green = 168, .red = 44, .alpha = 222}, + {.blue = 209, .green = 227, .red = 81, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } -#endif TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulDarken) { CFX_ScanlineCompositor compositor; @@ -574,10 +588,16 @@ {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, +#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64) + {.blue = 255, .green = 99, .red = 0, .alpha = 161}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, +#else {.blue = 253, .green = 98, .red = 0, .alpha = 161}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 252, .green = 98, .red = 0, .alpha = 244}, + {.blue = 253, .green = 98, .red = 0, .alpha = 222}, + {.blue = 253, .green = 98, .red = 0, .alpha = 222}, +#endif + {.blue = 255, .green = 99, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { @@ -585,10 +605,16 @@ {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 100, .green = 0, .red = 0, .alpha = 255}, +#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64) + {.blue = 158, .green = 38, .red = 96, .alpha = 161}, + {.blue = 114, .green = 9, .red = 140, .alpha = 222}, + {.blue = 184, .green = 53, .red = 25, .alpha = 222}, +#else {.blue = 156, .green = 36, .red = 95, .alpha = 161}, - {.blue = 112, .green = 9, .red = 138, .alpha = 222}, - {.blue = 182, .green = 53, .red = 24, .alpha = 222}, - {.blue = 125, .green = 16, .red = 44, .alpha = 244}, + {.blue = 113, .green = 9, .red = 138, .alpha = 222}, + {.blue = 183, .green = 53, .red = 24, .alpha = 222}, +#endif + {.blue = 126, .green = 17, .red = 45, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { @@ -596,16 +622,20 @@ {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 0, .green = 100, .red = 0, .alpha = 255}, +#if BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_ARM64) + {.blue = 96, .green = 158, .red = 38, .alpha = 161}, + {.blue = 25, .green = 184, .red = 53, .alpha = 222}, + {.blue = 140, .green = 114, .red = 9, .alpha = 222}, +#else {.blue = 95, .green = 156, .red = 36, .alpha = 161}, - {.blue = 24, .green = 182, .red = 53, .alpha = 222}, - {.blue = 138, .green = 112, .red = 9, .alpha = 222}, - {.blue = 44, .green = 125, .red = 16, .alpha = 244}, + {.blue = 24, .green = 183, .red = 53, .alpha = 222}, + {.blue = 138, .green = 113, .red = 9, .alpha = 222}, +#endif + {.blue = 45, .green = 126, .red = 17, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } -#if !defined(NDEBUG) -// TODO(crbug.com/514846121): Should pass in release mode as well. TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulSoftLight) { CFX_ScanlineCompositor compositor; ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgraPremul, @@ -615,44 +645,40 @@ /*blend_type=*/BlendMode::kSoftLight, /*bRgbByteOrder=*/false)); - // TODO(crbug.com/514846121): Blue and green values are wrong. static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 87, .red = 0, .alpha = 255}, - {.blue = 218, .green = 79, .red = 0, .alpha = 161}, - {.blue = 229, .green = 74, .red = 0, .alpha = 222}, - {.blue = 229, .green = 74, .red = 0, .alpha = 222}, - {.blue = 6, .green = 73, .red = 0, .alpha = 244}, + {.blue = 255, .green = 96, .red = 0, .alpha = 161}, + {.blue = 255, .green = 94, .red = 0, .alpha = 222}, + {.blue = 255, .green = 94, .red = 0, .alpha = 222}, + {.blue = 255, .green = 91, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); - // TODO(crbug.com/514846121): Blue, green and red values are wrong. static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 160, .green = 0, .red = 255, .alpha = 255}, - {.blue = 142, .green = 36, .red = 104, .alpha = 161}, - {.blue = 101, .green = 9, .red = 166, .alpha = 222}, - {.blue = 171, .green = 53, .red = 51, .alpha = 222}, - {.blue = 140, .green = 16, .red = 145, .alpha = 244}, + {.blue = 255, .green = 39, .red = 0, .alpha = 255}, + {.blue = 196, .green = 47, .red = 96, .alpha = 161}, + {.blue = 168, .green = 22, .red = 140, .alpha = 222}, + {.blue = 238, .green = 67, .red = 25, .alpha = 222}, + {.blue = 227, .green = 43, .red = 45, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); - // TODO(crbug.com/514846121): Blue, green and red values are wrong. static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 0, .green = 255, .red = 40, .alpha = 255}, - {.blue = 95, .green = 148, .red = 38, .alpha = 161}, - {.blue = 24, .green = 190, .red = 58, .alpha = 222}, - {.blue = 138, .green = 120, .red = 13, .alpha = 222}, - {.blue = 44, .green = 192, .red = 32, .alpha = 244}, + {.blue = 255, .green = 160, .red = 0, .alpha = 255}, + {.blue = 158, .green = 172, .red = 38, .alpha = 161}, + {.blue = 114, .green = 205, .red = 53, .alpha = 222}, + {.blue = 229, .green = 135, .red = 9, .alpha = 222}, + {.blue = 209, .green = 165, .red = 17, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } -#endif TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulHue) { CFX_ScanlineCompositor compositor; @@ -668,32 +694,32 @@ {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 253, .green = 98, .red = 0, .alpha = 161}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 252, .green = 98, .red = 0, .alpha = 244}, + {.blue = 255, .green = 99, .red = 0, .alpha = 161}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 99, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 100, .green = 0, .red = 255, .alpha = 255}, - {.blue = 156, .green = 36, .red = 156, .alpha = 161}, - {.blue = 112, .green = 9, .red = 228, .alpha = 222}, - {.blue = 182, .green = 53, .red = 113, .alpha = 222}, - {.blue = 125, .green = 16, .red = 207, .alpha = 244}, + {.blue = 99, .green = 0, .red = 254, .alpha = 255}, + {.blue = 158, .green = 38, .red = 158, .alpha = 161}, + {.blue = 113, .green = 9, .red = 228, .alpha = 222}, + {.blue = 183, .green = 53, .red = 113, .alpha = 222}, + {.blue = 126, .green = 17, .red = 208, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 0, .green = 123, .red = 49, .alpha = 255}, - {.blue = 95, .green = 161, .red = 49, .alpha = 161}, - {.blue = 24, .green = 189, .red = 71, .alpha = 222}, - {.blue = 138, .green = 119, .red = 26, .alpha = 222}, - {.blue = 44, .green = 140, .red = 48, .alpha = 244}, + {.blue = 0, .green = 123, .red = 48, .alpha = 255}, + {.blue = 96, .green = 163, .red = 49, .alpha = 161}, + {.blue = 25, .green = 192, .red = 71, .alpha = 222}, + {.blue = 140, .green = 122, .red = 26, .alpha = 222}, + {.blue = 45, .green = 141, .red = 48, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } @@ -712,10 +738,10 @@ {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 253, .green = 98, .red = 0, .alpha = 161}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 252, .green = 98, .red = 0, .alpha = 244}, + {.blue = 255, .green = 99, .red = 0, .alpha = 161}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 99, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { @@ -723,10 +749,10 @@ {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 194, .green = 60, .red = 95, .alpha = 161}, - {.blue = 167, .green = 43, .red = 138, .alpha = 222}, - {.blue = 237, .green = 88, .red = 24, .alpha = 222}, - {.blue = 224, .green = 80, .red = 44, .alpha = 244}, + {.blue = 196, .green = 61, .red = 96, .alpha = 161}, + {.blue = 168, .green = 44, .red = 140, .alpha = 222}, + {.blue = 238, .green = 89, .red = 25, .alpha = 222}, + {.blue = 227, .green = 81, .red = 45, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { @@ -734,10 +760,10 @@ {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 156, .green = 156, .red = 36, .alpha = 161}, - {.blue = 113, .green = 182, .red = 53, .alpha = 222}, - {.blue = 228, .green = 112, .red = 9, .alpha = 222}, - {.blue = 207, .green = 125, .red = 16, .alpha = 244}, + {.blue = 158, .green = 158, .red = 38, .alpha = 161}, + {.blue = 114, .green = 184, .red = 53, .alpha = 222}, + {.blue = 229, .green = 114, .red = 9, .alpha = 222}, + {.blue = 209, .green = 126, .red = 17, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } @@ -756,38 +782,36 @@ {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 253, .green = 98, .red = 0, .alpha = 161}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 252, .green = 98, .red = 0, .alpha = 244}, + {.blue = 255, .green = 99, .red = 0, .alpha = 161}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 99, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 100, .green = 0, .red = 255, .alpha = 255}, - {.blue = 156, .green = 36, .red = 156, .alpha = 161}, - {.blue = 112, .green = 9, .red = 228, .alpha = 222}, - {.blue = 182, .green = 53, .red = 113, .alpha = 222}, - {.blue = 125, .green = 16, .red = 207, .alpha = 244}, + {.blue = 99, .green = 0, .red = 254, .alpha = 255}, + {.blue = 158, .green = 38, .red = 158, .alpha = 161}, + {.blue = 113, .green = 9, .red = 228, .alpha = 222}, + {.blue = 183, .green = 53, .red = 113, .alpha = 222}, + {.blue = 126, .green = 17, .red = 208, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 0, .green = 123, .red = 49, .alpha = 255}, - {.blue = 95, .green = 161, .red = 49, .alpha = 161}, - {.blue = 24, .green = 189, .red = 71, .alpha = 222}, - {.blue = 138, .green = 119, .red = 26, .alpha = 222}, - {.blue = 44, .green = 140, .red = 48, .alpha = 244}, + {.blue = 0, .green = 123, .red = 48, .alpha = 255}, + {.blue = 96, .green = 163, .red = 49, .alpha = 161}, + {.blue = 25, .green = 192, .red = 71, .alpha = 222}, + {.blue = 140, .green = 122, .red = 26, .alpha = 222}, + {.blue = 45, .green = 141, .red = 48, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } -#if !defined(NDEBUG) -// TODO(crbug.com/514846121): Should pass in release mode as well. TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulLuminosity) { CFX_ScanlineCompositor compositor; ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgraPremul, @@ -802,35 +826,33 @@ {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 253, .green = 98, .red = 0, .alpha = 161}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 253, .green = 97, .red = 0, .alpha = 222}, - {.blue = 252, .green = 98, .red = 0, .alpha = 244}, + {.blue = 255, .green = 99, .red = 0, .alpha = 161}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 98, .red = 0, .alpha = 222}, + {.blue = 255, .green = 99, .red = 0, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1); static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 100, .green = 0, .red = 255, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 194, .green = 60, .red = 95, .alpha = 161}, - {.blue = 167, .green = 43, .red = 138, .alpha = 222}, - {.blue = 237, .green = 88, .red = 24, .alpha = 222}, - {.blue = 224, .green = 80, .red = 44, .alpha = 244}, + {.blue = 255, .green = 100, .red = 1, .alpha = 255}, + {.blue = 196, .green = 61, .red = 96, .alpha = 161}, + {.blue = 168, .green = 44, .red = 140, .alpha = 222}, + {.blue = 238, .green = 89, .red = 25, .alpha = 222}, + {.blue = 227, .green = 81, .red = 46, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2); - // TODO(crbug.com/514846121): Some blue and red values are wrong. static constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = { {.blue = 0, .green = 0, .red = 0, .alpha = 0}, {.blue = 0, .green = 255, .red = 100, .alpha = 255}, {.blue = 255, .green = 100, .red = 0, .alpha = 255}, - {.blue = 255, .green = 185, .red = 142, .alpha = 255}, - {.blue = 178, .green = 178, .red = 58, .alpha = 161}, - {.blue = 147, .green = 215, .red = 87, .alpha = 222}, - {.blue = 05, .green = 145, .red = 42, .alpha = 222}, - {.blue = 00, .green = 184, .red = 76, .alpha = 244}, + {.blue = 255, .green = 186, .red = 142, .alpha = 255}, + {.blue = 158, .green = 178, .red = 72, .alpha = 161}, + {.blue = 114, .green = 214, .red = 104, .alpha = 222}, + {.blue = 229, .green = 144, .red = 59, .alpha = 222}, + {.blue = 209, .green = 182, .red = 109, .alpha = 243}, }; RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3); } -#endif #endif // defined(PDF_USE_SKIA)