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)