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