[Skia] Create a new palette when upsampling 1-bit-per-pixel bitmaps
For a 1-bit-per-pixel bitmap, its color palette sometimes stands for
the boundary of a range of colors instead of just 2 colors.
In Upsample(), this CL adds the process to create a new palette based
on this range and uses it for upsampling the bitmap to 32 bits per
pixel.
Meanwhile, move the process that fills a 32-bit-per-pixel buffer with
the palette into a helper Fill32BppDestStorageWithPalette() so that
this process can be reused within Upsample().
Bug: pdfium:1810
Change-Id: Ia2c4394d8d7d0809a3987d5a3304e7c7892ade6f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98175
Commit-Queue: Nigi <nigi@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/DEPS b/DEPS
index 7185232..aaae84c 100644
--- a/DEPS
+++ b/DEPS
@@ -130,7 +130,7 @@
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling pdfium_tests
# and whatever else without interference from each other.
- 'pdfium_tests_revision': '75cce6244b9c04dbe67ce0d7929e0ca0ab7f0ae7',
+ 'pdfium_tests_revision': 'de98839600918731c7247d5202240acdb7c4b092',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling skia
# and whatever else without interference from each other.
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index c4040ae..3acca4e 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -292,6 +292,33 @@
FXARGB_R(color) == FXARGB_B(color);
}
+// Called by Upsample(), returns a 32 bit-per-pixel buffer filled with colors
+// from `palette`.
+DataVector<uint32_t> Fill32BppDestStorageWithPalette(
+ const RetainPtr<CFX_DIBBase>& source,
+ pdfium::span<const uint32_t> palette) {
+ int width = source->GetWidth();
+ int height = source->GetHeight();
+ void* buffer = source->GetBuffer();
+ DCHECK(buffer);
+ DataVector<uint32_t> dst32_storage(Fx2DSizeOrDie(width, height));
+ pdfium::span<SkPMColor> dst32_pixels(dst32_storage);
+
+ for (int y = 0; y < height; ++y) {
+ const uint8_t* src_row =
+ static_cast<const uint8_t*>(buffer) + y * source->GetPitch();
+ pdfium::span<uint32_t> dst_row = dst32_pixels.subspan(y * width);
+ for (int x = 0; x < width; ++x) {
+ unsigned index = src_row[x];
+ if (index >= palette.size()) {
+ index = 0;
+ }
+ dst_row[x] = palette[index];
+ }
+ }
+ return dst32_storage;
+}
+
static void DebugValidate(const RetainPtr<CFX_DIBitmap>& bitmap,
const RetainPtr<CFX_DIBitmap>& device) {
if (bitmap) {
@@ -689,7 +716,7 @@
// are specified in the palette.
uint8_t color0 = 0x00;
uint8_t color1 = 0xFF;
- bool use_two_colors = true;
+
if (pSource->GetFormat() == FXDIB_Format::k1bppRgb &&
pSource->HasPalette()) {
// When `pSource` has 1 bit per pixel, its palette will contain 2
@@ -700,52 +727,47 @@
// differently depending on these conditions.
uint32_t palette_color0 = pSource->GetPaletteArgb(0);
uint32_t palette_color1 = pSource->GetPaletteArgb(1);
- use_two_colors = IsRGBColorGrayScale(palette_color0) &&
- IsRGBColorGrayScale(palette_color1);
- if (use_two_colors) {
- color0 = FXARGB_R(palette_color0);
- color1 = FXARGB_R(palette_color1);
+ bool use_two_colors = IsRGBColorGrayScale(palette_color0) &&
+ IsRGBColorGrayScale(palette_color1);
+ if (!use_two_colors) {
+ // If more than 2 colors are provided, calculate the range of colors
+ // and store them in `new_palette`
+ FX_ARGB new_palette[CFX_DIBBase::kPaletteSize];
+ CFX_ImageStretcher::BuildPaletteFrom1BppSource(pSource, new_palette);
+ dst32_storage = Fill32BppDestStorageWithPalette(pSource, new_palette);
+ buffer = dst32_storage.data();
+ rowBytes = width * sizeof(uint32_t);
+ colorType = Get32BitSkColorType(bRgbByteOrder);
+ break;
}
- // TODO(pdfium:1810): Handle upsampling when a range of colors (more
- // than 2 colors) are provided in the source palette.
+ color0 = FXARGB_R(palette_color0);
+ color1 = FXARGB_R(palette_color1);
}
- if (use_two_colors) {
- dst8_storage = DataVector<uint8_t>(Fx2DSizeOrDie(width, height));
- pdfium::span<uint8_t> dst8_pixels(dst8_storage);
- for (int y = 0; y < height; ++y) {
- const uint8_t* srcRow =
- static_cast<const uint8_t*>(buffer) + y * rowBytes;
- pdfium::span<uint8_t> dst_row = dst8_pixels.subspan(y * width);
- for (int x = 0; x < width; ++x)
- dst_row[x] = srcRow[x >> 3] & (1 << (~x & 0x07)) ? color1 : color0;
- }
- buffer = dst8_storage.data();
- rowBytes = width;
+ dst8_storage = DataVector<uint8_t>(Fx2DSizeOrDie(width, height));
+ pdfium::span<uint8_t> dst8_pixels(dst8_storage);
+ for (int y = 0; y < height; ++y) {
+ const uint8_t* srcRow =
+ static_cast<const uint8_t*>(buffer) + y * rowBytes;
+ pdfium::span<uint8_t> dst_row = dst8_pixels.subspan(y * width);
+ for (int x = 0; x < width; ++x)
+ dst_row[x] = srcRow[x >> 3] & (1 << (~x & 0x07)) ? color1 : color0;
}
+ buffer = dst8_storage.data();
+ rowBytes = width;
break;
}
case 8:
// we upscale ctables to 32bit.
if (pSource->HasPalette()) {
- dst32_storage = DataVector<uint32_t>(Fx2DSizeOrDie(width, height));
- pdfium::span<SkPMColor> dst32_pixels(dst32_storage);
const size_t src_palette_size = pSource->GetRequiredPaletteSize();
pdfium::span<const uint32_t> src_palette = pSource->GetPaletteSpan();
CHECK_LE(src_palette_size, src_palette.size());
- for (int y = 0; y < height; ++y) {
- const uint8_t* srcRow =
- static_cast<const uint8_t*>(buffer) + y * rowBytes;
- pdfium::span<uint32_t> dst_row = dst32_pixels.subspan(y * width);
- for (int x = 0; x < width; ++x) {
- unsigned index = srcRow[x];
- if (index >= src_palette_size) {
- index = 0;
- }
- dst_row[x] = src_palette[index];
- }
- }
+ if (src_palette_size < src_palette.size())
+ src_palette = src_palette.first(src_palette_size);
+
+ dst32_storage = Fill32BppDestStorageWithPalette(pSource, src_palette);
buffer = dst32_storage.data();
rowBytes = width * sizeof(uint32_t);
colorType = Get32BitSkColorType(bRgbByteOrder);
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index 1378ece..1f64695 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -208,10 +208,6 @@
en_contact.pdf mac * * *
en_diy.pdf mac * * *
en_foxit.pdf mac * * *
-
-# TODO(pdfium:1810): Remove after associated bug is fixed
-en_fqa.pdf * * * skia
-
en_fqa2.pdf mac * * *
en_introduce.pdf mac * * *
en_tem.pdf mac * * *