Make FPDFImageObj_SetBitmap() behavior match comments.
This makes the behavior match FPDFImageObj_LoadJpegFile() as well. Add
unit test. Also add ScopedFPDFPageObject and use it in the test.
Change-Id: I7d149cf939857ed1e4d087d62bbc35098cbaa7b3
Reviewed-on: https://pdfium-review.googlesource.com/c/48456
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index eae3f32..fccd9cb 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -160,9 +160,6 @@
int count,
FPDF_PAGEOBJECT image_object,
FPDF_BITMAP bitmap) {
- if (!pages)
- return false;
-
CPDF_ImageObject* pImgObj = CPDFImageObjectFromFPDFPageObject(image_object);
if (!pImgObj)
return false;
@@ -170,11 +167,14 @@
if (!bitmap)
return false;
- for (int index = 0; index < count; index++) {
- CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
- if (pPage)
- pImgObj->GetImage()->ResetCache(pPage);
+ if (pages) {
+ for (int index = 0; index < count; index++) {
+ CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
+ if (pPage)
+ pImgObj->GetImage()->ResetCache(pPage);
+ }
}
+
RetainPtr<CFX_DIBitmap> holder(CFXDIBitmapFromFPDFBitmap(bitmap));
pImgObj->GetImage()->SetImage(holder);
pImgObj->CalcBoundingBox();
diff --git a/fpdfsdk/fpdf_editimg_unittest.cpp b/fpdfsdk/fpdf_editimg_unittest.cpp
index 16e464d..fa04758 100644
--- a/fpdfsdk/fpdf_editimg_unittest.cpp
+++ b/fpdfsdk/fpdf_editimg_unittest.cpp
@@ -5,6 +5,7 @@
#include "public/fpdf_edit.h"
#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "public/cpp/fpdf_scopers.h"
#include "testing/gtest/include/gtest/gtest.h"
class PDFEditImgTest : public testing::Test {
@@ -70,6 +71,20 @@
FPDF_CloseDocument(doc);
}
+TEST_F(PDFEditImgTest, SetBitmap) {
+ ScopedFPDFDocument doc(FPDF_CreateNewDocument());
+ ScopedFPDFPage page(FPDFPage_New(doc.get(), 0, 100, 100));
+ ScopedFPDFPageObject image(FPDFPageObj_NewImageObj(doc.get()));
+ ScopedFPDFBitmap bitmap(FPDFBitmap_Create(100, 100, 0));
+
+ FPDF_PAGE page_ptr = page.get();
+ FPDF_PAGE* pages = &page_ptr;
+ EXPECT_TRUE(FPDFImageObj_SetBitmap(nullptr, 1, image.get(), bitmap.get()));
+ EXPECT_TRUE(FPDFImageObj_SetBitmap(pages, 0, image.get(), bitmap.get()));
+ EXPECT_FALSE(FPDFImageObj_SetBitmap(pages, 1, nullptr, bitmap.get()));
+ EXPECT_FALSE(FPDFImageObj_SetBitmap(pages, 1, image.get(), nullptr));
+}
+
TEST_F(PDFEditImgTest, GetSetImageMatrix) {
FPDF_DOCUMENT doc = FPDF_CreateNewDocument();
FPDF_PAGEOBJECT image = FPDFPageObj_NewImageObj(doc);
diff --git a/public/cpp/fpdf_deleters.h b/public/cpp/fpdf_deleters.h
index d9d95cd..5275381 100644
--- a/public/cpp/fpdf_deleters.h
+++ b/public/cpp/fpdf_deleters.h
@@ -31,16 +31,16 @@
inline void operator()(FPDF_DOCUMENT doc) { FPDF_CloseDocument(doc); }
};
+struct FPDFFontDeleter {
+ inline void operator()(FPDF_FONT font) { FPDFFont_Close(font); }
+};
+
struct FPDFFormHandleDeleter {
inline void operator()(FPDF_FORMHANDLE form) {
FPDFDOC_ExitFormFillEnvironment(form);
}
};
-struct FPDFTextPageDeleter {
- inline void operator()(FPDF_TEXTPAGE text) { FPDFText_ClosePage(text); }
-};
-
struct FPDFPageDeleter {
inline void operator()(FPDF_PAGE page) { FPDF_ClosePage(page); }
};
@@ -51,12 +51,18 @@
}
};
+struct FPDFPageObjectDeleter {
+ inline void operator()(FPDF_PAGEOBJECT object) {
+ FPDFPageObj_Destroy(object);
+ }
+};
+
struct FPDFStructTreeDeleter {
inline void operator()(FPDF_STRUCTTREE tree) { FPDF_StructTree_Close(tree); }
};
-struct FPDFFontDeleter {
- inline void operator()(FPDF_FONT font) { FPDFFont_Close(font); }
+struct FPDFTextPageDeleter {
+ inline void operator()(FPDF_TEXTPAGE text) { FPDFText_ClosePage(text); }
};
#endif // PUBLIC_CPP_FPDF_DELETERS_H_
diff --git a/public/cpp/fpdf_scopers.h b/public/cpp/fpdf_scopers.h
index 3601f47..3fe63e3 100644
--- a/public/cpp/fpdf_scopers.h
+++ b/public/cpp/fpdf_scopers.h
@@ -33,14 +33,13 @@
std::unique_ptr<std::remove_pointer<FPDF_DOCUMENT>::type,
FPDFDocumentDeleter>;
+using ScopedFPDFFont =
+ std::unique_ptr<std::remove_pointer<FPDF_FONT>::type, FPDFFontDeleter>;
+
using ScopedFPDFFormHandle =
std::unique_ptr<std::remove_pointer<FPDF_FORMHANDLE>::type,
FPDFFormHandleDeleter>;
-using ScopedFPDFTextPage =
- std::unique_ptr<std::remove_pointer<FPDF_TEXTPAGE>::type,
- FPDFTextPageDeleter>;
-
using ScopedFPDFPage =
std::unique_ptr<std::remove_pointer<FPDF_PAGE>::type, FPDFPageDeleter>;
@@ -48,11 +47,16 @@
std::unique_ptr<std::remove_pointer<FPDF_PAGELINK>::type,
FPDFPageLinkDeleter>;
+using ScopedFPDFPageObject =
+ std::unique_ptr<std::remove_pointer<FPDF_PAGEOBJECT>::type,
+ FPDFPageObjectDeleter>;
+
using ScopedFPDFStructTree =
std::unique_ptr<std::remove_pointer<FPDF_STRUCTTREE>::type,
FPDFStructTreeDeleter>;
-using ScopedFPDFFont =
- std::unique_ptr<std::remove_pointer<FPDF_FONT>::type, FPDFFontDeleter>;
+using ScopedFPDFTextPage =
+ std::unique_ptr<std::remove_pointer<FPDF_TEXTPAGE>::type,
+ FPDFTextPageDeleter>;
#endif // PUBLIC_CPP_FPDF_SCOPERS_H_