CPDF_ContentParser::Stage CPDF_ContentParser::PrepareContent() { m_CurrentOffset = 0; if (m_StreamArray.empty()) { m_pData.Reset(m_pSingleStream->GetData()); m_Size = m_pSingleStream->GetSize(); return Stage::kParse; } FX_SAFE_UINT32 safeSize = 0; for (const auto& stream : m_StreamArray) { m_StreamSegmentOffsets.push_back(safeSize.ValueOrDie()); safeSize += stream->GetSize(); safeSize += 1; if (!safeSize.IsValid()) return Stage::kComplete; } m_Size = safeSize.ValueOrDie(); m_pData.Reset( std::unique_ptr<uint8_t, FxFreeDeleter>(FX_Alloc(uint8_t, m_Size))); uint32_t pos = 0; for (const auto& stream : m_StreamArray) { memcpy(m_pData.Get() + pos, stream->GetData(), stream->GetSize()); pos += stream->GetSize(); m_pData.Get()[pos++] = ' '; } m_StreamArray.clear(); return Stage::kParse; }
bool CCodec_RLScanlineDecoder::Create(const uint8_t* src_buf, uint32_t src_size, int width, int height, int nComps, int bpc) { m_pSrcBuf = src_buf; m_SrcSize = src_size; m_OutputWidth = m_OrigWidth = width; m_OutputHeight = m_OrigHeight = height; m_nComps = nComps; m_bpc = bpc; // Aligning the pitch to 4 bytes requires an integer overflow check. FX_SAFE_UINT32 pitch = width; pitch *= nComps; pitch *= bpc; pitch += 31; pitch /= 32; pitch *= 4; if (!pitch.IsValid()) { return false; } m_Pitch = pitch.ValueOrDie(); // Overflow should already have been checked before this is called. m_dwLineBytes = (static_cast<uint32_t>(width) * nComps * bpc + 7) / 8; m_pScanline = FX_Alloc(uint8_t, m_Pitch); return CheckDestSize(); }
FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { CPDF_Stream* pStream = pObj->AsStream(); if (!pStream) return false; CPDF_Dictionary* pDict = pStream->GetDict(); CPDF_Array* pSize = pDict->GetArrayBy("Size"); CPDF_Array* pEncode = pDict->GetArrayBy("Encode"); CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); if (!IsValidBitsPerSample(m_nBitsPerSample)) return FALSE; m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); m_pSampleStream.reset(new CPDF_StreamAcc); m_pSampleStream->LoadAllData(pStream, FALSE); FX_SAFE_UINT32 nTotalSampleBits = 1; m_EncodeInfo.resize(m_nInputs); for (uint32_t i = 0; i < m_nInputs; i++) { m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; if (!pSize && i == 0) m_EncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); nTotalSampleBits *= m_EncodeInfo[i].sizes; if (pEncode) { m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); } else { m_EncodeInfo[i].encode_min = 0; m_EncodeInfo[i].encode_max = m_EncodeInfo[i].sizes == 1 ? 1 : (FX_FLOAT)m_EncodeInfo[i].sizes - 1; } } nTotalSampleBits *= m_nBitsPerSample; nTotalSampleBits *= m_nOutputs; FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; nTotalSampleBytes += 7; nTotalSampleBytes /= 8; if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { return FALSE; } m_DecodeInfo.resize(m_nOutputs); for (uint32_t i = 0; i < m_nOutputs; i++) { if (pDecode) { m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); } else { m_DecodeInfo[i].decode_min = m_pRanges[i * 2]; m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; } } return TRUE; }
int CPDF_DIBSource::ContinueToLoadMask() { if (m_bImageMask) { m_bpp = 1; m_bpc = 1; m_nComponents = 1; m_AlphaFlag = 1; } else if (m_bpc * m_nComponents == 1) { m_bpp = 1; } else if (m_bpc * m_nComponents <= 8) { m_bpp = 8; } else { m_bpp = 24; } if (!m_bpc || !m_nComponents) { return 0; } FX_SAFE_UINT32 pitch = CalculatePitch32(m_bpp, m_Width); if (!pitch.IsValid()) { return 0; } m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); if (m_pColorSpace && m_bStdCS) { m_pColorSpace->EnableStdConversion(true); } LoadPalette(); if (m_bColorKey) { m_bpp = 32; m_AlphaFlag = 2; pitch = CalculatePitch32(m_bpp, m_Width); if (!pitch.IsValid()) { return 0; } m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); } m_Pitch = pitch.ValueOrDie(); return 1; }
bool CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream) { if (!pStream) return false; m_pDocument = pDoc; m_pDict = pStream->GetDict(); if (!m_pDict) return false; m_pStream = pStream; m_Width = m_pDict->GetIntegerFor("Width"); m_Height = m_pDict->GetIntegerFor("Height"); if (m_Width <= 0 || m_Height <= 0 || m_Width > kMaxImageDimension || m_Height > kMaxImageDimension) { return false; } m_GroupFamily = 0; m_bLoadMask = false; if (!LoadColorInfo(nullptr, nullptr)) return false; if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) return false; FX_SAFE_UINT32 src_size = CalculatePitch8(m_bpc, m_nComponents, m_Width) * m_Height; if (!src_size.IsValid()) return false; m_pStreamAcc = pdfium::MakeUnique<CPDF_StreamAcc>(); m_pStreamAcc->LoadAllData(pStream, false, src_size.ValueOrDie(), true); if (m_pStreamAcc->GetSize() == 0 || !m_pStreamAcc->GetData()) return false; if (!CreateDecoder()) return false; if (m_bImageMask) { m_bpp = 1; m_bpc = 1; m_nComponents = 1; m_AlphaFlag = 1; } else if (m_bpc * m_nComponents == 1) { m_bpp = 1; } else if (m_bpc * m_nComponents <= 8) { m_bpp = 8; } else { m_bpp = 24; } FX_SAFE_UINT32 pitch = CalculatePitch32(m_bpp, m_Width); if (!pitch.IsValid()) return false; m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); LoadPalette(); if (m_bColorKey) { m_bpp = 32; m_AlphaFlag = 2; pitch = CalculatePitch32(m_bpp, m_Width); if (!pitch.IsValid()) return false; m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); } m_Pitch = pitch.ValueOrDie(); return true; }
void CPDF_ContentParser::Continue(IFX_Pause* pPause) { int steps = 0; while (m_Status == ToBeContinued) { if (m_InternalStage == STAGE_GETCONTENT) { if (m_CurrentOffset == m_nStreams) { if (!m_StreamArray.empty()) { FX_SAFE_UINT32 safeSize = 0; for (const auto& stream : m_StreamArray) { safeSize += stream->GetSize(); safeSize += 1; } if (!safeSize.IsValid()) { m_Status = Done; return; } m_Size = safeSize.ValueOrDie(); m_pData = FX_Alloc(uint8_t, m_Size); uint32_t pos = 0; for (const auto& stream : m_StreamArray) { FXSYS_memcpy(m_pData + pos, stream->GetData(), stream->GetSize()); pos += stream->GetSize(); m_pData[pos++] = ' '; } m_StreamArray.clear(); } else { m_pData = (uint8_t*)m_pSingleStream->GetData(); m_Size = m_pSingleStream->GetSize(); } m_InternalStage = STAGE_PARSE; m_CurrentOffset = 0; } else { CPDF_Array* pContent = m_pObjectHolder->m_pFormDict->GetArrayFor("Contents"); m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc); CPDF_Stream* pStreamObj = ToStream( pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr); m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, false); m_CurrentOffset++; } } if (m_InternalStage == STAGE_PARSE) { if (!m_pParser) { m_pParser.reset(new CPDF_StreamContentParser( m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources, nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources, &m_pObjectHolder->m_BBox, nullptr, 0)); m_pParser->GetCurStates()->m_ColorState.SetDefault(); } if (m_CurrentOffset >= m_Size) { m_InternalStage = STAGE_CHECKCLIP; } else { m_CurrentOffset += m_pParser->Parse(m_pData + m_CurrentOffset, m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); } } if (m_InternalStage == STAGE_CHECKCLIP) { if (m_pType3Char) { m_pType3Char->m_bColored = m_pParser->IsColored(); m_pType3Char->m_Width = FXSYS_round(m_pParser->GetType3Data()[0] * 1000); m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->GetType3Data()[2] * 1000); m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->GetType3Data()[3] * 1000); m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->GetType3Data()[4] * 1000); m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->GetType3Data()[5] * 1000); } for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) { if (!pObj->m_ClipPath) 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->IsShading()) 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(); } m_Status = Done; return; } steps++; if (pPause && pPause->NeedToPauseNow()) break; } }
void sycc420_to_rgb(opj_image_t* img) { if (!sycc420_size_is_valid(img)) return; OPJ_UINT32 prec = img->comps[0].prec; if (!prec) return; OPJ_UINT32 offset = 1 << (prec - 1); OPJ_UINT32 upb = (1 << prec) - 1; OPJ_UINT32 yw = img->comps[0].w; OPJ_UINT32 yh = img->comps[0].h; OPJ_UINT32 cbw = img->comps[1].w; OPJ_UINT32 cbh = img->comps[1].h; OPJ_UINT32 crw = img->comps[2].w; bool extw = sycc420_must_extend_cbcr(yw, cbw); bool exth = sycc420_must_extend_cbcr(yh, cbh); FX_SAFE_UINT32 safeSize = yw; safeSize *= yh; if (!safeSize.IsValid()) return; int* r = FX_Alloc(int, safeSize.ValueOrDie()); int* g = FX_Alloc(int, safeSize.ValueOrDie()); int* b = FX_Alloc(int, safeSize.ValueOrDie()); int* d0 = r; int* d1 = g; int* d2 = b; const int* y = img->comps[0].data; const int* cb = img->comps[1].data; const int* cr = img->comps[2].data; if (!y || !cb || !cr) return; const int* ny = nullptr; int* nr = nullptr; int* ng = nullptr; int* nb = nullptr; OPJ_UINT32 i = 0; OPJ_UINT32 j = 0; for (i = 0; i < (yh & ~(OPJ_UINT32)1); i += 2) { ny = y + yw; nr = r + yw; ng = g + yw; nb = b + yw; for (j = 0; j < (yw & ~(OPJ_UINT32)1); j += 2) { sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); ++y; ++r; ++g; ++b; sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); ++y; ++r; ++g; ++b; sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb); ++ny; ++nr; ++ng; ++nb; sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb); ++ny; ++nr; ++ng; ++nb; ++cb; ++cr; } if (j < yw) { if (extw) { --cb; --cr; } sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); ++y; ++r; ++g; ++b; sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb); ++ny; ++nr; ++ng; ++nb; ++cb; ++cr; } y += yw; r += yw; g += yw; b += yw; } if (i < yh) { if (exth) { cb -= cbw; cr -= crw; } for (j = 0; j < (yw & ~(OPJ_UINT32)1); j += 2) { sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); ++y; ++r; ++g; ++b; sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); ++y; ++r; ++g; ++b; ++cb; ++cr; } if (j < yw) { if (extw) { --cb; --cr; } sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b); } } FX_Free(img->comps[0].data); img->comps[0].data = d0; FX_Free(img->comps[1].data); img->comps[1].data = d1; FX_Free(img->comps[2].data); img->comps[2].data = d2; img->comps[1].w = yw; img->comps[1].h = yh; img->comps[2].w = yw; img->comps[2].h = yh; img->comps[1].w = yw; img->comps[1].h = yh; img->comps[2].w = yw; img->comps[2].h = yh; img->comps[1].dx = img->comps[0].dx; img->comps[2].dx = img->comps[0].dx; img->comps[1].dy = img->comps[0].dy; img->comps[2].dy = img->comps[0].dy; }