summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJane Liu <janeliulwq@google.com>2017-08-09 14:09:34 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-08-09 18:35:54 +0000
commitbe63ab97e0385b4024ef84fda79fc84dc111ab23 (patch)
treebd56d9e46aefc7f9617f27da624831df1abe67b0
parentd24b97ee1d065eff482355ea3ff82be59bb528b1 (diff)
downloadpdfium-be63ab97e0385b4024ef84fda79fc84dc111ab23.tar.xz
API and test for retrieving image filters from image objects
Added FPDFImageObj_GetImageFilterCount() and FPDFImageObj_GetImageFilters() for retrieving image filters of image objects. * Added a corresponding embedder test. * Changed the filter of an image object in embedded_image.pdf from DCTDecode to ASCIIHexDecode + DCTDecode, so we have a test case for images with more than one filter. Bug=pdfium:677 Change-Id: I398790a2cad33fea4ca16a0eb0889c04caa6b962 Reviewed-on: https://pdfium-review.googlesource.com/10130 Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org> Commit-Queue: Jane Liu <janeliulwq@google.com>
-rw-r--r--fpdfsdk/fpdfedit_embeddertest.cpp46
-rw-r--r--fpdfsdk/fpdfeditimg.cpp45
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c2
-rw-r--r--public/fpdf_edit.h25
-rw-r--r--testing/resources/embedded_images.pdfbin27089 -> 34279 bytes
5 files changed, 118 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index c381b25efa..e62ef2149b 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -1038,3 +1038,49 @@ TEST_F(FPDFEditEmbeddertest, DestroyPageObject) {
// There should be no memory leaks with a call to FPDFPageObj_Destroy().
FPDFPageObj_Destroy(rect);
}
+
+TEST_F(FPDFEditEmbeddertest, GetImageFilters) {
+ EXPECT_TRUE(OpenDocument("embedded_images.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Verify that retrieving the filter of a non-image object would fail.
+ FPDF_PAGEOBJECT obj = FPDFPage_GetObject(page, 32);
+ ASSERT_NE(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(obj));
+ ASSERT_EQ(0, FPDFImageObj_GetImageFilterCount(obj));
+ EXPECT_EQ(0u, FPDFImageObj_GetImageFilter(obj, 0, nullptr, 0));
+
+ // Verify the returned filter string for an image object with a single filter.
+ obj = FPDFPage_GetObject(page, 33);
+ ASSERT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(obj));
+ ASSERT_EQ(1, FPDFImageObj_GetImageFilterCount(obj));
+ unsigned long len = FPDFImageObj_GetImageFilter(obj, 0, nullptr, 0);
+ std::vector<char> buf(len);
+ EXPECT_EQ(24u, FPDFImageObj_GetImageFilter(obj, 0, buf.data(), len));
+ EXPECT_STREQ(L"FlateDecode",
+ GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
+ .c_str());
+ EXPECT_EQ(0u, FPDFImageObj_GetImageFilter(obj, 1, nullptr, 0));
+
+ // Verify all the filters for an image object with a list of filters.
+ obj = FPDFPage_GetObject(page, 38);
+ ASSERT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(obj));
+ ASSERT_EQ(2, FPDFImageObj_GetImageFilterCount(obj));
+ len = FPDFImageObj_GetImageFilter(obj, 0, nullptr, 0);
+ buf.clear();
+ buf.resize(len);
+ EXPECT_EQ(30u, FPDFImageObj_GetImageFilter(obj, 0, buf.data(), len));
+ EXPECT_STREQ(L"ASCIIHexDecode",
+ GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
+ .c_str());
+
+ len = FPDFImageObj_GetImageFilter(obj, 1, nullptr, 0);
+ buf.clear();
+ buf.resize(len);
+ EXPECT_EQ(20u, FPDFImageObj_GetImageFilter(obj, 1, buf.data(), len));
+ EXPECT_STREQ(L"DCTDecode",
+ GetPlatformWString(reinterpret_cast<unsigned short*>(buf.data()))
+ .c_str());
+
+ UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp
index 0d0c54604b..b4254e97c6 100644
--- a/fpdfsdk/fpdfeditimg.cpp
+++ b/fpdfsdk/fpdfeditimg.cpp
@@ -10,6 +10,8 @@
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_imageobject.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
#include "fpdfsdk/fsdk_define.h"
#include "third_party/base/ptr_util.h"
@@ -179,3 +181,46 @@ FPDFImageObj_GetImageDataRaw(FPDF_PAGEOBJECT image_object,
return len;
}
+
+DLLEXPORT int STDCALL
+FPDFImageObj_GetImageFilterCount(FPDF_PAGEOBJECT image_object) {
+ CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
+ if (!pObj || !pObj->IsImage())
+ return 0;
+
+ CFX_RetainPtr<CPDF_Image> pImg = pObj->AsImage()->GetImage();
+ if (!pImg)
+ return 0;
+
+ CPDF_Dictionary* pDict = pImg->GetDict();
+ CPDF_Object* pFilter = pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
+ if (!pFilter)
+ return 0;
+
+ if (pFilter->IsArray())
+ return pFilter->AsArray()->GetCount();
+ if (pFilter->IsName())
+ return 1;
+
+ return 0;
+}
+
+DLLEXPORT unsigned long STDCALL
+FPDFImageObj_GetImageFilter(FPDF_PAGEOBJECT image_object,
+ int index,
+ void* buffer,
+ unsigned long buflen) {
+ if (index < 0 || index >= FPDFImageObj_GetImageFilterCount(image_object))
+ return 0;
+
+ CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
+ CPDF_Object* pFilter =
+ pObj->AsImage()->GetImage()->GetDict()->GetDirectObjectFor("Filter");
+ CFX_WideString wsFilters;
+ if (pFilter->IsName())
+ wsFilters = pFilter->AsName()->GetUnicodeText();
+ else
+ wsFilters = pFilter->AsArray()->GetUnicodeTextAt(index);
+
+ return Utf16EncodeMaybeCopyAndReturnLength(wsFilters, buffer, buflen);
+}
diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c
index ef5b804baa..8276eb64b7 100644
--- a/fpdfsdk/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -136,6 +136,8 @@ int CheckPDFiumCApi() {
CHK(FPDFImageObj_GetBitmap);
CHK(FPDFImageObj_GetImageDataDecoded);
CHK(FPDFImageObj_GetImageDataRaw);
+ CHK(FPDFImageObj_GetImageFilterCount);
+ CHK(FPDFImageObj_GetImageFilter);
CHK(FPDFPageObj_CreateNewPath);
CHK(FPDFPageObj_CreateNewRect);
CHK(FPDFPath_SetStrokeColor);
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index aab48af3f1..54127d80ea 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -336,6 +336,31 @@ FPDFImageObj_GetImageDataRaw(FPDF_PAGEOBJECT image_object,
void* buffer,
unsigned long buflen);
+// Get the number of filters (i.e. decoders) of the image in |image_object|.
+//
+// image_object - handle to an image object.
+//
+// Returns the number of |image_object|'s filters.
+DLLEXPORT int STDCALL
+FPDFImageObj_GetImageFilterCount(FPDF_PAGEOBJECT image_object);
+
+// Get the filter at |index| of |image_object|'s list of filters. Note that the
+// filters need to be applied in order, i.e. the first filter should be applied
+// first, then the second, etc. |buffer| is only modified if |buflen| is longer
+// than the length of the filter string.
+//
+// image_object - handle to an image object.
+// index - the index of the filter requested.
+// buffer - buffer for holding filter string, encoded in UTF16-LE.
+// buflen - length of the buffer.
+//
+// Returns the length of the filter string.
+DLLEXPORT unsigned long STDCALL
+FPDFImageObj_GetImageFilter(FPDF_PAGEOBJECT image_object,
+ int index,
+ void* buffer,
+ unsigned long buflen);
+
// Create a new path object at an initial position.
//
// x - initial horizontal position.
diff --git a/testing/resources/embedded_images.pdf b/testing/resources/embedded_images.pdf
index 81845822a4..82adbeaa4c 100644
--- a/testing/resources/embedded_images.pdf
+++ b/testing/resources/embedded_images.pdf
Binary files differ