Clean up fx_codec_tiff.cpp.

Fix regressions from commit 4997b22.

BUG=618164

Review-Url: https://codereview.chromium.org/2053573003
diff --git a/core/fxcodec/codec/ccodec_tiffmodule.h b/core/fxcodec/codec/ccodec_tiffmodule.h
index d746bb7..7b89584 100644
--- a/core/fxcodec/codec/ccodec_tiffmodule.h
+++ b/core/fxcodec/codec/ccodec_tiffmodule.h
@@ -20,15 +20,14 @@
 
   CCodec_TiffContext* CreateDecoder(IFX_FileRead* file_ptr);
 
-  void GetFrames(CCodec_TiffContext* ctx, int32_t& frames);
-  FX_BOOL LoadFrameInfo(CCodec_TiffContext* ctx,
-                        int32_t frame,
-                        uint32_t& width,
-                        uint32_t& height,
-                        uint32_t& comps,
-                        uint32_t& bpc,
-                        CFX_DIBAttribute* pAttribute);
-  FX_BOOL Decode(CCodec_TiffContext* ctx, class CFX_DIBitmap* pDIBitmap);
+  bool LoadFrameInfo(CCodec_TiffContext* ctx,
+                     int32_t frame,
+                     int32_t* width,
+                     int32_t* height,
+                     int32_t* comps,
+                     int32_t* bpc,
+                     CFX_DIBAttribute* pAttribute);
+  bool Decode(CCodec_TiffContext* ctx, class CFX_DIBitmap* pDIBitmap);
   void DestroyDecoder(CCodec_TiffContext* ctx);
 };
 
diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp
index ec3347c..bdb158f 100644
--- a/core/fxcodec/codec/fx_codec_progress.cpp
+++ b/core/fxcodec/codec/fx_codec_progress.cpp
@@ -6,17 +6,37 @@
 
 #include "core/fxcodec/codec/include/ccodec_progressivedecoder.h"
 
+#include <algorithm>
+
 #include "core/fxcodec/include/fx_codec.h"
 #include "core/fxge/include/fx_dib.h"
+#include "third_party/base/numerics/safe_math.h"
 
 #define FXCODEC_BLOCK_SIZE 4096
-#define FXCODEC_PNG_GAMMA 2.2
+
+namespace {
 
 #if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
-#undef FXCODEC_PNG_GAMMA
-#define FXCODEC_PNG_GAMMA 1.7
+const double kPngGamma = 1.7;
+#else
+const double kPngGamma = 2.2;
 #endif
 
+void RGB2BGR(uint8_t* buffer, int width = 1) {
+  if (buffer && width > 0) {
+    uint8_t temp;
+    int i = 0;
+    int j = 0;
+    for (; i < width; i++, j += 3) {
+      temp = buffer[j];
+      buffer[j] = buffer[j + 2];
+      buffer[j + 2] = temp;
+    }
+  }
+}
+
+}  // namespace
+
 void CCodec_ProgressiveDecoder::CFXCODEC_WeightTable::Calc(int dest_len,
                                                            int dest_min,
                                                            int dest_max,
@@ -24,9 +44,6 @@
                                                            int src_min,
                                                            int src_max,
                                                            FX_BOOL bInterpol) {
-  if (m_pWeightTables) {
-    FX_Free(m_pWeightTables);
-  }
   double scale, base;
   scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len;
   if (dest_len < 0) {
@@ -38,7 +55,7 @@
       (int)(sizeof(int) * 2 +
             sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1));
   m_DestMin = dest_min;
-  m_pWeightTables = FX_Alloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4);
+  m_pWeightTables.resize((dest_max - dest_min) * m_ItemSize + 4);
   if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {
     for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) {
       PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
@@ -118,32 +135,27 @@
     }
   }
 }
+
 void CCodec_ProgressiveDecoder::CFXCODEC_HorzTable::Calc(int dest_len,
                                                          int src_len,
                                                          FX_BOOL bInterpol) {
-  if (m_pWeightTables) {
-    FX_Free(m_pWeightTables);
-  }
   double scale = (double)dest_len / (double)src_len;
   m_ItemSize = sizeof(int) * 4;
   int size = dest_len * m_ItemSize + 4;
-  m_pWeightTables = FX_Alloc(uint8_t, size);
-  FXSYS_memset(m_pWeightTables, 0, size);
+  m_pWeightTables.resize(size, 0);
   if (scale > 1) {
     int pre_des_col = 0;
     for (int src_col = 0; src_col < src_len; src_col++) {
       double des_col_f = src_col * scale;
       int des_col = FXSYS_round((FX_FLOAT)des_col_f);
-      PixelWeight* pWeight =
-          (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize);
+      PixelWeight* pWeight = GetPixelWeight(des_col);
       pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
       pWeight->m_Weights[0] = 65536;
       pWeight->m_Weights[1] = 0;
       if (src_col == src_len - 1 && des_col < dest_len - 1) {
         for (int des_col_index = pre_des_col + 1; des_col_index < dest_len;
              des_col_index++) {
-          pWeight =
-              (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize);
+          pWeight = GetPixelWeight(des_col_index);
           pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
           pWeight->m_Weights[0] = 65536;
           pWeight->m_Weights[1] = 0;
@@ -153,7 +165,7 @@
       int des_col_len = des_col - pre_des_col;
       for (int des_col_index = pre_des_col + 1; des_col_index < des_col;
            des_col_index++) {
-        pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize);
+        pWeight = GetPixelWeight(des_col_index);
         pWeight->m_SrcStart = src_col - 1;
         pWeight->m_SrcEnd = src_col;
         pWeight->m_Weights[0] =
@@ -170,72 +182,66 @@
   for (int des_col = 0; des_col < dest_len; des_col++) {
     double src_col_f = des_col / scale;
     int src_col = FXSYS_round((FX_FLOAT)src_col_f);
-    PixelWeight* pWeight =
-        (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize);
+    PixelWeight* pWeight = GetPixelWeight(des_col);
     pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
     pWeight->m_Weights[0] = 65536;
     pWeight->m_Weights[1] = 0;
   }
 }
+
 void CCodec_ProgressiveDecoder::CFXCODEC_VertTable::Calc(int dest_len,
                                                          int src_len) {
-  if (m_pWeightTables) {
-    FX_Free(m_pWeightTables);
-  }
   double scale = (double)dest_len / (double)src_len;
   m_ItemSize = sizeof(int) * 4;
   int size = dest_len * m_ItemSize + 4;
-  m_pWeightTables = FX_Alloc(uint8_t, size);
-  FXSYS_memset(m_pWeightTables, 0, size);
-  if (scale > 1) {
-    double step = 0.0;
-    int src_row = 0;
-    while (step < (double)dest_len) {
-      int start_step = (int)step;
-      step = scale * (++src_row);
-      int end_step = (int)step;
-      if (end_step >= dest_len) {
-        end_step = dest_len;
-        for (int des_row = start_step; des_row < end_step; des_row++) {
-          PixelWeight* pWeight =
-              (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);
-          pWeight->m_SrcStart = start_step;
-          pWeight->m_SrcEnd = start_step;
-          pWeight->m_Weights[0] = 65536;
-          pWeight->m_Weights[1] = 0;
-        }
-        return;
-      }
-      int length = end_step - start_step;
-      {
-        PixelWeight* pWeight =
-            (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize);
-        pWeight->m_SrcStart = start_step;
-        pWeight->m_SrcEnd = start_step;
-        pWeight->m_Weights[0] = 65536;
-        pWeight->m_Weights[1] = 0;
-      }
-      for (int des_row = start_step + 1; des_row < end_step; des_row++) {
-        PixelWeight* pWeight =
-            (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);
-        pWeight->m_SrcStart = start_step;
-        pWeight->m_SrcEnd = end_step;
-        pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) /
-                                            (FX_FLOAT)length * 65536);
-        pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
-      }
-    }
-  } else {
+  m_pWeightTables.resize(size, 0);
+  if (scale <= 1) {
     for (int des_row = 0; des_row < dest_len; des_row++) {
-      PixelWeight* pWeight =
-          (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);
+      PixelWeight* pWeight = GetPixelWeight(des_row);
       pWeight->m_SrcStart = des_row;
       pWeight->m_SrcEnd = des_row;
       pWeight->m_Weights[0] = 65536;
       pWeight->m_Weights[1] = 0;
     }
+    return;
+  }
+
+  double step = 0.0;
+  int src_row = 0;
+  while (step < (double)dest_len) {
+    int start_step = (int)step;
+    step = scale * (++src_row);
+    int end_step = (int)step;
+    if (end_step >= dest_len) {
+      end_step = dest_len;
+      for (int des_row = start_step; des_row < end_step; des_row++) {
+        PixelWeight* pWeight = GetPixelWeight(des_row);
+        pWeight->m_SrcStart = start_step;
+        pWeight->m_SrcEnd = start_step;
+        pWeight->m_Weights[0] = 65536;
+        pWeight->m_Weights[1] = 0;
+      }
+      return;
+    }
+    int length = end_step - start_step;
+    {
+      PixelWeight* pWeight = GetPixelWeight(start_step);
+      pWeight->m_SrcStart = start_step;
+      pWeight->m_SrcEnd = start_step;
+      pWeight->m_Weights[0] = 65536;
+      pWeight->m_Weights[1] = 0;
+    }
+    for (int des_row = start_step + 1; des_row < end_step; des_row++) {
+      PixelWeight* pWeight = GetPixelWeight(des_row);
+      pWeight->m_SrcStart = start_step;
+      pWeight->m_SrcEnd = end_step;
+      pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) /
+                                          (FX_FLOAT)length * 65536);
+      pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
+    }
   }
 }
+
 CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder(
     CCodec_ModuleMgr* pCodecMgr) {
   m_pFile = nullptr;
@@ -253,7 +259,8 @@
   m_offSet = 0;
   m_SrcSize = 0;
   m_ScanlineSize = 0;
-  m_SrcWidth = m_SrcHeight = 0;
+  m_SrcWidth = 0;
+  m_SrcHeight = 0;
   m_SrcComponents = 0;
   m_SrcBPC = 0;
   m_SrcPassNumber = 0;
@@ -274,27 +281,24 @@
   m_GifFrameRect = FX_RECT(0, 0, 0, 0);
   m_BmpIsTopBottom = FALSE;
 }
+
 CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() {
   m_pFile = nullptr;
-  if (m_pJpegContext) {
+  if (m_pJpegContext)
     m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext);
-  }
-  if (m_pPngContext) {
+  if (m_pPngContext)
     m_pCodecMgr->GetPngModule()->Finish(m_pPngContext);
-  }
-  if (m_pGifContext) {
+  if (m_pGifContext)
     m_pCodecMgr->GetGifModule()->Finish(m_pGifContext);
-  }
-  if (m_pBmpContext) {
+  if (m_pBmpContext)
     m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext);
-  }
-  if (m_pTiffContext) {
+  if (m_pTiffContext)
     m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext);
