Use std::span<> in CCodec_JPEGModule

Also rename .cpp file to match class name and .h file.
Modify some helper functions to operate on spans.
Move some initializations to member declarations.

Change-Id: Ie0889bda91daaef80fae6f5681f8ce068e92453b
Reviewed-on: https://pdfium-review.googlesource.com/41534
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 00a5448..8386f03 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -727,6 +727,7 @@
     "core/fxcodec/codec/ccodec_flatemodule.h",
     "core/fxcodec/codec/ccodec_iccmodule.h",
     "core/fxcodec/codec/ccodec_jbig2module.h",
+    "core/fxcodec/codec/ccodec_jpegmodule.cpp",
     "core/fxcodec/codec/ccodec_jpegmodule.h",
     "core/fxcodec/codec/ccodec_jpxmodule.h",
     "core/fxcodec/codec/ccodec_scanlinedecoder.cpp",
@@ -738,7 +739,6 @@
     "core/fxcodec/codec/fx_codec_flate.cpp",
     "core/fxcodec/codec/fx_codec_icc.cpp",
     "core/fxcodec/codec/fx_codec_jbig.cpp",
-    "core/fxcodec/codec/fx_codec_jpeg.cpp",
     "core/fxcodec/codec/fx_codec_jpx_opj.cpp",
     "core/fxcodec/fx_codec.h",
     "core/fxcodec/fx_codec_def.h",
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index b1c2fc9..9fdfa76 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -71,15 +71,15 @@
   return m_pStream ? m_pStream->GetDict() : nullptr;
 }
 
-std::unique_ptr<CPDF_Dictionary> CPDF_Image::InitJPEG(uint8_t* pData,
-                                                      uint32_t size) {
+std::unique_ptr<CPDF_Dictionary> CPDF_Image::InitJPEG(
+    pdfium::span<uint8_t> src_span) {
   int32_t width;
   int32_t height;
   int32_t num_comps;
   int32_t bits;
   bool color_trans;
   if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo(
-          pData, size, &width, &height, &num_comps, &bits, &color_trans)) {
+          src_span, &width, &height, &num_comps, &bits, &color_trans)) {
     return nullptr;
   }
 
@@ -128,12 +128,11 @@
   if (!pFile->ReadBlock(data.data(), 0, dwEstimateSize))
     return;
 
-  std::unique_ptr<CPDF_Dictionary> pDict =
-      InitJPEG(data.data(), dwEstimateSize);
+  std::unique_ptr<CPDF_Dictionary> pDict = InitJPEG(data);
   if (!pDict && size > dwEstimateSize) {
     data.resize(size);
     pFile->ReadBlock(data.data(), 0, size);
-    pDict = InitJPEG(data.data(), size);
+    pDict = InitJPEG(data);
   }
   if (!pDict)
     return;
@@ -151,7 +150,7 @@
   if (!pFile->ReadBlock(data.data(), 0, size))
     return;
 
-  std::unique_ptr<CPDF_Dictionary> pDict = InitJPEG(data.data(), size);
+  std::unique_ptr<CPDF_Dictionary> pDict = InitJPEG(data);
   if (!pDict)
     return;
 
diff --git a/core/fpdfapi/page/cpdf_image.h b/core/fpdfapi/page/cpdf_image.h
index 1be9b4d..f775221 100644
--- a/core/fpdfapi/page/cpdf_image.h
+++ b/core/fpdfapi/page/cpdf_image.h
@@ -14,6 +14,7 @@
 #include "core/fxcrt/maybe_owned.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "third_party/base/span.h"
 
 class CFX_DIBBase;
 class CFX_DIBitmap;
@@ -73,7 +74,7 @@
   ~CPDF_Image() override;
 
   void FinishInitialization(CPDF_Dictionary* pStreamDict);
-  std::unique_ptr<CPDF_Dictionary> InitJPEG(uint8_t* pData, uint32_t size);
+  std::unique_ptr<CPDF_Dictionary> InitJPEG(pdfium::span<uint8_t> src_span);
 
   int32_t m_Height = 0;
   int32_t m_Width = 0;
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index 4b27cb3..bafb582 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -89,7 +89,7 @@
   if (decoder == "DCTDecode" || decoder == "DCT") {
     std::unique_ptr<CCodec_ScanlineDecoder> pDecoder =
         CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
-            src_buf, limit, width, height, 0,
+            {src_buf, limit}, width, height, 0,
             !pParam || pParam->GetIntegerFor("ColorTransform", 1));
     return DecodeAllScanlines(std::move(pDecoder), dest_buf, dest_size);
   }
