Move C-style functions into CGifContext

There are a number of functions in fx_gix.h/.cpp that take in a
pointer to a CGifContext as their first parameter. Moving these to be
methods in that class.

BUG=pdfium:902

Change-Id: I8c583ab9e42dda4241aa8a6f865408a94fa6d273
Reviewed-on: https://pdfium-review.googlesource.com/14670
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/codec/ccodec_gifmodule.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp
index 911323c..b7e55d5 100644
--- a/core/fxcodec/codec/ccodec_gifmodule.cpp
+++ b/core/fxcodec/codec/ccodec_gifmodule.cpp
@@ -30,7 +30,7 @@
                                              int* bg_index,
                                              CFX_DIBAttribute* pAttribute) {
   auto* context = static_cast<CGifContext*>(pContext);
-  GifDecodeStatus ret = gif_read_header(context);
+  GifDecodeStatus ret = context->ReadHeader();
   if (ret != GifDecodeStatus::Success)
     return ret;
 
@@ -46,11 +46,11 @@
 GifDecodeStatus CCodec_GifModule::LoadFrameInfo(Context* pContext,
                                                 int* frame_num) {
   auto* context = static_cast<CGifContext*>(pContext);
-  GifDecodeStatus ret = gif_get_frame(context);
+  GifDecodeStatus ret = context->GetFrame();
   if (ret != GifDecodeStatus::Success)
     return ret;
 
-  *frame_num = gif_get_frame_num(context);
+  *frame_num = context->GetFrameNum();
   return GifDecodeStatus::Success;
 }
 
@@ -58,7 +58,7 @@
                                             int frame_num,
                                             CFX_DIBAttribute* pAttribute) {
   auto* context = static_cast<CGifContext*>(pContext);
-  GifDecodeStatus ret = gif_load_frame(context, frame_num);
+  GifDecodeStatus ret = context->LoadFrame(frame_num);
   if (ret != GifDecodeStatus::Success || !pAttribute)
     return ret;
 
@@ -81,12 +81,12 @@
 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);
+  return context->GetAvailInput(avail_buf_ptr);
 }
 
 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);
+  context->SetInputBuffer((uint8_t*)src_buf, src_size);
 }
diff --git a/core/fxcodec/lgif/cgifcontext.cpp b/core/fxcodec/lgif/cgifcontext.cpp
index 4dc6636..1eb1b33 100644
--- a/core/fxcodec/lgif/cgifcontext.cpp
+++ b/core/fxcodec/lgif/cgifcontext.cpp
@@ -6,13 +6,21 @@
 
 #include "core/fxcodec/lgif/cgifcontext.h"
 
+#include <algorithm>
 #include <utility>
 
 #include "core/fxcodec/codec/ccodec_gifmodule.h"
+#include "core/fxcodec/lbmp/fx_bmp.h"
 #include "core/fxcodec/lgif/fx_gif.h"
 #include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
 
+namespace {
+
+const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2};
+
+}  // namespace
+
 CGifContext::CGifContext(CCodec_GifModule* gif_module,
                          CCodec_GifModule::Delegate* pDelegate)
     : m_pModule(gif_module),
@@ -64,3 +72,466 @@
       cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal_ptr,
       delay_time, user_input, trans_index, disposal_method, interlace);
 }
