瀏覽代碼

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 年之前
父節點
當前提交
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 {};
     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);
     VERIFY(bits_per_component == 1 || bits_per_component == 2 || bits_per_component == 4);
     Vector<u8> upsampled_storage;
     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 (auto byte : content) {
         for (int i = 0; i < 8; i += bits_per_component) {
         for (int i = 0; i < 8; i += bits_per_component) {
             auto value = (byte >> (8 - bits_per_component - i)) & mask;
             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;
     return upsampled_storage;
@@ -895,7 +902,8 @@ PDFErrorOr<NonnullRefPtr<Gfx::Bitmap>> Renderer::load_image(NonnullRefPtr<Stream
 
 
     Vector<u8> upsampled_storage;
     Vector<u8> upsampled_storage;
     if (bits_per_component < 8) {
     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;
         content = upsampled_storage;
         bits_per_component = 8;
         bits_per_component = 8;
     }
     }