Loosen palette check in FPDFImageObj_GetBitmap()
Adjust FPDFImageObj_GetBitmap() behavior based on PDFium embedder
feedback. One of the checks added in
https://pdfium-review.googlesource.com/111950 does not work for images
that have both indexed colorspaces and /Mask.
Add a test PDF where an image has these properties to trigger this
behavior.
Bug: 343075986
Change-Id: I74805f22d5dffc6adcad144cdd1c8c424b68240b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/119970
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index d63b948..bc248f6 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -4492,6 +4492,25 @@
UnloadPage(page);
}
+TEST_F(FPDFEditEmbedderTest, GetBitmapWithArgbImageWithPalette) {
+ ASSERT_TRUE(OpenDocument("bug_343075986.pdf"));
+
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ constexpr int kExpectedObjects = 2;
+ ASSERT_EQ(kExpectedObjects, FPDFPage_CountObjects(page));
+ FPDF_PAGEOBJECT obj = FPDFPage_GetObject(page, 1);
+ ASSERT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(obj));
+
+ ScopedFPDFBitmap bitmap(FPDFImageObj_GetBitmap(obj));
+ ASSERT_TRUE(bitmap);
+ EXPECT_EQ(FPDFBitmap_BGR, FPDFBitmap_GetFormat(bitmap.get()));
+ CompareBitmap(bitmap.get(), 4, 4, "49b4d39d3fd81c9853b493b615e475d1");
+
+ UnloadPage(page);
+}
+
TEST_F(FPDFEditEmbedderTest, GetRenderedBitmapHandlesSetMatrix) {
ASSERT_TRUE(OpenDocument("embedded_images.pdf"));
FPDF_PAGE page = LoadPage(0);
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index 479c6eb..2f18a80 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -220,32 +220,30 @@
ConversionOp op;
switch (pSource->GetFormat()) {
case FXDIB_Format::k1bppMask:
- case FXDIB_Format::k8bppMask:
+ case FXDIB_Format::k8bppMask: {
// Masks do not have palettes, so they can be safely converted to
// `FXDIB_Format::k8bppRgb`.
CHECK(!pSource->HasPalette());
op = ConversionOp::kConvertTo8bppRgb;
break;
- case FXDIB_Format::k1bppRgb:
+ }
+ case FXDIB_Format::k1bppRgb: {
// If there is a palette, then convert to `FXDIB_Format::kRgb` to avoid
// creating a bitmap with a palette.
op = pSource->HasPalette() ? ConversionOp::kConvertToRgb
: ConversionOp::kConvertTo8bppRgb;
break;
+ }
case FXDIB_Format::k8bppRgb:
+ case FXDIB_Format::kArgb:
+ case FXDIB_Format::kRgb:
+ case FXDIB_Format::kRgb32: {
// If there is a palette, then convert to `FXDIB_Format::kRgb` to avoid
// creating a bitmap with a palette.
op = pSource->HasPalette() ? ConversionOp::kConvertToRgb
: ConversionOp::kRealize;
break;
-
- case FXDIB_Format::kArgb:
- case FXDIB_Format::kRgb:
- case FXDIB_Format::kRgb32:
- CHECK(!pSource->HasPalette());
- op = ConversionOp::kRealize;
- break;
-
+ }
case FXDIB_Format::kInvalid: {
NOTREACHED_NORETURN();
}
diff --git a/testing/resources/bug_343075986.in b/testing/resources/bug_343075986.in
new file mode 100644
index 0000000..7223eca
--- /dev/null
+++ b/testing/resources/bug_343075986.in
@@ -0,0 +1,67 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 1
+ /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 4 0 R
+ /MediaBox [0 0 40 60]
+ /Resources <<
+ /XObject <<
+ /Img1 5 0 R
+ >>
+ >>
+>>
+endobj
+{{object 4 0}} <<
+ {{streamlen}}
+>>
+stream
+% Draw yellow background.
+q
+1 1 0 rg
+0 0 40 60 re f
+Q
+% Draw image where the black is masked out to let the yellow show.
+q
+40 0 0 60 0 0 cm
+/Img1 Do
+Q
+endstream
+endobj
+{{object 5 0}} <<
+ /Type /XObject
+ /Subtype /Image
+ /Width 4
+ /Height 4
+ /BitsPerComponent 8
+ /ColorSpace [
+ /Indexed
+ /DeviceRGB
+ 4
+ <000000 FF0000 00FF00 0000FF FFFFFF>
+ ]
+ /Filter /ASCIIHexDecode
+ /Mask [0 0 0 0 0 0] % Mask out black.
+ {{streamlen}}
+>>
+stream
+00 00 01 01
+00 02 02 01
+03 02 02 04
+03 03 04 04
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_343075986.pdf b/testing/resources/bug_343075986.pdf
new file mode 100644
index 0000000..d3719a1
--- /dev/null
+++ b/testing/resources/bug_343075986.pdf
@@ -0,0 +1,79 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /Count 1
+ /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 4 0 R
+ /MediaBox [0 0 40 60]
+ /Resources <<
+ /XObject <<
+ /Img1 5 0 R
+ >>
+ >>
+>>
+endobj
+4 0 obj <<
+ /Length 151
+>>
+stream
+% Draw yellow background.
+q
+1 1 0 rg
+0 0 40 60 re f
+Q
+% Draw image where the black is masked out to let the yellow show.
+q
+40 0 0 60 0 0 cm
+/Img1 Do
+Q
+endstream
+endobj
+5 0 obj <<
+ /Type /XObject
+ /Subtype /Image
+ /Width 4
+ /Height 4
+ /BitsPerComponent 8
+ /ColorSpace [
+ /Indexed
+ /DeviceRGB
+ 4
+ <000000 FF0000 00FF00 0000FF FFFFFF>
+ ]
+ /Filter /ASCIIHexDecode
+ /Mask [0 0 0 0 0 0] % Mask out black.
+ /Length 48
+>>
+stream
+00 00 01 01
+00 02 02 01
+03 02 02 04
+03 03 04 04
+endstream
+endobj
+xref
+0 6
+0000000000 65535 f
+0000000015 00000 n
+0000000068 00000 n
+0000000131 00000 n
+0000000286 00000 n
+0000000489 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 6
+>>
+startxref
+829
+%%EOF