+
+GifDecodeStatus CGifContext::ReadHeader() {
+  uint32_t skip_size_org = skip_size;
+  GifHeader* gif_header_ptr = nullptr;
+  if (!ReadData(reinterpret_cast<uint8_t**>(&gif_header_ptr), 6))
+    return GifDecodeStatus::Unfinished;
+
+  if (strncmp(gif_header_ptr->signature, GIF_SIGNATURE, 3) != 0 ||
+      gif_header_ptr->version[0] != '8' || gif_header_ptr->version[2] != 'a') {
+    AddError("Not A Gif Image");
+    return GifDecodeStatus::Error;
+  }
+  GifLSD* gif_lsd_ptr = nullptr;
+  if (!ReadData(reinterpret_cast<uint8_t**>(&gif_lsd_ptr), 7)) {
+    skip_size = skip_size_org;
+    return GifDecodeStatus::Unfinished;
+  }
+  if (reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->global_pal) {
+    global_pal_exp =
+        reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->pal_bits;
+    int32_t global_pal_size = (2 << global_pal_exp) * 3;
+    uint8_t* global_pal_ptr = nullptr;
+    if (!ReadData(&global_pal_ptr, global_pal_size)) {
+      skip_size = skip_size_org;
+      return GifDecodeStatus::Unfinished;
+    }
+    global_sort_flag = ((GifGF*)&gif_lsd_ptr->global_flag)->sort_flag;
+    global_color_resolution =
+        ((GifGF*)&gif_lsd_ptr->global_flag)->color_resolution;
+    m_GlobalPalette.resize(global_pal_size / 3);
+    memcpy(m_GlobalPalette.data(), global_pal_ptr, global_pal_size);
+  }
+  width =
+      (int)GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->width));
+  height =
+      (int)GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->height));
+  bc_index = gif_lsd_ptr->bc_index;
+  pixel_aspect = gif_lsd_ptr->pixel_aspect;
+  return GifDecodeStatus::Success;
+}
+
+GifDecodeStatus CGifContext::GetFrame() {
+  GifDecodeStatus ret = GifDecodeStatus::Success;
+  while (true) {
+    switch (decode_status) {
+      case GIF_D_STATUS_TAIL:
+        return GifDecodeStatus::Success;
+      case GIF_D_STATUS_SIG: {
+        uint8_t* sig_ptr = nullptr;
+        if (!ReadData(&sig_ptr, 1))
+          return GifDecodeStatus::Unfinished;
+
+        switch (*sig_ptr) {
+          case GIF_SIG_EXTENSION:
+            SaveDecodingStatus(GIF_D_STATUS_EXT);
+            continue;
+          case GIF_SIG_IMAGE:
+            SaveDecodingStatus(GIF_D_STATUS_IMG_INFO);
+            continue;
+          case GIF_SIG_TRAILER:
+            SaveDecodingStatus(GIF_D_STATUS_TAIL);
+            return GifDecodeStatus::Success;
+          default:
+            if (avail_in) {
+              // The Gif File has non_standard Tag!
+              SaveDecodingStatus(GIF_D_STATUS_SIG);
+              continue;
+            }
+            // The Gif File Doesn't have Trailer Tag!
+            return GifDecodeStatus::Success;
+        }
+      }
+      case GIF_D_STATUS_EXT: {
+        uint8_t* ext_ptr = nullptr;
+        if (!ReadData(&ext_ptr, 1))
+          return GifDecodeStatus::Unfinished;
+
+        switch (*ext_ptr) {
+          case GIF_BLOCK_CE:
+            SaveDecodingStatus(GIF_D_STATUS_EXT_CE);
+            continue;
+          case GIF_BLOCK_GCE:
+            SaveDecodingStatus(GIF_D_STATUS_EXT_GCE);
+            continue;
+          case GIF_BLOCK_PTE:
+            SaveDecodingStatus(GIF_D_STATUS_EXT_PTE);
+            continue;
+          default: {
+            int32_t status = GIF_D_STATUS_EXT_UNE;
+            if (*ext_ptr == GIF_BLOCK_PTE) {
+              status = GIF_D_STATUS_EXT_PTE;
+            }
+            SaveDecodingStatus(status);
+            continue;
+          }
+        }
+      }
+      case GIF_D_STATUS_IMG_INFO: {
+        ret = DecodeImageInfo();
+        if (ret != GifDecodeStatus::Success)
+          return ret;
+
+        continue;
+      }
+      case GIF_D_STATUS_IMG_DATA: {
+        uint8_t* data_size_ptr = nullptr;
+        uint8_t* data_ptr = nullptr;
+        uint32_t skip_size_org = skip_size;
+        if (!ReadData(&data_size_ptr, 1))
+          return GifDecodeStatus::Unfinished;
+
+        while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
+          if (!ReadData(&data_ptr, *data_size_ptr)) {
+            skip_size = skip_size_org;
+            return GifDecodeStatus::Unfinished;
+          }
+          SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+          skip_size_org = skip_size;
+          if (!ReadData(&data_size_ptr, 1))
+            return GifDecodeStatus::Unfinished;
+        }
+        SaveDecodingStatus(GIF_D_STATUS_SIG);
+        continue;
+      }
+      default: {
+        ret = DecodeExtension();
+        if (ret != GifDecodeStatus::Success)
+          return ret;
+        break;
+      }
+    }
+  }
+  return GifDecodeStatus::Success;
+}
+
+GifDecodeStatus CGifContext::LoadFrame(int32_t frame_num) {
+  if (!pdfium::IndexInBounds(m_Images, frame_num))
+    return GifDecodeStatus::Error;
+
+  uint8_t* data_size_ptr = nullptr;
+  uint8_t* data_ptr = nullptr;
+  uint32_t skip_size_org = skip_size;
+  GifImage* gif_image_ptr = m_Images[frame_num].get();
+  uint32_t gif_img_row_bytes = gif_image_ptr->m_ImageInfo.width;
+  if (gif_img_row_bytes == 0) {
+    AddError("Error Invalid Number of Row Bytes");
+    return GifDecodeStatus::Error;
+  }
+  if (decode_status == GIF_D_STATUS_TAIL) {
+    gif_image_ptr->m_ImageRowBuf.resize(gif_img_row_bytes);
+    GifGCE* gif_img_gce_ptr = gif_image_ptr->m_ImageGCE.get();
+    int32_t loc_pal_num =
+        ((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->local_pal
+            ? (2 << ((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->pal_bits)
+            : 0;
+    avail_in = 0;
+    GifPalette* pLocalPalette = gif_image_ptr->m_LocalPalettes.empty()
+                                    ? nullptr
+                                    : gif_image_ptr->m_LocalPalettes.data();
+    if (!gif_img_gce_ptr) {
+      bool bRes = GetRecordPosition(
+          gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left,
+          gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width,
+          gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette, 0, 0,
+          -1, 0,
+          (bool)((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace);
+      if (!bRes) {
+        gif_image_ptr->m_ImageRowBuf.clear();
+        AddError("Error Read Record Position Data");
+        return GifDecodeStatus::Error;
+      }
+    } else {
+      bool bRes = GetRecordPosition(
+          gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left,
+          gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width,
+          gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette,
+          (int32_t)gif_image_ptr->m_ImageGCE->delay_time,
+          (bool)((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)->user_input,
+          ((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)->transparency
+              ? (int32_t)gif_image_ptr->m_ImageGCE->trans_index
+              : -1,
+          (int32_t)((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)
+              ->disposal_method,
+          (bool)((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace);
+      if (!bRes) {
+        gif_image_ptr->m_ImageRowBuf.clear();
+        AddError("Error Read Record Position Data");
+        return GifDecodeStatus::Error;
+      }
+    }
+    if (gif_image_ptr->image_code_exp > GIF_MAX_LZW_EXP) {
+      gif_image_ptr->m_ImageRowBuf.clear();
+      AddError("Error Invalid Code Size");
+      return GifDecodeStatus::Error;
+    }
+    if (!m_ImgDecoder.get())
+      m_ImgDecoder = pdfium::MakeUnique<CGifLZWDecoder>(m_szLastError);
+    m_ImgDecoder->InitTable(!gif_image_ptr->m_LocalPalettes.empty()
+                                ? gif_image_ptr->local_pallette_exp
+                                : global_pal_exp,
+                            gif_image_ptr->image_code_exp);
+    img_row_offset = 0;
+    img_row_avail_size = 0;
+    img_pass_num = 0;
+    gif_image_ptr->image_row_num = 0;
+    SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+  }
+  CGifLZWDecoder* img_decoder_ptr = m_ImgDecoder.get();
+  if (decode_status == GIF_D_STATUS_IMG_DATA) {
+    if (!ReadData(&data_size_ptr, 1))
+      return GifDecodeStatus::Unfinished;
+
+    if (*data_size_ptr != GIF_BLOCK_TERMINAL) {
+      if (!ReadData(&data_ptr, *data_size_ptr)) {
+        skip_size = skip_size_org;
+        return GifDecodeStatus::Unfinished;
+      }
+      img_decoder_ptr->Input(data_ptr, *data_size_ptr);
+      SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+      img_row_offset += img_row_avail_size;
+      img_row_avail_size = gif_img_row_bytes - img_row_offset;
+      GifDecodeStatus ret = img_decoder_ptr->Decode(
+          gif_image_ptr->m_ImageRowBuf.data() + img_row_offset,
+          &img_row_avail_size);
+      if (ret == GifDecodeStatus::Error) {
+        DecodingFailureAtTailCleanup(gif_image_ptr);
+        return GifDecodeStatus::Error;
+      }
+      while (ret != GifDecodeStatus::Error) {
+        if (ret == GifDecodeStatus::Success) {
+          ReadScanline(gif_image_ptr->image_row_num,
+                       gif_image_ptr->m_ImageRowBuf.data());
+          gif_image_ptr->m_ImageRowBuf.clear();
+          SaveDecodingStatus(GIF_D_STATUS_TAIL);
+          return GifDecodeStatus::Success;
+        }
+        if (ret == GifDecodeStatus::Unfinished) {
+          ASSERT(img_decoder_ptr->GetAvailInput() == 0);
+          skip_size_org = skip_size;
+          if (!ReadData(&data_size_ptr, 1))
+            return GifDecodeStatus::Unfinished;
+
+          if (*data_size_ptr != GIF_BLOCK_TERMINAL) {
+            if (!ReadData(&data_ptr, *data_size_ptr)) {
+              skip_size = skip_size_org;
+              return GifDecodeStatus::Unfinished;
+            }
+            img_decoder_ptr->Input(data_ptr, *data_size_ptr);
+            SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+            img_row_offset += img_row_avail_size;
+            img_row_avail_size = gif_img_row_bytes - img_row_offset;
+            ret = img_decoder_ptr->Decode(
+                gif_image_ptr->m_ImageRowBuf.data() + img_row_offset,
+                &img_row_avail_size);
+          }
+        }
+        if (ret == GifDecodeStatus::InsufficientDestSize) {
+          if (((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace) {
+            ReadScanline(gif_image_ptr->image_row_num,
+                         gif_image_ptr->m_ImageRowBuf.data());
+            gif_image_ptr->image_row_num += s_gif_interlace_step[img_pass_num];
+            if (gif_image_ptr->image_row_num >=
+                (int32_t)gif_image_ptr->m_ImageInfo.height) {
+              img_pass_num++;
+              if (img_pass_num == FX_ArraySize(s_gif_interlace_step)) {
+                DecodingFailureAtTailCleanup(gif_image_ptr);
+                return GifDecodeStatus::Error;
+              }
+              gif_image_ptr->image_row_num =
+                  s_gif_interlace_step[img_pass_num] / 2;
+            }
+          } else {
+            ReadScanline(gif_image_ptr->image_row_num++,
+                         gif_image_ptr->m_ImageRowBuf.data());
+          }
+          img_row_offset = 0;
+          img_row_avail_size = gif_img_row_bytes;
+          ret = img_decoder_ptr->Decode(
+              gif_image_ptr->m_ImageRowBuf.data() + img_row_offset,
+              &img_row_avail_size);
+        }
+        if (ret == GifDecodeStatus::Error) {
+          DecodingFailureAtTailCleanup(gif_image_ptr);
+          return GifDecodeStatus::Error;
+        }
+      }
+    }
+    SaveDecodingStatus(GIF_D_STATUS_TAIL);
+  }
+  AddError("Decode Image Data Error");
+  return GifDecodeStatus::Error;
+}
+
+void CGifContext::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) {
+  next_in = src_buf;
+  avail_in = src_size;
+  skip_size = 0;
+}
+
+uint32_t CGifContext::GetAvailInput(uint8_t** avail_buf_ptr) const {
+  if (avail_buf_ptr) {
+    *avail_buf_ptr = nullptr;
+    if (avail_in > 0)
+      *avail_buf_ptr = next_in;
+  }
+  return avail_in;
+}
+
+int32_t CGifContext::GetFrameNum() const {
+  return pdfium::CollectionSize<int32_t>(m_Images);
+}
+
+uint8_t* CGifContext::ReadData(uint8_t** des_buf_pp, uint32_t data_size) {
+  if (avail_in < skip_size + data_size)
+    return nullptr;
+
+  *des_buf_pp = next_in + skip_size;
+  skip_size += data_size;
+  return *des_buf_pp;
+}
+
+void CGifContext::SaveDecodingStatus(int32_t status) {
+  decode_status = status;
+  next_in += skip_size;
+  avail_in -= skip_size;
+  skip_size = 0;
+}
+
+GifDecodeStatus CGifContext::DecodeExtension() {
+  uint8_t* data_size_ptr = nullptr;
+  uint8_t* data_ptr = nullptr;
+  uint32_t skip_size_org = skip_size;
+  switch (decode_status) {
+    case GIF_D_STATUS_EXT_CE: {
+      if (!ReadData(&data_size_ptr, 1)) {
+        skip_size = skip_size_org;
+        return GifDecodeStatus::Unfinished;
+      }
+      cmt_data.clear();
+      while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
+        uint8_t data_size = *data_size_ptr;
+        if (!ReadData(&data_ptr, *data_size_ptr) ||
+            !ReadData(&data_size_ptr, 1)) {
+          skip_size = skip_size_org;
+          return GifDecodeStatus::Unfinished;
+        }
+        cmt_data += ByteString(data_ptr, data_size);
+      }
+      break;
+    }
+    case GIF_D_STATUS_EXT_PTE: {
+      GifPTE* gif_pte = nullptr;
+      if (!ReadData(reinterpret_cast<uint8_t**>(&gif_pte), 13))
+        return GifDecodeStatus::Unfinished;
+
+      m_GifGCE = nullptr;
+      if (!ReadData(&data_size_ptr, 1)) {
+        skip_size = skip_size_org;
+        return GifDecodeStatus::Unfinished;
+      }
+      while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
+        if (!ReadData(&data_ptr, *data_size_ptr) ||
+            !ReadData(&data_size_ptr, 1)) {
+          skip_size = skip_size_org;
+          return GifDecodeStatus::Unfinished;
+        }
+      }
+      break;
+    }
+    case GIF_D_STATUS_EXT_GCE: {
+      GifGCE* gif_gce_ptr = nullptr;
+      if (!ReadData(reinterpret_cast<uint8_t**>(&gif_gce_ptr), 6))
+        return GifDecodeStatus::Unfinished;
+
+      if (!m_GifGCE.get())
+        m_GifGCE = pdfium::MakeUnique<GifGCE>();
+      m_GifGCE->block_size = gif_gce_ptr->block_size;
+      m_GifGCE->gce_flag = gif_gce_ptr->gce_flag;
+      m_GifGCE->delay_time = GetWord_LSBFirst(
+          reinterpret_cast<uint8_t*>(&gif_gce_ptr->delay_time));
+      m_GifGCE->trans_index = gif_gce_ptr->trans_index;
+      break;
+    }
+    default: {
+      if (decode_status == GIF_D_STATUS_EXT_PTE)
+        m_GifGCE = nullptr;
+      if (!ReadData(&data_size_ptr, 1))
+        return GifDecodeStatus::Unfinished;
+
+      while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
+        if (!ReadData(&data_ptr, *data_size_ptr) ||
+            !ReadData(&data_size_ptr, 1)) {
+          skip_size = skip_size_org;
+          return GifDecodeStatus::Unfinished;
+        }
+      }
+    }
+  }
+  SaveDecodingStatus(GIF_D_STATUS_SIG);
+  return GifDecodeStatus::Success;
+}
+
+GifDecodeStatus CGifContext::DecodeImageInfo() {
+  if (width == 0 || height == 0) {
+    AddError("No Image Header Info");
+    return GifDecodeStatus::Error;
+  }
+  uint32_t skip_size_org = skip_size;
+  GifImageInfo* gif_img_info_ptr = nullptr;
+  if (!ReadData(reinterpret_cast<uint8_t**>(&gif_img_info_ptr), 9))
+    return GifDecodeStatus::Unfinished;
+
+  auto gif_image = pdfium::MakeUnique<GifImage>();
+  gif_image->m_ImageInfo.left =
+      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->left));
+  gif_image->m_ImageInfo.top =
+      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->top));
+  gif_image->m_ImageInfo.width =
+      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->width));
+  gif_image->m_ImageInfo.height =
+      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->height));
+  gif_image->m_ImageInfo.local_flag = gif_img_info_ptr->local_flag;
+  if (gif_image->m_ImageInfo.left + gif_image->m_ImageInfo.width > width ||
+      gif_image->m_ImageInfo.top + gif_image->m_ImageInfo.height > height) {
+    AddError("Image Data Out Of LSD, The File May Be Corrupt");
+    return GifDecodeStatus::Error;
+  }
+  GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag;
+  if (gif_img_info_lf_ptr->local_pal) {
+    gif_image->local_pallette_exp = gif_img_info_lf_ptr->pal_bits;
+    int32_t loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3;
+    uint8_t* loc_pal_ptr = nullptr;
+    if (!ReadData(&loc_pal_ptr, loc_pal_size)) {
+      skip_size = skip_size_org;
+      return GifDecodeStatus::Unfinished;
+    }
+    gif_image->m_LocalPalettes = std::vector<GifPalette>(loc_pal_size / 3);
+    std::copy(loc_pal_ptr, loc_pal_ptr + loc_pal_size,
+              reinterpret_cast<uint8_t*>(gif_image->m_LocalPalettes.data()));
+  }
+  uint8_t* code_size_ptr = nullptr;
+  if (!ReadData(&code_size_ptr, 1)) {
+    skip_size = skip_size_org;
+    return GifDecodeStatus::Unfinished;
+  }
+  gif_image->image_code_exp = *code_size_ptr;
+  RecordCurrentPosition(&gif_image->image_data_pos);
+  gif_image->image_data_pos += skip_size;
+  gif_image->m_ImageGCE = nullptr;
+  if (m_GifGCE.get()) {
+    gif_image->m_ImageGCE = std::move(m_GifGCE);
+    m_GifGCE = nullptr;
+  }
+  m_Images.push_back(std::move(gif_image));
+  SaveDecodingStatus(GIF_D_STATUS_IMG_DATA);
+  return GifDecodeStatus::Success;
+}
+
+void CGifContext::DecodingFailureAtTailCleanup(GifImage* gif_image_ptr) {
+  gif_image_ptr->m_ImageRowBuf.clear();
+  SaveDecodingStatus(GIF_D_STATUS_TAIL);
+  AddError("Decode Image Data Error");
+}
diff --git a/core/fxcodec/lgif/cgifcontext.h b/core/fxcodec/lgif/cgifcontext.h
index 71cf2bc..fdff235 100644
--- a/core/fxcodec/lgif/cgifcontext.h
+++ b/core/fxcodec/lgif/cgifcontext.h
@@ -36,6 +36,12 @@
                          int32_t trans_index,
                          int32_t disposal_method,
                          bool interlace);
