Index: core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp |
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp |
index 3fabdf9f4ff878b035d41f5d0eb9a59a9fb4de02..b1fd51ebe9056941d8d668b181492dbca7096ae1 100644 |
--- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp |
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp |
@@ -4,6 +4,7 @@ |
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
+#include "../../../../third_party/base/nonstd_unique_ptr.h" |
#include "../../../include/fpdfapi/fpdf_module.h" |
#include "../../../include/fpdfapi/fpdf_pageobj.h" |
#include "../../../include/fpdfapi/fpdf_render.h" |
@@ -55,6 +56,49 @@ FX_SAFE_DWORD CalculatePitch32(int bpp, int width) |
return pitch; |
} |
+// Wrapper class to hold objects allocated in CPDF_DIBSource::LoadJpxBitmap(), |
+// because nonstd::unique_ptr does not support custom deleters yet. |
+class JpxBitMapContext |
+{ |
+ public: |
+ explicit JpxBitMapContext(ICodec_JpxModule* jpx_module) |
+ : jpx_module_(jpx_module), |
+ ctx_(nullptr), |
+ output_offsets_(nullptr) {} |
+ |
+ ~JpxBitMapContext() { |
+ FX_Free(output_offsets_); |
+ jpx_module_->DestroyDecoder(ctx_); |
+ } |
+ |
+ // Takes ownership of |ctx|. |
+ void set_context(void* ctx) { |
+ ctx_ = ctx; |
+ } |
+ |
+ void* context() { |
+ return ctx_; |
+ } |
+ |
+ // Takes ownership of |output_offsets|. |
+ void set_output_offsets(unsigned char* output_offsets) { |
+ output_offsets_ = output_offsets; |
+ } |
+ |
+ unsigned char* output_offsets() { |
+ return output_offsets_; |
+ } |
+ |
+ private: |
+ ICodec_JpxModule* jpx_module_; // Weak pointer. |
+ void* ctx_; // Decoder context, owned. |
+ unsigned char* output_offsets_; // Output offsets for decoding, owned. |
+ |
+ // Disallow evil constructors |
+ JpxBitMapContext(const JpxBitMapContext&); |
+ void operator=(const JpxBitMapContext&); |
+}; |
+ |
} // namespace |
CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatteColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const |
@@ -124,7 +168,6 @@ CPDF_DIBSource::CPDF_DIBSource() |
m_pCompData = NULL; |
m_bColorKey = FALSE; |
m_pMaskedLine = m_pLineBuf = NULL; |
- m_pCachedBitmap = NULL; |
m_pDecoder = NULL; |
m_nComponents = 0; |
m_bpc = 0; |
@@ -148,7 +191,7 @@ CPDF_DIBSource::~CPDF_DIBSource() |
if (m_pLineBuf) { |
FX_Free(m_pLineBuf); |
} |
- delete m_pCachedBitmap; |
+ m_pCachedBitmap.reset(); |
delete m_pDecoder; |
if (m_pCompData) { |
FX_Free(m_pCompData); |
@@ -165,10 +208,7 @@ CPDF_DIBSource::~CPDF_DIBSource() |
} |
CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const |
{ |
- if (m_pCachedBitmap) { |
- return m_pCachedBitmap; |
- } |
- return Clone(); |
+ return m_pCachedBitmap ? m_pCachedBitmap.get() : Clone(); |
} |
void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const |
{ |
@@ -375,8 +415,7 @@ int CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) |
m_pGlobalStream ? m_pGlobalStream->GetData() : NULL, m_pGlobalStream ? m_pGlobalStream->GetSize() : 0, m_pCachedBitmap->GetBuffer(), |
m_pCachedBitmap->GetPitch(), pPause); |
if (ret < 0) { |
- delete m_pCachedBitmap; |
- m_pCachedBitmap = NULL; |
+ m_pCachedBitmap.reset(); |
delete m_pGlobalStream; |
m_pGlobalStream = NULL; |
pJbig2Module->DestroyJbig2Context(m_pJbig2Context); |
@@ -401,8 +440,7 @@ int CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) |
} |
FXCODEC_STATUS ret = pJbig2Module->ContinueDecode(m_pJbig2Context, pPause); |
if (ret < 0) { |
- delete m_pCachedBitmap; |
- m_pCachedBitmap = NULL; |
+ m_pCachedBitmap.reset(); |
delete m_pGlobalStream; |
m_pGlobalStream = NULL; |
pJbig2Module->DestroyJbig2Context(m_pJbig2Context); |
@@ -593,12 +631,11 @@ int CPDF_DIBSource::CreateDecoder() |
m_pDecoder = FPDFAPI_CreateFlateDecoder(src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams); |
} else if (decoder == FX_BSTRC("JPXDecode")) { |
LoadJpxBitmap(); |
- return m_pCachedBitmap != NULL ? 1 : 0; |
+ return m_pCachedBitmap ? 1 : 0; |
} else if (decoder == FX_BSTRC("JBIG2Decode")) { |
- m_pCachedBitmap = new CFX_DIBitmap; |
+ m_pCachedBitmap.reset(new CFX_DIBitmap); |
if (!m_pCachedBitmap->Create(m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) { |
- delete m_pCachedBitmap; |
- m_pCachedBitmap = NULL; |
+ m_pCachedBitmap.reset(); |
return 0; |
} |
m_Status = 1; |
@@ -629,30 +666,37 @@ int CPDF_DIBSource::CreateDecoder() |
void CPDF_DIBSource::LoadJpxBitmap() |
{ |
ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); |
- if (pJpxModule == NULL) { |
+ if (!pJpxModule) |
return; |
- } |
- FX_LPVOID ctx = pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), m_pColorSpace != NULL); |
- if (ctx == NULL) { |
+ |
+ nonstd::unique_ptr<JpxBitMapContext> context( |
+ new JpxBitMapContext(pJpxModule)); |
+ context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), |
+ m_pStreamAcc->GetSize(), |
+ m_pColorSpace != nullptr)); |
+ if (!context->context()) |
return; |
- } |
- FX_DWORD width = 0, height = 0, codestream_nComps = 0, image_nComps = 0; |
- pJpxModule->GetImageInfo(ctx, width, height, codestream_nComps, image_nComps); |
- if ((int)width < m_Width || (int)height < m_Height) { |
- pJpxModule->DestroyDecoder(ctx); |
+ |
+ FX_DWORD width = 0; |
+ FX_DWORD height = 0; |
+ FX_DWORD codestream_nComps = 0; |
+ FX_DWORD image_nComps = 0; |
+ pJpxModule->GetImageInfo(context->context(), width, height, |
+ codestream_nComps, image_nComps); |
+ if ((int)width < m_Width || (int)height < m_Height) |
return; |
- } |
+ |
int output_nComps; |
- FX_BOOL bTranslateColor, bSwapRGB = FALSE; |
+ FX_BOOL bTranslateColor; |
+ FX_BOOL bSwapRGB = FALSE; |
if (m_pColorSpace) { |
- if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) { |
+ if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) |
return; |
- } |
output_nComps = codestream_nComps; |
bTranslateColor = FALSE; |
if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { |
bSwapRGB = TRUE; |
- m_pColorSpace = NULL; |
+ m_pColorSpace = nullptr; |
} |
} else { |
bTranslateColor = TRUE; |
@@ -680,35 +724,36 @@ void CPDF_DIBSource::LoadJpxBitmap() |
width = (width * output_nComps + 2) / 3; |
format = FXDIB_Rgb; |
} |
- m_pCachedBitmap = new CFX_DIBitmap; |
+ m_pCachedBitmap.reset(new CFX_DIBitmap); |
if (!m_pCachedBitmap->Create(width, height, format)) { |
- delete m_pCachedBitmap; |
- m_pCachedBitmap = NULL; |
+ m_pCachedBitmap.reset(); |
return; |
} |
m_pCachedBitmap->Clear(0xFFFFFFFF); |
- FX_LPBYTE output_offsets = FX_Alloc(FX_BYTE, output_nComps); |
- for (int i = 0; i < output_nComps; i ++) { |
- output_offsets[i] = i; |
- } |
+ context->set_output_offsets(FX_Alloc(unsigned char, output_nComps)); |
+ for (int i = 0; i < output_nComps; ++i) |
+ context->output_offsets()[i] = i; |
if (bSwapRGB) { |
- output_offsets[0] = 2; |
- output_offsets[2] = 0; |
- } |
- if (!pJpxModule->Decode(ctx, m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), bTranslateColor, output_offsets)) { |
- delete m_pCachedBitmap; |
- m_pCachedBitmap = NULL; |
+ context->output_offsets()[0] = 2; |
+ context->output_offsets()[2] = 0; |
+ } |
+ if (!pJpxModule->Decode(context->context(), |
+ m_pCachedBitmap->GetBuffer(), |
+ m_pCachedBitmap->GetPitch(), |
+ bTranslateColor, |
+ context->output_offsets())) { |
+ m_pCachedBitmap.reset(); |
return; |
} |
- FX_Free(output_offsets); |
- pJpxModule->DestroyDecoder(ctx); |
- if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED && m_bpc < 8) { |
+ if (m_pColorSpace && |
+ m_pColorSpace->GetFamily() == PDFCS_INDEXED && |
+ m_bpc < 8) { |
int scale = 8 - m_bpc; |
- for (FX_DWORD row = 0; row < height; row ++) { |
+ for (FX_DWORD row = 0; row < height; ++row) { |
FX_LPBYTE scanline = (FX_LPBYTE)m_pCachedBitmap->GetScanline(row); |
- for (FX_DWORD col = 0; col < width; col ++) { |
+ for (FX_DWORD col = 0; col < width; ++col) { |
*scanline = (*scanline) >> scale; |
- scanline++; |
+ ++scanline; |
} |
} |
} |