-  }
   FX_Free(m_pSrcBuf);
   FX_Free(m_pDecodeBuf);
   FX_Free(m_pSrcPalette);
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData(
     CCodec_JpegModule* pJpegModule,
     FXCODEC_STATUS& err_status) {
@@ -332,6 +336,7 @@
   pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail);
   return TRUE;
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule,
                                                      int width,
                                                      int height,
@@ -345,14 +350,24 @@
     pCodec->m_SrcHeight = height;
     pCodec->m_SrcBPC = bpc;
     pCodec->m_SrcPassNumber = pass;
-    pCodec->m_SrcComponents =
-        *color_type == 0 ? 1 : *color_type == 2
-                                   ? 3
-                                   : *color_type == 3
-                                         ? 4
-                                         : *color_type == 4
-                                               ? 2
-                                               : *color_type == 6 ? 4 : 0;
+    switch (*color_type) {
+      case 0:
+        pCodec->m_SrcComponents = 1;
+        break;
+      case 4:
+        pCodec->m_SrcComponents = 2;
+        break;
+      case 2:
+        pCodec->m_SrcComponents = 3;
+        break;
+      case 3:
+      case 6:
+        pCodec->m_SrcComponents = 4;
+        break;
+      default:
+        pCodec->m_SrcComponents = 0;
+        break;
+    }
     pCodec->m_clipBox = FX_RECT(0, 0, width, height);
     return FALSE;
   }
@@ -377,9 +392,10 @@
       ASSERT(FALSE);
       return FALSE;
   }
-  *gamma = FXCODEC_PNG_GAMMA;
+  *gamma = kPngGamma;
   return TRUE;
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule,
                                                          int line,
                                                          uint8_t*& src_buf) {
@@ -454,6 +470,7 @@
   }
   return TRUE;
 }
+
 void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz(
     CFX_DIBitmap* pDeviceBitmap,
     int32_t des_line,
@@ -525,6 +542,7 @@
     }
   }
 }
+
 void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule,
                                                                 int pass,
                                                                 int line) {
@@ -554,6 +572,7 @@
     }
   }
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(CCodec_GifModule* pGifModule,
                                                    FXCODEC_STATUS& err_status) {
   uint32_t dwSize = (uint32_t)m_pFile->GetSize();
@@ -590,6 +609,7 @@
   pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail);
   return TRUE;
 }
+
 void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback(
     void* pModule,
     uint32_t& cur_pos) {
@@ -598,12 +618,14 @@
       pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext);
   cur_pos = pCodec->m_offSet - remain_size;
 }
+
 uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback(
     void* pModule,
     int32_t frame_num,
     int32_t pal_size) {
   return FX_Alloc(uint8_t, pal_size);
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(
     void* pModule,
     uint32_t rcd_pos,
@@ -693,6 +715,7 @@
   }
   return TRUE;
 }
+
 void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule,
                                                         int32_t row_num,
                                                         uint8_t* row_buf) {
@@ -723,41 +746,42 @@
   int des_top = pCodec->m_startY;
   int src_hei = pCodec->m_clipBox.Height();
   int des_hei = pCodec->m_sizeY;
-  if (line >= src_top && line < src_bottom) {
-    double scale_y = (double)des_hei / (double)src_hei;
-    int src_row = line - src_top;
-    int des_row = (int)(src_row * scale_y) + des_top;
-    if (des_row >= des_top + des_hei) {
-      return;
-    }
-    pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf,
-                             pCodec->m_SrcFormat);
-    if (scale_y > 1.0 &&
-        (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) {
-      pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
-      return;
-    }
-    if (scale_y > 1.0) {
-      int des_bottom = des_top + pCodec->m_sizeY;
-      int des_Bpp = pDIBitmap->GetBPP() >> 3;
-      uint32_t des_ScanOffet = pCodec->m_startX * des_Bpp;
-      if (des_row + (int)scale_y >= des_bottom - 1) {
-        uint8_t* scan_src =
-            (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet;
-        int cur_row = des_row;
-        while (++cur_row < des_bottom) {
-          uint8_t* scan_des =
-              (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet;
-          uint32_t size = pCodec->m_sizeX * des_Bpp;
-          FXSYS_memcpy(scan_des, scan_src, size);
-        }
-      }
-      if (bLastPass) {
-        pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row);
-      }
+  if (line < src_top || line >= src_bottom)
+    return;
+
+  double scale_y = (double)des_hei / (double)src_hei;
+  int src_row = line - src_top;
+  int des_row = (int)(src_row * scale_y) + des_top;
+  if (des_row >= des_top + des_hei)
+    return;
+
+  pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf,
+                           pCodec->m_SrcFormat);
+  if (scale_y > 1.0 && (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) {
+    pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
+    return;
+  }
+  if (scale_y <= 1.0)
+    return;
+
+  int des_bottom = des_top + pCodec->m_sizeY;
+  int des_Bpp = pDIBitmap->GetBPP() >> 3;
+  uint32_t des_ScanOffet = pCodec->m_startX * des_Bpp;
+  if (des_row + (int)scale_y >= des_bottom - 1) {
+    uint8_t* scan_src =
+        (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet;
+    int cur_row = des_row;
+    while (++cur_row < des_bottom) {
+      uint8_t* scan_des =
+          (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet;
+      uint32_t size = pCodec->m_sizeX * des_Bpp;
+      FXSYS_memcpy(scan_des, scan_src, size);
     }
   }
+  if (bLastPass)
+    pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row);
 }
+
 void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert(
     CFX_DIBitmap* pDeviceBitmap,
     double scale_y,
@@ -765,10 +789,12 @@
   int des_Bpp = pDeviceBitmap->GetBPP() >> 3;
   uint32_t des_ScanOffet = m_startX * des_Bpp;
   int des_top = m_startY;
-  int des_row_1 = des_row - int(2 * scale_y);
-  if (des_row_1 < des_top) {
-    des_row_1 = des_top;
-  }
+  pdfium::base::CheckedNumeric<double> scale_y2 = scale_y;
+  scale_y2 *= 2;
+  pdfium::base::CheckedNumeric<int> check_des_row_1 = des_row;
+  check_des_row_1 -= scale_y2.ValueOrDie();
+  int des_row_1 = check_des_row_1.ValueOrDie();
+  des_row_1 = std::max(des_row_1, des_top);
   for (; des_row_1 < des_row; des_row_1++) {
     uint8_t* scan_des =
         (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;
@@ -836,12 +862,13 @@
     GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y);
   }
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(CCodec_BmpModule* pBmpModule,
                                                    FXCODEC_STATUS& err_status) {
   uint32_t dwSize = (uint32_t)m_pFile->GetSize();
-  if (dwSize <= m_offSet) {
+  if (dwSize <= m_offSet)
     return FALSE;
-  }
+
   dwSize = dwSize - m_offSet;
   uint32_t dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, nullptr);
   if (dwAvail == m_SrcSize) {
@@ -872,18 +899,17 @@
   pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail);
   return TRUE;
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback(
     void* pModule,
     uint32_t rcd_pos) {
   CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
   pCodec->m_offSet = rcd_pos;
   FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
-  if (!pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(),
-                               error_status)) {
-    return FALSE;
-  }
-  return TRUE;
+  return pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(),
+                                 error_status);
 }
+
 void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule,
                                                         int32_t row_num,
                                                         uint8_t* row_buf) {
@@ -896,25 +922,27 @@
   int des_top = pCodec->m_startY;
   int src_hei = pCodec->m_clipBox.Height();
   int des_hei = pCodec->m_sizeY;
-  if (row_num >= src_top && row_num < src_bottom) {
-    double scale_y = (double)des_hei / (double)src_hei;
-    int src_row = row_num - src_top;
-    int des_row = (int)(src_row * scale_y) + des_top;
-    if (des_row >= des_top + des_hei) {
-      return;
-    }
-    pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf,
-                             pCodec->m_SrcFormat);
-    if (scale_y > 1.0) {
-      if (pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) {
-        pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
-        return;
-      } else {
-        pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row);
-      }
-    }
+  if (row_num < src_top || row_num >= src_bottom)
+    return;
+
+  double scale_y = (double)des_hei / (double)src_hei;
+  int src_row = row_num - src_top;
+  int des_row = (int)(src_row * scale_y) + des_top;
+  if (des_row >= des_top + des_hei)
+    return;
+
+  pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf,
+                           pCodec->m_SrcFormat);
+  if (scale_y <= 1.0)
+    return;
+
+  if (pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) {
+    pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
+    return;
   }
+  pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row);
 }
