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

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

Issue 2474303003: Clean up fpdf_page_parsers (Closed)
Patch Set: Fix includes, move method to namespace 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 186
201 OrigSize = ((width + 7) / 8); 187 OrigSize = ((width + 7) / 8);
202 } 188 }
203 if (height && OrigSize > INT_MAX / height) 189 if (height && OrigSize > INT_MAX / height)
204 return nullptr; 190 return nullptr;
205 191
206 OrigSize *= height; 192 OrigSize *= height;
207 uint8_t* pData = nullptr; 193 uint8_t* pData = nullptr;
208 uint32_t dwStreamSize; 194 uint32_t dwStreamSize;
209 if (Decoder.IsEmpty()) { 195 if (Decoder.IsEmpty()) {
210 if (OrigSize > m_Size - m_Pos) { 196 if (OrigSize > m_Size - m_Pos)
211 OrigSize = m_Size - m_Pos; 197 OrigSize = m_Size - m_Pos;
212 }
213 pData = FX_Alloc(uint8_t, OrigSize); 198 pData = FX_Alloc(uint8_t, OrigSize);
214 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); 199 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize);
215 dwStreamSize = OrigSize; 200 dwStreamSize = OrigSize;
216 m_Pos += OrigSize; 201 m_Pos += OrigSize;
217 } else { 202 } else {
218 uint32_t dwDestSize = OrigSize; 203 uint32_t dwDestSize = OrigSize;
219 dwStreamSize = 204 dwStreamSize =
220 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, 205 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height,
221 Decoder, pParam, pData, dwDestSize); 206 Decoder, pParam, pData, dwDestSize);
222 FX_Free(pData); 207 FX_Free(pData);
223 if ((int)dwStreamSize < 0) 208 if (static_cast<int>(dwStreamSize) < 0)
224 return nullptr; 209 return nullptr;
225 210
226 uint32_t dwSavePos = m_Pos; 211 uint32_t dwSavePos = m_Pos;
227 m_Pos += dwStreamSize; 212 m_Pos += dwStreamSize;
228 while (1) { 213 while (1) {
229 uint32_t dwPrevPos = m_Pos; 214 uint32_t dwPrevPos = m_Pos;
230 CPDF_StreamParser::SyntaxType type = ParseNextElement(); 215 CPDF_StreamParser::SyntaxType type = ParseNextElement();
231 if (type == CPDF_StreamParser::EndOfData) 216 if (type == CPDF_StreamParser::EndOfData)
232 break; 217 break;
233 218
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 if (memcmp(m_WordBuffer, "true", 4) == 0) 406 if (memcmp(m_WordBuffer, "true", 4) == 0)
422 return new CPDF_Boolean(true); 407 return new CPDF_Boolean(true);
423 408
424 if (memcmp(m_WordBuffer, "null", 4) == 0) 409 if (memcmp(m_WordBuffer, "null", 4) == 0)
425 return new CPDF_Null; 410 return new CPDF_Null;
426 } 411 }
427 412
428 return nullptr; 413 return nullptr;
429 } 414 }
430 415
416 // TODO(npm): the following methods are almost identical in cpdf_syntaxparser
431 void CPDF_StreamParser::GetNextWord(bool& bIsNumber) { 417 void CPDF_StreamParser::GetNextWord(bool& bIsNumber) {
432 m_WordSize = 0; 418 m_WordSize = 0;
433 bIsNumber = true; 419 bIsNumber = true;
434 if (!PositionIsInBounds()) 420 if (!PositionIsInBounds())
435 return; 421 return;
436 422
437 int ch = m_pBuf[m_Pos++]; 423 int ch = m_pBuf[m_Pos++];
438 while (1) { 424 while (1) {
439 while (PDFCharIsWhitespace(ch)) { 425 while (PDFCharIsWhitespace(ch)) {
440 if (!PositionIsInBounds()) { 426 if (!PositionIsInBounds()) {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 622
637 if (buf.GetLength() > kMaxStringLength) 623 if (buf.GetLength() > kMaxStringLength)
638 return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); 624 return CFX_ByteString(buf.GetBuffer(), kMaxStringLength);
639 625
640 return buf.MakeString(); 626 return buf.MakeString();
641 } 627 }
642 628
643 bool CPDF_StreamParser::PositionIsInBounds() const { 629 bool CPDF_StreamParser::PositionIsInBounds() const {
644 return m_Pos < m_Size; 630 return m_Pos < m_Size;
645 } 631 }
646
647 CPDF_ContentParser::CPDF_ContentParser()
648 : m_Status(Ready),
649 m_InternalStage(STAGE_GETCONTENT),
650 m_pObjectHolder(nullptr),
651 m_bForm(false),
652 m_pType3Char(nullptr),
653 m_pData(nullptr),
654 m_Size(0),
655 m_CurrentOffset(0) {}
656
657 CPDF_ContentParser::~CPDF_ContentParser() {
658 if (!m_pSingleStream)
659 FX_Free(m_pData);
660 }
661
662 void CPDF_ContentParser::Start(CPDF_Page* pPage) {
663 if (m_Status != Ready || !pPage || !pPage->m_pDocument ||
664 !pPage->m_pFormDict) {
665 m_Status = Done;
666 return;
667 }
668 m_pObjectHolder = pPage;
669 m_bForm = false;
670 m_Status = ToBeContinued;
671 m_InternalStage = STAGE_GETCONTENT;
672 m_CurrentOffset = 0;
673
674 CPDF_Object* pContent = pPage->m_pFormDict->GetDirectObjectFor("Contents");
675 if (!pContent) {
676 m_Status = Done;
677 return;
678 }
679 if (CPDF_Stream* pStream = pContent->AsStream()) {
680 m_nStreams = 0;
681 m_pSingleStream.reset(new CPDF_StreamAcc);
682 m_pSingleStream->LoadAllData(pStream, false);
683 } else if (CPDF_Array* pArray = pContent->AsArray()) {
684 m_nStreams = pArray->GetCount();
685 if (m_nStreams)
686 m_StreamArray.resize(m_nStreams);
687 else
688 m_Status = Done;
689 } else {
690 m_Status = Done;
691 }
692 }
693
694 void CPDF_ContentParser::Start(CPDF_Form* pForm,
695 CPDF_AllStates* pGraphicStates,
696 const CFX_Matrix* pParentMatrix,
697 CPDF_Type3Char* pType3Char,
698 int level) {
699 m_pType3Char = pType3Char;
700 m_pObjectHolder = pForm;
701 m_bForm = true;
702 CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixFor("Matrix");
703 if (pGraphicStates) {
704 form_matrix.Concat(pGraphicStates->m_CTM);
705 }
706 CPDF_Array* pBBox = pForm->m_pFormDict->GetArrayFor("BBox");
707 CFX_FloatRect form_bbox;
708 CPDF_Path ClipPath;
709 if (pBBox) {
710 form_bbox = pBBox->GetRect();
711 ClipPath.Emplace();
712 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right,
713 form_bbox.top);
714 ClipPath.Transform(&form_matrix);
715 if (pParentMatrix) {
716 ClipPath.Transform(pParentMatrix);
717 }
718 form_bbox.Transform(&form_matrix);
719 if (pParentMatrix) {
720 form_bbox.Transform(pParentMatrix);
721 }
722 }
723 CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDictFor("Resources");
724 m_pParser.reset(new CPDF_StreamContentParser(
725 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources,
726 pParentMatrix, pForm, pResources, &form_bbox, pGraphicStates, level));
727 m_pParser->GetCurStates()->m_CTM = form_matrix;
728 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix;
729 if (ClipPath) {
730 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING,
731 true);
732 }
733 if (pForm->m_Transparency & PDFTRANS_GROUP) {
734 CPDF_GeneralState* pState = &m_pParser->GetCurStates()->m_GeneralState;
735 pState->SetBlendType(FXDIB_BLEND_NORMAL);
736 pState->SetStrokeAlpha(1.0f);
737 pState->SetFillAlpha(1.0f);
738 pState->SetSoftMask(nullptr);
739 }
740 m_nStreams = 0;
741 m_pSingleStream.reset(new CPDF_StreamAcc);
742 m_pSingleStream->LoadAllData(pForm->m_pFormStream, false);
743 m_pData = (uint8_t*)m_pSingleStream->GetData();
744 m_Size = m_pSingleStream->GetSize();
745 m_Status = ToBeContinued;
746 m_InternalStage = STAGE_PARSE;
747 m_CurrentOffset = 0;
748 }
749
750 void CPDF_ContentParser::Continue(IFX_Pause* pPause) {
751 int steps = 0;
752 while (m_Status == ToBeContinued) {
753 if (m_InternalStage == STAGE_GETCONTENT) {
754 if (m_CurrentOffset == m_nStreams) {
755 if (!m_StreamArray.empty()) {
756 FX_SAFE_UINT32 safeSize = 0;
757 for (const auto& stream : m_StreamArray) {
758 safeSize += stream->GetSize();
759 safeSize += 1;
760 }
761 if (!safeSize.IsValid()) {
762 m_Status = Done;
763 return;
764 }
765 m_Size = safeSize.ValueOrDie();
766 m_pData = FX_Alloc(uint8_t, m_Size);
767 uint32_t pos = 0;
768 for (const auto& stream : m_StreamArray) {
769 FXSYS_memcpy(m_pData + pos, stream->GetData(), stream->GetSize());
770 pos += stream->GetSize();
771 m_pData[pos++] = ' ';
772 }
773 m_StreamArray.clear();
774 } else {
775 m_pData = (uint8_t*)m_pSingleStream->GetData();
776 m_Size = m_pSingleStream->GetSize();
777 }
778 m_InternalStage = STAGE_PARSE;
779 m_CurrentOffset = 0;
780 } else {
781 CPDF_Array* pContent =
782 m_pObjectHolder->m_pFormDict->GetArrayFor("Contents");
783 m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc);
784 CPDF_Stream* pStreamObj = ToStream(
785 pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr);
786 m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, false);
787 m_CurrentOffset++;
788 }
789 }
790 if (m_InternalStage == STAGE_PARSE) {
791 if (!m_pParser) {
792 m_pParser.reset(new CPDF_StreamContentParser(
793 m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources,
794 nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources,
795 &m_pObjectHolder->m_BBox, nullptr, 0));
796 m_pParser->GetCurStates()->m_ColorState.SetDefault();
797 }
798 if (m_CurrentOffset >= m_Size) {
799 m_InternalStage = STAGE_CHECKCLIP;
800 } else {
801 m_CurrentOffset +=
802 m_pParser->Parse(m_pData + m_CurrentOffset,
803 m_Size - m_CurrentOffset, PARSE_STEP_LIMIT);
804 }
805 }
806 if (m_InternalStage == STAGE_CHECKCLIP) {
807 if (m_pType3Char) {
808 m_pType3Char->m_bColored = m_pParser->IsColored();
809 m_pType3Char->m_Width =
810 FXSYS_round(m_pParser->GetType3Data()[0] * 1000);
811 m_pType3Char->m_BBox.left =
812 FXSYS_round(m_pParser->GetType3Data()[2] * 1000);
813 m_pType3Char->m_BBox.bottom =
814 FXSYS_round(m_pParser->GetType3Data()[3] * 1000);
815 m_pType3Char->m_BBox.right =
816 FXSYS_round(m_pParser->GetType3Data()[4] * 1000);
817 m_pType3Char->m_BBox.top =
818 FXSYS_round(m_pParser->GetType3Data()[5] * 1000);
819 }
820 for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) {
821 if (!pObj->m_ClipPath)
822 continue;
823 if (pObj->m_ClipPath.GetPathCount() != 1)
824 continue;
825 if (pObj->m_ClipPath.GetTextCount())
826 continue;
827 CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0);
828 if (!ClipPath.IsRect() || pObj->IsShading())
829 continue;
830 CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0),
831 ClipPath.GetPointX(2), ClipPath.GetPointY(2));
832 CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right,
833 pObj->m_Top);
834 if (old_rect.Contains(obj_rect)) {
835 pObj->m_ClipPath.SetNull();
836 }
837 }
838 m_Status = Done;
839 return;
840 }
841 steps++;
842 if (pPause && pPause->NeedToPauseNow()) {
843 break;
844 }
845 }
846 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698