Index: core/src/fxcodec/codec/fx_codec_progress.cpp |
diff --git a/core/src/fxcodec/codec/fx_codec_progress.cpp b/core/src/fxcodec/codec/fx_codec_progress.cpp |
index 383e3ed93dd3f76a1655b243018fcb779e6cd692..5dbc19b4b6285d791b61a0a6e19295c09a6755f6 100644 |
--- a/core/src/fxcodec/codec/fx_codec_progress.cpp |
+++ b/core/src/fxcodec/codec/fx_codec_progress.cpp |
@@ -1,2354 +1,2354 @@ |
-// Copyright 2014 PDFium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
- |
-#include "core/include/fxge/fx_dib.h" |
-#include "core/include/fxcodec/fx_codec.h" |
-#include "fx_codec_progress.h" |
-void CFXCODEC_WeightTable::Calc(int dest_len, |
- int dest_min, |
- int dest_max, |
- int src_len, |
- int src_min, |
- int src_max, |
- FX_BOOL bInterpol) { |
- if (m_pWeightTables) { |
- FX_Free(m_pWeightTables); |
- } |
- double scale, base; |
- scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len)); |
- if (dest_len < 0) { |
- base = (FX_FLOAT)(src_len); |
- } else { |
- base = 0.0f; |
- } |
- m_ItemSize = |
- (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); |
- if (m_pWeightTables == NULL) { |
- return; |
- } |
- 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); |
- double src_pos = dest_pixel * scale + scale / 2 + base; |
- if (bInterpol) { |
- pixel_weights.m_SrcStart = |
- (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); |
- pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); |
- if (pixel_weights.m_SrcStart < src_min) { |
- pixel_weights.m_SrcStart = src_min; |
- } |
- if (pixel_weights.m_SrcEnd >= src_max) { |
- pixel_weights.m_SrcEnd = src_max - 1; |
- } |
- if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { |
- pixel_weights.m_Weights[0] = 65536; |
- } else { |
- pixel_weights.m_Weights[1] = FXSYS_round( |
- (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * |
- 65536); |
- pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; |
- } |
- } else { |
- pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = |
- (int)FXSYS_floor((FX_FLOAT)src_pos); |
- pixel_weights.m_Weights[0] = 65536; |
- } |
- } |
- return; |
- } |
- for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { |
- PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); |
- double src_start = dest_pixel * scale + base; |
- double src_end = src_start + scale; |
- int start_i, end_i; |
- if (src_start < src_end) { |
- start_i = (int)FXSYS_floor((FX_FLOAT)src_start); |
- end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); |
- } else { |
- start_i = (int)FXSYS_floor((FX_FLOAT)src_end); |
- end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); |
- } |
- if (start_i < src_min) { |
- start_i = src_min; |
- } |
- if (end_i >= src_max) { |
- end_i = src_max - 1; |
- } |
- if (start_i > end_i) { |
- pixel_weights.m_SrcStart = start_i; |
- pixel_weights.m_SrcEnd = start_i; |
- continue; |
- } |
- pixel_weights.m_SrcStart = start_i; |
- pixel_weights.m_SrcEnd = end_i; |
- for (int j = start_i; j <= end_i; j++) { |
- double dest_start = FXSYS_Div((FX_FLOAT)(j)-base, scale); |
- double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale); |
- if (dest_start > dest_end) { |
- double temp = dest_start; |
- dest_start = dest_end; |
- dest_end = temp; |
- } |
- double area_start = dest_start > (FX_FLOAT)(dest_pixel) |
- ? dest_start |
- : (FX_FLOAT)(dest_pixel); |
- double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) |
- ? (FX_FLOAT)(dest_pixel + 1) |
- : dest_end; |
- double weight = area_start >= area_end ? 0.0f : area_end - area_start; |
- if (weight == 0 && j == end_i) { |
- pixel_weights.m_SrcEnd--; |
- break; |
- } |
- pixel_weights.m_Weights[j - start_i] = |
- FXSYS_round((FX_FLOAT)(weight * 65536)); |
- } |
- } |
-} |
-void 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); |
- if (m_pWeightTables == NULL) { |
- return; |
- } |
- FXSYS_memset(m_pWeightTables, 0, size); |
- 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); |
- 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->m_SrcStart = pWeight->m_SrcEnd = src_col; |
- pWeight->m_Weights[0] = 65536; |
- pWeight->m_Weights[1] = 0; |
- } |
- return; |
- } |
- 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->m_SrcStart = src_col - 1; |
- pWeight->m_SrcEnd = src_col; |
- pWeight->m_Weights[0] = |
- bInterpol ? FXSYS_round((FX_FLOAT)( |
- ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index) / |
- (FX_FLOAT)des_col_len * 65536)) |
- : 65536; |
- pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; |
- } |
- pre_des_col = des_col; |
- } |
- return; |
- } |
- 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); |
- pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; |
- pWeight->m_Weights[0] = 65536; |
- pWeight->m_Weights[1] = 0; |
- } |
-} |
-void 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); |
- if (m_pWeightTables == NULL) { |
- return; |
- } |
- FXSYS_memset(m_pWeightTables, 0, size); |
- if (scale > 1) { |
- double step = 0.0; |
- int src_row = 0; |
- while (step < (double)dest_len) { |
- int start_step = (int)step; |
- step = scale * (++src_row); |
- int end_step = (int)step; |
- if (end_step >= dest_len) { |
- end_step = dest_len; |
- for (int des_row = start_step; des_row < end_step; des_row++) { |
- PixelWeight* pWeight = |
- (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); |
- pWeight->m_SrcStart = start_step; |
- pWeight->m_SrcEnd = start_step; |
- pWeight->m_Weights[0] = 65536; |
- pWeight->m_Weights[1] = 0; |
- } |
- return; |
- } |
- int length = end_step - start_step; |
- { |
- PixelWeight* pWeight = |
- (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize); |
- pWeight->m_SrcStart = start_step; |
- pWeight->m_SrcEnd = start_step; |
- pWeight->m_Weights[0] = 65536; |
- pWeight->m_Weights[1] = 0; |
- } |
- for (int des_row = start_step + 1; des_row < end_step; des_row++) { |
- PixelWeight* pWeight = |
- (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); |
- pWeight->m_SrcStart = start_step; |
- pWeight->m_SrcEnd = end_step; |
- pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / |
- (FX_FLOAT)length * 65536); |
- pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; |
- } |
- } |
- } else { |
- 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; |
- pWeight->m_Weights[0] = 65536; |
- pWeight->m_Weights[1] = 0; |
- } |
- } |
-} |
-CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder( |
- CCodec_ModuleMgr* pCodecMgr) { |
- m_pFile = NULL; |
- m_pJpegContext = NULL; |
- m_pPngContext = NULL; |
- m_pGifContext = NULL; |
- m_pBmpContext = NULL; |
- m_pTiffContext = NULL; |
- m_pCodecMgr = NULL; |
- m_pSrcBuf = NULL; |
- m_pDecodeBuf = NULL; |
- m_pDeviceBitmap = NULL; |
- m_pSrcPalette = NULL; |
- m_pCodecMgr = pCodecMgr; |
- m_offSet = 0; |
- m_SrcSize = 0; |
- m_ScanlineSize = 0; |
- m_SrcWidth = m_SrcHeight = 0; |
- m_SrcComponents = 0; |
- m_SrcBPC = 0; |
- m_SrcPassNumber = 0; |
- m_clipBox = FX_RECT(0, 0, 0, 0); |
- m_imagType = FXCODEC_IMAGE_UNKNOWN; |
- m_status = FXCODEC_STATUS_DECODE_FINISH; |
- m_TransMethod = -1; |
- m_SrcRow = 0; |
- m_SrcFormat = FXCodec_Invalid; |
- m_bInterpol = TRUE; |
- m_FrameNumber = 0; |
- m_FrameCur = 0; |
- m_SrcPaletteNumber = 0; |
- m_GifPltNumber = 0; |
- m_GifBgIndex = 0; |
- m_pGifPalette = NULL; |
- m_GifTransIndex = -1; |
- m_GifFrameRect = FX_RECT(0, 0, 0, 0); |
- m_BmpIsTopBottom = FALSE; |
-} |
-CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { |
- m_pFile = NULL; |
- if (m_pJpegContext != NULL) { |
- m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); |
- } |
- if (m_pPngContext != NULL) { |
- m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); |
- } |
- if (m_pGifContext != NULL) { |
- m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); |
- } |
- if (m_pBmpContext != NULL) { |
- m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); |
- } |
- if (m_pTiffContext != NULL) { |
- m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); |
- } |
- if (m_pSrcBuf != NULL) { |
- FX_Free(m_pSrcBuf); |
- } |
- if (m_pDecodeBuf != NULL) { |
- FX_Free(m_pDecodeBuf); |
- } |
- if (m_pSrcPalette != NULL) { |
- FX_Free(m_pSrcPalette); |
- } |
-} |
-FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData( |
- ICodec_JpegModule* pJpegModule, |
- FXCODEC_STATUS& err_status) { |
- FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); |
- if (dwSize <= m_offSet) { |
- return FALSE; |
- } |
- dwSize = dwSize - m_offSet; |
- FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL); |
- if (dwAvail == m_SrcSize) { |
- if (dwSize > FXCODEC_BLOCK_SIZE) { |
- dwSize = FXCODEC_BLOCK_SIZE; |
- } |
- m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / |
- FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; |
- m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); |
- if (!m_pSrcBuf) { |
- err_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- } else { |
- FX_DWORD dwConsume = m_SrcSize - dwAvail; |
- if (dwAvail) { |
- FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); |
- } |
- if (dwSize > dwConsume) { |
- dwSize = dwConsume; |
- } |
- } |
- if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { |
- err_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += dwSize; |
- pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail); |
- return TRUE; |
-} |
-FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, |
- int width, |
- int height, |
- int bpc, |
- int pass, |
- int* color_type, |
- double* gamma) { |
- CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
- if (pCodec->m_pDeviceBitmap == NULL) { |
- pCodec->m_SrcWidth = width; |
- 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; |
- pCodec->m_clipBox = FX_RECT(0, 0, width, height); |
- return FALSE; |
- } |
- FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat(); |
- switch (format) { |
- case FXDIB_1bppMask: |
- case FXDIB_1bppRgb: |
- ASSERT(FALSE); |
- return FALSE; |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: |
- *color_type = 0; |
- break; |
- case FXDIB_Rgb: |
- *color_type = 2; |
- break; |
- case FXDIB_Rgb32: |
- case FXDIB_Argb: |
- *color_type = 6; |
- break; |
- default: |
- ASSERT(FALSE); |
- return FALSE; |
- } |
- *gamma = FXCODEC_PNG_GAMMA; |
- return TRUE; |
-} |
-FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, |
- int line, |
- uint8_t*& src_buf) { |
- CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
- CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
- ASSERT(pDIBitmap != NULL); |
- if (pDIBitmap == NULL) { |
- return FALSE; |
- } |
- if (line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) { |
- double scale_y = |
- (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height(); |
- int32_t row = |
- (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY; |
- uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row); |
- uint8_t* des_scan = pCodec->m_pDecodeBuf; |
- src_buf = pCodec->m_pDecodeBuf; |
- int32_t src_Bpp = pDIBitmap->GetBPP() >> 3; |
- int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3; |
- int32_t src_left = pCodec->m_startX; |
- int32_t des_left = pCodec->m_clipBox.left; |
- src_scan += src_left * src_Bpp; |
- des_scan += des_left * des_Bpp; |
- for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) { |
- PixelWeight* pPixelWeights = |
- pCodec->m_WeightHorzOO.GetPixelWeight(src_col); |
- if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) { |
- continue; |
- } |
- switch (pDIBitmap->GetFormat()) { |
- case FXDIB_1bppMask: |
- case FXDIB_1bppRgb: |
- ASSERT(FALSE); |
- return FALSE; |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: { |
- if (pDIBitmap->GetPalette() != NULL) { |
- return FALSE; |
- } |
- FX_DWORD des_g = 0; |
- des_g += pPixelWeights->m_Weights[0] * src_scan[src_col]; |
- des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16); |
- } break; |
- case FXDIB_Rgb: |
- case FXDIB_Rgb32: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- const uint8_t* p = src_scan + src_col * src_Bpp; |
- des_b += pPixelWeights->m_Weights[0] * (*p++); |
- des_g += pPixelWeights->m_Weights[0] * (*p++); |
- des_r += pPixelWeights->m_Weights[0] * (*p); |
- uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; |
- *pDes++ = (uint8_t)((des_b) >> 16); |
- *pDes++ = (uint8_t)((des_g) >> 16); |
- *pDes = (uint8_t)((des_r) >> 16); |
- } break; |
- case FXDIB_Argb: { |
- FX_DWORD des_r = 0, des_g = 0, des_b = 0; |
- const uint8_t* p = src_scan + src_col * src_Bpp; |
- des_b += pPixelWeights->m_Weights[0] * (*p++); |
- des_g += pPixelWeights->m_Weights[0] * (*p++); |
- des_r += pPixelWeights->m_Weights[0] * (*p++); |
- uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; |
- *pDes++ = (uint8_t)((des_b) >> 16); |
- *pDes++ = (uint8_t)((des_g) >> 16); |
- *pDes++ = (uint8_t)((des_r) >> 16); |
- *pDes = *p; |
- } break; |
- default: |
- return FALSE; |
- } |
- } |
- } |
- return TRUE; |
-} |
-void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz( |
- CFX_DIBitmap* pDeviceBitmap, |
- int32_t des_line, |
- uint8_t* src_scan, |
- FXCodec_Format src_format) { |
- uint8_t* des_scan = (uint8_t*)pDeviceBitmap->GetScanline(des_line); |
- int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3; |
- int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
- int32_t src_left = m_clipBox.left; |
- int32_t des_left = m_startX; |
- src_scan += src_left * src_Bpp; |
- des_scan += des_left * des_Bpp; |
- for (int32_t des_col = 0; des_col < m_sizeX; des_col++) { |
- PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col); |
- switch (pDeviceBitmap->GetFormat()) { |
- case FXDIB_1bppMask: |
- case FXDIB_1bppRgb: |
- ASSERT(FALSE); |
- return; |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: { |
- if (pDeviceBitmap->GetPalette() != NULL) { |
- return; |
- } |
- FX_DWORD des_g = 0; |
- des_g += |
- pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart]; |
- des_g += |
- pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd]; |
- *des_scan++ = (uint8_t)(des_g >> 16); |
- } break; |
- case FXDIB_Rgb: |
- case FXDIB_Rgb32: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- const uint8_t* p = src_scan; |
- p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; |
- des_b += pPixelWeights->m_Weights[0] * (*p++); |
- des_g += pPixelWeights->m_Weights[0] * (*p++); |
- des_r += pPixelWeights->m_Weights[0] * (*p); |
- p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; |
- des_b += pPixelWeights->m_Weights[1] * (*p++); |
- des_g += pPixelWeights->m_Weights[1] * (*p++); |
- des_r += pPixelWeights->m_Weights[1] * (*p); |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- des_scan += des_Bpp - 3; |
- } break; |
- case FXDIB_Argb: { |
- FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
- const uint8_t* p = src_scan; |
- p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; |
- des_b += pPixelWeights->m_Weights[0] * (*p++); |
- des_g += pPixelWeights->m_Weights[0] * (*p++); |
- des_r += pPixelWeights->m_Weights[0] * (*p++); |
- des_a += pPixelWeights->m_Weights[0] * (*p); |
- p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; |
- des_b += pPixelWeights->m_Weights[1] * (*p++); |
- des_g += pPixelWeights->m_Weights[1] * (*p++); |
- des_r += pPixelWeights->m_Weights[1] * (*p++); |
- des_a += pPixelWeights->m_Weights[1] * (*p); |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- *des_scan++ = (uint8_t)((des_a) >> 16); |
- } break; |
- default: |
- return; |
- } |
- } |
-} |
-void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, |
- int pass, |
- int line) { |
- CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
- CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
- ASSERT(pDIBitmap != NULL); |
- int src_top = pCodec->m_clipBox.top; |
- int src_bottom = pCodec->m_clipBox.bottom; |
- 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->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, |
- pCodec->m_SrcFormat); |
- if (pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) { |
- pCodec->ResampleVert(pDIBitmap, scale_y, des_row); |
- return; |
- } |
- if (pass == 6 && scale_y > 1.0) { |
- pCodec->ResampleVert(pDIBitmap, scale_y, des_row); |
- } |
- } |
-} |
-FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, |
- FXCODEC_STATUS& err_status) { |
- FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); |
- if (dwSize <= m_offSet) { |
- return FALSE; |
- } |
- dwSize = dwSize - m_offSet; |
- FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL); |
- if (dwAvail == m_SrcSize) { |
- if (dwSize > FXCODEC_BLOCK_SIZE) { |
- dwSize = FXCODEC_BLOCK_SIZE; |
- } |
- m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / |
- FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; |
- m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); |
- if (!m_pSrcBuf) { |
- err_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- } else { |
- FX_DWORD dwConsume = m_SrcSize - dwAvail; |
- if (dwAvail) { |
- FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); |
- } |
- if (dwSize > dwConsume) { |
- dwSize = dwConsume; |
- } |
- } |
- if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { |
- err_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += dwSize; |
- pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail); |
- return TRUE; |
-} |
-void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback( |
- void* pModule, |
- FX_DWORD& cur_pos) { |
- CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
- FX_DWORD remain_size = |
- 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, |
- FX_DWORD rcd_pos, |
- const FX_RECT& img_rc, |
- int32_t pal_num, |
- void* pal_ptr, |
- int32_t delay_time, |
- FX_BOOL user_input, |
- int32_t trans_index, |
- int32_t disposal_method, |
- FX_BOOL interlace) { |
- CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
- pCodec->m_offSet = rcd_pos; |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; |
- if (!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), |
- error_status)) { |
- return FALSE; |
- } |
- uint8_t* pPalette = NULL; |
- if (pal_num != 0 && pal_ptr) { |
- pPalette = (uint8_t*)pal_ptr; |
- } else { |
- pal_num = pCodec->m_GifPltNumber; |
- pPalette = pCodec->m_pGifPalette; |
- } |
- if (pCodec->m_pSrcPalette == NULL) { |
- pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); |
- } else if (pal_num > pCodec->m_SrcPaletteNumber) { |
- pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num); |
- } |
- if (pCodec->m_pSrcPalette == NULL) { |
- return FALSE; |
- } |
- pCodec->m_SrcPaletteNumber = pal_num; |
- for (int i = 0; i < pal_num; i++) { |
- FX_DWORD j = i * 3; |
- pCodec->m_pSrcPalette[i] = |
- ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]); |
- } |
- pCodec->m_GifTransIndex = trans_index; |
- pCodec->m_GifFrameRect = img_rc; |
- pCodec->m_SrcPassNumber = interlace ? 4 : 1; |
- int32_t pal_index = pCodec->m_GifBgIndex; |
- CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap; |
- if (trans_index >= pal_num) { |
- trans_index = -1; |
- } |
- if (trans_index != -1) { |
- pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff; |
- if (pDevice->HasAlpha()) { |
- pal_index = trans_index; |
- } |
- } |
- int startX = pCodec->m_startX; |
- int startY = pCodec->m_startY; |
- int sizeX = pCodec->m_sizeX; |
- int sizeY = pCodec->m_sizeY; |
- int Bpp = pDevice->GetBPP() / 8; |
- FX_ARGB argb = pCodec->m_pSrcPalette[pal_index]; |
- for (int row = 0; row < sizeY; row++) { |
- uint8_t* pScanline = |
- (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp; |
- switch (pCodec->m_TransMethod) { |
- case 3: { |
- uint8_t gray = |
- FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); |
- FXSYS_memset(pScanline, gray, sizeX); |
- break; |
- } |
- case 8: { |
- for (int col = 0; col < sizeX; col++) { |
- *pScanline++ = FXARGB_B(argb); |
- *pScanline++ = FXARGB_G(argb); |
- *pScanline++ = FXARGB_R(argb); |
- pScanline += Bpp - 3; |
- } |
- break; |
- } |
- case 12: { |
- for (int col = 0; col < sizeX; col++) { |
- FXARGB_SETDIB(pScanline, argb); |
- pScanline += 4; |
- } |
- break; |
- } |
- } |
- } |
- return TRUE; |
-} |
-void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, |
- int32_t row_num, |
- uint8_t* row_buf) { |
- CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
- CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
- ASSERT(pDIBitmap != NULL); |
- int32_t img_width = pCodec->m_GifFrameRect.Width(); |
- if (!pDIBitmap->HasAlpha()) { |
- uint8_t* byte_ptr = row_buf; |
- for (int i = 0; i < img_width; i++) { |
- if (*byte_ptr == pCodec->m_GifTransIndex) { |
- *byte_ptr = pCodec->m_GifBgIndex; |
- } |
- byte_ptr++; |
- } |
- } |
- int32_t pal_index = pCodec->m_GifBgIndex; |
- if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) { |
- pal_index = pCodec->m_GifTransIndex; |
- } |
- FXSYS_memset(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth); |
- FX_BOOL bLastPass = (row_num % 2) == 1; |
- int32_t line = row_num + pCodec->m_GifFrameRect.top; |
- int32_t left = pCodec->m_GifFrameRect.left; |
- FXSYS_memcpy(pCodec->m_pDecodeBuf + left, row_buf, img_width); |
- int src_top = pCodec->m_clipBox.top; |
- int src_bottom = pCodec->m_clipBox.bottom; |
- 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; |
- FX_DWORD 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; |
- FX_DWORD 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, |
- int des_row) { |
- int des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
- FX_DWORD 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; |
- } |
- for (; des_row_1 < des_row; des_row_1++) { |
- uint8_t* scan_des = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; |
- PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); |
- const uint8_t* scan_src1 = |
- pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + |
- des_ScanOffet; |
- const uint8_t* scan_src2 = |
- pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; |
- for (int des_col = 0; des_col < m_sizeX; des_col++) { |
- switch (pDeviceBitmap->GetFormat()) { |
- case FXDIB_Invalid: |
- case FXDIB_1bppMask: |
- case FXDIB_1bppRgb: |
- return; |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: { |
- if (pDeviceBitmap->GetPalette() != NULL) { |
- return; |
- } |
- int des_g = 0; |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- *scan_des++ = (uint8_t)(des_g >> 16); |
- } break; |
- case FXDIB_Rgb: |
- case FXDIB_Rgb32: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- des_b += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_r += pWeight->m_Weights[0] * (*scan_src1++); |
- scan_src1 += des_Bpp - 3; |
- des_b += pWeight->m_Weights[1] * (*scan_src2++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- des_r += pWeight->m_Weights[1] * (*scan_src2++); |
- scan_src2 += des_Bpp - 3; |
- *scan_des++ = (uint8_t)((des_b) >> 16); |
- *scan_des++ = (uint8_t)((des_g) >> 16); |
- *scan_des++ = (uint8_t)((des_r) >> 16); |
- scan_des += des_Bpp - 3; |
- } break; |
- case FXDIB_Argb: { |
- FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
- des_b += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_r += pWeight->m_Weights[0] * (*scan_src1++); |
- des_a += pWeight->m_Weights[0] * (*scan_src1++); |
- des_b += pWeight->m_Weights[1] * (*scan_src2++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- des_r += pWeight->m_Weights[1] * (*scan_src2++); |
- des_a += pWeight->m_Weights[1] * (*scan_src2++); |
- *scan_des++ = (uint8_t)((des_b) >> 16); |
- *scan_des++ = (uint8_t)((des_g) >> 16); |
- *scan_des++ = (uint8_t)((des_r) >> 16); |
- *scan_des++ = (uint8_t)((des_a) >> 16); |
- } break; |
- default: |
- return; |
- } |
- } |
- } |
- int des_bottom = des_top + m_sizeY - 1; |
- if (des_row + (int)(2 * scale_y) >= des_bottom && |
- des_row + (int)scale_y < des_bottom) { |
- GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y); |
- } |
-} |
-FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, |
- FXCODEC_STATUS& err_status) { |
- FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); |
- if (dwSize <= m_offSet) { |
- return FALSE; |
- } |
- dwSize = dwSize - m_offSet; |
- FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL); |
- if (dwAvail == m_SrcSize) { |
- if (dwSize > FXCODEC_BLOCK_SIZE) { |
- dwSize = FXCODEC_BLOCK_SIZE; |
- } |
- m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / |
- FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; |
- m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); |
- if (!m_pSrcBuf) { |
- err_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- } else { |
- FX_DWORD dwConsume = m_SrcSize - dwAvail; |
- if (dwAvail) { |
- FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); |
- } |
- if (dwSize > dwConsume) { |
- dwSize = dwConsume; |
- } |
- } |
- if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { |
- err_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += dwSize; |
- pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail); |
- return TRUE; |
-} |
-FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback( |
- void* pModule, |
- FX_DWORD 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; |
-} |
-void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, |
- int32_t row_num, |
- uint8_t* row_buf) { |
- CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
- CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
- ASSERT(pDIBitmap != NULL); |
- FXSYS_memcpy(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize); |
- int src_top = pCodec->m_clipBox.top; |
- int src_bottom = pCodec->m_clipBox.bottom; |
- 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); |
- } |
- } |
- } |
-} |
-void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, |
- double scale_y, |
- int des_row) { |
- int des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
- FX_DWORD 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); |
- if (des_row_1 >= des_bottom - 1) { |
- uint8_t* scan_src = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
- while (++des_row < des_bottom) { |
- uint8_t* scan_des = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
- FX_DWORD size = m_sizeX * des_Bpp; |
- FXSYS_memcpy(scan_des, scan_src, size); |
- } |
- return; |
- } |
- for (; des_row_1 > des_row; des_row_1--) { |
- uint8_t* scan_des = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; |
- PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); |
- const uint8_t* scan_src1 = |
- pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + |
- des_ScanOffet; |
- const uint8_t* scan_src2 = |
- pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; |
- for (int des_col = 0; des_col < m_sizeX; des_col++) { |
- switch (pDeviceBitmap->GetFormat()) { |
- case FXDIB_Invalid: |
- case FXDIB_1bppMask: |
- case FXDIB_1bppRgb: |
- return; |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: { |
- if (pDeviceBitmap->GetPalette() != NULL) { |
- return; |
- } |
- int des_g = 0; |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- *scan_des++ = (uint8_t)(des_g >> 16); |
- } break; |
- case FXDIB_Rgb: |
- case FXDIB_Rgb32: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- des_b += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_r += pWeight->m_Weights[0] * (*scan_src1++); |
- scan_src1 += des_Bpp - 3; |
- des_b += pWeight->m_Weights[1] * (*scan_src2++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- des_r += pWeight->m_Weights[1] * (*scan_src2++); |
- scan_src2 += des_Bpp - 3; |
- *scan_des++ = (uint8_t)((des_b) >> 16); |
- *scan_des++ = (uint8_t)((des_g) >> 16); |
- *scan_des++ = (uint8_t)((des_r) >> 16); |
- scan_des += des_Bpp - 3; |
- } break; |
- case FXDIB_Argb: { |
- FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
- des_b += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_r += pWeight->m_Weights[0] * (*scan_src1++); |
- des_a += pWeight->m_Weights[0] * (*scan_src1++); |
- des_b += pWeight->m_Weights[1] * (*scan_src2++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- des_r += pWeight->m_Weights[1] * (*scan_src2++); |
- des_a += pWeight->m_Weights[1] * (*scan_src2++); |
- *scan_des++ = (uint8_t)((des_b) >> 16); |
- *scan_des++ = (uint8_t)((des_g) >> 16); |
- *scan_des++ = (uint8_t)((des_r) >> 16); |
- *scan_des++ = (uint8_t)((des_a) >> 16); |
- } break; |
- default: |
- return; |
- } |
- } |
- } |
-} |
-FX_BOOL CCodec_ProgressiveDecoder::DetectImageType( |
- FXCODEC_IMAGE_TYPE imageType, |
- CFX_DIBAttribute* pAttribute) { |
- m_offSet = 0; |
- FX_DWORD size = (FX_DWORD)m_pFile->GetSize(); |
- if (size > FXCODEC_BLOCK_SIZE) { |
- size = FXCODEC_BLOCK_SIZE; |
- } |
- if (m_pSrcBuf != NULL) { |
- FX_Free(m_pSrcBuf); |
- m_pSrcBuf = NULL; |
- } |
- m_pSrcBuf = FX_Alloc(uint8_t, size); |
- if (m_pSrcBuf == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- FXSYS_memset(m_pSrcBuf, 0, size); |
- m_SrcSize = size; |
- switch (imageType) { |
- case FXCODEC_IMAGE_BMP: { |
- ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); |
- if (pBmpModule == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- pBmpModule->InputImagePositionBufCallback = |
- BmpInputImagePositionBufCallback; |
- pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback; |
- m_pBmpContext = pBmpModule->Start((void*)this); |
- if (m_pBmpContext == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
- if (!bResult) { |
- m_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += size; |
- pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size); |
- FX_DWORD* pPalette = NULL; |
- int32_t readResult = pBmpModule->ReadHeader( |
- m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, |
- &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); |
- while (readResult == 2) { |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; |
- if (!BmpReadMoreData(pBmpModule, error_status)) { |
- m_status = error_status; |
- return FALSE; |
- } |
- readResult = pBmpModule->ReadHeader( |
- m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, |
- &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); |
- } |
- if (readResult == 1) { |
- m_SrcBPC = 8; |
- m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
- if (m_pSrcPalette != NULL) { |
- FX_Free(m_pSrcPalette); |
- m_pSrcPalette = NULL; |
- } |
- if (m_SrcPaletteNumber) { |
- m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber); |
- if (m_pSrcPalette == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- FXSYS_memcpy(m_pSrcPalette, pPalette, |
- m_SrcPaletteNumber * sizeof(FX_DWORD)); |
- } |
- return TRUE; |
- } |
- if (m_pBmpContext != NULL) { |
- pBmpModule->Finish(m_pBmpContext); |
- m_pBmpContext = NULL; |
- } |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } break; |
- case FXCODEC_IMAGE_JPG: { |
- ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); |
- if (pJpegModule == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- m_pJpegContext = pJpegModule->Start(); |
- if (m_pJpegContext == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
- if (!bResult) { |
- m_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += size; |
- pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size); |
- int32_t readResult = |
- pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, |
- &m_SrcComponents, pAttribute); |
- while (readResult == 2) { |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; |
- if (!JpegReadMoreData(pJpegModule, error_status)) { |
- m_status = error_status; |
- return FALSE; |
- } |
- readResult = |
- pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, |
- &m_SrcComponents, pAttribute); |
- } |
- if (!readResult) { |
- m_SrcBPC = 8; |
- m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
- return TRUE; |
- } |
- if (m_pJpegContext != NULL) { |
- pJpegModule->Finish(m_pJpegContext); |
- m_pJpegContext = NULL; |
- } |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } break; |
- case FXCODEC_IMAGE_PNG: { |
- ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); |
- if (pPngModule == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- pPngModule->ReadHeaderCallback = |
- CCodec_ProgressiveDecoder::PngReadHeaderFunc; |
- pPngModule->AskScanlineBufCallback = |
- CCodec_ProgressiveDecoder::PngAskScanlineBufFunc; |
- pPngModule->FillScanlineBufCompletedCallback = |
- CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc; |
- m_pPngContext = pPngModule->Start((void*)this); |
- if (m_pPngContext == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
- if (!bResult) { |
- m_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += size; |
- bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute); |
- while (bResult) { |
- FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; |
- FX_DWORD input_size = |
- remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; |
- if (input_size == 0) { |
- if (m_pPngContext != NULL) { |
- pPngModule->Finish(m_pPngContext); |
- } |
- m_pPngContext = NULL; |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } |
- if (m_pSrcBuf != NULL && input_size > m_SrcSize) { |
- FX_Free(m_pSrcBuf); |
- m_pSrcBuf = FX_Alloc(uint8_t, input_size); |
- if (m_pSrcBuf == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- FXSYS_memset(m_pSrcBuf, 0, input_size); |
- m_SrcSize = input_size; |
- } |
- bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); |
- if (!bResult) { |
- m_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += input_size; |
- bResult = |
- pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute); |
- } |
- ASSERT(!bResult); |
- if (m_pPngContext != NULL) { |
- pPngModule->Finish(m_pPngContext); |
- m_pPngContext = NULL; |
- } |
- if (m_SrcPassNumber == 0) { |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } |
- } break; |
- case FXCODEC_IMAGE_GIF: { |
- ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
- if (pGifModule == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- pGifModule->RecordCurrentPositionCallback = |
- CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback; |
- pGifModule->AskLocalPaletteBufCallback = |
- CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback; |
- pGifModule->InputRecordPositionBufCallback = |
- CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback; |
- pGifModule->ReadScanlineCallback = |
- CCodec_ProgressiveDecoder::GifReadScanlineCallback; |
- m_pGifContext = pGifModule->Start((void*)this); |
- if (m_pGifContext == NULL) { |
- m_status = FXCODEC_STATUS_ERR_MEMORY; |
- return FALSE; |
- } |
- FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
- if (!bResult) { |
- m_status = FXCODEC_STATUS_ERR_READ; |
- return FALSE; |
- } |
- m_offSet += size; |
- pGifModule->Input(m_pGifContext, m_pSrcBuf, size); |
- m_SrcComponents = 1; |
- int32_t readResult = pGifModule->ReadHeader( |
- m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, |
- (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); |
- while (readResult == 2) { |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; |
- if (!GifReadMoreData(pGifModule, error_status)) { |
- m_status = error_status; |
- return FALSE; |
- } |
- readResult = pGifModule->ReadHeader( |
- m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, |
- (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); |
- } |
- if (readResult == 1) { |
- m_SrcBPC = 8; |
- m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
- return TRUE; |
- } |
- if (m_pGifContext != NULL) { |
- pGifModule->Finish(m_pGifContext); |
- m_pGifContext = NULL; |
- } |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } break; |
- case FXCODEC_IMAGE_TIF: { |
- ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); |
- if (pTiffModule == NULL) { |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } |
- m_pTiffContext = pTiffModule->CreateDecoder(m_pFile); |
- if (m_pTiffContext == NULL) { |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } |
- int32_t frames = 0; |
- pTiffModule->GetFrames(m_pTiffContext, frames); |
- FX_DWORD bpc; |
- FX_BOOL ret = pTiffModule->LoadFrameInfo( |
- m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, |
- (FX_DWORD&)m_SrcComponents, bpc, pAttribute); |
- m_SrcComponents = 4; |
- m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
- if (!ret) { |
- pTiffModule->DestroyDecoder(m_pTiffContext); |
- (m_pTiffContext = NULL); |
- (m_status = FXCODEC_STATUS_ERR_FORMAT); |
- return FALSE; |
- } |
- } break; |
- default: |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- return FALSE; |
- } |
- return TRUE; |
-} |
-FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo( |
- IFX_FileRead* pFile, |
- FXCODEC_IMAGE_TYPE imageType, |
- CFX_DIBAttribute* pAttribute) { |
- switch (m_status) { |
- case FXCODEC_STATUS_FRAME_READY: |
- case FXCODEC_STATUS_FRAME_TOBECONTINUE: |
- case FXCODEC_STATUS_DECODE_READY: |
- case FXCODEC_STATUS_DECODE_TOBECONTINUE: |
- return FXCODEC_STATUS_ERROR; |
- default:; |
- } |
- if (pFile == NULL) { |
- m_status = FXCODEC_STATUS_ERR_PARAMS; |
- m_pFile = NULL; |
- return m_status; |
- } |
- m_pFile = pFile; |
- m_offSet = 0; |
- m_SrcWidth = m_SrcHeight = 0; |
- m_SrcComponents = m_SrcBPC = 0; |
- m_clipBox = FX_RECT(0, 0, 0, 0); |
- m_startX = m_startY = 0; |
- m_sizeX = m_sizeY = 0; |
- m_SrcPassNumber = 0; |
- if (imageType != FXCODEC_IMAGE_UNKNOWN && |
- DetectImageType(imageType, pAttribute)) { |
- m_imagType = imageType; |
- m_status = FXCODEC_STATUS_FRAME_READY; |
- return m_status; |
- } |
- for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) { |
- if (DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) { |
- m_imagType = (FXCODEC_IMAGE_TYPE)type; |
- m_status = FXCODEC_STATUS_FRAME_READY; |
- return m_status; |
- } |
- } |
- m_status = FXCODEC_STATUS_ERR_FORMAT; |
- m_pFile = NULL; |
- return m_status; |
-} |
-void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) { |
- 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; |
- } |
- 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; |
- int ratio_h = m_clipBox.Height() / m_sizeY; |
- int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w; |
- if (ratio >= 8) { |
- down_scale = 8; |
- } else if (ratio >= 4) { |
- down_scale = 4; |
- } else if (ratio >= 2) { |
- down_scale = 2; |
- } |
- m_clipBox.left /= down_scale; |
- m_clipBox.right /= down_scale; |
- m_clipBox.top /= down_scale; |
- m_clipBox.bottom /= down_scale; |
- if (m_clipBox.right == m_clipBox.left) { |
- m_clipBox.right = m_clipBox.left + 1; |
- } |
- if (m_clipBox.bottom == m_clipBox.top) { |
- m_clipBox.bottom = m_clipBox.top + 1; |
- } |
-} |
-void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, |
- FXCodec_Format src_format) { |
- switch (des_format) { |
- case FXDIB_1bppMask: |
- case FXDIB_1bppRgb: { |
- switch (src_format) { |
- case FXCodec_1bppGray: |
- m_TransMethod = 0; |
- break; |
- default: |
- m_TransMethod = -1; |
- } |
- } break; |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: { |
- switch (src_format) { |
- case FXCodec_1bppGray: |
- m_TransMethod = 1; |
- break; |
- case FXCodec_8bppGray: |
- m_TransMethod = 2; |
- break; |
- case FXCodec_1bppRgb: |
- case FXCodec_8bppRgb: |
- m_TransMethod = 3; |
- break; |
- case FXCodec_Rgb: |
- case FXCodec_Rgb32: |
- case FXCodec_Argb: |
- m_TransMethod = 4; |
- break; |
- case FXCodec_Cmyk: |
- m_TransMethod = 5; |
- break; |
- default: |
- m_TransMethod = -1; |
- } |
- } break; |
- case FXDIB_Rgb: { |
- switch (src_format) { |
- case FXCodec_1bppGray: |
- m_TransMethod = 6; |
- break; |
- case FXCodec_8bppGray: |
- m_TransMethod = 7; |
- break; |
- case FXCodec_1bppRgb: |
- case FXCodec_8bppRgb: |
- m_TransMethod = 8; |
- break; |
- case FXCodec_Rgb: |
- case FXCodec_Rgb32: |
- case FXCodec_Argb: |
- m_TransMethod = 9; |
- break; |
- case FXCodec_Cmyk: |
- m_TransMethod = 10; |
- break; |
- default: |
- m_TransMethod = -1; |
- } |
- } break; |
- case FXDIB_Rgb32: |
- case FXDIB_Argb: { |
- switch (src_format) { |
- case FXCodec_1bppGray: |
- m_TransMethod = 6; |
- break; |
- case FXCodec_8bppGray: |
- m_TransMethod = 7; |
- break; |
- case FXCodec_1bppRgb: |
- case FXCodec_8bppRgb: |
- if (des_format == FXDIB_Argb) { |
- m_TransMethod = 12; |
- } else { |
- m_TransMethod = 8; |
- } |
- break; |
- case FXCodec_Rgb: |
- case FXCodec_Rgb32: |
- m_TransMethod = 9; |
- break; |
- case FXCodec_Cmyk: |
- m_TransMethod = 10; |
- break; |
- case FXCodec_Argb: |
- m_TransMethod = 11; |
- break; |
- default: |
- m_TransMethod = -1; |
- } |
- } break; |
- default: |
- 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, |
- FXCodec_Format src_format) { |
- int src_left = m_clipBox.left; |
- int des_left = m_startX; |
- uint8_t* des_scan = |
- pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch(); |
- int src_bpp = src_format & 0xff; |
- int des_bpp = pDeviceBitmap->GetBPP(); |
- int src_Bpp = src_bpp >> 3; |
- int des_Bpp = des_bpp >> 3; |
- src_scan += src_left * src_Bpp; |
- des_scan += des_left * des_Bpp; |
- for (int des_col = 0; des_col < m_sizeX; des_col++) { |
- PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col); |
- switch (m_TransMethod) { |
- case -1: |
- return; |
- case 0: |
- return; |
- case 1: |
- return; |
- case 2: { |
- FX_DWORD des_g = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- des_g += pixel_weight * src_scan[j]; |
- } |
- *des_scan++ = (uint8_t)(des_g >> 16); |
- } break; |
- case 3: { |
- int des_r = 0, des_g = 0, des_b = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- unsigned long argb = m_pSrcPalette[src_scan[j]]; |
- des_r += pixel_weight * (uint8_t)(argb >> 16); |
- des_g += pixel_weight * (uint8_t)(argb >> 8); |
- des_b += pixel_weight * (uint8_t)argb; |
- } |
- *des_scan++ = |
- (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); |
- } break; |
- case 4: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- const uint8_t* src_pixel = src_scan + j * src_Bpp; |
- des_b += pixel_weight * (*src_pixel++); |
- des_g += pixel_weight * (*src_pixel++); |
- des_r += pixel_weight * (*src_pixel); |
- } |
- *des_scan++ = |
- (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); |
- } break; |
- case 5: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- const uint8_t* src_pixel = src_scan + j * src_Bpp; |
- uint8_t src_b = 0, src_g = 0, src_r = 0; |
- AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], |
- 255 - src_pixel[2], 255 - src_pixel[3], src_r, |
- src_g, src_b); |
- des_b += pixel_weight * src_b; |
- des_g += pixel_weight * src_g; |
- des_r += pixel_weight * src_r; |
- } |
- *des_scan++ = |
- (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); |
- } break; |
- case 6: |
- return; |
- case 7: { |
- FX_DWORD des_g = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- des_g += pixel_weight * src_scan[j]; |
- } |
- FXSYS_memset(des_scan, (uint8_t)(des_g >> 16), 3); |
- des_scan += des_Bpp; |
- } break; |
- case 8: { |
- int des_r = 0, des_g = 0, des_b = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- unsigned long argb = m_pSrcPalette[src_scan[j]]; |
- des_r += pixel_weight * (uint8_t)(argb >> 16); |
- des_g += pixel_weight * (uint8_t)(argb >> 8); |
- des_b += pixel_weight * (uint8_t)argb; |
- } |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- des_scan += des_Bpp - 3; |
- } break; |
- case 12: { |
- if (m_pBmpContext) { |
- int des_r = 0, des_g = 0, des_b = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- unsigned long argb = m_pSrcPalette[src_scan[j]]; |
- des_r += pixel_weight * (uint8_t)(argb >> 16); |
- des_g += pixel_weight * (uint8_t)(argb >> 8); |
- des_b += pixel_weight * (uint8_t)argb; |
- } |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- *des_scan++ = 0xFF; |
- } else { |
- int des_a = 0, des_r = 0, des_g = 0, des_b = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- unsigned long argb = m_pSrcPalette[src_scan[j]]; |
- des_a += pixel_weight * (uint8_t)(argb >> 24); |
- des_r += pixel_weight * (uint8_t)(argb >> 16); |
- des_g += pixel_weight * (uint8_t)(argb >> 8); |
- des_b += pixel_weight * (uint8_t)argb; |
- } |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- *des_scan++ = (uint8_t)((des_a) >> 16); |
- } |
- } break; |
- case 9: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- const uint8_t* src_pixel = src_scan + j * src_Bpp; |
- des_b += pixel_weight * (*src_pixel++); |
- des_g += pixel_weight * (*src_pixel++); |
- des_r += pixel_weight * (*src_pixel); |
- } |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- des_scan += des_Bpp - 3; |
- } break; |
- case 10: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- const uint8_t* src_pixel = src_scan + j * src_Bpp; |
- uint8_t src_b = 0, src_g = 0, src_r = 0; |
- AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], |
- 255 - src_pixel[2], 255 - src_pixel[3], src_r, |
- src_g, src_b); |
- des_b += pixel_weight * src_b; |
- des_g += pixel_weight * src_g; |
- des_r += pixel_weight * src_r; |
- } |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- des_scan += des_Bpp - 3; |
- } break; |
- case 11: { |
- FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0; |
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
- j++) { |
- int pixel_weight = |
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
- const uint8_t* src_pixel = src_scan + j * src_Bpp; |
- pixel_weight = pixel_weight * src_pixel[3] / 255; |
- des_b += pixel_weight * (*src_pixel++); |
- des_g += pixel_weight * (*src_pixel++); |
- des_r += pixel_weight * (*src_pixel); |
- des_alpha += pixel_weight; |
- } |
- *des_scan++ = (uint8_t)((des_b) >> 16); |
- *des_scan++ = (uint8_t)((des_g) >> 16); |
- *des_scan++ = (uint8_t)((des_r) >> 16); |
- *des_scan++ = (uint8_t)((des_alpha * 255) >> 16); |
- } break; |
- default: |
- return; |
- } |
- } |
-} |
-void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, |
- double scale_y, |
- int des_row) { |
- int des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
- FX_DWORD des_ScanOffet = m_startX * des_Bpp; |
- if (m_bInterpol) { |
- int des_top = m_startY; |
- int des_row_1 = des_row - int(scale_y); |
- if (des_row_1 < des_top) { |
- int des_bottom = des_top + m_sizeY; |
- if (des_row + (int)scale_y >= des_bottom - 1) { |
- uint8_t* scan_src = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
- while (++des_row < des_bottom) { |
- uint8_t* scan_des = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
- FX_DWORD size = m_sizeX * des_Bpp; |
- FXSYS_memcpy(scan_des, scan_src, size); |
- } |
- } |
- return; |
- } |
- for (; des_row_1 < des_row; des_row_1++) { |
- uint8_t* scan_des = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; |
- PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); |
- const uint8_t* scan_src1 = |
- pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + |
- des_ScanOffet; |
- const uint8_t* scan_src2 = |
- pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + |
- des_ScanOffet; |
- for (int des_col = 0; des_col < m_sizeX; des_col++) { |
- switch (pDeviceBitmap->GetFormat()) { |
- case FXDIB_Invalid: |
- case FXDIB_1bppMask: |
- case FXDIB_1bppRgb: |
- return; |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: { |
- if (pDeviceBitmap->GetPalette() != NULL) { |
- return; |
- } |
- int des_g = 0; |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- *scan_des++ = (uint8_t)(des_g >> 16); |
- } break; |
- case FXDIB_Rgb: |
- case FXDIB_Rgb32: { |
- FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
- des_b += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_r += pWeight->m_Weights[0] * (*scan_src1++); |
- scan_src1 += des_Bpp - 3; |
- des_b += pWeight->m_Weights[1] * (*scan_src2++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- des_r += pWeight->m_Weights[1] * (*scan_src2++); |
- scan_src2 += des_Bpp - 3; |
- *scan_des++ = (uint8_t)((des_b) >> 16); |
- *scan_des++ = (uint8_t)((des_g) >> 16); |
- *scan_des++ = (uint8_t)((des_r) >> 16); |
- scan_des += des_Bpp - 3; |
- } break; |
- case FXDIB_Argb: { |
- FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
- des_b += pWeight->m_Weights[0] * (*scan_src1++); |
- des_g += pWeight->m_Weights[0] * (*scan_src1++); |
- des_r += pWeight->m_Weights[0] * (*scan_src1++); |
- des_a += pWeight->m_Weights[0] * (*scan_src1++); |
- des_b += pWeight->m_Weights[1] * (*scan_src2++); |
- des_g += pWeight->m_Weights[1] * (*scan_src2++); |
- des_r += pWeight->m_Weights[1] * (*scan_src2++); |
- des_a += pWeight->m_Weights[1] * (*scan_src2++); |
- *scan_des++ = (uint8_t)((des_b) >> 16); |
- *scan_des++ = (uint8_t)((des_g) >> 16); |
- *scan_des++ = (uint8_t)((des_r) >> 16); |
- *scan_des++ = (uint8_t)((des_a) >> 16); |
- } break; |
- default: |
- return; |
- } |
- } |
- } |
- int des_bottom = des_top + m_sizeY; |
- if (des_row + (int)scale_y >= des_bottom - 1) { |
- uint8_t* scan_src = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
- while (++des_row < des_bottom) { |
- uint8_t* scan_des = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
- FX_DWORD size = m_sizeX * des_Bpp; |
- FXSYS_memcpy(scan_des, scan_src, size); |
- } |
- } |
- return; |
- } |
- int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1); |
- if (multiple > 0) { |
- uint8_t* scan_src = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
- for (int i = 1; i <= multiple; i++) { |
- if (des_row + i >= m_startY + m_sizeY) { |
- return; |
- } |
- uint8_t* scan_des = |
- (uint8_t*)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet; |
- FX_DWORD size = m_sizeX * des_Bpp; |
- FXSYS_memcpy(scan_des, scan_src, size); |
- } |
- } |
-} |
-void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, |
- int32_t src_line, |
- uint8_t* src_scan, |
- FXCodec_Format src_format) { |
- int src_top = m_clipBox.top; |
- int des_top = m_startY; |
- int src_hei = m_clipBox.Height(); |
- int des_hei = m_sizeY; |
- if (src_line >= src_top) { |
- double scale_y = (double)des_hei / (double)src_hei; |
- int src_row = src_line - src_top; |
- int des_row = (int)(src_row * scale_y) + des_top; |
- if (des_row >= des_top + des_hei) { |
- return; |
- } |
- ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format); |
- if (scale_y > 1.0) { |
- ResampleVert(pDeviceBitmap, scale_y, des_row); |
- } |
- } |
-} |
-FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, |
- IFX_Pause* pPause) { |
- if (!(m_status == FXCODEC_STATUS_FRAME_READY || |
- m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) { |
- return FXCODEC_STATUS_ERROR; |
- } |
- switch (m_imagType) { |
- case FXCODEC_IMAGE_BMP: |
- case FXCODEC_IMAGE_JPG: |
- case FXCODEC_IMAGE_PNG: |
- case FXCODEC_IMAGE_TIF: |
- frames = m_FrameNumber = 1; |
- return m_status = FXCODEC_STATUS_DECODE_READY; |
- case FXCODEC_IMAGE_GIF: { |
- ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
- while (TRUE) { |
- int32_t readResult = |
- pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); |
- while (readResult == 2) { |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ; |
- if (!GifReadMoreData(pGifModule, error_status)) { |
- return error_status; |
- } |
- if (pPause && pPause->NeedToPauseNow()) { |
- return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE; |
- } |
- readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); |
- } |
- if (readResult == 1) { |
- frames = m_FrameNumber; |
- return m_status = FXCODEC_STATUS_DECODE_READY; |
- } |
- if (m_pGifContext != NULL) { |
- pGifModule->Finish(m_pGifContext); |
- m_pGifContext = NULL; |
- } |
- return m_status = FXCODEC_STATUS_ERROR; |
- } |
- } break; |
- default:; |
- } |
- return FXCODEC_STATUS_ERROR; |
-} |
-FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, |
- int start_x, |
- int start_y, |
- int size_x, |
- int size_y, |
- int32_t frames, |
- FX_BOOL bInterpol) { |
- if (m_status != FXCODEC_STATUS_DECODE_READY) { |
- return FXCODEC_STATUS_ERROR; |
- } |
- if (pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 || frames < 0 || |
- frames >= m_FrameNumber) { |
- return FXCODEC_STATUS_ERR_PARAMS; |
- } |
- m_pDeviceBitmap = pDIBitmap; |
- if (m_clipBox.IsEmpty()) { |
- return FXCODEC_STATUS_ERR_PARAMS; |
- } |
- 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()) { |
- return FXCODEC_STATUS_ERR_PARAMS; |
- } |
- m_startX = device_rc.left; |
- m_startY = device_rc.top; |
- m_sizeX = device_rc.Width(); |
- m_sizeY = device_rc.Height(); |
- m_bInterpol = bInterpol; |
- m_FrameCur = 0; |
- if (start_x < 0 || out_range_x > 0) { |
- FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x; |
- if (start_x < 0) { |
- m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX); |
- } |
- if (out_range_x > 0) { |
- m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX); |
- } |
- } |
- if (start_y < 0 || out_range_y > 0) { |
- FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y; |
- if (start_y < 0) { |
- m_clipBox.top -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY); |
- } |
- if (out_range_y > 0) { |
- m_clipBox.bottom -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY); |
- } |
- } |
- if (m_clipBox.IsEmpty()) { |
- return FXCODEC_STATUS_ERR_PARAMS; |
- } |
- switch (m_imagType) { |
- case FXCODEC_IMAGE_JPG: { |
- ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); |
- int down_scale = 1; |
- GetDownScale(down_scale); |
- FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); |
- while (!bStart) { |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; |
- if (!JpegReadMoreData(pJpegModule, error_status)) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = error_status; |
- } |
- bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); |
- } |
- int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale; |
- scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4; |
- if (m_pDecodeBuf != NULL) { |
- FX_Free(m_pDecodeBuf); |
- m_pDecodeBuf = NULL; |
- } |
- m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); |
- if (m_pDecodeBuf == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- FXSYS_memset(m_pDecodeBuf, 0, scanline_size); |
- 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()); |
- switch (m_SrcComponents) { |
- case 1: |
- m_SrcFormat = FXCodec_8bppGray; |
- break; |
- case 3: |
- m_SrcFormat = FXCodec_Rgb; |
- break; |
- case 4: |
- m_SrcFormat = FXCodec_Cmyk; |
- break; |
- } |
- GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat); |
- return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- } break; |
- case FXCODEC_IMAGE_PNG: { |
- ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); |
- if (pPngModule == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- if (m_pPngContext != NULL) { |
- pPngModule->Finish(m_pPngContext); |
- m_pPngContext = NULL; |
- } |
- m_pPngContext = pPngModule->Start((void*)this); |
- if (m_pPngContext == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- m_offSet = 0; |
- switch (m_pDeviceBitmap->GetFormat()) { |
- case FXDIB_8bppMask: |
- case FXDIB_8bppRgb: |
- m_SrcComponents = 1; |
- m_SrcFormat = FXCodec_8bppGray; |
- break; |
- case FXDIB_Rgb: |
- m_SrcComponents = 3; |
- m_SrcFormat = FXCodec_Rgb; |
- break; |
- case FXDIB_Rgb32: |
- case FXDIB_Argb: |
- m_SrcComponents = 4; |
- m_SrcFormat = FXCodec_Argb; |
- break; |
- default: { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_PARAMS; |
- } |
- } |
- GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); |
- int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; |
- if (m_pDecodeBuf != NULL) { |
- FX_Free(m_pDecodeBuf); |
- m_pDecodeBuf = NULL; |
- } |
- m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); |
- if (m_pDecodeBuf == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- 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; |
- case FXCODEC_IMAGE_GIF: { |
- ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
- if (pGifModule == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- m_SrcFormat = FXCodec_8bppRgb; |
- GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); |
- int scanline_size = (m_SrcWidth + 3) / 4 * 4; |
- if (m_pDecodeBuf != NULL) { |
- FX_Free(m_pDecodeBuf); |
- m_pDecodeBuf = NULL; |
- } |
- m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); |
- if (m_pDecodeBuf == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- FXSYS_memset(m_pDecodeBuf, 0, scanline_size); |
- 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()); |
- m_FrameCur = frames; |
- return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- } break; |
- case FXCODEC_IMAGE_BMP: { |
- ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); |
- if (pBmpModule == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- switch (m_SrcComponents) { |
- case 1: |
- m_SrcFormat = FXCodec_8bppRgb; |
- break; |
- case 3: |
- m_SrcFormat = FXCodec_Rgb; |
- break; |
- case 4: |
- m_SrcFormat = FXCodec_Rgb32; |
- break; |
- } |
- GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); |
- m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; |
- if (m_pDecodeBuf != NULL) { |
- FX_Free(m_pDecodeBuf); |
- m_pDecodeBuf = NULL; |
- } |
- m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize); |
- if (m_pDecodeBuf == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- FXSYS_memset(m_pDecodeBuf, 0, m_ScanlineSize); |
- 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; |
- case FXCODEC_IMAGE_TIF: |
- return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- default: |
- break; |
- } |
- return FXCODEC_STATUS_ERROR; |
-} |
-FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { |
- if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
- return FXCODEC_STATUS_ERROR; |
- } |
- switch (m_imagType) { |
- case FXCODEC_IMAGE_JPG: { |
- ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); |
- while (TRUE) { |
- FX_BOOL readRes = |
- pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); |
- while (!readRes) { |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; |
- if (!JpegReadMoreData(pJpegModule, error_status)) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = error_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()); |
- } |
- if (m_SrcRow >= m_clipBox.bottom) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_DECODE_FINISH; |
- } |
- Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat); |
- m_SrcRow++; |
- if (pPause && pPause->NeedToPauseNow()) { |
- return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- } |
- } |
- } break; |
- case FXCODEC_IMAGE_PNG: { |
- ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); |
- while (TRUE) { |
- FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; |
- FX_DWORD input_size = |
- remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; |
- if (input_size == 0) { |
- if (m_pPngContext != NULL) { |
- pPngModule->Finish(m_pPngContext); |
- } |
- m_pPngContext = NULL; |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_DECODE_FINISH; |
- } |
- if (m_pSrcBuf != NULL && input_size > m_SrcSize) { |
- FX_Free(m_pSrcBuf); |
- m_pSrcBuf = FX_Alloc(uint8_t, input_size); |
- if (m_pSrcBuf == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- FXSYS_memset(m_pSrcBuf, 0, input_size); |
- m_SrcSize = input_size; |
- } |
- FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); |
- if (!bResult) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_READ; |
- } |
- m_offSet += input_size; |
- bResult = |
- pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, nullptr); |
- if (!bResult) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERROR; |
- } |
- if (pPause && pPause->NeedToPauseNow()) { |
- return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- } |
- } |
- } break; |
- case FXCODEC_IMAGE_GIF: { |
- ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
- while (TRUE) { |
- int32_t readRes = |
- pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); |
- while (readRes == 2) { |
- FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; |
- if (!GifReadMoreData(pGifModule, error_status)) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = error_status; |
- } |
- if (pPause && pPause->NeedToPauseNow()) { |
- return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- } |
- readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); |
- } |
- if (readRes == 1) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_DECODE_FINISH; |
- } |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERROR; |
- } |
- } break; |
- case FXCODEC_IMAGE_BMP: { |
- ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); |
- 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 = NULL; |
- m_pFile = NULL; |
- return m_status = error_status; |
- } |
- if (pPause && pPause->NeedToPauseNow()) { |
- return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- } |
- readRes = pBmpModule->LoadImage(m_pBmpContext); |
- } |
- if (readRes == 1) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_DECODE_FINISH; |
- } |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERROR; |
- } |
- } break; |
- case FXCODEC_IMAGE_TIF: { |
- ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); |
- FX_BOOL ret = FALSE; |
- if (m_pDeviceBitmap->GetBPP() == 32 && |
- m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX && |
- m_pDeviceBitmap->GetHeight() == m_SrcHeight && |
- m_SrcHeight == m_sizeY && m_startX == 0 && m_startY == 0 && |
- m_clipBox.left == 0 && m_clipBox.top == 0 && |
- m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) { |
- ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap); |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- 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() == NULL) { |
- delete pDIBitmap; |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap); |
- if (!ret) { |
- delete pDIBitmap; |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- 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 == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- CFX_DIBitmap* pFormatBitmap = NULL; |
- 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:; |
- } |
- switch (m_pDeviceBitmap->GetFormat()) { |
- case FXDIB_8bppRgb: |
- case FXDIB_8bppMask: { |
- for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { |
- uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); |
- uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); |
- for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { |
- uint8_t _a = 255 - src_line[3]; |
- uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; |
- uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; |
- uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; |
- *des_line++ = FXRGB2GRAY(r, g, b); |
- src_line += 4; |
- } |
- } |
- } break; |
- case FXDIB_Rgb: |
- case FXDIB_Rgb32: { |
- int32_t desBpp = |
- (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4; |
- for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { |
- uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); |
- uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); |
- for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { |
- uint8_t _a = 255 - src_line[3]; |
- uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; |
- uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; |
- uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; |
- *des_line++ = b; |
- *des_line++ = g; |
- *des_line++ = r; |
- des_line += desBpp - 3; |
- src_line += 4; |
- } |
- } |
- } break; |
- default:; |
- } |
- if (pClipBitmap != pFormatBitmap) { |
- delete pClipBitmap; |
- } |
- if (pFormatBitmap == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- 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 = NULL; |
- if (pStrechBitmap == NULL) { |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_ERR_MEMORY; |
- } |
- m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, |
- pStrechBitmap, 0, 0); |
- delete pStrechBitmap; |
- pStrechBitmap = NULL; |
- m_pDeviceBitmap = NULL; |
- m_pFile = NULL; |
- return m_status = FXCODEC_STATUS_DECODE_FINISH; |
- } |
- } break; |
- default: |
- break; |
- } |
- return FXCODEC_STATUS_ERROR; |
-} |
-ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { |
- return new CCodec_ProgressiveDecoder(this); |
-} |
+// Copyright 2014 PDFium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
+ |
+#include "core/include/fxge/fx_dib.h" |
+#include "core/include/fxcodec/fx_codec.h" |
+#include "fx_codec_progress.h" |
+void CFXCODEC_WeightTable::Calc(int dest_len, |
+ int dest_min, |
+ int dest_max, |
+ int src_len, |
+ int src_min, |
+ int src_max, |
+ FX_BOOL bInterpol) { |
+ if (m_pWeightTables) { |
+ FX_Free(m_pWeightTables); |
+ } |
+ double scale, base; |
+ scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len)); |
+ if (dest_len < 0) { |
+ base = (FX_FLOAT)(src_len); |
+ } else { |
+ base = 0.0f; |
+ } |
+ m_ItemSize = |
+ (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); |
+ if (m_pWeightTables == NULL) { |
+ return; |
+ } |
+ 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); |
+ double src_pos = dest_pixel * scale + scale / 2 + base; |
+ if (bInterpol) { |
+ pixel_weights.m_SrcStart = |
+ (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); |
+ pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); |
+ if (pixel_weights.m_SrcStart < src_min) { |
+ pixel_weights.m_SrcStart = src_min; |
+ } |
+ if (pixel_weights.m_SrcEnd >= src_max) { |
+ pixel_weights.m_SrcEnd = src_max - 1; |
+ } |
+ if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { |
+ pixel_weights.m_Weights[0] = 65536; |
+ } else { |
+ pixel_weights.m_Weights[1] = FXSYS_round( |
+ (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * |
+ 65536); |
+ pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; |
+ } |
+ } else { |
+ pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = |
+ (int)FXSYS_floor((FX_FLOAT)src_pos); |
+ pixel_weights.m_Weights[0] = 65536; |
+ } |
+ } |
+ return; |
+ } |
+ for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { |
+ PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); |
+ double src_start = dest_pixel * scale + base; |
+ double src_end = src_start + scale; |
+ int start_i, end_i; |
+ if (src_start < src_end) { |
+ start_i = (int)FXSYS_floor((FX_FLOAT)src_start); |
+ end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); |
+ } else { |
+ start_i = (int)FXSYS_floor((FX_FLOAT)src_end); |
+ end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); |
+ } |
+ if (start_i < src_min) { |
+ start_i = src_min; |
+ } |
+ if (end_i >= src_max) { |
+ end_i = src_max - 1; |
+ } |
+ if (start_i > end_i) { |
+ pixel_weights.m_SrcStart = start_i; |
+ pixel_weights.m_SrcEnd = start_i; |
+ continue; |
+ } |
+ pixel_weights.m_SrcStart = start_i; |
+ pixel_weights.m_SrcEnd = end_i; |
+ for (int j = start_i; j <= end_i; j++) { |
+ double dest_start = FXSYS_Div((FX_FLOAT)(j)-base, scale); |
+ double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale); |
+ if (dest_start > dest_end) { |
+ double temp = dest_start; |
+ dest_start = dest_end; |
+ dest_end = temp; |
+ } |
+ double area_start = dest_start > (FX_FLOAT)(dest_pixel) |
+ ? dest_start |
+ : (FX_FLOAT)(dest_pixel); |
+ double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) |
+ ? (FX_FLOAT)(dest_pixel + 1) |
+ : dest_end; |
+ double weight = area_start >= area_end ? 0.0f : area_end - area_start; |
+ if (weight == 0 && j == end_i) { |
+ pixel_weights.m_SrcEnd--; |
+ break; |
+ } |
+ pixel_weights.m_Weights[j - start_i] = |
+ FXSYS_round((FX_FLOAT)(weight * 65536)); |
+ } |
+ } |
+} |
+void 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); |
+ if (m_pWeightTables == NULL) { |
+ return; |
+ } |
+ FXSYS_memset(m_pWeightTables, 0, size); |
+ 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); |
+ 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->m_SrcStart = pWeight->m_SrcEnd = src_col; |
+ pWeight->m_Weights[0] = 65536; |
+ pWeight->m_Weights[1] = 0; |
+ } |
+ return; |
+ } |
+ 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->m_SrcStart = src_col - 1; |
+ pWeight->m_SrcEnd = src_col; |
+ pWeight->m_Weights[0] = |
+ bInterpol ? FXSYS_round((FX_FLOAT)( |
+ ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index) / |
+ (FX_FLOAT)des_col_len * 65536)) |
+ : 65536; |
+ pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; |
+ } |
+ pre_des_col = des_col; |
+ } |
+ return; |
+ } |
+ 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); |
+ pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col; |
+ pWeight->m_Weights[0] = 65536; |
+ pWeight->m_Weights[1] = 0; |
+ } |
+} |
+void 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); |
+ if (m_pWeightTables == NULL) { |
+ return; |
+ } |
+ FXSYS_memset(m_pWeightTables, 0, size); |
+ if (scale > 1) { |
+ double step = 0.0; |
+ int src_row = 0; |
+ while (step < (double)dest_len) { |
+ int start_step = (int)step; |
+ step = scale * (++src_row); |
+ int end_step = (int)step; |
+ if (end_step >= dest_len) { |
+ end_step = dest_len; |
+ for (int des_row = start_step; des_row < end_step; des_row++) { |
+ PixelWeight* pWeight = |
+ (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); |
+ pWeight->m_SrcStart = start_step; |
+ pWeight->m_SrcEnd = start_step; |
+ pWeight->m_Weights[0] = 65536; |
+ pWeight->m_Weights[1] = 0; |
+ } |
+ return; |
+ } |
+ int length = end_step - start_step; |
+ { |
+ PixelWeight* pWeight = |
+ (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize); |
+ pWeight->m_SrcStart = start_step; |
+ pWeight->m_SrcEnd = start_step; |
+ pWeight->m_Weights[0] = 65536; |
+ pWeight->m_Weights[1] = 0; |
+ } |
+ for (int des_row = start_step + 1; des_row < end_step; des_row++) { |
+ PixelWeight* pWeight = |
+ (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize); |
+ pWeight->m_SrcStart = start_step; |
+ pWeight->m_SrcEnd = end_step; |
+ pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / |
+ (FX_FLOAT)length * 65536); |
+ pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0]; |
+ } |
+ } |
+ } else { |
+ 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; |
+ pWeight->m_Weights[0] = 65536; |
+ pWeight->m_Weights[1] = 0; |
+ } |
+ } |
+} |
+CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder( |
+ CCodec_ModuleMgr* pCodecMgr) { |
+ m_pFile = NULL; |
+ m_pJpegContext = NULL; |
+ m_pPngContext = NULL; |
+ m_pGifContext = NULL; |
+ m_pBmpContext = NULL; |
+ m_pTiffContext = NULL; |
+ m_pCodecMgr = NULL; |
+ m_pSrcBuf = NULL; |
+ m_pDecodeBuf = NULL; |
+ m_pDeviceBitmap = NULL; |
+ m_pSrcPalette = NULL; |
+ m_pCodecMgr = pCodecMgr; |
+ m_offSet = 0; |
+ m_SrcSize = 0; |
+ m_ScanlineSize = 0; |
+ m_SrcWidth = m_SrcHeight = 0; |
+ m_SrcComponents = 0; |
+ m_SrcBPC = 0; |
+ m_SrcPassNumber = 0; |
+ m_clipBox = FX_RECT(0, 0, 0, 0); |
+ m_imagType = FXCODEC_IMAGE_UNKNOWN; |
+ m_status = FXCODEC_STATUS_DECODE_FINISH; |
+ m_TransMethod = -1; |
+ m_SrcRow = 0; |
+ m_SrcFormat = FXCodec_Invalid; |
+ m_bInterpol = TRUE; |
+ m_FrameNumber = 0; |
+ m_FrameCur = 0; |
+ m_SrcPaletteNumber = 0; |
+ m_GifPltNumber = 0; |
+ m_GifBgIndex = 0; |
+ m_pGifPalette = NULL; |
+ m_GifTransIndex = -1; |
+ m_GifFrameRect = FX_RECT(0, 0, 0, 0); |
+ m_BmpIsTopBottom = FALSE; |
+} |
+CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { |
+ m_pFile = NULL; |
+ if (m_pJpegContext != NULL) { |
+ m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); |
+ } |
+ if (m_pPngContext != NULL) { |
+ m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); |
+ } |
+ if (m_pGifContext != NULL) { |
+ m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); |
+ } |
+ if (m_pBmpContext != NULL) { |
+ m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); |
+ } |
+ if (m_pTiffContext != NULL) { |
+ m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); |
+ } |
+ if (m_pSrcBuf != NULL) { |
+ FX_Free(m_pSrcBuf); |
+ } |
+ if (m_pDecodeBuf != NULL) { |
+ FX_Free(m_pDecodeBuf); |
+ } |
+ if (m_pSrcPalette != NULL) { |
+ FX_Free(m_pSrcPalette); |
+ } |
+} |
+FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData( |
+ ICodec_JpegModule* pJpegModule, |
+ FXCODEC_STATUS& err_status) { |
+ FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); |
+ if (dwSize <= m_offSet) { |
+ return FALSE; |
+ } |
+ dwSize = dwSize - m_offSet; |
+ FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL); |
+ if (dwAvail == m_SrcSize) { |
+ if (dwSize > FXCODEC_BLOCK_SIZE) { |
+ dwSize = FXCODEC_BLOCK_SIZE; |
+ } |
+ m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / |
+ FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; |
+ m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); |
+ if (!m_pSrcBuf) { |
+ err_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ } else { |
+ FX_DWORD dwConsume = m_SrcSize - dwAvail; |
+ if (dwAvail) { |
+ FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); |
+ } |
+ if (dwSize > dwConsume) { |
+ dwSize = dwConsume; |
+ } |
+ } |
+ if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { |
+ err_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += dwSize; |
+ pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail); |
+ return TRUE; |
+} |
+FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, |
+ int width, |
+ int height, |
+ int bpc, |
+ int pass, |
+ int* color_type, |
+ double* gamma) { |
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
+ if (pCodec->m_pDeviceBitmap == NULL) { |
+ pCodec->m_SrcWidth = width; |
+ 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; |
+ pCodec->m_clipBox = FX_RECT(0, 0, width, height); |
+ return FALSE; |
+ } |
+ FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat(); |
+ switch (format) { |
+ case FXDIB_1bppMask: |
+ case FXDIB_1bppRgb: |
+ ASSERT(FALSE); |
+ return FALSE; |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: |
+ *color_type = 0; |
+ break; |
+ case FXDIB_Rgb: |
+ *color_type = 2; |
+ break; |
+ case FXDIB_Rgb32: |
+ case FXDIB_Argb: |
+ *color_type = 6; |
+ break; |
+ default: |
+ ASSERT(FALSE); |
+ return FALSE; |
+ } |
+ *gamma = FXCODEC_PNG_GAMMA; |
+ return TRUE; |
+} |
+FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, |
+ int line, |
+ uint8_t*& src_buf) { |
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
+ ASSERT(pDIBitmap != NULL); |
+ if (pDIBitmap == NULL) { |
+ return FALSE; |
+ } |
+ if (line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) { |
+ double scale_y = |
+ (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height(); |
+ int32_t row = |
+ (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY; |
+ uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row); |
+ uint8_t* des_scan = pCodec->m_pDecodeBuf; |
+ src_buf = pCodec->m_pDecodeBuf; |
+ int32_t src_Bpp = pDIBitmap->GetBPP() >> 3; |
+ int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3; |
+ int32_t src_left = pCodec->m_startX; |
+ int32_t des_left = pCodec->m_clipBox.left; |
+ src_scan += src_left * src_Bpp; |
+ des_scan += des_left * des_Bpp; |
+ for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) { |
+ PixelWeight* pPixelWeights = |
+ pCodec->m_WeightHorzOO.GetPixelWeight(src_col); |
+ if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) { |
+ continue; |
+ } |
+ switch (pDIBitmap->GetFormat()) { |
+ case FXDIB_1bppMask: |
+ case FXDIB_1bppRgb: |
+ ASSERT(FALSE); |
+ return FALSE; |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: { |
+ if (pDIBitmap->GetPalette() != NULL) { |
+ return FALSE; |
+ } |
+ FX_DWORD des_g = 0; |
+ des_g += pPixelWeights->m_Weights[0] * src_scan[src_col]; |
+ des_scan[pPixelWeights->m_SrcStart] = (uint8_t)(des_g >> 16); |
+ } break; |
+ case FXDIB_Rgb: |
+ case FXDIB_Rgb32: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ const uint8_t* p = src_scan + src_col * src_Bpp; |
+ des_b += pPixelWeights->m_Weights[0] * (*p++); |
+ des_g += pPixelWeights->m_Weights[0] * (*p++); |
+ des_r += pPixelWeights->m_Weights[0] * (*p); |
+ uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; |
+ *pDes++ = (uint8_t)((des_b) >> 16); |
+ *pDes++ = (uint8_t)((des_g) >> 16); |
+ *pDes = (uint8_t)((des_r) >> 16); |
+ } break; |
+ case FXDIB_Argb: { |
+ FX_DWORD des_r = 0, des_g = 0, des_b = 0; |
+ const uint8_t* p = src_scan + src_col * src_Bpp; |
+ des_b += pPixelWeights->m_Weights[0] * (*p++); |
+ des_g += pPixelWeights->m_Weights[0] * (*p++); |
+ des_r += pPixelWeights->m_Weights[0] * (*p++); |
+ uint8_t* pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp]; |
+ *pDes++ = (uint8_t)((des_b) >> 16); |
+ *pDes++ = (uint8_t)((des_g) >> 16); |
+ *pDes++ = (uint8_t)((des_r) >> 16); |
+ *pDes = *p; |
+ } break; |
+ default: |
+ return FALSE; |
+ } |
+ } |
+ } |
+ return TRUE; |
+} |
+void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz( |
+ CFX_DIBitmap* pDeviceBitmap, |
+ int32_t des_line, |
+ uint8_t* src_scan, |
+ FXCodec_Format src_format) { |
+ uint8_t* des_scan = (uint8_t*)pDeviceBitmap->GetScanline(des_line); |
+ int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3; |
+ int32_t des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
+ int32_t src_left = m_clipBox.left; |
+ int32_t des_left = m_startX; |
+ src_scan += src_left * src_Bpp; |
+ des_scan += des_left * des_Bpp; |
+ for (int32_t des_col = 0; des_col < m_sizeX; des_col++) { |
+ PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col); |
+ switch (pDeviceBitmap->GetFormat()) { |
+ case FXDIB_1bppMask: |
+ case FXDIB_1bppRgb: |
+ ASSERT(FALSE); |
+ return; |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: { |
+ if (pDeviceBitmap->GetPalette() != NULL) { |
+ return; |
+ } |
+ FX_DWORD des_g = 0; |
+ des_g += |
+ pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart]; |
+ des_g += |
+ pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd]; |
+ *des_scan++ = (uint8_t)(des_g >> 16); |
+ } break; |
+ case FXDIB_Rgb: |
+ case FXDIB_Rgb32: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ const uint8_t* p = src_scan; |
+ p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; |
+ des_b += pPixelWeights->m_Weights[0] * (*p++); |
+ des_g += pPixelWeights->m_Weights[0] * (*p++); |
+ des_r += pPixelWeights->m_Weights[0] * (*p); |
+ p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; |
+ des_b += pPixelWeights->m_Weights[1] * (*p++); |
+ des_g += pPixelWeights->m_Weights[1] * (*p++); |
+ des_r += pPixelWeights->m_Weights[1] * (*p); |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ des_scan += des_Bpp - 3; |
+ } break; |
+ case FXDIB_Argb: { |
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
+ const uint8_t* p = src_scan; |
+ p = src_scan + pPixelWeights->m_SrcStart * src_Bpp; |
+ des_b += pPixelWeights->m_Weights[0] * (*p++); |
+ des_g += pPixelWeights->m_Weights[0] * (*p++); |
+ des_r += pPixelWeights->m_Weights[0] * (*p++); |
+ des_a += pPixelWeights->m_Weights[0] * (*p); |
+ p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp; |
+ des_b += pPixelWeights->m_Weights[1] * (*p++); |
+ des_g += pPixelWeights->m_Weights[1] * (*p++); |
+ des_r += pPixelWeights->m_Weights[1] * (*p++); |
+ des_a += pPixelWeights->m_Weights[1] * (*p); |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ *des_scan++ = (uint8_t)((des_a) >> 16); |
+ } break; |
+ default: |
+ return; |
+ } |
+ } |
+} |
+void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, |
+ int pass, |
+ int line) { |
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
+ ASSERT(pDIBitmap != NULL); |
+ int src_top = pCodec->m_clipBox.top; |
+ int src_bottom = pCodec->m_clipBox.bottom; |
+ 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->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, |
+ pCodec->m_SrcFormat); |
+ if (pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) { |
+ pCodec->ResampleVert(pDIBitmap, scale_y, des_row); |
+ return; |
+ } |
+ if (pass == 6 && scale_y > 1.0) { |
+ pCodec->ResampleVert(pDIBitmap, scale_y, des_row); |
+ } |
+ } |
+} |
+FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, |
+ FXCODEC_STATUS& err_status) { |
+ FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); |
+ if (dwSize <= m_offSet) { |
+ return FALSE; |
+ } |
+ dwSize = dwSize - m_offSet; |
+ FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL); |
+ if (dwAvail == m_SrcSize) { |
+ if (dwSize > FXCODEC_BLOCK_SIZE) { |
+ dwSize = FXCODEC_BLOCK_SIZE; |
+ } |
+ m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / |
+ FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; |
+ m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); |
+ if (!m_pSrcBuf) { |
+ err_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ } else { |
+ FX_DWORD dwConsume = m_SrcSize - dwAvail; |
+ if (dwAvail) { |
+ FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); |
+ } |
+ if (dwSize > dwConsume) { |
+ dwSize = dwConsume; |
+ } |
+ } |
+ if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { |
+ err_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += dwSize; |
+ pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail); |
+ return TRUE; |
+} |
+void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback( |
+ void* pModule, |
+ FX_DWORD& cur_pos) { |
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
+ FX_DWORD remain_size = |
+ 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, |
+ FX_DWORD rcd_pos, |
+ const FX_RECT& img_rc, |
+ int32_t pal_num, |
+ void* pal_ptr, |
+ int32_t delay_time, |
+ FX_BOOL user_input, |
+ int32_t trans_index, |
+ int32_t disposal_method, |
+ FX_BOOL interlace) { |
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
+ pCodec->m_offSet = rcd_pos; |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; |
+ if (!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), |
+ error_status)) { |
+ return FALSE; |
+ } |
+ uint8_t* pPalette = NULL; |
+ if (pal_num != 0 && pal_ptr) { |
+ pPalette = (uint8_t*)pal_ptr; |
+ } else { |
+ pal_num = pCodec->m_GifPltNumber; |
+ pPalette = pCodec->m_pGifPalette; |
+ } |
+ if (pCodec->m_pSrcPalette == NULL) { |
+ pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); |
+ } else if (pal_num > pCodec->m_SrcPaletteNumber) { |
+ pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num); |
+ } |
+ if (pCodec->m_pSrcPalette == NULL) { |
+ return FALSE; |
+ } |
+ pCodec->m_SrcPaletteNumber = pal_num; |
+ for (int i = 0; i < pal_num; i++) { |
+ FX_DWORD j = i * 3; |
+ pCodec->m_pSrcPalette[i] = |
+ ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]); |
+ } |
+ pCodec->m_GifTransIndex = trans_index; |
+ pCodec->m_GifFrameRect = img_rc; |
+ pCodec->m_SrcPassNumber = interlace ? 4 : 1; |
+ int32_t pal_index = pCodec->m_GifBgIndex; |
+ CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap; |
+ if (trans_index >= pal_num) { |
+ trans_index = -1; |
+ } |
+ if (trans_index != -1) { |
+ pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff; |
+ if (pDevice->HasAlpha()) { |
+ pal_index = trans_index; |
+ } |
+ } |
+ int startX = pCodec->m_startX; |
+ int startY = pCodec->m_startY; |
+ int sizeX = pCodec->m_sizeX; |
+ int sizeY = pCodec->m_sizeY; |
+ int Bpp = pDevice->GetBPP() / 8; |
+ FX_ARGB argb = pCodec->m_pSrcPalette[pal_index]; |
+ for (int row = 0; row < sizeY; row++) { |
+ uint8_t* pScanline = |
+ (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp; |
+ switch (pCodec->m_TransMethod) { |
+ case 3: { |
+ uint8_t gray = |
+ FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); |
+ FXSYS_memset(pScanline, gray, sizeX); |
+ break; |
+ } |
+ case 8: { |
+ for (int col = 0; col < sizeX; col++) { |
+ *pScanline++ = FXARGB_B(argb); |
+ *pScanline++ = FXARGB_G(argb); |
+ *pScanline++ = FXARGB_R(argb); |
+ pScanline += Bpp - 3; |
+ } |
+ break; |
+ } |
+ case 12: { |
+ for (int col = 0; col < sizeX; col++) { |
+ FXARGB_SETDIB(pScanline, argb); |
+ pScanline += 4; |
+ } |
+ break; |
+ } |
+ } |
+ } |
+ return TRUE; |
+} |
+void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, |
+ int32_t row_num, |
+ uint8_t* row_buf) { |
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
+ ASSERT(pDIBitmap != NULL); |
+ int32_t img_width = pCodec->m_GifFrameRect.Width(); |
+ if (!pDIBitmap->HasAlpha()) { |
+ uint8_t* byte_ptr = row_buf; |
+ for (int i = 0; i < img_width; i++) { |
+ if (*byte_ptr == pCodec->m_GifTransIndex) { |
+ *byte_ptr = pCodec->m_GifBgIndex; |
+ } |
+ byte_ptr++; |
+ } |
+ } |
+ int32_t pal_index = pCodec->m_GifBgIndex; |
+ if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) { |
+ pal_index = pCodec->m_GifTransIndex; |
+ } |
+ FXSYS_memset(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth); |
+ FX_BOOL bLastPass = (row_num % 2) == 1; |
+ int32_t line = row_num + pCodec->m_GifFrameRect.top; |
+ int32_t left = pCodec->m_GifFrameRect.left; |
+ FXSYS_memcpy(pCodec->m_pDecodeBuf + left, row_buf, img_width); |
+ int src_top = pCodec->m_clipBox.top; |
+ int src_bottom = pCodec->m_clipBox.bottom; |
+ 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; |
+ FX_DWORD 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; |
+ FX_DWORD 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, |
+ int des_row) { |
+ int des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
+ FX_DWORD 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; |
+ } |
+ for (; des_row_1 < des_row; des_row_1++) { |
+ uint8_t* scan_des = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; |
+ PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); |
+ const uint8_t* scan_src1 = |
+ pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + |
+ des_ScanOffet; |
+ const uint8_t* scan_src2 = |
+ pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; |
+ for (int des_col = 0; des_col < m_sizeX; des_col++) { |
+ switch (pDeviceBitmap->GetFormat()) { |
+ case FXDIB_Invalid: |
+ case FXDIB_1bppMask: |
+ case FXDIB_1bppRgb: |
+ return; |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: { |
+ if (pDeviceBitmap->GetPalette() != NULL) { |
+ return; |
+ } |
+ int des_g = 0; |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ *scan_des++ = (uint8_t)(des_g >> 16); |
+ } break; |
+ case FXDIB_Rgb: |
+ case FXDIB_Rgb32: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ des_b += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_r += pWeight->m_Weights[0] * (*scan_src1++); |
+ scan_src1 += des_Bpp - 3; |
+ des_b += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_r += pWeight->m_Weights[1] * (*scan_src2++); |
+ scan_src2 += des_Bpp - 3; |
+ *scan_des++ = (uint8_t)((des_b) >> 16); |
+ *scan_des++ = (uint8_t)((des_g) >> 16); |
+ *scan_des++ = (uint8_t)((des_r) >> 16); |
+ scan_des += des_Bpp - 3; |
+ } break; |
+ case FXDIB_Argb: { |
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
+ des_b += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_r += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_a += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_b += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_r += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_a += pWeight->m_Weights[1] * (*scan_src2++); |
+ *scan_des++ = (uint8_t)((des_b) >> 16); |
+ *scan_des++ = (uint8_t)((des_g) >> 16); |
+ *scan_des++ = (uint8_t)((des_r) >> 16); |
+ *scan_des++ = (uint8_t)((des_a) >> 16); |
+ } break; |
+ default: |
+ return; |
+ } |
+ } |
+ } |
+ int des_bottom = des_top + m_sizeY - 1; |
+ if (des_row + (int)(2 * scale_y) >= des_bottom && |
+ des_row + (int)scale_y < des_bottom) { |
+ GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y); |
+ } |
+} |
+FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, |
+ FXCODEC_STATUS& err_status) { |
+ FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize(); |
+ if (dwSize <= m_offSet) { |
+ return FALSE; |
+ } |
+ dwSize = dwSize - m_offSet; |
+ FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL); |
+ if (dwAvail == m_SrcSize) { |
+ if (dwSize > FXCODEC_BLOCK_SIZE) { |
+ dwSize = FXCODEC_BLOCK_SIZE; |
+ } |
+ m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / |
+ FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE; |
+ m_pSrcBuf = FX_Realloc(uint8_t, m_pSrcBuf, m_SrcSize); |
+ if (!m_pSrcBuf) { |
+ err_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ } else { |
+ FX_DWORD dwConsume = m_SrcSize - dwAvail; |
+ if (dwAvail) { |
+ FXSYS_memcpy(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail); |
+ } |
+ if (dwSize > dwConsume) { |
+ dwSize = dwConsume; |
+ } |
+ } |
+ if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) { |
+ err_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += dwSize; |
+ pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail); |
+ return TRUE; |
+} |
+FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback( |
+ void* pModule, |
+ FX_DWORD 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; |
+} |
+void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, |
+ int32_t row_num, |
+ uint8_t* row_buf) { |
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; |
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; |
+ ASSERT(pDIBitmap != NULL); |
+ FXSYS_memcpy(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize); |
+ int src_top = pCodec->m_clipBox.top; |
+ int src_bottom = pCodec->m_clipBox.bottom; |
+ 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); |
+ } |
+ } |
+ } |
+} |
+void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, |
+ double scale_y, |
+ int des_row) { |
+ int des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
+ FX_DWORD 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); |
+ if (des_row_1 >= des_bottom - 1) { |
+ uint8_t* scan_src = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
+ while (++des_row < des_bottom) { |
+ uint8_t* scan_des = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
+ FX_DWORD size = m_sizeX * des_Bpp; |
+ FXSYS_memcpy(scan_des, scan_src, size); |
+ } |
+ return; |
+ } |
+ for (; des_row_1 > des_row; des_row_1--) { |
+ uint8_t* scan_des = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; |
+ PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); |
+ const uint8_t* scan_src1 = |
+ pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + |
+ des_ScanOffet; |
+ const uint8_t* scan_src2 = |
+ pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet; |
+ for (int des_col = 0; des_col < m_sizeX; des_col++) { |
+ switch (pDeviceBitmap->GetFormat()) { |
+ case FXDIB_Invalid: |
+ case FXDIB_1bppMask: |
+ case FXDIB_1bppRgb: |
+ return; |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: { |
+ if (pDeviceBitmap->GetPalette() != NULL) { |
+ return; |
+ } |
+ int des_g = 0; |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ *scan_des++ = (uint8_t)(des_g >> 16); |
+ } break; |
+ case FXDIB_Rgb: |
+ case FXDIB_Rgb32: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ des_b += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_r += pWeight->m_Weights[0] * (*scan_src1++); |
+ scan_src1 += des_Bpp - 3; |
+ des_b += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_r += pWeight->m_Weights[1] * (*scan_src2++); |
+ scan_src2 += des_Bpp - 3; |
+ *scan_des++ = (uint8_t)((des_b) >> 16); |
+ *scan_des++ = (uint8_t)((des_g) >> 16); |
+ *scan_des++ = (uint8_t)((des_r) >> 16); |
+ scan_des += des_Bpp - 3; |
+ } break; |
+ case FXDIB_Argb: { |
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
+ des_b += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_r += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_a += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_b += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_r += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_a += pWeight->m_Weights[1] * (*scan_src2++); |
+ *scan_des++ = (uint8_t)((des_b) >> 16); |
+ *scan_des++ = (uint8_t)((des_g) >> 16); |
+ *scan_des++ = (uint8_t)((des_r) >> 16); |
+ *scan_des++ = (uint8_t)((des_a) >> 16); |
+ } break; |
+ default: |
+ return; |
+ } |
+ } |
+ } |
+} |
+FX_BOOL CCodec_ProgressiveDecoder::DetectImageType( |
+ FXCODEC_IMAGE_TYPE imageType, |
+ CFX_DIBAttribute* pAttribute) { |
+ m_offSet = 0; |
+ FX_DWORD size = (FX_DWORD)m_pFile->GetSize(); |
+ if (size > FXCODEC_BLOCK_SIZE) { |
+ size = FXCODEC_BLOCK_SIZE; |
+ } |
+ if (m_pSrcBuf != NULL) { |
+ FX_Free(m_pSrcBuf); |
+ m_pSrcBuf = NULL; |
+ } |
+ m_pSrcBuf = FX_Alloc(uint8_t, size); |
+ if (m_pSrcBuf == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ FXSYS_memset(m_pSrcBuf, 0, size); |
+ m_SrcSize = size; |
+ switch (imageType) { |
+ case FXCODEC_IMAGE_BMP: { |
+ ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); |
+ if (pBmpModule == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ pBmpModule->InputImagePositionBufCallback = |
+ BmpInputImagePositionBufCallback; |
+ pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback; |
+ m_pBmpContext = pBmpModule->Start((void*)this); |
+ if (m_pBmpContext == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
+ if (!bResult) { |
+ m_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += size; |
+ pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size); |
+ FX_DWORD* pPalette = NULL; |
+ int32_t readResult = pBmpModule->ReadHeader( |
+ m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, |
+ &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); |
+ while (readResult == 2) { |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; |
+ if (!BmpReadMoreData(pBmpModule, error_status)) { |
+ m_status = error_status; |
+ return FALSE; |
+ } |
+ readResult = pBmpModule->ReadHeader( |
+ m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom, |
+ &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute); |
+ } |
+ if (readResult == 1) { |
+ m_SrcBPC = 8; |
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
+ if (m_pSrcPalette != NULL) { |
+ FX_Free(m_pSrcPalette); |
+ m_pSrcPalette = NULL; |
+ } |
+ if (m_SrcPaletteNumber) { |
+ m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber); |
+ if (m_pSrcPalette == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ FXSYS_memcpy(m_pSrcPalette, pPalette, |
+ m_SrcPaletteNumber * sizeof(FX_DWORD)); |
+ } |
+ return TRUE; |
+ } |
+ if (m_pBmpContext != NULL) { |
+ pBmpModule->Finish(m_pBmpContext); |
+ m_pBmpContext = NULL; |
+ } |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } break; |
+ case FXCODEC_IMAGE_JPG: { |
+ ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); |
+ if (pJpegModule == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ m_pJpegContext = pJpegModule->Start(); |
+ if (m_pJpegContext == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
+ if (!bResult) { |
+ m_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += size; |
+ pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size); |
+ int32_t readResult = |
+ pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, |
+ &m_SrcComponents, pAttribute); |
+ while (readResult == 2) { |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; |
+ if (!JpegReadMoreData(pJpegModule, error_status)) { |
+ m_status = error_status; |
+ return FALSE; |
+ } |
+ readResult = |
+ pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, |
+ &m_SrcComponents, pAttribute); |
+ } |
+ if (!readResult) { |
+ m_SrcBPC = 8; |
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
+ return TRUE; |
+ } |
+ if (m_pJpegContext != NULL) { |
+ pJpegModule->Finish(m_pJpegContext); |
+ m_pJpegContext = NULL; |
+ } |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } break; |
+ case FXCODEC_IMAGE_PNG: { |
+ ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); |
+ if (pPngModule == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ pPngModule->ReadHeaderCallback = |
+ CCodec_ProgressiveDecoder::PngReadHeaderFunc; |
+ pPngModule->AskScanlineBufCallback = |
+ CCodec_ProgressiveDecoder::PngAskScanlineBufFunc; |
+ pPngModule->FillScanlineBufCompletedCallback = |
+ CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc; |
+ m_pPngContext = pPngModule->Start((void*)this); |
+ if (m_pPngContext == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
+ if (!bResult) { |
+ m_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += size; |
+ bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute); |
+ while (bResult) { |
+ FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; |
+ FX_DWORD input_size = |
+ remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; |
+ if (input_size == 0) { |
+ if (m_pPngContext != NULL) { |
+ pPngModule->Finish(m_pPngContext); |
+ } |
+ m_pPngContext = NULL; |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } |
+ if (m_pSrcBuf != NULL && input_size > m_SrcSize) { |
+ FX_Free(m_pSrcBuf); |
+ m_pSrcBuf = FX_Alloc(uint8_t, input_size); |
+ if (m_pSrcBuf == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ FXSYS_memset(m_pSrcBuf, 0, input_size); |
+ m_SrcSize = input_size; |
+ } |
+ bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); |
+ if (!bResult) { |
+ m_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += input_size; |
+ bResult = |
+ pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute); |
+ } |
+ ASSERT(!bResult); |
+ if (m_pPngContext != NULL) { |
+ pPngModule->Finish(m_pPngContext); |
+ m_pPngContext = NULL; |
+ } |
+ if (m_SrcPassNumber == 0) { |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } |
+ } break; |
+ case FXCODEC_IMAGE_GIF: { |
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
+ if (pGifModule == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ pGifModule->RecordCurrentPositionCallback = |
+ CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback; |
+ pGifModule->AskLocalPaletteBufCallback = |
+ CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback; |
+ pGifModule->InputRecordPositionBufCallback = |
+ CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback; |
+ pGifModule->ReadScanlineCallback = |
+ CCodec_ProgressiveDecoder::GifReadScanlineCallback; |
+ m_pGifContext = pGifModule->Start((void*)this); |
+ if (m_pGifContext == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ return FALSE; |
+ } |
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size); |
+ if (!bResult) { |
+ m_status = FXCODEC_STATUS_ERR_READ; |
+ return FALSE; |
+ } |
+ m_offSet += size; |
+ pGifModule->Input(m_pGifContext, m_pSrcBuf, size); |
+ m_SrcComponents = 1; |
+ int32_t readResult = pGifModule->ReadHeader( |
+ m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, |
+ (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); |
+ while (readResult == 2) { |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT; |
+ if (!GifReadMoreData(pGifModule, error_status)) { |
+ m_status = error_status; |
+ return FALSE; |
+ } |
+ readResult = pGifModule->ReadHeader( |
+ m_pGifContext, &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber, |
+ (void**)&m_pGifPalette, &m_GifBgIndex, nullptr); |
+ } |
+ if (readResult == 1) { |
+ m_SrcBPC = 8; |
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
+ return TRUE; |
+ } |
+ if (m_pGifContext != NULL) { |
+ pGifModule->Finish(m_pGifContext); |
+ m_pGifContext = NULL; |
+ } |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } break; |
+ case FXCODEC_IMAGE_TIF: { |
+ ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); |
+ if (pTiffModule == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } |
+ m_pTiffContext = pTiffModule->CreateDecoder(m_pFile); |
+ if (m_pTiffContext == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } |
+ int32_t frames = 0; |
+ pTiffModule->GetFrames(m_pTiffContext, frames); |
+ FX_DWORD bpc; |
+ FX_BOOL ret = pTiffModule->LoadFrameInfo( |
+ m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, |
+ (FX_DWORD&)m_SrcComponents, bpc, pAttribute); |
+ m_SrcComponents = 4; |
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight); |
+ if (!ret) { |
+ pTiffModule->DestroyDecoder(m_pTiffContext); |
+ (m_pTiffContext = NULL); |
+ (m_status = FXCODEC_STATUS_ERR_FORMAT); |
+ return FALSE; |
+ } |
+ } break; |
+ default: |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ return FALSE; |
+ } |
+ return TRUE; |
+} |
+FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo( |
+ IFX_FileRead* pFile, |
+ FXCODEC_IMAGE_TYPE imageType, |
+ CFX_DIBAttribute* pAttribute) { |
+ switch (m_status) { |
+ case FXCODEC_STATUS_FRAME_READY: |
+ case FXCODEC_STATUS_FRAME_TOBECONTINUE: |
+ case FXCODEC_STATUS_DECODE_READY: |
+ case FXCODEC_STATUS_DECODE_TOBECONTINUE: |
+ return FXCODEC_STATUS_ERROR; |
+ default:; |
+ } |
+ if (pFile == NULL) { |
+ m_status = FXCODEC_STATUS_ERR_PARAMS; |
+ m_pFile = NULL; |
+ return m_status; |
+ } |
+ m_pFile = pFile; |
+ m_offSet = 0; |
+ m_SrcWidth = m_SrcHeight = 0; |
+ m_SrcComponents = m_SrcBPC = 0; |
+ m_clipBox = FX_RECT(0, 0, 0, 0); |
+ m_startX = m_startY = 0; |
+ m_sizeX = m_sizeY = 0; |
+ m_SrcPassNumber = 0; |
+ if (imageType != FXCODEC_IMAGE_UNKNOWN && |
+ DetectImageType(imageType, pAttribute)) { |
+ m_imagType = imageType; |
+ m_status = FXCODEC_STATUS_FRAME_READY; |
+ return m_status; |
+ } |
+ for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) { |
+ if (DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) { |
+ m_imagType = (FXCODEC_IMAGE_TYPE)type; |
+ m_status = FXCODEC_STATUS_FRAME_READY; |
+ return m_status; |
+ } |
+ } |
+ m_status = FXCODEC_STATUS_ERR_FORMAT; |
+ m_pFile = NULL; |
+ return m_status; |
+} |
+void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip) { |
+ 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; |
+ } |
+ 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; |
+ int ratio_h = m_clipBox.Height() / m_sizeY; |
+ int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w; |
+ if (ratio >= 8) { |
+ down_scale = 8; |
+ } else if (ratio >= 4) { |
+ down_scale = 4; |
+ } else if (ratio >= 2) { |
+ down_scale = 2; |
+ } |
+ m_clipBox.left /= down_scale; |
+ m_clipBox.right /= down_scale; |
+ m_clipBox.top /= down_scale; |
+ m_clipBox.bottom /= down_scale; |
+ if (m_clipBox.right == m_clipBox.left) { |
+ m_clipBox.right = m_clipBox.left + 1; |
+ } |
+ if (m_clipBox.bottom == m_clipBox.top) { |
+ m_clipBox.bottom = m_clipBox.top + 1; |
+ } |
+} |
+void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, |
+ FXCodec_Format src_format) { |
+ switch (des_format) { |
+ case FXDIB_1bppMask: |
+ case FXDIB_1bppRgb: { |
+ switch (src_format) { |
+ case FXCodec_1bppGray: |
+ m_TransMethod = 0; |
+ break; |
+ default: |
+ m_TransMethod = -1; |
+ } |
+ } break; |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: { |
+ switch (src_format) { |
+ case FXCodec_1bppGray: |
+ m_TransMethod = 1; |
+ break; |
+ case FXCodec_8bppGray: |
+ m_TransMethod = 2; |
+ break; |
+ case FXCodec_1bppRgb: |
+ case FXCodec_8bppRgb: |
+ m_TransMethod = 3; |
+ break; |
+ case FXCodec_Rgb: |
+ case FXCodec_Rgb32: |
+ case FXCodec_Argb: |
+ m_TransMethod = 4; |
+ break; |
+ case FXCodec_Cmyk: |
+ m_TransMethod = 5; |
+ break; |
+ default: |
+ m_TransMethod = -1; |
+ } |
+ } break; |
+ case FXDIB_Rgb: { |
+ switch (src_format) { |
+ case FXCodec_1bppGray: |
+ m_TransMethod = 6; |
+ break; |
+ case FXCodec_8bppGray: |
+ m_TransMethod = 7; |
+ break; |
+ case FXCodec_1bppRgb: |
+ case FXCodec_8bppRgb: |
+ m_TransMethod = 8; |
+ break; |
+ case FXCodec_Rgb: |
+ case FXCodec_Rgb32: |
+ case FXCodec_Argb: |
+ m_TransMethod = 9; |
+ break; |
+ case FXCodec_Cmyk: |
+ m_TransMethod = 10; |
+ break; |
+ default: |
+ m_TransMethod = -1; |
+ } |
+ } break; |
+ case FXDIB_Rgb32: |
+ case FXDIB_Argb: { |
+ switch (src_format) { |
+ case FXCodec_1bppGray: |
+ m_TransMethod = 6; |
+ break; |
+ case FXCodec_8bppGray: |
+ m_TransMethod = 7; |
+ break; |
+ case FXCodec_1bppRgb: |
+ case FXCodec_8bppRgb: |
+ if (des_format == FXDIB_Argb) { |
+ m_TransMethod = 12; |
+ } else { |
+ m_TransMethod = 8; |
+ } |
+ break; |
+ case FXCodec_Rgb: |
+ case FXCodec_Rgb32: |
+ m_TransMethod = 9; |
+ break; |
+ case FXCodec_Cmyk: |
+ m_TransMethod = 10; |
+ break; |
+ case FXCodec_Argb: |
+ m_TransMethod = 11; |
+ break; |
+ default: |
+ m_TransMethod = -1; |
+ } |
+ } break; |
+ default: |
+ 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, |
+ FXCodec_Format src_format) { |
+ int src_left = m_clipBox.left; |
+ int des_left = m_startX; |
+ uint8_t* des_scan = |
+ pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch(); |
+ int src_bpp = src_format & 0xff; |
+ int des_bpp = pDeviceBitmap->GetBPP(); |
+ int src_Bpp = src_bpp >> 3; |
+ int des_Bpp = des_bpp >> 3; |
+ src_scan += src_left * src_Bpp; |
+ des_scan += des_left * des_Bpp; |
+ for (int des_col = 0; des_col < m_sizeX; des_col++) { |
+ PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col); |
+ switch (m_TransMethod) { |
+ case -1: |
+ return; |
+ case 0: |
+ return; |
+ case 1: |
+ return; |
+ case 2: { |
+ FX_DWORD des_g = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ des_g += pixel_weight * src_scan[j]; |
+ } |
+ *des_scan++ = (uint8_t)(des_g >> 16); |
+ } break; |
+ case 3: { |
+ int des_r = 0, des_g = 0, des_b = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ unsigned long argb = m_pSrcPalette[src_scan[j]]; |
+ des_r += pixel_weight * (uint8_t)(argb >> 16); |
+ des_g += pixel_weight * (uint8_t)(argb >> 8); |
+ des_b += pixel_weight * (uint8_t)argb; |
+ } |
+ *des_scan++ = |
+ (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); |
+ } break; |
+ case 4: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ const uint8_t* src_pixel = src_scan + j * src_Bpp; |
+ des_b += pixel_weight * (*src_pixel++); |
+ des_g += pixel_weight * (*src_pixel++); |
+ des_r += pixel_weight * (*src_pixel); |
+ } |
+ *des_scan++ = |
+ (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); |
+ } break; |
+ case 5: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ const uint8_t* src_pixel = src_scan + j * src_Bpp; |
+ uint8_t src_b = 0, src_g = 0, src_r = 0; |
+ AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], |
+ 255 - src_pixel[2], 255 - src_pixel[3], src_r, |
+ src_g, src_b); |
+ des_b += pixel_weight * src_b; |
+ des_g += pixel_weight * src_g; |
+ des_r += pixel_weight * src_r; |
+ } |
+ *des_scan++ = |
+ (uint8_t)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16)); |
+ } break; |
+ case 6: |
+ return; |
+ case 7: { |
+ FX_DWORD des_g = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ des_g += pixel_weight * src_scan[j]; |
+ } |
+ FXSYS_memset(des_scan, (uint8_t)(des_g >> 16), 3); |
+ des_scan += des_Bpp; |
+ } break; |
+ case 8: { |
+ int des_r = 0, des_g = 0, des_b = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ unsigned long argb = m_pSrcPalette[src_scan[j]]; |
+ des_r += pixel_weight * (uint8_t)(argb >> 16); |
+ des_g += pixel_weight * (uint8_t)(argb >> 8); |
+ des_b += pixel_weight * (uint8_t)argb; |
+ } |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ des_scan += des_Bpp - 3; |
+ } break; |
+ case 12: { |
+ if (m_pBmpContext) { |
+ int des_r = 0, des_g = 0, des_b = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ unsigned long argb = m_pSrcPalette[src_scan[j]]; |
+ des_r += pixel_weight * (uint8_t)(argb >> 16); |
+ des_g += pixel_weight * (uint8_t)(argb >> 8); |
+ des_b += pixel_weight * (uint8_t)argb; |
+ } |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ *des_scan++ = 0xFF; |
+ } else { |
+ int des_a = 0, des_r = 0, des_g = 0, des_b = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ unsigned long argb = m_pSrcPalette[src_scan[j]]; |
+ des_a += pixel_weight * (uint8_t)(argb >> 24); |
+ des_r += pixel_weight * (uint8_t)(argb >> 16); |
+ des_g += pixel_weight * (uint8_t)(argb >> 8); |
+ des_b += pixel_weight * (uint8_t)argb; |
+ } |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ *des_scan++ = (uint8_t)((des_a) >> 16); |
+ } |
+ } break; |
+ case 9: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ const uint8_t* src_pixel = src_scan + j * src_Bpp; |
+ des_b += pixel_weight * (*src_pixel++); |
+ des_g += pixel_weight * (*src_pixel++); |
+ des_r += pixel_weight * (*src_pixel); |
+ } |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ des_scan += des_Bpp - 3; |
+ } break; |
+ case 10: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ const uint8_t* src_pixel = src_scan + j * src_Bpp; |
+ uint8_t src_b = 0, src_g = 0, src_r = 0; |
+ AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], |
+ 255 - src_pixel[2], 255 - src_pixel[3], src_r, |
+ src_g, src_b); |
+ des_b += pixel_weight * src_b; |
+ des_g += pixel_weight * src_g; |
+ des_r += pixel_weight * src_r; |
+ } |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ des_scan += des_Bpp - 3; |
+ } break; |
+ case 11: { |
+ FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0; |
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
+ j++) { |
+ int pixel_weight = |
+ pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; |
+ const uint8_t* src_pixel = src_scan + j * src_Bpp; |
+ pixel_weight = pixel_weight * src_pixel[3] / 255; |
+ des_b += pixel_weight * (*src_pixel++); |
+ des_g += pixel_weight * (*src_pixel++); |
+ des_r += pixel_weight * (*src_pixel); |
+ des_alpha += pixel_weight; |
+ } |
+ *des_scan++ = (uint8_t)((des_b) >> 16); |
+ *des_scan++ = (uint8_t)((des_g) >> 16); |
+ *des_scan++ = (uint8_t)((des_r) >> 16); |
+ *des_scan++ = (uint8_t)((des_alpha * 255) >> 16); |
+ } break; |
+ default: |
+ return; |
+ } |
+ } |
+} |
+void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, |
+ double scale_y, |
+ int des_row) { |
+ int des_Bpp = pDeviceBitmap->GetBPP() >> 3; |
+ FX_DWORD des_ScanOffet = m_startX * des_Bpp; |
+ if (m_bInterpol) { |
+ int des_top = m_startY; |
+ int des_row_1 = des_row - int(scale_y); |
+ if (des_row_1 < des_top) { |
+ int des_bottom = des_top + m_sizeY; |
+ if (des_row + (int)scale_y >= des_bottom - 1) { |
+ uint8_t* scan_src = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
+ while (++des_row < des_bottom) { |
+ uint8_t* scan_des = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
+ FX_DWORD size = m_sizeX * des_Bpp; |
+ FXSYS_memcpy(scan_des, scan_src, size); |
+ } |
+ } |
+ return; |
+ } |
+ for (; des_row_1 < des_row; des_row_1++) { |
+ uint8_t* scan_des = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet; |
+ PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top); |
+ const uint8_t* scan_src1 = |
+ pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + |
+ des_ScanOffet; |
+ const uint8_t* scan_src2 = |
+ pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + |
+ des_ScanOffet; |
+ for (int des_col = 0; des_col < m_sizeX; des_col++) { |
+ switch (pDeviceBitmap->GetFormat()) { |
+ case FXDIB_Invalid: |
+ case FXDIB_1bppMask: |
+ case FXDIB_1bppRgb: |
+ return; |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: { |
+ if (pDeviceBitmap->GetPalette() != NULL) { |
+ return; |
+ } |
+ int des_g = 0; |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ *scan_des++ = (uint8_t)(des_g >> 16); |
+ } break; |
+ case FXDIB_Rgb: |
+ case FXDIB_Rgb32: { |
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0; |
+ des_b += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_r += pWeight->m_Weights[0] * (*scan_src1++); |
+ scan_src1 += des_Bpp - 3; |
+ des_b += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_r += pWeight->m_Weights[1] * (*scan_src2++); |
+ scan_src2 += des_Bpp - 3; |
+ *scan_des++ = (uint8_t)((des_b) >> 16); |
+ *scan_des++ = (uint8_t)((des_g) >> 16); |
+ *scan_des++ = (uint8_t)((des_r) >> 16); |
+ scan_des += des_Bpp - 3; |
+ } break; |
+ case FXDIB_Argb: { |
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0; |
+ des_b += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_g += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_r += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_a += pWeight->m_Weights[0] * (*scan_src1++); |
+ des_b += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_g += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_r += pWeight->m_Weights[1] * (*scan_src2++); |
+ des_a += pWeight->m_Weights[1] * (*scan_src2++); |
+ *scan_des++ = (uint8_t)((des_b) >> 16); |
+ *scan_des++ = (uint8_t)((des_g) >> 16); |
+ *scan_des++ = (uint8_t)((des_r) >> 16); |
+ *scan_des++ = (uint8_t)((des_a) >> 16); |
+ } break; |
+ default: |
+ return; |
+ } |
+ } |
+ } |
+ int des_bottom = des_top + m_sizeY; |
+ if (des_row + (int)scale_y >= des_bottom - 1) { |
+ uint8_t* scan_src = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
+ while (++des_row < des_bottom) { |
+ uint8_t* scan_des = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
+ FX_DWORD size = m_sizeX * des_Bpp; |
+ FXSYS_memcpy(scan_des, scan_src, size); |
+ } |
+ } |
+ return; |
+ } |
+ int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1); |
+ if (multiple > 0) { |
+ uint8_t* scan_src = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet; |
+ for (int i = 1; i <= multiple; i++) { |
+ if (des_row + i >= m_startY + m_sizeY) { |
+ return; |
+ } |
+ uint8_t* scan_des = |
+ (uint8_t*)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet; |
+ FX_DWORD size = m_sizeX * des_Bpp; |
+ FXSYS_memcpy(scan_des, scan_src, size); |
+ } |
+ } |
+} |
+void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, |
+ int32_t src_line, |
+ uint8_t* src_scan, |
+ FXCodec_Format src_format) { |
+ int src_top = m_clipBox.top; |
+ int des_top = m_startY; |
+ int src_hei = m_clipBox.Height(); |
+ int des_hei = m_sizeY; |
+ if (src_line >= src_top) { |
+ double scale_y = (double)des_hei / (double)src_hei; |
+ int src_row = src_line - src_top; |
+ int des_row = (int)(src_row * scale_y) + des_top; |
+ if (des_row >= des_top + des_hei) { |
+ return; |
+ } |
+ ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format); |
+ if (scale_y > 1.0) { |
+ ResampleVert(pDeviceBitmap, scale_y, des_row); |
+ } |
+ } |
+} |
+FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, |
+ IFX_Pause* pPause) { |
+ if (!(m_status == FXCODEC_STATUS_FRAME_READY || |
+ m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) { |
+ return FXCODEC_STATUS_ERROR; |
+ } |
+ switch (m_imagType) { |
+ case FXCODEC_IMAGE_BMP: |
+ case FXCODEC_IMAGE_JPG: |
+ case FXCODEC_IMAGE_PNG: |
+ case FXCODEC_IMAGE_TIF: |
+ frames = m_FrameNumber = 1; |
+ return m_status = FXCODEC_STATUS_DECODE_READY; |
+ case FXCODEC_IMAGE_GIF: { |
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
+ while (TRUE) { |
+ int32_t readResult = |
+ pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); |
+ while (readResult == 2) { |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ; |
+ if (!GifReadMoreData(pGifModule, error_status)) { |
+ return error_status; |
+ } |
+ if (pPause && pPause->NeedToPauseNow()) { |
+ return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE; |
+ } |
+ readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); |
+ } |
+ if (readResult == 1) { |
+ frames = m_FrameNumber; |
+ return m_status = FXCODEC_STATUS_DECODE_READY; |
+ } |
+ if (m_pGifContext != NULL) { |
+ pGifModule->Finish(m_pGifContext); |
+ m_pGifContext = NULL; |
+ } |
+ return m_status = FXCODEC_STATUS_ERROR; |
+ } |
+ } break; |
+ default:; |
+ } |
+ return FXCODEC_STATUS_ERROR; |
+} |
+FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, |
+ int start_x, |
+ int start_y, |
+ int size_x, |
+ int size_y, |
+ int32_t frames, |
+ FX_BOOL bInterpol) { |
+ if (m_status != FXCODEC_STATUS_DECODE_READY) { |
+ return FXCODEC_STATUS_ERROR; |
+ } |
+ if (pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 || frames < 0 || |
+ frames >= m_FrameNumber) { |
+ return FXCODEC_STATUS_ERR_PARAMS; |
+ } |
+ m_pDeviceBitmap = pDIBitmap; |
+ if (m_clipBox.IsEmpty()) { |
+ return FXCODEC_STATUS_ERR_PARAMS; |
+ } |
+ 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()) { |
+ return FXCODEC_STATUS_ERR_PARAMS; |
+ } |
+ m_startX = device_rc.left; |
+ m_startY = device_rc.top; |
+ m_sizeX = device_rc.Width(); |
+ m_sizeY = device_rc.Height(); |
+ m_bInterpol = bInterpol; |
+ m_FrameCur = 0; |
+ if (start_x < 0 || out_range_x > 0) { |
+ FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x; |
+ if (start_x < 0) { |
+ m_clipBox.left -= (int32_t)FXSYS_ceil((FX_FLOAT)start_x * scaleX); |
+ } |
+ if (out_range_x > 0) { |
+ m_clipBox.right -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_x * scaleX); |
+ } |
+ } |
+ if (start_y < 0 || out_range_y > 0) { |
+ FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y; |
+ if (start_y < 0) { |
+ m_clipBox.top -= (int32_t)FXSYS_ceil((FX_FLOAT)start_y * scaleY); |
+ } |
+ if (out_range_y > 0) { |
+ m_clipBox.bottom -= (int32_t)FXSYS_floor((FX_FLOAT)out_range_y * scaleY); |
+ } |
+ } |
+ if (m_clipBox.IsEmpty()) { |
+ return FXCODEC_STATUS_ERR_PARAMS; |
+ } |
+ switch (m_imagType) { |
+ case FXCODEC_IMAGE_JPG: { |
+ ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); |
+ int down_scale = 1; |
+ GetDownScale(down_scale); |
+ FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); |
+ while (!bStart) { |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; |
+ if (!JpegReadMoreData(pJpegModule, error_status)) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = error_status; |
+ } |
+ bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale); |
+ } |
+ int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale; |
+ scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4; |
+ if (m_pDecodeBuf != NULL) { |
+ FX_Free(m_pDecodeBuf); |
+ m_pDecodeBuf = NULL; |
+ } |
+ m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); |
+ if (m_pDecodeBuf == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ FXSYS_memset(m_pDecodeBuf, 0, scanline_size); |
+ 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()); |
+ switch (m_SrcComponents) { |
+ case 1: |
+ m_SrcFormat = FXCodec_8bppGray; |
+ break; |
+ case 3: |
+ m_SrcFormat = FXCodec_Rgb; |
+ break; |
+ case 4: |
+ m_SrcFormat = FXCodec_Cmyk; |
+ break; |
+ } |
+ GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat); |
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
+ } break; |
+ case FXCODEC_IMAGE_PNG: { |
+ ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); |
+ if (pPngModule == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ if (m_pPngContext != NULL) { |
+ pPngModule->Finish(m_pPngContext); |
+ m_pPngContext = NULL; |
+ } |
+ m_pPngContext = pPngModule->Start((void*)this); |
+ if (m_pPngContext == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ m_offSet = 0; |
+ switch (m_pDeviceBitmap->GetFormat()) { |
+ case FXDIB_8bppMask: |
+ case FXDIB_8bppRgb: |
+ m_SrcComponents = 1; |
+ m_SrcFormat = FXCodec_8bppGray; |
+ break; |
+ case FXDIB_Rgb: |
+ m_SrcComponents = 3; |
+ m_SrcFormat = FXCodec_Rgb; |
+ break; |
+ case FXDIB_Rgb32: |
+ case FXDIB_Argb: |
+ m_SrcComponents = 4; |
+ m_SrcFormat = FXCodec_Argb; |
+ break; |
+ default: { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_PARAMS; |
+ } |
+ } |
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); |
+ int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; |
+ if (m_pDecodeBuf != NULL) { |
+ FX_Free(m_pDecodeBuf); |
+ m_pDecodeBuf = NULL; |
+ } |
+ m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); |
+ if (m_pDecodeBuf == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ 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; |
+ case FXCODEC_IMAGE_GIF: { |
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
+ if (pGifModule == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ m_SrcFormat = FXCodec_8bppRgb; |
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); |
+ int scanline_size = (m_SrcWidth + 3) / 4 * 4; |
+ if (m_pDecodeBuf != NULL) { |
+ FX_Free(m_pDecodeBuf); |
+ m_pDecodeBuf = NULL; |
+ } |
+ m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size); |
+ if (m_pDecodeBuf == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ FXSYS_memset(m_pDecodeBuf, 0, scanline_size); |
+ 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()); |
+ m_FrameCur = frames; |
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
+ } break; |
+ case FXCODEC_IMAGE_BMP: { |
+ ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); |
+ if (pBmpModule == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ switch (m_SrcComponents) { |
+ case 1: |
+ m_SrcFormat = FXCodec_8bppRgb; |
+ break; |
+ case 3: |
+ m_SrcFormat = FXCodec_Rgb; |
+ break; |
+ case 4: |
+ m_SrcFormat = FXCodec_Rgb32; |
+ break; |
+ } |
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat); |
+ m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4; |
+ if (m_pDecodeBuf != NULL) { |
+ FX_Free(m_pDecodeBuf); |
+ m_pDecodeBuf = NULL; |
+ } |
+ m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize); |
+ if (m_pDecodeBuf == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ FXSYS_memset(m_pDecodeBuf, 0, m_ScanlineSize); |
+ 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; |
+ case FXCODEC_IMAGE_TIF: |
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
+ default: |
+ break; |
+ } |
+ return FXCODEC_STATUS_ERROR; |
+} |
+FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { |
+ if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
+ return FXCODEC_STATUS_ERROR; |
+ } |
+ switch (m_imagType) { |
+ case FXCODEC_IMAGE_JPG: { |
+ ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule(); |
+ while (TRUE) { |
+ FX_BOOL readRes = |
+ pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf); |
+ while (!readRes) { |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; |
+ if (!JpegReadMoreData(pJpegModule, error_status)) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = error_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()); |
+ } |
+ if (m_SrcRow >= m_clipBox.bottom) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_DECODE_FINISH; |
+ } |
+ Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat); |
+ m_SrcRow++; |
+ if (pPause && pPause->NeedToPauseNow()) { |
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
+ } |
+ } |
+ } break; |
+ case FXCODEC_IMAGE_PNG: { |
+ ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); |
+ while (TRUE) { |
+ FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet; |
+ FX_DWORD input_size = |
+ remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size; |
+ if (input_size == 0) { |
+ if (m_pPngContext != NULL) { |
+ pPngModule->Finish(m_pPngContext); |
+ } |
+ m_pPngContext = NULL; |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_DECODE_FINISH; |
+ } |
+ if (m_pSrcBuf != NULL && input_size > m_SrcSize) { |
+ FX_Free(m_pSrcBuf); |
+ m_pSrcBuf = FX_Alloc(uint8_t, input_size); |
+ if (m_pSrcBuf == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ FXSYS_memset(m_pSrcBuf, 0, input_size); |
+ m_SrcSize = input_size; |
+ } |
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size); |
+ if (!bResult) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_READ; |
+ } |
+ m_offSet += input_size; |
+ bResult = |
+ pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, nullptr); |
+ if (!bResult) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERROR; |
+ } |
+ if (pPause && pPause->NeedToPauseNow()) { |
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
+ } |
+ } |
+ } break; |
+ case FXCODEC_IMAGE_GIF: { |
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); |
+ while (TRUE) { |
+ int32_t readRes = |
+ pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); |
+ while (readRes == 2) { |
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; |
+ if (!GifReadMoreData(pGifModule, error_status)) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = error_status; |
+ } |
+ if (pPause && pPause->NeedToPauseNow()) { |
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
+ } |
+ readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); |
+ } |
+ if (readRes == 1) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_DECODE_FINISH; |
+ } |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERROR; |
+ } |
+ } break; |
+ case FXCODEC_IMAGE_BMP: { |
+ ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); |
+ 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 = NULL; |
+ m_pFile = NULL; |
+ return m_status = error_status; |
+ } |
+ if (pPause && pPause->NeedToPauseNow()) { |
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
+ } |
+ readRes = pBmpModule->LoadImage(m_pBmpContext); |
+ } |
+ if (readRes == 1) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_DECODE_FINISH; |
+ } |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERROR; |
+ } |
+ } break; |
+ case FXCODEC_IMAGE_TIF: { |
+ ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); |
+ FX_BOOL ret = FALSE; |
+ if (m_pDeviceBitmap->GetBPP() == 32 && |
+ m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX && |
+ m_pDeviceBitmap->GetHeight() == m_SrcHeight && |
+ m_SrcHeight == m_sizeY && m_startX == 0 && m_startY == 0 && |
+ m_clipBox.left == 0 && m_clipBox.top == 0 && |
+ m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) { |
+ ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap); |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ 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() == NULL) { |
+ delete pDIBitmap; |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap); |
+ if (!ret) { |
+ delete pDIBitmap; |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ 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 == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ CFX_DIBitmap* pFormatBitmap = NULL; |
+ 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:; |
+ } |
+ switch (m_pDeviceBitmap->GetFormat()) { |
+ case FXDIB_8bppRgb: |
+ case FXDIB_8bppMask: { |
+ for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { |
+ uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); |
+ uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); |
+ for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { |
+ uint8_t _a = 255 - src_line[3]; |
+ uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; |
+ uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; |
+ uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; |
+ *des_line++ = FXRGB2GRAY(r, g, b); |
+ src_line += 4; |
+ } |
+ } |
+ } break; |
+ case FXDIB_Rgb: |
+ case FXDIB_Rgb32: { |
+ int32_t desBpp = |
+ (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4; |
+ for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) { |
+ uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row); |
+ uint8_t* des_line = (uint8_t*)pFormatBitmap->GetScanline(row); |
+ for (int32_t col = 0; col < pClipBitmap->GetWidth(); col++) { |
+ uint8_t _a = 255 - src_line[3]; |
+ uint8_t b = (src_line[0] * src_line[3] + 0xFF * _a) / 255; |
+ uint8_t g = (src_line[1] * src_line[3] + 0xFF * _a) / 255; |
+ uint8_t r = (src_line[2] * src_line[3] + 0xFF * _a) / 255; |
+ *des_line++ = b; |
+ *des_line++ = g; |
+ *des_line++ = r; |
+ des_line += desBpp - 3; |
+ src_line += 4; |
+ } |
+ } |
+ } break; |
+ default:; |
+ } |
+ if (pClipBitmap != pFormatBitmap) { |
+ delete pClipBitmap; |
+ } |
+ if (pFormatBitmap == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ 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 = NULL; |
+ if (pStrechBitmap == NULL) { |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_ERR_MEMORY; |
+ } |
+ m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, |
+ pStrechBitmap, 0, 0); |
+ delete pStrechBitmap; |
+ pStrechBitmap = NULL; |
+ m_pDeviceBitmap = NULL; |
+ m_pFile = NULL; |
+ return m_status = FXCODEC_STATUS_DECODE_FINISH; |
+ } |
+ } break; |
+ default: |
+ break; |
+ } |
+ return FXCODEC_STATUS_ERROR; |
+} |
+ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { |
+ return new CCodec_ProgressiveDecoder(this); |
+} |