summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn15
-rw-r--r--core/fxcodec/codec/ccodec_progressivedecoder.h61
-rw-r--r--core/fxcodec/codec/fx_codec_progress.cpp1571
-rw-r--r--core/fxcodec/fx_codec_def.h3
-rw-r--r--testing/libfuzzer/BUILD.gn16
-rw-r--r--xfa/fxfa/cxfa_ffwidget.cpp2
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp2
7 files changed, 855 insertions, 815 deletions
diff --git a/BUILD.gn b/BUILD.gn
index c6663ec8f3..e6e6ea504e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -284,10 +284,7 @@ jumbo_static_library("image_diff") {
"testing/image_diff/image_diff_png.h",
]
configs += [ ":pdfium_core_config" ]
- deps = []
- if (!pdf_enable_xfa) {
- deps += [ "third_party:png" ]
- }
+ deps = [ "third_party:png" ]
}
# Targets below this are only visible within this file (and to the
@@ -791,8 +788,6 @@ jumbo_static_library("fxcodec") {
"core/fxcodec/codec/ccodec_bmpmodule.h",
"core/fxcodec/codec/ccodec_gifmodule.cpp",
"core/fxcodec/codec/ccodec_gifmodule.h",
- "core/fxcodec/codec/ccodec_pngmodule.cpp",
- "core/fxcodec/codec/ccodec_pngmodule.h",
"core/fxcodec/codec/ccodec_progressivedecoder.h",
"core/fxcodec/codec/fx_codec_progress.cpp",
"core/fxcodec/gif/cfx_gif.cpp",
@@ -802,7 +797,13 @@ jumbo_static_library("fxcodec") {
"core/fxcodec/gif/cfx_lzwdecompressor.cpp",
"core/fxcodec/gif/cfx_lzwdecompressor.h",
]
- deps += [ "third_party:png" ]
+ if (pdf_enable_xfa_png) {
+ sources += [
+ "core/fxcodec/codec/ccodec_pngmodule.cpp",
+ "core/fxcodec/codec/ccodec_pngmodule.h",
+ ]
+ deps += [ "third_party:png" ]
+ }
if (pdf_enable_xfa_tiff) {
sources += [
"core/fxcodec/codec/ccodec_tiffmodule.cpp",
diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h
index 9a0136c872..476a7c1b4a 100644
--- a/core/fxcodec/codec/ccodec_progressivedecoder.h
+++ b/core/fxcodec/codec/ccodec_progressivedecoder.h
@@ -14,7 +14,6 @@
#include "core/fxcodec/codec/ccodec_bmpmodule.h"
#include "core/fxcodec/codec/ccodec_gifmodule.h"
#include "core/fxcodec/codec/ccodec_jpegmodule.h"
-#include "core/fxcodec/codec/ccodec_pngmodule.h"
#include "core/fxcodec/fx_codec_def.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/retain_ptr.h"
@@ -22,6 +21,10 @@
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/fx_dib.h"
+#ifdef PDF_ENABLE_XFA_PNG
+#include "core/fxcodec/codec/ccodec_pngmodule.h"
+#endif // PDF_ENABLE_XFA_PNG
+
#ifdef PDF_ENABLE_XFA_TIFF
#include "core/fxcodec/codec/ccodec_tiffmodule.h"
#endif // PDF_ENABLE_XFA_TIFF
@@ -30,9 +33,14 @@ class CCodec_ModuleMgr;
class CFX_DIBAttribute;
class IFX_SeekableReadStream;
+class CCodec_Dummy {}; // Placeholder to work around C++ syntax issues
+
class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate,
public CCodec_GifModule::Delegate,
- public CCodec_PngModule::Delegate {
+#ifdef PDF_ENABLE_XFA_PNG
+ public CCodec_PngModule::Delegate,
+#endif // PDF_ENABLE_XFA_PNG
+ public CCodec_Dummy {
public:
enum FXCodec_Format {
FXCodec_Invalid = 0,
@@ -126,6 +134,7 @@ class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate,
std::vector<uint8_t> m_pWeightTables;
};
+#ifdef PDF_ENABLE_XFA_PNG
// CCodec_PngModule::Delegate
bool PngReadHeader(int width,
int height,
@@ -135,6 +144,7 @@ class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate,
double* gamma) override;
bool PngAskScanlineBuf(int line, uint8_t** pSrcBuf) override;
void PngFillScanlineBufCompleted(int pass, int line) override;
+#endif // PDF_ENABLE_XFA_PNG
// CCodec_GifModule::Delegate
void GifRecordCurrentPosition(uint32_t& cur_pos) override;
@@ -157,24 +167,43 @@ class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate,
private:
bool BmpReadMoreData(CCodec_BmpModule* pBmpModule,
FXCODEC_STATUS& err_status);
+ bool BmpDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
+ FXCODEC_STATUS BmpStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
+ FXCODEC_STATUS BmpContinueDecode();
+
bool GifReadMoreData(CCodec_GifModule* pGifModule,
FXCODEC_STATUS& err_status);
+ bool GifDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
+ FXCODEC_STATUS GifStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
+ FXCODEC_STATUS GifContinueDecode();
+ void GifDoubleLineResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
+ double scale_y,
+ int dest_row);
+
bool JpegReadMoreData(CCodec_JpegModule* pJpegModule,
FXCODEC_STATUS& err_status);
+ bool JpegDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
+ FXCODEC_STATUS JpegStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
+ FXCODEC_STATUS JpegContinueDecode();
+
+#ifdef PDF_ENABLE_XFA_PNG
void PngOneOneMapResampleHorz(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
int32_t dest_line,
uint8_t* src_scan,
FXCodec_Format src_format);
- bool DetectImageType(FXCODEC_IMAGE_TYPE imageType,
- CFX_DIBAttribute* pAttribute);
- bool BmpDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
- bool JpegDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
bool PngDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
- bool GifDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
+ FXCODEC_STATUS PngStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
+ FXCODEC_STATUS PngContinueDecode();
+#endif // PDF_ENABLE_XFA_PNG
+
#ifdef PDF_ENABLE_XFA_TIFF
bool TiffDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size);
+ FXCODEC_STATUS TiffContinueDecode();
#endif // PDF_ENABLE_XFA_TIFF
+ bool DetectImageType(FXCODEC_IMAGE_TYPE imageType,
+ CFX_DIBAttribute* pAttribute);
+
void GetDownScale(int& down_scale);
void GetTransMethod(FXDIB_Format dest_format, FXCodec_Format src_format);
@@ -192,28 +221,14 @@ class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate,
void ResampleVertBT(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
double scale_y,
int dest_row);
- void GifDoubleLineResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
- double scale_y,
- int dest_row);
-
- FXCODEC_STATUS JpegStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
- FXCODEC_STATUS PngStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
- FXCODEC_STATUS GifStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
- FXCODEC_STATUS BmpStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap);
-
- FXCODEC_STATUS JpegContinueDecode();
- FXCODEC_STATUS PngContinueDecode();
- FXCODEC_STATUS GifContinueDecode();
- FXCODEC_STATUS BmpContinueDecode();
-#ifdef PDF_ENABLE_XFA_TIFF
- FXCODEC_STATUS TiffContinueDecode();
-#endif // PDF_ENABLE_XFA_TIFF
RetainPtr<IFX_SeekableReadStream> m_pFile;
RetainPtr<CFX_DIBitmap> m_pDeviceBitmap;
UnownedPtr<CCodec_ModuleMgr> m_pCodecMgr;
std::unique_ptr<CCodec_JpegModule::Context> m_pJpegContext;
+#ifdef PDF_ENABLE_XFA_PNG
std::unique_ptr<CCodec_PngModule::Context> m_pPngContext;
+#endif // PDF_ENABLE_XFA_PNG
std::unique_ptr<CCodec_GifModule::Context> m_pGifContext;
std::unique_ptr<CCodec_BmpModule::Context> m_pBmpContext;
#ifdef PDF_ENABLE_XFA_TIFF
diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp
index e606c414bb..bfd60acd0e 100644
--- a/core/fxcodec/codec/fx_codec_progress.cpp
+++ b/core/fxcodec/codec/fx_codec_progress.cpp
@@ -23,11 +23,13 @@
namespace {
+#ifdef PDF_ENABLE_XFA_PNG
#if _FX_OS_ == _FX_OS_MACOSX_
const double kPngGamma = 1.7;
#else // _FX_OS_ == _FX_OS_MACOSX_
const double kPngGamma = 2.2;
#endif // _FX_OS_ == _FX_OS_MACOSX_
+#endif // PDF_ENABLE_XFA_PNG
void RGB2BGR(uint8_t* buffer, int width = 1) {
if (buffer && width > 0) {
@@ -288,43 +290,7 @@ CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() {
FX_Free(m_pSrcPalette);
}
-bool CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule,
- FXCODEC_STATUS& err_status) {
- uint32_t dwSize = (uint32_t)m_pFile->GetSize();
- if (dwSize <= m_offSet) {
- return false;
- }
- dwSize = dwSize - m_offSet;
- uint32_t dwAvail = pJpegModule->GetAvailInput(m_pJpegContext.get(), nullptr);
- 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_TryRealloc(uint8_t, m_pSrcBuf, m_SrcSize);
- if (!m_pSrcBuf) {
- err_status = FXCODEC_STATUS_ERR_MEMORY;
- return false;
- }
- } else {
- uint32_t dwConsume = m_SrcSize - dwAvail;
- if (dwAvail) {
- memmove(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.get(), m_pSrcBuf, dwSize + dwAvail);
- return true;
-}
-
+#ifdef PDF_ENABLE_XFA_PNG
bool CCodec_ProgressiveDecoder::PngReadHeader(int width,
int height,
int bpc,
@@ -455,82 +421,6 @@ bool CCodec_ProgressiveDecoder::PngAskScanlineBuf(int line, uint8_t** pSrcBuf) {
return true;
}
-void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz(
- const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
- int32_t dest_line,
- uint8_t* src_scan,
- FXCodec_Format src_format) {
- uint8_t* dest_scan = (uint8_t*)pDeviceBitmap->GetScanline(dest_line);
- int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3;
- int32_t dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
- int32_t src_left = m_clipBox.left;
- int32_t dest_left = m_startX;
- src_scan += src_left * src_Bpp;
- dest_scan += dest_left * dest_Bpp;
- for (int32_t dest_col = 0; dest_col < m_sizeX; dest_col++) {
- PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(dest_col);
- switch (pDeviceBitmap->GetFormat()) {
- case FXDIB_1bppMask:
- case FXDIB_1bppRgb:
- NOTREACHED();
- return;
- case FXDIB_8bppMask:
- case FXDIB_8bppRgb: {
- if (pDeviceBitmap->GetPalette()) {
- return;
- }
- uint32_t dest_g = 0;
- dest_g +=
- pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart];
- dest_g +=
- pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd];
- *dest_scan++ = (uint8_t)(dest_g >> 16);
- } break;
- case FXDIB_Rgb:
- case FXDIB_Rgb32: {
- uint32_t dest_b = 0;
- uint32_t dest_g = 0;
- uint32_t dest_r = 0;
- const uint8_t* p = src_scan;
- p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
- dest_b += pPixelWeights->m_Weights[0] * (*p++);
- dest_g += pPixelWeights->m_Weights[0] * (*p++);
- dest_r += pPixelWeights->m_Weights[0] * (*p);
- p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
- dest_b += pPixelWeights->m_Weights[1] * (*p++);
- dest_g += pPixelWeights->m_Weights[1] * (*p++);
- dest_r += pPixelWeights->m_Weights[1] * (*p);
- *dest_scan++ = (uint8_t)((dest_b) >> 16);
- *dest_scan++ = (uint8_t)((dest_g) >> 16);
- *dest_scan++ = (uint8_t)((dest_r) >> 16);
- dest_scan += dest_Bpp - 3;
- } break;
- case FXDIB_Argb: {
- uint32_t dest_a = 0;
- uint32_t dest_b = 0;
- uint32_t dest_g = 0;
- uint32_t dest_r = 0;
- const uint8_t* p = src_scan;
- p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
- dest_b += pPixelWeights->m_Weights[0] * (*p++);
- dest_g += pPixelWeights->m_Weights[0] * (*p++);
- dest_r += pPixelWeights->m_Weights[0] * (*p++);
- dest_a += pPixelWeights->m_Weights[0] * (*p);
- p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
- dest_b += pPixelWeights->m_Weights[1] * (*p++);
- dest_g += pPixelWeights->m_Weights[1] * (*p++);
- dest_r += pPixelWeights->m_Weights[1] * (*p++);
- dest_a += pPixelWeights->m_Weights[1] * (*p);
- *dest_scan++ = (uint8_t)((dest_b) >> 16);
- *dest_scan++ = (uint8_t)((dest_g) >> 16);
- *dest_scan++ = (uint8_t)((dest_r) >> 16);
- *dest_scan++ = (uint8_t)((dest_a) >> 16);
- } break;
- default:
- return;
- }
- }
-}
void CCodec_ProgressiveDecoder::PngFillScanlineBufCompleted(int pass,
int line) {
@@ -558,50 +448,7 @@ void CCodec_ProgressiveDecoder::PngFillScanlineBufCompleted(int pass,
}
}
}
-
-bool CCodec_ProgressiveDecoder::GifReadMoreData(CCodec_GifModule* pGifModule,
- FXCODEC_STATUS& err_status) {
- if (static_cast<uint32_t>(m_pFile->GetSize()) <= m_offSet)
- return false;
-
- uint32_t dwFileRemaining = m_pFile->GetSize() - m_offSet;
- uint32_t dwUnusedBuffer =
- !m_InvalidateGifBuffer
- ? pGifModule->GetAvailInput(m_pGifContext.get(), nullptr)
- : 0;
- uint32_t dwAmountToFetchFromFile = dwFileRemaining;
- if (dwUnusedBuffer == m_SrcSize) {
- if (dwFileRemaining > FXCODEC_BLOCK_SIZE)
- dwAmountToFetchFromFile = FXCODEC_BLOCK_SIZE;
- m_SrcSize = std::min(
- (dwAmountToFetchFromFile + dwUnusedBuffer + FXCODEC_BLOCK_SIZE - 1) /
- FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE,
- static_cast<uint32_t>(m_pFile->GetSize()));
- m_pSrcBuf = FX_TryRealloc(uint8_t, m_pSrcBuf, m_SrcSize);
- if (!m_pSrcBuf) {
- err_status = FXCODEC_STATUS_ERR_MEMORY;
- return false;
- }
- } else {
- uint32_t dwConsumed = m_SrcSize - dwUnusedBuffer;
- if (dwUnusedBuffer)
- memmove(m_pSrcBuf, m_pSrcBuf + dwConsumed, dwUnusedBuffer);
- if (dwFileRemaining > dwConsumed)
- dwAmountToFetchFromFile = dwConsumed;
- }
-
- if (!m_pFile->ReadBlock(m_pSrcBuf + dwUnusedBuffer, m_offSet,
- dwAmountToFetchFromFile)) {
- err_status = FXCODEC_STATUS_ERR_READ;
- return false;
- }
-
- m_offSet += dwAmountToFetchFromFile;
- pGifModule->Input(m_pGifContext.get(), m_pSrcBuf,
- dwAmountToFetchFromFile + dwUnusedBuffer);
- m_InvalidateGifBuffer = false;
- return true;
-}
+#endif // PDF_ENABLE_XFA_PNG
void CCodec_ProgressiveDecoder::GifRecordCurrentPosition(uint32_t& cur_pos) {
uint32_t remain_size =
@@ -762,135 +609,6 @@ void CCodec_ProgressiveDecoder::GifReadScanline(int32_t row_num,
GifDoubleLineResampleVert(pDIBitmap, scale_y, dest_row);
}
-void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert(
- const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
- double scale_y,
- int dest_row) {
- int dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
- uint32_t dest_ScanOffet = m_startX * dest_Bpp;
- int dest_top = m_startY;
- pdfium::base::CheckedNumeric<double> scale_y2 = scale_y;
- scale_y2 *= 2;
- pdfium::base::CheckedNumeric<int> check_dest_row_1 = dest_row;
- check_dest_row_1 -= scale_y2.ValueOrDie();
- int dest_row_1 = check_dest_row_1.ValueOrDie();
- dest_row_1 = std::max(dest_row_1, dest_top);
- for (; dest_row_1 < dest_row; dest_row_1++) {
- uint8_t* scan_des =
- (uint8_t*)pDeviceBitmap->GetScanline(dest_row_1) + dest_ScanOffet;
- PixelWeight* pWeight = m_WeightVert.GetPixelWeight(dest_row_1 - dest_top);
- const uint8_t* scan_src1 =
- pDeviceBitmap->GetScanline(pWeight->m_SrcStart + dest_top) +
- dest_ScanOffet;
- const uint8_t* scan_src2 =
- pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + dest_top) +
- dest_ScanOffet;
- for (int dest_col = 0; dest_col < m_sizeX; dest_col++) {
- switch (pDeviceBitmap->GetFormat()) {
- case FXDIB_Invalid:
- case FXDIB_1bppMask:
- case FXDIB_1bppRgb:
- return;
- case FXDIB_8bppMask:
- case FXDIB_8bppRgb: {
- if (pDeviceBitmap->GetPalette()) {
- return;
- }
- int dest_g = 0;
- dest_g += pWeight->m_Weights[0] * (*scan_src1++);
- dest_g += pWeight->m_Weights[1] * (*scan_src2++);
- *scan_des++ = (uint8_t)(dest_g >> 16);
- } break;
- case FXDIB_Rgb:
- case FXDIB_Rgb32: {
- uint32_t dest_b = 0;
- uint32_t dest_g = 0;
- uint32_t dest_r = 0;
- dest_b += pWeight->m_Weights[0] * (*scan_src1++);
- dest_g += pWeight->m_Weights[0] * (*scan_src1++);
- dest_r += pWeight->m_Weights[0] * (*scan_src1++);
- scan_src1 += dest_Bpp - 3;
- dest_b += pWeight->m_Weights[1] * (*scan_src2++);
- dest_g += pWeight->m_Weights[1] * (*scan_src2++);
- dest_r += pWeight->m_Weights[1] * (*scan_src2++);
- scan_src2 += dest_Bpp - 3;
- *scan_des++ = (uint8_t)((dest_b) >> 16);
- *scan_des++ = (uint8_t)((dest_g) >> 16);
- *scan_des++ = (uint8_t)((dest_r) >> 16);
- scan_des += dest_Bpp - 3;
- } break;
- case FXDIB_Argb: {
- uint32_t dest_a = 0;
- uint32_t dest_b = 0;
- uint32_t dest_g = 0;
- uint32_t dest_r = 0;
- dest_b += pWeight->m_Weights[0] * (*scan_src1++);
- dest_g += pWeight->m_Weights[0] * (*scan_src1++);
- dest_r += pWeight->m_Weights[0] * (*scan_src1++);
- dest_a += pWeight->m_Weights[0] * (*scan_src1++);
- dest_b += pWeight->m_Weights[1] * (*scan_src2++);
- dest_g += pWeight->m_Weights[1] * (*scan_src2++);
- dest_r += pWeight->m_Weights[1] * (*scan_src2++);
- dest_a += pWeight->m_Weights[1] * (*scan_src2++);
- *scan_des++ = (uint8_t)((dest_b) >> 16);
- *scan_des++ = (uint8_t)((dest_g) >> 16);
- *scan_des++ = (uint8_t)((dest_r) >> 16);
- *scan_des++ = (uint8_t)((dest_a) >> 16);
- } break;
- default:
- return;
- }
- }
- }
- int dest_bottom = dest_top + m_sizeY - 1;
- if (dest_row + (int)(2 * scale_y) >= dest_bottom &&
- dest_row + (int)scale_y < dest_bottom) {
- GifDoubleLineResampleVert(pDeviceBitmap, scale_y, dest_row + (int)scale_y);
- }
-}
-
-bool CCodec_ProgressiveDecoder::BmpReadMoreData(CCodec_BmpModule* pBmpModule,
- FXCODEC_STATUS& err_status) {
- uint32_t dwSize = (uint32_t)m_pFile->GetSize();
- if (dwSize <= m_offSet)
- return false;
-
- dwSize = dwSize - m_offSet;
- FX_SAFE_UINT32 avail_input =
- pBmpModule->GetAvailInput(m_pBmpContext.get(), nullptr);
- if (!avail_input.IsValid())
- return false;
-
- uint32_t dwAvail = avail_input.ValueOrDie();
- 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_TryRealloc(uint8_t, m_pSrcBuf, m_SrcSize);
- if (!m_pSrcBuf) {
- err_status = FXCODEC_STATUS_ERR_MEMORY;
- return false;
- }
- } else {
- uint32_t dwConsume = m_SrcSize - dwAvail;
- if (dwAvail) {
- memmove(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.get(), m_pSrcBuf, dwSize + dwAvail);
- return true;
-}
-
bool CCodec_ProgressiveDecoder::BmpInputImagePositionBuf(uint32_t rcd_pos) {
m_offSet = rcd_pos;
FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
@@ -1021,36 +739,6 @@ void CCodec_ProgressiveDecoder::ResampleVertBT(
}
}
-bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
- CFX_DIBAttribute* pAttribute) {
- m_offSet = 0;
- uint32_t size = (uint32_t)m_pFile->GetSize();
- if (size > FXCODEC_BLOCK_SIZE) {
- size = FXCODEC_BLOCK_SIZE;
- }
- FX_Free(m_pSrcBuf);
- m_pSrcBuf = FX_Alloc(uint8_t, size);
- memset(m_pSrcBuf, 0, size);
- m_SrcSize = size;
- switch (imageType) {
- case FXCODEC_IMAGE_BMP:
- return BmpDetectImageType(pAttribute, size);
- case FXCODEC_IMAGE_JPG:
- return JpegDetectImageType(pAttribute, size);
- case FXCODEC_IMAGE_PNG:
- return PngDetectImageType(pAttribute, size);
- case FXCODEC_IMAGE_GIF:
- return GifDetectImageType(pAttribute, size);
-#ifdef PDF_ENABLE_XFA_TIFF
- case FXCODEC_IMAGE_TIFF:
- return TiffDetectImageType(pAttribute, size);
-#endif // PDF_ENABLE_XFA_TIFF
- default:
- m_status = FXCODEC_STATUS_ERR_FORMAT;
- return false;
- }
-}
-
bool CCodec_ProgressiveDecoder::BmpDetectImageType(CFX_DIBAttribute* pAttribute,
uint32_t size) {
CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
@@ -1141,6 +829,366 @@ bool CCodec_ProgressiveDecoder::BmpDetectImageType(CFX_DIBAttribute* pAttribute,
return true;
}
+bool CCodec_ProgressiveDecoder::BmpReadMoreData(CCodec_BmpModule* pBmpModule,
+ FXCODEC_STATUS& err_status) {
+ uint32_t dwSize = (uint32_t)m_pFile->GetSize();
+ if (dwSize <= m_offSet)
+ return false;
+
+ dwSize = dwSize - m_offSet;
+ FX_SAFE_UINT32 avail_input =
+ pBmpModule->GetAvailInput(m_pBmpContext.get(), nullptr);
+ if (!avail_input.IsValid())
+ return false;
+
+ uint32_t dwAvail = avail_input.ValueOrDie();
+ 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_TryRealloc(uint8_t, m_pSrcBuf, m_SrcSize);
+ if (!m_pSrcBuf) {
+ err_status = FXCODEC_STATUS_ERR_MEMORY;
+ return false;
+ }
+ } else {
+ uint32_t dwConsume = m_SrcSize - dwAvail;
+ if (dwAvail) {
+ memmove(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.get(), m_pSrcBuf, dwSize + dwAvail);
+ return true;
+}
+
+FXCODEC_STATUS CCodec_ProgressiveDecoder::BmpStartDecode(
+ const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
+ CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
+ if (!pBmpModule) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
+ m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize);
+ memset(m_pDecodeBuf, 0, m_ScanlineSize);
+ m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
+ m_clipBox.Width());
+ m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
+ m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ return m_status;
+}
+
+FXCODEC_STATUS CCodec_ProgressiveDecoder::BmpContinueDecode() {
+ CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
+ if (!pBmpModule) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ while (true) {
+ int32_t readRes = pBmpModule->LoadImage(m_pBmpContext.get());
+ while (readRes == 2) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
+ if (!BmpReadMoreData(pBmpModule, error_status)) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = error_status;
+ return m_status;
+ }
+ readRes = pBmpModule->LoadImage(m_pBmpContext.get());
+ }
+ if (readRes == 1) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
+ return m_status;
+ }
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERROR;
+ return m_status;
+ }
+}
+
+bool CCodec_ProgressiveDecoder::GifReadMoreData(CCodec_GifModule* pGifModule,
+ FXCODEC_STATUS& err_status) {
+ if (static_cast<uint32_t>(m_pFile->GetSize()) <= m_offSet)
+ return false;
+
+ uint32_t dwFileRemaining = m_pFile->GetSize() - m_offSet;
+ uint32_t dwUnusedBuffer =
+ !m_InvalidateGifBuffer
+ ? pGifModule->GetAvailInput(m_pGifContext.get(), nullptr)
+ : 0;
+ uint32_t dwAmountToFetchFromFile = dwFileRemaining;
+ if (dwUnusedBuffer == m_SrcSize) {
+ if (dwFileRemaining > FXCODEC_BLOCK_SIZE)
+ dwAmountToFetchFromFile = FXCODEC_BLOCK_SIZE;
+ m_SrcSize = std::min(
+ (dwAmountToFetchFromFile + dwUnusedBuffer + FXCODEC_BLOCK_SIZE - 1) /
+ FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE,
+ static_cast<uint32_t>(m_pFile->GetSize()));
+ m_pSrcBuf = FX_TryRealloc(uint8_t, m_pSrcBuf, m_SrcSize);
+ if (!m_pSrcBuf) {
+ err_status = FXCODEC_STATUS_ERR_MEMORY;
+ return false;
+ }
+ } else {
+ uint32_t dwConsumed = m_SrcSize - dwUnusedBuffer;
+ if (dwUnusedBuffer)
+ memmove(m_pSrcBuf, m_pSrcBuf + dwConsumed, dwUnusedBuffer);
+ if (dwFileRemaining > dwConsumed)
+ dwAmountToFetchFromFile = dwConsumed;
+ }
+
+ if (!m_pFile->ReadBlock(m_pSrcBuf + dwUnusedBuffer, m_offSet,
+ dwAmountToFetchFromFile)) {
+ err_status = FXCODEC_STATUS_ERR_READ;
+ return false;
+ }
+
+ m_offSet += dwAmountToFetchFromFile;
+ pGifModule->Input(m_pGifContext.get(), m_pSrcBuf,
+ dwAmountToFetchFromFile + dwUnusedBuffer);
+ m_InvalidateGifBuffer = false;
+ return true;
+}
+
+bool CCodec_ProgressiveDecoder::GifDetectImageType(CFX_DIBAttribute* pAttribute,
+ uint32_t size) {
+ CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
+ if (!pGifModule) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return false;
+ }
+ m_pGifContext = pGifModule->Start(this);
+ 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.get(), m_pSrcBuf, size);
+ m_SrcComponents = 1;
+ CFX_GifDecodeStatus readResult = pGifModule->ReadHeader(
+ m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
+ &m_pGifPalette, &m_GifBgIndex, nullptr);
+ while (readResult == CFX_GifDecodeStatus::Unfinished) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
+ if (!GifReadMoreData(pGifModule, error_status)) {
+ m_pGifContext = nullptr;
+ m_status = error_status;
+ return false;
+ }
+ readResult = pGifModule->ReadHeader(m_pGifContext.get(), &m_SrcWidth,
+ &m_SrcHeight, &m_GifPltNumber,
+ &m_pGifPalette, &m_GifBgIndex, nullptr);
+ }
+ if (readResult == CFX_GifDecodeStatus::Success) {
+ m_SrcBPC = 8;
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
+ return true;
+ }
+ m_pGifContext = nullptr;
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return false;
+}
+
+FXCODEC_STATUS CCodec_ProgressiveDecoder::GifStartDecode(
+ const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
+ CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
+ if (!pGifModule) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ m_SrcFormat = FXCodec_8bppRgb;
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
+ int scanline_size = (m_SrcWidth + 3) / 4 * 4;
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
+ memset(m_pDecodeBuf, 0, scanline_size);
+ m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
+ m_clipBox.Width());
+ m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
+ m_FrameCur = 0;
+ m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ return m_status;
+}
+
+FXCODEC_STATUS CCodec_ProgressiveDecoder::GifContinueDecode() {
+ CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
+ if (!pGifModule) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+
+ CFX_GifDecodeStatus readRes =
+ pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
+ while (readRes == CFX_GifDecodeStatus::Unfinished) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
+ if (!GifReadMoreData(pGifModule, error_status)) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = error_status;
+ return m_status;
+ }
+ readRes = pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
+ }
+
+ if (readRes == CFX_GifDecodeStatus::Success) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
+ return m_status;
+ }
+
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERROR;
+ return m_status;
+}
+
+void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert(
+ const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
+ double scale_y,
+ int dest_row) {
+ int dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
+ uint32_t dest_ScanOffet = m_startX * dest_Bpp;
+ int dest_top = m_startY;
+ pdfium::base::CheckedNumeric<double> scale_y2 = scale_y;
+ scale_y2 *= 2;
+ pdfium::base::CheckedNumeric<int> check_dest_row_1 = dest_row;
+ check_dest_row_1 -= scale_y2.ValueOrDie();
+ int dest_row_1 = check_dest_row_1.ValueOrDie();
+ dest_row_1 = std::max(dest_row_1, dest_top);
+ for (; dest_row_1 < dest_row; dest_row_1++) {
+ uint8_t* scan_des =
+ (uint8_t*)pDeviceBitmap->GetScanline(dest_row_1) + dest_ScanOffet;
+ PixelWeight* pWeight = m_WeightVert.GetPixelWeight(dest_row_1 - dest_top);
+ const uint8_t* scan_src1 =
+ pDeviceBitmap->GetScanline(pWeight->m_SrcStart + dest_top) +
+ dest_ScanOffet;
+ const uint8_t* scan_src2 =
+ pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + dest_top) +
+ dest_ScanOffet;
+ for (int dest_col = 0; dest_col < m_sizeX; dest_col++) {
+ switch (pDeviceBitmap->GetFormat()) {
+ case FXDIB_Invalid:
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ return;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ if (pDeviceBitmap->GetPalette()) {
+ return;
+ }
+ int dest_g = 0;
+ dest_g += pWeight->m_Weights[0] * (*scan_src1++);
+ dest_g += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (uint8_t)(dest_g >> 16);
+ } break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ uint32_t dest_b = 0;
+ uint32_t dest_g = 0;
+ uint32_t dest_r = 0;
+ dest_b += pWeight->m_Weights[0] * (*scan_src1++);
+ dest_g += pWeight->m_Weights[0] * (*scan_src1++);
+ dest_r += pWeight->m_Weights[0] * (*scan_src1++);
+ scan_src1 += dest_Bpp - 3;
+ dest_b += pWeight->m_Weights[1] * (*scan_src2++);
+ dest_g += pWeight->m_Weights[1] * (*scan_src2++);
+ dest_r += pWeight->m_Weights[1] * (*scan_src2++);
+ scan_src2 += dest_Bpp - 3;
+ *scan_des++ = (uint8_t)((dest_b) >> 16);
+ *scan_des++ = (uint8_t)((dest_g) >> 16);
+ *scan_des++ = (uint8_t)((dest_r) >> 16);
+ scan_des += dest_Bpp - 3;
+ } break;
+ case FXDIB_Argb: {
+ uint32_t dest_a = 0;
+ uint32_t dest_b = 0;
+ uint32_t dest_g = 0;
+ uint32_t dest_r = 0;
+ dest_b += pWeight->m_Weights[0] * (*scan_src1++);
+ dest_g += pWeight->m_Weights[0] * (*scan_src1++);
+ dest_r += pWeight->m_Weights[0] * (*scan_src1++);
+ dest_a += pWeight->m_Weights[0] * (*scan_src1++);
+ dest_b += pWeight->m_Weights[1] * (*scan_src2++);
+ dest_g += pWeight->m_Weights[1] * (*scan_src2++);
+ dest_r += pWeight->m_Weights[1] * (*scan_src2++);
+ dest_a += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (uint8_t)((dest_b) >> 16);
+ *scan_des++ = (uint8_t)((dest_g) >> 16);
+ *scan_des++ = (uint8_t)((dest_r) >> 16);
+ *scan_des++ = (uint8_t)((dest_a) >> 16);
+ } break;
+ default:
+ return;
+ }
+ }
+ }
+ int dest_bottom = dest_top + m_sizeY - 1;
+ if (dest_row + (int)(2 * scale_y) >= dest_bottom &&
+ dest_row + (int)scale_y < dest_bottom) {
+ GifDoubleLineResampleVert(pDeviceBitmap, scale_y, dest_row + (int)scale_y);
+ }
+}
+
+bool CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule,
+ FXCODEC_STATUS& err_status) {
+ uint32_t dwSize = (uint32_t)m_pFile->GetSize();
+ if (dwSize <= m_offSet) {
+ return false;
+ }
+ dwSize = dwSize - m_offSet;
+ uint32_t dwAvail = pJpegModule->GetAvailInput(m_pJpegContext.get(), nullptr);
+ 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_TryRealloc(uint8_t, m_pSrcBuf, m_SrcSize);
+ if (!m_pSrcBuf) {
+ err_status = FXCODEC_STATUS_ERR_MEMORY;
+ return false;
+ }
+ } else {
+ uint32_t dwConsume = m_SrcSize - dwAvail;
+ if (dwAvail) {
+ memmove(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.get(), m_pSrcBuf, dwSize + dwAvail);
+ return true;
+}
+
bool CCodec_ProgressiveDecoder::JpegDetectImageType(
CFX_DIBAttribute* pAttribute,
uint32_t size) {
@@ -1187,6 +1235,172 @@ bool CCodec_ProgressiveDecoder::JpegDetectImageType(
return false;
}
+FXCODEC_STATUS CCodec_ProgressiveDecoder::JpegStartDecode(
+ const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
+ int down_scale = 1;
+ GetDownScale(down_scale);
+ // Setting jump marker before calling StartScanLine, since a longjmp to
+ // the marker indicates a fatal error.
+ if (setjmp(*m_pJpegContext->GetJumpMark()) == -1) {
+ m_pJpegContext.reset();
+ m_status = FXCODEC_STATUS_ERROR;
+ return FXCODEC_STATUS_ERROR;
+ }
+
+ CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
+ bool startStatus =
+ pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
+ while (!startStatus) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
+ if (!JpegReadMoreData(pJpegModule, error_status)) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = error_status;
+ return m_status;
+ }
+
+ startStatus = pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
+ }
+ int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale;
+ scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4;
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
+ memset(m_pDecodeBuf, 0, scanline_size);
+ m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
+ m_clipBox.Width());
+ 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);
+ m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ return m_status;
+}
+
+FXCODEC_STATUS CCodec_ProgressiveDecoder::JpegContinueDecode() {
+ CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
+ // Setting jump marker before calling ReadScanLine, since a longjmp to
+ // the marker indicates a fatal error.
+ if (setjmp(*m_pJpegContext->GetJumpMark()) == -1) {
+ m_pJpegContext.reset();
+ m_status = FXCODEC_STATUS_ERROR;
+ return FXCODEC_STATUS_ERROR;
+ }
+
+ while (true) {
+ bool readRes =
+ pJpegModule->ReadScanline(m_pJpegContext.get(), m_pDecodeBuf);
+ while (!readRes) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
+ if (!JpegReadMoreData(pJpegModule, error_status)) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = error_status;
+ return m_status;
+ }
+ readRes = pJpegModule->ReadScanline(m_pJpegContext.get(), 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 = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
+ return m_status;
+ }
+ Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat);
+ m_SrcRow++;
+ }
+}
+
+#ifdef PDF_ENABLE_XFA_PNG
+void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz(
+ const RetainPtr<CFX_DIBitmap>& pDeviceBitmap,
+ int32_t dest_line,
+ uint8_t* src_scan,
+ FXCodec_Format src_format) {
+ uint8_t* dest_scan = (uint8_t*)pDeviceBitmap->GetScanline(dest_line);
+ int32_t src_Bpp = (m_SrcFormat & 0xff) >> 3;
+ int32_t dest_Bpp = pDeviceBitmap->GetBPP() >> 3;
+ int32_t src_left = m_clipBox.left;
+ int32_t dest_left = m_startX;
+ src_scan += src_left * src_Bpp;
+ dest_scan += dest_left * dest_Bpp;
+ for (int32_t dest_col = 0; dest_col < m_sizeX; dest_col++) {
+ PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(dest_col);
+ switch (pDeviceBitmap->GetFormat()) {
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ NOTREACHED();
+ return;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ if (pDeviceBitmap->GetPalette()) {
+ return;
+ }
+ uint32_t dest_g = 0;
+ dest_g +=
+ pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart];
+ dest_g +=
+ pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd];
+ *dest_scan++ = (uint8_t)(dest_g >> 16);
+ } break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ uint32_t dest_b = 0;
+ uint32_t dest_g = 0;
+ uint32_t dest_r = 0;
+ const uint8_t* p = src_scan;
+ p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
+ dest_b += pPixelWeights->m_Weights[0] * (*p++);
+ dest_g += pPixelWeights->m_Weights[0] * (*p++);
+ dest_r += pPixelWeights->m_Weights[0] * (*p);
+ p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
+ dest_b += pPixelWeights->m_Weights[1] * (*p++);
+ dest_g += pPixelWeights->m_Weights[1] * (*p++);
+ dest_r += pPixelWeights->m_Weights[1] * (*p);
+ *dest_scan++ = (uint8_t)((dest_b) >> 16);
+ *dest_scan++ = (uint8_t)((dest_g) >> 16);
+ *dest_scan++ = (uint8_t)((dest_r) >> 16);
+ dest_scan += dest_Bpp - 3;
+ } break;
+ case FXDIB_Argb: {
+ uint32_t dest_a = 0;
+ uint32_t dest_b = 0;
+ uint32_t dest_g = 0;
+ uint32_t dest_r = 0;
+ const uint8_t* p = src_scan;
+ p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
+ dest_b += pPixelWeights->m_Weights[0] * (*p++);
+ dest_g += pPixelWeights->m_Weights[0] * (*p++);
+ dest_r += pPixelWeights->m_Weights[0] * (*p++);
+ dest_a += pPixelWeights->m_Weights[0] * (*p);
+ p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
+ dest_b += pPixelWeights->m_Weights[1] * (*p++);
+ dest_g += pPixelWeights->m_Weights[1] * (*p++);
+ dest_r += pPixelWeights->m_Weights[1] * (*p++);
+ dest_a += pPixelWeights->m_Weights[1] * (*p);
+ *dest_scan++ = (uint8_t)((dest_b) >> 16);
+ *dest_scan++ = (uint8_t)((dest_g) >> 16);
+ *dest_scan++ = (uint8_t)((dest_r) >> 16);
+ *dest_scan++ = (uint8_t)((dest_a) >> 16);
+ } break;
+ default:
+ return;
+ }
+ }
+}
+
bool CCodec_ProgressiveDecoder::PngDetectImageType(CFX_DIBAttribute* pAttribute,
uint32_t size) {
CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
@@ -1240,45 +1454,98 @@ bool CCodec_ProgressiveDecoder::PngDetectImageType(CFX_DIBAttribute* pAttribute,
return true;
}
-bool CCodec_ProgressiveDecoder::GifDetectImageType(CFX_DIBAttribute* pAttribute,
- uint32_t size) {
- CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
- if (!pGifModule) {
+FXCODEC_STATUS CCodec_ProgressiveDecoder::PngStartDecode(
+ const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
+ CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
+ if (!pPngModule) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
m_status = FXCODEC_STATUS_ERR_MEMORY;
- return false;
+ return m_status;
}
- m_pGifContext = pGifModule->Start(this);
- bool bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
- if (!bResult) {
- m_status = FXCODEC_STATUS_ERR_READ;
- return false;
+ m_pPngContext = pPngModule->Start(this);
+ if (!m_pPngContext) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
}
- m_offSet += size;
- pGifModule->Input(m_pGifContext.get(), m_pSrcBuf, size);
- m_SrcComponents = 1;
- CFX_GifDecodeStatus readResult = pGifModule->ReadHeader(
- m_pGifContext.get(), &m_SrcWidth, &m_SrcHeight, &m_GifPltNumber,
- &m_pGifPalette, &m_GifBgIndex, nullptr);
- while (readResult == CFX_GifDecodeStatus::Unfinished) {
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
- if (!GifReadMoreData(pGifModule, error_status)) {
- m_pGifContext = nullptr;
- m_status = error_status;
- return false;
+ 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 = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_PARAMS;
+ return m_status;
}
- readResult = pGifModule->ReadHeader(m_pGifContext.get(), &m_SrcWidth,
- &m_SrcHeight, &m_GifPltNumber,
- &m_pGifPalette, &m_GifBgIndex, nullptr);
}
- if (readResult == CFX_GifDecodeStatus::Success) {
- m_SrcBPC = 8;
- m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
- return true;
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
+ int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
+ memset(m_pDecodeBuf, 0, scanline_size);
+ m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width());
+ m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
+ m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ return m_status;
+}
+
+FXCODEC_STATUS CCodec_ProgressiveDecoder::PngContinueDecode() {
+ CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
+ if (!pPngModule) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ while (true) {
+ uint32_t remain_size = (uint32_t)m_pFile->GetSize() - m_offSet;
+ uint32_t input_size =
+ remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
+ if (input_size == 0) {
+ m_pPngContext.reset();
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
+ return m_status;
+ }
+ if (m_pSrcBuf && input_size > m_SrcSize) {
+ FX_Free(m_pSrcBuf);
+ m_pSrcBuf = FX_Alloc(uint8_t, input_size);
+ memset(m_pSrcBuf, 0, input_size);
+ m_SrcSize = input_size;
+ }
+ bool bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);
+ if (!bResult) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_READ;
+ return m_status;
+ }
+ m_offSet += input_size;
+ bResult =
+ pPngModule->Input(m_pPngContext.get(), m_pSrcBuf, input_size, nullptr);
+ if (!bResult) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERROR;
+ return m_status;
+ }
}
- m_pGifContext = nullptr;
- m_status = FXCODEC_STATUS_ERR_FORMAT;
- return false;
}
+#endif // PDF_ENABLE_XFA_PNG
#ifdef PDF_ENABLE_XFA_TIFF
bool CCodec_ProgressiveDecoder::TiffDetectImageType(
@@ -1307,8 +1574,179 @@ bool CCodec_ProgressiveDecoder::TiffDetectImageType(
}
return true;
}
+
+FXCODEC_STATUS CCodec_ProgressiveDecoder::TiffContinueDecode() {
+ CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
+ if (!pTiffModule) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ 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.get(), m_pDeviceBitmap);
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ if (!ret) {
+ m_status = FXCODEC_STATUS_ERROR;
+ return m_status;
+ }
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
+ return m_status;
+ }
+
+ auto pDIBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);
+ if (!pDIBitmap->GetBuffer()) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ ret = pTiffModule->Decode(m_pTiffContext.get(), pDIBitmap);
+ if (!ret) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERROR;
+ return m_status;
+ }
+ RetainPtr<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 (!pClipBitmap) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ RetainPtr<CFX_DIBitmap> pFormatBitmap;
+ switch (m_pDeviceBitmap->GetFormat()) {
+ case FXDIB_8bppRgb:
+ pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
+ FXDIB_8bppRgb);
+ break;
+ case FXDIB_8bppMask:
+ pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
+ FXDIB_8bppMask);
+ break;
+ case FXDIB_Rgb:
+ pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
+ FXDIB_Rgb);
+ break;
+ case FXDIB_Rgb32:
+ pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
+ FXDIB_Rgb32);
+ break;
+ case FXDIB_Argb:
+ pFormatBitmap = pClipBitmap;
+ break;
+ default:
+ break;
+ }
+ switch (m_pDeviceBitmap->GetFormat()) {
+ case FXDIB_8bppRgb:
+ case FXDIB_8bppMask: {
+ for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
+ uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
+ uint8_t* dest_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;
+ *dest_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* dest_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;
+ *dest_line++ = b;
+ *dest_line++ = g;
+ *dest_line++ = r;
+ dest_line += desBpp - 3;
+ src_line += 4;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+ if (!pFormatBitmap) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ RetainPtr<CFX_DIBitmap> pStrechBitmap =
+ pFormatBitmap->StretchTo(m_sizeX, m_sizeY, FXDIB_INTERPOL, nullptr);
+ pFormatBitmap = nullptr;
+ if (!pStrechBitmap) {
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return m_status;
+ }
+ m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY,
+ pStrechBitmap, 0, 0);
+ m_pDeviceBitmap = nullptr;
+ m_pFile = nullptr;
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
+ return m_status;
+}
#endif // PDF_ENABLE_XFA_TIFF
+bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType,
+ CFX_DIBAttribute* pAttribute) {
+ m_offSet = 0;
+ uint32_t size = (uint32_t)m_pFile->GetSize();
+ if (size > FXCODEC_BLOCK_SIZE) {
+ size = FXCODEC_BLOCK_SIZE;
+ }
+ FX_Free(m_pSrcBuf);
+ m_pSrcBuf = FX_Alloc(uint8_t, size);
+ memset(m_pSrcBuf, 0, size);
+ m_SrcSize = size;
+ switch (imageType) {
+ case FXCODEC_IMAGE_BMP:
+ return BmpDetectImageType(pAttribute, size);
+ case FXCODEC_IMAGE_JPG:
+ return JpegDetectImageType(pAttribute, size);
+#ifdef PDF_ENABLE_XFA_PNG
+ case FXCODEC_IMAGE_PNG:
+ return PngDetectImageType(pAttribute, size);
+#endif // PDF_ENABLE_XFA_PNG
+ case FXCODEC_IMAGE_GIF:
+ return GifDetectImageType(pAttribute, size);
+#ifdef PDF_ENABLE_XFA_TIFF
+ case FXCODEC_IMAGE_TIFF:
+ return TiffDetectImageType(pAttribute, size);
+#endif // PDF_ENABLE_XFA_TIFF
+ default:
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return false;
+ }
+}
+
FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(
const RetainPtr<IFX_SeekableReadStream>& pFile,
FXCODEC_IMAGE_TYPE imageType,
@@ -1862,7 +2300,9 @@ std::pair<FXCODEC_STATUS, size_t> CCodec_ProgressiveDecoder::GetFrames() {
switch (m_imagType) {
case FXCODEC_IMAGE_JPG:
case FXCODEC_IMAGE_BMP:
+#ifdef PDF_ENABLE_XFA_PNG
case FXCODEC_IMAGE_PNG:
+#endif // PDF_ENABLE_XFA_PNG
#ifdef PDF_ENABLE_XFA_TIFF
case FXCODEC_IMAGE_TIFF:
#endif // PDF_ENABLE_XFA_TIFF
@@ -1957,8 +2397,10 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(
switch (m_imagType) {
case FXCODEC_IMAGE_JPG:
return JpegStartDecode(pDIBitmap);
+#ifdef PDF_ENABLE_XFA_PNG
case FXCODEC_IMAGE_PNG:
return PngStartDecode(pDIBitmap);
+#endif // PDF_ENABLE_XFA_PNG
case FXCODEC_IMAGE_GIF:
return GifStartDecode(pDIBitmap);
case FXCODEC_IMAGE_BMP:
@@ -1973,150 +2415,6 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(
}
}
-FXCODEC_STATUS CCodec_ProgressiveDecoder::JpegStartDecode(
- const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
- int down_scale = 1;
- GetDownScale(down_scale);
- // Setting jump marker before calling StartScanLine, since a longjmp to
- // the marker indicates a fatal error.
- if (setjmp(*m_pJpegContext->GetJumpMark()) == -1) {
- m_pJpegContext.reset();
- m_status = FXCODEC_STATUS_ERROR;
- return FXCODEC_STATUS_ERROR;
- }
-
- CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
- bool startStatus =
- pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
- while (!startStatus) {
- FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
- if (!JpegReadMoreData(pJpegModule, error_status)) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = error_status;
- return m_status;
- }
-
- startStatus = pJpegModule->StartScanline(m_pJpegContext.get(), down_scale);
- }
- int scanline_size = (m_SrcWidth + down_scale - 1) / down_scale;
- scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4;
- FX_Free(m_pDecodeBuf);
- m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
- memset(m_pDecodeBuf, 0, scanline_size);
- m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
- m_clipBox.Width());
- 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);
- m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
- return m_status;
-}
-
-FXCODEC_STATUS CCodec_ProgressiveDecoder::PngStartDecode(
- const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
- CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
- if (!pPngModule) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- m_pPngContext = pPngModule->Start(this);
- if (!m_pPngContext) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- 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 = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_PARAMS;
- return m_status;
- }
- }
- GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
- int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
- FX_Free(m_pDecodeBuf);
- m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
- memset(m_pDecodeBuf, 0, scanline_size);
- m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width());
- m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
- m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
- return m_status;
-}
-
-FXCODEC_STATUS CCodec_ProgressiveDecoder::GifStartDecode(
- const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
- CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
- if (!pGifModule) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- m_SrcFormat = FXCodec_8bppRgb;
- GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
- int scanline_size = (m_SrcWidth + 3) / 4 * 4;
- FX_Free(m_pDecodeBuf);
- m_pDecodeBuf = FX_Alloc(uint8_t, scanline_size);
- memset(m_pDecodeBuf, 0, scanline_size);
- m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
- m_clipBox.Width());
- m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
- m_FrameCur = 0;
- m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
- return m_status;
-}
-
-FXCODEC_STATUS CCodec_ProgressiveDecoder::BmpStartDecode(
- const RetainPtr<CFX_DIBitmap>& pDIBitmap) {
- CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
- if (!pBmpModule) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
- m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
- FX_Free(m_pDecodeBuf);
- m_pDecodeBuf = FX_Alloc(uint8_t, m_ScanlineSize);
- memset(m_pDecodeBuf, 0, m_ScanlineSize);
- m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0,
- m_clipBox.Width());
- m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
- m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
- return m_status;
-}
-
FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() {
if (m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE)
return FXCODEC_STATUS_ERROR;
@@ -2124,8 +2422,10 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() {
switch (m_imagType) {
case FXCODEC_IMAGE_JPG:
return JpegContinueDecode();
+#ifdef PDF_ENABLE_XFA_PNG
case FXCODEC_IMAGE_PNG:
return PngContinueDecode();
+#endif // PDF_ENABLE_XFA_PNG
case FXCODEC_IMAGE_GIF:
return GifContinueDecode();
case FXCODEC_IMAGE_BMP:
@@ -2139,293 +2439,6 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() {
}
}
-FXCODEC_STATUS CCodec_ProgressiveDecoder::JpegContinueDecode() {
- CCodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
- // Setting jump marker before calling ReadScanLine, since a longjmp to
- // the marker indicates a fatal error.
- if (setjmp(*m_pJpegContext->GetJumpMark()) == -1) {
- m_pJpegContext.reset();
- m_status = FXCODEC_STATUS_ERROR;
- return FXCODEC_STATUS_ERROR;
- }
-
- while (true) {
- bool readRes =
- pJpegModule->ReadScanline(m_pJpegContext.get(), m_pDecodeBuf);
- while (!readRes) {
- FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
- if (!JpegReadMoreData(pJpegModule, error_status)) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = error_status;
- return m_status;
- }
- readRes = pJpegModule->ReadScanline(m_pJpegContext.get(), 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 = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_DECODE_FINISH;
- return m_status;
- }
- Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat);
- m_SrcRow++;
- }
-}
-
-FXCODEC_STATUS CCodec_ProgressiveDecoder::PngContinueDecode() {
- CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
- if (!pPngModule) {
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- while (true) {
- uint32_t remain_size = (uint32_t)m_pFile->GetSize() - m_offSet;
- uint32_t input_size =
- remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
- if (input_size == 0) {
- m_pPngContext.reset();
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_DECODE_FINISH;
- return m_status;
- }
- if (m_pSrcBuf && input_size > m_SrcSize) {
- FX_Free(m_pSrcBuf);
- m_pSrcBuf = FX_Alloc(uint8_t, input_size);
- memset(m_pSrcBuf, 0, input_size);
- m_SrcSize = input_size;
- }
- bool bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);
- if (!bResult) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_READ;
- return m_status;
- }
- m_offSet += input_size;
- bResult =
- pPngModule->Input(m_pPngContext.get(), m_pSrcBuf, input_size, nullptr);
- if (!bResult) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERROR;
- return m_status;
- }
- }
-}
-
-FXCODEC_STATUS CCodec_ProgressiveDecoder::GifContinueDecode() {
- CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
- if (!pGifModule) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
-
- CFX_GifDecodeStatus readRes =
- pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
- while (readRes == CFX_GifDecodeStatus::Unfinished) {
- FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
- if (!GifReadMoreData(pGifModule, error_status)) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = error_status;
- return m_status;
- }
- readRes = pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr);
- }
-
- if (readRes == CFX_GifDecodeStatus::Success) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_DECODE_FINISH;
- return m_status;
- }
-
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERROR;
- return m_status;
-}
-
-FXCODEC_STATUS CCodec_ProgressiveDecoder::BmpContinueDecode() {
- CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
- if (!pBmpModule) {
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- while (true) {
- int32_t readRes = pBmpModule->LoadImage(m_pBmpContext.get());
- while (readRes == 2) {
- FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
- if (!BmpReadMoreData(pBmpModule, error_status)) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = error_status;
- return m_status;
- }
- readRes = pBmpModule->LoadImage(m_pBmpContext.get());
- }
- if (readRes == 1) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_DECODE_FINISH;
- return m_status;
- }
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERROR;
- return m_status;
- }
-}
-
-#ifdef PDF_ENABLE_XFA_TIFF
-FXCODEC_STATUS CCodec_ProgressiveDecoder::TiffContinueDecode() {
- CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
- if (!pTiffModule) {
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- 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.get(), m_pDeviceBitmap);
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- if (!ret) {
- m_status = FXCODEC_STATUS_ERROR;
- return m_status;
- }
- m_status = FXCODEC_STATUS_DECODE_FINISH;
- return m_status;
- }
-
- auto pDIBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);
- if (!pDIBitmap->GetBuffer()) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- ret = pTiffModule->Decode(m_pTiffContext.get(), pDIBitmap);
- if (!ret) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERROR;
- return m_status;
- }
- RetainPtr<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 (!pClipBitmap) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- RetainPtr<CFX_DIBitmap> pFormatBitmap;
- switch (m_pDeviceBitmap->GetFormat()) {
- case FXDIB_8bppRgb:
- pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
- FXDIB_8bppRgb);
- break;
- case FXDIB_8bppMask:
- pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
- FXDIB_8bppMask);
- break;
- case FXDIB_Rgb:
- pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
- FXDIB_Rgb);
- break;
- case FXDIB_Rgb32:
- pFormatBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
- pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(),
- FXDIB_Rgb32);
- break;
- case FXDIB_Argb:
- pFormatBitmap = pClipBitmap;
- break;
- default:
- break;
- }
- switch (m_pDeviceBitmap->GetFormat()) {
- case FXDIB_8bppRgb:
- case FXDIB_8bppMask: {
- for (int32_t row = 0; row < pClipBitmap->GetHeight(); row++) {
- uint8_t* src_line = (uint8_t*)pClipBitmap->GetScanline(row);
- uint8_t* dest_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;
- *dest_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* dest_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;
- *dest_line++ = b;
- *dest_line++ = g;
- *dest_line++ = r;
- dest_line += desBpp - 3;
- src_line += 4;
- }
- }
- } break;
- default:
- break;
- }
- if (!pFormatBitmap) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- RetainPtr<CFX_DIBitmap> pStrechBitmap =
- pFormatBitmap->StretchTo(m_sizeX, m_sizeY, FXDIB_INTERPOL, nullptr);
- pFormatBitmap = nullptr;
- if (!pStrechBitmap) {
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_ERR_MEMORY;
- return m_status;
- }
- m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY,
- pStrechBitmap, 0, 0);
- m_pDeviceBitmap = nullptr;
- m_pFile = nullptr;
- m_status = FXCODEC_STATUS_DECODE_FINISH;
- return m_status;
-}
-#endif // PDF_ENABLE_XFA_TIFF
-
std::unique_ptr<CCodec_ProgressiveDecoder>
CCodec_ModuleMgr::CreateProgressiveDecoder() {
return pdfium::MakeUnique<CCodec_ProgressiveDecoder>(this);
diff --git a/core/fxcodec/fx_codec_def.h b/core/fxcodec/fx_codec_def.h
index e4ac0437eb..b7944ee1c1 100644
--- a/core/fxcodec/fx_codec_def.h
+++ b/core/fxcodec/fx_codec_def.h
@@ -28,13 +28,16 @@ enum FXCODEC_IMAGE_TYPE {
FXCODEC_IMAGE_UNKNOWN = 0,
FXCODEC_IMAGE_BMP,
FXCODEC_IMAGE_JPG,
+#ifdef PDF_ENABLE_XFA_PNG
FXCODEC_IMAGE_PNG,
+#endif // PDF_ENABLE_XFA_PNG
FXCODEC_IMAGE_GIF,
#ifdef PDF_ENABLE_XFA_TIFF
FXCODEC_IMAGE_TIFF,
#endif // PDF_ENABLE_XFA_TIFF
FXCODEC_IMAGE_MAX
};
+
enum FXCODEC_RESUNIT {
FXCODEC_RESUNIT_NONE = 0,
FXCODEC_RESUNIT_INCH,
diff --git a/testing/libfuzzer/BUILD.gn b/testing/libfuzzer/BUILD.gn
index a45c8d2576..5a050a2237 100644
--- a/testing/libfuzzer/BUILD.gn
+++ b/testing/libfuzzer/BUILD.gn
@@ -42,12 +42,14 @@ group("libfuzzer") {
":pdf_codec_bmp_fuzzer",
":pdf_codec_gif_fuzzer",
":pdf_codec_jpeg_fuzzer",
- ":pdf_codec_png_fuzzer",
":pdf_css_fuzzer",
":pdf_fm2js_fuzzer",
":pdf_formcalc_fuzzer",
":pdf_lzw_fuzzer",
]
+ if (pdf_enable_xfa_png) {
+ deps += [ ":pdf_codec_png_fuzzer" ]
+ }
if (pdf_enable_xfa_tiff) {
deps += [ ":pdf_codec_tiff_fuzzer" ]
}
@@ -100,11 +102,13 @@ if (pdf_enable_xfa) {
]
}
- pdfium_fuzzer("pdf_codec_png_fuzzer") {
- sources = [
- "pdf_codec_png_fuzzer.cc",
- "xfa_codec_fuzzer.h",
- ]
+ if (pdf_enable_xfa_png) {
+ pdfium_fuzzer("pdf_codec_png_fuzzer") {
+ sources = [
+ "pdf_codec_png_fuzzer.cc",
+ "xfa_codec_fuzzer.h",
+ ]
+ }
}
if (pdf_enable_xfa_tiff) {
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index 6fd2397670..3c5a3411a7 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -52,7 +52,9 @@ FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
dibFormat = FXDIB_Rgb;
}
} break;
+#ifdef PDF_ENABLE_XFA_PNG
case FXCODEC_IMAGE_PNG:
+#endif // PDF_ENABLE_XFA_PNG
default:
break;
}
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 674ec00d8e..7e479b1858 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -165,8 +165,10 @@ FXCODEC_IMAGE_TYPE XFA_GetImageType(const WideString& wsType) {
wsContentType.MakeLower();
if (wsContentType == L"image/jpg")
return FXCODEC_IMAGE_JPG;
+#ifdef PDF_ENABLE_XFA_PNG
if (wsContentType == L"image/png")
return FXCODEC_IMAGE_PNG;
+#endif // PDF_ENABLE_XFA_PNG
if (wsContentType == L"image/gif")
return FXCODEC_IMAGE_GIF;
if (wsContentType == L"image/bmp")