Index: core/fpdfapi/fpdf_page/cpdf_image.cpp |
diff --git a/core/fpdfapi/fpdf_edit/fpdf_edit_image.cpp b/core/fpdfapi/fpdf_page/cpdf_image.cpp |
similarity index 74% |
rename from core/fpdfapi/fpdf_edit/fpdf_edit_image.cpp |
rename to core/fpdfapi/fpdf_page/cpdf_image.cpp |
index 50e4f79881e7fbf6be46712777d34ba0bf57cef0..d9e7d774be526695c9904c961a85cace523b64af 100644 |
--- a/core/fpdfapi/fpdf_edit/fpdf_edit_image.cpp |
+++ b/core/fpdfapi/fpdf_page/cpdf_image.cpp |
@@ -1,20 +1,78 @@ |
-// Copyright 2014 PDFium Authors. All rights reserved. |
+// Copyright 2016 PDFium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
-#include "core/fpdfapi/fpdf_page/include/cpdf_page.h" |
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h" |
+ |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
+#include "core/fpdfapi/include/cpdf_modulemgr.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
+#include "core/include/fxge/fx_dib.h" |
#include "core/fpdfapi/fpdf_page/pageint.h" |
+#include "core/include/fxcodec/fx_codec.h" |
#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" |
-#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
-#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
-#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h" |
+#include "core/fpdfapi/fpdf_page/include/cpdf_page.h" |
#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" |
#include "core/fpdfapi/fpdf_render/render_int.h" |
-#include "core/fpdfapi/include/cpdf_modulemgr.h" |
-#include "core/include/fxcodec/fx_codec.h" |
+ |
+CPDF_Image::CPDF_Image(CPDF_Document* pDoc) |
+ : m_pDIBSource(nullptr), |
+ m_pMask(nullptr), |
+ m_MatteColor(0), |
+ m_pStream(nullptr), |
+ m_bInline(FALSE), |
+ m_pInlineDict(nullptr), |
+ m_pDocument(pDoc), |
+ m_pOC(nullptr) {} |
+ |
+CPDF_Image::~CPDF_Image() { |
+ if (m_bInline) { |
+ if (m_pStream) |
+ m_pStream->Release(); |
+ if (m_pInlineDict) |
+ m_pInlineDict->Release(); |
+ } |
+} |
+ |
+void CPDF_Image::Release() { |
+ if (m_bInline || (m_pStream && m_pStream->GetObjNum() == 0)) |
+ delete this; |
+} |
+ |
+CPDF_Image* CPDF_Image::Clone() { |
+ if (m_pStream->GetObjNum()) |
+ return m_pDocument->GetPageData()->GetImage(m_pStream); |
+ |
+ CPDF_Image* pImage = new CPDF_Image(m_pDocument); |
+ pImage->LoadImageF(ToStream(m_pStream->Clone()), m_bInline); |
+ if (m_bInline) |
+ pImage->SetInlineDict(ToDictionary(m_pInlineDict->Clone(TRUE))); |
+ |
+ return pImage; |
+} |
+ |
+FX_BOOL CPDF_Image::LoadImageF(CPDF_Stream* pStream, FX_BOOL bInline) { |
+ m_pStream = pStream; |
+ if (m_bInline && m_pInlineDict) { |
+ m_pInlineDict->Release(); |
+ m_pInlineDict = NULL; |
+ } |
+ m_bInline = bInline; |
+ CPDF_Dictionary* pDict = pStream->GetDict(); |
+ if (m_bInline) { |
+ m_pInlineDict = ToDictionary(pDict->Clone()); |
+ } |
+ m_pOC = pDict->GetDictBy("OC"); |
+ m_bIsMask = |
+ !pDict->KeyExist("ColorSpace") || pDict->GetIntegerBy("ImageMask"); |
+ m_bInterpolate = pDict->GetIntegerBy("Interpolate"); |
+ m_Height = pDict->GetIntegerBy("Height"); |
+ m_Width = pDict->GetIntegerBy("Width"); |
+ return TRUE; |
+} |
CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, FX_DWORD size) { |
int32_t width; |
@@ -61,6 +119,7 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, FX_DWORD size) { |
} |
return pDict; |
} |
+ |
void CPDF_Image::SetJpegImage(uint8_t* pData, FX_DWORD size) { |
CPDF_Dictionary* pDict = InitJPEG(pData, size); |
if (!pDict) { |
@@ -68,6 +127,7 @@ void CPDF_Image::SetJpegImage(uint8_t* pData, FX_DWORD size) { |
} |
m_pStream->InitStream(pData, size, pDict); |
} |
+ |
void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) { |
FX_DWORD size = (FX_DWORD)pFile->GetSize(); |
if (!size) { |
@@ -92,23 +152,12 @@ void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) { |
} |
m_pStream->InitStreamFromFile(pFile, pDict); |
} |
-void _DCTEncodeBitmap(CPDF_Dictionary* pBitmapDict, |
- const CFX_DIBitmap* pBitmap, |
- int quality, |
- uint8_t*& buf, |
- FX_STRSIZE& size) {} |
-void _JBIG2EncodeBitmap(CPDF_Dictionary* pBitmapDict, |
- const CFX_DIBitmap* pBitmap, |
- CPDF_Document* pDoc, |
- uint8_t*& buf, |
- FX_STRSIZE& size, |
- FX_BOOL bLossLess) {} |
+ |
void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
int32_t iCompress, |
IFX_FileWrite* pFileWrite, |
IFX_FileRead* pFileRead, |
- const CFX_DIBitmap* pMask, |
- const CPDF_ImageSetParam* pParam) { |
+ const CFX_DIBitmap* pMask) { |
int32_t BitmapWidth = pBitmap->GetWidth(); |
int32_t BitmapHeight = pBitmap->GetHeight(); |
if (BitmapWidth < 1 || BitmapHeight < 1) { |
@@ -117,8 +166,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
uint8_t* src_buf = pBitmap->GetBuffer(); |
int32_t src_pitch = pBitmap->GetPitch(); |
int32_t bpp = pBitmap->GetBPP(); |
- FX_BOOL bUseMatte = |
- pParam && pParam->pMatteColor && (pBitmap->GetFormat() == FXDIB_Argb); |
+ |
CPDF_Dictionary* pDict = new CPDF_Dictionary; |
pDict->SetAtName("Type", "XObject"); |
pDict->SetAtName("Subtype", "Image"); |
@@ -234,11 +282,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
pMaskDict->SetAtInteger("BitsPerComponent", 8); |
if (pMaskBitmap->GetBPP() == 8 && |
(iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { |
- _DCTEncodeBitmap(pMaskDict, pMaskBitmap, pParam ? pParam->nQuality : 75, |
- mask_buf, mask_size); |
} else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { |
- _JBIG2EncodeBitmap(pMaskDict, pMaskBitmap, m_pDocument, mask_buf, |
- mask_size, TRUE); |
} else { |
mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth); |
mask_size = maskHeight * maskWidth; // Safe since checked alloc returned. |
@@ -248,15 +292,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
} |
} |
pMaskDict->SetAtInteger("Length", mask_size); |
- if (bUseMatte) { |
- int a, r, g, b; |
- ArgbDecode(*(pParam->pMatteColor), a, r, g, b); |
- CPDF_Array* pMatte = new CPDF_Array; |
- pMatte->AddInteger(r); |
- pMatte->AddInteger(g); |
- pMatte->AddInteger(b); |
- pMaskDict->SetAt("Matte", pMatte); |
- } |
+ |
CPDF_Stream* pMaskStream = new CPDF_Stream(mask_buf, mask_size, pMaskDict); |
m_pDocument->AddIndirectObject(pMaskStream); |
pDict->SetAtReference("SMask", m_pDocument, pMaskStream); |
@@ -267,14 +303,8 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
FX_BOOL bStream = pFileWrite && pFileRead; |
if (opType == 0) { |
if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { |
- if (pBitmap->GetBPP() == 1) { |
- _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size, |
- TRUE); |
- } |
} else { |
if (pBitmap->GetBPP() == 1) { |
- _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size, |
- FALSE); |
} else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) { |
CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); |
pNewBitmap->Copy(pBitmap); |
@@ -289,32 +319,6 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
dest_size = 0; |
delete pNewBitmap; |
return; |
- } else { |
- if (bUseMatte) { |
- CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); |
- pNewBitmap->Create(BitmapWidth, BitmapHeight, FXDIB_Argb); |
- uint8_t* dst_buf = pNewBitmap->GetBuffer(); |
- int32_t src_offset = 0; |
- for (int32_t row = 0; row < BitmapHeight; row++) { |
- src_offset = row * src_pitch; |
- for (int32_t column = 0; column < BitmapWidth; column++) { |
- FX_FLOAT alpha = src_buf[src_offset + 3] / 255.0f; |
- dst_buf[src_offset] = (uint8_t)(src_buf[src_offset] * alpha); |
- dst_buf[src_offset + 1] = |
- (uint8_t)(src_buf[src_offset + 1] * alpha); |
- dst_buf[src_offset + 2] = |
- (uint8_t)(src_buf[src_offset + 2] * alpha); |
- dst_buf[src_offset + 3] = (uint8_t)(src_buf[src_offset + 3]); |
- src_offset += 4; |
- } |
- } |
- _DCTEncodeBitmap(pDict, pNewBitmap, pParam ? pParam->nQuality : 75, |
- dest_buf, dest_size); |
- delete pNewBitmap; |
- } else { |
- _DCTEncodeBitmap(pDict, pBitmap, pParam ? pParam->nQuality : 75, |
- dest_buf, dest_size); |
- } |
} |
} |
if (bStream) { |
@@ -352,7 +356,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
for (int32_t row = 0; row < BitmapHeight; row++) { |
src_offset = row * src_pitch; |
for (int32_t column = 0; column < BitmapWidth; column++) { |
- FX_FLOAT alpha = bUseMatte ? src_buf[src_offset + 3] / 255.0f : 1; |
+ FX_FLOAT alpha = 1; |
pDest[dest_offset] = (uint8_t)(src_buf[src_offset + 2] * alpha); |
pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha); |
pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha); |
@@ -386,6 +390,72 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, |
m_Height = BitmapHeight; |
FX_Free(dest_buf); |
} |
+ |
void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) { |
pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap); |
} |
+ |
+CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, |
+ FX_DWORD* pMatteColor, |
+ FX_BOOL bStdCS, |
+ FX_DWORD GroupFamily, |
+ FX_BOOL bLoadMask) const { |
+ std::unique_ptr<CPDF_DIBSource> source(new CPDF_DIBSource); |
+ if (source->Load(m_pDocument, m_pStream, |
+ reinterpret_cast<CPDF_DIBSource**>(ppMask), pMatteColor, |
+ nullptr, nullptr, bStdCS, GroupFamily, bLoadMask)) { |
+ return source.release(); |
+ } |
+ return nullptr; |
+} |
+ |
+CFX_DIBSource* CPDF_Image::DetachBitmap() { |
+ CFX_DIBSource* pBitmap = m_pDIBSource; |
+ m_pDIBSource = nullptr; |
+ return pBitmap; |
+} |
+ |
+CFX_DIBSource* CPDF_Image::DetachMask() { |
+ CFX_DIBSource* pBitmap = m_pMask; |
+ m_pMask = nullptr; |
+ return pBitmap; |
+} |
+ |
+FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, |
+ CPDF_Dictionary* pPageResource, |
+ FX_BOOL bStdCS, |
+ FX_DWORD GroupFamily, |
+ FX_BOOL bLoadMask) { |
+ std::unique_ptr<CPDF_DIBSource> source(new CPDF_DIBSource); |
+ int ret = |
+ source->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource, |
+ pPageResource, bStdCS, GroupFamily, bLoadMask); |
+ if (ret == 2) { |
+ m_pDIBSource = source.release(); |
+ return TRUE; |
+ } |
+ if (!ret) { |
+ m_pDIBSource = nullptr; |
+ return FALSE; |
+ } |
+ m_pMask = source->DetachMask(); |
+ m_MatteColor = source->GetMatteColor(); |
+ m_pDIBSource = source.release(); |
+ return FALSE; |
+} |
+ |
+FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) { |
+ CPDF_DIBSource* pSource = static_cast<CPDF_DIBSource*>(m_pDIBSource); |
+ int ret = pSource->ContinueLoadDIBSource(pPause); |
+ if (ret == 2) { |
+ return TRUE; |
+ } |
+ if (!ret) { |
+ delete m_pDIBSource; |
+ m_pDIBSource = nullptr; |
+ return FALSE; |
+ } |
+ m_pMask = pSource->DetachMask(); |
+ m_MatteColor = pSource->GetMatteColor(); |
+ return FALSE; |
+} |