summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/page/fpdf_page_parser.cpp72
-rw-r--r--core/fpdfapi/page/pageint.h11
-rw-r--r--core/fpdfapi/parser/cpdf_stream.h2
3 files changed, 53 insertions, 32 deletions
diff --git a/core/fpdfapi/page/fpdf_page_parser.cpp b/core/fpdfapi/page/fpdf_page_parser.cpp
index a55fa23bef..5fdca908c8 100644
--- a/core/fpdfapi/page/fpdf_page_parser.cpp
+++ b/core/fpdfapi/page/fpdf_page_parser.cpp
@@ -620,8 +620,9 @@ void CPDF_StreamContentParser::Handle_BeginImage() {
}
}
}
- CPDF_Stream* pStream =
- m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj);
+ pDict->SetNameFor("Subtype", "Image");
+ UniqueStream pStream(m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj));
+ bool bGaveDictAway = !!pStream;
while (1) {
CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
if (type == CPDF_StreamParser::EndOfData) {
@@ -635,15 +636,9 @@ void CPDF_StreamContentParser::Handle_BeginImage() {
break;
}
}
- pDict->SetNameFor("Subtype", "Image");
- CPDF_ImageObject* pImgObj = AddImage(pStream, nullptr, true);
- if (!pImgObj) {
- if (pStream) {
- pStream->Release();
- } else {
- pDict->Release();
- }
- }
+ CPDF_ImageObject* pImgObj = AddImage(std::move(pStream));
+ if (!pImgObj && !bGaveDictAway)
+ pDict->Release();
}
void CPDF_StreamContentParser::Handle_BeginMarkedContent() {
@@ -714,7 +709,7 @@ void CPDF_StreamContentParser::Handle_ExecuteXObject() {
CFX_ByteString name = GetString(0);
if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() &&
m_pLastImage->GetStream()->GetObjNum()) {
- AddImage(nullptr, m_pLastImage, false);
+ AddImage(m_pLastImage);
return;
}
@@ -729,7 +724,7 @@ void CPDF_StreamContentParser::Handle_ExecuteXObject() {
type = pXObject->GetDict()->GetStringFor("Subtype");
if (type == "Image") {
- CPDF_ImageObject* pObj = AddImage(pXObject, nullptr, false);
+ CPDF_ImageObject* pObj = AddImage(pXObject->GetObjNum());
m_LastImageName = name;
m_pLastImage = pObj->GetImage();
if (!m_pObjectHolder->HasImageMask())
@@ -760,29 +755,48 @@ void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) {
m_pObjectHolder->GetPageObjectList()->push_back(std::move(pFormObj));
}
-CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream,
- CPDF_Image* pImage,
- bool bInline) {
- if (!pStream && !pImage)
+CPDF_ImageObject* CPDF_StreamContentParser::AddImage(UniqueStream pStream) {
+ if (!pStream)
return nullptr;
- CFX_Matrix ImageMatrix = m_pCurStates->m_CTM;
- ImageMatrix.Concat(m_mtContentToUser);
+ auto pImageObj = pdfium::MakeUnique<CPDF_ImageObject>();
+ pImageObj->SetOwnedImage(
+ pdfium::MakeUnique<CPDF_Image>(m_pDocument, pStream.release(), true));
- std::unique_ptr<CPDF_ImageObject> pImageObj(new CPDF_ImageObject);
- if (pImage) {
- pImageObj->SetUnownedImage(
- m_pDocument->GetPageData()->GetImage(pImage->GetStream()));
- } else if (!pStream->IsInline()) {
- pImageObj->SetUnownedImage(m_pDocument->LoadImageF(pStream));
- } else {
- pImageObj->SetOwnedImage(
- pdfium::MakeUnique<CPDF_Image>(m_pDocument, pStream, bInline));
- }
+ return AddImageObject(std::move(pImageObj));
+}
+
+CPDF_ImageObject* CPDF_StreamContentParser::AddImage(uint32_t streamObjNum) {
+ CPDF_Stream* pStream = ToStream(m_pDocument->GetIndirectObject(streamObjNum));
+ if (!pStream)
+ return nullptr;
+
+ auto pImageObj = pdfium::MakeUnique<CPDF_ImageObject>();
+ pImageObj->SetUnownedImage(m_pDocument->LoadImageF(pStream));
+ return AddImageObject(std::move(pImageObj));
+}
+
+CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Image* pImage) {
+ if (!pImage)
+ return nullptr;
+
+ auto pImageObj = pdfium::MakeUnique<CPDF_ImageObject>();
+ pImageObj->SetUnownedImage(
+ m_pDocument->GetPageData()->GetImage(pImage->GetStream()));
+
+ return AddImageObject(std::move(pImageObj));
+}
+
+CPDF_ImageObject* CPDF_StreamContentParser::AddImageObject(
+ std::unique_ptr<CPDF_ImageObject> pImageObj) {
SetGraphicStates(pImageObj.get(), pImageObj->GetImage()->IsMask(), false,
false);
+
+ CFX_Matrix ImageMatrix = m_pCurStates->m_CTM;
+ ImageMatrix.Concat(m_mtContentToUser);
pImageObj->m_Matrix = ImageMatrix;
pImageObj->CalcBoundingBox();
+
CPDF_ImageObject* pRet = pImageObj.get();
m_pObjectHolder->GetPageObjectList()->push_back(std::move(pImageObj));
return pRet;
diff --git a/core/fpdfapi/page/pageint.h b/core/fpdfapi/page/pageint.h
index 5f8351e261..7ab9c6c863 100644
--- a/core/fpdfapi/page/pageint.h
+++ b/core/fpdfapi/page/pageint.h
@@ -16,6 +16,7 @@
#include "core/fpdfapi/page/cpdf_contentmark.h"
#include "core/fpdfapi/page/cpdf_countedobject.h"
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fxcrt/cfx_string_pool_template.h"
#include "core/fxcrt/cfx_weak_ptr.h"
#include "core/fxge/cfx_pathdata.h"
@@ -143,9 +144,10 @@ class CPDF_StreamContentParser {
void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag);
void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h);
void AddPathObject(int FillType, bool bStroke);
- CPDF_ImageObject* AddImage(CPDF_Stream* pStream,
- CPDF_Image* pImage,
- bool bInline);
+ CPDF_ImageObject* AddImage(UniqueStream pStream);
+ CPDF_ImageObject* AddImage(uint32_t streamObjNum);
+ CPDF_ImageObject* AddImage(CPDF_Image* pImage);
+
void AddForm(CPDF_Stream* pStream);
void SetGraphicStates(CPDF_PageObject* pObj,
bool bColor,
@@ -162,6 +164,9 @@ class CPDF_StreamContentParser {
std::unordered_map<uint32_t, void (CPDF_StreamContentParser::*)()>;
static OpCodes InitializeOpCodes();
+ // Takes ownership of |pImageObj|, returns unowned pointer to it.
+ CPDF_ImageObject* AddImageObject(std::unique_ptr<CPDF_ImageObject> pImageObj);
+
void Handle_CloseFillStrokePath();
void Handle_FillStrokePath();
void Handle_CloseEOFillStrokePath();
diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h
index ed266778b3..575a9ebe0b 100644
--- a/core/fpdfapi/parser/cpdf_stream.h
+++ b/core/fpdfapi/parser/cpdf_stream.h
@@ -58,6 +58,8 @@ class CPDF_Stream : public CPDF_Object {
IFX_FileRead* m_pFile = nullptr;
};
+using UniqueStream = std::unique_ptr<CPDF_Stream, ReleaseDeleter<CPDF_Stream>>;
+
inline CPDF_Stream* ToStream(CPDF_Object* obj) {
return obj ? obj->AsStream() : nullptr;
}