+
 void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap,
                                                double scale_y,
                                                int des_row) {
@@ -922,7 +950,9 @@
   uint32_t des_ScanOffet = m_startX * des_Bpp;
   int des_top = m_startY;
   int des_bottom = m_startY + m_sizeY;
-  int des_row_1 = des_row + int(scale_y);
+  pdfium::base::CheckedNumeric<int> check_des_row_1 = des_row;
+  check_des_row_1 += pdfium::base::checked_cast<int>(scale_y);
+  int des_row_1 = check_des_row_1.ValueOrDie();
   if (des_row_1 >= des_bottom - 1) {
     uint8_t* scan_src =
         (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
@@ -996,6 +1026,7 @@
     }
   }
 }
+
 FX_BOOL CCodec_ProgressiveDecoder::DetectImageType(
     FXCODEC_IMAGE_TYPE imageType,
     CFX_DIBAttribute* pAttribute) {
@@ -1063,7 +1094,7 @@
       }
       m_status = FXCODEC_STATUS_ERR_FORMAT;
       return FALSE;
-    } break;
+    }
     case FXCODEC_IMAGE_JPG: {
       CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
       if (!pJpegModule) {
@@ -1106,7 +1137,7 @@
       }
       m_status = FXCODEC_STATUS_ERR_FORMAT;
       return FALSE;
-    } break;
+    }
     case FXCODEC_IMAGE_PNG: {
       CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
       if (!pPngModule) {
@@ -1167,7 +1198,8 @@
         m_status = FXCODEC_STATUS_ERR_FORMAT;
         return FALSE;
       }
-    } break;
+      return TRUE;
+    }
     case FXCODEC_IMAGE_GIF: {
       CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
       if (!pGifModule) {
@@ -1219,7 +1251,7 @@
       }
       m_status = FXCODEC_STATUS_ERR_FORMAT;
       return FALSE;
-    } break;
+    }
     case FXCODEC_IMAGE_TIF: {
       CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
       if (!pTiffModule) {
@@ -1231,27 +1263,26 @@
         m_status = FXCODEC_STATUS_ERR_FORMAT;
         return FALSE;
       }
-      int32_t frames = 0;
-      pTiffModule->GetFrames(m_pTiffContext, frames);
-      uint32_t bpc;
-      FX_BOOL ret = pTiffModule->LoadFrameInfo(
-          m_pTiffContext, 0, (uint32_t&)m_SrcWidth, (uint32_t&)m_SrcHeight,
-          (uint32_t&)m_SrcComponents, bpc, pAttribute);
+      int32_t dummy_bpc;
+      FX_BOOL ret = pTiffModule->LoadFrameInfo(m_pTiffContext, 0, &m_SrcWidth,
+                                               &m_SrcHeight, &m_SrcComponents,
+                                               &dummy_bpc, pAttribute);
       m_SrcComponents = 4;
       m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
       if (!ret) {
         pTiffModule->DestroyDecoder(m_pTiffContext);
-        (m_pTiffContext = nullptr);
-        (m_status = FXCODEC_STATUS_ERR_FORMAT);
+        m_pTiffContext = nullptr;
+        m_status = FXCODEC_STATUS_ERR_FORMAT;
         return FALSE;
       }
-    } break;
+      return TRUE;
+    }
     default:
       m_status = FXCODEC_STATUS_ERR_FORMAT;
       return FALSE;
   }
-  return TRUE;
 }
+
 FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(
     IFX_FileRead* pFile,
     FXCODEC_IMAGE_TYPE imageType,
@@ -1295,32 +1326,26 @@
   m_pFile = nullptr;
   return m_status;
 }
+
 void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) {
-  if (m_status != FXCODEC_STATUS_FRAME_READY) {
+  if (m_status != FXCODEC_STATUS_FRAME_READY)
     return;
-  }
+
   if (clip->IsEmpty()) {
     m_clipBox = FX_RECT(0, 0, 0, 0);
     return;
   }
-  if (clip->left < 0) {
-    clip->left = 0;
-  }
-  if (clip->right > m_SrcWidth) {
-    clip->right = m_SrcWidth;
-  }
-  if (clip->top < 0) {
-    clip->top = 0;
-  }
-  if (clip->bottom > m_SrcHeight) {
-    clip->bottom = m_SrcHeight;
-  }
+  clip->left = std::max(clip->left, 0);
+  clip->right = std::min(clip->right, m_SrcWidth);
+  clip->top = std::max(clip->top, 0);
+  clip->bottom = std::min(clip->bottom, m_SrcHeight);
   if (clip->IsEmpty()) {
     m_clipBox = FX_RECT(0, 0, 0, 0);
     return;
   }
   m_clipBox = *clip;
 }
+
 void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale) {
   down_scale = 1;
   int ratio_w = m_clipBox.Width() / m_sizeX;
@@ -1344,6 +1369,7 @@
     m_clipBox.bottom = m_clipBox.top + 1;
   }
 }
+
 void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format,
                                                FXCodec_Format src_format) {
   switch (des_format) {
@@ -1441,18 +1467,7 @@
       m_TransMethod = -1;
   }
 }
-void _RGB2BGR(uint8_t* buffer, int width = 1) {
-  if (buffer && width > 0) {
-    uint8_t temp;
-    int i = 0;
-    int j = 0;
-    for (; i < width; i++, j += 3) {
-      temp = buffer[j];
-      buffer[j] = buffer[j + 2];
-      buffer[j + 2] = temp;
-    }
-  }
-}
+
 void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap,
                                                  int des_line,
                                                  uint8_t* src_scan,
@@ -1654,6 +1669,7 @@
     }
   }
 }
+
 void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap,
                                              double scale_y,
                                              int des_row) {
@@ -1661,7 +1677,9 @@
   uint32_t des_ScanOffet = m_startX * des_Bpp;
   if (m_bInterpol) {
     int des_top = m_startY;
-    int des_row_1 = des_row - int(scale_y);
+    pdfium::base::CheckedNumeric<int> check_des_row_1 = des_row;
+    check_des_row_1 -= pdfium::base::checked_cast<int>(scale_y);
+    int des_row_1 = check_des_row_1.ValueOrDie();
     if (des_row_1 < des_top) {
       int des_bottom = des_top + m_sizeY;
       if (des_row + (int)scale_y >= des_bottom - 1) {
@@ -1766,6 +1784,7 @@
     }
   }
 }
+
 void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap,
                                          int32_t src_line,
                                          uint8_t* src_scan,
@@ -1787,6 +1806,7 @@
     }
   }
 }
+
 FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames,
                                                     IFX_Pause* pPause) {
   if (!(m_status == FXCODEC_STATUS_FRAME_READY ||
@@ -1799,10 +1819,11 @@
     case FXCODEC_IMAGE_PNG:
     case FXCODEC_IMAGE_TIF:
       frames = m_FrameNumber = 1;
-      return m_status = FXCODEC_STATUS_DECODE_READY;
+      m_status = FXCODEC_STATUS_DECODE_READY;
+      return m_status;
     case FXCODEC_IMAGE_GIF: {
       CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
-      while (TRUE) {
+      while (true) {
         int32_t readResult =
             pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);
         while (readResult == 2) {
@@ -1811,26 +1832,29 @@
             return error_status;
           }
           if (pPause && pPause->NeedToPauseNow()) {
-            return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE;
+            m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE;
+            return m_status;
           }
           readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);
         }
         if (readResult == 1) {
           frames = m_FrameNumber;
-          return m_status = FXCODEC_STATUS_DECODE_READY;
+          m_status = FXCODEC_STATUS_DECODE_READY;
+          return m_status;
         }
         if (m_pGifContext) {
           pGifModule->Finish(m_pGifContext);
           m_pGifContext = nullptr;
         }
-        return m_status = FXCODEC_STATUS_ERROR;
+        m_status = FXCODEC_STATUS_ERROR;
+        return m_status;
       }
-    } break;
+    }
     default:
-      break;
+      return FXCODEC_STATUS_ERROR;
   }
-  return FXCODEC_STATUS_ERROR;
 }
+
 FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap,
                                                       int start_x,
                                                       int start_y,
@@ -1846,21 +1870,20 @@
     return FXCODEC_STATUS_ERR_PARAMS;
   }
   m_pDeviceBitmap = pDIBitmap;
-  if (m_clipBox.IsEmpty()) {
+  if (m_clipBox.IsEmpty())
     return FXCODEC_STATUS_ERR_PARAMS;
-  }
-  if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535) {
+  if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535)
     return FXCODEC_STATUS_ERR_PARAMS;
-  }
+
   FX_RECT device_rc =
       FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y);
   int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth();
   int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight();
   device_rc.Intersect(
       FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight()));
-  if (device_rc.IsEmpty()) {
+  if (device_rc.IsEmpty())
     return FXCODEC_STATUS_ERR_PARAMS;
-  }
+
   m_startX = device_rc.left;
   m_startY = device_rc.top;
   m_sizeX = device_rc.Width();