+  GifDecodeStatus ReadHeader();
+  GifDecodeStatus GetFrame();
+  GifDecodeStatus LoadFrame(int32_t frame_num);
+  void SetInputBuffer(uint8_t* src_buf, uint32_t src_size);
+  uint32_t GetAvailInput(uint8_t** avail_buf_ptr) const;
+  int32_t GetFrameNum() const;
 
   UnownedPtr<CCodec_GifModule> m_pModule;
   UnownedPtr<CCodec_GifModule::Delegate> m_pDelegate;
@@ -59,6 +65,13 @@
   uint8_t global_color_resolution;
   uint8_t img_pass_num;
   char m_szLastError[GIF_MAX_ERROR_SIZE];
+
+ private:
+  uint8_t* ReadData(uint8_t** des_buf_pp, uint32_t data_size);
+  void SaveDecodingStatus(int32_t status);
+  GifDecodeStatus DecodeExtension();
+  GifDecodeStatus DecodeImageInfo();
+  void DecodingFailureAtTailCleanup(GifImage* gif_image_ptr);
 };
 
 #endif  // CORE_FXCODEC_LGIF_CGIFCONTEXT_H_
diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp
index ea78259..6e1c26e 100644
--- a/core/fxcodec/lgif/fx_gif.cpp
+++ b/core/fxcodec/lgif/fx_gif.cpp
@@ -23,168 +23,6 @@
 static_assert(sizeof(GifHeader) == 6, "GifHeader should have a size of 6");
 static_assert(sizeof(GifLSD) == 7, "GifLSD should have a size of 7");
 
