1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-09 09:34:57 +09:00

LibGfx: Correctly handle OS/2 BMPs with 3-byte color entries

We now properly handle OS/2 format BMPs that use 3 bytes per color
entry instead of 4. While OS/2 2.x officially specified 4 bytes per
color, some tools still produce files with 3-byte entries. We can
identify such files by checking the available color table space.
This commit is contained in:
aplefull 2025-05-06 21:32:35 +02:00 committed by Jelle Raaijmakers
parent 4d8717fa3a
commit e5944a4d9e
Notes: github-actions[bot] 2025-05-09 19:49:19 +00:00
3 changed files with 33 additions and 3 deletions

View file

@ -958,7 +958,26 @@ static ErrorOr<void> decode_bmp_color_table(BMPLoadingContext& context)
return {};
}
auto bytes_per_color = context.dib_type == DIBType::Core ? 3 : 4;
// OS/2 1.x (Core) uses 3 bytes per color
// OS/2 2.x (OSV2) can use 3 or 4 bytes per color
u8 bytes_per_color;
if (context.dib_type == DIBType::Core) {
bytes_per_color = 3;
} else if (context.dib_type == DIBType::OSV2 || context.dib_type == DIBType::OSV2Short) {
// For OS/2 2.x we need to determine the number of bytes per color based on the size of the color table
u8 header_size = context.is_included_in_ico ? 0 : bmp_header_size;
u32 available_size = context.data_offset - header_size - context.dib_size();
u32 max_colors = 1 << context.dib.core.bpp;
if (available_size == 3 * max_colors) {
bytes_per_color = 3;
} else {
bytes_per_color = 4;
}
} else {
bytes_per_color = 4;
}
u32 max_colors = 1 << context.dib.core.bpp;
u8 header_size = !context.is_included_in_ico ? bmp_header_size : 0;
@ -974,9 +993,9 @@ static ErrorOr<void> decode_bmp_color_table(BMPLoadingContext& context)
if (context.dib_type <= DIBType::OSV2) {
// Partial color tables are not supported, so the space of the color
// table must be at least enough for the maximum amount of colors
if (size_of_color_table < 3 * max_colors) {
if (size_of_color_table < bytes_per_color * max_colors) {
// This is against the spec, but most viewers process it anyways
dbgln("BMP with CORE header does not have enough colors. Has: {}, expected: {}", size_of_color_table, (3 * max_colors));
dbgln("BMP with CORE header does not have enough colors. Has: {}, expected: {}", size_of_color_table, (bytes_per_color * max_colors));
}
}