@@ -1899,7 +1922,8 @@
         if (!JpegReadMoreData(pJpegModule, error_status)) {
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = error_status;
+          m_status = error_status;
+          return m_status;
         }
         bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale);
       }
@@ -1923,14 +1947,16 @@
           break;
       }
       GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat);
-      return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
-    } break;
+      m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+      return m_status;
+    }
     case FXCODEC_IMAGE_PNG: {
       CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
       if (!pPngModule) {
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
-        return m_status = FXCODEC_STATUS_ERR_MEMORY;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
       }
       if (m_pPngContext) {
         pPngModule->Finish(m_pPngContext);
@@ -1940,7 +1966,8 @@
       if (!m_pPngContext) {
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
-        return m_status = FXCODEC_STATUS_ERR_MEMORY;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
       }
       m_offSet = 0;
       switch (m_pDeviceBitmap->GetFormat()) {
@@ -1961,7 +1988,8 @@
         default: {
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERR_PARAMS;
+          m_status = FXCODEC_STATUS_ERR_PARAMS;
+          return m_status;
         }
       }
       GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
@@ -1971,14 +1999,16 @@
       FXSYS_memset(m_pDecodeBuf, 0, scanline_size);
       m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol);
       m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
-      return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
-    } break;
+      m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+      return m_status;
+    }
     case FXCODEC_IMAGE_GIF: {
       CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
       if (!pGifModule) {
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
-        return m_status = FXCODEC_STATUS_ERR_MEMORY;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
       }
       m_SrcFormat = FXCodec_8bppRgb;
       GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
@@ -1990,14 +2020,16 @@
                         m_clipBox.Width(), m_bInterpol);
       m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
       m_FrameCur = frames;
-      return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
-    } break;
+      m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+      return m_status;
+    }
     case FXCODEC_IMAGE_BMP: {
       CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
       if (!pBmpModule) {
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
-        return m_status = FXCODEC_STATUS_ERR_MEMORY;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
       }
       switch (m_SrcComponents) {
         case 1:
@@ -2018,23 +2050,25 @@
       m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
                         m_clipBox.Width(), m_bInterpol);
       m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
-      return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
-    } break;
+      m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+      return m_status;
+    }
     case FXCODEC_IMAGE_TIF:
-      return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+      m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+      return m_status;
     default:
-      break;
+      return FXCODEC_STATUS_ERROR;
   }
-  return FXCODEC_STATUS_ERROR;
 }
+
 FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) {
-  if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) {
+  if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE)
     return FXCODEC_STATUS_ERROR;
-  }
+
   switch (m_imagType) {
     case FXCODEC_IMAGE_JPG: {
       CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
-      while (TRUE) {
+      while (true) {
         FX_BOOL readRes =
             pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);
         while (!readRes) {
@@ -2042,29 +2076,32 @@
           if (!JpegReadMoreData(pJpegModule, error_status)) {
             m_pDeviceBitmap = nullptr;
             m_pFile = nullptr;
-            return m_status = error_status;
+            m_status = error_status;
+            return m_status;
           }
           readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);
         }
         if (m_SrcFormat == FXCodec_Rgb) {
           int src_Bpp = (m_SrcFormat & 0xff) >> 3;
-          _RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width());
+          RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width());
         }
         if (m_SrcRow >= m_clipBox.bottom) {
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_DECODE_FINISH;
+          m_status = FXCODEC_STATUS_DECODE_FINISH;
+          return m_status;
         }
         Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat);
         m_SrcRow++;
         if (pPause && pPause->NeedToPauseNow()) {
-          return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+          m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+          return m_status;
         }
       }
-    } break;
+    }
     case FXCODEC_IMAGE_PNG: {
       CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
-      while (TRUE) {
+      while (true) {
         uint32_t remain_size = (uint32_t)m_pFile->GetSize() - m_offSet;
         uint32_t input_size =
             remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
@@ -2075,7 +2112,8 @@
           m_pPngContext = nullptr;
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_DECODE_FINISH;
+          m_status = FXCODEC_STATUS_DECODE_FINISH;
+          return m_status;
         }
         if (m_pSrcBuf && input_size > m_SrcSize) {
           FX_Free(m_pSrcBuf);
@@ -2087,7 +2125,8 @@
         if (!bResult) {
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERR_READ;
+          m_status = FXCODEC_STATUS_ERR_READ;
+          return m_status;
         }
         m_offSet += input_size;
         bResult =
@@ -2095,16 +2134,18 @@
         if (!bResult) {
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERROR;
+          m_status = FXCODEC_STATUS_ERROR;
+          return m_status;
         }
         if (pPause && pPause->NeedToPauseNow()) {
-          return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+          m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+          return m_status;
         }
       }
-    } break;
+    }
     case FXCODEC_IMAGE_GIF: {
       CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
-      while (TRUE) {
+      while (true) {
         int32_t readRes =
             pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr);
         while (readRes == 2) {
@@ -2112,49 +2153,57 @@
           if (!GifReadMoreData(pGifModule, error_status)) {
             m_pDeviceBitmap = nullptr;
             m_pFile = nullptr;
-            return m_status = error_status;
+            m_status = error_status;
+            return m_status;
           }
           if (pPause && pPause->NeedToPauseNow()) {
-            return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+            m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+            return m_status;
           }
           readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr);
         }
         if (readRes == 1) {
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_DECODE_FINISH;
+          m_status = FXCODEC_STATUS_DECODE_FINISH;
+          return m_status;
         }
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
-        return m_status = FXCODEC_STATUS_ERROR;
+        m_status = FXCODEC_STATUS_ERROR;
+        return m_status;
       }
-    } break;
+    }
     case FXCODEC_IMAGE_BMP: {
       CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
-      while (TRUE) {
+      while (true) {
         int32_t readRes = pBmpModule->LoadImage(m_pBmpContext);
         while (readRes == 2) {
           FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
           if (!BmpReadMoreData(pBmpModule, error_status)) {
             m_pDeviceBitmap = nullptr;
             m_pFile = nullptr;
-            return m_status = error_status;
+            m_status = error_status;
+            return m_status;
           }
           if (pPause && pPause->NeedToPauseNow()) {
-            return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+            m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+            return m_status;
           }
           readRes = pBmpModule->LoadImage(m_pBmpContext);
         }
         if (readRes == 1) {
           m_pDeviceBitmap = nullptr;
           m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_DECODE_FINISH;
+          m_status = FXCODEC_STATUS_DECODE_FINISH;
+          return m_status;
         }
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
-        return m_status = FXCODEC_STATUS_ERROR;
+        m_status = FXCODEC_STATUS_ERROR;
+        return m_status;
       }
-    } break;
+    };
     case FXCODEC_IMAGE_TIF: {
       CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
       FX_BOOL ret = FALSE;
@@ -2168,136 +2217,143 @@
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
         if (!ret) {
-          return m_status = FXCODEC_STATUS_ERROR;
+          m_status = FXCODEC_STATUS_ERROR;
+          return m_status;
         }
-        return m_status = FXCODEC_STATUS_DECODE_FINISH;
-      } else {
-        CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap;
-        pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);
-        if (!pDIBitmap->GetBuffer()) {
-          delete pDIBitmap;
-          m_pDeviceBitmap = nullptr;
-          m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERR_MEMORY;
-        }
-        ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap);
-        if (!ret) {
-          delete pDIBitmap;
-          m_pDeviceBitmap = nullptr;
-          m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERROR;
-        }
-        CFX_DIBitmap* pClipBitmap =
-            (m_clipBox.left == 0 && m_clipBox.top == 0 &&
-             m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight)
-                ? pDIBitmap
-                : pDIBitmap->Clone(&m_clipBox);
-        if (pDIBitmap != pClipBitmap) {
-          delete pDIBitmap;
-        }
-        if (!pClipBitmap) {
-          m_pDeviceBitmap = nullptr;
-          m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERR_MEMORY;
-        }
-        CFX_DIBitmap* pFormatBitmap = nullptr;
-        switch (m_pDeviceBitmap->GetFormat()) {
-          case FXDIB_8bppRgb:
-            pFormatBitmap = new CFX_DIBitmap;
-            pFormatBitmap->Create(pClipBitmap->GetWidth(),
-                                  pClipBitmap->GetHeight(), FXDIB_8bppRgb);
-            break;
-          case FXDIB_8bppMask:
-            pFormatBitmap = new CFX_DIBitmap;
-            pFormatBitmap->Create(pClipBitmap->GetWidth(),
-                                  pClipBitmap->GetHeight(), FXDIB_8bppMask);
-            break;
-          case FXDIB_Rgb:
-            pFormatBitmap = new CFX_DIBitmap;
-            pFormatBitmap->Create(pClipBitmap->GetWidth(),
-                                  pClipBitmap->GetHeight(), FXDIB_Rgb);
-            break;
-          case FXDIB_Rgb32:
-            pFormatBitmap = new CFX_DIBitmap;
-            pFormatBitmap->Create(pClipBitmap->GetWidth(),
-                                  pClipBitmap->GetHeight(), FXDIB_Rgb32);
-            break;
-          case FXDIB_Argb:
-            pFormatBitmap = pClipBitmap;
-            break;
-          default:
-            break;
-        }
-        switch (m_pDeviceBitmap->GetFormat()) {
-          case FXDIB_8bppRgb:
-          case FXDIB_8bppMask: {
-            for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
-              uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
-              uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row);
-              for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
-                uint8_t _a = 255 - src_line[3];
-                uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
-                uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
-                uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
-                *des_line++ = FXRGB2GRAY(r, g, b);
-                src_line += 4;
-              }
-            }
-          } break;
-          case FXDIB_Rgb:
-          case FXDIB_Rgb32: {
-            int32_t desBpp =
-                (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4;
-            for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
-              uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
-              uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row);
-              for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
-                uint8_t _a = 255 - src_line[3];
-                uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
-                uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
-                uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
-                *des_line++ = b;
-                *des_line++ = g;
-                *des_line++ = r;
-                des_line += desBpp - 3;
-                src_line += 4;
-              }
-            }
-          } break;
-          default:
-            break;
-        }
-        if (pClipBitmap != pFormatBitmap) {
-          delete pClipBitmap;
-        }
-        if (!pFormatBitmap) {
-          m_pDeviceBitmap = nullptr;
-          m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERR_MEMORY;
-        }
-        CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo(
-            m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE);
-        delete pFormatBitmap;
-        pFormatBitmap = nullptr;
-        if (!pStrechBitmap) {
-          m_pDeviceBitmap = nullptr;
-          m_pFile = nullptr;
-          return m_status = FXCODEC_STATUS_ERR_MEMORY;
-        }
-        m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY,
-                                        pStrechBitmap, 0, 0);
-        delete pStrechBitmap;
-        pStrechBitmap = nullptr;
+        m_status = FXCODEC_STATUS_DECODE_FINISH;
+        return m_status;
+      }
+
+      CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap;
+      pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);
+      if (!pDIBitmap->GetBuffer()) {
+        delete pDIBitmap;
         m_pDeviceBitmap = nullptr;
         m_pFile = nullptr;
-        return m_status = FXCODEC_STATUS_DECODE_FINISH;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
       }
