diff options
Diffstat (limited to 'core/src/fxcodec/codec/fx_codec_progress.cpp')
-rw-r--r-- | core/src/fxcodec/codec/fx_codec_progress.cpp | 4708 |
1 files changed, 2354 insertions, 2354 deletions
diff --git a/core/src/fxcodec/codec/fx_codec_progress.cpp b/core/src/fxcodec/codec/fx_codec_progress.cpp index 383e3ed93d..5dbc19b4b6 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); +} |