From 548334e57cae1039824d3db97bab5348fbe674e2 Mon Sep 17 00:00:00 2001 From: Jane Liu Date: Thu, 3 Aug 2017 16:33:40 -0400 Subject: APIs and tests for retrieving raw/decoded data from image objects Added FPDFImageObj_GetImageDataDecoded() for retrieving the uncompressed data of an image, and FPDFImageObj_GetImageDataRaw() for retrieving the raw data of an image. * Refactored out DecodeStreamMaybeCopyAndReturnLength(), which is used to decode both attachment data and image data. * Within DecodeStreamMaybeCopyAndReturnLength(), used a different decoder function which takes care of multiple filters if exist. As a result, CPDF_StreamParser::DecodeInlineStream() which was made static previously is now moved back into namespace. Bug=pdfium:677 Change-Id: I22a22c99acaca98ef8c15f88911f2646a2c854d5 Reviewed-on: https://pdfium-review.googlesource.com/9811 Commit-Queue: Jane Liu Reviewed-by: Lei Zhang --- fpdfsdk/fpdfview.cpp | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) (limited to 'fpdfsdk/fpdfview.cpp') diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp index 5aa80139ae..57e4806d39 100644 --- a/fpdfsdk/fpdfview.cpp +++ b/fpdfsdk/fpdfview.cpp @@ -357,10 +357,48 @@ CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap) { unsigned long Utf16EncodeMaybeCopyAndReturnLength(const CFX_WideString& text, void* buffer, unsigned long buflen) { - CFX_ByteString encodedText = text.UTF16LE_Encode(); - unsigned long len = encodedText.GetLength(); + CFX_ByteString encoded_text = text.UTF16LE_Encode(); + unsigned long len = encoded_text.GetLength(); if (buffer && len <= buflen) - memcpy(buffer, encodedText.c_str(), len); + memcpy(buffer, encoded_text.c_str(), len); + return len; +} + +unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream, + void* buffer, + unsigned long buflen) { + ASSERT(stream); + uint8_t* data = stream->GetRawData(); + uint32_t len = stream->GetRawSize(); + CPDF_Dictionary* dict = stream->GetDict(); + CPDF_Object* decoder = dict ? dict->GetDirectObjectFor("Filter") : nullptr; + if (decoder && (decoder->IsArray() || decoder->IsName())) { + // Decode the stream if one or more stream filters are specified. + uint8_t* decoded_data = nullptr; + uint32_t decoded_len = 0; + CFX_ByteString dummy_last_decoder; + CPDF_Dictionary* dummy_last_param; + if (PDF_DataDecode(data, len, dict, dict->GetIntegerFor("DL"), false, + &decoded_data, &decoded_len, &dummy_last_decoder, + &dummy_last_param)) { + if (buffer && buflen >= decoded_len) + memcpy(buffer, decoded_data, decoded_len); + + // Free the buffer for the decoded data if it was allocated by + // PDF_DataDecode(). Note that for images with a single image-specific + // filter, |decoded_data| is directly assigned to be |data|, so + // |decoded_data| does not need to be freed. + if (decoded_data != data) + FX_Free(decoded_data); + + return decoded_len; + } + } + // Copy the raw data and return its length if there is no valid filter + // specified or if decoding failed. + if (buffer && buflen >= len) + memcpy(buffer, data, len); + return len; } -- cgit v1.2.3