-namespace {
-
-uint8_t* gif_read_data(CGifContext* context,
-                       uint8_t** des_buf_pp,
-                       uint32_t data_size) {
-  if (!context || context->avail_in < context->skip_size + data_size)
-    return nullptr;
-
-  *des_buf_pp = context->next_in + context->skip_size;
-  context->skip_size += data_size;
-  return *des_buf_pp;
-}
-
-void gif_save_decoding_status(CGifContext* context, int32_t status) {
-  context->decode_status = status;
-  context->next_in += context->skip_size;
-  context->avail_in -= context->skip_size;
-  context->skip_size = 0;
-}
-
-GifDecodeStatus gif_decode_extension(CGifContext* context) {
-  uint8_t* data_size_ptr = nullptr;
-  uint8_t* data_ptr = nullptr;
-  uint32_t skip_size_org = context->skip_size;
-  switch (context->decode_status) {
-    case GIF_D_STATUS_EXT_CE: {
-      if (!gif_read_data(context, &data_size_ptr, 1)) {
-        context->skip_size = skip_size_org;
-        return GifDecodeStatus::Unfinished;
-      }
-      context->cmt_data.clear();
-      while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
-        uint8_t data_size = *data_size_ptr;
-        if (!gif_read_data(context, &data_ptr, *data_size_ptr) ||
-            !gif_read_data(context, &data_size_ptr, 1)) {
-          context->skip_size = skip_size_org;
-          return GifDecodeStatus::Unfinished;
-        }
-        context->cmt_data += ByteString(data_ptr, data_size);
-      }
-      break;
-    }
-    case GIF_D_STATUS_EXT_PTE: {
-      GifPTE* gif_pte = nullptr;
-      if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_pte), 13))
-        return GifDecodeStatus::Unfinished;
-
-      context->m_GifGCE = nullptr;
-      if (!gif_read_data(context, &data_size_ptr, 1)) {
-        context->skip_size = skip_size_org;
-        return GifDecodeStatus::Unfinished;
-      }
-      while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
-        if (!gif_read_data(context, &data_ptr, *data_size_ptr) ||
-            !gif_read_data(context, &data_size_ptr, 1)) {
-          context->skip_size = skip_size_org;
-          return GifDecodeStatus::Unfinished;
-        }
-      }
-      break;
-    }
-    case GIF_D_STATUS_EXT_GCE: {
-      GifGCE* gif_gce_ptr = nullptr;
-      if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_gce_ptr), 6))
-        return GifDecodeStatus::Unfinished;
-
-      if (!context->m_GifGCE.get())
-        context->m_GifGCE = pdfium::MakeUnique<GifGCE>();
-      context->m_GifGCE->block_size = gif_gce_ptr->block_size;
-      context->m_GifGCE->gce_flag = gif_gce_ptr->gce_flag;
-      context->m_GifGCE->delay_time = GetWord_LSBFirst(
-          reinterpret_cast<uint8_t*>(&gif_gce_ptr->delay_time));
-      context->m_GifGCE->trans_index = gif_gce_ptr->trans_index;
-      break;
-    }
-    default: {
-      if (context->decode_status == GIF_D_STATUS_EXT_PTE)
-        context->m_GifGCE = nullptr;
-      if (!gif_read_data(context, &data_size_ptr, 1))
-        return GifDecodeStatus::Unfinished;
-
-      while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
-        if (!gif_read_data(context, &data_ptr, *data_size_ptr) ||
-            !gif_read_data(context, &data_size_ptr, 1)) {
-          context->skip_size = skip_size_org;
-          return GifDecodeStatus::Unfinished;
-        }
-      }
-    }
-  }
-  gif_save_decoding_status(context, GIF_D_STATUS_SIG);
-  return GifDecodeStatus::Success;
-}
-
-GifDecodeStatus gif_decode_image_info(CGifContext* context) {
-  if (context->width == 0 || context->height == 0) {
-    context->AddError("No Image Header Info");
-    return GifDecodeStatus::Error;
-  }
-  uint32_t skip_size_org = context->skip_size;
-  GifImageInfo* gif_img_info_ptr = nullptr;
-  if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_img_info_ptr),
-                     9))
-    return GifDecodeStatus::Unfinished;
-
-  auto gif_image = pdfium::MakeUnique<GifImage>();
-  gif_image->m_ImageInfo.left =
-      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->left));
-  gif_image->m_ImageInfo.top =
-      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->top));
-  gif_image->m_ImageInfo.width =
-      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->width));
-  gif_image->m_ImageInfo.height =
-      GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->height));
-  gif_image->m_ImageInfo.local_flag = gif_img_info_ptr->local_flag;
-  if (gif_image->m_ImageInfo.left + gif_image->m_ImageInfo.width >
-          context->width ||
-      gif_image->m_ImageInfo.top + gif_image->m_ImageInfo.height >
-          context->height) {
-    context->AddError("Image Data Out Of LSD, The File May Be Corrupt");
-    return GifDecodeStatus::Error;
-  }
-  GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag;
-  if (gif_img_info_lf_ptr->local_pal) {
-    gif_image->local_pallette_exp = gif_img_info_lf_ptr->pal_bits;
-    int32_t loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3;
-    uint8_t* loc_pal_ptr = nullptr;
-    if (!gif_read_data(context, &loc_pal_ptr, loc_pal_size)) {
-      context->skip_size = skip_size_org;
-      return GifDecodeStatus::Unfinished;
-    }
-    gif_image->m_LocalPalettes = std::vector<GifPalette>(loc_pal_size / 3);
-    std::copy(loc_pal_ptr, loc_pal_ptr + loc_pal_size,
-              reinterpret_cast<uint8_t*>(gif_image->m_LocalPalettes.data()));
-  }
-  uint8_t* code_size_ptr = nullptr;
-  if (!gif_read_data(context, &code_size_ptr, 1)) {
-    context->skip_size = skip_size_org;
-    return GifDecodeStatus::Unfinished;
-  }
-  gif_image->image_code_exp = *code_size_ptr;
-  context->RecordCurrentPosition(&gif_image->image_data_pos);
-  gif_image->image_data_pos += context->skip_size;
-  gif_image->m_ImageGCE = nullptr;
-  if (context->m_GifGCE.get()) {
-    gif_image->m_ImageGCE = std::move(context->m_GifGCE);
-    context->m_GifGCE = nullptr;
-  }
-  context->m_Images.push_back(std::move(gif_image));
-  gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA);
-  return GifDecodeStatus::Success;
-}
-
-void gif_decoding_failure_at_tail_cleanup(CGifContext* context,
-                                          GifImage* gif_image_ptr) {
-  gif_image_ptr->m_ImageRowBuf.clear();
-  gif_save_decoding_status(context, GIF_D_STATUS_TAIL);
-  context->AddError("Decode Image Data Error");
-}
-
-}  // namespace
-
 GifImage::GifImage() {}
 
 GifImage::~GifImage() {}