diff --git a/core/fpdfapi/render/cpdf_dibbase.cpp b/core/fpdfapi/render/cpdf_dibbase.cpp
index a1fae05..dd710f6 100644
--- a/core/fpdfapi/render/cpdf_dibbase.cpp
+++ b/core/fpdfapi/render/cpdf_dibbase.cpp
@@ -484,7 +484,7 @@
     m_pDecoder = pEncoders->GetBasicModule()->CreateRunLengthDecoder(
         {src_data, src_size}, m_Width, m_Height, m_nComponents, m_bpc);
   } else if (decoder == "DCTDecode") {
-    if (!CreateDCTDecoder(src_data, src_size, pParams))
+    if (!CreateDCTDecoder({src_data, src_size}, pParams))
       return LoadState::kFail;
   }
   if (!m_pDecoder)
@@ -503,12 +503,11 @@
   return LoadState::kSuccess;
 }
 
-bool CPDF_DIBBase::CreateDCTDecoder(const uint8_t* src_data,
-                                    uint32_t src_size,
+bool CPDF_DIBBase::CreateDCTDecoder(pdfium::span<const uint8_t> src_span,
                                     const CPDF_Dictionary* pParams) {
   CCodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule();
   m_pDecoder = pJpegModule->CreateDecoder(
-      src_data, src_size, m_Width, m_Height, m_nComponents,
+      src_span, m_Width, m_Height, m_nComponents,
       !pParams || pParams->GetIntegerFor("ColorTransform", 1));
   if (m_pDecoder)
     return true;
@@ -516,15 +515,15 @@
   bool bTransform = false;
   int comps;
   int bpc;
-  if (!pJpegModule->LoadInfo(src_data, src_size, &m_Width, &m_Height, &comps,
-                             &bpc, &bTransform)) {
+  if (!pJpegModule->LoadInfo(src_span, &m_Width, &m_Height, &comps, &bpc,
+                             &bTransform)) {
     return false;
   }
 
   if (m_nComponents == static_cast<uint32_t>(comps)) {
     m_bpc = bpc;
-    m_pDecoder = pJpegModule->CreateDecoder(
-        src_data, src_size, m_Width, m_Height, m_nComponents, bTransform);
+    m_pDecoder = pJpegModule->CreateDecoder(src_span, m_Width, m_Height,
+                                            m_nComponents, bTransform);
     return true;
   }
 
@@ -569,7 +568,7 @@
     return false;
 
   m_bpc = bpc;
-  m_pDecoder = pJpegModule->CreateDecoder(src_data, src_size, m_Width, m_Height,
+  m_pDecoder = pJpegModule->CreateDecoder(src_span, m_Width, m_Height,
                                           m_nComponents, bTransform);
   return true;
 }
diff --git a/core/fpdfapi/render/cpdf_dibbase.h b/core/fpdfapi/render/cpdf_dibbase.h
index 423069d..be48c31 100644
--- a/core/fpdfapi/render/cpdf_dibbase.h
+++ b/core/fpdfapi/render/cpdf_dibbase.h
@@ -22,6 +22,7 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
 #include "core/fxge/dib/cfx_dibbase.h"
+#include "third_party/base/span.h"
 
 class CCodec_Jbig2Context;
 class CCodec_ScanlineDecoder;
@@ -90,8 +91,7 @@
   RetainPtr<CFX_DIBitmap> LoadJpxBitmap();
   void LoadPalette();
   LoadState CreateDecoder();
-  bool CreateDCTDecoder(const uint8_t* src_data,
-                        uint32_t src_size,
+  bool CreateDCTDecoder(pdfium::span<const uint8_t> src_data,
                         const CPDF_Dictionary* pParams);
   void TranslateScanline24bpp(uint8_t* dest_scan,
                               const uint8_t* src_scan) const;
diff --git a/core/fxcodec/codec/fx_codec_jpeg.cpp b/core/fxcodec/codec/ccodec_jpegmodule.cpp
similarity index 88%
rename from core/fxcodec/codec/fx_codec_jpeg.cpp
rename to core/fxcodec/codec/ccodec_jpegmodule.cpp
index d8e94b0..e6aef3c 100644
--- a/core/fxcodec/codec/fx_codec_jpeg.cpp
+++ b/core/fxcodec/codec/ccodec_jpegmodule.cpp
@@ -4,14 +4,16 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "core/fxcodec/codec/ccodec_jpegmodule.h"
+
 #include <setjmp.h>
 
 #include <memory>
 #include <utility>
 
-#include "core/fxcodec/codec/ccodec_jpegmodule.h"
 #include "core/fxcodec/codec/ccodec_scanlinedecoder.h"
 #include "core/fxcodec/fx_codec.h"
+#include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/fx_dib.h"
@@ -45,23 +47,20 @@
   void (*m_FreeFunc)(void*);
 };
 
-extern "C" {
+static pdfium::span<const uint8_t> JpegScanSOI(
+    pdfium::span<const uint8_t> src_span) {
+  if (src_span.empty())
+    return {};
 
-static void JpegScanSOI(const uint8_t** src_buf, uint32_t* src_size) {
-  if (*src_size == 0)
-    return;
-
-  uint32_t offset = 0;
-  while (offset < *src_size - 1) {
-    if ((*src_buf)[offset] == 0xff && (*src_buf)[offset + 1] == 0xd8) {
-      *src_buf += offset;
-      *src_size -= offset;
-      return;
-    }
-    offset++;
+  for (size_t offset = 0; offset < src_span.size() - 1; ++offset) {
+    if (src_span[offset] == 0xff && src_span[offset + 1] == 0xd8)
+      return src_span.subspan(offset);
   }
+  return src_span;
 }
 
+extern "C" {
+
 static void _src_do_nothing(struct jpeg_decompress_struct* cinfo) {}
 
 static void _error_fatal(j_common_ptr cinfo) {
@@ -111,14 +110,13 @@
 }
 #endif  // PDF_ENABLE_XFA
 
-static bool JpegLoadInfo(const uint8_t* src_buf,
-                         uint32_t src_size,
+static bool JpegLoadInfo(pdfium::span<const uint8_t> src_span,
                          int* width,
                          int* height,
                          int* num_components,
                          int* bits_per_components,
                          bool* color_transform) {
-  JpegScanSOI(&src_buf, &src_size);
+  src_span = JpegScanSOI(src_span);
   struct jpeg_decompress_struct cinfo;
   struct jpeg_error_mgr jerr;
   jerr.error_exit = _error_fatal;
@@ -140,8 +138,8 @@
   src.skip_input_data = _src_skip_data;
   src.fill_input_buffer = _src_fill_buffer;
   src.resync_to_restart = _src_resync;
-  src.bytes_in_buffer = src_size;
-  src.next_input_byte = src_buf;
+  src.bytes_in_buffer = src_span.size();
+  src.next_input_byte = src_span.data();
   cinfo.src = &src;
   if (setjmp(mark) == -1) {
     jpeg_destroy_decompress(&cinfo);
@@ -167,8 +165,7 @@
   CCodec_JpegDecoder();
   ~CCodec_JpegDecoder() override;
 
-  bool Create(const uint8_t* src_buf,
-              uint32_t src_size,
+  bool Create(pdfium::span<const uint8_t> src_buf,
               int width,
               int height,
               int nComps,
@@ -185,30 +182,23 @@
   struct jpeg_decompress_struct cinfo;
   struct jpeg_error_mgr jerr;
   struct jpeg_source_mgr src;
-  const uint8_t* m_SrcBuf;
-  uint32_t m_SrcSize;
-  uint8_t* m_pScanlineBuf;
+  pdfium::span<const uint8_t> m_SrcSpan;
+  std::unique_ptr<uint8_t, FxFreeDeleter> m_pScanlineBuf;
+  bool m_bInited = false;
+  bool m_bStarted = false;
+  bool m_bJpegTransform = false;
 
-  bool m_bInited;
-  bool m_bStarted;
-  bool m_bJpegTransform;
-
- protected:
-  uint32_t m_nDefaultScaleDenom;
+ private:
+  uint32_t m_nDefaultScaleDenom = 1;
 };
 
 CCodec_JpegDecoder::CCodec_JpegDecoder() {
-  m_pScanlineBuf = nullptr;
-  m_bStarted = false;
-  m_bInited = false;
   memset(&cinfo, 0, sizeof(cinfo));
   memset(&jerr, 0, sizeof(jerr));
   memset(&src, 0, sizeof(src));
-  m_nDefaultScaleDenom = 1;
 }
 
 CCodec_JpegDecoder::~CCodec_JpegDecoder() {
-  FX_Free(m_pScanlineBuf);
   if (m_bInited)
     jpeg_destroy_decompress(&cinfo);
 }
@@ -222,8 +212,8 @@
   jpeg_create_decompress(&cinfo);
   m_bInited = true;
   cinfo.src = &src;
-  src.bytes_in_buffer = m_SrcSize;
-  src.next_input_byte = m_SrcBuf;
+  src.bytes_in_buffer = m_SrcSpan.size();
+  src.next_input_byte = m_SrcSpan.data();
   if (setjmp(m_JmpBuf) == -1) {
     jpeg_destroy_decompress(&cinfo);
     m_bInited = false;
@@ -249,15 +239,12 @@
   return true;
 }
 
-bool CCodec_JpegDecoder::Create(const uint8_t* src_buf,
-                                uint32_t src_size,
+bool CCodec_JpegDecoder::Create(pdfium::span<const uint8_t> src_span,
                                 int width,
                                 int height,
                                 int nComps,
                                 bool ColorTransform) {
-  JpegScanSOI(&src_buf, &src_size);
-  m_SrcBuf = src_buf;
-  m_SrcSize = src_size;
+  m_SrcSpan = JpegScanSOI(src_span);
   jerr.error_exit = _error_fatal;
   jerr.emit_message = _error_do_nothing1;
   jerr.output_message = _error_do_nothing;
@@ -269,9 +256,9 @@
   src.fill_input_buffer = _src_fill_buffer;
   src.resync_to_restart = _src_resync;
   m_bJpegTransform = ColorTransform;
-  if (src_size > 1 && memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0) {
-    ((uint8_t*)src_buf)[src_size - 2] = 0xFF;
-    ((uint8_t*)src_buf)[src_size - 1] = 0xD9;
+  if (m_SrcSpan.size() >= 2) {
+    const_cast<uint8_t*>(m_SrcSpan.data())[m_SrcSpan.size() - 2] = 0xFF;
+    const_cast<uint8_t*>(m_SrcSpan.data())[m_SrcSpan.size() - 1] = 0xD9;
   }
   m_OutputWidth = m_OrigWidth = width;
   m_OutputHeight = m_OrigHeight = height;
@@ -287,7 +274,7 @@
   m_Pitch =
       (static_cast<uint32_t>(cinfo.image_width) * cinfo.num_components + 3) /
       4 * 4;
-  m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch);
+  m_pScanlineBuf.reset(FX_Alloc(uint8_t, m_Pitch));
   m_nComps = cinfo.num_components;
   m_bpc = 8;
   m_bStarted = false;
@@ -323,40 +310,38 @@
   if (setjmp(m_JmpBuf) == -1)
     return nullptr;
 
-  int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1);
-  return nlines > 0 ? m_pScanlineBuf : nullptr;
+  uint8_t* row_array[] = {m_pScanlineBuf.get()};
+  int nlines = jpeg_read_scanlines(&cinfo, row_array, 1);
+  return nlines > 0 ? m_pScanlineBuf.get() : nullptr;
 }
 
 uint32_t CCodec_JpegDecoder::GetSrcOffset() {
-  return (uint32_t)(m_SrcSize - src.bytes_in_buffer);
+  return static_cast<uint32_t>(m_SrcSpan.size() - src.bytes_in_buffer);
 }
 
 std::unique_ptr<CCodec_ScanlineDecoder> CCodec_JpegModule::CreateDecoder(
-    const uint8_t* src_buf,
-    uint32_t src_size,
+    pdfium::span<const uint8_t> src_span,
     int width,
     int height,
     int nComps,
     bool ColorTransform) {
-  if (!src_buf || src_size == 0)
+  if (src_span.empty())
     return nullptr;
 
   auto pDecoder = pdfium::MakeUnique<CCodec_JpegDecoder>();
-  if (!pDecoder->Create(src_buf, src_size, width, height, nComps,
-                        ColorTransform)) {
+  if (!pDecoder->Create(src_span, width, height, nComps, ColorTransform))
     return nullptr;
-  }
+
   return std::move(pDecoder);
 }
 
-bool CCodec_JpegModule::LoadInfo(const uint8_t* src_buf,
-                                 uint32_t src_size,
+bool CCodec_JpegModule::LoadInfo(pdfium::span<const uint8_t> src_span,
                                  int* width,
                                  int* height,
                                  int* num_components,
                                  int* bits_per_components,
                                  bool* color_transform) {
-  return JpegLoadInfo(src_buf, src_size, width, height, num_components,
+  return JpegLoadInfo(src_span, width, height, num_components,
                       bits_per_components, color_transform);
 }
 
diff --git a/core/fxcodec/codec/ccodec_jpegmodule.h b/core/fxcodec/codec/ccodec_jpegmodule.h
index d990ee9..fb116f5 100644
--- a/core/fxcodec/codec/ccodec_jpegmodule.h
+++ b/core/fxcodec/codec/ccodec_jpegmodule.h
@@ -12,6 +12,7 @@
 
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/retain_ptr.h"
+#include "third_party/base/span.h"
 
 class CCodec_ScanlineDecoder;
 class CFX_DIBBase;
@@ -28,14 +29,14 @@
     virtual jmp_buf* GetJumpMark() = 0;
   };
 
-  std::unique_ptr<CCodec_ScanlineDecoder> CreateDecoder(const uint8_t* src_buf,
-                                                        uint32_t src_size,
-                                                        int width,
-                                                        int height,
-                                                        int nComps,
-                                                        bool ColorTransform);
-  bool LoadInfo(const uint8_t* src_buf,
-                uint32_t src_size,
+  std::unique_ptr<CCodec_ScanlineDecoder> CreateDecoder(
+      pdfium::span<const uint8_t> src_buf,
+      int width,
+      int height,
+      int nComps,
+      bool ColorTransform);
+
+  bool LoadInfo(pdfium::span<const uint8_t> src_span,
                 int* width,
                 int* height,
                 int* num_components,