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