Move CCodec_GifModule state to CGifContext

Introduce a base CCodec_GifModule::Context class with a virtual
destructor so holders of unique_ptr's to these can delete them
without actually having any knowledge of the implementation
details of the context.

Bug: 728669
Change-Id: Ia50f94300924a1053c326984eac3b03f25f1b83c
Reviewed-on: https://pdfium-review.googlesource.com/6190
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/codec/ccodec_gifmodule.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp
index 11980ee..7570193 100644
--- a/core/fxcodec/codec/ccodec_gifmodule.cpp
+++ b/core/fxcodec/codec/ccodec_gifmodule.cpp
@@ -13,23 +13,23 @@
 #include "core/fxge/fx_dib.h"
 #include "third_party/base/ptr_util.h"
 
-CCodec_GifModule::CCodec_GifModule() {
-  memset(m_szLastError, 0, sizeof(m_szLastError));
-}
+CCodec_GifModule::CCodec_GifModule() {}
 
 CCodec_GifModule::~CCodec_GifModule() {}
 
-std::unique_ptr<CGifContext> CCodec_GifModule::Start() {
-  return pdfium::MakeUnique<CGifContext>(this, m_szLastError);
+std::unique_ptr<CCodec_GifModule::Context> CCodec_GifModule::Start(
+    Delegate* pDelegate) {
+  return pdfium::MakeUnique<CGifContext>(this, pDelegate);
 }
 
-GifDecodeStatus CCodec_GifModule::ReadHeader(CGifContext* context,
+GifDecodeStatus CCodec_GifModule::ReadHeader(Context* pContext,
                                              int* width,
                                              int* height,
                                              int* pal_num,
                                              void** pal_pp,
                                              int* bg_index,
                                              CFX_DIBAttribute* pAttribute) {
+  auto* context = static_cast<CGifContext*>(pContext);
   GifDecodeStatus ret = gif_read_header(context);
   if (ret != GifDecodeStatus::Success)
     return ret;
@@ -43,8 +43,9 @@
   return GifDecodeStatus::Success;
 }
 
-GifDecodeStatus CCodec_GifModule::LoadFrameInfo(CGifContext* context,
+GifDecodeStatus CCodec_GifModule::LoadFrameInfo(Context* pContext,
                                                 int* frame_num) {
+  auto* context = static_cast<CGifContext*>(pContext);
   GifDecodeStatus ret = gif_get_frame(context);
   if (ret != GifDecodeStatus::Success)
     return ret;
@@ -53,9 +54,10 @@
   return GifDecodeStatus::Success;
 }
 
-GifDecodeStatus CCodec_GifModule::LoadFrame(CGifContext* context,
+GifDecodeStatus CCodec_GifModule::LoadFrame(Context* pContext,
                                             int frame_num,
                                             CFX_DIBAttribute* pAttribute) {
+  auto* context = static_cast<CGifContext*>(pContext);
   GifDecodeStatus ret = gif_load_frame(context, frame_num);
   if (ret != GifDecodeStatus::Success || !pAttribute)
     return ret;
@@ -76,13 +78,15 @@
   return GifDecodeStatus::Success;
 }
 
-uint32_t CCodec_GifModule::GetAvailInput(CGifContext* context,
+uint32_t CCodec_GifModule::GetAvailInput(Context* pContext,
                                          uint8_t** avail_buf_ptr) {
+  auto* context = static_cast<CGifContext*>(pContext);
   return gif_get_avail_input(context, avail_buf_ptr);
 }
 
-void CCodec_GifModule::Input(CGifContext* context,
+void CCodec_GifModule::Input(Context* pContext,
                              const uint8_t* src_buf,
                              uint32_t src_size) {
+  auto* context = static_cast<CGifContext*>(pContext);
   gif_input_buffer(context, (uint8_t*)src_buf, src_size);
 }
diff --git a/core/fxcodec/codec/ccodec_gifmodule.h b/core/fxcodec/codec/ccodec_gifmodule.h
index 2ccd4f4..fe1c464 100644
--- a/core/fxcodec/codec/ccodec_gifmodule.h
+++ b/core/fxcodec/codec/ccodec_gifmodule.h
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "core/fxcodec/lgif/fx_gif.h"
-#include "core/fxcrt/cfx_unowned_ptr.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
 
@@ -18,6 +17,11 @@
 
 class CCodec_GifModule {
  public:
+  class Context {
+   public:
+    virtual ~Context() {}
+  };
+
   class Delegate {
    public:
     virtual void GifRecordCurrentPosition(uint32_t& cur_pos) = 0;
@@ -36,31 +40,20 @@
   CCodec_GifModule();
   ~CCodec_GifModule();
 
-  std::unique_ptr<CGifContext> Start();
-  uint32_t GetAvailInput(CGifContext* context,
-                         uint8_t** avail_buf_ptr = nullptr);
-
-  void Input(CGifContext* context, const uint8_t* src_buf, uint32_t src_size);
-
-  GifDecodeStatus ReadHeader(CGifContext* context,
+  std::unique_ptr<Context> Start(Delegate* pDelegate);
+  uint32_t GetAvailInput(Context* context, uint8_t** avail_buf_ptr = nullptr);
+  void Input(Context* context, const uint8_t* src_buf, uint32_t src_size);
+  GifDecodeStatus ReadHeader(Context* context,
                              int* width,
                              int* height,
                              int* pal_num,
                              void** pal_pp,
                              int* bg_index,
                              CFX_DIBAttribute* pAttribute);
-
-  GifDecodeStatus LoadFrameInfo(CGifContext* context, int* frame_num);
-  GifDecodeStatus LoadFrame(CGifContext* context,
+  GifDecodeStatus LoadFrameInfo(Context* context, int* frame_num);
+  GifDecodeStatus LoadFrame(Context* context,
                             int frame_num,
                             CFX_DIBAttribute* pAttribute);
-
-  Delegate* GetDelegate() const { return m_pDelegate.Get(); }
-  void SetDelegate(Delegate* pDelegate) { m_pDelegate = pDelegate; }
-
- protected:
-  CFX_UnownedPtr<Delegate> m_pDelegate;
-  char m_szLastError[256];
 };
 
 #endif  // CORE_FXCODEC_CODEC_CCODEC_GIFMODULE_H_
diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h
index eab76a7..19101c1 100644
--- a/core/fxcodec/codec/ccodec_progressivedecoder.h
+++ b/core/fxcodec/codec/ccodec_progressivedecoder.h
@@ -16,7 +16,6 @@
 #include "core/fxcodec/codec/ccodec_pngmodule.h"
 #include "core/fxcodec/codec/ccodec_tiffmodule.h"
 #include "core/fxcodec/fx_codec_def.h"
-#include "core/fxcodec/lgif/cgifcontext.h"
 #include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/cfx_unowned_ptr.h"
 #include "core/fxcrt/fx_system.h"
@@ -132,7 +131,7 @@
   // TODO(tsepez): All these contexts probably should be unique_ptrs.
   CFX_UnownedPtr<CCodec_JpegModule::Context> m_pJpegContext;
   CFX_UnownedPtr<CCodec_PngModule::Context> m_pPngContext;
-  std::unique_ptr<CGifContext> m_pGifContext;
+  std::unique_ptr<CCodec_GifModule::Context> m_pGifContext;
   CFX_UnownedPtr<CCodec_BmpModule::Context> m_pBmpContext;
   CFX_UnownedPtr<CCodec_TiffContext> m_pTiffContext;
   FXCODEC_IMAGE_TYPE m_imagType;
diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp
index f652351..a11ba44 100644
--- a/core/fxcodec/codec/fx_codec_progress.cpp
+++ b/core/fxcodec/codec/fx_codec_progress.cpp
@@ -1160,8 +1160,7 @@
         m_status = FXCODEC_STATUS_ERR_MEMORY;
         return false;
       }
-      pGifModule->SetDelegate(this);
-      m_pGifContext = pGifModule->Start();
+      m_pGifContext = pGifModule->Start(this);
       bool bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
       if (!bResult) {
         m_status = FXCODEC_STATUS_ERR_READ;
diff --git a/core/fxcodec/lgif/cgifcontext.cpp b/core/fxcodec/lgif/cgifcontext.cpp
index 9c03cff..e57e978 100644
--- a/core/fxcodec/lgif/cgifcontext.cpp
+++ b/core/fxcodec/lgif/cgifcontext.cpp
@@ -13,15 +13,16 @@
 #include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
 
-CGifContext::CGifContext(CCodec_GifModule* gif_module, char* error_string)
-    : global_pal_num(0),
+CGifContext::CGifContext(CCodec_GifModule* gif_module,
+                         CCodec_GifModule::Delegate* pDelegate)
+    : m_pModule(gif_module),
+      m_pDelegate(pDelegate),
+      global_pal_num(0),
       img_row_offset(0),
       img_row_avail_size(0),
       avail_in(0),
       decode_status(GIF_D_STATUS_SIG),
       skip_size(0),
-      m_Module(gif_module),
-      err_ptr(error_string),
       next_in(nullptr),
       width(0),
       height(0),
@@ -29,20 +30,22 @@
       pixel_aspect(0),
       global_sort_flag(0),
       global_color_resolution(0),
-      img_pass_num(0) {}
+      img_pass_num(0) {
+  memset(m_szLastError, 0, sizeof(m_szLastError));
+}
 
 CGifContext::~CGifContext() {}
 
 void CGifContext::AddError(const char* err_msg) {
-  strncpy(err_ptr, err_msg, GIF_MAX_ERROR_SIZE - 1);
+  strncpy(m_szLastError, err_msg, GIF_MAX_ERROR_SIZE - 1);
 }
 
 void CGifContext::RecordCurrentPosition(uint32_t* cur_pos_ptr) {
-  m_Module->GetDelegate()->GifRecordCurrentPosition(*cur_pos_ptr);
+  m_pDelegate->GifRecordCurrentPosition(*cur_pos_ptr);
 }
 
 void CGifContext::ReadScanline(int32_t row_num, uint8_t* row_buf) {
-  m_Module->GetDelegate()->GifReadScanline(row_num, row_buf);
+  m_pDelegate->GifReadScanline(row_num, row_buf);
 }
 
 bool CGifContext::GetRecordPosition(uint32_t cur_pos,
@@ -57,7 +60,7 @@
                                     int32_t trans_index,
                                     int32_t disposal_method,
                                     bool interlace) {
-  return m_Module->GetDelegate()->GifInputRecordPositionBuf(
+  return m_pDelegate->GifInputRecordPositionBuf(
       cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal_ptr,
       delay_time, user_input, trans_index, disposal_method, interlace);
 }
diff --git a/core/fxcodec/lgif/cgifcontext.h b/core/fxcodec/lgif/cgifcontext.h
index 20d640e..fa46b14 100644
--- a/core/fxcodec/lgif/cgifcontext.h
+++ b/core/fxcodec/lgif/cgifcontext.h
@@ -10,16 +10,16 @@
 #include <memory>
 #include <vector>
 
+#include "core/fxcodec/codec/ccodec_gifmodule.h"
 #include "core/fxcodec/lgif/fx_gif.h"
 #include "core/fxcrt/cfx_unowned_ptr.h"
 #include "core/fxcrt/fx_basic.h"
 
-class CCodec_GifModule;
-
-class CGifContext {
+class CGifContext : public CCodec_GifModule::Context {
  public:
-  CGifContext(CCodec_GifModule* gif_module, char* error_string);
-  ~CGifContext();
+  CGifContext(CCodec_GifModule* gif_module,
+              CCodec_GifModule::Delegate* pDelegate);
+  ~CGifContext() override;
 
   void AddError(const char* err_msg);
   void RecordCurrentPosition(uint32_t* cur_pos_ptr);
@@ -37,6 +37,8 @@
                          int32_t disposal_method,
                          bool interlace);
 
+  CFX_UnownedPtr<CCodec_GifModule> m_pModule;
+  CFX_UnownedPtr<CCodec_GifModule::Delegate> m_pDelegate;
   std::vector<GifPalette> m_GlobalPalette;
   int32_t global_pal_num;
   uint32_t img_row_offset;
@@ -44,23 +46,19 @@
   uint32_t avail_in;
   int32_t decode_status;
   uint32_t skip_size;
-
-  CFX_UnownedPtr<CCodec_GifModule> m_Module;
-  char* err_ptr;
   CFX_ByteString cmt_data;
   std::unique_ptr<GifGCE> m_GifGCE;
   uint8_t* next_in;
   std::vector<std::unique_ptr<GifImage>> m_Images;
   std::unique_ptr<CGifLZWDecoder> m_ImgDecoder;
-
   int width;
   int height;
-
   uint8_t bc_index;
   uint8_t pixel_aspect;
   uint8_t global_sort_flag;
   uint8_t global_color_resolution;
   uint8_t img_pass_num;
+  char m_szLastError[GIF_MAX_ERROR_SIZE];
 };
 
 #endif  // CORE_FXCODEC_LGIF_CGIFCONTEXT_H_
diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp
index b4fe328..cef4f9a 100644
--- a/core/fxcodec/lgif/fx_gif.cpp
+++ b/core/fxcodec/lgif/fx_gif.cpp
@@ -565,7 +565,7 @@
     }
     if (!context->m_ImgDecoder.get())
       context->m_ImgDecoder =
-          pdfium::MakeUnique<CGifLZWDecoder>(context->err_ptr);
+          pdfium::MakeUnique<CGifLZWDecoder>(context->m_szLastError);
     context->m_ImgDecoder->InitTable(gif_image_ptr->image_code_size);
     context->img_row_offset = 0;
     context->img_row_avail_size = 0;