FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { CFX_ByteString name = pArray->GetString(1); if (name == FX_BSTRC("None")) { m_Type = None; } else { m_Type = Colorant; CPDF_Object* pAltCS = pArray->GetElementValue(2); if (pAltCS == m_pArray) { return FALSE; } m_pAltCS = Load(pDoc, pAltCS); if (!m_pAltCS) { return FALSE; } CPDF_Object* pFuncObj = pArray->GetElementValue(3); if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) { m_pFunc = CPDF_Function::Load(pFuncObj); } if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) { delete m_pFunc; m_pFunc = NULL; } } return TRUE; }
FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const { if (m_Type == None) { return FALSE; } if (m_pFunc == NULL) { if (m_pAltCS == NULL) { return FALSE; } int nComps = m_pAltCS->CountComponents(); CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps); for (int i = 0; i < nComps; i ++) { results[i] = *pBuf; } m_pAltCS->GetRGB(results, R, G, B); return TRUE; } CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs()); int nresults = 0; m_pFunc->Call(pBuf, 1, results, nresults); if (nresults == 0) { return FALSE; } if (m_pAltCS) { m_pAltCS->GetRGB(results, R, G, B); return TRUE; } R = G = B = 0; return FALSE; }
FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { if (pArray->GetCount() < 4) { return FALSE; } CPDF_Object* pBaseObj = pArray->GetElementValue(1); if (pBaseObj == m_pArray) { return FALSE; } CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL); if (m_pBaseCS == NULL) { return FALSE; } m_nBaseComponents = m_pBaseCS->CountComponents(); m_pCompMinMax = FX_Alloc(FX_FLOAT, m_nBaseComponents * 2); FX_FLOAT defvalue; for (int i = 0; i < m_nBaseComponents; i ++) { m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], m_pCompMinMax[i * 2 + 1]); m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2]; } m_MaxIndex = pArray->GetInteger(2); CPDF_Object* pTableObj = pArray->GetElementValue(3); if (pTableObj == NULL) { return FALSE; } if (pTableObj->GetType() == PDFOBJ_STRING) { m_Table = ((CPDF_String*)pTableObj)->GetString(); } else if (pTableObj->GetType() == PDFOBJ_STREAM) { CPDF_StreamAcc acc; acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE); m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize()); } return TRUE; }
FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { CPDF_Array* pObj = ToArray(pArray->GetElementValue(1)); if (!pObj) return FALSE; m_nComponents = pObj->GetCount(); CPDF_Object* pAltCS = pArray->GetElementValue(2); if (!pAltCS || pAltCS == m_pArray) { return FALSE; } m_pAltCS = Load(pDoc, pAltCS); m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3)); if (!m_pAltCS || !m_pFunc) { return FALSE; } if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) { return FALSE; } return TRUE; }
FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { CPDF_Object* pObj = pArray->GetElementValue(1); if (!pObj) { return FALSE; } if (pObj->GetType() != PDFOBJ_ARRAY) { return FALSE; } m_nComponents = ((CPDF_Array*)pObj)->GetCount(); CPDF_Object* pAltCS = pArray->GetElementValue(2); if (!pAltCS || pAltCS == m_pArray) { return FALSE; } m_pAltCS = Load(pDoc, pAltCS); m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3)); if (m_pAltCS == NULL || m_pFunc == NULL) { return FALSE; } if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) { return FALSE; } return TRUE; }
FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { if (pArray->GetCount() < 4) { return FALSE; } CPDF_Object* pBaseObj = pArray->GetElementValue(1); if (pBaseObj == m_pArray) { return FALSE; } CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL); if (!m_pBaseCS) { return FALSE; } m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); m_nBaseComponents = m_pBaseCS->CountComponents(); m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2); FX_FLOAT defvalue; for (int i = 0; i < m_nBaseComponents; i++) { m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], m_pCompMinMax[i * 2 + 1]); m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2]; } m_MaxIndex = pArray->GetInteger(2); CPDF_Object* pTableObj = pArray->GetElementValue(3); if (!pTableObj) return FALSE; if (CPDF_String* pString = pTableObj->AsString()) { m_Table = pString->GetString(); } else if (CPDF_Stream* pStream = pTableObj->AsStream()) { CPDF_StreamAcc acc; acc.LoadAllData(pStream, FALSE); m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize()); } return TRUE; }
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; } }
CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, CPDF_Dictionary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode) { if (m_Pos == m_Size) { return NULL; } if (PDF_CharType[m_pBuf[m_Pos]] == 'W') { m_Pos ++; } CFX_ByteString Decoder; CPDF_Dictionary* pParam = NULL; CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter")); if (pFilter == NULL) { } else if (pFilter->GetType() == PDFOBJ_ARRAY) { Decoder = ((CPDF_Array*)pFilter)->GetString(0); CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); if (pParams) { pParam = pParams->GetDict(0); } } else { Decoder = pFilter->GetString(); pParam = pDict->GetDict(FX_BSTRC("DecodeParms")); } FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width")); FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height")); FX_DWORD OrigSize = 0; if (pCSObj != NULL) { FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent")); FX_DWORD nComponents = 1; CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); if (pCS == NULL) { nComponents = 3; } else { nComponents = pCS->CountComponents(); pDoc->GetPageData()->ReleaseColorSpace(pCSObj); } FX_DWORD pitch = width; if (bpc && pitch > INT_MAX / bpc) { return NULL; } pitch *= bpc; if (nComponents && pitch > INT_MAX / nComponents) { return NULL; } pitch *= nComponents; if (pitch > INT_MAX - 7) { return NULL; } pitch += 7; pitch /= 8; OrigSize = pitch; } else { if (width > INT_MAX - 7) { return NULL; } OrigSize = ((width + 7) / 8); } if (height && OrigSize > INT_MAX / height) { return NULL; } OrigSize *= height; uint8_t* pData = NULL; FX_DWORD dwStreamSize; if (Decoder.IsEmpty()) { if (OrigSize > m_Size - m_Pos) { OrigSize = m_Size - m_Pos; } pData = FX_Alloc(uint8_t, OrigSize); FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); dwStreamSize = OrigSize; m_Pos += OrigSize; } else { FX_DWORD dwDestSize = OrigSize; dwStreamSize = PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, Decoder, pParam, pData, dwDestSize); if ((int)dwStreamSize < 0) { return NULL; } if (bDecode) { m_Pos += dwStreamSize; dwStreamSize = dwDestSize; if (pFilter->GetType() == PDFOBJ_ARRAY) { ((CPDF_Array*)pFilter)->RemoveAt(0); CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); if (pParams) { pParams->RemoveAt(0); } } else { pDict->RemoveAt(FX_BSTRC("Filter")); pDict->RemoveAt(FX_BSTRC("DecodeParms")); } } else { if (pData) { FX_Free(pData); } FX_DWORD dwSavePos = m_Pos; m_Pos += dwStreamSize; while (1) { FX_DWORD dwPrevPos = m_Pos; CPDF_StreamParser::SyntaxType type = ParseNextElement(); if (type == CPDF_StreamParser::EndOfData) { break; } if (type != CPDF_StreamParser::Keyword) { dwStreamSize += m_Pos - dwPrevPos; continue; } if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && GetWordBuf()[1] == 'I') { m_Pos = dwPrevPos; break; } dwStreamSize += m_Pos - dwPrevPos; } m_Pos = dwSavePos; pData = FX_Alloc(uint8_t, dwStreamSize); FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); m_Pos += dwStreamSize; } } pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize); return CPDF_Stream::Create(pData, dwStreamSize, pDict); }
void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, CFX_Matrix* pMatrix, FX_RECT& clip_rect, int alpha, FX_BOOL bAlphaMode) { CPDF_Function** pFuncs = pPattern->m_pFunctions; int nFuncs = pPattern->m_nFuncs; CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict(); CPDF_ColorSpace* pColorSpace = pPattern->m_pCS; if (!pColorSpace) { return; } FX_ARGB background = 0; if (!pPattern->m_bShadingObj && pPattern->m_pShadingObj->GetDict()->KeyExist("Background")) { CPDF_Array* pBackColor = pPattern->m_pShadingObj->GetDict()->GetArray("Background"); if (pBackColor && pBackColor->GetCount() >= (FX_DWORD)pColorSpace->CountComponents()) { CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents()); for (int i = 0; i < pColorSpace->CountComponents(); i++) { comps[i] = pBackColor->GetNumber(i); } FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; pColorSpace->GetRGB(comps, R, G, B); background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255)); } } if (pDict->KeyExist("BBox")) { CFX_FloatRect rect = pDict->GetRect("BBox"); rect.Transform(pMatrix); clip_rect.Intersect(rect.GetOutterRect()); } CPDF_DeviceBuffer buffer; buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150); CFX_Matrix FinalMatrix = *pMatrix; FinalMatrix.Concat(*buffer.GetMatrix()); CFX_DIBitmap* pBitmap = buffer.GetBitmap(); if (!pBitmap->GetBuffer()) { return; } pBitmap->Clear(background); int fill_mode = m_Options.m_Flags; switch (pPattern->m_ShadingType) { case kInvalidShading: case kMaxShading: return; case kFunctionBasedShading: DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); break; case kAxialShading: DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); break; case kRadialShading: DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); break; case kFreeFormGouraudTriangleMeshShading: { DrawFreeGouraudShading(pBitmap, &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs, pColorSpace, alpha); } break; case kLatticeFormGouraudTriangleMeshShading: { DrawLatticeGouraudShading(pBitmap, &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs, pColorSpace, alpha); } break; case kCoonsPatchMeshShading: case kTensorProductPatchMeshShading: { DrawCoonPatchMeshes( pPattern->m_ShadingType == kTensorProductPatchMeshShading, pBitmap, &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs, pColorSpace, fill_mode, alpha); } break; } if (bAlphaMode) { pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha); } if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor); } buffer.OutputToDevice(); }
CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict, FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix) { if (pSMaskDict == NULL) { return NULL; } int width = pClipRect->right - pClipRect->left; int height = pClipRect->bottom - pClipRect->top; FX_BOOL bLuminosity = FALSE; bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha"); CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G")); if (pGroup == NULL) { return NULL; } nonstd::unique_ptr<CPDF_Function> pFunc; CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR")); if (pFuncObj && (pFuncObj->IsDictionary() || pFuncObj->IsStream())) pFunc.reset(CPDF_Function::Load(pFuncObj)); CFX_AffineMatrix matrix = *pMatrix; matrix.TranslateI(-pClipRect->left, -pClipRect->top); CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup); form.ParseContent(NULL, NULL, NULL, NULL); CFX_FxgeDevice bitmap_device; #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) { return NULL; } #else if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) { return NULL; } #endif CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap(); CPDF_Object* pCSObj = NULL; CPDF_ColorSpace* pCS = NULL; if (bLuminosity) { CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC")); FX_ARGB back_color = 0xff000000; if (pBC) { CPDF_Dictionary* pDict = pGroup->GetDict(); if (pDict && pDict->GetDict(FX_BSTRC("Group"))) pCSObj = pDict->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS")); else pCSObj = NULL; pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj); if (pCS) { FX_FLOAT R, G, B; FX_DWORD comps = 8; if (pCS->CountComponents() > static_cast<int32_t>(comps)) { comps = (FX_DWORD)pCS->CountComponents(); } CFX_FixedBufGrow<FX_FLOAT, 8> float_array(comps); FX_FLOAT* pFloats = float_array; FX_SAFE_DWORD num_floats = comps; num_floats *= sizeof(FX_FLOAT); if (!num_floats.IsValid()) { return NULL; } FXSYS_memset(pFloats, 0, num_floats.ValueOrDie()); int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount(); for (int i = 0; i < count; i++) { pFloats[i] = pBC->GetNumber(i); } pCS->GetRGB(pFloats, R, G, B); back_color = 0xff000000 | ((int32_t)(R * 255) << 16) | ((int32_t)(G * 255) << 8) | (int32_t)(B * 255); m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); } } bitmap.Clear(back_color); } else { bitmap.Clear(0); } CPDF_Dictionary* pFormResource = NULL; if (form.m_pFormDict) { pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources")); } CPDF_RenderOptions options; options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA; CPDF_RenderStatus status; status.Initialize(m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity); status.RenderObjectList(&form, &matrix); nonstd::unique_ptr<CFX_DIBitmap> pMask(new CFX_DIBitmap); if (!pMask->Create(width, height, FXDIB_8bppMask)) return nullptr; uint8_t* dest_buf = pMask->GetBuffer(); int dest_pitch = pMask->GetPitch(); uint8_t* src_buf = bitmap.GetBuffer(); int src_pitch = bitmap.GetPitch(); std::vector<uint8_t> transfers(256); if (pFunc) { CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs()); for (int i = 0; i < 256; i++) { FX_FLOAT input = (FX_FLOAT)i / 255.0f; int nresult; pFunc->Call(&input, 1, results, nresult); transfers[i] = FXSYS_round(results[0] * 255); } } else { for (int i = 0; i < 256; i++) { transfers[i] = i; } } if (bLuminosity) { int Bpp = bitmap.GetBPP() / 8; for (int row = 0; row < height; row++) { uint8_t* dest_pos = dest_buf + row * dest_pitch; uint8_t* src_pos = src_buf + row * src_pitch; for (int col = 0; col < width; col++) { *dest_pos++ = transfers[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)]; src_pos += Bpp; } } } else if (pFunc) { int size = dest_pitch * height; for (int i = 0; i < size; i++) { dest_buf[i] = transfers[src_buf[i]]; } } else { FXSYS_memcpy(dest_buf, src_buf, dest_pitch * height); } return pMask.release(); }
FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { CPDF_Stream* pStream = pArray->GetStream(1); if (pStream == NULL) { return FALSE; } m_pProfile = pDoc->LoadIccProfile(pStream); if (!m_pProfile) { return FALSE; } m_nComponents = m_pProfile->GetComponents(); //Try using the nComponents from ICC profile CPDF_Dictionary* pDict = pStream->GetDict(); if (m_pProfile->m_pTransform == NULL) { // No valid ICC profile or using sRGB CPDF_Object* pAlterCSObj = pDict ? pDict->GetElementValue(FX_BSTRC("Alternate")) : NULL; if (pAlterCSObj) { CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj); if (pAlterCS) { if (m_nComponents == 0) { // NO valid ICC profile if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace m_nComponents = pAlterCS->CountComponents(); m_pAlterCS = pAlterCS; m_bOwn = TRUE; } else { // No valid alternative colorspace pAlterCS->ReleaseCS(); int32_t nDictComponents = pDict ? pDict->GetInteger(FX_BSTRC("N")) : 0; if (nDictComponents != 1 && nDictComponents != 3 && nDictComponents != 4) { return FALSE; } m_nComponents = nDictComponents; } } else { // Using sRGB if (pAlterCS->CountComponents() != m_nComponents) { pAlterCS->ReleaseCS(); } else { m_pAlterCS = pAlterCS; m_bOwn = TRUE; } } } } if (!m_pAlterCS) { if (m_nComponents == 1) { m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY); } else if (m_nComponents == 3) { m_pAlterCS = GetStockCS(PDFCS_DEVICERGB); } else if (m_nComponents == 4) { m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK); } } } CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range")); m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2); for (int i = 0; i < m_nComponents * 2; i ++) { if (pRanges) { m_pRanges[i] = pRanges->GetNumber(i); } else if (i % 2) { m_pRanges[i] = 1.0f; } else { m_pRanges[i] = 0; } } return TRUE; }
CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict, FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix) { if (pSMaskDict == NULL) { return NULL; } CFX_DIBitmap* pMask = NULL; int width = pClipRect->right - pClipRect->left; int height = pClipRect->bottom - pClipRect->top; FX_BOOL bLuminosity = FALSE; bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha"); CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G")); if (pGroup == NULL) { return NULL; } CPDF_Function* pFunc = NULL; CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR")); if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || pFuncObj->GetType() == PDFOBJ_STREAM)) { pFunc = CPDF_Function::Load(pFuncObj); } CFX_AffineMatrix matrix = *pMatrix; matrix.TranslateI(-pClipRect->left, -pClipRect->top); CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup); form.ParseContent(NULL, NULL, NULL, NULL); CFX_FxgeDevice bitmap_device; #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) { return NULL; } #else if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) { return NULL; } #endif CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap(); CPDF_Object* pCSObj = NULL; CPDF_ColorSpace* pCS = NULL; if (bLuminosity) { CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC")); FX_ARGB back_color = 0xff000000; if (pBC) { pCSObj = pGroup->GetDict()->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS")); pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj); if (pCS) { FX_FLOAT R, G, B; FX_DWORD num_floats = 8; if (pCS->CountComponents() > (FX_INT32)num_floats) { num_floats = (FX_DWORD)pCS->CountComponents(); } CFX_FixedBufGrow<FX_FLOAT, 8> float_array(num_floats); FX_FLOAT* pFloats = float_array; FXSYS_memset32(pFloats, 0, num_floats * sizeof(FX_FLOAT)); int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount(); for (int i = 0; i < count; i ++) { pFloats[i] = pBC->GetNumber(i); } pCS->GetRGB(pFloats, R, G, B); back_color = 0xff000000 | ((FX_INT32)(R * 255) << 16) | ((FX_INT32)(G * 255) << 8) | (FX_INT32)(B * 255); m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); } } bitmap.Clear(back_color); } else { bitmap.Clear(0); } CPDF_Dictionary* pFormResource = NULL; if (form.m_pFormDict) { pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources")); } CPDF_RenderOptions options; options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA; CPDF_RenderStatus status; status.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity); status.RenderObjectList(&form, &matrix); pMask = FX_NEW CFX_DIBitmap; if (!pMask->Create(width, height, FXDIB_8bppMask)) { delete pMask; return NULL; } FX_LPBYTE dest_buf = pMask->GetBuffer(); int dest_pitch = pMask->GetPitch(); FX_LPBYTE src_buf = bitmap.GetBuffer(); int src_pitch = bitmap.GetPitch(); FX_LPBYTE pTransfer = FX_Alloc(FX_BYTE, 256); if (pFunc) { CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs()); for (int i = 0; i < 256; i ++) { FX_FLOAT input = (FX_FLOAT)i / 255.0f; int nresult; pFunc->Call(&input, 1, results, nresult); pTransfer[i] = FXSYS_round(results[0] * 255); } } else { for (int i = 0; i < 256; i ++) { pTransfer[i] = i; } } if (bLuminosity) { int Bpp = bitmap.GetBPP() / 8; for (int row = 0; row < height; row ++) { FX_LPBYTE dest_pos = dest_buf + row * dest_pitch; FX_LPBYTE src_pos = src_buf + row * src_pitch; for (int col = 0; col < width; col ++) { *dest_pos ++ = pTransfer[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)]; src_pos += Bpp; } } } else if (pFunc) { int size = dest_pitch * height; for (int i = 0; i < size; i ++) { dest_buf[i] = pTransfer[src_buf[i]]; } } else { FXSYS_memcpy32(dest_buf, src_buf, dest_pitch * height); } if (pFunc) { delete pFunc; } FX_Free(pTransfer); return pMask; }
std::unique_ptr<CPDF_Stream> CPDF_StreamParser::ReadInlineStream( CPDF_Document* pDoc, std::unique_ptr<CPDF_Dictionary> pDict, const CPDF_Object* pCSObj) { if (m_Pos < m_pBuf.size() && PDFCharIsWhitespace(m_pBuf[m_Pos])) m_Pos++; if (m_Pos == m_pBuf.size()) return nullptr; ByteString Decoder; CPDF_Dictionary* pParam = nullptr; CPDF_Object* pFilter = pDict->GetDirectObjectFor("Filter"); if (pFilter) { if (CPDF_Array* pArray = pFilter->AsArray()) { Decoder = pArray->GetStringAt(0); CPDF_Array* pParams = pDict->GetArrayFor(pdfium::stream::kDecodeParms); if (pParams) pParam = pParams->GetDictAt(0); } else { Decoder = pFilter->GetString(); pParam = pDict->GetDictFor(pdfium::stream::kDecodeParms); } } uint32_t width = pDict->GetIntegerFor("Width"); uint32_t height = pDict->GetIntegerFor("Height"); uint32_t OrigSize = 0; if (pCSObj) { uint32_t bpc = pDict->GetIntegerFor("BitsPerComponent"); uint32_t nComponents = 1; CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj, nullptr); if (pCS) { nComponents = pCS->CountComponents(); pDoc->GetPageData()->ReleaseColorSpace(pCSObj); } else { nComponents = 3; } uint32_t pitch = width; if (bpc && pitch > INT_MAX / bpc) return nullptr; pitch *= bpc; if (nComponents && pitch > INT_MAX / nComponents) return nullptr; pitch *= nComponents; if (pitch > INT_MAX - 7) return nullptr; pitch += 7; pitch /= 8; OrigSize = pitch; } else { if (width > INT_MAX - 7) return nullptr; OrigSize = ((width + 7) / 8); } if (height && OrigSize > INT_MAX / height) return nullptr; OrigSize *= height; std::unique_ptr<uint8_t, FxFreeDeleter> pData; uint32_t dwStreamSize; if (Decoder.IsEmpty()) { if (OrigSize > m_pBuf.size() - m_Pos) OrigSize = m_pBuf.size() - m_Pos; pData.reset(FX_Alloc(uint8_t, OrigSize)); auto copy_span = m_pBuf.subspan(m_Pos, OrigSize); memcpy(pData.get(), copy_span.data(), copy_span.size()); dwStreamSize = OrigSize; m_Pos += OrigSize; } else { dwStreamSize = DecodeInlineStream(m_pBuf.subspan(m_Pos), width, height, Decoder, pParam, OrigSize); if (static_cast<int>(dwStreamSize) < 0) return nullptr; uint32_t dwSavePos = m_Pos; m_Pos += dwStreamSize; while (1) { uint32_t dwPrevPos = m_Pos; CPDF_StreamParser::SyntaxType type = ParseNextElement(); if (type == CPDF_StreamParser::EndOfData) break; if (type != CPDF_StreamParser::Keyword) { dwStreamSize += m_Pos - dwPrevPos; continue; } if (GetWord() == "EI") { m_Pos = dwPrevPos; break; } dwStreamSize += m_Pos - dwPrevPos; } m_Pos = dwSavePos; pData.reset(FX_Alloc(uint8_t, dwStreamSize)); auto copy_span = m_pBuf.subspan(m_Pos, dwStreamSize); memcpy(pData.get(), copy_span.data(), copy_span.size()); m_Pos += dwStreamSize; } pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(dwStreamSize)); return pdfium::MakeUnique<CPDF_Stream>(std::move(pData), dwStreamSize, std::move(pDict)); }