Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix BMP palette loading #386

Merged

Conversation

kaixiong
Copy link
Member

This PR fixes the palette loading in the BMP image loader.

The bug is due to the loader reading from the wrong file offset.

BMP files begin with a fixed size file header and a DIB (device-independent bitmap) header that has been continually extended over the years. According to Wikipedia, there are 8 versions of the DIB header with differing sizes. They vary from the original 12 bytes to as large as 124 bytes in recent revisions. Each version subsumes the fields of previous versions. The colour table i.e. palette is found right after [1].

The loader currently reads part of the DIB header to get what it needs and proceeds to read the palette entries without accounting for the actual DIB header size. This patch fixes this by seeking to the end of the DIB header, utilizing the size given by the header's first field.

[1] Except when the compression schemes BI_BITFIELDS or BI_ALPHABITFIELDS are used, which isn't supported by the loader.

@@ -341,12 +343,14 @@ namespace LV {
return nullptr;
}

if (bi_compression > 3) {
if (bi_compression >= 3) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of approach "undocumented unnamed magic number". This seems to be 3 because BI_BITFIELDS == 3 in Windows. If we cannot use that constant without including Windows headers, let's either (a) add a good comment or (b) make our own copy of that constant (or both)?

visual_log (VISUAL_LOG_ERROR, "Bitmap uses an invalid or unsupported compression scheme");
fp.seekg (saved_stream_pos);
return nullptr;
}

fp.seekg (dib_header_pos + std::streampos {bi_size}, std::ios::beg);
Copy link
Member

@hartwork hartwork Jan 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add comments (or make otherwise more obvious) that…

  • that we're jumping to the start of the palette here (— we could also move the line_below_ comment /* Load the palette */ to better show it's part of palette loading?)
  • that this is the correct value (only) because we ruled out both BI_BITFIELDS and BI_ALPHABITFIELDS earlier (referring to the first paragraph at https://en.wikipedia.org/wiki/BMP_file_format#Color_table)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, let me make that change.

@kaixiong kaixiong requested a review from hartwork January 25, 2025 10:45
Copy link
Member

@hartwork hartwork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaixiong thanks for the adjustments! 👍

@kaixiong kaixiong merged commit 1788dec into add-palette-iteration-comparison-api Jan 25, 2025
6 checks passed
@kaixiong kaixiong deleted the fix-bmp-palette-loading branch January 25, 2025 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants