update sdl Merge commit '4d48f9d23713d94b861da7b5d41baf2a41334994'
This commit is contained in:
303
external/sdl/SDL/src/video/SDL_bmp.c
vendored
303
external/sdl/SDL/src/video/SDL_bmp.c
vendored
@ -71,7 +71,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
|
||||
/* !!! FIXME: for all these reads, handle error vs eof? handle -2 if non-blocking? */
|
||||
for (;;) {
|
||||
if (SDL_RWread(src, &ch, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
/*
|
||||
@ -80,7 +80,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
*/
|
||||
if (ch) {
|
||||
Uint8 pixel;
|
||||
if (SDL_RWread(src, &pixel, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
if (isRle8) { /* 256-color bitmap, compressed */
|
||||
@ -107,7 +107,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
| a cursor move, or some absolute data.
|
||||
| zero tag may be absolute mode or an escape
|
||||
*/
|
||||
if (SDL_RWread(src, &ch, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
switch (ch) {
|
||||
@ -118,11 +118,11 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
case 1: /* end of bitmap */
|
||||
return SDL_FALSE; /* success! */
|
||||
case 2: /* delta */
|
||||
if (SDL_RWread(src, &ch, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
ofs += ch;
|
||||
if (SDL_RWread(src, &ch, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
bits -= (ch * pitch);
|
||||
@ -132,7 +132,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
needsPad = (ch & 1);
|
||||
do {
|
||||
Uint8 pixel;
|
||||
if (SDL_RWread(src, &pixel, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
COPY_PIXEL(pixel);
|
||||
@ -141,7 +141,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
needsPad = (((ch + 1) >> 1) & 1); /* (ch+1)>>1: bytes size */
|
||||
for (;;) {
|
||||
Uint8 pixel;
|
||||
if (SDL_RWread(src, &pixel, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
COPY_PIXEL(pixel >> 4);
|
||||
@ -155,7 +155,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
}
|
||||
}
|
||||
/* pad at even boundary */
|
||||
if (needsPad && (SDL_RWread(src, &ch, 1) <= 0)) {
|
||||
if (needsPad && !SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
@ -195,7 +195,7 @@ static void CorrectAlphaChannel(SDL_Surface *surface)
|
||||
|
||||
SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
{
|
||||
SDL_bool was_error;
|
||||
SDL_bool was_error = SDL_TRUE;
|
||||
Sint64 fp_offset = 0;
|
||||
int bmpPitch;
|
||||
int i, pad;
|
||||
@ -235,42 +235,45 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
|
||||
/* Make sure we are passed a valid data source */
|
||||
surface = NULL;
|
||||
was_error = SDL_FALSE;
|
||||
if (src == NULL) {
|
||||
SDL_InvalidParamError("src");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read in the BMP file header */
|
||||
fp_offset = SDL_RWtell(src);
|
||||
if (fp_offset < 0) {
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
SDL_ClearError();
|
||||
if (SDL_RWread(src, magic, 2) != 2) {
|
||||
SDL_Error(SDL_EFREAD);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (SDL_strncmp(magic, "BM", 2) != 0) {
|
||||
SDL_SetError("File is not a Windows BMP file");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
/* bfSize = */ SDL_ReadLE32(src);
|
||||
/* bfReserved1 = */ SDL_ReadLE16(src);
|
||||
/* bfReserved2 = */ SDL_ReadLE16(src);
|
||||
bfOffBits = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, NULL /* bfSize */) ||
|
||||
!SDL_ReadU16LE(src, NULL /* bfReserved1 */) ||
|
||||
!SDL_ReadU16LE(src, NULL /* bfReserved2 */) ||
|
||||
!SDL_ReadU32LE(src, &bfOffBits)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read the Win32 BITMAPINFOHEADER */
|
||||
biSize = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, &biSize)) {
|
||||
goto done;
|
||||
}
|
||||
if (biSize == 12) { /* really old BITMAPCOREHEADER */
|
||||
biWidth = (Uint32)SDL_ReadLE16(src);
|
||||
biHeight = (Uint32)SDL_ReadLE16(src);
|
||||
/* biPlanes = */ SDL_ReadLE16(src);
|
||||
biBitCount = SDL_ReadLE16(src);
|
||||
Uint16 biWidth16, biHeight16;
|
||||
if (!SDL_ReadU16LE(src, &biWidth16) ||
|
||||
!SDL_ReadU16LE(src, &biHeight16) ||
|
||||
!SDL_ReadU16LE(src, NULL /* biPlanes */) ||
|
||||
!SDL_ReadU16LE(src, &biBitCount)) {
|
||||
goto done;
|
||||
}
|
||||
biWidth = biWidth16;
|
||||
biHeight = biHeight16;
|
||||
biCompression = BI_RGB;
|
||||
/* biSizeImage = 0; */
|
||||
/* biXPelsPerMeter = 0; */
|
||||
@ -279,16 +282,18 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
/* biClrImportant = 0; */
|
||||
} else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */
|
||||
Uint32 headerSize;
|
||||
biWidth = SDL_ReadLE32(src);
|
||||
biHeight = SDL_ReadLE32(src);
|
||||
/* biPlanes = */ SDL_ReadLE16(src);
|
||||
biBitCount = SDL_ReadLE16(src);
|
||||
biCompression = SDL_ReadLE32(src);
|
||||
/* biSizeImage = */ SDL_ReadLE32(src);
|
||||
/* biXPelsPerMeter = */ SDL_ReadLE32(src);
|
||||
/* biYPelsPerMeter = */ SDL_ReadLE32(src);
|
||||
biClrUsed = SDL_ReadLE32(src);
|
||||
/* biClrImportant = */ SDL_ReadLE32(src);
|
||||
if (!SDL_ReadS32LE(src, &biWidth) ||
|
||||
!SDL_ReadS32LE(src, &biHeight) ||
|
||||
!SDL_ReadU16LE(src, NULL /* biPlanes */) ||
|
||||
!SDL_ReadU16LE(src, &biBitCount) ||
|
||||
!SDL_ReadU32LE(src, &biCompression) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biSizeImage */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biXPelsPerMeter */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biYPelsPerMeter */) ||
|
||||
!SDL_ReadU32LE(src, &biClrUsed) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biClrImportant */)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */
|
||||
if (biSize != 64) {
|
||||
@ -301,24 +306,32 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
following the legacy v1 info header, just past biSize. */
|
||||
if (biCompression == BI_BITFIELDS) {
|
||||
haveRGBMasks = SDL_TRUE;
|
||||
Rmask = SDL_ReadLE32(src);
|
||||
Gmask = SDL_ReadLE32(src);
|
||||
Bmask = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, &Rmask) ||
|
||||
!SDL_ReadU32LE(src, &Gmask) ||
|
||||
!SDL_ReadU32LE(src, &Bmask)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* ...v3 adds an alpha mask. */
|
||||
if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
|
||||
haveAlphaMask = SDL_TRUE;
|
||||
Amask = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, &Amask)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */
|
||||
if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */
|
||||
/*Rmask = */ SDL_ReadLE32(src);
|
||||
/*Gmask = */ SDL_ReadLE32(src);
|
||||
/*Bmask = */ SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, NULL /* Rmask */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* Gmask */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* Bmask */)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
|
||||
/*Amask = */ SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, NULL /* Amask */)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,12 +344,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
/* skip any header bytes we didn't handle... */
|
||||
headerSize = (Uint32)(SDL_RWtell(src) - (fp_offset + 14));
|
||||
if (biSize > headerSize) {
|
||||
SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR);
|
||||
if (SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR) < 0) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (biWidth <= 0 || biHeight == 0) {
|
||||
SDL_SetError("BMP file with bad dimensions (%" SDL_PRIs32 "x%" SDL_PRIs32 ")", biWidth, biHeight);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (biHeight < 0) {
|
||||
@ -348,7 +362,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
|
||||
/* Check for read error */
|
||||
if (SDL_strcmp(SDL_GetError(), "") != 0) {
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -366,7 +379,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
case 6:
|
||||
case 7:
|
||||
SDL_SetError("%d-bpp BMP images are not supported", biBitCount);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
default:
|
||||
ExpandBMP = 0;
|
||||
@ -431,7 +443,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
surface = SDL_CreateSurface(biWidth, biHeight, format);
|
||||
|
||||
if (surface == NULL) {
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -441,13 +452,11 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
if (palette) {
|
||||
if (SDL_RWseek(src, fp_offset + 14 + biSize, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (biBitCount >= 32) { /* we shift biClrUsed by this value later. */
|
||||
SDL_SetError("Unsupported or incorrect biBitCount field");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -459,26 +468,27 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
biClrUsed = 1 << biBitCount; /* try forcing it? */
|
||||
if (biClrUsed > (Uint32)palette->ncolors) {
|
||||
SDL_SetError("Unsupported or incorrect biClrUsed field");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (biSize == 12) {
|
||||
for (i = 0; i < (int)biClrUsed; ++i) {
|
||||
/* !!! FIXME: this should check for i/o errors! */
|
||||
SDL_RWread(src, &palette->colors[i].b, 1);
|
||||
SDL_RWread(src, &palette->colors[i].g, 1);
|
||||
SDL_RWread(src, &palette->colors[i].r, 1);
|
||||
if (!SDL_ReadU8(src, &palette->colors[i].b) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].g) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].r)) {
|
||||
goto done;
|
||||
}
|
||||
palette->colors[i].a = SDL_ALPHA_OPAQUE;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (int)biClrUsed; ++i) {
|
||||
/* !!! FIXME: this should check for i/o errors! */
|
||||
SDL_RWread(src, &palette->colors[i].b, 1);
|
||||
SDL_RWread(src, &palette->colors[i].g, 1);
|
||||
SDL_RWread(src, &palette->colors[i].r, 1);
|
||||
SDL_RWread(src, &palette->colors[i].a, 1);
|
||||
if (!SDL_ReadU8(src, &palette->colors[i].b) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].g) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].r) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].a)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* According to Microsoft documentation, the fourth element
|
||||
is reserved and must be zero, so we shouldn't treat it as
|
||||
@ -493,7 +503,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
/* Read the surface pixels. Note that the bmp image is upside down */
|
||||
if (SDL_RWseek(src, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) {
|
||||
@ -537,16 +546,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
int shift = (8 - ExpandBMP);
|
||||
for (i = 0; i < surface->w; ++i) {
|
||||
if (i % (8 / ExpandBMP) == 0) {
|
||||
if (SDL_RWread(src, &pixel, 1) != 1) {
|
||||
SDL_Error(SDL_EFREAD);
|
||||
was_error = SDL_TRUE;
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
bits[i] = (pixel >> shift);
|
||||
if (bits[i] >= biClrUsed) {
|
||||
SDL_SetError("A BMP image contains a pixel with a color out of the palette");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
pixel <<= ExpandBMP;
|
||||
@ -555,15 +561,12 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
|
||||
default:
|
||||
if (SDL_RWread(src, bits, surface->pitch) != surface->pitch) {
|
||||
SDL_Error(SDL_EFREAD);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (biBitCount == 8 && palette && biClrUsed < (1u << biBitCount)) {
|
||||
for (i = 0; i < surface->w; ++i) {
|
||||
if (bits[i] >= biClrUsed) {
|
||||
SDL_SetError("A BMP image contains a pixel with a color out of the palette");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -598,7 +601,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
if (pad) {
|
||||
Uint8 padbyte;
|
||||
for (i = 0; i < pad; ++i) {
|
||||
SDL_RWread(src, &padbyte, 1);
|
||||
if (!SDL_ReadU8(src, &padbyte)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (topDown) {
|
||||
@ -610,6 +615,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
if (correctAlpha) {
|
||||
CorrectAlphaChannel(surface);
|
||||
}
|
||||
|
||||
was_error = SDL_FALSE;
|
||||
|
||||
done:
|
||||
if (was_error) {
|
||||
if (src) {
|
||||
@ -629,15 +637,10 @@ SDL_Surface *SDL_LoadBMP(const char *file)
|
||||
return SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1);
|
||||
}
|
||||
|
||||
int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, SDL_bool freedst)
|
||||
{
|
||||
/* !!! FIXME: this calls SDL_ClearError() and then checks if an error happened during this function to
|
||||
!!! FIXME: decide if there was a problem, but there's risk of innocent things setting an error
|
||||
!!! FIXME: string for innocent unrelated reasons, and also, an app supplying its own RWops
|
||||
!!! FIXME: implementation may not set the error string on failure. We should check for i/o
|
||||
!!! FIXME: failures as we go, and return early if one occurs. */
|
||||
|
||||
Sint64 fp_offset;
|
||||
SDL_bool was_error = SDL_TRUE;
|
||||
Sint64 fp_offset, new_offset;
|
||||
int i, pad;
|
||||
SDL_Surface *intermediate_surface;
|
||||
Uint8 *bits;
|
||||
@ -678,6 +681,11 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
/* Make sure we have somewhere to save */
|
||||
intermediate_surface = NULL;
|
||||
if (dst) {
|
||||
if (!surface) {
|
||||
SDL_InvalidParamError("surface");
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef SAVE_32BIT_BMP
|
||||
/* We can save alpha information in a 32-bit BMP */
|
||||
if (surface->format->BitsPerPixel >= 8 &&
|
||||
@ -693,6 +701,7 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
} else {
|
||||
SDL_SetError("%d bpp BMP files not supported",
|
||||
surface->format->BitsPerPixel);
|
||||
goto done;
|
||||
}
|
||||
} else if ((surface->format->BitsPerPixel == 24) && !save32bit &&
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
@ -707,32 +716,33 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
) {
|
||||
intermediate_surface = surface;
|
||||
} else {
|
||||
SDL_PixelFormat format;
|
||||
Uint32 pixel_format;
|
||||
|
||||
/* If the surface has a colorkey or alpha channel we'll save a
|
||||
32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
|
||||
if (save32bit) {
|
||||
SDL_InitFormat(&format, SDL_PIXELFORMAT_BGRA32);
|
||||
pixel_format = SDL_PIXELFORMAT_BGRA32;
|
||||
} else {
|
||||
SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
|
||||
pixel_format = SDL_PIXELFORMAT_BGR24;
|
||||
}
|
||||
intermediate_surface = SDL_ConvertSurface(surface, &format);
|
||||
intermediate_surface = SDL_ConvertSurfaceFormat(surface, pixel_format);
|
||||
if (intermediate_surface == NULL) {
|
||||
SDL_SetError("Couldn't convert image to %d bpp",
|
||||
format.BitsPerPixel);
|
||||
(int)SDL_BITSPERPIXEL(pixel_format));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Set no error here because it may overwrite a more useful message from
|
||||
SDL_RWFromFile() if SDL_SaveBMP_RW() is called from SDL_SaveBMP(). */
|
||||
return -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (save32bit) {
|
||||
saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE);
|
||||
}
|
||||
|
||||
if (intermediate_surface && (SDL_LockSurface(intermediate_surface) == 0)) {
|
||||
if (SDL_LockSurface(intermediate_surface) == 0) {
|
||||
const int bw = intermediate_surface->w * intermediate_surface->format->BytesPerPixel;
|
||||
|
||||
/* Set the BMP file header values */
|
||||
@ -743,12 +753,16 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
|
||||
/* Write the BMP file header values */
|
||||
fp_offset = SDL_RWtell(dst);
|
||||
SDL_ClearError();
|
||||
SDL_RWwrite(dst, magic, 2);
|
||||
SDL_WriteLE32(dst, bfSize);
|
||||
SDL_WriteLE16(dst, bfReserved1);
|
||||
SDL_WriteLE16(dst, bfReserved2);
|
||||
SDL_WriteLE32(dst, bfOffBits);
|
||||
if (fp_offset < 0) {
|
||||
goto done;
|
||||
}
|
||||
if (SDL_RWwrite(dst, magic, 2) != 2 ||
|
||||
!SDL_WriteU32LE(dst, bfSize) ||
|
||||
!SDL_WriteU16LE(dst, bfReserved1) ||
|
||||
!SDL_WriteU16LE(dst, bfReserved2) ||
|
||||
!SDL_WriteU32LE(dst, bfOffBits)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set the BMP info values */
|
||||
biSize = 40;
|
||||
@ -783,31 +797,39 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
}
|
||||
|
||||
/* Write the BMP info values */
|
||||
SDL_WriteLE32(dst, biSize);
|
||||
SDL_WriteLE32(dst, biWidth);
|
||||
SDL_WriteLE32(dst, biHeight);
|
||||
SDL_WriteLE16(dst, biPlanes);
|
||||
SDL_WriteLE16(dst, biBitCount);
|
||||
SDL_WriteLE32(dst, biCompression);
|
||||
SDL_WriteLE32(dst, biSizeImage);
|
||||
SDL_WriteLE32(dst, biXPelsPerMeter);
|
||||
SDL_WriteLE32(dst, biYPelsPerMeter);
|
||||
SDL_WriteLE32(dst, biClrUsed);
|
||||
SDL_WriteLE32(dst, biClrImportant);
|
||||
if (!SDL_WriteU32LE(dst, biSize) ||
|
||||
!SDL_WriteS32LE(dst, biWidth) ||
|
||||
!SDL_WriteS32LE(dst, biHeight) ||
|
||||
!SDL_WriteU16LE(dst, biPlanes) ||
|
||||
!SDL_WriteU16LE(dst, biBitCount) ||
|
||||
!SDL_WriteU32LE(dst, biCompression) ||
|
||||
!SDL_WriteU32LE(dst, biSizeImage) ||
|
||||
!SDL_WriteU32LE(dst, biXPelsPerMeter) ||
|
||||
!SDL_WriteU32LE(dst, biYPelsPerMeter) ||
|
||||
!SDL_WriteU32LE(dst, biClrUsed) ||
|
||||
!SDL_WriteU32LE(dst, biClrImportant)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Write the BMP info values for the version 4 header */
|
||||
if (save32bit && !saveLegacyBMP) {
|
||||
SDL_WriteLE32(dst, bV4RedMask);
|
||||
SDL_WriteLE32(dst, bV4GreenMask);
|
||||
SDL_WriteLE32(dst, bV4BlueMask);
|
||||
SDL_WriteLE32(dst, bV4AlphaMask);
|
||||
SDL_WriteLE32(dst, bV4CSType);
|
||||
for (i = 0; i < 3 * 3; i++) {
|
||||
SDL_WriteLE32(dst, bV4Endpoints[i]);
|
||||
if (!SDL_WriteU32LE(dst, bV4RedMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4GreenMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4BlueMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4AlphaMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4CSType)) {
|
||||
goto done;
|
||||
}
|
||||
for (i = 0; i < 3 * 3; i++) {
|
||||
if (!SDL_WriteU32LE(dst, bV4Endpoints[i])) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (!SDL_WriteU32LE(dst, bV4GammaRed) ||
|
||||
!SDL_WriteU32LE(dst, bV4GammaGreen) ||
|
||||
!SDL_WriteU32LE(dst, bV4GammaBlue)) {
|
||||
goto done;
|
||||
}
|
||||
SDL_WriteLE32(dst, bV4GammaRed);
|
||||
SDL_WriteLE32(dst, bV4GammaGreen);
|
||||
SDL_WriteLE32(dst, bV4GammaBlue);
|
||||
}
|
||||
|
||||
/* Write the palette (in BGR color order) */
|
||||
@ -818,21 +840,25 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
colors = intermediate_surface->format->palette->colors;
|
||||
ncolors = intermediate_surface->format->palette->ncolors;
|
||||
for (i = 0; i < ncolors; ++i) {
|
||||
SDL_RWwrite(dst, &colors[i].b, 1);
|
||||
SDL_RWwrite(dst, &colors[i].g, 1);
|
||||
SDL_RWwrite(dst, &colors[i].r, 1);
|
||||
SDL_RWwrite(dst, &colors[i].a, 1);
|
||||
if (!SDL_WriteU8(dst, colors[i].b) ||
|
||||
!SDL_WriteU8(dst, colors[i].g) ||
|
||||
!SDL_WriteU8(dst, colors[i].r) ||
|
||||
!SDL_WriteU8(dst, colors[i].a)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the bitmap offset */
|
||||
bfOffBits = (Uint32)(SDL_RWtell(dst) - fp_offset);
|
||||
if (SDL_RWseek(dst, fp_offset + 10, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
goto done;
|
||||
}
|
||||
if (!SDL_WriteU32LE(dst, bfOffBits)) {
|
||||
goto done;
|
||||
}
|
||||
SDL_WriteLE32(dst, bfOffBits);
|
||||
if (SDL_RWseek(dst, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Write the bitmap image upside down */
|
||||
@ -841,38 +867,53 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
while (bits > (Uint8 *)intermediate_surface->pixels) {
|
||||
bits -= intermediate_surface->pitch;
|
||||
if (SDL_RWwrite(dst, bits, bw) != bw) {
|
||||
SDL_Error(SDL_EFWRITE);
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
if (pad) {
|
||||
const Uint8 padbyte = 0;
|
||||
for (i = 0; i < pad; ++i) {
|
||||
SDL_RWwrite(dst, &padbyte, 1);
|
||||
if (!SDL_WriteU8(dst, padbyte)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the BMP file size */
|
||||
bfSize = (Uint32)(SDL_RWtell(dst) - fp_offset);
|
||||
if (SDL_RWseek(dst, fp_offset + 2, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
new_offset = SDL_RWtell(dst);
|
||||
if (new_offset < 0) {
|
||||
goto done;
|
||||
}
|
||||
bfSize = (Uint32)(new_offset - fp_offset);
|
||||
if (SDL_RWseek(dst, fp_offset + 2, SDL_RW_SEEK_SET) < 0) {
|
||||
goto done;
|
||||
}
|
||||
if (!SDL_WriteU32LE(dst, bfSize)) {
|
||||
goto done;
|
||||
}
|
||||
SDL_WriteLE32(dst, bfSize);
|
||||
if (SDL_RWseek(dst, fp_offset + bfSize, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Close it up.. */
|
||||
SDL_UnlockSurface(intermediate_surface);
|
||||
if (intermediate_surface != surface) {
|
||||
SDL_DestroySurface(intermediate_surface);
|
||||
}
|
||||
|
||||
was_error = SDL_FALSE;
|
||||
}
|
||||
|
||||
if (freedst && dst) {
|
||||
SDL_RWclose(dst);
|
||||
done:
|
||||
if (intermediate_surface && intermediate_surface != surface) {
|
||||
SDL_DestroySurface(intermediate_surface);
|
||||
}
|
||||
return (SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1;
|
||||
if (freedst && dst) {
|
||||
if (SDL_RWclose(dst) < 0) {
|
||||
was_error = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
if (was_error) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SaveBMP(SDL_Surface *surface, const char *file)
|
||||
|
Reference in New Issue
Block a user