-    } break;
+      ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap);
+      if (!ret) {
+        delete pDIBitmap;
+        m_pDeviceBitmap = nullptr;
+        m_pFile = nullptr;
+        m_status = FXCODEC_STATUS_ERROR;
+        return m_status;
+      }
+      CFX_DIBitmap* pClipBitmap =
+          (m_clipBox.left == 0 && m_clipBox.top == 0 &&
+           m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight)
+              ? pDIBitmap
+              : pDIBitmap->Clone(&m_clipBox);
+      if (pDIBitmap != pClipBitmap) {
+        delete pDIBitmap;
+      }
+      if (!pClipBitmap) {
+        m_pDeviceBitmap = nullptr;
+        m_pFile = nullptr;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
+      }
+      CFX_DIBitmap* pFormatBitmap = nullptr;
+      switch (m_pDeviceBitmap->GetFormat()) {
+        case FXDIB_8bppRgb:
+          pFormatBitmap = new CFX_DIBitmap;
+          pFormatBitmap->Create(pClipBitmap->GetWidth(),
+                                pClipBitmap->GetHeight(), FXDIB_8bppRgb);
+          break;
+        case FXDIB_8bppMask:
+          pFormatBitmap = new CFX_DIBitmap;
+          pFormatBitmap->Create(pClipBitmap->GetWidth(),
+                                pClipBitmap->GetHeight(), FXDIB_8bppMask);
+          break;
+        case FXDIB_Rgb:
+          pFormatBitmap = new CFX_DIBitmap;
+          pFormatBitmap->Create(pClipBitmap->GetWidth(),
+                                pClipBitmap->GetHeight(), FXDIB_Rgb);
+          break;
+        case FXDIB_Rgb32:
+          pFormatBitmap = new CFX_DIBitmap;
+          pFormatBitmap->Create(pClipBitmap->GetWidth(),
+                                pClipBitmap->GetHeight(), FXDIB_Rgb32);
+          break;
+        case FXDIB_Argb:
+          pFormatBitmap = pClipBitmap;
+          break;
+        default:
+          break;
+      }
+      switch (m_pDeviceBitmap->GetFormat()) {
+        case FXDIB_8bppRgb:
+        case FXDIB_8bppMask: {
+          for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
+            uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
+            uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row);
+            for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
+              uint8_t _a = 255 - src_line[3];
+              uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
+              uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
+              uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
+              *des_line++ = FXRGB2GRAY(r, g, b);
+              src_line += 4;
+            }
+          }
+        } break;
+        case FXDIB_Rgb:
+        case FXDIB_Rgb32: {
+          int32_t desBpp = (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4;
+          for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
+            uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
+            uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row);
+            for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
+              uint8_t _a = 255 - src_line[3];
+              uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
+              uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
+              uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
+              *des_line++ = b;
+              *des_line++ = g;
+              *des_line++ = r;
+              des_line += desBpp - 3;
+              src_line += 4;
+            }
+          }
+        } break;
+        default:
+          break;
+      }
+      if (pClipBitmap != pFormatBitmap) {
+        delete pClipBitmap;
+      }
+      if (!pFormatBitmap) {
+        m_pDeviceBitmap = nullptr;
+        m_pFile = nullptr;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
+      }
+      CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo(
+          m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE);
+      delete pFormatBitmap;
+      pFormatBitmap = nullptr;
+      if (!pStrechBitmap) {
+        m_pDeviceBitmap = nullptr;
+        m_pFile = nullptr;
+        m_status = FXCODEC_STATUS_ERR_MEMORY;
+        return m_status;
+      }
+      m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY,
+                                      pStrechBitmap, 0, 0);
+      delete pStrechBitmap;
+      pStrechBitmap = nullptr;
+      m_pDeviceBitmap = nullptr;
+      m_pFile = nullptr;
+      m_status = FXCODEC_STATUS_DECODE_FINISH;
+      return m_status;
+    }
     default:
-      break;
+      return FXCODEC_STATUS_ERROR;
   }
-  return FXCODEC_STATUS_ERROR;
 }
+
 CCodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() {
   return new CCodec_ProgressiveDecoder(this);
 }
diff --git a/core/fxcodec/codec/fx_codec_tiff.cpp b/core/fxcodec/codec/fx_codec_tiff.cpp
index c8c94db..09cfea4 100644
--- a/core/fxcodec/codec/fx_codec_tiff.cpp
+++ b/core/fxcodec/codec/fx_codec_tiff.cpp
@@ -12,172 +12,69 @@
 #include "third_party/libtiff/tiffiop.h"
 }
 
-void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData,
-                                  unsigned int dwProfileSize,
-                                  int nComponents,
-                                  int intent,
-                                  uint32_t dwSrcFormat = Icc_FORMAT_DEFAULT);
-void IccLib_TranslateImage(void* pTransform,
-                           unsigned char* pDest,
-                           const unsigned char* pSrc,
-                           int pixels);
-void IccLib_DestroyTransform(void* pTransform);
 class CCodec_TiffContext {
  public:
   CCodec_TiffContext();
   ~CCodec_TiffContext();
 
-  FX_BOOL InitDecoder(IFX_FileRead* file_ptr);
-  void GetFrames(int32_t& frames);
-  FX_BOOL LoadFrameInfo(int32_t frame,
-                        uint32_t& width,
-                        uint32_t& height,
-                        uint32_t& comps,
-                        uint32_t& bpc,
-                        CFX_DIBAttribute* pAttribute);
-  FX_BOOL Decode(CFX_DIBitmap* pDIBitmap);
+  bool InitDecoder(IFX_FileRead* file_ptr);
+  bool LoadFrameInfo(int32_t frame,
+                     int32_t* width,
+                     int32_t* height,
+                     int32_t* comps,
+                     int32_t* bpc,
+                     CFX_DIBAttribute* pAttribute);
+  bool Decode(CFX_DIBitmap* pDIBitmap);
 
-  union {
-    IFX_FileRead* in;
-    IFX_FileStream* out;
-  } io;
-
-  uint32_t offset;
-
-  TIFF* tif_ctx;
-  void* icc_ctx;
-  int32_t frame_num;
-  int32_t frame_cur;
-  FX_BOOL isDecoder;
+  IFX_FileRead* io_in() const { return m_io_in; }
+  uint32_t offset() const { return m_offset; }
+  void set_offset(uint32_t offset) { m_offset = offset; }
+  void increment_offset(uint32_t offset) { m_offset += offset; }
 
  private:
-  FX_BOOL isSupport(CFX_DIBitmap* pDIBitmap);
+  bool IsSupport(const CFX_DIBitmap* pDIBitmap) const;
   void SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps);
-  FX_BOOL Decode1bppRGB(CFX_DIBitmap* pDIBitmap,
-                        int32_t height,
-                        int32_t width,
-                        uint16_t bps,
-                        uint16_t spp);
-  FX_BOOL Decode8bppRGB(CFX_DIBitmap* pDIBitmap,
-                        int32_t height,
-                        int32_t width,
-                        uint16_t bps,
-                        uint16_t spp);
-  FX_BOOL Decode24bppRGB(CFX_DIBitmap* pDIBitmap,
-                         int32_t height,
-                         int32_t width,
-                         uint16_t bps,
-                         uint16_t spp);
+  bool Decode1bppRGB(CFX_DIBitmap* pDIBitmap,
+                     int32_t height,
+                     int32_t width,
+                     uint16_t bps,
+                     uint16_t spp);
+  bool Decode8bppRGB(CFX_DIBitmap* pDIBitmap,
+                     int32_t height,
+                     int32_t width,
+                     uint16_t bps,
+                     uint16_t spp);
+  bool Decode24bppRGB(CFX_DIBitmap* pDIBitmap,
+                      int32_t height,
+                      int32_t width,
+                      uint16_t bps,
+                      uint16_t spp);
+
+  IFX_FileRead* m_io_in;
+  uint32_t m_offset;
+  TIFF* m_tif_ctx;
 };
