Composite opaque BGR rows via Zip() and skip per-pixel alpha division

CompositeRow_Bgr2Bgra_NoBlend_NoClip() advanced through the source row
by reassigning src_span via subspan(src_Bpp) once per pixel, which
bounds-checks against the shrinking span's own size every iteration.
The compiler cannot elide that check, because the checked offset is a
derived induction variable rather than the loop's own.

The caller knows the source format, so let it reinterpret the row into
fixed-size pixel structs and hand the compositor a typed span. The row
then becomes a single fxcrt::Zip() loop that compares sizes once and
iterates checklessly.

On the per-pixel BGRA no-blend path, the two callers already branch on
src_alpha, so they now handle a fully opaque source directly.
AlphaUnion() would be 255, the ratio 255, and AlphaMerge(..., 255)
returns the source, so that case is a copy and skips the general path's
division entirely. Opaque pixels dominate in real documents.

Bug: 549552310
Change-Id: Iba8d9bf1326c8d9a539e1c4db614ee29405c83d3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/155530
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@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 2849e73..498f80a 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.cpp
+++ b/core/fxge/dib/cfx_scanlinecompositor.cpp
@@ -412,18 +412,43 @@
   });
 }
 
+// Copies a source pixel into a BGRA destination, forcing it opaque. The
+// source may carry an alpha channel or not; it is ignored either way.
+template <typename SrcPixelStruct, typename DestPixelStruct>
+void CopyPixelToOpaqueBgra(const SrcPixelStruct& input,
+                           DestPixelStruct& output) {
+  output.blue = input.blue;
+  output.green = input.green;
+  output.red = input.red;
+  output.alpha = 255;
+}
+
+template <typename DestPixelStruct, typename SrcPixelStruct>
+void CopyRowToOpaqueBgra(pdfium::span<DestPixelStruct> dest_span,
+                         pdfium::span<const SrcPixelStruct> src_span) {
+  for (auto [dest, src] : fxcrt::Zip(dest_span, src_span)) {
+    CopyPixelToOpaqueBgra(src, dest);
+  }
+}
+
+// Picks the source pixel layout for the row above. A kBgr source has 3-byte
+// pixels and a kBgrx source 4-byte ones, whose 4th byte is ignored.
 template <typename DestPixelStruct>
 void CompositeRow_Bgr2Bgra_NoBlend_NoClip(
     pdfium::span<DestPixelStruct> dest_span,
     pdfium::span<const uint8_t> src_span,
-    size_t src_Bpp) {
-  for (auto& dest : dest_span) {
-    dest.blue = src_span[0];
-    dest.green = src_span[1];
-    dest.red = src_span[2];
-    dest.alpha = 255;
-    src_span = src_span.subspan(src_Bpp);
+    int src_Bpp) {
+  const size_t width = dest_span.size();
+  if (src_Bpp == 3) {
+    CopyRowToOpaqueBgra(dest_span,
+                        fxcrt::reinterpret_span<const FX_BGR_STRUCT<uint8_t>>(
+                            src_span.first(width * 3)));
+    return;
   }
+  CHECK_EQ(src_Bpp, 4);
+  CopyRowToOpaqueBgra(dest_span,
+                      fxcrt::reinterpret_span<const FX_BGRA_STRUCT<uint8_t>>(
+                          src_span.first(width * 4)));
 }
 
 template <typename DestPixelStruct>
@@ -613,7 +638,12 @@
     for (auto [input, output] : fxcrt::Zip(src_span, dest_span)) {
       const uint8_t src_alpha =
           CompositePixelBgra2BgraCommon(input, /*clip=*/255, output);
-      if (src_alpha != 0) {
+      if (src_alpha == 255) {
+        // Fully opaque source: AlphaUnion() would be 255, the ratio 255, and
+        // AlphaMerge(..., 255) returns the source, so the general path in
+        // CompositePixelBgra2BgraNoBlend() reduces to a plain copy.
+        CopyPixelToOpaqueBgra(input, output);
+      } else if (src_alpha != 0) {
         CompositePixelBgra2BgraNoBlend(input, src_alpha, output);
       }
     }
@@ -647,7 +677,10 @@
        fxcrt::Zip(src_span, clip_span, dest_span)) {
     const uint8_t src_alpha =
         CompositePixelBgra2BgraCommon(input, clip, output);
-    if (src_alpha != 0) {
+    if (src_alpha == 255) {
+      // Same plain-copy reduction as the no-clip loop above.
+      CopyPixelToOpaqueBgra(input, output);
+    } else if (src_alpha != 0) {
       CompositePixelBgra2BgraNoBlend(input, src_alpha, output);
     }
   }