| OLD | NEW |
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fpdfapi/page/cpdf_streamcontentparser.h" | 7 #include "core/fpdfapi/page/cpdf_streamcontentparser.h" |
| 8 | 8 |
| 9 #include "core/fpdfapi/font/cpdf_font.h" | 9 #include "core/fpdfapi/font/cpdf_font.h" |
| 10 #include "core/fpdfapi/font/cpdf_type3font.h" | 10 #include "core/fpdfapi/font/cpdf_type3font.h" |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 m_pCurStates->m_ColorState.Emplace(); | 173 m_pCurStates->m_ColorState.Emplace(); |
| 174 } | 174 } |
| 175 for (size_t i = 0; i < FX_ArraySize(m_Type3Data); ++i) { | 175 for (size_t i = 0; i < FX_ArraySize(m_Type3Data); ++i) { |
| 176 m_Type3Data[i] = 0.0; | 176 m_Type3Data[i] = 0.0; |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 | 179 |
| 180 CPDF_StreamContentParser::~CPDF_StreamContentParser() { | 180 CPDF_StreamContentParser::~CPDF_StreamContentParser() { |
| 181 ClearAllParams(); | 181 ClearAllParams(); |
| 182 FX_Free(m_pPathPoints); | 182 FX_Free(m_pPathPoints); |
| 183 delete m_pLastImageDict; | 183 if (m_pLastImageDict) { |
| 184 delete m_pLastCloneImageDict; | 184 m_pLastImageDict->Release(); |
| 185 } |
| 186 if (m_pLastCloneImageDict) { |
| 187 m_pLastCloneImageDict->Release(); |
| 188 } |
| 185 } | 189 } |
| 186 | 190 |
| 187 int CPDF_StreamContentParser::GetNextParamPos() { | 191 int CPDF_StreamContentParser::GetNextParamPos() { |
| 188 if (m_ParamCount == kParamBufSize) { | 192 if (m_ParamCount == kParamBufSize) { |
| 189 m_ParamStartPos++; | 193 m_ParamStartPos++; |
| 190 if (m_ParamStartPos == kParamBufSize) { | 194 if (m_ParamStartPos == kParamBufSize) { |
| 191 m_ParamStartPos = 0; | 195 m_ParamStartPos = 0; |
| 192 } | 196 } |
| 193 if (m_ParamBuf[m_ParamStartPos].m_Type == 0) | 197 if (m_ParamBuf[m_ParamStartPos].m_Type == 0) { |
| 194 delete m_ParamBuf[m_ParamStartPos].m_pObject; | 198 if (CPDF_Object* pObject = m_ParamBuf[m_ParamStartPos].m_pObject) |
| 195 | 199 pObject->Release(); |
| 200 } |
| 196 return m_ParamStartPos; | 201 return m_ParamStartPos; |
| 197 } | 202 } |
| 198 int index = m_ParamStartPos + m_ParamCount; | 203 int index = m_ParamStartPos + m_ParamCount; |
| 199 if (index >= kParamBufSize) { | 204 if (index >= kParamBufSize) { |
| 200 index -= kParamBufSize; | 205 index -= kParamBufSize; |
| 201 } | 206 } |
| 202 m_ParamCount++; | 207 m_ParamCount++; |
| 203 return index; | 208 return index; |
| 204 } | 209 } |
| 205 | 210 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 232 | 237 |
| 233 void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj) { | 238 void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj) { |
| 234 ContentParam& param = m_ParamBuf[GetNextParamPos()]; | 239 ContentParam& param = m_ParamBuf[GetNextParamPos()]; |
| 235 param.m_Type = ContentParam::OBJECT; | 240 param.m_Type = ContentParam::OBJECT; |
| 236 param.m_pObject = pObj; | 241 param.m_pObject = pObj; |
| 237 } | 242 } |
| 238 | 243 |
| 239 void CPDF_StreamContentParser::ClearAllParams() { | 244 void CPDF_StreamContentParser::ClearAllParams() { |
| 240 uint32_t index = m_ParamStartPos; | 245 uint32_t index = m_ParamStartPos; |
| 241 for (uint32_t i = 0; i < m_ParamCount; i++) { | 246 for (uint32_t i = 0; i < m_ParamCount; i++) { |
| 242 if (m_ParamBuf[index].m_Type == 0) | 247 if (m_ParamBuf[index].m_Type == 0) { |
| 243 delete m_ParamBuf[index].m_pObject; | 248 if (CPDF_Object* pObject = m_ParamBuf[index].m_pObject) |
| 244 | 249 pObject->Release(); |
| 250 } |
| 245 index++; | 251 index++; |
| 246 if (index == kParamBufSize) { | 252 if (index == kParamBufSize) { |
| 247 index = 0; | 253 index = 0; |
| 248 } | 254 } |
| 249 } | 255 } |
| 250 m_ParamStartPos = 0; | 256 m_ParamStartPos = 0; |
| 251 m_ParamCount = 0; | 257 m_ParamCount = 0; |
| 252 } | 258 } |
| 253 | 259 |
| 254 CPDF_Object* CPDF_StreamContentParser::GetObject(uint32_t index) { | 260 CPDF_Object* CPDF_StreamContentParser::GetObject(uint32_t index) { |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 FX_FILESIZE savePos = m_pSyntax->GetPos(); | 524 FX_FILESIZE savePos = m_pSyntax->GetPos(); |
| 519 CPDF_Dictionary* pDict = | 525 CPDF_Dictionary* pDict = |
| 520 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); | 526 new CPDF_Dictionary(m_pDocument->GetByteStringPool()); |
| 521 while (1) { | 527 while (1) { |
| 522 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | 528 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 523 if (type == CPDF_StreamParser::Keyword) { | 529 if (type == CPDF_StreamParser::Keyword) { |
| 524 CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), | 530 CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), |
| 525 m_pSyntax->GetWordSize()); | 531 m_pSyntax->GetWordSize()); |
| 526 if (bsKeyword != "ID") { | 532 if (bsKeyword != "ID") { |
| 527 m_pSyntax->SetPos(savePos); | 533 m_pSyntax->SetPos(savePos); |
| 528 delete pDict; | 534 pDict->Release(); |
| 529 return; | 535 return; |
| 530 } | 536 } |
| 531 } | 537 } |
| 532 if (type != CPDF_StreamParser::Name) { | 538 if (type != CPDF_StreamParser::Name) { |
| 533 break; | 539 break; |
| 534 } | 540 } |
| 535 CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, | 541 CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, |
| 536 m_pSyntax->GetWordSize() - 1); | 542 m_pSyntax->GetWordSize() - 1); |
| 537 std::unique_ptr<CPDF_Object> pObj(m_pSyntax->ReadNextObject(false, 0)); | 543 std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj( |
| 544 m_pSyntax->ReadNextObject(false, 0)); |
| 538 if (!key.IsEmpty()) { | 545 if (!key.IsEmpty()) { |
| 539 uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0; | 546 uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0; |
| 540 if (dwObjNum) | 547 if (dwObjNum) |
| 541 pDict->SetReferenceFor(key, m_pDocument, dwObjNum); | 548 pDict->SetReferenceFor(key, m_pDocument, dwObjNum); |
| 542 else | 549 else |
| 543 pDict->SetFor(key, pObj.release()); | 550 pDict->SetFor(key, pObj.release()); |
| 544 } | 551 } |
| 545 } | 552 } |
| 546 PDF_ReplaceAbbr(pDict); | 553 PDF_ReplaceAbbr(pDict); |
| 547 CPDF_Object* pCSObj = nullptr; | 554 CPDF_Object* pCSObj = nullptr; |
| 548 if (pDict->KeyExist("ColorSpace")) { | 555 if (pDict->KeyExist("ColorSpace")) { |
| 549 pCSObj = pDict->GetDirectObjectFor("ColorSpace"); | 556 pCSObj = pDict->GetDirectObjectFor("ColorSpace"); |
| 550 if (pCSObj->IsName()) { | 557 if (pCSObj->IsName()) { |
| 551 CFX_ByteString name = pCSObj->GetString(); | 558 CFX_ByteString name = pCSObj->GetString(); |
| 552 if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") { | 559 if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") { |
| 553 pCSObj = FindResourceObj("ColorSpace", name); | 560 pCSObj = FindResourceObj("ColorSpace", name); |
| 554 if (pCSObj && pCSObj->IsInline()) { | 561 if (pCSObj && pCSObj->IsInline()) { |
| 555 pCSObj = pCSObj->Clone(); | 562 pCSObj = pCSObj->Clone(); |
| 556 pDict->SetFor("ColorSpace", pCSObj); | 563 pDict->SetFor("ColorSpace", pCSObj); |
| 557 } | 564 } |
| 558 } | 565 } |
| 559 } | 566 } |
| 560 } | 567 } |
| 561 pDict->SetNameFor("Subtype", "Image"); | 568 pDict->SetNameFor("Subtype", "Image"); |
| 562 std::unique_ptr<CPDF_Stream> pStream( | 569 UniqueStream pStream(m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj)); |
| 563 m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj)); | |
| 564 bool bGaveDictAway = !!pStream; | 570 bool bGaveDictAway = !!pStream; |
| 565 while (1) { | 571 while (1) { |
| 566 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | 572 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 567 if (type == CPDF_StreamParser::EndOfData) { | 573 if (type == CPDF_StreamParser::EndOfData) { |
| 568 break; | 574 break; |
| 569 } | 575 } |
| 570 if (type != CPDF_StreamParser::Keyword) { | 576 if (type != CPDF_StreamParser::Keyword) { |
| 571 continue; | 577 continue; |
| 572 } | 578 } |
| 573 if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && | 579 if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && |
| 574 m_pSyntax->GetWordBuf()[1] == 'I') { | 580 m_pSyntax->GetWordBuf()[1] == 'I') { |
| 575 break; | 581 break; |
| 576 } | 582 } |
| 577 } | 583 } |
| 578 CPDF_ImageObject* pImgObj = AddImage(std::move(pStream)); | 584 CPDF_ImageObject* pImgObj = AddImage(std::move(pStream)); |
| 579 if (!pImgObj && !bGaveDictAway) | 585 if (!pImgObj && !bGaveDictAway) |
| 580 delete pDict; | 586 pDict->Release(); |
| 581 } | 587 } |
| 582 | 588 |
| 583 void CPDF_StreamContentParser::Handle_BeginMarkedContent() { | 589 void CPDF_StreamContentParser::Handle_BeginMarkedContent() { |
| 584 m_CurContentMark.AddMark(GetString(0), nullptr, false); | 590 m_CurContentMark.AddMark(GetString(0), nullptr, false); |
| 585 } | 591 } |
| 586 | 592 |
| 587 void CPDF_StreamContentParser::Handle_BeginText() { | 593 void CPDF_StreamContentParser::Handle_BeginText() { |
| 588 m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); | 594 m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); |
| 589 OnChangeTextMatrix(); | 595 OnChangeTextMatrix(); |
| 590 m_pCurStates->m_TextX = 0; | 596 m_pCurStates->m_TextX = 0; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 if (!pXObject) { | 662 if (!pXObject) { |
| 657 m_bResourceMissing = true; | 663 m_bResourceMissing = true; |
| 658 return; | 664 return; |
| 659 } | 665 } |
| 660 | 666 |
| 661 CFX_ByteString type; | 667 CFX_ByteString type; |
| 662 if (pXObject->GetDict()) | 668 if (pXObject->GetDict()) |
| 663 type = pXObject->GetDict()->GetStringFor("Subtype"); | 669 type = pXObject->GetDict()->GetStringFor("Subtype"); |
| 664 | 670 |
| 665 if (type == "Image") { | 671 if (type == "Image") { |
| 666 CPDF_ImageObject* pObj = pXObject->IsInline() | 672 CPDF_ImageObject* pObj = |
| 667 ? AddImage(std::unique_ptr<CPDF_Stream>( | 673 pXObject->IsInline() |
| 668 ToStream(pXObject->Clone()))) | 674 ? AddImage(UniqueStream(ToStream(pXObject->Clone()))) |
| 669 : AddImage(pXObject->GetObjNum()); | 675 : AddImage(pXObject->GetObjNum()); |
| 670 | 676 |
| 671 m_LastImageName = name; | 677 m_LastImageName = name; |
| 672 m_pLastImage = pObj->GetImage(); | 678 m_pLastImage = pObj->GetImage(); |
| 673 if (!m_pObjectHolder->HasImageMask()) | 679 if (!m_pObjectHolder->HasImageMask()) |
| 674 m_pObjectHolder->SetHasImageMask(m_pLastImage->IsMask()); | 680 m_pObjectHolder->SetHasImageMask(m_pLastImage->IsMask()); |
| 675 } else if (type == "Form") { | 681 } else if (type == "Form") { |
| 676 AddForm(pXObject); | 682 AddForm(pXObject); |
| 677 } | 683 } |
| 678 } | 684 } |
| 679 | 685 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 691 pFormObj->m_pForm->ParseContent(&status, nullptr, nullptr, m_Level + 1); | 697 pFormObj->m_pForm->ParseContent(&status, nullptr, nullptr, m_Level + 1); |
| 692 if (!m_pObjectHolder->BackgroundAlphaNeeded() && | 698 if (!m_pObjectHolder->BackgroundAlphaNeeded() && |
| 693 pFormObj->m_pForm->BackgroundAlphaNeeded()) { | 699 pFormObj->m_pForm->BackgroundAlphaNeeded()) { |
| 694 m_pObjectHolder->SetBackgroundAlphaNeeded(true); | 700 m_pObjectHolder->SetBackgroundAlphaNeeded(true); |
| 695 } | 701 } |
| 696 pFormObj->CalcBoundingBox(); | 702 pFormObj->CalcBoundingBox(); |
| 697 SetGraphicStates(pFormObj.get(), true, true, true); | 703 SetGraphicStates(pFormObj.get(), true, true, true); |
| 698 m_pObjectHolder->GetPageObjectList()->push_back(std::move(pFormObj)); | 704 m_pObjectHolder->GetPageObjectList()->push_back(std::move(pFormObj)); |
| 699 } | 705 } |
| 700 | 706 |
| 701 CPDF_ImageObject* CPDF_StreamContentParser::AddImage( | 707 CPDF_ImageObject* CPDF_StreamContentParser::AddImage(UniqueStream pStream) { |
| 702 std::unique_ptr<CPDF_Stream> pStream) { | |
| 703 if (!pStream) | 708 if (!pStream) |
| 704 return nullptr; | 709 return nullptr; |
| 705 | 710 |
| 706 auto pImageObj = pdfium::MakeUnique<CPDF_ImageObject>(); | 711 auto pImageObj = pdfium::MakeUnique<CPDF_ImageObject>(); |
| 707 pImageObj->SetOwnedImage( | 712 pImageObj->SetOwnedImage( |
| 708 pdfium::MakeUnique<CPDF_Image>(m_pDocument, std::move(pStream))); | 713 pdfium::MakeUnique<CPDF_Image>(m_pDocument, std::move(pStream))); |
| 709 return AddImageObject(std::move(pImageObj)); | 714 return AddImageObject(std::move(pImageObj)); |
| 710 } | 715 } |
| 711 | 716 |
| 712 CPDF_ImageObject* CPDF_StreamContentParser::AddImage(uint32_t streamObjNum) { | 717 CPDF_ImageObject* CPDF_StreamContentParser::AddImage(uint32_t streamObjNum) { |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1550 } | 1555 } |
| 1551 default: | 1556 default: |
| 1552 bProcessed = false; | 1557 bProcessed = false; |
| 1553 } | 1558 } |
| 1554 if (!bProcessed) { | 1559 if (!bProcessed) { |
| 1555 m_pSyntax->SetPos(last_pos); | 1560 m_pSyntax->SetPos(last_pos); |
| 1556 return; | 1561 return; |
| 1557 } | 1562 } |
| 1558 } | 1563 } |
| 1559 } | 1564 } |
| OLD | NEW |