Reduce scope of more UNSAFE_TODOs in dib code

Rewrite loops as described in
https://pdfium-review.googlesource.com/119312 to potentially make them
faster, and allow UNSAFE_TODOs to be defined more narrowly.

Change-Id: Iad1bba149e6015ae3a5c924d57fdc8919fe9b1aa
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121559
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
diff --git a/core/fxge/dib/cfx_dibbase.cpp b/core/fxge/dib/cfx_dibbase.cpp
index 5f7b423..9c7dbd5 100644
--- a/core/fxge/dib/cfx_dibbase.cpp
+++ b/core/fxge/dib/cfx_dibbase.cpp
@@ -930,17 +930,26 @@
 
   pFlipped->SetPalette(GetPaletteSpan());
   const int Bpp = GetBPP() / 8;
-  UNSAFE_TODO({
+  if (!bXFlip) {
     for (int row = 0; row < GetHeight(); ++row) {
-      const uint8_t* src_scan = GetScanline(row).data();
-      uint8_t* dest_scan =
-          pFlipped->GetWritableScanline(bYFlip ? GetHeight() - row - 1 : row)
-              .data();
-      if (!bXFlip) {
+      UNSAFE_TODO({
+        const uint8_t* src_scan = GetScanline(row).data();
+        uint8_t* dest_scan =
+            pFlipped->GetWritableScanline(bYFlip ? GetHeight() - row - 1 : row)
+                .data();
         FXSYS_memcpy(dest_scan, src_scan, GetPitch());
-        continue;
-      }
-      if (GetBPP() == 1) {
+      });
+    }
+    return pFlipped;
+  }
+
+  if (GetBPP() == 1) {
+    for (int row = 0; row < GetHeight(); ++row) {
+      UNSAFE_TODO({
+        const uint8_t* src_scan = GetScanline(row).data();
+        uint8_t* dest_scan =
+            pFlipped->GetWritableScanline(bYFlip ? GetHeight() - row - 1 : row)
+                .data();
         FXSYS_memset(dest_scan, 0, GetPitch());
         for (int col = 0; col < GetWidth(); ++col) {
           if (src_scan[col / 8] & (1 << (7 - col % 8))) {
@@ -948,34 +957,64 @@
             dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
           }
         }
-        continue;
-      }
+      });
+    }
+    return pFlipped;
+  }
 
-      dest_scan += (GetWidth() - 1) * Bpp;
-      if (Bpp == 1) {
+  if (Bpp == 1) {
+    for (int row = 0; row < GetHeight(); ++row) {
+      UNSAFE_TODO({
+        const uint8_t* src_scan = GetScanline(row).data();
+        uint8_t* dest_scan =
+            pFlipped->GetWritableScanline(bYFlip ? GetHeight() - row - 1 : row)
+                .data();
+        dest_scan += (GetWidth() - 1) * Bpp;
         for (int col = 0; col < GetWidth(); ++col) {
           *dest_scan = *src_scan;
           --dest_scan;
           ++src_scan;
         }
-      } else if (Bpp == 3) {
+      });
+    }
+    return pFlipped;
+  }
+
+  if (Bpp == 3) {
+    for (int row = 0; row < GetHeight(); ++row) {
+      UNSAFE_TODO({
+        const uint8_t* src_scan = GetScanline(row).data();
+        uint8_t* dest_scan =
+            pFlipped->GetWritableScanline(bYFlip ? GetHeight() - row - 1 : row)
+                .data();
+        dest_scan += (GetWidth() - 1) * Bpp;
         for (int col = 0; col < GetWidth(); ++col) {
           FXSYS_memcpy(dest_scan, src_scan, 3);
           dest_scan -= 3;
           src_scan += 3;
         }
-      } else {
-        DCHECK_EQ(Bpp, 4);
-        for (int col = 0; col < GetWidth(); ++col) {
-          const auto* src_scan32 = reinterpret_cast<const uint32_t*>(src_scan);
-          uint32_t* dest_scan32 = reinterpret_cast<uint32_t*>(dest_scan);
-          *dest_scan32 = *src_scan32;
-          dest_scan -= 4;
-          src_scan += 4;
-        }
-      }
+      });
     }
-  });
+    return pFlipped;
+  }
+
+  CHECK_EQ(Bpp, 4);
+  for (int row = 0; row < GetHeight(); ++row) {
+    UNSAFE_TODO({
+      const uint8_t* src_scan = GetScanline(row).data();
+      uint8_t* dest_scan =
+          pFlipped->GetWritableScanline(bYFlip ? GetHeight() - row - 1 : row)
+              .data();
+      dest_scan += (GetWidth() - 1) * Bpp;
+      for (int col = 0; col < GetWidth(); ++col) {
+        const auto* src_scan32 = reinterpret_cast<const uint32_t*>(src_scan);
+        uint32_t* dest_scan32 = reinterpret_cast<uint32_t*>(dest_scan);
+        *dest_scan32 = *src_scan32;
+        dest_scan -= 4;
+        src_scan += 4;
+      }
+    });
+  }
   return pFlipped;
 }
 
