Home | History | Annotate | Download | only in codec
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fxcodec/codec/ccodec_progressivedecoder.h"
      8 
      9 #include <algorithm>
     10 #include <memory>
     11 
     12 #include "core/fxcodec/fx_codec.h"
     13 #include "core/fxge/fx_dib.h"
     14 #include "third_party/base/numerics/safe_math.h"
     15 #include "third_party/base/ptr_util.h"
     16 
     17 #define FXCODEC_BLOCK_SIZE 4096
     18 
     19 namespace {
     20 
     21 #if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
     22 const double kPngGamma = 1.7;
     23 #else  // _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
     24 const double kPngGamma = 2.2;
     25 #endif  // _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
     26 
     27 void RGB2BGR(uint8_t* buffer, int width = 1) {
     28   if (buffer && width > 0) {
     29     uint8_t temp;
     30     int i = 0;
     31     int j = 0;
     32     for (; i < width; i++, j += 3) {
     33       temp = buffer[j];
     34       buffer[j] = buffer[j + 2];
     35       buffer[j + 2] = temp;
     36     }
     37   }
     38 }
     39 
     40 }  // namespace
     41 
     42 CCodec_ProgressiveDecoder::CFXCODEC_WeightTable::CFXCODEC_WeightTable() {}
     43 
     44 CCodec_ProgressiveDecoder::CFXCODEC_WeightTable::~CFXCODEC_WeightTable() {}
     45 
     46 void CCodec_ProgressiveDecoder::CFXCODEC_WeightTable::Calc(int dest_len,
     47                                                            int dest_min,
     48                                                            int dest_max,
     49                                                            int src_len,
     50                                                            int src_min,
     51                                                            int src_max,
     52                                                            bool bInterpol) {
     53   double scale, base;
     54   scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len;
     55   if (dest_len < 0) {
     56     base = (FX_FLOAT)(src_len);
     57   } else {
     58     base = 0.0f;
     59   }
     60   m_ItemSize =
     61       (int)(sizeof(int) * 2 +
     62             sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1));
     63   m_DestMin = dest_min;
     64   m_pWeightTables.resize((dest_max - dest_min) * m_ItemSize + 4);
     65   if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {
     66     for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) {
     67       PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
     68       double src_pos = dest_pixel * scale + scale / 2 + base;
     69       if (bInterpol) {
     70         pixel_weights.m_SrcStart =
     71             (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
     72         pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
     73         if (pixel_weights.m_SrcStart < src_min) {
     74           pixel_weights.m_SrcStart = src_min;
     75         }
     76         if (pixel_weights.m_SrcEnd >= src_max) {
     77           pixel_weights.m_SrcEnd = src_max - 1;
     78         }
     79         if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
     80           pixel_weights.m_Weights[0] = 65536;
     81         } else {
     82           pixel_weights.m_Weights[1] = FXSYS_round(
     83               (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) *
     84               65536);
     85           pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
     86         }
     87       } else {
     88         pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd =
     89             (int)FXSYS_floor((FX_FLOAT)src_pos);
     90         pixel_weights.m_Weights[0] = 65536;
     91       }
     92     }
     93     return;
     94   }
     95   for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) {
     96     PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
     97     double src_start = dest_pixel * scale + base;
     98     double src_end = src_start + scale;
     99     int start_i, end_i;
    100     if (src_start < src_end) {
    101       start_i = (int)FXSYS_floor((FX_FLOAT)src_start);
    102       end_i = (int)FXSYS_ceil((FX_FLOAT)src_end);
    103     } else {
    104       start_i = (int)FXSYS_floor((FX_FLOAT)src_end);
    105       end_i = (int)FXSYS_ceil((FX_FLOAT)src_start);
    106     }
    107     if (start_i < src_min) {
    108       start_i = src_min;
    109     }
    110     if (end_i >= src_max) {
    111       end_i = src_max - 1;
    112     }
    113     if (start_i > end_i) {
    114       pixel_weights.m_SrcStart = start_i;
    115       pixel_weights.m_SrcEnd = start_i;
    116       continue;
    117     }
    118     pixel_weights.m_SrcStart = start_i;
    119     pixel_weights.m_SrcEnd = end_i;
    120     for (int j = start_i; j <= end_i; j++) {
    121       double dest_start = ((FX_FLOAT)j - base) / scale;
    122       double dest_end = ((FX_FLOAT)(j + 1) - base) / scale;
    123       if (dest_start > dest_end) {
    124         double temp = dest_start;
    125         dest_start = dest_end;
    126         dest_end = temp;
    127       }
    128       double area_start = dest_start > (FX_FLOAT)(dest_pixel)
    129                               ? dest_start
    130                               : (FX_FLOAT)(dest_pixel);
    131       double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1)
    132                             ? (FX_FLOAT)(dest_pixel + 1)
    133                             : dest_end;
    134       double weight = area_start >= area_end ? 0.0f : area_end - area_start;
    135       if (weight == 0 && j == end_i) {
    136         pixel_weights.m_SrcEnd--;
    137         break;
    138       }
    139       pixel_weights.m_Weights[j - start_i] =
    140           FXSYS_round((FX_FLOAT)(weight * 65536));
    141     }
    142   }
    143 }
    144 
    145 CCodec_ProgressiveDecoder::CFXCODEC_HorzTable::CFXCODEC_HorzTable() {}
    146 
    147 CCodec_ProgressiveDecoder::CFXCODEC_HorzTable::~CFXCODEC_HorzTable() {}
    148 
    149 void CCodec_ProgressiveDecoder::CFXCODEC_HorzTable::Calc(int dest_len,
    150                                                          int src_len,
    151                                                          bool bInterpol) {
    152   double scale = (double)dest_len / (double)src_len;
    153   m_ItemSize = sizeof(int) * 4;
    154   int size = dest_len * m_ItemSize + 4;
    155   m_pWeightTables.resize(size, 0);
    156   if (scale > 1) {
    157     int pre_des_col = 0;
    158     for (int src_col = 0; src_col < src_len; src_col++) {
    159       double des_col_f = src_col * scale;
    160       int des_col = FXSYS_round((FX_FLOAT)des_col_f);
    161       PixelWeight* pWeight = GetPixelWeight(des_col);
    162       pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
    163       pWeight->m_Weights[0] = 65536;
    164       pWeight->m_Weights[1] = 0;
    165       if (src_col == src_len - 1 && des_col < dest_len - 1) {
    166         for (int des_col_index = pre_des_col + 1; des_col_index < dest_len;
    167              des_col_index++) {
    168           pWeight = GetPixelWeight(des_col_index);
    169           pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
    170           pWeight->m_Weights[0] = 65536;
    171           pWeight->m_Weights[1] = 0;
    172         }
    173         return;
    174       }
    175       int des_col_len = des_col - pre_des_col;
    176       for (int des_col_index = pre_des_col + 1; des_col_index < des_col;
    177            des_col_index++) {
    178         pWeight = GetPixelWeight(des_col_index);
    179         pWeight->m_SrcStart = src_col - 1;
    180         pWeight->m_SrcEnd = src_col;
    181         pWeight->m_Weights[0] =
    182             bInterpol ? FXSYS_round((FX_FLOAT)(
    183                             ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index) /
    184                             (FX_FLOAT)des_col_len * 65536))
    185                       : 65536;
    186         pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
    187       }
    188       pre_des_col = des_col;
    189     }
    190     return;
    191   }
    192   for (int des_col = 0; des_col < dest_len; des_col++) {
    193     double src_col_f = des_col / scale;
    194     int src_col = FXSYS_round((FX_FLOAT)src_col_f);
    195     PixelWeight* pWeight = GetPixelWeight(des_col);
    196     pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
    197     pWeight->m_Weights[0] = 65536;
    198     pWeight->m_Weights[1] = 0;
    199   }
    200 }
    201 
    202 CCodec_ProgressiveDecoder::CFXCODEC_VertTable::CFXCODEC_VertTable() {}
    203 
    204 CCodec_ProgressiveDecoder::CFXCODEC_VertTable::~CFXCODEC_VertTable() {}
    205 
    206 void CCodec_ProgressiveDecoder::CFXCODEC_VertTable::Calc(int dest_len,
    207                                                          int src_len) {
    208   double scale = (double)dest_len / (double)src_len;
    209   m_ItemSize = sizeof(int) * 4;
    210   int size = dest_len * m_ItemSize + 4;
    211   m_pWeightTables.resize(size, 0);
    212   if (scale <= 1) {
    213     for (int des_row = 0; des_row < dest_len; des_row++) {
    214       PixelWeight* pWeight = GetPixelWeight(des_row);
    215       pWeight->m_SrcStart = des_row;
    216       pWeight->m_SrcEnd = des_row;
    217       pWeight->m_Weights[0] = 65536;
    218       pWeight->m_Weights[1] = 0;
    219     }
    220     return;
    221   }
    222 
    223   double step = 0.0;
    224   int src_row = 0;
    225   while (step < (double)dest_len) {
    226     int start_step = (int)step;
    227     step = scale * (++src_row);
    228     int end_step = (int)step;
    229     if (end_step >= dest_len) {
    230       end_step = dest_len;
    231       for (int des_row = start_step; des_row < end_step; des_row++) {
    232         PixelWeight* pWeight = GetPixelWeight(des_row);
    233         pWeight->m_SrcStart = start_step;
    234         pWeight->m_SrcEnd = start_step;
    235         pWeight->m_Weights[0] = 65536;
    236         pWeight->m_Weights[1] = 0;
    237       }
    238       return;
    239     }
    240     int length = end_step - start_step;
    241     {
    242       PixelWeight* pWeight = GetPixelWeight(start_step);
    243       pWeight->m_SrcStart = start_step;
    244       pWeight->m_SrcEnd = start_step;
    245       pWeight->m_Weights[0] = 65536;
    246       pWeight->m_Weights[1] = 0;
    247     }
    248     for (int des_row = start_step + 1; des_row < end_step; des_row++) {
    249       PixelWeight* pWeight = GetPixelWeight(des_row);
    250       pWeight->m_SrcStart = start_step;
    251       pWeight->m_SrcEnd = end_step;
    252       pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) /
    253                                           (FX_FLOAT)length * 65536);
    254       pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
    255     }
    256   }
    257 }
    258 
    259 CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder(
    260     CCodec_ModuleMgr* pCodecMgr) {
    261   m_pFile = nullptr;
    262   m_pJpegContext = nullptr;
    263   m_pPngContext = nullptr;
    264   m_pGifContext = nullptr;
    265   m_pBmpContext = nullptr;
    266   m_pTiffContext = nullptr;
    267   m_pCodecMgr = nullptr;
    268   m_pSrcBuf = nullptr;
    269   m_pDecodeBuf = nullptr;
    270   m_pDeviceBitmap = nullptr;
    271   m_pSrcPalette = nullptr;
    272   m_pCodecMgr = pCodecMgr;
    273   m_offSet = 0;
    274   m_SrcSize = 0;
    275   m_ScanlineSize = 0;
    276   m_SrcWidth = 0;
    277   m_SrcHeight = 0;
    278   m_SrcComponents = 0;
    279   m_SrcBPC = 0;
    280   m_SrcPassNumber = 0;
    281   m_clipBox = FX_RECT(0, 0, 0, 0);
    282   m_imagType = FXCODEC_IMAGE_UNKNOWN;
    283   m_status = FXCODEC_STATUS_DECODE_FINISH;
    284   m_TransMethod = -1;
    285   m_SrcRow = 0;
    286   m_SrcFormat = FXCodec_Invalid;
    287   m_bInterpol = true;
    288   m_FrameNumber = 0;
    289   m_FrameCur = 0;
    290   m_SrcPaletteNumber = 0;
    291   m_GifPltNumber = 0;
    292   m_GifBgIndex = 0;
    293   m_pGifPalette = nullptr;
    294   m_GifTransIndex = -1;
    295   m_GifFrameRect = FX_RECT(0, 0, 0, 0);
    296   m_BmpIsTopBottom = false;
    297 }
    298 
    299 CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() {
    300   m_pFile = nullptr;
    301   if (m_pJpegContext)
    302     m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext);
    303   if (m_pBmpContext)
    304     m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext);
    305   if (m_pGifContext)
    306     m_pCodecMgr->GetGifModule()->Finish(m_pGifContext);
    307   if (m_pPngContext)
    308     m_pCodecMgr->GetPngModule()->Finish(m_pPngContext);
    309   if (m_pTiffContext)
    310     m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext);
    311   FX_Free(m_pSrcBuf);
    312   FX_Free(m_pDecodeBuf);
    313   FX_Free(m_pSrcPalette);
    314 }
    315 
    316 bool CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule,
    317                                                  FXCODEC_STATUS& err_status) {
    318   uint32_t dwSize = (uint32_t)m_pFile->GetSize();
    319   if (dwSize <= m_offSet) {
    320     return false;
    321   }
    322   dwSize = dwSize - m_offSet;
    323   uint32_t dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, nullptr);
    324   if (dwAvail == m_SrcSize) {
    325     if (dwSize > FXCODEC_BLOCK_SIZE) {
    326       dwSize = FXCODEC_BLOCK_SIZE;
    327     }
    328     m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) /
    329                 FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;
    330     m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize);
    331     if (!m_pSrcBuf) {
    332       err_status = FXCODEC_STATUS_ERR_MEMORY;
    333       return false;
    334     }
    335   } else {
    336     uint32_t dwConsume = m_SrcSize - dwAvail;
    337     if (dwAvail) {
    338       FXSYS_memmove(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);
    339     }
    340     if (dwSize > dwConsume) {
    341       dwSize = dwConsume;
    342     }
    343   }
    344   if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {
    345     err_status = FXCODEC_STATUS_ERR_READ;
    346     return false;
    347   }
    348   m_offSet += dwSize;
    349   pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail);
    350   return true;
    351 }
    352 
    353 bool CCodec_ProgressiveDecoder::PngReadHeader(int width,
    354                                               int height,
    355                                               int bpc,
    356                                               int pass,
    357                                               int* color_type,
    358                                               double* gamma) {
    359   if (!m_pDeviceBitmap) {
    360     m_SrcWidth = width;
    361     m_SrcHeight = height;
    362     m_SrcBPC = bpc;
    363     m_SrcPassNumber = pass;
    364     switch (*color_type) {
    365       case 0:
    366         m_SrcComponents = 1;
    367         break;
    368       case 4:
    369         m_SrcComponents = 2;
    370         break;
    371       case 2:
    372         m_SrcComponents = 3;
    373         break;
    374       case 3:
    375       case 6:
    376         m_SrcComponents = 4;
    377         break;
    378       default:
    379         m_SrcComponents = 0;
    380         break;
    381     }
    382     m_clipBox = FX_RECT(0, 0, width, height);
    383     return false;
    384   }
    385   FXDIB_Format format = m_pDeviceBitmap->GetFormat();
    386   switch (format) {
    387     case FXDIB_1bppMask:
    388     case FXDIB_1bppRgb:
    389       ASSERT(false);
    390       return false;
    391     case FXDIB_8bppMask:
    392     case FXDIB_8bppRgb:
    393       *color_type = 0;
    394       break;
    395     case FXDIB_Rgb:
    396       *color_type = 2;
    397       break;
    398     case FXDIB_Rgb32:
    399     case FXDIB_Argb:
    400       *color_type = 6;
    401       break;
    402     default:
    403       ASSERT(false);
    404       return false;
    405   }
    406   *gamma = kPngGamma;
    407   return true;
    408 }
    409 
    410 bool CCodec_ProgressiveDecoder::PngAskScanlineBuf(int line, uint8_t*& src_buf) {
    411   CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap;
    412   if (!pDIBitmap) {
    413     ASSERT(false);
    414     return false;
    415   }
    416   if (line >= m_clipBox.top && line < m_clipBox.bottom) {
    417     double scale_y = (double)m_sizeY / (double)m_clipBox.Height();
    418     int32_t row = (int32_t)((line - m_clipBox.top) * scale_y) + m_startY;
    419     uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row);
    420     uint8_t* des_scan = m_pDecodeBuf;
    421     src_buf = m_pDecodeBuf;
    422     int32_t src_Bpp = pDIBitmap->GetBPP() >> 3;
    423     int32_t des_Bpp = (m_SrcFormat & 0xff) >> 3;
    424     int32_t src_left = m_startX;
    425     int32_t des_left = m_clipBox.left;
    426     src_scan += src_left * src_Bpp;
    427     des_scan += des_left * des_Bpp;
    428     for (int32_t src_col = 0; src_col < m_sizeX; src_col++) {
    429       PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col);
    430       if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) {
    431         continue;
    432       }
    433       switch (pDIBitmap->GetFormat()) {
    434         case FXDIB_1bppMask:
    435         case FXDIB_1bppRgb:
    436           ASSERT(false);
    437           return false;
    438         case FXDIB_8bppMask:
    439         case FXDIB_8bppRgb: {
    440           if (pDIBitmap->GetPalette()) {
    441             return false;
    442           }
    443           uint32_t des_g = 0;
    444           des_g += pPixelWeights->m_Weights[0] * src_scan[src_col];
    445           des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16);
    446         } break;
    447         case FXDIB_Rgb:
    448         case FXDIB_Rgb32: {
    449           uint32_t des_b = 0, des_g = 0, des_r = 0;
    450           const uint8_t* p = src_scan + src_col * src_Bpp;
    451           des_b += pPixelWeights->m_Weights[0] * (*p++);
    452           des_g += pPixelWeights->m_Weights[0] * (*p++);
    453           des_r += pPixelWeights->m_Weights[0] * (*p);
    454           uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp];
    455           *pDes++ = (uint8_t)((des_b) >> 16);
    456           *pDes++ = (uint8_t)((des_g) >> 16);
    457           *pDes = (uint8_t)((des_r) >> 16);
    458         } break;
    459         case FXDIB_Argb: {
    460           uint32_t des_r = 0, des_g = 0, des_b = 0;
    461           const uint8_t* p = src_scan + src_col * src_Bpp;
    462           des_b += pPixelWeights->m_Weights[0] * (*p++);
    463           des_g += pPixelWeights->m_Weights[0] * (*p++);
    464           des_r += pPixelWeights->m_Weights[0] * (*p++);
    465           uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp];
    466           *pDes++ = (uint8_t)((des_b) >> 16);
    467           *pDes++ = (uint8_t)((des_g) >> 16);
    468           *pDes++ = (uint8_t)((des_r) >> 16);
    469           *pDes = *p;
    470         } break;
    471         default:
    472           return false;
    473       }
    474     }
    475   }
    476   return true;
    477 }
    478 
    479 void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz(
    480     CFX_DIBitmap* pDeviceBitmap,
    481     int32_t des_line,
    482     uint8_t* src_scan,
    483     FXCodec_Format src_format) {
    484   uint8_t* des_scan = (uint8_t*)pDeviceBitmap->GetScanline(des_line);
    485   int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3;
    486   int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3;
    487   int32_t src_left = m_clipBox.left;
    488   int32_t des_left = m_startX;
    489   src_scan += src_left * src_Bpp;
    490   des_scan += des_left * des_Bpp;
    491   for (int32_t des_col = 0; des_col < m_sizeX; des_col++) {
    492     PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col);
    493     switch (pDeviceBitmap->GetFormat()) {
    494       case FXDIB_1bppMask:
    495       case FXDIB_1bppRgb:
    496         ASSERT(false);
    497         return;
    498       case FXDIB_8bppMask:
    499       case FXDIB_8bppRgb: {
    500         if (pDeviceBitmap->GetPalette()) {
    501           return;
    502         }
    503         uint32_t des_g = 0;
    504         des_g +=
    505             pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart];
    506         des_g +=
    507             pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd];
    508         *des_scan++ = (uint8_t)(des_g >> 16);
    509       } break;
    510       case FXDIB_Rgb:
    511       case FXDIB_Rgb32: {
    512         uint32_t des_b = 0, des_g = 0, des_r = 0;
    513         const uint8_t* p = src_scan;
    514         p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
    515         des_b += pPixelWeights->m_Weights[0] * (*p++);
    516         des_g += pPixelWeights->m_Weights[0] * (*p++);
    517         des_r += pPixelWeights->m_Weights[0] * (*p);
    518         p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
    519         des_b += pPixelWeights->m_Weights[1] * (*p++);
    520         des_g += pPixelWeights->m_Weights[1] * (*p++);
    521         des_r += pPixelWeights->m_Weights[1] * (*p);
    522         *des_scan++ = (uint8_t)((des_b) >> 16);
    523         *des_scan++ = (uint8_t)((des_g) >> 16);
    524         *des_scan++ = (uint8_t)((des_r) >> 16);
    525         des_scan += des_Bpp - 3;
    526       } break;
    527       case FXDIB_Argb: {
    528         uint32_t des_a = 0, des_b = 0, des_g = 0, des_r = 0;
    529         const uint8_t* p = src_scan;
    530         p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
    531         des_b += pPixelWeights->m_Weights[0] * (*p++);
    532         des_g += pPixelWeights->m_Weights[0] * (*p++);
    533         des_r += pPixelWeights->m_Weights[0] * (*p++);
    534         des_a += pPixelWeights->m_Weights[0] * (*p);
    535         p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
    536         des_b += pPixelWeights->m_Weights[1] * (*p++);
    537         des_g += pPixelWeights->m_Weights[1] * (*p++);
    538         des_r += pPixelWeights->m_Weights[1] * (*p++);
    539         des_a += pPixelWeights->m_Weights[1] * (*p);
    540         *des_scan++ = (uint8_t)((des_b) >> 16);
    541         *des_scan++ = (uint8_t)((des_g) >> 16);
    542         *des_scan++ = (uint8_t)((des_r) >> 16);
    543         *des_scan++ = (uint8_t)((des_a) >> 16);
    544       } break;
    545       default:
    546         return;
    547     }
    548   }
    549 }
    550 
    551 void CCodec_ProgressiveDecoder::PngFillScanlineBufCompleted(int pass,
    552                                                             int line) {
    553   CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap;
    554   ASSERT(pDIBitmap);
    555   int src_top = m_clipBox.top;
    556   int src_bottom = m_clipBox.bottom;
    557   int des_top = m_startY;
    558   int src_hei = m_clipBox.Height();
    559   int des_hei = m_sizeY;
    560   if (line >= src_top && line < src_bottom) {
    561     double scale_y = (double)des_hei / (double)src_hei;
    562     int src_row = line - src_top;
    563     int des_row = (int)(src_row * scale_y) + des_top;
    564     if (des_row >= des_top + des_hei) {
    565       return;
    566     }
    567     PngOneOneMapResampleHorz(pDIBitmap, des_row, m_pDecodeBuf, m_SrcFormat);
    568     if (m_SrcPassNumber == 1 && scale_y > 1.0) {
    569       ResampleVert(pDIBitmap, scale_y, des_row);
    570       return;
    571     }
    572     if (pass == 6 && scale_y > 1.0) {
    573       ResampleVert(pDIBitmap, scale_y, des_row);
    574     }
    575   }
    576 }
    577 
    578 bool CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule,
    579                                                 FXCODEC_STATUS& err_status) {
    580   uint32_t dwSize = (uint32_t)m_pFile->GetSize();
    581   if (dwSize <= m_offSet) {
    582     return false;
    583   }
    584   dwSize = dwSize - m_offSet;
    585   uint32_t dwAvail = pGifModule->GetAvailInput(m_pGifContext, nullptr);
    586   if (dwAvail == m_SrcSize) {
    587     if (dwSize > FXCODEC_BLOCK_SIZE) {
    588       dwSize = FXCODEC_BLOCK_SIZE;
    589     }
    590     m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) /
    591                 FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;
    592     m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize);
    593     if (!m_pSrcBuf) {
    594       err_status = FXCODEC_STATUS_ERR_MEMORY;
    595       return false;
    596     }
    597   } else {
    598     uint32_t dwConsume = m_SrcSize - dwAvail;
    599     if (dwAvail) {
    600       FXSYS_memmove(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);
    601     }
    602     if (dwSize > dwConsume) {
    603       dwSize = dwConsume;
    604     }
    605   }
    606   if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {
    607     err_status = FXCODEC_STATUS_ERR_READ;
    608     return false;
    609   }
    610   m_offSet += dwSize;
    611   pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail);
    612   return true;
    613 }
    614 
    615 void CCodec_ProgressiveDecoder::GifRecordCurrentPosition(uint32_t& cur_pos) {
    616   uint32_t remain_size =
    617       m_pCodecMgr->GetGifModule()->GetAvailInput(m_pGifContext);
    618   cur_pos = m_offSet - remain_size;
    619 }
    620 
    621 uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBuf(int32_t frame_num,
    622                                                           int32_t pal_size) {
    623   return FX_Alloc(uint8_t, pal_size);
    624 }
    625 
    626 bool CCodec_ProgressiveDecoder::GifInputRecordPositionBuf(
    627     uint32_t rcd_pos,
    628     const FX_RECT& img_rc,
    629     int32_t pal_num,
    630     void* pal_ptr,
    631     int32_t delay_time,
    632     bool user_input,
    633     int32_t trans_index,
    634     int32_t disposal_method,
    635     bool interlace) {
    636   m_offSet = rcd_pos;
    637   FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
    638   if (!GifReadMoreData(m_pCodecMgr->GetGifModule(), error_status)) {
    639     return false;
    640   }
    641   uint8_t* pPalette = nullptr;
    642   if (pal_num != 0 && pal_ptr) {
    643     pPalette = (uint8_t*)pal_ptr;
    644   } else {
    645     pal_num = m_GifPltNumber;
    646     pPalette = m_pGifPalette;
    647   }
    648   if (!m_pSrcPalette)
    649     m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num);
    650   else if (pal_num > m_SrcPaletteNumber)
    651     m_pSrcPalette = FX_Realloc(FX_ARGB, m_pSrcPalette, pal_num);
    652   if (!m_pSrcPalette)
    653     return false;
    654 
    655   m_SrcPaletteNumber = pal_num;
    656   for (int i = 0; i < pal_num; i++) {
    657     uint32_t j = i * 3;
    658     m_pSrcPalette[i] =
    659         ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]);
    660   }
    661   m_GifTransIndex = trans_index;
    662   m_GifFrameRect = img_rc;
    663   m_SrcPassNumber = interlace ? 4 : 1;
    664   int32_t pal_index = m_GifBgIndex;
    665   CFX_DIBitmap* pDevice = m_pDeviceBitmap;
    666   if (trans_index >= pal_num)
    667     trans_index = -1;
    668   if (trans_index != -1) {
    669     m_pSrcPalette[trans_index] &= 0x00ffffff;
    670     if (pDevice->HasAlpha())
    671       pal_index = trans_index;
    672   }
    673   if (pal_index >= pal_num)
    674     return false;
    675 
    676   int startX = m_startX;
    677   int startY = m_startY;
    678   int sizeX = m_sizeX;
    679   int sizeY = m_sizeY;
    680   int Bpp = pDevice->GetBPP() / 8;
    681   FX_ARGB argb = m_pSrcPalette[pal_index];
    682   for (int row = 0; row < sizeY; row++) {
    683     uint8_t* pScanline =
    684         (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp;
    685     switch (m_TransMethod) {
    686       case 3: {
    687         uint8_t gray =
    688             FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
    689         FXSYS_memset(pScanline, gray, sizeX);
    690         break;
    691       }
    692       case 8: {
    693         for (int col = 0; col < sizeX; col++) {
    694           *pScanline++ = FXARGB_B(argb);
    695           *pScanline++ = FXARGB_G(argb);
    696           *pScanline++ = FXARGB_R(argb);
    697           pScanline += Bpp - 3;
    698         }
    699         break;
    700       }
    701       case 12: {
    702         for (int col = 0; col < sizeX; col++) {
    703           FXARGB_SETDIB(pScanline, argb);
    704           pScanline += 4;
    705         }
    706         break;
    707       }
    708     }
    709   }
    710   return true;
    711 }
    712 
    713 void CCodec_ProgressiveDecoder::GifReadScanline(int32_t row_num,
    714                                                 uint8_t* row_buf) {
    715   CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap;
    716   ASSERT(pDIBitmap);
    717   int32_t img_width = m_GifFrameRect.Width();
    718   if (!pDIBitmap->HasAlpha()) {
    719     uint8_t* byte_ptr = row_buf;
    720     for (int i = 0; i < img_width; i++) {
    721       if (*byte_ptr == m_GifTransIndex) {
    722         *byte_ptr = m_GifBgIndex;
    723       }
    724       byte_ptr++;
    725     }
    726   }
    727   int32_t pal_index = m_GifBgIndex;
    728   if (m_GifTransIndex != -1 && m_pDeviceBitmap->HasAlpha()) {
    729     pal_index = m_GifTransIndex;
    730   }
    731   FXSYS_memset(m_pDecodeBuf, pal_index, m_SrcWidth);
    732   bool bLastPass = (row_num % 2) == 1;
    733   int32_t line = row_num + m_GifFrameRect.top;
    734   int32_t left = m_GifFrameRect.left;
    735   FXSYS_memcpy(m_pDecodeBuf + left, row_buf, img_width);
    736   int src_top = m_clipBox.top;
    737   int src_bottom = m_clipBox.bottom;
    738   int des_top = m_startY;
    739   int src_hei = m_clipBox.Height();
    740   int des_hei = m_sizeY;
    741   if (line < src_top || line >= src_bottom)
    742     return;
    743 
    744   double scale_y = (double)des_hei / (double)src_hei;
    745   int src_row = line - src_top;
    746   int des_row = (int)(src_row * scale_y) + des_top;
    747   if (des_row >= des_top + des_hei)
    748     return;
    749 
    750   ReSampleScanline(pDIBitmap, des_row, m_pDecodeBuf, m_SrcFormat);
    751   if (scale_y > 1.0 && (!m_bInterpol || m_SrcPassNumber == 1)) {
    752     ResampleVert(pDIBitmap, scale_y, des_row);
    753     return;
    754   }
    755   if (scale_y <= 1.0)
    756     return;
    757 
    758   int des_bottom = des_top + m_sizeY;
    759   int des_Bpp = pDIBitmap->GetBPP() >> 3;
    760   uint32_t des_ScanOffet = m_startX * des_Bpp;
    761   if (des_row + (int)scale_y >= des_bottom - 1) {
    762     uint8_t* scan_src =
    763         (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet;
    764     int cur_row = des_row;
    765     while (++cur_row < des_bottom) {
    766       uint8_t* scan_des =
    767           (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet;
    768       uint32_t size = m_sizeX * des_Bpp;
    769       FXSYS_memmove(scan_des, scan_src, size);
    770     }
    771   }
    772   if (bLastPass)
    773     GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row);
    774 }
    775 
    776 void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert(
    777     CFX_DIBitmap* pDeviceBitmap,
    778     double scale_y,
    779     int des_row) {
    780   int des_Bpp = pDeviceBitmap->GetBPP() >> 3;
    781   uint32_t des_ScanOffet = m_startX * des_Bpp;
    782   int des_top = m_startY;
    783   pdfium::base::CheckedNumeric<double> scale_y2 = scale_y;
    784   scale_y2 *= 2;
    785   pdfium::base::CheckedNumeric<int> check_des_row_1 = des_row;
    786   check_des_row_1 -= scale_y2.ValueOrDie();
    787   int des_row_1 = check_des_row_1.ValueOrDie();
    788   des_row_1 = std::max(des_row_1, des_top);
    789   for (; des_row_1 < des_row; des_row_1++) {
    790     uint8_t* scan_des =
    791         (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;
    792     PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);
    793     const uint8_t* scan_src1 =
    794         pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) +
    795         des_ScanOffet;
    796     const uint8_t* scan_src2 =
    797         pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;
    798     for (int des_col = 0; des_col < m_sizeX; des_col++) {
    799       switch (pDeviceBitmap->GetFormat()) {
    800         case FXDIB_Invalid:
    801         case FXDIB_1bppMask:
    802         case FXDIB_1bppRgb:
    803           return;
    804         case FXDIB_8bppMask:
    805         case FXDIB_8bppRgb: {
    806           if (pDeviceBitmap->GetPalette()) {
    807             return;
    808           }
    809           int des_g = 0;
    810           des_g += pWeight->m_Weights[0] * (*scan_src1++);
    811           des_g += pWeight->m_Weights[1] * (*scan_src2++);
    812           *scan_des++ = (uint8_t)(des_g >> 16);
    813         } break;
    814         case FXDIB_Rgb:
    815         case FXDIB_Rgb32: {
    816           uint32_t des_b = 0, des_g = 0, des_r = 0;
    817           des_b += pWeight->m_Weights[0] * (*scan_src1++);
    818           des_g += pWeight->m_Weights[0] * (*scan_src1++);
    819           des_r += pWeight->m_Weights[0] * (*scan_src1++);
    820           scan_src1 += des_Bpp - 3;
    821           des_b += pWeight->m_Weights[1] * (*scan_src2++);
    822           des_g += pWeight->m_Weights[1] * (*scan_src2++);
    823           des_r += pWeight->m_Weights[1] * (*scan_src2++);
    824           scan_src2 += des_Bpp - 3;
    825           *scan_des++ = (uint8_t)((des_b) >> 16);
    826           *scan_des++ = (uint8_t)((des_g) >> 16);
    827           *scan_des++ = (uint8_t)((des_r) >> 16);
    828           scan_des += des_Bpp - 3;
    829         } break;
    830         case FXDIB_Argb: {
    831           uint32_t des_a = 0, des_b = 0, des_g = 0, des_r = 0;
    832           des_b += pWeight->m_Weights[0] * (*scan_src1++);
    833           des_g += pWeight->m_Weights[0] * (*scan_src1++);
    834           des_r += pWeight->m_Weights[0] * (*scan_src1++);
    835           des_a += pWeight->m_Weights[0] * (*scan_src1++);
    836           des_b += pWeight->m_Weights[1] * (*scan_src2++);
    837           des_g += pWeight->m_Weights[1] * (*scan_src2++);
    838           des_r += pWeight->m_Weights[1] * (*scan_src2++);
    839           des_a += pWeight->m_Weights[1] * (*scan_src2++);
    840           *scan_des++ = (uint8_t)((des_b) >> 16);
    841           *scan_des++ = (uint8_t)((des_g) >> 16);
    842           *scan_des++ = (uint8_t)((des_r) >> 16);
    843           *scan_des++ = (uint8_t)((des_a) >> 16);
    844         } break;
    845         default:
    846           return;
    847       }
    848     }
    849   }
    850   int des_bottom = des_top + m_sizeY - 1;
    851   if (des_row + (int)(2 * scale_y) >= des_bottom &&
    852       des_row + (int)scale_y < des_bottom) {
    853     GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y);
    854   }
    855 }
    856 
    857 bool CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule,
    858                                                 FXCODEC_STATUS& err_status) {
    859   uint32_t dwSize = (uint32_t)m_pFile->GetSize();
    860   if (dwSize <= m_offSet)
    861     return false;
    862 
    863   dwSize = dwSize - m_offSet;
    864   uint32_t dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, nullptr);
    865   if (dwAvail == m_SrcSize) {
    866     if (dwSize > FXCODEC_BLOCK_SIZE) {
    867       dwSize = FXCODEC_BLOCK_SIZE;
    868     }
    869     m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) /
    870                 FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;
    871     m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize);
    872     if (!m_pSrcBuf) {
    873       err_status = FXCODEC_STATUS_ERR_MEMORY;
    874       return false;
    875     }
    876   } else {
    877     uint32_t dwConsume = m_SrcSize - dwAvail;
    878     if (dwAvail) {
    879       FXSYS_memmove(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);
    880     }
    881     if (dwSize > dwConsume) {
    882       dwSize = dwConsume;
    883     }
    884   }
    885   if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {
    886     err_status = FXCODEC_STATUS_ERR_READ;
    887     return false;
    888   }
    889   m_offSet += dwSize;
    890   pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail);
    891   return true;
    892 }
    893 
    894 bool CCodec_ProgressiveDecoder::BmpInputImagePositionBuf(uint32_t rcd_pos) {
    895   m_offSet = rcd_pos;
    896   FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
    897   return BmpReadMoreData(m_pCodecMgr->GetBmpModule(), error_status);
    898 }
    899 
    900 void CCodec_ProgressiveDecoder::BmpReadScanline(int32_t row_num,
    901                                                 uint8_t* row_buf) {
    902   CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap;
    903   ASSERT(pDIBitmap);
    904   FXSYS_memcpy(m_pDecodeBuf, row_buf, m_ScanlineSize);
    905   int src_top = m_clipBox.top;
    906   int src_bottom = m_clipBox.bottom;
    907   int des_top = m_startY;
    908   int src_hei = m_clipBox.Height();
    909   int des_hei = m_sizeY;
    910   if (row_num < src_top || row_num >= src_bottom)
    911     return;
    912 
    913   double scale_y = (double)des_hei / (double)src_hei;
    914   int src_row = row_num - src_top;
    915   int des_row = (int)(src_row * scale_y) + des_top;
    916   if (des_row >= des_top + des_hei)
    917     return;
    918 
    919   ReSampleScanline(pDIBitmap, des_row, m_pDecodeBuf, m_SrcFormat);
    920   if (scale_y <= 1.0)
    921     return;
    922 
    923   if (m_BmpIsTopBottom || !m_bInterpol) {
    924     ResampleVert(pDIBitmap, scale_y, des_row);
    925     return;
    926   }
    927   ResampleVertBT(pDIBitmap, scale_y, des_row);
    928 }
    929 
    930 void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap,
    931                                                double scale_y,
    932                                                int des_row) {
    933   int des_Bpp = pDeviceBitmap->GetBPP() >> 3;
    934   uint32_t des_ScanOffet = m_startX * des_Bpp;
    935   int des_top = m_startY;
    936   int des_bottom = m_startY + m_sizeY;
    937   pdfium::base::CheckedNumeric<int> check_des_row_1 = des_row;
    938   check_des_row_1 += pdfium::base::checked_cast<int>(scale_y);
    939   int des_row_1 = check_des_row_1.ValueOrDie();
    940   if (des_row_1 >= des_bottom - 1) {
    941     uint8_t* scan_src =
    942         (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
    943     while (++des_row < des_bottom) {
    944       uint8_t* scan_des =
    945           (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
    946       uint32_t size = m_sizeX * des_Bpp;
    947       FXSYS_memmove(scan_des, scan_src, size);
    948     }
    949     return;
    950   }
    951   for (; des_row_1 > des_row; des_row_1--) {
    952     uint8_t* scan_des =
    953         (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;
    954     PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);
    955     const uint8_t* scan_src1 =
    956         pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) +
    957         des_ScanOffet;
    958     const uint8_t* scan_src2 =
    959         pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;
    960     for (int des_col = 0; des_col < m_sizeX; des_col++) {
    961       switch (pDeviceBitmap->GetFormat()) {
    962         case FXDIB_Invalid:
    963         case FXDIB_1bppMask:
    964         case FXDIB_1bppRgb:
    965           return;
    966         case FXDIB_8bppMask:
    967         case FXDIB_8bppRgb: {
    968           if (pDeviceBitmap->GetPalette()) {
    969             return;
    970           }
    971           int des_g = 0;
    972           des_g += pWeight->m_Weights[0] * (*scan_src1++);
    973           des_g += pWeight->m_Weights[1] * (*scan_src2++);
    974           *scan_des++ = (uint8_t)(des_g >> 16);
    975         } break;
    976         case FXDIB_Rgb:
    977         case FXDIB_Rgb32: {
    978           uint32_t des_b = 0, des_g = 0, des_r = 0;
    979           des_b += pWeight->m_Weights[0] * (*scan_src1++);
    980           des_g += pWeight->m_Weights[0] * (*scan_src1++);
    981           des_r += pWeight->m_Weights[0] * (*scan_src1++);
    982           scan_src1 += des_Bpp - 3;
    983           des_b += pWeight->m_Weights[1] * (*scan_src2++);
    984           des_g += pWeight->m_Weights[1] * (*scan_src2++);
    985           des_r += pWeight->m_Weights[1] * (*scan_src2++);
    986           scan_src2 += des_Bpp - 3;
    987           *scan_des++ = (uint8_t)((des_b) >> 16);
    988           *scan_des++ = (uint8_t)((des_g) >> 16);
    989           *scan_des++ = (uint8_t)((des_r) >> 16);
    990           scan_des += des_Bpp - 3;
    991         } break;
    992         case FXDIB_Argb: {
    993           uint32_t des_a = 0, des_b = 0, des_g = 0, des_r = 0;
    994           des_b += pWeight->m_Weights[0] * (*scan_src1++);
    995           des_g += pWeight->m_Weights[0] * (*scan_src1++);
    996           des_r += pWeight->m_Weights[0] * (*scan_src1++);
    997           des_a += pWeight->m_Weights[0] * (*scan_src1++);
    998           des_b += pWeight->m_Weights[1] * (*scan_src2++);
    999           des_g += pWeight->m_Weights[1] * (*scan_src2++);
   1000           des_r += pWeight->m_Weights[1] * (*scan_src2++);
   1001           des_a += pWeight->m_Weights[1] * (*scan_src2++);
   1002           *scan_des++ = (uint8_t)((des_b) >> 16);
   1003           *scan_des++ = (uint8_t)((des_g) >> 16);
   1004           *scan_des++ = (uint8_t)((des_r) >> 16);
   1005           *scan_des++ = (uint8_t)((des_a) >> 16);
   1006         } break;
   1007         default:
   1008           return;
   1009       }
   1010     }
   1011   }
   1012 }
   1013 
   1014 bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
   1015                                                 CFX_DIBAttribute* pAttribute) {
   1016   m_offSet = 0;
   1017   uint32_t size = (uint32_t)m_pFile->GetSize();
   1018   if (size > FXCODEC_BLOCK_SIZE) {
   1019     size = FXCODEC_BLOCK_SIZE;
   1020   }
   1021   FX_Free(m_pSrcBuf);
   1022   m_pSrcBuf = FX_Alloc(uint8_t, size);
   1023   FXSYS_memset(m_pSrcBuf, 0, size);
   1024   m_SrcSize = size;
   1025   switch (imageType) {
   1026     case FXCODEC_IMAGE_BMP: {
   1027       ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
   1028       if (!pBmpModule) {
   1029         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1030         return false;
   1031       }
   1032       pBmpModule->SetDelegate(this);
   1033       m_pBmpContext = pBmpModule->Start();
   1034       if (!m_pBmpContext) {
   1035         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1036         return false;
   1037       }
   1038       bool bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
   1039       if (!bResult) {
   1040         m_status = FXCODEC_STATUS_ERR_READ;
   1041         return false;
   1042       }
   1043       m_offSet += size;
   1044       pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size);
   1045       uint32_t* pPalette = nullptr;
   1046       int32_t readResult = pBmpModule->ReadHeader(
   1047           m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,
   1048           &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute);
   1049       while (readResult == 2) {
   1050         FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
   1051         if (!BmpReadMoreData(pBmpModule, error_status)) {
   1052           m_status = error_status;
   1053           return false;
   1054         }
   1055         readResult = pBmpModule->ReadHeader(
   1056             m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,
   1057             &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute);
   1058       }
   1059       if (readResult == 1) {
   1060         m_SrcBPC = 8;
   1061         m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
   1062         FX_Free(m_pSrcPalette);
   1063         if (m_SrcPaletteNumber) {
   1064           m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber);
   1065           FXSYS_memcpy(m_pSrcPalette, pPalette,
   1066                        m_SrcPaletteNumber * sizeof(uint32_t));
   1067         } else {
   1068           m_pSrcPalette = nullptr;
   1069         }
   1070         return true;
   1071       }
   1072       if (m_pBmpContext) {
   1073         pBmpModule->Finish(m_pBmpContext);
   1074         m_pBmpContext = nullptr;
   1075       }
   1076       m_status = FXCODEC_STATUS_ERR_FORMAT;
   1077       return false;
   1078     }
   1079     case FXCODEC_IMAGE_JPG: {
   1080       CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
   1081       if (!pJpegModule) {
   1082         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1083         return false;
   1084       }
   1085       m_pJpegContext = pJpegModule->Start();
   1086       if (!m_pJpegContext) {
   1087         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1088         return false;
   1089       }
   1090       bool bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
   1091       if (!bResult) {
   1092         m_status = FXCODEC_STATUS_ERR_READ;
   1093         return false;
   1094       }
   1095       m_offSet += size;
   1096       pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size);
   1097       int32_t readResult =
   1098           pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight,
   1099                                   &m_SrcComponents, pAttribute);
   1100       while (readResult == 2) {
   1101         FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
   1102         if (!JpegReadMoreData(pJpegModule, error_status)) {
   1103           m_status = error_status;
   1104           return false;
   1105         }
   1106         readResult =
   1107             pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight,
   1108                                     &m_SrcComponents, pAttribute);
   1109       }
   1110       if (!readResult) {
   1111         m_SrcBPC = 8;
   1112         m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
   1113         return true;
   1114       }
   1115       if (m_pJpegContext) {
   1116         pJpegModule->Finish(m_pJpegContext);
   1117         m_pJpegContext = nullptr;
   1118       }
   1119       m_status = FXCODEC_STATUS_ERR_FORMAT;
   1120       return false;
   1121     }
   1122     case FXCODEC_IMAGE_PNG: {
   1123       ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
   1124       if (!pPngModule) {
   1125         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1126         return false;
   1127       }
   1128       pPngModule->SetDelegate(this);
   1129       m_pPngContext = pPngModule->Start();
   1130       if (!m_pPngContext) {
   1131         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1132         return false;
   1133       }
   1134       bool bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
   1135       if (!bResult) {
   1136         m_status = FXCODEC_STATUS_ERR_READ;
   1137         return false;
   1138       }
   1139       m_offSet += size;
   1140       bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute);
   1141       while (bResult) {
   1142         uint32_t remain_size = (uint32_t)m_pFile->GetSize() - m_offSet;
   1143         uint32_t input_size =
   1144             remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
   1145         if (input_size == 0) {
   1146           if (m_pPngContext) {
   1147             pPngModule->Finish(m_pPngContext);
   1148           }
   1149           m_pPngContext = nullptr;
   1150           m_status = FXCODEC_STATUS_ERR_FORMAT;
   1151           return false;
   1152         }
   1153         if (m_pSrcBuf && input_size > m_SrcSize) {
   1154           FX_Free(m_pSrcBuf);
   1155           m_pSrcBuf = FX_Alloc(uint8_t, input_size);
   1156           FXSYS_memset(m_pSrcBuf, 0, input_size);
   1157           m_SrcSize = input_size;
   1158         }
   1159         bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);
   1160         if (!bResult) {
   1161           m_status = FXCODEC_STATUS_ERR_READ;
   1162           return false;
   1163         }
   1164         m_offSet += input_size;
   1165         bResult =
   1166             pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute);
   1167       }
   1168       ASSERT(!bResult);
   1169       if (m_pPngContext) {
   1170         pPngModule->Finish(m_pPngContext);
   1171         m_pPngContext = nullptr;
   1172       }
   1173       if (m_SrcPassNumber == 0) {
   1174         m_status = FXCODEC_STATUS_ERR_FORMAT;
   1175         return false;
   1176       }
   1177       return true;
   1178     }
   1179     case FXCODEC_IMAGE_GIF: {
   1180       ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
   1181       if (!pGifModule) {
   1182         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1183         return false;
   1184       }
   1185       pGifModule->SetDelegate(this);
   1186       m_pGifContext = pGifModule->Start();
   1187       if (!m_pGifContext) {
   1188         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1189         return false;
   1190       }
   1191       bool bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
   1192       if (!bResult) {
   1193         m_status = FXCODEC_STATUS_ERR_READ;
   1194         return false;
   1195       }
   1196       m_offSet += size;
   1197       pGifModule->Input(m_pGifContext, m_pSrcBuf, size);
   1198       m_SrcComponents = 1;
   1199       int32_t readResult = pGifModule->ReadHeader(
   1200           m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
   1201           (void**)&m_pGifPalette, &m_GifBgIndex, nullptr);
   1202       while (readResult == 2) {
   1203         FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
   1204         if (!GifReadMoreData(pGifModule, error_status)) {
   1205           m_status = error_status;
   1206           return false;
   1207         }
   1208         readResult = pGifModule->ReadHeader(
   1209             m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
   1210             (void**)&m_pGifPalette, &m_GifBgIndex, nullptr);
   1211       }
   1212       if (readResult == 1) {
   1213         m_SrcBPC = 8;
   1214         m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
   1215         return true;
   1216       }
   1217       if (m_pGifContext) {
   1218         pGifModule->Finish(m_pGifContext);
   1219         m_pGifContext = nullptr;
   1220       }
   1221       m_status = FXCODEC_STATUS_ERR_FORMAT;
   1222       return false;
   1223     }
   1224     case FXCODEC_IMAGE_TIF: {
   1225       ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
   1226       if (!pTiffModule) {
   1227         m_status = FXCODEC_STATUS_ERR_FORMAT;
   1228         return false;
   1229       }
   1230       m_pTiffContext = pTiffModule->CreateDecoder(m_pFile);
   1231       if (!m_pTiffContext) {
   1232         m_status = FXCODEC_STATUS_ERR_FORMAT;
   1233         return false;
   1234       }
   1235       int32_t dummy_bpc;
   1236       bool ret = pTiffModule->LoadFrameInfo(m_pTiffContext, 0, &m_SrcWidth,
   1237                                             &m_SrcHeight, &m_SrcComponents,
   1238                                             &dummy_bpc, pAttribute);
   1239       m_SrcComponents = 4;
   1240       m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
   1241       if (!ret) {
   1242         pTiffModule->DestroyDecoder(m_pTiffContext);
   1243         m_pTiffContext = nullptr;
   1244         m_status = FXCODEC_STATUS_ERR_FORMAT;
   1245         return false;
   1246       }
   1247       return true;
   1248     }
   1249     default:
   1250       m_status = FXCODEC_STATUS_ERR_FORMAT;
   1251       return false;
   1252   }
   1253 }
   1254 
   1255 FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(
   1256     const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
   1257     FXCODEC_IMAGE_TYPE imageType,
   1258     CFX_DIBAttribute* pAttribute,
   1259     bool bSkipImageTypeCheck) {
   1260   switch (m_status) {
   1261     case FXCODEC_STATUS_FRAME_READY:
   1262     case FXCODEC_STATUS_FRAME_TOBECONTINUE:
   1263     case FXCODEC_STATUS_DECODE_READY:
   1264     case FXCODEC_STATUS_DECODE_TOBECONTINUE:
   1265       return FXCODEC_STATUS_ERROR;
   1266     default:
   1267       break;
   1268   }
   1269   if (!pFile) {
   1270     m_status = FXCODEC_STATUS_ERR_PARAMS;
   1271     m_pFile = nullptr;
   1272     return m_status;
   1273   }
   1274   m_pFile = pFile;
   1275   m_offSet = 0;
   1276   m_SrcWidth = m_SrcHeight = 0;
   1277   m_SrcComponents = m_SrcBPC = 0;
   1278   m_clipBox = FX_RECT(0, 0, 0, 0);
   1279   m_startX = m_startY = 0;
   1280   m_sizeX = m_sizeY = 0;
   1281   m_SrcPassNumber = 0;
   1282   if (imageType != FXCODEC_IMAGE_UNKNOWN &&
   1283       DetectImageType(imageType, pAttribute)) {
   1284     m_imagType = imageType;
   1285     m_status = FXCODEC_STATUS_FRAME_READY;
   1286     return m_status;
   1287   }
   1288   // If we got here then the image data does not match the requested decoder.
   1289   // If we're skipping the type check then bail out at this point and return
   1290   // the failed status.
   1291   if (bSkipImageTypeCheck)
   1292     return m_status;
   1293 
   1294   for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) {
   1295     if (DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) {
   1296       m_imagType = (FXCODEC_IMAGE_TYPE)type;
   1297       m_status = FXCODEC_STATUS_FRAME_READY;
   1298       return m_status;
   1299     }
   1300   }
   1301   m_status = FXCODEC_STATUS_ERR_FORMAT;
   1302   m_pFile = nullptr;
   1303   return m_status;
   1304 }
   1305 
   1306 void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) {
   1307   if (m_status != FXCODEC_STATUS_FRAME_READY)
   1308     return;
   1309 
   1310   if (clip->IsEmpty()) {
   1311     m_clipBox = FX_RECT(0, 0, 0, 0);
   1312     return;
   1313   }
   1314   clip->left = std::max(clip->left, 0);
   1315   clip->right = std::min(clip->right, m_SrcWidth);
   1316   clip->top = std::max(clip->top, 0);
   1317   clip->bottom = std::min(clip->bottom, m_SrcHeight);
   1318   if (clip->IsEmpty()) {
   1319     m_clipBox = FX_RECT(0, 0, 0, 0);
   1320     return;
   1321   }
   1322   m_clipBox = *clip;
   1323 }
   1324 
   1325 void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale) {
   1326   down_scale = 1;
   1327   int ratio_w = m_clipBox.Width() / m_sizeX;
   1328   int ratio_h = m_clipBox.Height() / m_sizeY;
   1329   int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w;
   1330   if (ratio >= 8) {
   1331     down_scale = 8;
   1332   } else if (ratio >= 4) {
   1333     down_scale = 4;
   1334   } else if (ratio >= 2) {
   1335     down_scale = 2;
   1336   }
   1337   m_clipBox.left /= down_scale;
   1338   m_clipBox.right /= down_scale;
   1339   m_clipBox.top /= down_scale;
   1340   m_clipBox.bottom /= down_scale;
   1341   if (m_clipBox.right == m_clipBox.left) {
   1342     m_clipBox.right = m_clipBox.left + 1;
   1343   }
   1344   if (m_clipBox.bottom == m_clipBox.top) {
   1345     m_clipBox.bottom = m_clipBox.top + 1;
   1346   }
   1347 }
   1348 
   1349 void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format,
   1350                                                FXCodec_Format src_format) {
   1351   switch (des_format) {
   1352     case FXDIB_1bppMask:
   1353     case FXDIB_1bppRgb: {
   1354       switch (src_format) {
   1355         case FXCodec_1bppGray:
   1356           m_TransMethod = 0;
   1357           break;
   1358         default:
   1359           m_TransMethod = -1;
   1360       }
   1361     } break;
   1362     case FXDIB_8bppMask:
   1363     case FXDIB_8bppRgb: {
   1364       switch (src_format) {
   1365         case FXCodec_1bppGray:
   1366           m_TransMethod = 1;
   1367           break;
   1368         case FXCodec_8bppGray:
   1369           m_TransMethod = 2;
   1370           break;
   1371         case FXCodec_1bppRgb:
   1372         case FXCodec_8bppRgb:
   1373           m_TransMethod = 3;
   1374           break;
   1375         case FXCodec_Rgb:
   1376         case FXCodec_Rgb32:
   1377         case FXCodec_Argb:
   1378           m_TransMethod = 4;
   1379           break;
   1380         case FXCodec_Cmyk:
   1381           m_TransMethod = 5;
   1382           break;
   1383         default:
   1384           m_TransMethod = -1;
   1385       }
   1386     } break;
   1387     case FXDIB_Rgb: {
   1388       switch (src_format) {
   1389         case FXCodec_1bppGray:
   1390           m_TransMethod = 6;
   1391           break;
   1392         case FXCodec_8bppGray:
   1393           m_TransMethod = 7;
   1394           break;
   1395         case FXCodec_1bppRgb:
   1396         case FXCodec_8bppRgb:
   1397           m_TransMethod = 8;
   1398           break;
   1399         case FXCodec_Rgb:
   1400         case FXCodec_Rgb32:
   1401         case FXCodec_Argb:
   1402           m_TransMethod = 9;
   1403           break;
   1404         case FXCodec_Cmyk:
   1405           m_TransMethod = 10;
   1406           break;
   1407         default:
   1408           m_TransMethod = -1;
   1409       }
   1410     } break;
   1411     case FXDIB_Rgb32:
   1412     case FXDIB_Argb: {
   1413       switch (src_format) {
   1414         case FXCodec_1bppGray:
   1415           m_TransMethod = 6;
   1416           break;
   1417         case FXCodec_8bppGray:
   1418           m_TransMethod = 7;
   1419           break;
   1420         case FXCodec_1bppRgb:
   1421         case FXCodec_8bppRgb:
   1422           if (des_format == FXDIB_Argb) {
   1423             m_TransMethod = 12;
   1424           } else {
   1425             m_TransMethod = 8;
   1426           }
   1427           break;
   1428         case FXCodec_Rgb:
   1429         case FXCodec_Rgb32:
   1430           m_TransMethod = 9;
   1431           break;
   1432         case FXCodec_Cmyk:
   1433           m_TransMethod = 10;
   1434           break;
   1435         case FXCodec_Argb:
   1436           m_TransMethod = 11;
   1437           break;
   1438         default:
   1439           m_TransMethod = -1;
   1440       }
   1441     } break;
   1442     default:
   1443       m_TransMethod = -1;
   1444   }
   1445 }
   1446 
   1447 void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap,
   1448                                                  int des_line,
   1449                                                  uint8_t* src_scan,
   1450                                                  FXCodec_Format src_format) {
   1451   int src_left = m_clipBox.left;
   1452   int des_left = m_startX;
   1453   uint8_t* des_scan =
   1454       pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch();
   1455   int src_bpp = src_format & 0xff;
   1456   int des_bpp = pDeviceBitmap->GetBPP();
   1457   int src_Bpp = src_bpp >> 3;
   1458   int des_Bpp = des_bpp >> 3;
   1459   src_scan += src_left * src_Bpp;
   1460   des_scan += des_left * des_Bpp;
   1461   for (int des_col = 0; des_col < m_sizeX; des_col++) {
   1462     PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col);
   1463     switch (m_TransMethod) {
   1464       case -1:
   1465         return;
   1466       case 0:
   1467         return;
   1468       case 1:
   1469         return;
   1470       case 2: {
   1471         uint32_t des_g = 0;
   1472         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1473              j++) {
   1474           int pixel_weight =
   1475               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1476           des_g += pixel_weight * src_scan[j];
   1477         }
   1478         *des_scan++ = (uint8_t)(des_g >> 16);
   1479       } break;
   1480       case 3: {
   1481         int des_r = 0, des_g = 0, des_b = 0;
   1482         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1483              j++) {
   1484           int pixel_weight =
   1485               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1486           unsigned long argb = m_pSrcPalette[src_scan[j]];
   1487           des_r += pixel_weight * (uint8_t)(argb >> 16);
   1488           des_g += pixel_weight * (uint8_t)(argb >> 8);
   1489           des_b += pixel_weight * (uint8_t)argb;
   1490         }
   1491         *des_scan++ =
   1492             (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));
   1493       } break;
   1494       case 4: {
   1495         uint32_t des_b = 0, des_g = 0, des_r = 0;
   1496         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1497              j++) {
   1498           int pixel_weight =
   1499               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1500           const uint8_t* src_pixel = src_scan + j * src_Bpp;
   1501           des_b += pixel_weight * (*src_pixel++);
   1502           des_g += pixel_weight * (*src_pixel++);
   1503           des_r += pixel_weight * (*src_pixel);
   1504         }
   1505         *des_scan++ =
   1506             (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));
   1507       } break;
   1508       case 5: {
   1509         uint32_t des_b = 0, des_g = 0, des_r = 0;
   1510         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1511              j++) {
   1512           int pixel_weight =
   1513               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1514           const uint8_t* src_pixel = src_scan + j * src_Bpp;
   1515           uint8_t src_b = 0, src_g = 0, src_r = 0;
   1516           AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1],
   1517                              255 - src_pixel[2], 255 - src_pixel[3], src_r,
   1518                              src_g, src_b);
   1519           des_b += pixel_weight * src_b;
   1520           des_g += pixel_weight * src_g;
   1521           des_r += pixel_weight * src_r;
   1522         }
   1523         *des_scan++ =
   1524             (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));
   1525       } break;
   1526       case 6:
   1527         return;
   1528       case 7: {
   1529         uint32_t des_g = 0;
   1530         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1531              j++) {
   1532           int pixel_weight =
   1533               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1534           des_g += pixel_weight * src_scan[j];
   1535         }
   1536         FXSYS_memset(des_scan, (uint8_t)(des_g >> 16), 3);
   1537         des_scan += des_Bpp;
   1538       } break;
   1539       case 8: {
   1540         int des_r = 0, des_g = 0, des_b = 0;
   1541         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1542              j++) {
   1543           int pixel_weight =
   1544               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1545           unsigned long argb = m_pSrcPalette[src_scan[j]];
   1546           des_r += pixel_weight * (uint8_t)(argb >> 16);
   1547           des_g += pixel_weight * (uint8_t)(argb >> 8);
   1548           des_b += pixel_weight * (uint8_t)argb;
   1549         }
   1550         *des_scan++ = (uint8_t)((des_b) >> 16);
   1551         *des_scan++ = (uint8_t)((des_g) >> 16);
   1552         *des_scan++ = (uint8_t)((des_r) >> 16);
   1553         des_scan += des_Bpp - 3;
   1554       } break;
   1555       case 12: {
   1556         if (m_pBmpContext) {
   1557           int des_r = 0, des_g = 0, des_b = 0;
   1558           for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1559                j++) {
   1560             int pixel_weight =
   1561                 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1562             unsigned long argb = m_pSrcPalette[src_scan[j]];
   1563             des_r += pixel_weight * (uint8_t)(argb >> 16);
   1564             des_g += pixel_weight * (uint8_t)(argb >> 8);
   1565             des_b += pixel_weight * (uint8_t)argb;
   1566           }
   1567           *des_scan++ = (uint8_t)((des_b) >> 16);
   1568           *des_scan++ = (uint8_t)((des_g) >> 16);
   1569           *des_scan++ = (uint8_t)((des_r) >> 16);
   1570           *des_scan++ = 0xFF;
   1571         } else {
   1572           int des_a = 0, des_r = 0, des_g = 0, des_b = 0;
   1573           for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1574                j++) {
   1575             int pixel_weight =
   1576                 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1577             unsigned long argb = m_pSrcPalette[src_scan[j]];
   1578             des_a += pixel_weight * (uint8_t)(argb >> 24);
   1579             des_r += pixel_weight * (uint8_t)(argb >> 16);
   1580             des_g += pixel_weight * (uint8_t)(argb >> 8);
   1581             des_b += pixel_weight * (uint8_t)argb;
   1582           }
   1583           *des_scan++ = (uint8_t)((des_b) >> 16);
   1584           *des_scan++ = (uint8_t)((des_g) >> 16);
   1585           *des_scan++ = (uint8_t)((des_r) >> 16);
   1586           *des_scan++ = (uint8_t)((des_a) >> 16);
   1587         }
   1588       } break;
   1589       case 9: {
   1590         uint32_t des_b = 0, des_g = 0, des_r = 0;
   1591         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1592              j++) {
   1593           int pixel_weight =
   1594               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1595           const uint8_t* src_pixel = src_scan + j * src_Bpp;
   1596           des_b += pixel_weight * (*src_pixel++);
   1597           des_g += pixel_weight * (*src_pixel++);
   1598           des_r += pixel_weight * (*src_pixel);
   1599         }
   1600         *des_scan++ = (uint8_t)((des_b) >> 16);
   1601         *des_scan++ = (uint8_t)((des_g) >> 16);
   1602         *des_scan++ = (uint8_t)((des_r) >> 16);
   1603         des_scan += des_Bpp - 3;
   1604       } break;
   1605       case 10: {
   1606         uint32_t des_b = 0, des_g = 0, des_r = 0;
   1607         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1608              j++) {
   1609           int pixel_weight =
   1610               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1611           const uint8_t* src_pixel = src_scan + j * src_Bpp;
   1612           uint8_t src_b = 0, src_g = 0, src_r = 0;
   1613           AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1],
   1614                              255 - src_pixel[2], 255 - src_pixel[3], src_r,
   1615                              src_g, src_b);
   1616           des_b += pixel_weight * src_b;
   1617           des_g += pixel_weight * src_g;
   1618           des_r += pixel_weight * src_r;
   1619         }
   1620         *des_scan++ = (uint8_t)((des_b) >> 16);
   1621         *des_scan++ = (uint8_t)((des_g) >> 16);
   1622         *des_scan++ = (uint8_t)((des_r) >> 16);
   1623         des_scan += des_Bpp - 3;
   1624       } break;
   1625       case 11: {
   1626         uint32_t des_alpha = 0, des_r = 0, des_g = 0, des_b = 0;
   1627         for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
   1628              j++) {
   1629           int pixel_weight =
   1630               pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
   1631           const uint8_t* src_pixel = src_scan + j * src_Bpp;
   1632           pixel_weight = pixel_weight * src_pixel[3] / 255;
   1633           des_b += pixel_weight * (*src_pixel++);
   1634           des_g += pixel_weight * (*src_pixel++);
   1635           des_r += pixel_weight * (*src_pixel);
   1636           des_alpha += pixel_weight;
   1637         }
   1638         *des_scan++ = (uint8_t)((des_b) >> 16);
   1639         *des_scan++ = (uint8_t)((des_g) >> 16);
   1640         *des_scan++ = (uint8_t)((des_r) >> 16);
   1641         *des_scan++ = (uint8_t)((des_alpha * 255) >> 16);
   1642       } break;
   1643       default:
   1644         return;
   1645     }
   1646   }
   1647 }
   1648 
   1649 void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap,
   1650                                              double scale_y,
   1651                                              int des_row) {
   1652   int des_Bpp = pDeviceBitmap->GetBPP() >> 3;
   1653   uint32_t des_ScanOffet = m_startX * des_Bpp;
   1654   if (m_bInterpol) {
   1655     int des_top = m_startY;
   1656     pdfium::base::CheckedNumeric<int> check_des_row_1 = des_row;
   1657     check_des_row_1 -= pdfium::base::checked_cast<int>(scale_y);
   1658     int des_row_1 = check_des_row_1.ValueOrDie();
   1659     if (des_row_1 < des_top) {
   1660       int des_bottom = des_top + m_sizeY;
   1661       if (des_row + (int)scale_y >= des_bottom - 1) {
   1662         uint8_t* scan_src =
   1663             (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
   1664         while (++des_row < des_bottom) {
   1665           uint8_t* scan_des =
   1666               (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
   1667           uint32_t size = m_sizeX * des_Bpp;
   1668           FXSYS_memmove(scan_des, scan_src, size);
   1669         }
   1670       }
   1671       return;
   1672     }
   1673     for (; des_row_1 < des_row; des_row_1++) {
   1674       uint8_t* scan_des =
   1675           (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;
   1676       PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);
   1677       const uint8_t* scan_src1 =
   1678           pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) +
   1679           des_ScanOffet;
   1680       const uint8_t* scan_src2 =
   1681           pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) +
   1682           des_ScanOffet;
   1683       for (int des_col = 0; des_col < m_sizeX; des_col++) {
   1684         switch (pDeviceBitmap->GetFormat()) {
   1685           case FXDIB_Invalid:
   1686           case FXDIB_1bppMask:
   1687           case FXDIB_1bppRgb:
   1688             return;
   1689           case FXDIB_8bppMask:
   1690           case FXDIB_8bppRgb: {
   1691             if (pDeviceBitmap->GetPalette()) {
   1692               return;
   1693             }
   1694             int des_g = 0;
   1695             des_g += pWeight->m_Weights[0] * (*scan_src1++);
   1696             des_g += pWeight->m_Weights[1] * (*scan_src2++);
   1697             *scan_des++ = (uint8_t)(des_g >> 16);
   1698           } break;
   1699           case FXDIB_Rgb:
   1700           case FXDIB_Rgb32: {
   1701             uint32_t des_b = 0, des_g = 0, des_r = 0;
   1702             des_b += pWeight->m_Weights[0] * (*scan_src1++);
   1703             des_g += pWeight->m_Weights[0] * (*scan_src1++);
   1704             des_r += pWeight->m_Weights[0] * (*scan_src1++);
   1705             scan_src1 += des_Bpp - 3;
   1706             des_b += pWeight->m_Weights[1] * (*scan_src2++);
   1707             des_g += pWeight->m_Weights[1] * (*scan_src2++);
   1708             des_r += pWeight->m_Weights[1] * (*scan_src2++);
   1709             scan_src2 += des_Bpp - 3;
   1710             *scan_des++ = (uint8_t)((des_b) >> 16);
   1711             *scan_des++ = (uint8_t)((des_g) >> 16);
   1712             *scan_des++ = (uint8_t)((des_r) >> 16);
   1713             scan_des += des_Bpp - 3;
   1714           } break;
   1715           case FXDIB_Argb: {
   1716             uint32_t des_a = 0, des_b = 0, des_g = 0, des_r = 0;
   1717             des_b += pWeight->m_Weights[0] * (*scan_src1++);
   1718             des_g += pWeight->m_Weights[0] * (*scan_src1++);
   1719             des_r += pWeight->m_Weights[0] * (*scan_src1++);
   1720             des_a += pWeight->m_Weights[0] * (*scan_src1++);
   1721             des_b += pWeight->m_Weights[1] * (*scan_src2++);
   1722             des_g += pWeight->m_Weights[1] * (*scan_src2++);
   1723             des_r += pWeight->m_Weights[1] * (*scan_src2++);
   1724             des_a += pWeight->m_Weights[1] * (*scan_src2++);
   1725             *scan_des++ = (uint8_t)((des_b) >> 16);
   1726             *scan_des++ = (uint8_t)((des_g) >> 16);
   1727             *scan_des++ = (uint8_t)((des_r) >> 16);
   1728             *scan_des++ = (uint8_t)((des_a) >> 16);
   1729           } break;
   1730           default:
   1731             return;
   1732         }
   1733       }
   1734     }
   1735     int des_bottom = des_top + m_sizeY;
   1736     if (des_row + (int)scale_y >= des_bottom - 1) {
   1737       uint8_t* scan_src =
   1738           (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
   1739       while (++des_row < des_bottom) {
   1740         uint8_t* scan_des =
   1741             (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
   1742         uint32_t size = m_sizeX * des_Bpp;
   1743         FXSYS_memmove(scan_des, scan_src, size);
   1744       }
   1745     }
   1746     return;
   1747   }
   1748   int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1);
   1749   if (multiple > 0) {
   1750     uint8_t* scan_src =
   1751         (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
   1752     for (int i = 1; i <= multiple; i++) {
   1753       if (des_row + i >= m_startY + m_sizeY) {
   1754         return;
   1755       }
   1756       uint8_t* scan_des =
   1757           (uint8_t*)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet;
   1758       uint32_t size = m_sizeX * des_Bpp;
   1759       FXSYS_memmove(scan_des, scan_src, size);
   1760     }
   1761   }
   1762 }
   1763 
   1764 void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap,
   1765                                          int32_t src_line,
   1766                                          uint8_t* src_scan,
   1767                                          FXCodec_Format src_format) {
   1768   int src_top = m_clipBox.top;
   1769   int des_top = m_startY;
   1770   int src_hei = m_clipBox.Height();
   1771   int des_hei = m_sizeY;
   1772   if (src_line >= src_top) {
   1773     double scale_y = (double)des_hei / (double)src_hei;
   1774     int src_row = src_line - src_top;
   1775     int des_row = (int)(src_row * scale_y) + des_top;
   1776     if (des_row >= des_top + des_hei) {
   1777       return;
   1778     }
   1779     ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format);
   1780     if (scale_y > 1.0) {
   1781       ResampleVert(pDeviceBitmap, scale_y, des_row);
   1782     }
   1783   }
   1784 }
   1785 
   1786 FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames,
   1787                                                     IFX_Pause* pPause) {
   1788   if (!(m_status == FXCODEC_STATUS_FRAME_READY ||
   1789         m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) {
   1790     return FXCODEC_STATUS_ERROR;
   1791   }
   1792   switch (m_imagType) {
   1793     case FXCODEC_IMAGE_JPG:
   1794     case FXCODEC_IMAGE_BMP:
   1795     case FXCODEC_IMAGE_PNG:
   1796     case FXCODEC_IMAGE_TIF:
   1797       frames = m_FrameNumber = 1;
   1798       m_status = FXCODEC_STATUS_DECODE_READY;
   1799       return m_status;
   1800     case FXCODEC_IMAGE_GIF: {
   1801       ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
   1802       if (!pGifModule) {
   1803         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1804         return m_status;
   1805       }
   1806       while (true) {
   1807         int32_t readResult =
   1808             pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);
   1809         while (readResult == 2) {
   1810           FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ;
   1811           if (!GifReadMoreData(pGifModule, error_status)) {
   1812             return error_status;
   1813           }
   1814           if (pPause && pPause->NeedToPauseNow()) {
   1815             m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE;
   1816             return m_status;
   1817           }
   1818           readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);
   1819         }
   1820         if (readResult == 1) {
   1821           frames = m_FrameNumber;
   1822           m_status = FXCODEC_STATUS_DECODE_READY;
   1823           return m_status;
   1824         }
   1825         if (m_pGifContext) {
   1826           pGifModule->Finish(m_pGifContext);
   1827           m_pGifContext = nullptr;
   1828         }
   1829         m_status = FXCODEC_STATUS_ERROR;
   1830         return m_status;
   1831       }
   1832     }
   1833     default:
   1834       return FXCODEC_STATUS_ERROR;
   1835   }
   1836 }
   1837 
   1838 FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap,
   1839                                                       int start_x,
   1840                                                       int start_y,
   1841                                                       int size_x,
   1842                                                       int size_y,
   1843                                                       int32_t frames,
   1844                                                       bool bInterpol) {
   1845   if (m_status != FXCODEC_STATUS_DECODE_READY)
   1846     return FXCODEC_STATUS_ERROR;
   1847 
   1848   if (!pDIBitmap || pDIBitmap->GetBPP() < 8 || frames < 0 ||
   1849       frames >= m_FrameNumber) {
   1850     return FXCODEC_STATUS_ERR_PARAMS;
   1851   }
   1852   m_pDeviceBitmap = pDIBitmap;
   1853   if (m_clipBox.IsEmpty())
   1854     return FXCODEC_STATUS_ERR_PARAMS;
   1855   if (size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535)
   1856     return FXCODEC_STATUS_ERR_PARAMS;
   1857 
   1858   FX_RECT device_rc =
   1859       FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y);
   1860   int32_t out_range_x = device_rc.right - pDIBitmap->GetWidth();
   1861   int32_t out_range_y = device_rc.bottom - pDIBitmap->GetHeight();
   1862   device_rc.Intersect(
   1863       FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight()));
   1864   if (device_rc.IsEmpty())
   1865     return FXCODEC_STATUS_ERR_PARAMS;
   1866 
   1867   m_startX = device_rc.left;
   1868   m_startY = device_rc.top;
   1869   m_sizeX = device_rc.Width();
   1870   m_sizeY = device_rc.Height();
   1871   m_bInterpol = bInterpol;
   1872   m_FrameCur = 0;
   1873   if (start_x < 0 || out_range_x > 0) {
   1874     FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x;
   1875     if (start_x < 0) {
   1876       m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX);
   1877     }
   1878     if (out_range_x > 0) {
   1879       m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX);
   1880     }
   1881   }
   1882   if (start_y < 0 || out_range_y > 0) {
   1883     FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y;
   1884     if (start_y < 0) {
   1885       m_clipBox.top -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY);
   1886     }
   1887     if (out_range_y > 0) {
   1888       m_clipBox.bottom -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY);
   1889     }
   1890   }
   1891   if (m_clipBox.IsEmpty()) {
   1892     return FXCODEC_STATUS_ERR_PARAMS;
   1893   }
   1894   switch (m_imagType) {
   1895     case FXCODEC_IMAGE_JPG: {
   1896       CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
   1897       int down_scale = 1;
   1898       GetDownScale(down_scale);
   1899       bool bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale);
   1900       while (!bStart) {
   1901         FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
   1902         if (!JpegReadMoreData(pJpegModule, error_status)) {
   1903           m_pDeviceBitmap = nullptr;
   1904           m_pFile = nullptr;
   1905           m_status = error_status;
   1906           return m_status;
   1907         }
   1908         bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale);
   1909       }
   1910       int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale;
   1911       scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4;
   1912       FX_Free(m_pDecodeBuf);
   1913       m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
   1914       FXSYS_memset(m_pDecodeBuf, 0, scanline_size);
   1915       m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
   1916                         m_clipBox.Width(), m_bInterpol);
   1917       m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
   1918       switch (m_SrcComponents) {
   1919         case 1:
   1920           m_SrcFormat = FXCodec_8bppGray;
   1921           break;
   1922         case 3:
   1923           m_SrcFormat = FXCodec_Rgb;
   1924           break;
   1925         case 4:
   1926           m_SrcFormat = FXCodec_Cmyk;
   1927           break;
   1928       }
   1929       GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat);
   1930       m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1931       return m_status;
   1932     }
   1933     case FXCODEC_IMAGE_PNG: {
   1934       ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
   1935       if (!pPngModule) {
   1936         m_pDeviceBitmap = nullptr;
   1937         m_pFile = nullptr;
   1938         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1939         return m_status;
   1940       }
   1941       if (m_pPngContext) {
   1942         pPngModule->Finish(m_pPngContext);
   1943         m_pPngContext = nullptr;
   1944       }
   1945       m_pPngContext = pPngModule->Start();
   1946       if (!m_pPngContext) {
   1947         m_pDeviceBitmap = nullptr;
   1948         m_pFile = nullptr;
   1949         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1950         return m_status;
   1951       }
   1952       m_offSet = 0;
   1953       switch (m_pDeviceBitmap->GetFormat()) {
   1954         case FXDIB_8bppMask:
   1955         case FXDIB_8bppRgb:
   1956           m_SrcComponents = 1;
   1957           m_SrcFormat = FXCodec_8bppGray;
   1958           break;
   1959         case FXDIB_Rgb:
   1960           m_SrcComponents = 3;
   1961           m_SrcFormat = FXCodec_Rgb;
   1962           break;
   1963         case FXDIB_Rgb32:
   1964         case FXDIB_Argb:
   1965           m_SrcComponents = 4;
   1966           m_SrcFormat = FXCodec_Argb;
   1967           break;
   1968         default: {
   1969           m_pDeviceBitmap = nullptr;
   1970           m_pFile = nullptr;
   1971           m_status = FXCODEC_STATUS_ERR_PARAMS;
   1972           return m_status;
   1973         }
   1974       }
   1975       GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
   1976       int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
   1977       FX_Free(m_pDecodeBuf);
   1978       m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
   1979       FXSYS_memset(m_pDecodeBuf, 0, scanline_size);
   1980       m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol);
   1981       m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
   1982       m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   1983       return m_status;
   1984     }
   1985     case FXCODEC_IMAGE_GIF: {
   1986       ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
   1987       if (!pGifModule) {
   1988         m_pDeviceBitmap = nullptr;
   1989         m_pFile = nullptr;
   1990         m_status = FXCODEC_STATUS_ERR_MEMORY;
   1991         return m_status;
   1992       }
   1993       m_SrcFormat = FXCodec_8bppRgb;
   1994       GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
   1995       int scanline_size = (m_SrcWidth + 3) / 4 * 4;
   1996       FX_Free(m_pDecodeBuf);
   1997       m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
   1998       FXSYS_memset(m_pDecodeBuf, 0, scanline_size);
   1999       m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
   2000                         m_clipBox.Width(), m_bInterpol);
   2001       m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
   2002       m_FrameCur = frames;
   2003       m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   2004       return m_status;
   2005     }
   2006     case FXCODEC_IMAGE_BMP: {
   2007       ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
   2008       if (!pBmpModule) {
   2009         m_pDeviceBitmap = nullptr;
   2010         m_pFile = nullptr;
   2011         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2012         return m_status;
   2013       }
   2014       switch (m_SrcComponents) {
   2015         case 1:
   2016           m_SrcFormat = FXCodec_8bppRgb;
   2017           break;
   2018         case 3:
   2019           m_SrcFormat = FXCodec_Rgb;
   2020           break;
   2021         case 4:
   2022           m_SrcFormat = FXCodec_Rgb32;
   2023           break;
   2024       }
   2025       GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
   2026       m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
   2027       FX_Free(m_pDecodeBuf);
   2028       m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize);
   2029       FXSYS_memset(m_pDecodeBuf, 0, m_ScanlineSize);
   2030       m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
   2031                         m_clipBox.Width(), m_bInterpol);
   2032       m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
   2033       m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   2034       return m_status;
   2035     }
   2036     case FXCODEC_IMAGE_TIF:
   2037       m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   2038       return m_status;
   2039     default:
   2040       return FXCODEC_STATUS_ERROR;
   2041   }
   2042 }
   2043 
   2044 FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) {
   2045   if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE)
   2046     return FXCODEC_STATUS_ERROR;
   2047 
   2048   switch (m_imagType) {
   2049     case FXCODEC_IMAGE_JPG: {
   2050       CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
   2051       while (true) {
   2052         bool readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);
   2053         while (!readRes) {
   2054           FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
   2055           if (!JpegReadMoreData(pJpegModule, error_status)) {
   2056             m_pDeviceBitmap = nullptr;
   2057             m_pFile = nullptr;
   2058             m_status = error_status;
   2059             return m_status;
   2060           }
   2061           readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);
   2062         }
   2063         if (m_SrcFormat == FXCodec_Rgb) {
   2064           int src_Bpp = (m_SrcFormat & 0xff) >> 3;
   2065           RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width());
   2066         }
   2067         if (m_SrcRow >= m_clipBox.bottom) {
   2068           m_pDeviceBitmap = nullptr;
   2069           m_pFile = nullptr;
   2070           m_status = FXCODEC_STATUS_DECODE_FINISH;
   2071           return m_status;
   2072         }
   2073         Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat);
   2074         m_SrcRow++;
   2075         if (pPause && pPause->NeedToPauseNow()) {
   2076           m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   2077           return m_status;
   2078         }
   2079       }
   2080     }
   2081     case FXCODEC_IMAGE_PNG: {
   2082       ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
   2083       if (!pPngModule) {
   2084         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2085         return m_status;
   2086       }
   2087       while (true) {
   2088         uint32_t remain_size = (uint32_t)m_pFile->GetSize() - m_offSet;
   2089         uint32_t input_size =
   2090             remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
   2091         if (input_size == 0) {
   2092           if (m_pPngContext) {
   2093             pPngModule->Finish(m_pPngContext);
   2094           }
   2095           m_pPngContext = nullptr;
   2096           m_pDeviceBitmap = nullptr;
   2097           m_pFile = nullptr;
   2098           m_status = FXCODEC_STATUS_DECODE_FINISH;
   2099           return m_status;
   2100         }
   2101         if (m_pSrcBuf && input_size > m_SrcSize) {
   2102           FX_Free(m_pSrcBuf);
   2103           m_pSrcBuf = FX_Alloc(uint8_t, input_size);
   2104           FXSYS_memset(m_pSrcBuf, 0, input_size);
   2105           m_SrcSize = input_size;
   2106         }
   2107         bool bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);
   2108         if (!bResult) {
   2109           m_pDeviceBitmap = nullptr;
   2110           m_pFile = nullptr;
   2111           m_status = FXCODEC_STATUS_ERR_READ;
   2112           return m_status;
   2113         }
   2114         m_offSet += input_size;
   2115         bResult =
   2116             pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, nullptr);
   2117         if (!bResult) {
   2118           m_pDeviceBitmap = nullptr;
   2119           m_pFile = nullptr;
   2120           m_status = FXCODEC_STATUS_ERROR;
   2121           return m_status;
   2122         }
   2123         if (pPause && pPause->NeedToPauseNow()) {
   2124           m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   2125           return m_status;
   2126         }
   2127       }
   2128     }
   2129     case FXCODEC_IMAGE_GIF: {
   2130       ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
   2131       if (!pGifModule) {
   2132         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2133         return m_status;
   2134       }
   2135       while (true) {
   2136         int32_t readRes =
   2137             pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr);
   2138         while (readRes == 2) {
   2139           FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
   2140           if (!GifReadMoreData(pGifModule, error_status)) {
   2141             m_pDeviceBitmap = nullptr;
   2142             m_pFile = nullptr;
   2143             m_status = error_status;
   2144             return m_status;
   2145           }
   2146           if (pPause && pPause->NeedToPauseNow()) {
   2147             m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   2148             return m_status;
   2149           }
   2150           readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr);
   2151         }
   2152         if (readRes == 1) {
   2153           m_pDeviceBitmap = nullptr;
   2154           m_pFile = nullptr;
   2155           m_status = FXCODEC_STATUS_DECODE_FINISH;
   2156           return m_status;
   2157         }
   2158         m_pDeviceBitmap = nullptr;
   2159         m_pFile = nullptr;
   2160         m_status = FXCODEC_STATUS_ERROR;
   2161         return m_status;
   2162       }
   2163     }
   2164     case FXCODEC_IMAGE_BMP: {
   2165       ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
   2166       if (!pBmpModule) {
   2167         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2168         return m_status;
   2169       }
   2170       while (true) {
   2171         int32_t readRes = pBmpModule->LoadImage(m_pBmpContext);
   2172         while (readRes == 2) {
   2173           FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
   2174           if (!BmpReadMoreData(pBmpModule, error_status)) {
   2175             m_pDeviceBitmap = nullptr;
   2176             m_pFile = nullptr;
   2177             m_status = error_status;
   2178             return m_status;
   2179           }
   2180           if (pPause && pPause->NeedToPauseNow()) {
   2181             m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
   2182             return m_status;
   2183           }
   2184           readRes = pBmpModule->LoadImage(m_pBmpContext);
   2185         }
   2186         if (readRes == 1) {
   2187           m_pDeviceBitmap = nullptr;
   2188           m_pFile = nullptr;
   2189           m_status = FXCODEC_STATUS_DECODE_FINISH;
   2190           return m_status;
   2191         }
   2192         m_pDeviceBitmap = nullptr;
   2193         m_pFile = nullptr;
   2194         m_status = FXCODEC_STATUS_ERROR;
   2195         return m_status;
   2196       }
   2197     }
   2198     case FXCODEC_IMAGE_TIF: {
   2199       ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
   2200       if (!pTiffModule) {
   2201         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2202         return m_status;
   2203       }
   2204       bool ret = false;
   2205       if (m_pDeviceBitmap->GetBPP() == 32 &&
   2206           m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX &&
   2207           m_pDeviceBitmap->GetHeight() == m_SrcHeight &&
   2208           m_SrcHeight == m_sizeY && m_startX == 0 && m_startY == 0 &&
   2209           m_clipBox.left == 0 && m_clipBox.top == 0 &&
   2210           m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) {
   2211         ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap);
   2212         m_pDeviceBitmap = nullptr;
   2213         m_pFile = nullptr;
   2214         if (!ret) {
   2215           m_status = FXCODEC_STATUS_ERROR;
   2216           return m_status;
   2217         }
   2218         m_status = FXCODEC_STATUS_DECODE_FINISH;
   2219         return m_status;
   2220       }
   2221 
   2222       CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap;
   2223       pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);
   2224       if (!pDIBitmap->GetBuffer()) {
   2225         delete pDIBitmap;
   2226         m_pDeviceBitmap = nullptr;
   2227         m_pFile = nullptr;
   2228         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2229         return m_status;
   2230       }
   2231       ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap);
   2232       if (!ret) {
   2233         delete pDIBitmap;
   2234         m_pDeviceBitmap = nullptr;
   2235         m_pFile = nullptr;
   2236         m_status = FXCODEC_STATUS_ERROR;
   2237         return m_status;
   2238       }
   2239       CFX_DIBitmap* pClipBitmap =
   2240           (m_clipBox.left == 0 && m_clipBox.top == 0 &&
   2241            m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight)
   2242               ? pDIBitmap
   2243               : pDIBitmap->Clone(&m_clipBox).release();
   2244       if (pDIBitmap != pClipBitmap) {
   2245         delete pDIBitmap;
   2246       }
   2247       if (!pClipBitmap) {
   2248         m_pDeviceBitmap = nullptr;
   2249         m_pFile = nullptr;
   2250         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2251         return m_status;
   2252       }
   2253       CFX_DIBitmap* pFormatBitmap = nullptr;
   2254       switch (m_pDeviceBitmap->GetFormat()) {
   2255         case FXDIB_8bppRgb:
   2256           pFormatBitmap = new CFX_DIBitmap;
   2257           pFormatBitmap->Create(pClipBitmap->GetWidth(),
   2258                                 pClipBitmap->GetHeight(), FXDIB_8bppRgb);
   2259           break;
   2260         case FXDIB_8bppMask:
   2261           pFormatBitmap = new CFX_DIBitmap;
   2262           pFormatBitmap->Create(pClipBitmap->GetWidth(),
   2263                                 pClipBitmap->GetHeight(), FXDIB_8bppMask);
   2264           break;
   2265         case FXDIB_Rgb:
   2266           pFormatBitmap = new CFX_DIBitmap;
   2267           pFormatBitmap->Create(pClipBitmap->GetWidth(),
   2268                                 pClipBitmap->GetHeight(), FXDIB_Rgb);
   2269           break;
   2270         case FXDIB_Rgb32:
   2271           pFormatBitmap = new CFX_DIBitmap;
   2272           pFormatBitmap->Create(pClipBitmap->GetWidth(),
   2273                                 pClipBitmap->GetHeight(), FXDIB_Rgb32);
   2274           break;
   2275         case FXDIB_Argb:
   2276           pFormatBitmap = pClipBitmap;
   2277           break;
   2278         default:
   2279           break;
   2280       }
   2281       switch (m_pDeviceBitmap->GetFormat()) {
   2282         case FXDIB_8bppRgb:
   2283         case FXDIB_8bppMask: {
   2284           for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
   2285             uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
   2286             uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row);
   2287             for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
   2288               uint8_t _a = 255 - src_line[3];
   2289               uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
   2290               uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
   2291               uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
   2292               *des_line++ = FXRGB2GRAY(r, g, b);
   2293               src_line += 4;
   2294             }
   2295           }
   2296         } break;
   2297         case FXDIB_Rgb:
   2298         case FXDIB_Rgb32: {
   2299           int32_t desBpp = (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4;
   2300           for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
   2301             uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
   2302             uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row);
   2303             for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) {
   2304               uint8_t _a = 255 - src_line[3];
   2305               uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
   2306               uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
   2307               uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
   2308               *des_line++ = b;
   2309               *des_line++ = g;
   2310               *des_line++ = r;
   2311               des_line += desBpp - 3;
   2312               src_line += 4;
   2313             }
   2314           }
   2315         } break;
   2316         default:
   2317           break;
   2318       }
   2319       if (pClipBitmap != pFormatBitmap) {
   2320         delete pClipBitmap;
   2321       }
   2322       if (!pFormatBitmap) {
   2323         m_pDeviceBitmap = nullptr;
   2324         m_pFile = nullptr;
   2325         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2326         return m_status;
   2327       }
   2328       std::unique_ptr<CFX_DIBitmap> pStrechBitmap = pFormatBitmap->StretchTo(
   2329           m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE);
   2330       delete pFormatBitmap;
   2331       pFormatBitmap = nullptr;
   2332       if (!pStrechBitmap) {
   2333         m_pDeviceBitmap = nullptr;
   2334         m_pFile = nullptr;
   2335         m_status = FXCODEC_STATUS_ERR_MEMORY;
   2336         return m_status;
   2337       }
   2338       m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY,
   2339                                       pStrechBitmap.get(), 0, 0);
   2340       m_pDeviceBitmap = nullptr;
   2341       m_pFile = nullptr;
   2342       m_status = FXCODEC_STATUS_DECODE_FINISH;
   2343       return m_status;
   2344     }
   2345     default:
   2346       return FXCODEC_STATUS_ERROR;
   2347   }
   2348 }
   2349 
   2350 std::unique_ptr<CCodec_ProgressiveDecoder>
   2351 CCodec_ModuleMgr::CreateProgressiveDecoder() {
   2352   return pdfium::MakeUnique<CCodec_ProgressiveDecoder>(this);
   2353 }
   2354