Pass spans to ProgressiveDecoder::GifReadScanline().

In turn, pass these to called functions.

-- use span-safe functions to copy memory

Change-Id: I7b9ebfc7298f18715dfc9068ef03dd3b4c898823
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/100830
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/gif/cfx_gifcontext.cpp b/core/fxcodec/gif/cfx_gifcontext.cpp
index ea17daf..29b962e 100644
--- a/core/fxcodec/gif/cfx_gifcontext.cpp
+++ b/core/fxcodec/gif/cfx_gifcontext.cpp
@@ -30,7 +30,8 @@
 
 CFX_GifContext::~CFX_GifContext() = default;
 
-void CFX_GifContext::ReadScanline(int32_t row_num, uint8_t* row_buf) {
+void CFX_GifContext::ReadScanline(int32_t row_num,
+                                  pdfium::span<uint8_t> row_buf) {
   delegate_->GifReadScanline(row_num, row_buf);
 }
 
@@ -251,7 +252,7 @@
 
       while (ret != LZWDecompressor::Status::kError) {
         if (ret == LZWDecompressor::Status::kSuccess) {
-          ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
+          ReadScanline(gif_image->row_num, gif_image->row_buffer);
           gif_image->row_buffer.clear();
           SaveDecodingStatus(GIF_D_STATUS_TAIL);
           return GifDecoder::Status::kSuccess;
@@ -282,7 +283,7 @@
 
         if (ret == LZWDecompressor::Status::kInsufficientDestSize) {
           if (gif_image->image_info.local_flags.interlace) {
-            ReadScanline(gif_image->row_num, gif_image->row_buffer.data());
+            ReadScanline(gif_image->row_num, gif_image->row_buffer);
             gif_image->row_num += kGifInterlaceStep[img_pass_num_];
             if (gif_image->row_num >=
                 static_cast<int32_t>(gif_image->image_info.height)) {
@@ -294,7 +295,7 @@
               gif_image->row_num = kGifInterlaceStep[img_pass_num_] / 2;
             }
           } else {
-            ReadScanline(gif_image->row_num++, gif_image->row_buffer.data());
+            ReadScanline(gif_image->row_num++, gif_image->row_buffer);
           }
 
           img_row_offset_ = 0;
diff --git a/core/fxcodec/gif/cfx_gifcontext.h b/core/fxcodec/gif/cfx_gifcontext.h
index 206f368..5e651f9 100644
--- a/core/fxcodec/gif/cfx_gifcontext.h
+++ b/core/fxcodec/gif/cfx_gifcontext.h
@@ -15,6 +15,7 @@
 #include "core/fxcodec/gif/lzw_decompressor.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "third_party/base/span.h"
 
 class CFX_CodecMemory;
 
@@ -25,7 +26,7 @@
   explicit CFX_GifContext(GifDecoder::Delegate* delegate);
   ~CFX_GifContext() override;
 
-  void ReadScanline(int32_t row_num, uint8_t* row_buf);
+  void ReadScanline(int32_t row_num, pdfium::span<uint8_t> row_buf);
   bool GetRecordPosition(uint32_t cur_pos,
                          int32_t left,
                          int32_t top,
diff --git a/core/fxcodec/gif/gif_decoder.h b/core/fxcodec/gif/gif_decoder.h
index 6339cde..cfcf0e9 100644
--- a/core/fxcodec/gif/gif_decoder.h
+++ b/core/fxcodec/gif/gif_decoder.h
@@ -13,6 +13,7 @@
 #include "core/fxcodec/gif/cfx_gif.h"
 #include "core/fxcodec/progressive_decoder_iface.h"
 #include "core/fxcrt/fx_coordinates.h"
+#include "third_party/base/span.h"
 
 #ifndef PDF_ENABLE_XFA_GIF
 #error "GIF must be enabled"
@@ -37,7 +38,8 @@
                                            CFX_GifPalette* pal_ptr,
                                            int32_t trans_index,
                                            bool interlace) = 0;
-    virtual void GifReadScanline(int32_t row_num, uint8_t* row_buf) = 0;
+    virtual void GifReadScanline(int32_t row_num,
+                                 pdfium::span<uint8_t> row_buf) = 0;
   };
 
   static std::unique_ptr<ProgressiveDecoderIface::Context> StartDecode(
diff --git a/core/fxcodec/progressive_decoder.cpp b/core/fxcodec/progressive_decoder.cpp
index d79dd1b..e9db8c4 100644
--- a/core/fxcodec/progressive_decoder.cpp
+++ b/core/fxcodec/progressive_decoder.cpp
@@ -264,9 +264,12 @@
   int32_t dest_Bpp = (m_SrcFormat & 0xff) >> 3;
   int32_t src_left = m_startX;
   int32_t dest_left = m_clipBox.left;
-  const uint8_t* src_scan =
-      pDIBitmap->GetScanline(row).subspan(src_left * src_Bpp).data();
-  uint8_t* dest_scan = m_DecodeBuf.data() + dest_left * dest_Bpp;
+  pdfium::span<const uint8_t> src_span =
+      pDIBitmap->GetScanline(row).subspan(src_left * src_Bpp);
+  pdfium::span<uint8_t> dest_span =
+      pdfium::make_span(m_DecodeBuf).subspan(dest_left * dest_Bpp);
+  const uint8_t* src_scan = src_span.data();
+  uint8_t* dest_scan = dest_span.data();
   switch (pDIBitmap->GetFormat()) {
     case FXDIB_Format::k1bppMask:
     case FXDIB_Format::k1bppRgb:
@@ -344,8 +347,7 @@
     if (dest_row >= dest_top + dest_height) {
       return;
     }
-    PngOneOneMapResampleHorz(pDIBitmap, dest_row, m_DecodeBuf.data(),
-                             m_SrcFormat);
+    PngOneOneMapResampleHorz(pDIBitmap, dest_row, m_DecodeBuf, m_SrcFormat);
     if (m_SrcPassNumber == 1 && scale_y > 1.0) {
       ResampleVert(pDIBitmap, scale_y, dest_row);
       return;
@@ -444,28 +446,31 @@
   return true;
 }
 
-void ProgressiveDecoder::GifReadScanline(int32_t row_num, uint8_t* row_buf) {
+void ProgressiveDecoder::GifReadScanline(int32_t row_num,
+                                         pdfium::span<uint8_t> row_buf) {
   RetainPtr<CFX_DIBitmap> pDIBitmap = m_pDeviceBitmap;
   DCHECK(pDIBitmap);
   int32_t img_width = m_GifFrameRect.Width();
   if (!pDIBitmap->IsAlphaFormat()) {
-    uint8_t* byte_ptr = row_buf;
+    pdfium::span<uint8_t> byte_span = row_buf;
     for (int i = 0; i < img_width; i++) {
-      if (*byte_ptr == m_GifTransIndex) {
-        *byte_ptr = m_GifBgIndex;
+      if (byte_span.front() == m_GifTransIndex) {
+        byte_span.front() = m_GifBgIndex;
       }
-      byte_ptr++;
+      byte_span = byte_span.subspan(1);
     }
   }
   int32_t pal_index = m_GifBgIndex;
   if (m_GifTransIndex != -1 && m_pDeviceBitmap->IsAlphaFormat()) {
     pal_index = m_GifTransIndex;
   }
-  memset(m_DecodeBuf.data(), pal_index, m_SrcWidth);
+  const int32_t left = m_GifFrameRect.left;
+  const pdfium::span<uint8_t> decode_span = m_DecodeBuf;
+  fxcrt::spanset(decode_span.first(m_SrcWidth), pal_index);
+  fxcrt::spancpy(decode_span.subspan(left), row_buf.first(img_width));
+
   bool bLastPass = (row_num % 2) == 1;
   int32_t line = row_num + m_GifFrameRect.top;
-  int32_t left = m_GifFrameRect.left;
-  memcpy(m_DecodeBuf.data() + left, row_buf, img_width);
   int src_top = m_clipBox.top;
   int src_bottom = m_clipBox.bottom;
   int dest_top = m_startY;
@@ -480,7 +485,7 @@
   if (dest_row >= dest_top + dest_height)
     return;
 
-  ResampleScanline(pDIBitmap, dest_row, m_DecodeBuf.data(), m_SrcFormat);
+  ResampleScanline(pDIBitmap, dest_row, decode_span, m_SrcFormat);
   if (scale_y > 1.0 && m_SrcPassNumber == 1) {
     ResampleVert(pDIBitmap, scale_y, dest_row);
     return;
@@ -538,7 +543,7 @@
   if (dest_row >= dest_top + dest_height)
     return;
 
-  ResampleScanline(pDIBitmap, dest_row, m_DecodeBuf.data(), m_SrcFormat);
+  ResampleScanline(pDIBitmap, dest_row, m_DecodeBuf, m_SrcFormat);
   if (scale_y <= 1.0)
     return;
 
@@ -1058,13 +1063,13 @@
 void ProgressiveDecoder::PngOneOneMapResampleHorz(
     const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
     int32_t dest_line,
-    uint8_t* src_scan,
+    pdfium::span<uint8_t> src_span,
     FXCodec_Format src_format) {
   int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3;
   int32_t dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
   int32_t src_left = m_clipBox.left;
   int32_t dest_left = m_startX;
-  src_scan += src_left * src_Bpp;
+  uint8_t* src_scan = src_span.subspan(src_left * src_Bpp).data();
   uint8_t* dest_scan = pDeviceBitmap->GetWritableScanline(dest_line)
                            .subspan(dest_left * dest_Bpp)
                            .data();
@@ -1685,8 +1690,9 @@
 void ProgressiveDecoder::ResampleScanline(
     const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
     int dest_line,
-    uint8_t* src_scan,
+    pdfium::span<uint8_t> src_span,
     FXCodec_Format src_format) {
+  uint8_t* src_scan = src_span.data();
   int src_left = m_clipBox.left;
   int dest_left = m_startX;
   uint8_t* dest_scan = pDeviceBitmap->GetWritableScanline(dest_line).data();
@@ -2034,7 +2040,7 @@
     if (dest_row >= dest_top + dest_height)
       return;
 
-    ResampleScanline(pDeviceBitmap, dest_row, m_DecodeBuf.data(), src_format);
+    ResampleScanline(pDeviceBitmap, dest_row, m_DecodeBuf, src_format);
     if (scale_y > 1.0)
       ResampleVert(pDeviceBitmap, scale_y, dest_row);
   }
diff --git a/core/fxcodec/progressive_decoder.h b/core/fxcodec/progressive_decoder.h
index c830900..117f937 100644
--- a/core/fxcodec/progressive_decoder.h
+++ b/core/fxcodec/progressive_decoder.h
@@ -20,6 +20,7 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/dib/cstretchengine.h"
 #include "core/fxge/dib/fx_dib.h"
+#include "third_party/base/span.h"
 
 #ifdef PDF_ENABLE_XFA_BMP
 #include "core/fxcodec/bmp/bmp_decoder.h"
@@ -111,7 +112,7 @@
                                  CFX_GifPalette* pal_ptr,
                                  int32_t trans_index,
                                  bool interlace) override;
-  void GifReadScanline(int32_t row_num, uint8_t* row_buf) override;
+  void GifReadScanline(int32_t row_num, pdfium::span<uint8_t> row_buf) override;
 #endif  // PDF_ENABLE_XFA_GIF
 
 #ifdef PDF_ENABLE_XFA_BMP
@@ -178,7 +179,7 @@
 #ifdef PDF_ENABLE_XFA_PNG
   void PngOneOneMapResampleHorz(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
                                 int32_t dest_line,
-                                uint8_t* src_scan,
+                                pdfium::span<uint8_t> src_span,
                                 FXCodec_Format src_format);
   bool PngDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute);
   FXCODEC_STATUS PngStartDecode();
@@ -206,7 +207,7 @@
 
   void ResampleScanline(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
                         int32_t dest_line,
-                        uint8_t* src_scan,
+                        pdfium::span<uint8_t> src_span,
                         FXCodec_Format src_format);
   void Resample(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
                 int32_t src_line,