Browse Source

LibGfx/BMP: Clear alpha in palette entries

The semantics of BGRx8888 aren't super clear and it means different
things for different parts of the codebase. In particular, the PNG
writer still writes the x channel to the alpha channel of its output.

In BMPs, the 4th palette byte is usually 0, which means after #21412 we
started writing all .bmp files with <= 8bpp as completely transparent
to PNGs.

This works around that.

(See also #19464 for previous similar workarounds.)

The added `bitmap.bmp` is a 1bpp file I drew in Photoshop and saved
using its "Save as..." saving path.
Nico Weber 1 year ago
parent
commit
ab143e9b0e

+ 10 - 0
Tests/LibGfx/TestImageDecoder.cpp

@@ -71,6 +71,16 @@ TEST_CASE(test_bmp_top_down)
     TRY_OR_FAIL(expect_single_frame(*plugin_decoder));
 }
 
+TEST_CASE(test_bmp_1bpp)
+{
+    auto file = TRY_OR_FAIL(Core::MappedFile::map(TEST_INPUT("bmp/bitmap.bmp"sv)));
+    EXPECT(Gfx::BMPImageDecoderPlugin::sniff(file->bytes()));
+    auto plugin_decoder = TRY_OR_FAIL(Gfx::BMPImageDecoderPlugin::create(file->bytes()));
+
+    auto frame = TRY_OR_FAIL(expect_single_frame_of_size(*plugin_decoder, { 399, 400 }));
+    EXPECT_EQ(frame.image->begin()[0], 0xff'ff'ff'ff);
+}
+
 TEST_CASE(test_ico_malformed_frame)
 {
     Array test_inputs = {

BIN
Tests/LibGfx/test-inputs/bmp/bitmap.bmp


+ 2 - 2
Userland/Libraries/LibGfx/ImageFormats/BMPLoader.cpp

@@ -979,11 +979,11 @@ static ErrorOr<void> decode_bmp_color_table(BMPLoadingContext& context)
         if (bytes_per_color == 4) {
             if (!streamer.has_u32())
                 return Error::from_string_literal("Cannot read 32 bits");
-            context.color_table.append(streamer.read_u32());
+            context.color_table.append(streamer.read_u32() | 0xff'00'00'00);
         } else {
             if (!streamer.has_u24())
                 return Error::from_string_literal("Cannot read 24 bits");
-            context.color_table.append(streamer.read_u24());
+            context.color_table.append(streamer.read_u24() | 0xff'00'00'00);
         }
     }