From b298bad12c5112c4c1f08db9fe41560749ae910a Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 8 Aug 2023 15:50:42 -0700
Subject: [PATCH] Updated SDL_image for SDL read/write size_t change
---
external/SDL | 2 +-
src/IMG_WIC.c | 11 +-
src/IMG_avif.c | 26 +-
src/IMG_bmp.c | 116 +++--
src/IMG_jpg.c | 8 +-
src/IMG_pcx.c | 7 +-
src/IMG_pnm.c | 8 +-
src/IMG_stb.c | 15 +-
src/IMG_svg.c | 2 +-
src/IMG_tga.c | 8 +-
src/IMG_tif.c | 8 +-
src/IMG_webp.c | 19 +-
src/IMG_xcf.c | 1315 +++++++++++++++++++++++++-----------------------
src/IMG_xpm.c | 16 +-
src/IMG_xv.c | 2 +-
15 files changed, 820 insertions(+), 743 deletions(-)
diff --git a/external/SDL b/external/SDL
index a509771a..8a1afc9b 160000
--- a/external/SDL
+++ b/external/SDL
@@ -1 +1 @@
-Subproject commit a509771a87559ca040a40b5fef932a8220343f7a
+Subproject commit 8a1afc9b10e9153f764f562008795b415d0575e1
diff --git a/src/IMG_WIC.c b/src/IMG_WIC.c
index 869f3bf8..04da3ea8 100644
--- a/src/IMG_WIC.c
+++ b/src/IMG_WIC.c
@@ -220,15 +220,10 @@ static SDL_Surface* WIC_LoadImage(SDL_RWops *src)
return NULL;
}
- Sint64 fileSize = SDL_RWsize(src);
- Uint8* memoryBuffer = (Uint8*)SDL_malloc(fileSize);
+ size_t fileSize;
+ Uint8 *memoryBuffer = (Uint8 *)SDL_LoadFile_RW(src, &fileSize, SDL_FALSE);
if (!memoryBuffer) {
- SDL_OutOfMemory();
- return NULL;
- }
-
- if (SDL_RWread(src, memoryBuffer, fileSize) != fileSize) {
- return NULL;
+ return NULL;
}
#define DONE_IF_FAILED(X) if (FAILED((X))) { goto done; }
diff --git a/src/IMG_avif.c b/src/IMG_avif.c
index c99f0c57..3eab716b 100644
--- a/src/IMG_avif.c
+++ b/src/IMG_avif.c
@@ -91,8 +91,8 @@ void IMG_QuitAVIF(void)
static SDL_bool ReadAVIFHeader(SDL_RWops *src, Uint8 **header_data, size_t *header_size)
{
Uint8 magic[16];
- Sint64 size;
- Sint64 read = 0;
+ Uint64 size;
+ Uint64 read = 0;
Uint8 *data;
*header_data = NULL;
@@ -107,10 +107,10 @@ static SDL_bool ReadAVIFHeader(SDL_RWops *src, Uint8 **header_data, size_t *head
return SDL_FALSE;
}
- size = (((size_t)magic[0] << 24) |
- ((size_t)magic[1] << 16) |
- ((size_t)magic[2] << 8) |
- ((size_t)magic[3] << 0));
+ size = (((Uint64)magic[0] << 24) |
+ ((Uint64)magic[1] << 16) |
+ ((Uint64)magic[2] << 8) |
+ ((Uint64)magic[3] << 0));
if (size == 1) {
/* 64-bit header size */
if (SDL_RWread(src, &magic[8], 8) != 8) {
@@ -128,7 +128,7 @@ static SDL_bool ReadAVIFHeader(SDL_RWops *src, Uint8 **header_data, size_t *head
((Uint64)magic[15] << 0));
}
- if (size > INT_MAX) {
+ if (size > SDL_SIZE_MAX) {
return SDL_FALSE;
}
if (size <= read) {
@@ -142,7 +142,7 @@ static SDL_bool ReadAVIFHeader(SDL_RWops *src, Uint8 **header_data, size_t *head
}
SDL_memcpy(data, magic, (size_t)read);
- if (SDL_RWread(src, &data[read], (size - read)) != (size - read)) {
+ if (SDL_RWread(src, &data[read], (size_t)(size - read)) != (size_t)(size - read)) {
SDL_free(data);
return SDL_FALSE;
}
@@ -209,9 +209,13 @@ static avifResult ReadAVIFIO(struct avifIO * io, uint32_t readFlags, uint64_t of
}
out->data = context->data;
- out->size = (size_t)SDL_RWread(context->src, context->data, size);
- if (out->size <= 0) {
- return AVIF_RESULT_IO_ERROR;
+ out->size = SDL_RWread(context->src, context->data, size);
+ if (out->size == 0) {
+ if (context->src->status == SDL_RWOPS_STATUS_NOT_READY) {
+ return AVIF_RESULT_WAITING_ON_IO;
+ } else {
+ return AVIF_RESULT_IO_ERROR;
+ }
}
return AVIF_RESULT_OK;
diff --git a/src/IMG_bmp.c b/src/IMG_bmp.c
index 712a6405..ae684490 100644
--- a/src/IMG_bmp.c
+++ b/src/IMG_bmp.c
@@ -65,15 +65,17 @@ static int IMG_isICOCUR(SDL_RWops *src, int type)
Uint16 bfType;
Uint16 bfCount;
- if ( !src )
+ if (!src) {
return 0;
+ }
start = SDL_RWtell(src);
is_ICOCUR = 0;
- bfReserved = SDL_ReadLE16(src);
- bfType = SDL_ReadLE16(src);
- bfCount = SDL_ReadLE16(src);
- if ((bfReserved == 0) && (bfType == type) && (bfCount != 0))
+ if (SDL_ReadU16LE(src, &bfReserved) &&
+ SDL_ReadU16LE(src, &bfType) &&
+ SDL_ReadU16LE(src, &bfCount) &&
+ (bfReserved == 0) && (bfType == type) && (bfCount != 0)) {
is_ICOCUR = 1;
+ }
SDL_RWseek(src, start, SDL_RW_SEEK_SET);
return (is_ICOCUR);
@@ -121,8 +123,8 @@ LoadICOCUR_RW(SDL_RWops * src, int type, SDL_bool freesrc)
*/
Uint8 *bits;
int ExpandBMP;
- int maxCol = 0;
- int icoOfs = 0;
+ Uint8 maxCol = 0;
+ Uint32 icoOfs = 0;
Uint32 palette[256];
/* The Win32 ICO file header (14 bytes) */
@@ -152,12 +154,11 @@ LoadICOCUR_RW(SDL_RWops * src, int type, SDL_bool freesrc)
/* Read in the ICO file header */
fp_offset = SDL_RWtell(src);
- SDL_ClearError();
- bfReserved = SDL_ReadLE16(src);
- bfType = SDL_ReadLE16(src);
- bfCount = SDL_ReadLE16(src);
- if ((bfReserved != 0) || (bfType != type) || (bfCount == 0)) {
+ if (!SDL_ReadU16LE(src, &bfReserved) ||
+ !SDL_ReadU16LE(src, &bfType) ||
+ !SDL_ReadU16LE(src, &bfCount) ||
+ (bfReserved != 0) || (bfType != type) || (bfCount == 0)) {
IMG_SetError("File is not a Windows %s file", type == 1 ? "ICO" : "CUR");
goto done;
}
@@ -165,9 +166,9 @@ LoadICOCUR_RW(SDL_RWops * src, int type, SDL_bool freesrc)
/* Read the Win32 Icon Directory */
for (i = 0; i < bfCount; i++) {
/* Icon Directory Entries */
- int bWidth = SDL_ReadU8(src); /* Uint8, but 0 = 256 ! */
- int bHeight = SDL_ReadU8(src); /* Uint8, but 0 = 256 ! */
- int bColorCount = SDL_ReadU8(src); /* Uint8, but 0 = 256 ! */
+ Uint8 bWidth; /* Uint8, but 0 = 256 ! */
+ Uint8 bHeight; /* Uint8, but 0 = 256 ! */
+ Uint8 bColorCount; /* Uint8, but 0 = 256 ! */
/*
Uint8 bReserved;
Uint16 wPlanes;
@@ -175,57 +176,72 @@ LoadICOCUR_RW(SDL_RWops * src, int type, SDL_bool freesrc)
Uint32 dwBytesInRes;
*/
Uint32 dwImageOffset;
+ int nWidth, nHeight, nColorCount;
+
+ if (!SDL_ReadU8(src, &bWidth) ||
+ !SDL_ReadU8(src, &bHeight) ||
+ !SDL_ReadU8(src, &bColorCount) ||
+ !SDL_ReadU8(src, NULL /* bReserved */) ||
+ !SDL_ReadU16LE(src, NULL /* wPlanes */) ||
+ !SDL_ReadU16LE(src, NULL /* wBitCount */) ||
+ !SDL_ReadU32LE(src, NULL /* dwBytesInRes */) ||
+ !SDL_ReadU32LE(src, &dwImageOffset)) {
+ goto done;
+ }
+
+ if (bWidth) {
+ nWidth = bWidth;
+ } else {
+ nWidth = 256;
+ }
+ if (bHeight) {
+ nHeight = bHeight;
+ } else {
+ nHeight = 256;
+ }
+ if (bColorCount) {
+ nColorCount = bColorCount;
+ } else {
+ nColorCount = 256;
+ }
- /* bReserved = */ SDL_ReadU8(src);
- /* wPlanes = */ SDL_ReadLE16(src);
- /* wBitCount = */ SDL_ReadLE16(src);
- /* dwBytesInRes = */ SDL_ReadLE32(src);
- dwImageOffset = SDL_ReadLE32(src);
-
- if (!bWidth)
- bWidth = 256;
- if (!bHeight)
- bHeight = 256;
- if (!bColorCount)
- bColorCount = 256;
-
- //printf("%dx%d@%d - %08x\n", bWidth, bHeight, bColorCount, dwImageOffset);
- if (bColorCount > maxCol) {
- maxCol = bColorCount;
+ //SDL_Log("%dx%d@%d - %08x\n", nWidth, nHeight, nColorCount, dwImageOffset);
+ (void)nWidth;
+ (void)nHeight;
+ if (nColorCount > maxCol) {
+ maxCol = nColorCount;
icoOfs = dwImageOffset;
- //printf("marked\n");
+ //SDL_Log("marked\n");
}
}
/* Advance to the DIB Data */
if (SDL_RWseek(src, icoOfs, SDL_RW_SEEK_SET) < 0) {
- SDL_Error(SDL_EFSEEK);
goto done;
}
/* Read the Win32 BITMAPINFOHEADER */
- biSize = SDL_ReadLE32(src);
+ if (!SDL_ReadU32LE(src, &biSize)) {
+ goto done;
+ }
if (biSize == 40) {
- 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;
+ }
} else {
IMG_SetError("Unsupported ICO bitmap format");
goto done;
}
- /* Check for read error */
- if (SDL_strcmp(SDL_GetError(), "") != 0) {
- goto done;
- }
-
/* We don't support any BMP compression right now */
switch (biCompression) {
case BI_RGB:
@@ -354,7 +370,7 @@ LoadICOCUR_RW(SDL_RWops * src, int type, SDL_bool freesrc)
break;
default:
- if (SDL_RWread(src, bits, surface->pitch) != surface->pitch) {
+ if (SDL_RWread(src, bits, surface->pitch) != (size_t)surface->pitch) {
goto done;
}
break;
diff --git a/src/IMG_jpg.c b/src/IMG_jpg.c
index 3bc69388..afba6b91 100644
--- a/src/IMG_jpg.c
+++ b/src/IMG_jpg.c
@@ -155,7 +155,7 @@ int IMG_isJPG(SDL_RWops *src)
start = SDL_RWtell(src);
is_JPG = 0;
in_scan = 0;
- if ( SDL_RWread(src, magic, 2) == 2 ) {
+ if (SDL_RWread(src, magic, 2) == 2) {
if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) {
is_JPG = 1;
while (is_JPG == 1) {
@@ -228,10 +228,10 @@ static void init_source (j_decompress_ptr cinfo)
static boolean fill_input_buffer (j_decompress_ptr cinfo)
{
my_source_mgr * src = (my_source_mgr *) cinfo->src;
- int nbytes;
+ size_t nbytes;
- nbytes = (int)SDL_RWread(src->ctx, src->buffer, INPUT_BUFFER_SIZE);
- if (nbytes <= 0) {
+ nbytes = SDL_RWread(src->ctx, src->buffer, INPUT_BUFFER_SIZE);
+ if (nbytes == 0) {
/* Insert a fake EOI marker */
src->buffer[0] = (Uint8) 0xFF;
src->buffer[1] = (Uint8) JPEG_EOI;
diff --git a/src/IMG_pcx.c b/src/IMG_pcx.c
index c904e4f1..17b57e7c 100644
--- a/src/IMG_pcx.c
+++ b/src/IMG_pcx.c
@@ -91,7 +91,8 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
struct PCXheader pcxh;
SDL_Surface *surface = NULL;
int width, height;
- int y, bpl;
+ int y;
+ size_t bpl;
Uint8 *row, *buf = NULL;
char *error = NULL;
int bits, src_bits;
@@ -158,7 +159,7 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
row = (Uint8 *)surface->pixels;
for ( y=0; y<surface->h; ++y ) {
/* decode a scan line to a temporary buffer first */
- int i;
+ size_t i;
if ( pcxh.Encoding == 0 ) {
if ( SDL_RWread(src, buf, bpl) != bpl ) {
error = "file truncated";
@@ -205,7 +206,7 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
}
} else if ( src_bits == 8 ) {
/* Copy the row directly */
- SDL_memcpy(row, buf, SDL_min(width, bpl));
+ SDL_memcpy(row, buf, SDL_min((size_t)width, bpl));
} else if ( src_bits == 24 ) {
/* de-interlace planes */
Uint8 *innerSrc = buf;
diff --git a/src/IMG_pnm.c b/src/IMG_pnm.c
index 6cc24884..cff39115 100644
--- a/src/IMG_pnm.c
+++ b/src/IMG_pnm.c
@@ -111,7 +111,8 @@ SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src)
Sint64 start;
SDL_Surface *surface = NULL;
int width, height;
- int maxval, y, bpl;
+ int maxval, y;
+ size_t bpl;
Uint8 *row;
Uint8 *buf = NULL;
char *error = NULL;
@@ -184,8 +185,8 @@ SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src)
row = (Uint8 *)surface->pixels;
for(y = 0; y < height; y++) {
if(ascii) {
- int i;
if(kind == PBM) {
+ int i;
for(i = 0; i < width; i++) {
Uint8 ch;
do {
@@ -196,6 +197,7 @@ SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src)
row[i] = ch;
}
} else {
+ size_t i;
for(i = 0; i < bpl; i++) {
int c;
c = ReadNumber(src);
@@ -219,7 +221,7 @@ SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src)
}
if(maxval < 255) {
/* scale up to full dynamic range (slow) */
- int i;
+ size_t i;
for(i = 0; i < bpl; i++)
row[i] = row[i] * 255 / maxval;
}
diff --git a/src/IMG_stb.c b/src/IMG_stb.c
index 0497285d..acfc3fa3 100644
--- a/src/IMG_stb.c
+++ b/src/IMG_stb.c
@@ -59,10 +59,7 @@
static int IMG_LoadSTB_RW_read(void *user, char *data, int size)
{
- Sint64 amount = SDL_RWread((SDL_RWops*)user, data, size);
- if (amount <= 0) {
- return 0;
- }
+ size_t amount = SDL_RWread((SDL_RWops*)user, data, size);
return (int)amount;
}
@@ -73,16 +70,8 @@ static void IMG_LoadSTB_RW_skip(void *user, int n)
static int IMG_LoadSTB_RW_eof(void *user)
{
- /* FIXME: Do we not have a way to detect EOF? -flibit */
- Uint8 filler;
- Sint64 bytes;
SDL_RWops *src = (SDL_RWops*)user;
- bytes = SDL_RWread(src, &filler, sizeof(filler));
- if (bytes != 1) { /* FIXME: Could also be an error... */
- return 1;
- }
- SDL_RWseek(src, -1, SDL_RW_SEEK_CUR);
- return 0;
+ return (src->status == SDL_RWOPS_STATUS_EOF);
}
SDL_Surface *IMG_LoadSTB_RW(SDL_RWops *src)
diff --git a/src/IMG_svg.c b/src/IMG_svg.c
index fb57bc3f..3271197e 100644
--- a/src/IMG_svg.c
+++ b/src/IMG_svg.c
@@ -90,7 +90,7 @@ int IMG_isSVG(SDL_RWops *src)
Sint64 start;
int is_SVG;
char magic[4096];
- Sint64 magic_len;
+ size_t magic_len;
if (!src)
return 0;
diff --git a/src/IMG_tga.c b/src/IMG_tga.c
index 14a707e4..65cde7a3 100644
--- a/src/IMG_tga.c
+++ b/src/IMG_tga.c
@@ -186,7 +186,7 @@ SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
}
if (hdr.has_cmap) {
- int palsiz = ncols * ((hdr.cmap_bits + 7) >> 3);
+ size_t palsiz = ncols * ((hdr.cmap_bits + 7) >> 3);
if (indexed && !grey) {
Uint8 *pal = (Uint8 *)SDL_malloc(palsiz), *p = pal;
SDL_Color *colors = img->format->palette->colors;
@@ -254,7 +254,7 @@ SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
int n = count;
if (n > w - x)
n = w - x;
- if (SDL_RWread(src, dst + x * bpp, n * bpp) != (n * bpp)) {
+ if (SDL_RWread(src, dst + x * bpp, n * bpp) != (size_t)(n * bpp)) {
error = "Error reading TGA data";
goto error;
}
@@ -280,7 +280,7 @@ SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
goto error;
}
if (c & 0x80) {
- if (SDL_RWread(src, &pixel, bpp) != bpp) {
+ if (SDL_RWread(src, &pixel, bpp) != (size_t)bpp) {
error = "Error reading TGA data";
goto error;
}
@@ -290,7 +290,7 @@ SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
}
}
} else {
- if (SDL_RWread(src, dst, w * bpp) != (w * bpp)) {
+ if (SDL_RWread(src, dst, w * bpp) != (size_t)(w * bpp)) {
error = "Error reading TGA data";
goto error;
}
diff --git a/src/IMG_tif.c b/src/IMG_tif.c
index b01e5efd..548d97af 100644
--- a/src/IMG_tif.c
+++ b/src/IMG_tif.c
@@ -88,11 +88,7 @@ void IMG_QuitTIF(void)
static tsize_t tiff_read(thandle_t fd, tdata_t buf, tsize_t size)
{
- Sint64 amount = SDL_RWread((SDL_RWops*)fd, buf, size);
- if (amount <= 0) {
- return 0;
- }
- return (tsize_t)amount;
+ return SDL_RWread((SDL_RWops*)fd, buf, size);
}
static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin)
@@ -102,7 +98,7 @@ static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin)
static tsize_t tiff_write(thandle_t fd, tdata_t buf, tsize_t size)
{
- return (tsize_t)SDL_RWwrite((SDL_RWops*)fd, buf, size);
+ return SDL_RWwrite((SDL_RWops*)fd, buf, size);
}
static int tiff_close(thandle_t fd)
diff --git a/src/IMG_webp.c b/src/IMG_webp.c
index 8e13ea90..bb862061 100644
--- a/src/IMG_webp.c
+++ b/src/IMG_webp.c
@@ -111,8 +111,8 @@ void IMG_QuitWEBP(void)
--lib.loaded;
}
-static int webp_getinfo (SDL_RWops *src, int *datasize) {
- Sint64 start;
+static int webp_getinfo(SDL_RWops *src, size_t *datasize) {
+ Sint64 start, size;
int is_WEBP;
Uint8 magic[20];
@@ -136,7 +136,12 @@ static int webp_getinfo (SDL_RWops *src, int *datasize) {
(magic[15] == ' ' || magic[15] == 'X' || magic[15] == 'L')) {
is_WEBP = 1;
if (datasize) {
- *datasize = (int)(SDL_RWseek(src, 0, SDL_RW_SEEK_END) - start);
+ size = SDL_RWsize(src);
+ if (size > 0) {
+ *datasize = (size_t)(size - start);
+ } else {
+ *datasize = 0;
+ }
}
}
}
@@ -157,7 +162,7 @@ SDL_Surface *IMG_LoadWEBP_RW(SDL_RWops *src)
SDL_Surface *surface = NULL;
Uint32 format;
WebPBitstreamFeatures features;
- int raw_data_size;
+ size_t raw_data_size;
uint8_t *raw_data = NULL;
uint8_t *ret;
@@ -184,7 +189,7 @@ SDL_Surface *IMG_LoadWEBP_RW(SDL_RWops *src)
goto error;
}
- if (SDL_RWread(src, raw_data, raw_data_size) != (Sint64)raw_data_size) {
+ if (SDL_RWread(src, raw_data, raw_data_size) != raw_data_size) {
error = "Failed to read WEBP";
goto error;
}
@@ -259,7 +264,7 @@ IMG_Animation *IMG_LoadWEBPAnimation_RW(SDL_RWops *src)
struct WebPDemuxer* dmuxer = NULL;
WebPIterator iter;
IMG_Animation *anim = NULL;
- int raw_data_size;
+ size_t raw_data_size;
uint8_t *raw_data = NULL;
uint8_t *ret;
int frame_idx;
@@ -288,7 +293,7 @@ IMG_Animation *IMG_LoadWEBPAnimation_RW(SDL_RWops *src)
goto error;
}
- if (SDL_RWread(src, raw_data, raw_data_size) != (Sint64)raw_data_size) {
+ if (SDL_RWread(src, raw_data, raw_data_size) != raw_data_size) {
error = "Failed to read WEBP Animation";
goto error;
}
diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
index 1617ebbf..a1b117d0 100644
--- a/src/IMG_xcf.c
+++ b/src/IMG_xcf.c
@@ -38,627 +38,689 @@
#if DEBUG
static char prop_names [][30] = {
- "end",
- "colormap",
- "active_layer",
- "active_channel",
- "selection",
- "floating_selection",
- "opacity",
- "mode",
- "visible",
- "linked",
- "preserve_transparency",
- "apply_mask",
- "edit_mask",
- "show_mask",
- "show_masked",
- "offsets",
- "color",
- "compression",
- "guides",
- "resolution",
- "tattoo",
- "parasites",
- "unit",
- "paths",
- "user_unit"
+ "end",
+ "colormap",
+ "active_layer",
+ "active_channel",
+ "selection",
+ "floating_selection",
+ "opacity",
+ "mode",
+ "visible",
+ "linked",
+ "preserve_transparency",
+ "apply_mask",
+ "edit_mask",
+ "show_mask",
+ "show_masked",
+ "offsets",
+ "color",
+ "compression",
+ "guides",
+ "resolution",
+ "tattoo",
+ "parasites",
+ "unit",
+ "paths",
+ "user_unit"
};
#endif
typedef enum
{
- PROP_END = 0,
- PROP_COLORMAP = 1,
- PROP_ACTIVE_LAYER = 2,
- PROP_ACTIVE_CHANNEL = 3,
- PROP_SELECTION = 4,
- PROP_FLOATING_SELECTION = 5,
- PROP_OPACITY = 6,
- PROP_MODE = 7,
- PROP_VISIBLE = 8,
- PROP_LINKED = 9,
- PROP_PRESERVE_TRANSPARENCY = 10,
- PROP_APPLY_MASK = 11,
- PROP_EDIT_MASK = 12,
- PROP_SHOW_MASK = 13,
- PROP_SHOW_MASKED = 14,
- PROP_OFFSETS = 15,
- PROP_COLOR = 16,
- PROP_COMPRESSION = 17,
- PROP_GUIDES = 18,
- PROP_RESOLUTION = 19,
- PROP_TATTOO = 20,
- PROP_PARASITES = 21,
- PROP_UNIT = 22,
- PROP_PATHS = 23,
- PROP_USER_UNIT = 24
+ PROP_END = 0,
+ PROP_COLORMAP = 1,
+ PROP_ACTIVE_LAYER = 2,
+ PROP_ACTIVE_CHANNEL = 3,
+ PROP_SELECTION = 4,
+ PROP_FLOATING_SELECTION = 5,
+ PROP_OPACITY = 6,
+ PROP_MODE = 7,
+ PROP_VISIBLE = 8,
+ PROP_LINKED = 9,
+ PROP_PRESERVE_TRANSPARENCY = 10,
+ PROP_APPLY_MASK = 11,
+ PROP_EDIT_MASK = 12,
+ PROP_SHOW_MASK = 13,
+ PROP_SHOW_MASKED = 14,
+ PROP_OFFSETS = 15,
+ PROP_COLOR = 16,
+ PROP_COMPRESSION = 17,
+ PROP_GUIDES = 18,
+ PROP_RESOLUTION = 19,
+ PROP_TATTOO = 20,
+ PROP_PARASITES = 21,
+ PROP_UNIT = 22,
+ PROP_PATHS = 23,
+ PROP_USER_UNIT = 24
} xcf_prop_type;
typedef enum {
- COMPR_NONE = 0,
- COMPR_RLE = 1,
- COMPR_ZLIB = 2,
- COMPR_FRACTAL = 3
+ COMPR_NONE = 0,
+ COMPR_RLE = 1,
+ COMPR_ZLIB = 2,
+ COMPR_FRACTAL = 3
} xcf_compr_type;
typedef enum {
- IMAGE_RGB = 0,
- IMAGE_GREYSCALE = 1,
- IMAGE_INDEXED = 2
+ IMAGE_RGB = 0,
+ IMAGE_GREYSCALE = 1,
+ IMAGE_INDEXED = 2
} xcf_image_type;
typedef struct {
- Uint32 id;
- Uint32 length;
- union {
- struct {
- Uint32 num;
- char * cmap;
- } colormap; // 1
- struct {
- Uint32 drawable_offset;
- } floating_selection; // 5
- Sint32 opacity;
- Sint32 mode;
- int visible;
- int linked;
- int preserve_transparency;
- int apply_mask;
- int show_mask;
- struct {
- Sint32 x;
- Sint32 y;
- } offset;
- unsigned char color [3];
- Uint8 compression;
- struct {
- Sint32 x;
- Sint32 y;
- } resolution;
- struct {
- char * name;
- Uint32 flags;
- Uint32 size;
- char * data;
- } parasite;
- } data;
+ Uint32 id;
+ Uint32 length;
+ union {
+ struct {
+ Uint32 num;
+ char *cmap;
+ } colormap; /* 1 */
+ struct {
+ Uint32 drawable_offset;
+ } floating_selection; /* 5 */
+ Uint32 opacity;
+ Uint32 mode;
+ Uint32 visible;
+ int linked;
+ int preserve_transparency;
+ int apply_mask;
+ int show_mask;
+ struct {
+ Sint32 x;
+ Sint32 y;
+ } offset;
+ unsigned char color[3];
+ Uint8 compression;
+ struct {
+ Sint32 x;
+ Sint32 y;
+ } resolution;
+ struct {
+ char *name;
+ Uint32 flags;
+ Uint32 size;
+ char *data;
+ } parasite;
+ } data;
} xcf_prop;
typedef struct {
- char sign [14];
- Uint32 file_version;
- Uint32 width;
- Uint32 height;
- Sint32 image_type;
- Uint32 precision;
- xcf_prop * properties;
-
- Uint32 * layer_file_offsets;
- Uint32 * channel_file_offsets;
-
- xcf_compr_type compr;
- Uint32 cm_num;
- unsigned char * cm_map;
+ char sign[14];
+ Uint32 file_version;
+ Uint32 width;
+ Uint32 height;
+ Uint32 image_type;
+ Uint32 precision;
+ xcf_prop *properties;
+
+ Uint64 *layer_file_offsets;
+ Uint64 *channel_file_offsets;
+
+ xcf_compr_type compr;
+ Uint32 cm_num;
+ unsigned char *cm_map;
} xcf_header;
typedef struct {
- Uint32 width;
- Uint32 height;
- Sint32 layer_type;
- char * name;
- xcf_prop * properties;
-
- Uint64 hierarchy_file_offset;
- Uint64 layer_mask_offset;
-
- Uint32 offset_x;
- Uint32 offset_y;
- int visible;
+ Uint32 width;
+ Uint32 height;
+ Uint32 layer_type;
+ char *name;
+ xcf_prop *properties;
+
+ Uint64 hierarchy_file_offset;
+ Uint64 layer_mask_offset;
+
+ Uint32 offset_x;
+ Uint32 offset_y;
+ int visible;
} xcf_layer;
typedef struct {
- Uint32 width;
- Uint32 height;
- char * name;
- xcf_prop * properties;
+ Uint32 width;
+ Uint32 height;
+ char *name;
+ xcf_prop *properties;
- Uint64 hierarchy_file_offset;
+ Uint64 hierarchy_file_offset;
- Uint32 color;
- Uint32 opacity;
- int selection;
- int visible;
+ Uint32 color;
+ Uint32 opacity;
+ int selection;
+ int visible;
} xcf_channel;
typedef struct {
- Uint32 width;
- Uint32 height;
- Uint32 bpp;
+ Uint32 width;
+ Uint32 height;
+ Uint32 bpp;
- Uint64 * level_file_offsets;
+ Uint64 *level_file_offsets;
} xcf_hierarchy;
typedef struct {
- Uint32 width;
- Uint32 height;
+ Uint32 width;
+ Uint32 height;
- Uint64 * tile_file_offsets;
+ Uint64 *tile_file_offsets;
} xcf_level;
-typedef unsigned char * xcf_tile;
+typedef unsigned char *xcf_tile;
-typedef unsigned char * (*load_tile_type) (SDL_RWops *, Uint64, int, int, int);
+typedef unsigned char *(*load_tile_type)(SDL_RWops *, size_t, int, int, int);
/* See if an image is contained in a data source */
int IMG_isXCF(SDL_RWops *src)
{
Sint64 start;
- int is_XCF;
+ int is_XCF = 0;
char magic[14];
- if ( !src )
- return 0;
- start = SDL_RWtell(src);
- is_XCF = 0;
- if ( SDL_RWread(src, magic, sizeof(magic)) == sizeof(magic) ) {
- if (SDL_strncmp(magic, "gimp xcf ", 9) == 0) {
- is_XCF = 1;
+ if (src) {
+ start = SDL_RWtell(src);
+ if (SDL_RWread(src, magic, sizeof(magic)) == sizeof(magic)) {
+ if (SDL_strncmp(magic, "gimp xcf ", 9) == 0) {
+ is_XCF = 1;
+ }
}
+ SDL_RWseek(src, start, SDL_RW_SEEK_SET);
}
- SDL_RWseek(src, start, SDL_RW_SEEK_SET);
- return(is_XCF);
+ return is_XCF;
}
-static char * read_string (SDL_RWops * src) {
- Sint64 remaining;
- Uint32 tmp;
- char * data;
-
- tmp = SDL_ReadBE32(src);
- remaining = SDL_RWsize(src) - SDL_RWtell(src);
- if (tmp > 0 && (Sint32)tmp <= remaining) {
- data = (char *) SDL_malloc (sizeof (char) * tmp);
- if (data) {
- if (SDL_RWread(src, data, tmp) == tmp) {
- data[tmp - 1] = '\0';
- } else {
- SDL_free(data);
- data = NULL;
- }
- }
- } else {
- data = NULL;
- }
- return data;
-}
-
-static Uint64 read_offset (SDL_RWops * src, const xcf_header * h) {
- Uint64 offset; // starting with version 11, offsets are 64 bits
- offset = (h->file_version >= 11) ? (Uint64)SDL_ReadBE32 (src) << 32 : 0;
- offset |= SDL_ReadBE32 (src);
- return offset;
+static char *read_string(SDL_RWops *src)
+{
+ Sint64 remaining;
+ Uint32 tmp;
+ char *data = NULL;
+
+ if (SDL_ReadU32BE(src, &tmp)) {
+ remaining = SDL_RWsize(src) - SDL_RWtell(src);
+ if (tmp <= remaining) {
+ data = (char *)SDL_malloc(tmp);
+ if (data) {
+ if (SDL_RWread(src, data, tmp) == tmp) {
+ data[tmp - 1] = '\0';
+ } else {
+ SDL_free(data);
+ data = NULL;
+ }
+ }
+ }
+ }
+ return data;
}
+static Uint64 read_offset(SDL_RWops *src, const xcf_header *h)
+{
+ Uint64 offset = 0; /* starting with version 11, offsets are 64 bits */
+ Uint32 offset32;
-static Uint32 Swap32 (Uint32 v) {
- return
- ((v & 0x000000FF) << 16)
- | ((v & 0x0000FF00))
- | ((v & 0x00FF0000) >> 16)
- | ((v & 0xFF000000));
+ if (h->file_version >= 11) {
+ if (SDL_ReadU32BE(src, &offset32)) {
+ offset |= offset32;
+ offset <<= 32;
+ }
+ }
+ if (SDL_ReadU32BE(src, &offset32)) {
+ offset |= offset32;
+ }
+ return offset;
}
-static int xcf_read_property (SDL_RWops * src, xcf_prop * prop) {
- Uint32 len;
- prop->id = SDL_ReadBE32 (src);
- prop->length = SDL_ReadBE32 (src);
+static int xcf_read_property(SDL_RWops *src, xcf_prop *prop)
+{
+ Uint32 len;
+
+ if (!SDL_ReadU32BE(src, &prop->id) ||
+ !SDL_ReadU32BE(src, &prop->length)) {
+ return 0;
+ }
#if DEBUG
- printf ("%.8" SDL_PRIs64 ": %s(%u): %u\n", SDL_RWtell (src), prop->id < 25 ? prop_names [prop->id] : "unknown", prop->id, prop->length);
+ SDL_Log("%.8" SDL_PRIs64 ": %s(%u): %u\n", SDL_RWtell (src), prop->id < 25 ? prop_names [prop->id] : "unknown", prop->id, prop->length);
#endif
- switch (prop->id) {
- case PROP_COLORMAP:
- prop->data.colormap.num = SDL_ReadBE32 (src);
- prop->data.colormap.cmap = (char *) SDL_malloc (sizeof (char) * prop->data.colormap.num * 3);
- if ( SDL_RWread(src, prop->data.colormap.cmap, prop->data.colormap.num*3) != prop->data.colormap.num*3 ) {
- return 0;
- }
- break;
-
- case PROP_OFFSETS:
- prop->data.offset.x = SDL_ReadBE32 (src);
- prop->data.offset.y = SDL_ReadBE32 (src);
- break;
- case PROP_OPACITY:
- prop->data.opacity = SDL_ReadBE32 (src);
- break;
- case PROP_COMPRESSION:
- case PROP_COLOR:
- if (prop->length > sizeof(prop->data)) {
- len = sizeof(prop->data);
- } else {
- len = prop->length;
- }
- if ( SDL_RWread(src, &prop->data, len) != len ) {
- return 0;
+ switch (prop->id) {
+ case PROP_COLORMAP:
+ if (!SDL_ReadU32BE(src, &prop->data.colormap.num)) {
+ return 0;
+ }
+ prop->data.colormap.cmap = (char *)SDL_malloc(sizeof(char) * prop->data.colormap.num * 3);
+ if (!prop->data.colormap.cmap) {
+ return 0;
+ }
+ if (SDL_RWread(src, prop->data.colormap.cmap, prop->data.colormap.num * 3) != prop->data.colormap.num * 3) {
+ SDL_free(prop->data.colormap.cmap);
+ return 0;
+ }
+ break;
+
+ case PROP_OFFSETS:
+ if (!SDL_ReadS32BE(src, &prop->data.offset.x) ||
+ !SDL_ReadS32BE(src, &prop->data.offset.y)) {
+ return 0;
+ }
+ break;
+ case PROP_OPACITY:
+ if (!SDL_ReadU32BE(src, &prop->data.opacity)) {
+ return 0;
+ }
+ break;
+ case PROP_COMPRESSION:
+ case PROP_COLOR:
+ if (prop->length > sizeof(prop->data)) {
+ len = sizeof(prop->data);
+ } else {
+ len = prop->length;
+ }
+ if (SDL_RWread(src, &prop->data, len) != len) {
+ return 0;
+ }
+ break;
+ case PROP_VISIBLE:
+ if (!SDL_ReadU32BE(src, &prop->data.visible)) {
+ return 0;
+ }
+ break;
+ default:
+ if (SDL_RWseek(src, prop->length, SDL_RW_SEEK_CUR) < 0)
+ return 0; /* ERROR */
}
- break;
- case PROP_VISIBLE:
- prop->data.visible = SDL_ReadBE32 (src);
- break;
- default:
- // SDL_RWread (src, &prop->data, prop->length);
- if (SDL_RWseek (src, prop->length, SDL_RW_SEEK_CUR) < 0)
- return 0; // ERROR
- }
- retur
(Patch may be truncated, please check the link at the top of this post.)