// Copyright 2014 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../../include/fpdfapi/fpdf_page.h" #include "../../../include/fpdfapi/fpdf_module.h" #include "pageint.h" #if defined(_FPDFAPI_MINI_) extern const FX_LPCSTR _PDF_CharType; void CPDF_StreamContentParser::InputData(FX_LPCBYTE src_buf, FX_DWORD src_size) { if (m_Level > _FPDF_MAX_FORM_LEVEL_) { return; } for (FX_DWORD i = 0; i < src_size; i ++) { int ch = src_buf[i]; int type = _PDF_CharType[ch]; start: switch (m_WordState) { case 0: if (type == 'W') { } else if (type == 'N') { m_WordState = 5; m_pWordBuf[0] = ch; m_WordSize = 1; } else if (type == 'R') { m_WordState = 4; m_pWordBuf[0] = ch; m_WordSize = 1; } else switch (ch) { case '/': m_WordState = 2; m_WordSize = 0; break; case '[': StartArray(); break; case ']': EndArray(); break; case '(': m_WordState = 7; m_StringLevel = 1; m_StringState = 0; m_StringBuf.Clear(); break; case '<': m_WordState = 3; break; case '>': m_WordState = 8; break; case '%': m_WordState = 1; break; } break; case 1: if (ch == '\n' || ch == '\r') { m_WordState = 0; } break; case 2: if (type != 'R' && type != 'N') { EndName(); m_WordState = 0; goto start; } if (m_WordSize < 256) { m_pWordBuf[m_WordSize++] = ch; } break; case 3: if (ch == '<') { StartDict(); m_WordState = 0; } else { m_StringBuf.Clear(); m_WordState = 6; goto start; } break; case 4: if (type != 'R' && type != 'N') { m_WordState = 0; EndKeyword(); if (m_bAbort) { return; } goto start; } if (m_WordSize < 256) { m_pWordBuf[m_WordSize++] = ch; } break; case 5: if (type != 'N') { EndNumber(); m_WordState = 0; goto start; } if (m_WordSize < 256) { m_pWordBuf[m_WordSize++] = ch; } break; case 6: if (ch == '>') { EndHexString(); m_WordState = 0; } else { m_StringBuf.AppendByte(ch); } break; case 7: switch (m_StringState) { case 0: if (ch == ')') { m_StringLevel --; if (m_StringLevel == 0) { EndString(); m_WordState = 0; break; } m_StringBuf.AppendByte(')'); } else if (ch == '(') { m_StringLevel ++; m_StringBuf.AppendByte('('); } else if (ch == '\\') { m_StringState = 1; } else { m_StringBuf.AppendByte((char)ch); } break; case 1: if (ch >= '0' && ch <= '7') { m_EscCode = ch - '0'; m_StringState = 2; break; } if (ch == 'n') { m_StringBuf.AppendByte('\n'); } else if (ch == 'r') { m_StringBuf.AppendByte('\r'); } else if (ch == 't') { m_StringBuf.AppendByte('\t'); } else if (ch == 'b') { m_StringBuf.AppendByte('\b'); } else if (ch == 'f') { m_StringBuf.AppendByte('\f'); } else if (ch == '\\') { m_StringBuf.AppendByte('\\'); } else if (ch == '(') { m_StringBuf.AppendByte('('); } else if (ch == ')') { m_StringBuf.AppendByte(')'); } else if (ch == '\r') { m_StringState = 4; break; } else if (ch == '\n') { } else { m_StringBuf.AppendByte(ch); } m_StringState = 0; break; case 2: if (ch >= '0' && ch <= '7') { m_EscCode = m_EscCode * 8 + ch - '0'; m_StringState = 3; } else { m_StringBuf.AppendByte(m_EscCode); m_StringState = 0; goto start; } break; case 3: if (ch >= '0' && ch <= '7') { m_EscCode = m_EscCode * 8 + ch - '0'; m_StringBuf.AppendByte(m_EscCode); m_StringState = 0; } else { m_StringBuf.AppendByte(m_EscCode); m_StringState = 0; goto start; } break; case 4: m_StringState = 0; if (ch != '\n') { goto start; } break; } break; case 8: m_WordState = 0; if (ch == '>') { EndDict(); } else { goto start; } break; case 9: switch (m_InlineImageState) { case 0: if (type == 'W' || type == 'D') { m_InlineImageState = 1; m_InlineWhiteChar = ch; } else { m_StringBuf.AppendByte(ch); } break; case 1: m_StringBuf.AppendByte(m_InlineWhiteChar); if (ch == 'I') { m_InlineImageState = 2; } else { m_InlineImageState = 0; goto start; } break; case 2: if (ch == 'D') { m_InlineImageState = 3; } else { m_StringBuf.AppendByte('I'); m_InlineImageState = 0; goto start; } break; case 3: EndImageDict(); break; } break; case 10: switch (m_InlineImageState) { case 0: if (type == 'W') { m_InlineImageState = 1; m_InlineWhiteChar = ch; } else { m_ImageSrcBuf.AppendByte(ch); } break; case 1: if (ch == 'E') { m_InlineImageState = 2; } else { m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); m_InlineImageState = 0; goto start; } break; case 2: if (ch == 'I') { m_InlineImageState = 3; } else { m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); m_ImageSrcBuf.AppendByte('E'); m_InlineImageState = 0; goto start; } break; case 3: if (type == 'W') { EndInlineImage(); } else { m_ImageSrcBuf.AppendByte(m_InlineWhiteChar); m_ImageSrcBuf.AppendByte('E'); m_ImageSrcBuf.AppendByte('I'); m_InlineImageState = 0; goto start; } break; } break; case 11: if (m_InlineImageState < m_ImageSrcBuf.GetSize()) { m_ImageSrcBuf.GetBuffer()[m_InlineImageState ++] = ch; } else { if (ch == 'I') { EndInlineImage(); } } break; } } } void CPDF_StreamContentParser::Finish() { switch (m_WordState) { case 0: break; case 1: break; case 2: EndName(); break; case 3: break; case 4: EndKeyword(); break; case 5: EndNumber(); break; case 6: EndHexString(); break; case 7: EndString(); break; case 8: break; case 9: break; case 10: EndInlineImage(); break; } m_WordState = 0; } void CPDF_StreamContentParser::AddContainer(CPDF_Object* pObject) { if (m_ObjectSize) { m_pObjectState[m_ObjectSize] = SetToCurObj(pObject); } FXSYS_assert(m_ObjectSize < _FPDF_MAX_OBJECT_STACK_SIZE_); m_pObjectStack[m_ObjectSize++] = pObject; } FX_BOOL CPDF_StreamContentParser::SetToCurObj(CPDF_Object* pObject) { if (m_ObjectSize == 0) { AddObjectParam(pObject); return TRUE; } FX_BOOL bInArrayOrDict = TRUE; CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; if (pCurObj->GetType() == PDFOBJ_ARRAY) { ((CPDF_Array*)pCurObj)->Add(pObject, m_pDocument); } else { if (!m_bDictName && m_pDictName[0]) { ((CPDF_Dictionary*)pCurObj)->SetAt((FX_LPCSTR)m_pDictName, pObject, m_pDocument); } else { bInArrayOrDict = FALSE; } m_bDictName = TRUE; } return bInArrayOrDict; } void CPDF_StreamContentParser::StartArray() { if (m_ObjectSize) if (m_pObjectStack[0]->GetType() != PDFOBJ_DICTIONARY && m_pObjectStack[m_ObjectSize - 1]->GetType() == PDFOBJ_ARRAY) { return; } CPDF_Array* pArray = FX_NEW CPDF_Array; AddContainer(pArray); } void CPDF_StreamContentParser::EndArray() { if (m_ObjectSize == 0) { return; } CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; if (pCurObj->GetType() != PDFOBJ_ARRAY) { return; } m_ObjectSize --; if (m_ObjectSize == 0) { AddObjectParam(pCurObj); } else { if (!m_pObjectState[m_ObjectSize]) { pCurObj->Release(); } } m_pObjectState[m_ObjectSize] = FALSE; } void CPDF_StreamContentParser::StartDict() { CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary; AddContainer(pDict); m_bDictName = TRUE; } void CPDF_StreamContentParser::EndDict() { if (m_ObjectSize == 0) { return; } CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; if (pCurObj->GetType() != PDFOBJ_DICTIONARY) { return; } m_ObjectSize --; if (m_ObjectSize == 0) { AddObjectParam(pCurObj); } else { if (!m_pObjectState[m_ObjectSize]) { pCurObj->Release(); } } m_pObjectState[m_ObjectSize] = FALSE; } void CPDF_StreamContentParser::EndName() { if (m_ObjectSize == 0) { AddNameParam((FX_LPCSTR)m_pWordBuf, m_WordSize); return; } CPDF_Object* pCurObj = m_pObjectStack[m_ObjectSize - 1]; if (pCurObj->GetType() == PDFOBJ_ARRAY) { ((CPDF_Array*)pCurObj)->AddName(CFX_ByteString(m_pWordBuf, m_WordSize)); } else { if (m_bDictName) { FXSYS_memcpy32(m_pDictName, m_pWordBuf, m_WordSize); m_pDictName[m_WordSize] = 0; } else { if (m_pDictName[0] != 0) { ((CPDF_Dictionary*)pCurObj)->SetAtName((FX_LPCSTR)m_pDictName, CFX_ByteString(m_pWordBuf, m_WordSize)); } } m_bDictName = !m_bDictName; } } void CPDF_StreamContentParser::EndNumber() { if (m_ObjectSize == 0) { AddNumberParam((FX_LPCSTR)m_pWordBuf, m_WordSize); return; } CPDF_Number *pObj = FX_NEW CPDF_Number(CFX_ByteStringC(m_pWordBuf, m_WordSize)); if (!SetToCurObj(pObj)) { pObj->Release(); } } extern CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf); void CPDF_StreamContentParser::EndHexString() { CPDF_String *pObj = FX_NEW CPDF_String(_FPDF_ByteStringFromHex(m_StringBuf), TRUE); if (!SetToCurObj(pObj)) { pObj->Release(); } } void CPDF_StreamContentParser::EndString() { CPDF_String *pObj = FX_NEW CPDF_String(m_StringBuf.GetByteString()); if (!SetToCurObj(pObj)) { pObj->Release(); } } void CPDF_StreamContentParser::Handle_BeginImage(void) { m_WordState = 9; m_InlineImageState = 0; m_StringBuf.Clear(); } void _PDF_ReplaceAbbr(CPDF_Object* pObj); void CPDF_StreamContentParser::EndImageDict() { if (m_StringBuf.GetSize() != m_LastImageDict.GetSize() || FXSYS_memcmp32(m_StringBuf.GetBuffer(), m_LastImageDict.GetBuffer(), m_StringBuf.GetSize())) { m_WordState = 0; StartDict(); InputData(m_StringBuf.GetBuffer(), m_StringBuf.GetSize()); Finish(); m_bSameLastDict = FALSE; if (m_pLastImageDict && m_bReleaseLastDict) { m_pLastImageDict->Release(); m_pLastImageDict = NULL; } if (!m_ObjectSize) { m_InlineImageState = 0; return; } m_pLastImageDict = (CPDF_Dictionary*)m_pObjectStack[--m_ObjectSize]; m_bReleaseLastDict = !m_pObjectState[m_ObjectSize]; m_pObjectState[m_ObjectSize] = FALSE; _PDF_ReplaceAbbr(m_pLastImageDict); m_LastImageDict.TakeOver(m_StringBuf); if (m_pLastImageDict->KeyExist(FX_BSTRC("ColorSpace"))) { CPDF_Object* pCSObj = m_pLastImageDict->GetElementValue(FX_BSTRC("ColorSpace")); if (pCSObj->GetType() == PDFOBJ_NAME) { CFX_ByteString name = pCSObj->GetString(); if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) { pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); if (pCSObj) { if (!pCSObj->GetObjNum()) { pCSObj = pCSObj->Clone(); } m_pLastImageDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument); } } } } } else { m_bSameLastDict = TRUE; } m_ImageSrcBuf.Clear(); if (m_pLastCloneImageDict) { m_pLastCloneImageDict->Release(); } m_pLastCloneImageDict = (CPDF_Dictionary*)m_pLastImageDict->Clone(); if (m_pLastCloneImageDict->KeyExist(FX_BSTRC("Filter"))) { m_WordState = 10; m_InlineImageState = 0; } else { int width = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Width")); int height = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Height")); int OrigSize = 0; CPDF_Object* pCSObj = m_pLastCloneImageDict->GetElementValue(FX_BSTRC("ColorSpace")); if (pCSObj != NULL) { int bpc = m_pLastCloneImageDict->GetInteger(FX_BSTRC("BitsPerComponent")); int nComponents = 1; CPDF_ColorSpace* pCS = m_pDocument->LoadColorSpace(pCSObj); if (pCS == NULL) { nComponents = 3; } else { nComponents = pCS->CountComponents(); m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); } int pitch = (width * bpc * nComponents + 7) / 8; OrigSize = pitch * height; } else { OrigSize = ((width + 7) / 8) * height; } m_ImageSrcBuf.AppendBlock(NULL, OrigSize); m_WordState = 11; m_InlineImageState = 0; } } void CPDF_StreamContentParser::EndInlineImage() { CFX_AffineMatrix ImageMatrix; ImageMatrix.Copy(m_pCurStates->m_CTM); ImageMatrix.Concat(m_mtContentToUser); m_LastImageData.CopyData(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize()); CPDF_Stream* pStream = CPDF_Stream::Create(m_ImageSrcBuf.GetBuffer(), m_ImageSrcBuf.GetSize(), m_pLastCloneImageDict); m_ImageSrcBuf.DetachBuffer(); m_pLastCloneImageDict = NULL; CPDF_InlineImages* pImages = FX_NEW CPDF_InlineImages; pImages->m_pStream = pStream; SetGraphicStates(pImages, !m_pLastCloneImageDict->KeyExist(FX_BSTRC("ColorSpace")), FALSE, FALSE); pImages->AddMatrix(ImageMatrix); m_pObjectList->m_ObjectList.AddTail(pImages); m_WordState = 0; } #define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) #define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) #define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) void CPDF_StreamContentParser::EndKeyword() { CPDF_Object *pObj = NULL; if (m_WordSize == 4) { if (*(FX_DWORD*)m_pWordBuf == FXDWORD_TRUE) { pObj = CPDF_Boolean::Create(TRUE); if (!SetToCurObj(pObj)) { pObj->Release(); } return; } else if (*(FX_DWORD*)m_pWordBuf == FXDWORD_NULL) { pObj = CPDF_Null::Create(); if (!SetToCurObj(pObj)) { pObj->Release(); } return; } } else if (m_WordSize == 5) { if (*(FX_DWORD*)m_pWordBuf == FXDWORD_FALS && m_pWordBuf[4] == 'e') { pObj = CPDF_Boolean::Create(FALSE); if (!SetToCurObj(pObj)) { pObj->Release(); } return; } } m_pWordBuf[m_WordSize] = 0; OnOperator((char*)m_pWordBuf); ClearAllParams(); } #define PAGEPARSE_STAGE_PARSE 2 #define PAGEPARSE_STAGE_CHECKCLIP 3 CPDF_ContentParser::CPDF_ContentParser() { m_pParser = NULL; m_Status = Ready; m_pStreamFilter = NULL; m_pType3Char = NULL; } CPDF_ContentParser::~CPDF_ContentParser() { Clear(); } void CPDF_ContentParser::Clear() { if (m_pParser) { delete m_pParser; } if (m_pStreamFilter) { delete m_pStreamFilter; } m_pParser = NULL; m_Status = Ready; } void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) { if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPage->m_pFormDict == NULL) { m_Status = Done; return; } m_pObjects = pPage; m_bForm = FALSE; if (pOptions) { m_Options = *pOptions; } CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); if (pContent == NULL) { m_Status = Done; return; } if (pContent->GetType() == PDFOBJ_STREAM) { m_nStreams = 1; } else if (pContent->GetType() == PDFOBJ_ARRAY) { m_nStreams = ((CPDF_Array*)pContent)->GetCount(); } else { m_Status = Done; return; } m_Status = ToBeContinued; m_InternalStage = PAGEPARSE_STAGE_PARSE; m_CurrentOffset = 0; m_pParser = FX_NEW CPDF_StreamContentParser; m_pParser->Initialize(); m_pParser->PrepareParse(pPage->m_pDocument, pPage->m_pResources, NULL, NULL, pPage, pPage->m_pResources, &pPage->m_BBox, &m_Options, NULL, 0); m_pParser->m_pCurStates->m_ColorState.GetModify()->Default(); } void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix, CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level) { m_pType3Char = pType3Char; m_pObjects = pForm; m_bForm = TRUE; CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix")); if (pGraphicStates) { form_matrix.Concat(pGraphicStates->m_CTM); } CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); CFX_FloatRect form_bbox; CPDF_Path ClipPath; if (pBBox) { form_bbox = pBBox->GetRect(); ClipPath.New(); ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top); ClipPath.Transform(&form_matrix); if (pParentMatrix) { ClipPath.Transform(pParentMatrix); } form_bbox.Transform(&form_matrix); } CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); m_pParser = FX_NEW CPDF_StreamContentParser; m_pParser->Initialize(); m_pParser->PrepareParse(pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates, level); m_pParser->m_pCurStates->m_CTM = form_matrix; if (ClipPath.NotNull()) { m_pParser->m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE); } if (pForm->m_Transparency & PDFTRANS_GROUP) { CPDF_GeneralStateData* pData = m_pParser->m_pCurStates->m_GeneralState.GetModify(); pData->m_BlendType = FXDIB_BLEND_NORMAL; pData->m_StrokeAlpha = 1.0f; pData->m_FillAlpha = 1.0f; pData->m_pSoftMask = NULL; } m_pStreamFilter = pForm->m_pFormStream->GetStreamFilter(); m_nStreams = 1; m_Status = ToBeContinued; m_InternalStage = PAGEPARSE_STAGE_PARSE; m_CurrentOffset = 0; } void CPDF_ContentParser::Continue(IFX_Pause* pPause) { while (m_Status == ToBeContinued) { if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { if (m_pStreamFilter == NULL) { if (m_CurrentOffset == m_nStreams) { m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; if (m_pType3Char) { m_pType3Char->m_bColored = m_pParser->m_bColored; m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Data[0] * 1000); m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000); m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000); m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000); m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000); m_pType3Char->m_bPageRequired = m_pParser->m_bResourceMissing; } delete m_pParser; m_pParser = NULL; continue; } CPDF_Object* pContent = m_pObjects->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); if (pContent->GetType() == PDFOBJ_STREAM) { m_pStreamFilter = ((CPDF_Stream*)pContent)->GetStreamFilter(); } else { CPDF_Stream* pStream = ((CPDF_Array*)pContent)->GetStream(m_CurrentOffset); if (pStream == NULL) { m_CurrentOffset ++; continue; } m_pStreamFilter = pStream->GetStreamFilter(); } } FX_DWORD len = m_pStreamFilter->ReadBlock(m_pParser->m_pStreamBuf, STREAM_PARSE_BUFSIZE); m_pParser->InputData(m_pParser->m_pStreamBuf, len); if (m_pParser->m_bAbort) { delete m_pStreamFilter; m_pStreamFilter = NULL; m_Status = Done; delete m_pParser; m_pParser = NULL; return; } if (len < STREAM_PARSE_BUFSIZE) { m_pParser->Finish(); m_CurrentOffset ++; delete m_pStreamFilter; m_pStreamFilter = NULL; } if (pPause && pPause->NeedToPauseNow()) { return; } } if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); while (pos) { CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos); if (pObj == NULL) { continue; } if (pObj->m_ClipPath.IsNull()) { continue; } if (pObj->m_ClipPath.GetPathCount() != 1) { continue; } if (pObj->m_ClipPath.GetTextCount()) { continue; } CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { continue; } CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), ClipPath.GetPointX(2), ClipPath.GetPointY(2)); CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top); if (old_rect.Contains(obj_rect)) { pObj->m_ClipPath.SetNull(); } } if (m_pObjects->m_ObjectList.GetCount() == 1) { CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetAt(m_pObjects->m_ObjectList.GetHeadPosition()); if (pObj && pObj->m_Type == PDFPAGE_TEXT) { CPDF_TextObject* pText = (CPDF_TextObject*)pObj; } } m_Status = Done; return; } } } int CPDF_ContentParser::EstimateProgress() { if (m_Status == Ready) { return 0; } if (m_Status == Done) { return 100; } if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { return 90; } if (m_pStreamFilter == NULL) { return 90 * m_CurrentOffset / m_nStreams; } int total_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_nStreams; int parsed_raw_size = m_pStreamFilter->GetStream()->GetRawSize() * m_CurrentOffset + m_pStreamFilter->GetSrcPos(); return 90 * parsed_raw_size / total_raw_size; } CPDF_InlineImages::CPDF_InlineImages() { m_Type = PDFPAGE_INLINES; m_pStream = NULL; m_pBitmap = NULL; } CPDF_InlineImages::~CPDF_InlineImages() { if (m_pStream) { m_pStream->Release(); } if (m_pBitmap) { delete m_pBitmap; } } void CPDF_InlineImages::AddMatrix(CFX_AffineMatrix& matrix) { m_Matrices.Add(matrix); CFX_FloatRect rect = matrix.GetUnitRect(); if (m_Matrices.GetSize() > 1) { CFX_FloatRect rect1(m_Left, m_Bottom, m_Right, m_Top); rect.Union(rect1); } m_Left = rect.left; m_Right = rect.right; m_Top = rect.top; m_Bottom = rect.bottom; } #endif