Skip to content

Commit dc13a6a

Browse files
brokenpartsslouken
authored andcommitted
SDL_SaveBMP_IO: Write bitmap header v5 values
bV4CSType was changed to LCS_sRGB to work with Preview on macOS. Fixes: #11903
1 parent fe6bd8e commit dc13a6a

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

src/video/SDL_bmp.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,23 @@
4646
#endif
4747

4848
// Logical color space values for BMP files
49+
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/eb4bbd50-b3ce-4917-895c-be31f214797f
4950
#ifndef LCS_WINDOWS_COLOR_SPACE
5051
// 0x57696E20 == "Win "
5152
#define LCS_WINDOWS_COLOR_SPACE 0x57696E20
5253
#endif
5354

55+
#ifndef LCS_sRGB
56+
// 0x73524742 == "sRGB"
57+
#define LCS_sRGB 0x73524742
58+
#endif
59+
60+
// Logical/physical color relationship
61+
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/9fec0834-607d-427d-abd5-ab240fb0db38
62+
#ifndef LCS_GM_GRAPHICS
63+
#define LCS_GM_GRAPHICS 0x00000002
64+
#endif
65+
5466
static bool readRlePixels(SDL_Surface *surface, SDL_IOStream *src, int isRle8)
5567
{
5668
/*
@@ -637,6 +649,12 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
637649
Uint32 bV4GammaGreen = 0;
638650
Uint32 bV4GammaBlue = 0;
639651

652+
// The additional header members from the Win32 BITMAPV5HEADER struct (124 bytes in total)
653+
Uint32 bV5Intent = 0;
654+
Uint32 bV5ProfileData = 0;
655+
Uint32 bV5ProfileSize = 0;
656+
Uint32 bV5Reserved = 0;
657+
640658
// Make sure we have somewhere to save
641659
if (!SDL_SurfaceValid(surface)) {
642660
SDL_InvalidParamError("surface");
@@ -728,19 +746,25 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
728746
}
729747
biClrImportant = 0;
730748

731-
// Set the BMP info values for the version 4 header
749+
// Set the BMP info values
732750
if (save32bit && !saveLegacyBMP) {
733-
biSize = 108;
751+
biSize = 124;
752+
// Version 4 values
734753
biCompression = BI_BITFIELDS;
735754
// The BMP format is always little endian, these masks stay the same
736755
bV4RedMask = 0x00ff0000;
737756
bV4GreenMask = 0x0000ff00;
738757
bV4BlueMask = 0x000000ff;
739758
bV4AlphaMask = 0xff000000;
740-
bV4CSType = LCS_WINDOWS_COLOR_SPACE;
759+
bV4CSType = LCS_sRGB;
741760
bV4GammaRed = 0;
742761
bV4GammaGreen = 0;
743762
bV4GammaBlue = 0;
763+
// Version 5 values
764+
bV5Intent = LCS_GM_GRAPHICS;
765+
bV5ProfileData = 0;
766+
bV5ProfileSize = 0;
767+
bV5Reserved = 0;
744768
}
745769

746770
// Write the BMP info values
@@ -758,8 +782,9 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
758782
goto done;
759783
}
760784

761-
// Write the BMP info values for the version 4 header
785+
// Write the BMP info values
762786
if (save32bit && !saveLegacyBMP) {
787+
// Version 4 values
763788
if (!SDL_WriteU32LE(dst, bV4RedMask) ||
764789
!SDL_WriteU32LE(dst, bV4GreenMask) ||
765790
!SDL_WriteU32LE(dst, bV4BlueMask) ||
@@ -777,6 +802,13 @@ bool SDL_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio)
777802
!SDL_WriteU32LE(dst, bV4GammaBlue)) {
778803
goto done;
779804
}
805+
// Version 5 values
806+
if (!SDL_WriteU32LE(dst, bV5Intent) ||
807+
!SDL_WriteU32LE(dst, bV5ProfileData) ||
808+
!SDL_WriteU32LE(dst, bV5ProfileSize) ||
809+
!SDL_WriteU32LE(dst, bV5Reserved)) {
810+
goto done;
811+
}
780812
}
781813

782814
// Write the palette (in BGR color order)

0 commit comments

Comments
 (0)