@@ -369,325 +207,3 @@
   }
   return GifDecodeStatus::Error;
 }
-
-GifDecodeStatus gif_read_header(CGifContext* context) {
-  if (!context)
-    return GifDecodeStatus::Error;
-
-  uint32_t skip_size_org = context->skip_size;
-  GifHeader* gif_header_ptr = nullptr;
-  if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_header_ptr), 6))
-    return GifDecodeStatus::Unfinished;
-
-  if (strncmp(gif_header_ptr->signature, GIF_SIGNATURE, 3) != 0 ||
-      gif_header_ptr->version[0] != '8' || gif_header_ptr->version[2] != 'a') {
-    context->AddError("Not A Gif Image");
-    return GifDecodeStatus::Error;
-  }
-  GifLSD* gif_lsd_ptr = nullptr;
-  if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_lsd_ptr), 7)) {
-    context->skip_size = skip_size_org;
-    return GifDecodeStatus::Unfinished;
-  }
-  if (reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->global_pal) {
-    context->global_pal_exp =
-        reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->pal_bits;
-    int32_t global_pal_size = (2 << context->global_pal_exp) * 3;
-    uint8_t* global_pal_ptr = nullptr;
-    if (!gif_read_data(context, &global_pal_ptr, global_pal_size)) {
-      context->skip_size = skip_size_org;
-      return GifDecodeStatus::Unfinished;
-    }
-    context->global_sort_flag = ((GifGF*)&gif_lsd_ptr->global_flag)->sort_flag;
-    context->global_color_resolution =
-        ((GifGF*)&gif_lsd_ptr->global_flag)->color_resolution;
-    context->m_GlobalPalette.resize(global_pal_size / 3);
-    memcpy(context->m_GlobalPalette.data(), global_pal_ptr, global_pal_size);
-  }
-  context->width =
-      (int)GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->width));
-  context->height =
-      (int)GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->height));
-  context->bc_index = gif_lsd_ptr->bc_index;
-  context->pixel_aspect = gif_lsd_ptr->pixel_aspect;
-  return GifDecodeStatus::Success;
-}
-
-GifDecodeStatus gif_get_frame(CGifContext* context) {
-  if (!context)
-    return GifDecodeStatus::Error;
-
-  GifDecodeStatus ret = GifDecodeStatus::Success;
-  while (true) {
-    switch (context->decode_status) {
-      case GIF_D_STATUS_TAIL:
-        return GifDecodeStatus::Success;
-      case GIF_D_STATUS_SIG: {
-        uint8_t* sig_ptr = nullptr;
-        if (!gif_read_data(context, &sig_ptr, 1))
-          return GifDecodeStatus::Unfinished;
-
-        switch (*sig_ptr) {
-          case GIF_SIG_EXTENSION:
-            gif_save_decoding_status(context, GIF_D_STATUS_EXT);
-            continue;
-          case GIF_SIG_IMAGE:
-            gif_save_decoding_status(context, GIF_D_STATUS_IMG_INFO);
-            continue;
-          case GIF_SIG_TRAILER:
-            gif_save_decoding_status(context, GIF_D_STATUS_TAIL);
-            return GifDecodeStatus::Success;
-          default:
-            if (context->avail_in) {
-              // The Gif File has non_standard Tag!
-              gif_save_decoding_status(context, GIF_D_STATUS_SIG);
-              continue;
-            }
-            // The Gif File Doesn't have Trailer Tag!
-            return GifDecodeStatus::Success;
-        }
-      }
-      case GIF_D_STATUS_EXT: {
-        uint8_t* ext_ptr = nullptr;
-        if (!gif_read_data(context, &ext_ptr, 1))
-          return GifDecodeStatus::Unfinished;
-
-        switch (*ext_ptr) {
-          case GIF_BLOCK_CE:
-            gif_save_decoding_status(context, GIF_D_STATUS_EXT_CE);
-            continue;
-          case GIF_BLOCK_GCE:
-            gif_save_decoding_status(context, GIF_D_STATUS_EXT_GCE);
-            continue;
-          case GIF_BLOCK_PTE:
-            gif_save_decoding_status(context, GIF_D_STATUS_EXT_PTE);
-            continue;
-          default: {
-            int32_t status = GIF_D_STATUS_EXT_UNE;
-            if (*ext_ptr == GIF_BLOCK_PTE) {
-              status = GIF_D_STATUS_EXT_PTE;
-            }
-            gif_save_decoding_status(context, status);
-            continue;
-          }
-        }
-      }
-      case GIF_D_STATUS_IMG_INFO: {
-        ret = gif_decode_image_info(context);
-        if (ret != GifDecodeStatus::Success)
-          return ret;
-
-        continue;
-      }
-      case GIF_D_STATUS_IMG_DATA: {
-        uint8_t* data_size_ptr = nullptr;
-        uint8_t* data_ptr = nullptr;
-        uint32_t skip_size_org = context->skip_size;
-        if (!gif_read_data(context, &data_size_ptr, 1))
-          return GifDecodeStatus::Unfinished;
-
-        while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
-          if (!gif_read_data(context, &data_ptr, *data_size_ptr)) {
-            context->skip_size = skip_size_org;
-            return GifDecodeStatus::Unfinished;
-          }
-          gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA);
-          skip_size_org = context->skip_size;
-          if (!gif_read_data(context, &data_size_ptr, 1))
-            return GifDecodeStatus::Unfinished;
-        }
-        gif_save_decoding_status(context, GIF_D_STATUS_SIG);
-        continue;
-      }
-      default: {
-        ret = gif_decode_extension(context);
-        if (ret != GifDecodeStatus::Success)
-          return ret;
-        break;
-      }
-    }
-  }
-  return GifDecodeStatus::Success;
-}
-
-GifDecodeStatus gif_load_frame(CGifContext* context, int32_t frame_num) {
-  if (!context || !pdfium::IndexInBounds(context->m_Images, frame_num))
-    return GifDecodeStatus::Error;
-
-  uint8_t* data_size_ptr = nullptr;
-  uint8_t* data_ptr = nullptr;
-  uint32_t skip_size_org = context->skip_size;
-  GifImage* gif_image_ptr = context->m_Images[frame_num].get();
-  uint32_t gif_img_row_bytes = gif_image_ptr->m_ImageInfo.width;
-  if (gif_img_row_bytes == 0) {
-    context->AddError("Error Invalid Number of Row Bytes");
-    return GifDecodeStatus::Error;
-  }
-  if (context->decode_status == GIF_D_STATUS_TAIL) {
-    gif_image_ptr->m_ImageRowBuf.resize(gif_img_row_bytes);
-    GifGCE* gif_img_gce_ptr = gif_image_ptr->m_ImageGCE.get();
-    int32_t loc_pal_num =
-        ((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->local_pal
-            ? (2 << ((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->pal_bits)
-            : 0;
-    context->avail_in = 0;
-    GifPalette* pLocalPalette = gif_image_ptr->m_LocalPalettes.empty()
-                                    ? nullptr
-                                    : gif_image_ptr->m_LocalPalettes.data();
-    if (!gif_img_gce_ptr) {
-      bool bRes = context->GetRecordPosition(
-          gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left,
-          gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width,
-          gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette, 0, 0,
-          -1, 0,
-          (bool)((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace);
-      if (!bRes) {
-        gif_image_ptr->m_ImageRowBuf.clear();
-        context->AddError("Error Read Record Position Data");
-        return GifDecodeStatus::Error;
-      }
-    } else {
-      bool bRes = context->GetRecordPosition(
-          gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left,
-          gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width,
-          gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette,
-          (int32_t)gif_image_ptr->m_ImageGCE->delay_time,
-          (bool)((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)->user_input,
-          ((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)->transparency
-              ? (int32_t)gif_image_ptr->m_ImageGCE->trans_index
-              : -1,
-          (int32_t)((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)
-              ->disposal_method,
-          (bool)((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace);
-      if (!bRes) {
-        gif_image_ptr->m_ImageRowBuf.clear();
-        context->AddError("Error Read Record Position Data");
-        return GifDecodeStatus::Error;
-      }
-    }
-    if (gif_image_ptr->image_code_exp > GIF_MAX_LZW_EXP) {
-      gif_image_ptr->m_ImageRowBuf.clear();
-      context->AddError("Error Invalid Code Size");
-      return GifDecodeStatus::Error;
-    }
-    if (!context->m_ImgDecoder.get())
-      context->m_ImgDecoder =
-          pdfium::MakeUnique<CGifLZWDecoder>(context->m_szLastError);
-    context->m_ImgDecoder->InitTable(!gif_image_ptr->m_LocalPalettes.empty()
-                                         ? gif_image_ptr->local_pallette_exp
-                                         : context->global_pal_exp,
-                                     gif_image_ptr->image_code_exp);
-    context->img_row_offset = 0;
-    context->img_row_avail_size = 0;
-    context->img_pass_num = 0;
-    gif_image_ptr->image_row_num = 0;
-    gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA);
-  }
-  CGifLZWDecoder* img_decoder_ptr = context->m_ImgDecoder.get();
-  if (context->decode_status == GIF_D_STATUS_IMG_DATA) {
-    if (!gif_read_data(context, &data_size_ptr, 1))
-      return GifDecodeStatus::Unfinished;
-
-    if (*data_size_ptr != GIF_BLOCK_TERMINAL) {
-      if (!gif_read_data(context, &data_ptr, *data_size_ptr)) {
-        context->skip_size = skip_size_org;
-        return GifDecodeStatus::Unfinished;
-      }
-      img_decoder_ptr->Input(data_ptr, *data_size_ptr);
-      gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA);
-      context->img_row_offset += context->img_row_avail_size;
-      context->img_row_avail_size = gif_img_row_bytes - context->img_row_offset;
-      GifDecodeStatus ret = img_decoder_ptr->Decode(
-          gif_image_ptr->m_ImageRowBuf.data() + context->img_row_offset,
-          &context->img_row_avail_size);
-      if (ret == GifDecodeStatus::Error) {
-        gif_decoding_failure_at_tail_cleanup(context, gif_image_ptr);
-        return GifDecodeStatus::Error;
-      }
-      while (ret != GifDecodeStatus::Error) {
-        if (ret == GifDecodeStatus::Success) {
-          context->ReadScanline(gif_image_ptr->image_row_num,
-                                gif_image_ptr->m_ImageRowBuf.data());
-          gif_image_ptr->m_ImageRowBuf.clear();
-          gif_save_decoding_status(context, GIF_D_STATUS_TAIL);
-          return GifDecodeStatus::Success;
-        }
-        if (ret == GifDecodeStatus::Unfinished) {
-          ASSERT(img_decoder_ptr->GetAvailInput() == 0);
-          skip_size_org = context->skip_size;
-          if (!gif_read_data(context, &data_size_ptr, 1))
-            return GifDecodeStatus::Unfinished;
-
-          if (*data_size_ptr != GIF_BLOCK_TERMINAL) {
-            if (!gif_read_data(context, &data_ptr, *data_size_ptr)) {
-              context->skip_size = skip_size_org;
-              return GifDecodeStatus::Unfinished;
-            }
-            img_decoder_ptr->Input(data_ptr, *data_size_ptr);
-            gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA);
-            context->img_row_offset += context->img_row_avail_size;
-            context->img_row_avail_size =
-                gif_img_row_bytes - context->img_row_offset;
-            ret = img_decoder_ptr->Decode(
-                gif_image_ptr->m_ImageRowBuf.data() + context->img_row_offset,
-                &context->img_row_avail_size);
-          }
-        }
-        if (ret == GifDecodeStatus::InsufficientDestSize) {
-          if (((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace) {
-            context->ReadScanline(gif_image_ptr->image_row_num,
-                                  gif_image_ptr->m_ImageRowBuf.data());
-            gif_image_ptr->image_row_num +=
-                s_gif_interlace_step[context->img_pass_num];
-            if (gif_image_ptr->image_row_num >=
-                (int32_t)gif_image_ptr->m_ImageInfo.height) {
-              context->img_pass_num++;
-              if (context->img_pass_num == FX_ArraySize(s_gif_interlace_step)) {
-                gif_decoding_failure_at_tail_cleanup(context, gif_image_ptr);
-                return GifDecodeStatus::Error;
-              }
-              gif_image_ptr->image_row_num =
-                  s_gif_interlace_step[context->img_pass_num] / 2;
-            }
-          } else {
-            context->ReadScanline(gif_image_ptr->image_row_num++,
-                                  gif_image_ptr->m_ImageRowBuf.data());
-          }
-          context->img_row_offset = 0;
-          context->img_row_avail_size = gif_img_row_bytes;
-          ret = img_decoder_ptr->Decode(
-              gif_image_ptr->m_ImageRowBuf.data() + context->img_row_offset,
-              &context->img_row_avail_size);
-        }
-        if (ret == GifDecodeStatus::Error) {
-          gif_decoding_failure_at_tail_cleanup(context, gif_image_ptr);
-          return GifDecodeStatus::Error;
-        }
-      }
-    }
-    gif_save_decoding_status(context, GIF_D_STATUS_TAIL);
-  }
-  context->AddError("Decode Image Data Error");
-  return GifDecodeStatus::Error;
-}
-
-void gif_input_buffer(CGifContext* context,
-                      uint8_t* src_buf,
-                      uint32_t src_size) {
-  context->next_in = src_buf;
-  context->avail_in = src_size;
-  context->skip_size = 0;
-}
-
-uint32_t gif_get_avail_input(CGifContext* context, uint8_t** avail_buf_ptr) {
-  if (avail_buf_ptr) {
-    *avail_buf_ptr = nullptr;
-    if (context->avail_in > 0)
-      *avail_buf_ptr = context->next_in;
-  }
-  return context->avail_in;
-}
-
-int32_t gif_get_frame_num(CGifContext* context) {
-  return pdfium::CollectionSize<int32_t>(context->m_Images);
-}
diff --git a/core/fxcodec/lgif/fx_gif.h b/core/fxcodec/lgif/fx_gif.h
index bddb22b..c3ddf36 100644
--- a/core/fxcodec/lgif/fx_gif.h
+++ b/core/fxcodec/lgif/fx_gif.h
@@ -164,15 +164,4 @@
   char* err_msg_ptr;
 };
 
-static const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2};
-
-GifDecodeStatus gif_read_header(CGifContext* gif_ptr);
-GifDecodeStatus gif_get_frame(CGifContext* gif_ptr);
-int32_t gif_get_frame_num(CGifContext* gif_ptr);
-GifDecodeStatus gif_load_frame(CGifContext* gif_ptr, int32_t frame_num);
-void gif_input_buffer(CGifContext* gif_ptr,
-                      uint8_t* src_buf,
-                      uint32_t src_size);
-uint32_t gif_get_avail_input(CGifContext* gif_ptr, uint8_t** avail_buf_ptr);
-
 #endif  // CORE_FXCODEC_LGIF_FX_GIF_H_