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