From d66f9d0b1fb0af57960f9c7163c475968505ee4a Mon Sep 17 00:00:00 2001 From: tsepez Date: Thu, 13 Oct 2016 09:42:30 -0700 Subject: split CPDF_StreamContentParser::AddImage() into 3 overloads. Small step before making CPDF_Image stream ownership saner. Review-Url: https://codereview.chromium.org/2416733002 --- core/fpdfapi/page/fpdf_page_parser.cpp | 72 ++++++++++++++++++++-------------- core/fpdfapi/page/pageint.h | 11 ++++-- core/fpdfapi/parser/cpdf_stream.h | 2 + 3 files changed, 53 insertions(+), 32 deletions(-) (limited to 'core') 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(); + pImageObj->SetOwnedImage( + pdfium::MakeUnique(m_pDocument, pStream.release(), true)); - std::unique_ptr 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(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(); + 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(); + pImageObj->SetUnownedImage( + m_pDocument->GetPageData()->GetImage(pImage->GetStream())); + + return AddImageObject(std::move(pImageObj)); +} + +CPDF_ImageObject* CPDF_StreamContentParser::AddImageObject( + std::unique_ptr 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; static OpCodes InitializeOpCodes(); + // Takes ownership of |pImageObj|, returns unowned pointer to it. + CPDF_ImageObject* AddImageObject(std::unique_ptr 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>; + inline CPDF_Stream* ToStream(CPDF_Object* obj) { return obj ? obj->AsStream() : nullptr; } -- cgit v1.2.3