SDL_image: Updated SDL_image for SDL read/write size_t change

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.)