@@ -1023,14 +1062,14 @@
   const int row_end = bXFlip ? GetHeight() - dest_clip.left : dest_clip.right;
   const int col_start = bYFlip ? GetWidth() - dest_clip.bottom : dest_clip.top;
   const int col_end = bYFlip ? GetWidth() - dest_clip.top : dest_clip.bottom;
-  UNSAFE_TODO({
-    if (GetBPP() == 1) {
-      fxcrt::Fill(dest_span, 0xff);
-      if (bYFlip) {
-        dest_span = dest_span.subspan(dest_last_row_offset);
-      }
-      const int dest_step = bYFlip ? -dest_pitch : dest_pitch;
-      for (int row = row_start; row < row_end; ++row) {
+  if (GetBPP() == 1) {
+    fxcrt::Fill(dest_span, 0xff);
+    if (bYFlip) {
+      dest_span = dest_span.subspan(dest_last_row_offset);
+    }
+    const int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+    for (int row = row_start; row < row_end; ++row) {
+      UNSAFE_TODO({
         const uint8_t* src_scan = GetScanline(row).data();
         int dest_col =
             (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
@@ -1042,50 +1081,76 @@
           }
           dest_scan += dest_step;
         }
-      }
-    } else {
-      int nBytes = GetBPP() / 8;
-      int dest_step = bYFlip ? -dest_pitch : dest_pitch;
-      if (nBytes == 3) {
-        dest_step -= 2;
-      }
-      if (bYFlip) {
-        dest_span = dest_span.subspan(dest_last_row_offset);
-      }
-      for (int row = row_start; row < row_end; ++row) {
+      });
+    }
+    return pTransBitmap;
+  }
+
+  const int nBytes = GetBPP() / 8;
+  int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+  if (nBytes == 3) {
+    dest_step -= 2;
+  }
+  if (bYFlip) {
+    dest_span = dest_span.subspan(dest_last_row_offset);
+  }
+
+  if (nBytes == 1) {
+    for (int row = row_start; row < row_end; ++row) {
+      UNSAFE_TODO({
         int dest_col =
             (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
             dest_clip.left;
         size_t dest_offset = Fx2DSizeOrDie(dest_col, nBytes);
         uint8_t* dest_scan = dest_span.subspan(dest_offset).data();
-        if (nBytes == 4) {
-          const uint32_t* src_scan =
-              GetScanlineAs<const uint32_t>(row).subspan(col_start).data();
-          for (int col = col_start; col < col_end; ++col) {
-            uint32_t* dest_scan32 = reinterpret_cast<uint32_t*>(dest_scan);
-            *dest_scan32 = *src_scan++;
-            dest_scan += dest_step;
-          }
-        } else {
-          const uint8_t* src_scan =
-              GetScanline(row).subspan(col_start * nBytes).data();
-          if (nBytes == 1) {
-            for (int col = col_start; col < col_end; ++col) {
-              *dest_scan = *src_scan++;
-              dest_scan += dest_step;
-            }
-          } else {
-            for (int col = col_start; col < col_end; ++col) {
-              FXSYS_memcpy(dest_scan, src_scan, 3);
-              dest_scan += 2 + dest_step;
-              src_scan += 3;
-            }
-          }
+        const uint8_t* src_scan =
+            GetScanline(row).subspan(col_start * nBytes).data();
+        for (int col = col_start; col < col_end; ++col) {
+          *dest_scan = *src_scan++;
+          dest_scan += dest_step;
         }
-      }
+      });
     }
     return pTransBitmap;
-  });
+  }
+
+  if (nBytes == 3) {
+    for (int row = row_start; row < row_end; ++row) {
+      UNSAFE_TODO({
+        int dest_col =
+            (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
+            dest_clip.left;
+        size_t dest_offset = Fx2DSizeOrDie(dest_col, nBytes);
+        uint8_t* dest_scan = dest_span.subspan(dest_offset).data();
+        const uint8_t* src_scan =
+            GetScanline(row).subspan(col_start * nBytes).data();
+        for (int col = col_start; col < col_end; ++col) {
+          FXSYS_memcpy(dest_scan, src_scan, 3);
+          dest_scan += 2 + dest_step;
+          src_scan += 3;
+        }
+      });
+    }
+    return pTransBitmap;
+  }
+
+  CHECK_EQ(nBytes, 4);
+  for (int row = row_start; row < row_end; ++row) {
+    UNSAFE_TODO({
+      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
+                     dest_clip.left;
+      size_t dest_offset = Fx2DSizeOrDie(dest_col, nBytes);
+      uint8_t* dest_scan = dest_span.subspan(dest_offset).data();
+      const uint32_t* src_scan =
+          GetScanlineAs<const uint32_t>(row).subspan(col_start).data();
+      for (int col = col_start; col < col_end; ++col) {
+        uint32_t* dest_scan32 = reinterpret_cast<uint32_t*>(dest_scan);
+        *dest_scan32 = *src_scan++;
+        dest_scan += dest_step;
+      }
+    });
+  }
+  return pTransBitmap;
 }
 
 RetainPtr<CFX_DIBitmap> CFX_DIBBase::TransformTo(const CFX_Matrix& mtDest,
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 6d4be64..3eb6d8f 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -784,10 +784,11 @@
     }
     return true;
   }
-  for (int row = rect.top; row < rect.bottom; row++) {
-    UNSAFE_TODO({
-      uint8_t* dest_scan = m_pBuffer.Get() + row * GetPitch() + rect.left * Bpp;
-      if (bAlpha) {
+  if (bAlpha) {
+    for (int row = rect.top; row < rect.bottom; row++) {
+      UNSAFE_TODO({
+        uint8_t* dest_scan =
+            m_pBuffer.Get() + row * GetPitch() + rect.left * Bpp;
         for (int col = 0; col < width; col++) {
           uint8_t back_alpha = dest_scan[3];
           if (back_alpha == 0) {
@@ -807,17 +808,22 @@
           dest_scan++;
           *dest_scan++ = dest_alpha;
         }
-      } else {
-        for (int col = 0; col < width; col++) {
-          for (int comps = 0; comps < Bpp; comps++) {
-            if (comps == 3) {
-              *dest_scan++ = 255;
-              continue;
-            }
-            *dest_scan =
-                FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
-            dest_scan++;
+      });
+    }
+    return true;
+  }
+
+  for (int row = rect.top; row < rect.bottom; row++) {
+    UNSAFE_TODO({
+      uint8_t* dest_scan = m_pBuffer.Get() + row * GetPitch() + rect.left * Bpp;
+      for (int col = 0; col < width; col++) {
+        for (int comps = 0; comps < Bpp; comps++) {
+          if (comps == 3) {
+            *dest_scan++ = 255;
+            continue;
           }
+          *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
+          dest_scan++;
         }
       }
     });