Просмотр исходного кода

LibPDF: For indexed images with 1, 2 or 4 bpp, do not repeat bit pattern

When upsampling e.g. the 4-bit value 0b1101 to 8-bit, we used to repeat
the value to fill the full 8-bits, e.g. 0b11011101. This maps RGB colors
to 8-bit nicely, but is the wrong thing to do for palette indices.
Stop doing this for palette indices.

Fixes "Indexed color space index out of range" for 11 files in the
PDF/A 0000.zip test set now that we correctly handle palette indices
as of the previous commit:

    Malformed PDF file: Indexed color space lookup table doesn't match
                        size, in 4 files, on 8 pages, 73 times
      path/to/0000/0000206.pdf 2 4 (2x) 5 (3x) 6 (4x)
      path/to/0000/0000364.pdf 5 6
      path/to/0000/0000918.pdf 5
      path/to/0000/0000683.pdf 8
Nico Weber 1 год назад
Родитель
Сommit
06b9633da5
1 измененных файлов с 11 добавлено и 3 удалено
  1. 11 3
      Userland/Libraries/LibPDF/Renderer.cpp

+ 11 - 3
Userland/Libraries/LibPDF/Renderer.cpp

@@ -827,7 +827,11 @@ PDFErrorOr<void> Renderer::show_text(DeprecatedString const& string)
     return {};
 }
 
-static Vector<u8> upsample_to_8_bit(ReadonlyBytes content, int bits_per_component)
+enum UpsampleMode {
+    StoreValuesUnchanged,
+    UpsampleTo8Bit,
+};
+static Vector<u8> upsample_to_8_bit(ReadonlyBytes content, int bits_per_component, UpsampleMode mode)
 {
     VERIFY(bits_per_component == 1 || bits_per_component == 2 || bits_per_component == 4);
     Vector<u8> upsampled_storage;
@@ -836,7 +840,10 @@ static Vector<u8> upsample_to_8_bit(ReadonlyBytes content, int bits_per_componen
     for (auto byte : content) {
         for (int i = 0; i < 8; i += bits_per_component) {
             auto value = (byte >> (8 - bits_per_component - i)) & mask;
-            upsampled_storage.append(value * (255 / mask));
+            if (mode == UpsampleMode::UpsampleTo8Bit)
+                upsampled_storage.append(value * (255 / mask));
+            else
+                upsampled_storage.append(value);
         }
     }
     return upsampled_storage;
@@ -895,7 +902,8 @@ PDFErrorOr<NonnullRefPtr<Gfx::Bitmap>> Renderer::load_image(NonnullRefPtr<Stream
 
     Vector<u8> upsampled_storage;
     if (bits_per_component < 8) {
-        upsampled_storage = upsample_to_8_bit(content, bits_per_component);
+        UpsampleMode mode = color_space->family() == ColorSpaceFamily::Indexed ? UpsampleMode::StoreValuesUnchanged : UpsampleMode::UpsampleTo8Bit;
+        upsampled_storage = upsample_to_8_bit(content, bits_per_component, mode);
         content = upsampled_storage;
         bits_per_component = 8;
     }