-CCodec_TiffContext::CCodec_TiffContext() {
-  offset = 0;
-  frame_num = 0;
-  frame_cur = 0;
-  io.in = nullptr;
-  tif_ctx = nullptr;
-  icc_ctx = nullptr;
-  isDecoder = TRUE;
-}
-CCodec_TiffContext::~CCodec_TiffContext() {
-  if (icc_ctx) {
-    IccLib_DestroyTransform(icc_ctx);
-    icc_ctx = nullptr;
-  }
-  if (tif_ctx) {
-    TIFFClose(tif_ctx);
-  }
-}
-static tsize_t _tiff_read(thandle_t context, tdata_t buf, tsize_t length) {
-  CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
-  FX_BOOL ret = FALSE;
-  if (pTiffContext->isDecoder) {
-    ret = pTiffContext->io.in->ReadBlock(buf, pTiffContext->offset, length);
-  } else {
-    ret = pTiffContext->io.out->ReadBlock(buf, pTiffContext->offset, length);
-  }
-  if (!ret) {
-    return 0;
-  }
-  pTiffContext->offset += (uint32_t)length;
-  return length;
-}
-static tsize_t _tiff_write(thandle_t context, tdata_t buf, tsize_t length) {
-  CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
-  ASSERT(!pTiffContext->isDecoder);
-  if (!pTiffContext->io.out->WriteBlock(buf, pTiffContext->offset, length)) {
-    return 0;
-  }
-  pTiffContext->offset += (uint32_t)length;
-  return length;
-}
-static toff_t _tiff_seek(thandle_t context, toff_t offset, int whence) {
-  CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
-  switch (whence) {
-    case 0:
-      pTiffContext->offset = (uint32_t)offset;
-      break;
-    case 1:
-      pTiffContext->offset += (uint32_t)offset;
-      break;
-    case 2:
-      if (pTiffContext->isDecoder) {
-        if (pTiffContext->io.in->GetSize() < (FX_FILESIZE)offset) {
-          return static_cast<toff_t>(-1);
-        }
-        pTiffContext->offset =
-            (uint32_t)(pTiffContext->io.in->GetSize() - offset);
-      } else {
-        if (pTiffContext->io.out->GetSize() < (FX_FILESIZE)offset) {
-          return static_cast<toff_t>(-1);
-        }
-        pTiffContext->offset =
-            (uint32_t)(pTiffContext->io.out->GetSize() - offset);
-      }
-      break;
-    default:
-      return static_cast<toff_t>(-1);
-  }
-  ASSERT(pTiffContext->isDecoder ? (pTiffContext->offset <=
-                                    (uint32_t)pTiffContext->io.in->GetSize())
-                                 : TRUE);
-  return pTiffContext->offset;
-}
-static int _tiff_close(thandle_t context) {
-  return 0;
-}
-static toff_t _tiff_get_size(thandle_t context) {
-  CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
-  return pTiffContext->isDecoder ? (toff_t)pTiffContext->io.in->GetSize()
-                                 : (toff_t)pTiffContext->io.out->GetSize();
-}
-static int _tiff_map(thandle_t context, tdata_t*, toff_t*) {
-  return 0;
-}
-static void _tiff_unmap(thandle_t context, tdata_t, toff_t) {}
-TIFF* _tiff_open(void* context, const char* mode) {
-  TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, _tiff_read,
-                             _tiff_write, _tiff_seek, _tiff_close,
-                             _tiff_get_size, _tiff_map, _tiff_unmap);
-  if (tif) {
-    tif->tif_fd = (int)(intptr_t)context;
-  }
-  return tif;
-}
+
 void* _TIFFmalloc(tmsize_t size) {
   return FXMEM_DefaultAlloc(size, 0);
 }
+
 void _TIFFfree(void* ptr) {
   FXMEM_DefaultFree(ptr, 0);
 }
+
 void* _TIFFrealloc(void* ptr, tmsize_t size) {
   return FXMEM_DefaultRealloc(ptr, size, 0);
 }
+
 void _TIFFmemset(void* ptr, int val, tmsize_t size) {
   FXSYS_memset(ptr, val, (size_t)size);
 }
+
 void _TIFFmemcpy(void* des, const void* src, tmsize_t size) {
   FXSYS_memcpy(des, src, (size_t)size);
 }
+
 int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size) {
   return FXSYS_memcmp(ptr1, ptr2, (size_t)size);
 }
@@ -185,77 +82,80 @@
 TIFFErrorHandler _TIFFwarningHandler = nullptr;
 TIFFErrorHandler _TIFFerrorHandler = nullptr;
 
-int TIFFCmyk2Rgb(thandle_t context,
-                 uint8 c,
-                 uint8 m,
-                 uint8 y,
-                 uint8 k,
-                 uint8* r,
-                 uint8* g,
-                 uint8* b) {
-  if (!context)
-    return 0;
-
-  CCodec_TiffContext* p = (CCodec_TiffContext*)context;
-  if (p->icc_ctx) {
-    unsigned char cmyk[4], bgr[3];
-    cmyk[0] = c, cmyk[1] = m, cmyk[2] = y, cmyk[3] = k;
-    IccLib_TranslateImage(p->icc_ctx, bgr, cmyk, 1);
-    *r = bgr[2], *g = bgr[1], *b = bgr[0];
-  } else {
-    AdobeCMYK_to_sRGB1(c, m, y, k, *r, *g, *b);
-  }
-  return 1;
-}
-FX_BOOL CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr) {
-  io.in = file_ptr;
-  return !!_tiff_open(this, "r");
-}
-void CCodec_TiffContext::GetFrames(int32_t& frames) {
-  frames = frame_num = TIFFNumberOfDirectories(tif_ctx);
-}
-#define TIFF_EXIF_GETINFO(key, T, tag)      \
-  {                                         \
-    T val = (T)0;                           \
-    TIFFGetField(tif_ctx, tag, &val);       \
-    if (val) {                              \
-      (key) = FX_Alloc(uint8_t, sizeof(T)); \
-      if ((key)) {                          \
-        T* ptr = (T*)(key);                 \
-        *ptr = val;                         \
-        pExif->m_TagVal.SetAt(tag, (key));  \
-      }                                     \
-    }                                       \
-  }                                         \
-  (key) = nullptr;
-#define TIFF_EXIF_GETSTRINGINFO(key, tag)    \
-  {                                          \
-    uint32_t size = 0;                       \
-    uint8_t* buf = nullptr;                  \
-    TIFFGetField(tif_ctx, tag, &size, &buf); \
-    if (size && buf) {                       \
-      (key) = FX_Alloc(uint8_t, size);       \
-      if ((key)) {                           \
-        FXSYS_memcpy((key), buf, size);      \
-        pExif->m_TagVal.SetAt(tag, (key));   \
-      }                                      \
-    }                                        \
-  }                                          \
-  (key) = nullptr;
-
 namespace {
 
+tsize_t tiff_read(thandle_t context, tdata_t buf, tsize_t length) {
+  CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
+  if (!pTiffContext->io_in()->ReadBlock(buf, pTiffContext->offset(), length))
+    return 0;
+
+  pTiffContext->increment_offset(length);
+  return length;
+}
+
+tsize_t tiff_write(thandle_t context, tdata_t buf, tsize_t length) {
+  ASSERT(false);
+  return 0;
+}
+
+toff_t tiff_seek(thandle_t context, toff_t offset, int whence) {
+  CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
+  switch (whence) {
+    case 0:
+      pTiffContext->set_offset(offset);
+      break;
+    case 1:
+      pTiffContext->increment_offset(offset);
+      break;
+    case 2:
+      if (pTiffContext->io_in()->GetSize() < (FX_FILESIZE)offset)
+        return static_cast<toff_t>(-1);
+      pTiffContext->set_offset(pTiffContext->io_in()->GetSize() - offset);
+      break;
+    default:
+      return static_cast<toff_t>(-1);
+  }
+  ASSERT(pTiffContext->offset() <= (uint32_t)pTiffContext->io_in()->GetSize());
+  return pTiffContext->offset();
+}
+
+int tiff_close(thandle_t context) {
+  return 0;
+}
+
+toff_t tiff_get_size(thandle_t context) {
+  CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
+  return (toff_t)pTiffContext->io_in()->GetSize();
+}
+
+int tiff_map(thandle_t context, tdata_t*, toff_t*) {
+  return 0;
+}
+
+void tiff_unmap(thandle_t context, tdata_t, toff_t) {}
+
+TIFF* tiff_open(void* context, const char* mode) {
+  TIFF* tif = TIFFClientOpen("Tiff Image", mode, (thandle_t)context, tiff_read,
+                             tiff_write, tiff_seek, tiff_close, tiff_get_size,
+                             tiff_map, tiff_unmap);
+  if (tif) {
+    tif->tif_fd = (int)(intptr_t)context;
+  }
+  return tif;
+}
+
 template <class T>
-FX_BOOL Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttribute* pAttr) {
+bool Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttribute* pAttr) {
   T val = 0;
   TIFFGetField(tif_ctx, tag, &val);
   if (!val)
-    return FALSE;
+    return false;
   T* ptr = FX_Alloc(T, 1);
   *ptr = val;
   pAttr->m_Exif[tag] = (void*)ptr;
-  return TRUE;
+  return true;
 }
