Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: core/fpdfapi/page/cpdf_streamparser.cpp

Issue 2474303003: Clean up fpdf_page_parsers (Closed)
Patch Set: Remove PDF_ from namespace stuff Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 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/pageint.h" 7 #include "core/fpdfapi/page/pageint.h"
8 8
9 #include <limits.h> 9 #include <limits.h>
10 10
11 #include "core/fpdfapi/cpdf_modulemgr.h" 11 #include "core/fpdfapi/cpdf_modulemgr.h"
12 #include "core/fpdfapi/font/cpdf_type3char.h"
13 #include "core/fpdfapi/page/cpdf_allstates.h"
14 #include "core/fpdfapi/page/cpdf_docpagedata.h" 12 #include "core/fpdfapi/page/cpdf_docpagedata.h"
15 #include "core/fpdfapi/page/cpdf_form.h"
16 #include "core/fpdfapi/page/cpdf_page.h"
17 #include "core/fpdfapi/page/cpdf_pageobject.h"
18 #include "core/fpdfapi/page/cpdf_path.h"
19 #include "core/fpdfapi/parser/cpdf_array.h" 13 #include "core/fpdfapi/parser/cpdf_array.h"
20 #include "core/fpdfapi/parser/cpdf_boolean.h" 14 #include "core/fpdfapi/parser/cpdf_boolean.h"
21 #include "core/fpdfapi/parser/cpdf_dictionary.h" 15 #include "core/fpdfapi/parser/cpdf_dictionary.h"
22 #include "core/fpdfapi/parser/cpdf_document.h" 16 #include "core/fpdfapi/parser/cpdf_document.h"
23 #include "core/fpdfapi/parser/cpdf_name.h" 17 #include "core/fpdfapi/parser/cpdf_name.h"
24 #include "core/fpdfapi/parser/cpdf_null.h" 18 #include "core/fpdfapi/parser/cpdf_null.h"
25 #include "core/fpdfapi/parser/cpdf_number.h" 19 #include "core/fpdfapi/parser/cpdf_number.h"
26 #include "core/fpdfapi/parser/cpdf_stream.h" 20 #include "core/fpdfapi/parser/cpdf_stream.h"
27 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
28 #include "core/fpdfapi/parser/cpdf_string.h" 21 #include "core/fpdfapi/parser/cpdf_string.h"
29 #include "core/fpdfapi/parser/fpdf_parser_decode.h" 22 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
30 #include "core/fpdfapi/parser/fpdf_parser_utility.h" 23 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
31 #include "core/fxcodec/fx_codec.h" 24 #include "core/fxcodec/fx_codec.h"
32 #include "core/fxcrt/fx_ext.h" 25 #include "core/fxcrt/fx_ext.h"
33 #include "core/fxcrt/fx_safe_types.h"
34 #include "core/fxge/cfx_fxgedevice.h"
35 #include "core/fxge/cfx_renderdevice.h"
36 26
37 CCodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( 27 CCodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(
38 const uint8_t* src_buf, 28 const uint8_t* src_buf,
39 uint32_t src_size, 29 uint32_t src_size,
40 int width, 30 int width,
41 int height, 31 int height,
42 const CPDF_Dictionary* pParams); 32 const CPDF_Dictionary* pParams);
43 33
44 namespace { 34 namespace {
45 35
46 const uint32_t kMaxNestedArrayLevel = 512; 36 const uint32_t kMaxNestedArrayLevel = 512;
47 const uint32_t kMaxWordBuffer = 256; 37 const uint32_t kMaxWordBuffer = 256;
48 const FX_STRSIZE kMaxStringLength = 32767; 38 const FX_STRSIZE kMaxStringLength = 32767;
49 39
50 uint32_t DecodeAllScanlines(CCodec_ScanlineDecoder* pDecoder, 40 uint32_t DecodeAllScanlines(CCodec_ScanlineDecoder* pDecoder,
51 uint8_t*& dest_buf, 41 uint8_t*& dest_buf,
52 uint32_t& dest_size) { 42 uint32_t& dest_size) {
53 if (!pDecoder) { 43 if (!pDecoder)
54 return FX_INVALID_OFFSET; 44 return FX_INVALID_OFFSET;
55 }
56 int ncomps = pDecoder->CountComps(); 45 int ncomps = pDecoder->CountComps();
57 int bpc = pDecoder->GetBPC(); 46 int bpc = pDecoder->GetBPC();
58 int width = pDecoder->GetWidth(); 47 int width = pDecoder->GetWidth();
59 int height = pDecoder->GetHeight(); 48 int height = pDecoder->GetHeight();
60 int pitch = (width * ncomps * bpc + 7) / 8; 49 int pitch = (width * ncomps * bpc + 7) / 8;
61 if (height == 0 || pitch > (1 << 30) / height) { 50 if (height == 0 || pitch > (1 << 30) / height) {
62 delete pDecoder; 51 delete pDecoder;
63 return FX_INVALID_OFFSET; 52 return FX_INVALID_OFFSET;
64 } 53 }
65 dest_buf = FX_Alloc2D(uint8_t, pitch, height); 54 dest_buf = FX_Alloc2D(uint8_t, pitch, height);
(...skipping 16 matching lines...) Expand all
82 int height, 71 int height,
83 CFX_ByteString& decoder, 72 CFX_ByteString& decoder,
84 CPDF_Dictionary* pParam, 73 CPDF_Dictionary* pParam,
85 uint8_t*& dest_buf, 74 uint8_t*& dest_buf,
86 uint32_t& dest_size) { 75 uint32_t& dest_size) {
87 if (decoder == "CCITTFaxDecode" || decoder == "CCF") { 76 if (decoder == "CCITTFaxDecode" || decoder == "CCF") {
88 CCodec_ScanlineDecoder* pDecoder = 77 CCodec_ScanlineDecoder* pDecoder =
89 FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam); 78 FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam);
90 return DecodeAllScanlines(pDecoder, dest_buf, dest_size); 79 return DecodeAllScanlines(pDecoder, dest_buf, dest_size);
91 } 80 }
92 if (decoder == "ASCII85Decode" || decoder == "A85") { 81 if (decoder == "ASCII85Decode" || decoder == "A85")
93 return A85Decode(src_buf, limit, dest_buf, dest_size); 82 return A85Decode(src_buf, limit, dest_buf, dest_size);
94 } 83 if (decoder == "ASCIIHexDecode" || decoder == "AHx")
95 if (decoder == "ASCIIHexDecode" || decoder == "AHx") {
96 return HexDecode(src_buf, limit, dest_buf, dest_size); 84 return HexDecode(src_buf, limit, dest_buf, dest_size);
97 }
98 if (decoder == "FlateDecode" || decoder == "Fl") { 85 if (decoder == "FlateDecode" || decoder == "Fl") {
99 return FPDFAPI_FlateOrLZWDecode(false, src_buf, limit, pParam, dest_size, 86 return FPDFAPI_FlateOrLZWDecode(false, src_buf, limit, pParam, dest_size,
100 dest_buf, dest_size); 87 dest_buf, dest_size);
101 } 88 }
102 if (decoder == "LZWDecode" || decoder == "LZW") { 89 if (decoder == "LZWDecode" || decoder == "LZW") {
103 return FPDFAPI_FlateOrLZWDecode(true, src_buf, limit, pParam, 0, dest_buf, 90 return FPDFAPI_FlateOrLZWDecode(true, src_buf, limit, pParam, 0, dest_buf,
104 dest_size); 91 dest_size);
105 } 92 }
106 if (decoder == "DCTDecode" || decoder == "DCT") { 93 if (decoder == "DCTDecode" || decoder == "DCT") {
107 CCodec_ScanlineDecoder* pDecoder = 94 CCodec_ScanlineDecoder* pDecoder =
108 CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( 95 CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
109 src_buf, limit, width, height, 0, 96 src_buf, limit, width, height, 0,
110 !pParam || pParam->GetIntegerFor("ColorTransform", 1)); 97 !pParam || pParam->GetIntegerFor("ColorTransform", 1));
111 return DecodeAllScanlines(pDecoder, dest_buf, dest_size); 98 return DecodeAllScanlines(pDecoder, dest_buf, dest_size);
112 } 99 }
113 if (decoder == "RunLengthDecode" || decoder == "RL") { 100 if (decoder == "RunLengthDecode" || decoder == "RL")
114 return RunLengthDecode(src_buf, limit, dest_buf, dest_size); 101 return RunLengthDecode(src_buf, limit, dest_buf, dest_size);
115 }
116 dest_size = 0; 102 dest_size = 0;
117 dest_buf = 0; 103 dest_buf = 0;
118 return (uint32_t)-1; 104 return (uint32_t)-1;
119 } 105 }
120 106
121 } // namespace 107 } // namespace
122 108
123 CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize) 109 CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize)
124 : m_pBuf(pData), 110 : m_pBuf(pData),
125 m_Size(dwSize), 111 m_Size(dwSize),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 184
199 OrigSize = ((width + 7) / 8); 185 OrigSize = ((width + 7) / 8);
200 } 186 }
201 if (height && OrigSize > INT_MAX / height) 187 if (height && OrigSize > INT_MAX / height)
202 return nullptr; 188 return nullptr;
203 189
204 OrigSize *= height; 190 OrigSize *= height;
205 uint8_t* pData = nullptr; 191 uint8_t* pData = nullptr;
206 uint32_t dwStreamSize; 192 uint32_t dwStreamSize;
207 if (Decoder.IsEmpty()) { 193 if (Decoder.IsEmpty()) {
208 if (OrigSize > m_Size - m_Pos) { 194 if (OrigSize > m_Size - m_Pos)
209 OrigSize = m_Size - m_Pos; 195 OrigSize = m_Size - m_Pos;
210 }
211 pData = FX_Alloc(uint8_t, OrigSize); 196 pData = FX_Alloc(uint8_t, OrigSize);
212 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); 197 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize);
213 dwStreamSize = OrigSize; 198 dwStreamSize = OrigSize;
214 m_Pos += OrigSize; 199 m_Pos += OrigSize;
215 } else { 200 } else {
216 uint32_t dwDestSize = OrigSize; 201 uint32_t dwDestSize = OrigSize;
217 dwStreamSize = 202 dwStreamSize =
218 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, 203 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height,
219 Decoder, pParam, pData, dwDestSize); 204 Decoder, pParam, pData, dwDestSize);
220 FX_Free(pData); 205 FX_Free(pData);
221 if ((int)dwStreamSize < 0) 206 if (static_cast<int>(dwStreamSize) < 0)
222 return nullptr; 207 return nullptr;
223 208
224 uint32_t dwSavePos = m_Pos; 209 uint32_t dwSavePos = m_Pos;
225 m_Pos += dwStreamSize; 210 m_Pos += dwStreamSize;
226 while (1) { 211 while (1) {
227 uint32_t dwPrevPos = m_Pos; 212 uint32_t dwPrevPos = m_Pos;
228 CPDF_StreamParser::SyntaxType type = ParseNextElement(); 213 CPDF_StreamParser::SyntaxType type = ParseNextElement();
229 if (type == CPDF_StreamParser::EndOfData) 214 if (type == CPDF_StreamParser::EndOfData)
230 break; 215 break;
231 216
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 if (memcmp(m_WordBuffer, "true", 4) == 0) 402 if (memcmp(m_WordBuffer, "true", 4) == 0)
418 return new CPDF_Boolean(true); 403 return new CPDF_Boolean(true);
419 404
420 if (memcmp(m_WordBuffer, "null", 4) == 0) 405 if (memcmp(m_WordBuffer, "null", 4) == 0)
421 return new CPDF_Null; 406 return new CPDF_Null;
422 } 407 }
423 408
424 return nullptr; 409 return nullptr;
425 } 410 }
426 411
412 // TODO(npm): the following methods are almost identical in cpdf_syntaxparser
427 void CPDF_StreamParser::GetNextWord(bool& bIsNumber) { 413 void CPDF_StreamParser::GetNextWord(bool& bIsNumber) {
428 m_WordSize = 0; 414 m_WordSize = 0;
429 bIsNumber = true; 415 bIsNumber = true;
430 if (!PositionIsInBounds()) 416 if (!PositionIsInBounds())
431 return; 417 return;
432 418
433 int ch = m_pBuf[m_Pos++]; 419 int ch = m_pBuf[m_Pos++];
434 while (1) { 420 while (1) {
435 while (PDFCharIsWhitespace(ch)) { 421 while (PDFCharIsWhitespace(ch)) {
436 if (!PositionIsInBounds()) { 422 if (!PositionIsInBounds()) {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 618
633 if (buf.GetLength() > kMaxStringLength) 619 if (buf.GetLength() > kMaxStringLength)
634 return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); 620 return CFX_ByteString(buf.GetBuffer(), kMaxStringLength);
635 621
636 return buf.MakeString(); 622 return buf.MakeString();
637 } 623 }
638 624
639 bool CPDF_StreamParser::PositionIsInBounds() const { 625 bool CPDF_StreamParser::PositionIsInBounds() const {
640 return m_Pos < m_Size; 626 return m_Pos < m_Size;
641 } 627 }
642
643 CPDF_ContentParser::CPDF_ContentParser()
644 : m_Status(Ready),
645 m_InternalStage(STAGE_GETCONTENT),
646 m_pObjectHolder(nullptr),
647 m_bForm(false),
648 m_pType3Char(nullptr),
649 m_pData(nullptr),
650 m_Size(0),
651 m_CurrentOffset(0) {}
652
653 CPDF_ContentParser::~CPDF_ContentParser() {
654 if (!m_pSingleStream)
655 FX_Free(m_pData);
656 }
657
658 void CPDF_ContentParser::Start(CPDF_Page* pPage) {
659 if (m_Status != Ready || !pPage || !pPage->m_pDocument ||
660 !pPage->m_pFormDict) {
661 m_Status = Done;
662 return;
663 }
664 m_pObjectHolder = pPage;
665 m_bForm = false;
666 m_Status = ToBeContinued;
667 m_InternalStage = STAGE_GETCONTENT;
668 m_CurrentOffset = 0;
669
670 CPDF_Object* pContent = pPage->m_pFormDict->GetDirectObjectFor("Contents");
671 if (!pContent) {
672 m_Status = Done;
673 return;
674 }
675 if (CPDF_Stream* pStream = pContent->AsStream()) {
676 m_nStreams = 0;
677 m_pSingleStream.reset(new CPDF_StreamAcc);
678 m_pSingleStream->LoadAllData(pStream, false);
679 } else if (CPDF_Array* pArray = pContent->AsArray()) {
680 m_nStreams = pArray->GetCount();
681 if (m_nStreams)
682 m_StreamArray.resize(m_nStreams);
683 else
684 m_Status = Done;
685 } else {
686 m_Status = Done;
687 }
688 }
689
690 void CPDF_ContentParser::Start(CPDF_Form* pForm,
691 CPDF_AllStates* pGraphicStates,
692 const CFX_Matrix* pParentMatrix,
693 CPDF_Type3Char* pType3Char,
694 int level) {
695 m_pType3Char = pType3Char;
696 m_pObjectHolder = pForm;
697 m_bForm = true;
698 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixFor("Matrix");
699 if (pGraphicStates) {
700 form_matrix.Concat(pGraphicStates->m_CTM);
701 }
702 CPDF_Array* pBBox = pForm->m_pFormDict->GetArrayFor("BBox");
703 CFX_FloatRect form_bbox;
704 CPDF_Path ClipPath;
705 if (pBBox) {
706 form_bbox = pBBox->GetRect();
707 ClipPath.Emplace();
708 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right,
709 form_bbox.top);
710 ClipPath.Transform(&form_matrix);
711 if (pParentMatrix) {
712 ClipPath.Transform(pParentMatrix);
713 }
714 form_bbox.Transform(&form_matrix);
715 if (pParentMatrix) {
716 form_bbox.Transform(pParentMatrix);
717 }
718 }
719 CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDictFor("Resources");
720 m_pParser.reset(new CPDF_StreamContentParser(
721 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources,
722 pParentMatrix, pForm, pResources, &form_bbox, pGraphicStates, level));
723 m_pParser->GetCurStates()->m_CTM = form_matrix;
724 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix;
725 if (ClipPath) {
726 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING,
727 true);
728 }
729 if (pForm->m_Transparency & PDFTRANS_GROUP) {
730 CPDF_GeneralState* pState = &m_pParser->GetCurStates()->m_GeneralState;
731 pState->SetBlendType(FXDIB_BLEND_NORMAL);
732 pState->SetStrokeAlpha(1.0f);
733 pState->SetFillAlpha(1.0f);
734 pState->SetSoftMask(nullptr);
735 }
736 m_nStreams = 0;
737 m_pSingleStream.reset(new CPDF_StreamAcc);
738 m_pSingleStream->LoadAllData(pForm->m_pFormStream, false);
739 m_pData = (uint8_t*)m_pSingleStream->GetData();
740 m_Size = m_pSingleStream->GetSize();
741 m_Status = ToBeContinued;
742 m_InternalStage = STAGE_PARSE;
743 m_CurrentOffset = 0;
744 }
745
746 void CPDF_ContentParser::Continue(IFX_Pause* pPause) {
747 int steps = 0;
748 while (m_Status == ToBeContinued) {
749 if (m_InternalStage == STAGE_GETCONTENT) {
750 if (m_CurrentOffset == m_nStreams) {
751 if (!m_StreamArray.empty()) {
752 FX_SAFE_UINT32 safeSize = 0;
753 for (const auto& stream : m_StreamArray) {
754 safeSize += stream->GetSize();
755 safeSize += 1;
756 }
757 if (!safeSize.IsValid()) {
758 m_Status = Done;
759 return;
760 }
761 m_Size = safeSize.ValueOrDie();
762 m_pData = FX_Alloc(uint8_t, m_Size);
763 uint32_t pos = 0;
764 for (const auto& stream : m_StreamArray) {
765 FXSYS_memcpy(m_pData + pos, stream->GetData(), stream->GetSize());
766 pos += stream->GetSize();
767 m_pData[pos++] = ' ';
768 }
769 m_StreamArray.clear();
770 } else {
771 m_pData = (uint8_t*)m_pSingleStream->GetData();
772 m_Size = m_pSingleStream->GetSize();
773 }
774 m_InternalStage = STAGE_PARSE;
775 m_CurrentOffset = 0;
776 } else {
777 CPDF_Array* pContent =
778 m_pObjectHolder->m_pFormDict->GetArrayFor("Contents");
779 m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc);
780 CPDF_Stream* pStreamObj = ToStream(
781 pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr);
782 m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, false);
783 m_CurrentOffset++;
784 }
785 }
786 if (m_InternalStage == STAGE_PARSE) {
787 if (!m_pParser) {
788 m_pParser.reset(new CPDF_StreamContentParser(
789 m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources,
790 nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources,
791 &m_pObjectHolder->m_BBox, nullptr, 0));
792 m_pParser->GetCurStates()->m_ColorState.SetDefault();
793 }
794 if (m_CurrentOffset >= m_Size) {
795 m_InternalStage = STAGE_CHECKCLIP;
796 } else {
797 m_CurrentOffset +=
798 m_pParser->Parse(m_pData + m_CurrentOffset,
799 m_Size - m_CurrentOffset, PARSE_STEP_LIMIT);
800 }
801 }
802 if (m_InternalStage == STAGE_CHECKCLIP) {
803 if (m_pType3Char) {
804 m_pType3Char->m_bColored = m_pParser->IsColored();
805 m_pType3Char->m_Width =
806 FXSYS_round(m_pParser->GetType3Data()[0] * 1000);
807 m_pType3Char->m_BBox.left =
808 FXSYS_round(m_pParser->GetType3Data()[2] * 1000);
809 m_pType3Char->m_BBox.bottom =
810 FXSYS_round(m_pParser->GetType3Data()[3] * 1000);
811 m_pType3Char->m_BBox.right =
812 FXSYS_round(m_pParser->GetType3Data()[4] * 1000);
813 m_pType3Char->m_BBox.top =
814 FXSYS_round(m_pParser->GetType3Data()[5] * 1000);
815 }
816 for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) {
817 if (!pObj->m_ClipPath)
818 continue;
819 if (pObj->m_ClipPath.GetPathCount() != 1)
820 continue;
821 if (pObj->m_ClipPath.GetTextCount())
822 continue;
823 CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0);
824 if (!ClipPath.IsRect() || pObj->IsShading())
825 continue;
826 CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0),
827 ClipPath.GetPointX(2), ClipPath.GetPointY(2));
828 CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right,
829 pObj->m_Top);
830 if (old_rect.Contains(obj_rect)) {
831 pObj->m_ClipPath.SetNull();
832 }
833 }
834 m_Status = Done;
835 return;
836 }
837 steps++;
838 if (pPause && pPause->NeedToPauseNow()) {
839 break;
840 }
841 }
842 }
OLDNEW
« no previous file with comments | « core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp ('k') | core/fpdfapi/page/cpdf_streamparser_unittest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698