summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Harrison <rharrison@chromium.org>2018-05-09 20:31:12 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-05-09 20:31:12 +0000
commitd5d48457dabbe71e7f6b0baf2eaea6aa0dc86736 (patch)
tree5694486d6c11a60a0ce602759c3c1e07c63b46fc
parent54ef2cb9eb5b145c6e973e95ccb488e121556ad7 (diff)
downloadpdfium-d5d48457dabbe71e7f6b0baf2eaea6aa0dc86736.tar.xz
Do not build PNG when codec is disabled
Currently all of the PNG related code is being built when support for the codec is disabled, it just isn't being utilized. Depending on the settings being used, this unneeded code may or may not get stripped during linking. This CL explicitly turns off building the PNG codec code if support for PNG is turned off. BUG=pdfium:1080 Change-Id: I9c5247145fcadbcb1bd2243aa83350304ba421ff Reviewed-on: https://pdfium-review.googlesource.com/32270 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Ryan Harrison <rharrison@chromium.org>
-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")