+
 void Tiff_Exif_GetStringInfo(TIFF* tif_ctx,
                              ttag_t tag,
                              CFX_DIBAttribute* pAttr) {
@@ -270,60 +170,7 @@
   pAttr->m_Exif[tag] = ptr;
 }
 
-}  // namespace
-
-FX_BOOL CCodec_TiffContext::LoadFrameInfo(int32_t frame,
-                                          uint32_t& width,
-                                          uint32_t& height,
-                                          uint32_t& comps,
-                                          uint32_t& bpc,
-                                          CFX_DIBAttribute* pAttribute) {
-  if (!TIFFSetDirectory(tif_ctx, (uint16)frame)) {
-    return FALSE;
-  }
-  uint16_t tif_cs;
-  uint32_t tif_icc_size = 0;
-  uint8_t* tif_icc_buf = nullptr;
-  uint16_t tif_bpc = 0;
-  uint16_t tif_cps;
-  uint32_t tif_rps;
-  width = height = comps = 0;
-  TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width);
-  TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height);
-  TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &comps);
-  TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc);
-  TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &tif_cs);
-  TIFFGetField(tif_ctx, TIFFTAG_COMPRESSION, &tif_cps);
-  TIFFGetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps);
-  TIFFGetField(tif_ctx, TIFFTAG_ICCPROFILE, &tif_icc_size, &tif_icc_buf);
-  if (pAttribute) {
-    pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH;
-    if (TIFFGetField(tif_ctx, TIFFTAG_RESOLUTIONUNIT,
-                     &pAttribute->m_wDPIUnit)) {
-      pAttribute->m_wDPIUnit -= 1;
-    }
-    Tiff_Exif_GetInfo<uint16_t>(tif_ctx, TIFFTAG_ORIENTATION, pAttribute);
-    if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_XRESOLUTION, pAttribute)) {
-      void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION];
-      FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
-      pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f);
-    }
-    if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_YRESOLUTION, pAttribute)) {
-      void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION];
-      FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
-      pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f);
-    }
-    Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute);
-    Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MAKE, pAttribute);
-    Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MODEL, pAttribute);
-  }
-  bpc = tif_bpc;
-  if (tif_rps > height) {
-    TIFFSetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps = height);
-  }
-  return TRUE;
-}
-void _TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) {
+void TiffBGRA2RGBA(uint8_t* pBuf, int32_t pixel, int32_t spp) {
   for (int32_t n = 0; n < pixel; n++) {
     uint8_t tmp = pBuf[0];
     pBuf[0] = pBuf[2];
@@ -331,41 +178,112 @@
     pBuf += spp;
   }
 }
-FX_BOOL CCodec_TiffContext::isSupport(CFX_DIBitmap* pDIBitmap) {
-  if (TIFFIsTiled(tif_ctx)) {
-    return FALSE;
+
+}  // namespace
+
+CCodec_TiffContext::CCodec_TiffContext()
+    : m_io_in(nullptr), m_offset(0), m_tif_ctx(nullptr) {}
+
+CCodec_TiffContext::~CCodec_TiffContext() {
+  if (m_tif_ctx)
+    TIFFClose(m_tif_ctx);
+}
+
+bool CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr) {
+  m_io_in = file_ptr;
+  m_tif_ctx = tiff_open(this, "r");
+  return !!m_tif_ctx;
+}
+
+bool CCodec_TiffContext::LoadFrameInfo(int32_t frame,
+                                       int32_t* width,
+                                       int32_t* height,
+                                       int32_t* comps,
+                                       int32_t* bpc,
+                                       CFX_DIBAttribute* pAttribute) {
+  if (!TIFFSetDirectory(m_tif_ctx, (uint16)frame))
+    return false;
+
+  uint32_t tif_width = 0;
+  uint32_t tif_height = 0;
+  uint16_t tif_comps = 0;
+  uint16_t tif_bpc = 0;
+  uint32_t tif_rps = 0;
+  TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &tif_width);
+  TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &tif_height);
+  TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &tif_comps);
+  TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc);
+  TIFFGetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps);
+
+  if (pAttribute) {
+    pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH;
+    if (TIFFGetField(m_tif_ctx, TIFFTAG_RESOLUTIONUNIT,
+                     &pAttribute->m_wDPIUnit)) {
+      pAttribute->m_wDPIUnit--;
+    }
+    Tiff_Exif_GetInfo<uint16_t>(m_tif_ctx, TIFFTAG_ORIENTATION, pAttribute);
+    if (Tiff_Exif_GetInfo<FX_FLOAT>(m_tif_ctx, TIFFTAG_XRESOLUTION,
+                                    pAttribute)) {
+      void* val = pAttribute->m_Exif[TIFFTAG_XRESOLUTION];
+      FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
+      pAttribute->m_nXDPI = (int32_t)(fDpi + 0.5f);
+    }
+    if (Tiff_Exif_GetInfo<FX_FLOAT>(m_tif_ctx, TIFFTAG_YRESOLUTION,
+                                    pAttribute)) {
+      void* val = pAttribute->m_Exif[TIFFTAG_YRESOLUTION];
+      FX_FLOAT fDpi = val ? *reinterpret_cast<FX_FLOAT*>(val) : 0;
+      pAttribute->m_nYDPI = (int32_t)(fDpi + 0.5f);
+    }
+    Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pAttribute);
+    Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MAKE, pAttribute);
+    Tiff_Exif_GetStringInfo(m_tif_ctx, TIFFTAG_MODEL, pAttribute);
   }
+  *width = pdfium::base::checked_cast<int32_t>(tif_width);
+  *height = pdfium::base::checked_cast<int32_t>(tif_height);
+  *comps = tif_comps;
+  *bpc = tif_bpc;
+  if (tif_rps > tif_height) {
+    tif_rps = tif_height;
+    TIFFSetField(m_tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps);
+  }
+  return true;
+}
+
+bool CCodec_TiffContext::IsSupport(const CFX_DIBitmap* pDIBitmap) const {
+  if (TIFFIsTiled(m_tif_ctx))
+    return false;
+
   uint16_t photometric;
-  if (!TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric)) {
-    return FALSE;
-  }
+  if (!TIFFGetField(m_tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric))
+    return false;
+
   switch (pDIBitmap->GetBPP()) {
     case 1:
     case 8:
       if (photometric != PHOTOMETRIC_PALETTE) {
-        return FALSE;
+        return false;
       }
       break;
     case 24:
       if (photometric != PHOTOMETRIC_RGB) {
-        return FALSE;
+        return false;
       }
       break;
     default:
-      return FALSE;
+      return false;
   }
   uint16_t planarconfig;
-  if (!TIFFGetFieldDefaulted(tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) {
-    return FALSE;
-  }
-  if (planarconfig == PLANARCONFIG_SEPARATE) {
-    return FALSE;
-  }
-  return TRUE;
+  if (!TIFFGetFieldDefaulted(m_tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig))
+    return false;
+
+  return planarconfig != PLANARCONFIG_SEPARATE;
 }
+
 void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, uint16_t bps) {
-  uint16_t *red_orig, *green_orig, *blue_orig;
-  TIFFGetField(tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig);
+  uint16_t* red_orig;
+  uint16_t* green_orig;
+  uint16_t* blue_orig;
+  TIFFGetField(m_tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig);
   for (int32_t i = (1L << bps) - 1; i >= 0; i--) {
 #define CVT(x) ((uint16_t)((x) >> 8))
     red_orig[i] = CVT(red_orig[i]);
@@ -383,53 +301,55 @@
     pDIBitmap->SetPaletteEntry(index, color);
   }
 }
-FX_BOOL CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap,
-                                          int32_t height,
-                                          int32_t width,
-                                          uint16_t bps,
-                                          uint16_t spp) {
+
+bool CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap,
+                                       int32_t height,
+                                       int32_t width,
+                                       uint16_t bps,
+                                       uint16_t spp) {
   if (pDIBitmap->GetBPP() != 1 || spp != 1 || bps != 1 ||
-      !isSupport(pDIBitmap)) {
-    return FALSE;
+      !IsSupport(pDIBitmap)) {
+    return false;
   }
   SetPalette(pDIBitmap, bps);
-  int32_t size = (int32_t)TIFFScanlineSize(tif_ctx);
+  int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx);
   uint8_t* buf = (uint8_t*)_TIFFmalloc(size);
   if (!buf) {
-    TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer");
-    return FALSE;
+    TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer");
+    return false;
   }
   uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer();
   uint32_t pitch = pDIBitmap->GetPitch();
   for (int32_t row = 0; row < height; row++) {
-    TIFFReadScanline(tif_ctx, buf, row, 0);
+    TIFFReadScanline(m_tif_ctx, buf, row, 0);
     for (int32_t j = 0; j < size; j++) {
       bitMapbuffer[row * pitch + j] = buf[j];
     }
   }
   _TIFFfree(buf);
-  return TRUE;
+  return true;
 }
-FX_BOOL CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap,
-                                          int32_t height,
-                                          int32_t width,
-                                          uint16_t bps,
-                                          uint16_t spp) {
+
+bool CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap,
+                                       int32_t height,
+                                       int32_t width,
+                                       uint16_t bps,
+                                       uint16_t spp) {
   if (pDIBitmap->GetBPP() != 8 || spp != 1 || (bps != 4 && bps != 8) ||
-      !isSupport(pDIBitmap)) {
-    return FALSE;
+      !IsSupport(pDIBitmap)) {
+    return false;
   }
   SetPalette(pDIBitmap, bps);
-  int32_t size = (int32_t)TIFFScanlineSize(tif_ctx);
+  int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx);
   uint8_t* buf = (uint8_t*)_TIFFmalloc(size);
   if (!buf) {
-    TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer");
-    return FALSE;
+    TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer");
+    return false;
   }
   uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer();
   uint32_t pitch = pDIBitmap->GetPitch();
   for (int32_t row = 0; row < height; row++) {
-    TIFFReadScanline(tif_ctx, buf, row, 0);
+    TIFFReadScanline(m_tif_ctx, buf, row, 0);
     for (int32_t j = 0; j < size; j++) {
       switch (bps) {
         case 4:
@@ -443,26 +363,27 @@
     }
   }
   _TIFFfree(buf);
-  return TRUE;
+  return true;
 }
