FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { if (pObj->GetType() != PDFOBJ_STREAM) { return FALSE; } CPDF_Stream* pStream = (CPDF_Stream*)pObj; CPDF_Dictionary* pDict = pStream->GetDict(); CPDF_Array* pSize = pDict->GetArray(FX_BSTRC("Size")); CPDF_Array* pEncode = pDict->GetArray(FX_BSTRC("Encode")); CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode")); m_nBitsPerSample = pDict->GetInteger(FX_BSTRC("BitsPerSample")); if (m_nBitsPerSample > 32) { return FALSE; } m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); m_pSampleStream = new CPDF_StreamAcc; m_pSampleStream->LoadAllData(pStream, FALSE); m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs); FX_SAFE_DWORD nTotalSampleBits = 1; for (int i = 0; i < m_nInputs; i++) { m_pEncodeInfo[i].sizes = pSize ? pSize->GetInteger(i) : 0; if (!pSize && i == 0) { m_pEncodeInfo[i].sizes = pDict->GetInteger(FX_BSTRC("Size")); } nTotalSampleBits *= m_pEncodeInfo[i].sizes; if (pEncode) { m_pEncodeInfo[i].encode_min = pEncode->GetFloat(i * 2); m_pEncodeInfo[i].encode_max = pEncode->GetFloat(i * 2 + 1); } else { m_pEncodeInfo[i].encode_min = 0; if (m_pEncodeInfo[i].sizes == 1) { m_pEncodeInfo[i].encode_max = 1; } else { m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; } } } nTotalSampleBits *= m_nBitsPerSample; nTotalSampleBits *= m_nOutputs; FX_SAFE_DWORD nTotalSampleBytes = nTotalSampleBits; nTotalSampleBytes += 7; nTotalSampleBytes /= 8; if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { return FALSE; } m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); for (int i = 0; i < m_nOutputs; i++) { if (pDecode) { m_pDecodeInfo[i].decode_min = pDecode->GetFloat(2 * i); m_pDecodeInfo[i].decode_max = pDecode->GetFloat(2 * i + 1); } else { m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; } } return TRUE; }
FX_BOOL CCodec_RLScanlineDecoder::Create(const uint8_t* src_buf, FX_DWORD 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; m_bColorTransformed = FALSE; m_DownScale = 1; // Aligning the pitch to 4 bytes requires an integer overflow check. FX_SAFE_DWORD 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<FX_DWORD>(width) * nComps * bpc + 7) / 8; m_pScanline = FX_Alloc(uint8_t, m_Pitch); return CheckDestSize(); }
void sycc420_to_rgb(opj_image_t* img) { 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; OPJ_UINT32 crh = img->comps[2].h; if (cbw != crw || cbh != crh) return; if (!sycc420_size_is_valid(yw, cbw) || !sycc420_size_is_valid(yh, cbh)) return; bool extw = sycc420_must_extend_cbcr(yw, cbw); bool exth = sycc420_must_extend_cbcr(yh, cbh); FX_SAFE_DWORD 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; 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; }