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