-FX_BOOL CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap,
-                                           int32_t height,
-                                           int32_t width,
-                                           uint16_t bps,
-                                           uint16_t spp) {
-  if (pDIBitmap->GetBPP() != 24 || !isSupport(pDIBitmap)) {
-    return FALSE;
-  }
-  int32_t size = (int32_t)TIFFScanlineSize(tif_ctx);
+
+bool CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap,
+                                        int32_t height,
+                                        int32_t width,
+                                        uint16_t bps,
+                                        uint16_t spp) {
+  if (pDIBitmap->GetBPP() != 24 || !IsSupport(pDIBitmap))
+    return false;
+
+  int32_t size = (int32_t)TIFFScanlineSize(m_tif_ctx);
   uint8_t* buf = (uint8_t*)_TIFFmalloc(size);
   if (!buf) {
-    TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer");
-    return FALSE;
+    TIFFError(TIFFFileName(m_tif_ctx), "No space for scanline buffer");
+    return false;
   }
   uint8_t* bitMapbuffer = (uint8_t*)pDIBitmap->GetBuffer();
   uint32_t pitch = pDIBitmap->GetPitch();
   for (int32_t row = 0; row < height; row++) {
-    TIFFReadScanline(tif_ctx, buf, row, 0);
+    TIFFReadScanline(m_tif_ctx, buf, row, 0);
     for (int32_t j = 0; j < size - 2; j += 3) {
       bitMapbuffer[row * pitch + j + 0] = buf[j + 2];
       bitMapbuffer[row * pitch + j + 1] = buf[j + 1];
@@ -470,43 +391,44 @@
     }
   }
   _TIFFfree(buf);
-  return TRUE;
+  return true;
 }
-FX_BOOL CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) {
+
+bool CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap) {
   uint32_t img_wid = pDIBitmap->GetWidth();
   uint32_t img_hei = pDIBitmap->GetHeight();
   uint32_t width = 0;
   uint32_t height = 0;
-  TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width);
-  TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height);
-  if (img_wid != width || img_hei != height) {
-    return FALSE;
-  }
+  TIFFGetField(m_tif_ctx, TIFFTAG_IMAGEWIDTH, &width);
+  TIFFGetField(m_tif_ctx, TIFFTAG_IMAGELENGTH, &height);
+  if (img_wid != width || img_hei != height)
+    return false;
+
   if (pDIBitmap->GetBPP() == 32) {
     uint16_t rotation = ORIENTATION_TOPLEFT;
-    TIFFGetField(tif_ctx, TIFFTAG_ORIENTATION, &rotation);
-    if (TIFFReadRGBAImageOriented(tif_ctx, img_wid, img_hei,
+    TIFFGetField(m_tif_ctx, TIFFTAG_ORIENTATION, &rotation);
+    if (TIFFReadRGBAImageOriented(m_tif_ctx, img_wid, img_hei,
                                   (uint32*)pDIBitmap->GetBuffer(), rotation,
                                   1)) {
       for (uint32_t row = 0; row < img_hei; row++) {
         uint8_t* row_buf = (uint8_t*)pDIBitmap->GetScanline(row);
-        _TiffBGRA2RGBA(row_buf, img_wid, 4);
+        TiffBGRA2RGBA(row_buf, img_wid, 4);
       }
-      return TRUE;
+      return true;
     }
   }
-  uint16_t spp, bps;
-  TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp);
-  TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps);
+  uint16_t spp;
+  uint16_t bps;
+  TIFFGetField(m_tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp);
+  TIFFGetField(m_tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps);
   uint32_t bpp = bps * spp;
-  if (bpp == 1) {
+  if (bpp == 1)
     return Decode1bppRGB(pDIBitmap, height, width, bps, spp);
-  } else if (bpp <= 8) {
+  if (bpp <= 8)
     return Decode8bppRGB(pDIBitmap, height, width, bps, spp);
-  } else if (bpp <= 24) {
+  if (bpp <= 24)
     return Decode24bppRGB(pDIBitmap, height, width, bps, spp);
-  }
-  return FALSE;
+  return false;
 }
 
 CCodec_TiffContext* CCodec_TiffModule::CreateDecoder(IFX_FileRead* file_ptr) {
@@ -518,22 +440,18 @@
   return pDecoder;
 }
 
-void CCodec_TiffModule::GetFrames(CCodec_TiffContext* ctx, int32_t& frames) {
-  ctx->GetFrames(frames);
-}
-
-FX_BOOL CCodec_TiffModule::LoadFrameInfo(CCodec_TiffContext* ctx,
-                                         int32_t frame,
-                                         uint32_t& width,
-                                         uint32_t& height,
-                                         uint32_t& comps,
-                                         uint32_t& bpc,
-                                         CFX_DIBAttribute* pAttribute) {
+bool CCodec_TiffModule::LoadFrameInfo(CCodec_TiffContext* ctx,
+                                      int32_t frame,
+                                      int32_t* width,
+                                      int32_t* height,
+                                      int32_t* comps,
+                                      int32_t* bpc,
+                                      CFX_DIBAttribute* pAttribute) {
   return ctx->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute);
 }
 
-FX_BOOL CCodec_TiffModule::Decode(CCodec_TiffContext* ctx,
-                                  class CFX_DIBitmap* pDIBitmap) {
+bool CCodec_TiffModule::Decode(CCodec_TiffContext* ctx,
+                               class CFX_DIBitmap* pDIBitmap) {
   return ctx->Decode(pDIBitmap);
 }
 
diff --git a/core/fxcodec/codec/include/ccodec_progressivedecoder.h b/core/fxcodec/codec/include/ccodec_progressivedecoder.h
index 5421d73..5774371 100644
--- a/core/fxcodec/codec/include/ccodec_progressivedecoder.h
+++ b/core/fxcodec/codec/include/ccodec_progressivedecoder.h
@@ -7,6 +7,8 @@
 #ifndef CORE_FXCODEC_CODEC_INCLUDE_CCODEC_PROGRESSIVEDECODER_H_
 #define CORE_FXCODEC_CODEC_INCLUDE_CCODEC_PROGRESSIVEDECODER_H_
 
+#include <vector>
+
 #include "core/fxcodec/include/fx_codec_def.h"
 #include "core/fxcrt/include/fx_system.h"
 #include "core/fxge/include/fx_dib.h"
@@ -40,7 +42,7 @@
     FXCodec_Cmyk = 0x120
   };
 
-  CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr);
+  explicit CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr);
   ~CCodec_ProgressiveDecoder();
 
   FXCODEC_STATUS LoadImageInfo(IFX_FileRead* pFile,
@@ -73,8 +75,8 @@
 
   class CFXCODEC_WeightTable {
    public:
-    CFXCODEC_WeightTable() { m_pWeightTables = nullptr; }
-    ~CFXCODEC_WeightTable() { FX_Free(m_pWeightTables); }
+    CFXCODEC_WeightTable() {}
+    ~CFXCODEC_WeightTable() {}
 
     void Calc(int dest_len,
               int dest_min,
@@ -84,37 +86,41 @@
               int src_max,
               FX_BOOL bInterpol);
     PixelWeight* GetPixelWeight(int pixel) {
-      return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize);
+      return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() +
+                                            (pixel - m_DestMin) * m_ItemSize);
     }
 
-    int m_DestMin, m_ItemSize;
-    uint8_t* m_pWeightTables;
+    int m_DestMin;
+    int m_ItemSize;
+    std::vector<uint8_t> m_pWeightTables;
   };
 
   class CFXCODEC_HorzTable {
    public:
-    CFXCODEC_HorzTable() { m_pWeightTables = nullptr; }
-    ~CFXCODEC_HorzTable() { FX_Free(m_pWeightTables); }
+    CFXCODEC_HorzTable() {}
+    ~CFXCODEC_HorzTable() {}
 
     void Calc(int dest_len, int src_len, FX_BOOL bInterpol);
     PixelWeight* GetPixelWeight(int pixel) {
-      return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize);
+      return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() +
+                                            pixel * m_ItemSize);
     }
 
     int m_ItemSize;
-    uint8_t* m_pWeightTables;
+    std::vector<uint8_t> m_pWeightTables;
   };
 
   class CFXCODEC_VertTable {
    public:
-    CFXCODEC_VertTable() { m_pWeightTables = nullptr; }
-    ~CFXCODEC_VertTable() { FX_Free(m_pWeightTables); }
+    CFXCODEC_VertTable() {}
+    ~CFXCODEC_VertTable() {}
     void Calc(int dest_len, int src_len);
     PixelWeight* GetPixelWeight(int pixel) {
-      return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize);
+      return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() +
+                                            pixel * m_ItemSize);
     }
     int m_ItemSize;
-    uint8_t* m_pWeightTables;
+    std::vector<uint8_t> m_pWeightTables;
   };
 
   IFX_FileRead* m_pFile;