Control: tags -1 - moreinfo

[ Reason ]
Fix CVE-2026-35444 and various other out-of-bounds accesses when parsing 
malformed/crafted image files

[ Impact ]
If not fixed, games/applications that load untrusted images using 
SDL2_image could be subject to denial-of-service (crash) or possibly 
exploitable.

[ Tests ]
autopkgtest (automated smoke-tests loading images in various formats) 
passes. Some sample games from trixie that depend on this library 
(assaultcube, wesnoth) appear to run normally. As with SDL3_image, I 
haven't attempted to load malformed/crafted/malicious images.

A test-build (equivalent except for the changelog) is available from 
<https://people.debian.org/~smcv/13.7/libsdl2-image/testbuild/>.

[ Risks ]
Could regress image loading in SDL2 games, especially in weird/rare 
formats. I suspect that in practice, none of our games/applications rely 
on being able to load the affected formats (*maybe* GIF and TGA).

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
All changes are robustness fixes from upstream. Most are fixed in 3.4.2 
or 3.4.4 upstream. One is not in an upstream release yet, I backported 
it into forky already.

[ Other info ]
Related to https://bugs.debian.org/1145180 for libsdl3-image, a newer 
branch of the same codebase.

Compared with the earlier proposal from Aquila Macedo Costa, this one 
addresses all known out-of-bounds accesses, not just the one that (for 
whatever reason) had a CVE ID allocated upstream.
diffstat for libsdl2-image-2.8.8+dfsg libsdl2-image-2.8.8+dfsg

 debian/changelog                                                               |   38 ++++
 debian/control                                                                 |    2 
 debian/gbp.conf                                                                |    2 
 debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch |   33 +++
 debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch     |   33 +++
 debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch                    |   31 +++
 debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch |   90 ++++++++++
 debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch |   25 ++
 debian/patches/series                                                          |   11 +
 debian/patches/tga-reject-images-with-zero-width-or-height.patch               |   39 ++++
 debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch |   24 ++
 debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch |   60 ++++++
 debian/patches/xcf-Permit-empty-strings-in-read_string.patch                   |   34 +++
 debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch |   39 ++++
 debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch |   43 ++++
 src/IMG_gif.c                                                                  |    6 
 src/IMG_lbm.c                                                                  |    7 
 src/IMG_tga.c                                                                  |    4 
 src/IMG_xcf.c                                                                  |   87 +++++++--
 src/IMG_xpm.c                                                                  |   11 -
 20 files changed, 587 insertions(+), 32 deletions(-)

diff -Nru libsdl2-image-2.8.8+dfsg/debian/changelog libsdl2-image-2.8.8+dfsg/debian/changelog
--- libsdl2-image-2.8.8+dfsg/debian/changelog	2025-03-04 09:59:59.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/debian/changelog	2026-08-23 14:45:36.000000000 +0100
@@ -1,3 +1,41 @@
+libsdl2-image (2.8.8+dfsg-1+deb13u1) trixie; urgency=medium
+
+  [ Aquila Macedo Costa ]
+  * d/p/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch:
+    Import upstream patch for CVE-2026-35444 (Closes: #1133010)
+  * d/patches: Add selected upstream malformed-image parser robustness fixes:
+    - d/p/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch:
+      check XPM color hash entries before use
+    - d/p/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch:
+      fix LBM palette overflow
+    - d/p/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch:
+      add XCF RLE decoder bounds checks
+    - d/p/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch,
+      d/p/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch:
+      add XCF do_layer_surface tile bounds check, report invalid XCF tile data
+      through SDL_SetError()
+    - d/p/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch:
+      check XCF hierarchy read failures before dereferencing
+    - d/p/tga-reject-images-with-zero-width-or-height.patch:
+      reject TGA images with zero width or height
+    - d/p/Fixed-out-of-bound-read-in-GIF-decoder.patch:
+      fix out-of-bounds reads in the GIF decoder
+
+  [ Simon McVittie ]
+  * d/control, d/gbp.conf: Branch for trixie
+  * d/patches: Improve patch metadata: add CVE ID, Debian bug number,
+    upstream commit references, etc.
+  * d/patches: Re-export patches with their mechanically-generated names and
+    apply them in the same order that upstream did, to make it more obvious
+    how this version compares with 2.8.12
+  * d/patches: Add additional robustness fixes for parsing malformed images:
+    - d/p/xcf-Permit-empty-strings-in-read_string.patch:
+      Avoid an out-of-bounds write if XCF files contain a zero-length string
+    - d/p/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch:
+      Harden XCF parsing against extremely long strings
+
+ -- Simon McVittie <[email protected]>  Sun, 23 Aug 2026 14:45:36 +0100
+
 libsdl2-image (2.8.8+dfsg-1) unstable; urgency=medium
 
   * New upstream stable release
diff -Nru libsdl2-image-2.8.8+dfsg/debian/control libsdl2-image-2.8.8+dfsg/debian/control
--- libsdl2-image-2.8.8+dfsg/debian/control	2025-03-04 09:59:59.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/debian/control	2026-08-23 14:45:36.000000000 +0100
@@ -15,7 +15,7 @@
 Standards-Version: 4.7.2
 Homepage: https://github.com/libsdl-org/SDL_image
 Vcs-Browser: https://salsa.debian.org/sdl-team/libsdl2-image
-Vcs-Git: https://salsa.debian.org/sdl-team/libsdl2-image.git
+Vcs-Git: https://salsa.debian.org/sdl-team/libsdl2-image.git -b debian/trixie
 
 Package: libsdl2-image-2.0-0
 Architecture: any
diff -Nru libsdl2-image-2.8.8+dfsg/debian/gbp.conf libsdl2-image-2.8.8+dfsg/debian/gbp.conf
--- libsdl2-image-2.8.8+dfsg/debian/gbp.conf	2025-03-04 09:59:59.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/debian/gbp.conf	2026-08-23 14:45:36.000000000 +0100
@@ -1,6 +1,6 @@
 [DEFAULT]
 pristine-tar = True
-debian-branch = debian/latest
+debian-branch = debian/trixie
 upstream-branch = upstream/latest
 
 [tag]
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bound-read-in-GIF-decoder.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,31 @@
+From: Sam Lantinga <[email protected]>
+Date: Wed, 29 Apr 2026 08:18:09 -0700
+Subject: Fixed out of bound read in GIF decoder
+
+Fixes https://github.com/libsdl-org/SDL_image/issues/724
+
+(cherry picked from commit e2b258927d11438cbf4ee55a5c4ff059a6e32d08)
+(cherry picked from commit 2c02f371f55a2f74a291639d95761066ac2afff0)
+Bug: https://github.com/libsdl-org/SDL_image/issues/724
+Origin: upstream, 2.8.12, commit:38fdd07d43a01b604fffb7453bff3ae2e9fd339a
+---
+ src/IMG_gif.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/IMG_gif.c b/src/IMG_gif.c
+index 58667e9..240bb7d 100644
+--- a/src/IMG_gif.c
++++ b/src/IMG_gif.c
+@@ -469,8 +469,10 @@ GetCode(SDL_RWops *src, int code_size, int flag, State_t * state)
+                 RWSetMsg("ran off the end of my bits");
+             return -1;
+         }
+-        state->buf[0] = state->buf[state->last_byte - 2];
+-        state->buf[1] = state->buf[state->last_byte - 1];
++        if (state->last_byte > 2) {
++            state->buf[0] = state->buf[state->last_byte - 2];
++            state->buf[1] = state->buf[state->last_byte - 1];
++        }
+ 
+         if ((ret = GetDataBlock(src, &state->buf[2], state)) > 0)
+             count = (unsigned char) ret;
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,90 @@
+From: Sam Lantinga <[email protected]>
+Date: Thu, 2 Apr 2026 08:41:46 -0700
+Subject: Fixed out of bounds read in XCF image loader (thanks @Sebasteuo!)
+
+(cherry picked from commit f55d589ba5de11c724afcdcae80b56bf26d91d15)
+(cherry picked from commit a1a06276a51ca7e6e63908b200df8a278d8c5039)
+Origin: upstream, 2.8.10, commit:fa9ffb8cced56aba2a2ab27d7c4388278e6b70c0
+Bug: https://github.com/libsdl-org/SDL_image/security/advisories/GHSA-gq8w-x74c-h6p7
+Bug-CVE: https://security-tracker.debian.org/tracker/CVE-2026-35444
+Bug-Debian: https://bugs.debian.org/1133010
+---
+ src/IMG_xcf.c | 50 ++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 30 insertions(+), 20 deletions(-)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index 95c1526..a1683ec 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -716,20 +716,26 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+                     switch (head->image_type) {
+                     case IMAGE_INDEXED:
+                         for (x = tx; x < tx + ox; x++) {
+-                            *row = ((Uint32)(head->cm_map[*p8 * 3]) << 16);
+-                            *row |= ((Uint32)(head->cm_map[*p8 * 3 + 1]) << 8);
+-                            *row |= ((Uint32)(head->cm_map[*p8++ * 3 + 2]) << 0);
+-                            *row |= ((Uint32)*p8++ << 24);
+-                            row++;
++                            Uint8 c = *p8++;
++                            Uint8 a = *p8++;
++                            if (c < head->cm_num) {
++                                *row++ = ((Uint32)(head->cm_map[c * 3]) << 16) |
++                                         ((Uint32)(head->cm_map[c * 3 + 1]) << 8) |
++                                         ((Uint32)(head->cm_map[c * 3 + 2]) << 0) |
++                                         ((Uint32)a << 24);
++                            } else {
++                                *row++ = 0;
++                            }
+                         }
+                         break;
+                     case IMAGE_GREYSCALE:
+                         for (x = tx; x < tx + ox; x++) {
+-                            *row = ((Uint32)*p8 << 16);
+-                            *row |= ((Uint32)*p8 << 8);
+-                            *row |= ((Uint32)*p8++ << 0);
+-                            *row |= ((Uint32)*p8++ << 24);
+-                            row++;
++                            Uint8 c = *p8++;
++                            Uint8 a = *p8++;
++                            *row++ = ((Uint32)c << 16) |
++                                     ((Uint32)c << 8) |
++                                     ((Uint32)c << 0) |
++                                     ((Uint32)a << 24);
+                         }
+                         break;
+                     default:
+@@ -747,20 +753,24 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+                     switch (head->image_type) {
+                     case IMAGE_INDEXED:
+                         for (x = tx; x < tx + ox; x++) {
+-                            *row++ = 0xFF000000
+-                                | ((Uint32)(head->cm_map[*p8 * 3]) << 16)
+-                                | ((Uint32)(head->cm_map[*p8 * 3 + 1]) << 8)
+-                                | ((Uint32)(head->cm_map[*p8 * 3 + 2]) << 0);
+-                            p8++;
++                            Uint8 c = *p8++;
++                            if (c < head->cm_num) {
++                                *row++ = 0xFF000000 |
++                                         ((Uint32)(head->cm_map[c * 3]) << 16) |
++                                         ((Uint32)(head->cm_map[c * 3 + 1]) << 8) |
++                                         ((Uint32)(head->cm_map[c * 3 + 2]) << 0);
++                            } else {
++                                *row++ = 0;
++                            }
+                         }
+                         break;
+                     case IMAGE_GREYSCALE:
+                         for (x = tx; x < tx + ox; x++) {
+-                            *row++ = 0xFF000000
+-                                | (((Uint32)(*p8)) << 16)
+-                                | (((Uint32)(*p8)) << 8)
+-                                | (((Uint32)(*p8)) << 0);
+-                            ++p8;
++                            Uint8 c = *p8++;
++                            *row++ = 0xFF000000 |
++                                     (((Uint32)c) << 16) |
++                                     (((Uint32)c) << 8) |
++                                     (((Uint32)c) << 0);
+                         }
+                         break;
+                     default:
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,33 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Mon, 6 Apr 2026 19:30:53 +0200
+Subject: Fix heap-buffer-overflow READ in XCF do_layer_surface (CWE-122)
+
+Add bounds check for tile buffer access in do_layer_surface.
+
+(cherry picked from commit 5b0d414cae99b2e162a1e46ecba4fcd7ac8c5d85)
+Origin: https://github.com/libsdl-org/SDL_image/pull/719
+Applied-upstream: 2.8.12, commit:3796a0bc0c45c1a3fed4b43c697e75c5061d4d67
+---
+ src/IMG_xcf.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index ed7d203..f067746 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -700,6 +700,15 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+ 
+             p8 = tile;
+             p = (Uint32 *) p8;
++
++            /* Bounds check: reject layer if tile data exceeds buffer */
++            if ((Uint64)ox * oy * hierarchy->bpp > (Uint64)(hierarchy->width * hierarchy->height * hierarchy->bpp)) {
++                free_xcf_tile(tile);
++                free_xcf_level(level);
++                free_xcf_hierarchy(hierarchy);
++                return 1;
++            }
++
+             for (y = ty; y < ty + oy; y++) {
+                 if ((y >= (Uint32)surface->h) || ((tx+ox) > (Uint32)surface->w)) {
+                     break;
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,33 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Mon, 6 Apr 2026 19:29:38 +0200
+Subject: Fix heap-buffer-overflow WRITE in LBM palette (CWE-122)
+
+When nbplanes > 8 without HAM flag, nbrcolorsfinal exceeds 256,
+causing writes past the palette buffer. Reject nbplanes > 8 for
+paletted images.
+
+(cherry picked from commit 2fe0746733c9f280d2c344bce231dd70fdf3bdb8)
+Origin: https://github.com/libsdl-org/SDL_image/pull/717
+Applied-upstream: 2.8.12, commit:695a166b94d772e9da4597682858dc27f870a013
+---
+ src/IMG_lbm.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/IMG_lbm.c b/src/IMG_lbm.c
+index 66215e6..bb10f90 100644
+--- a/src/IMG_lbm.c
++++ b/src/IMG_lbm.c
+@@ -232,6 +232,13 @@ SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
+ 
+     nbplanes = bmhd.planes;
+ 
++    /* Sanity check: nbplanes must not exceed 8 for paletted images.
++       Higher values cause 1<<nbplanes to exceed the 256-entry palette. */
++    if ( !pbm && nbplanes > 8 && nbplanes != 24 && flagHAM == 0 ) {
++        SDL_SetError("LBM: invalid number of bitplanes (%u)", nbplanes);
++        goto done;
++    }
++
+     if ( pbm )                         /* File format : 'Packed Bitmap' */
+     {
+         bytesperline *= 8;
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,25 @@
+From: Ozkan Sezer <[email protected]>
+Date: Wed, 13 May 2026 14:51:47 +0300
+Subject: IMG_xcf.c (read_string): add back the positive string size check
+
+[Otherwise a claimed size >= 2**31 bytes could lead to underflow. -smcv]
+
+(cherry picked from commit cdbe3bf771606a3502c1c5994812bfc48d4814a0)
+Origin: upstream, 2.8.12, commit:d23a437d9b620cfca437ffa5aa332799435973bd
+---
+ src/IMG_xcf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index b513448..4e2e635 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -241,7 +241,7 @@ static char * read_string (SDL_RWops * src) {
+     return data;
+   }
+ 
+-  if ((Sint32)tmp <= remaining) {
++  if ((Sint32)tmp > 0 && (Sint32)tmp <= remaining) {
+     data = (char *) SDL_malloc (sizeof (char) * tmp);
+     if (data) {
+       SDL_RWread(src, data, tmp, 1);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/series libsdl2-image-2.8.8+dfsg/debian/patches/series
--- libsdl2-image-2.8.8+dfsg/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/series	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,11 @@
+Fixed-out-of-bounds-read-in-XCF-image-loader-thanks-Sebas.patch
+xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch
+Fix-heap-buffer-overflow-WRITE-in-LBM-palette-CWE-122.patch
+xcf-Permit-empty-strings-in-read_string.patch
+Fix-heap-buffer-overflow-READ-in-XCF-do_layer_surface-CWE.patch
+xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch
+xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch
+xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch
+tga-reject-images-with-zero-width-or-height.patch
+Fixed-out-of-bound-read-in-GIF-decoder.patch
+IMG_xcf.c-read_string-add-back-the-positive-string-size-c.patch
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/tga-reject-images-with-zero-width-or-height.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,39 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Thu, 23 Apr 2026 11:20:40 -0700
+Subject: tga: reject images with zero width or height
+
+When SDL_CreateSurface() is called with w=0 or h=0 it may return a
+non-NULL surface but with a NULL pixels pointer (zero-size allocation).
+Subsequent code at IMG_LoadTGA_IO accesses img->pixels unconditionally,
+resulting in undefined behavior: UBSan reports "applying zero offset to
+null pointer" for the expression (Uint8*)img->pixels + (h-1)*img->pitch
+when pitch is 0.
+
+Reject zero-dimension images early before creating the surface.
+
+CWE-476 (NULL Pointer Dereference)
+Found by: NORAI fuzzer (libFuzzer + UBSan)
+PoC: poc_sdl007_tga_null_pixels.tga
+
+(cherry picked from commit 4ba58feebaf87ad80b8ab3971ea8f82132884c54)
+(cherry picked from commit 9f1318e7c112493fcd224eafe8809d4001d1bb33)
+Origin: upstream, 2.8.12, commit:67c8f531ad09ddc0e6d4c7b1468c863235711ed4
+---
+ src/IMG_tga.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/IMG_tga.c b/src/IMG_tga.c
+index 537f2ee..8d6d52f 100644
+--- a/src/IMG_tga.c
++++ b/src/IMG_tga.c
+@@ -178,6 +178,10 @@ SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src)
+ 
+     w = LE16(hdr.width);
+     h = LE16(hdr.height);
++    if (w == 0 || h == 0) {
++        error = "TGA image with zero width or height";
++        goto error;
++    }
+     img = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, format);
+     if (img == NULL) {
+         error = "Out of memory";
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Added-an-SDL_SetError-when-rejecting-out-of-bounds-ti.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,24 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 14:58:56 -0400
+Subject: xcf: Added an SDL_SetError when rejecting out-of-bounds tile data.
+
+(cherry picked from commit 1aedddcbd205c4e1ea0f99fdb2c785acc8e2489b)
+
+[This fixes incorrect error reporting by #719 -smcv]
+Origin: upstream, 2.8.12, commit:cde1749f5223d7b99750fb79e7822fe11797a2a8
+---
+ src/IMG_xcf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index f067746..4e9f157 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -703,6 +703,7 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+ 
+             /* Bounds check: reject layer if tile data exceeds buffer */
+             if ((Uint64)ox * oy * hierarchy->bpp > (Uint64)(hierarchy->width * hierarchy->height * hierarchy->bpp)) {
++                SDL_SetError("Gimp image invalid tile");
+                 free_xcf_tile(tile);
+                 free_xcf_level(level);
+                 free_xcf_hierarchy(hierarchy);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Fix-heap-buffer-overflow-READ-in-XCF-RLE-decoder-CWE-.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,60 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 15:09:55 -0400
+Subject: xcf: Fix heap-buffer-overflow READ in XCF RLE decoder (CWE-122)
+
+Add destination pointer bounds check in load_xcf_tile_rle.
+
+This fix backported to SDL2 from 6c804082117c95c24b3d3af886319e8c21fcd8e0.
+
+(cherry picked from commit 3ce6cb6f968427cd1041f9dc7b0bb6024fd4c782)
+Origin: backport, https://github.com/libsdl-org/SDL_image/pull/720
+Applied-upstream: 2.8.12, commit:f4a54104604dacd44bd43a4502c70926ca79902f
+---
+ src/IMG_xcf.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index 4e9f157..f768049 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -537,7 +537,7 @@ static unsigned char * load_xcf_tile_none (SDL_RWops * src, Uint64 len, int bpp,
+ }
+ 
+ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp, int x, int y) {
+-  unsigned char * load, * t, * data, * d;
++  unsigned char * load, * t, * data, * data_end, * d;
+   int i, size, count, j, length;
+   unsigned char val;
+ 
+@@ -552,6 +552,11 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp,
+   SDL_RWread (src, t, 1, (size_t)len); /* reallen */
+ 
+   data = (unsigned char *) SDL_calloc (1, x*y*bpp);
++  if (!data) {
++    SDL_free(load);
++    return NULL;
++  }
++  data_end = data + x*y*bpp;
+   for (i = 0; i < bpp; i++) {
+     d    = data + i;
+     size = x*y;
+@@ -578,6 +583,9 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp,
+         size -= length;
+ 
+         while (length-- > 0) {
++          if (d >= data_end) {
++            break;
++          }
+           *d = *t++;
+           d += bpp;
+         }
+@@ -600,6 +608,9 @@ static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp,
+         val = *t++;
+ 
+         for (j = 0; j < length; j++) {
++          if (d >= data_end) {
++            break;
++          }
+           *d = val;
+           d += bpp;
+         }
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-fix-null-pointer-dereference-when-read_xcf_hierarchy-.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,39 @@
+From: Jorge Barredo Ferreira <[email protected]>
+Date: Tue, 7 Apr 2026 17:16:58 +0200
+Subject: xcf: fix null pointer dereference when read_xcf_hierarchy() fails
+
+read_xcf_hierarchy() can return NULL when SDL_calloc() fails or when
+SDL_ReadU32BE() fails to read the width/height/bpp fields. The return
+value was not checked before dereferencing hierarchy->bpp at line 755
+in do_layer_surface(), leading to a null pointer dereference.
+
+Add a NULL check immediately after the call to return early with an
+error in that case.
+
+CWE-476 (NULL Pointer Dereference)
+Found by: NORAI fuzzer (libFuzzer + ASan/UBSan)
+PoC: poc_sdl006_xcf_hierarchy_null.xcf
+
+(cherry picked from commit 336fb104494815984250c40f8ee6bd1325b7ba1e)
+(cherry picked from commit be7fee9064ed15d88e0bc573c018045daacfd01a)
+Origin: https://github.com/libsdl-org/SDL_image/pull/722
+Applied-upstream: 2.8.12, commit:aa03c0f5d0a2a8ba42c719de672650a0dda939e2
+---
+ src/IMG_xcf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index f768049..b513448 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -666,6 +666,10 @@ do_layer_surface(SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_
+ 
+     SDL_RWseek(src, layer->hierarchy_file_offset, RW_SEEK_SET);
+     hierarchy = read_xcf_hierarchy(src, head);
++    if (!hierarchy) {
++        SDL_SetError("Failed to read XCF image hierarchy");
++        return 1;
++    }
+ 
+     if (hierarchy->bpp > 4) {  /* unsupported. */
+         SDL_Log("Unknown Gimp image bpp (%u)\n", (unsigned int) hierarchy->bpp);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xcf-Permit-empty-strings-in-read_string.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,34 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 14:53:45 -0400
+Subject: xcf: Permit empty strings in read_string().
+
+Reference Issue #716.
+
+(cherry picked from commit 1da905ae95748edbf063102574be5f25ff42ae39)
+Origin: upstream, 2.8.12, commit:2d2928376e1e044fd9e501d25e6e39e71b8fb85c
+Bug: https://github.com/libsdl-org/SDL_image/issues/716
+---
+ src/IMG_xcf.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/src/IMG_xcf.c b/src/IMG_xcf.c
+index a1683ec..ed7d203 100644
+--- a/src/IMG_xcf.c
++++ b/src/IMG_xcf.c
+@@ -233,7 +233,15 @@ static char * read_string (SDL_RWops * src) {
+ 
+   tmp = SDL_ReadBE32(src);
+   remaining = SDL_RWsize(src) - SDL_RWtell(src);
+-  if (tmp > 0 && (Sint32)tmp <= remaining) {
++  if (tmp == 0) {
++    data = (char *) SDL_malloc(1);
++    if (data) {
++      data[0] = 0;
++    }
++    return data;
++  }
++
++  if ((Sint32)tmp <= remaining) {
+     data = (char *) SDL_malloc (sizeof (char) * tmp);
+     if (data) {
+       SDL_RWread(src, data, tmp, 1);
diff -Nru libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch
--- libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsdl2-image-2.8.8+dfsg/debian/patches/xpm-Remove-QUICK_COLORHASH-replace-it-with-inline-code-th.patch	2026-08-23 14:45:36.000000000 +0100
@@ -0,0 +1,43 @@
+From: "Ryan C. Gordon" <[email protected]>
+Date: Mon, 6 Apr 2026 14:24:56 -0400
+Subject: xpm: Remove QUICK_COLORHASH,
+ replace it with inline code that checks for NULL.
+
+Closes #721.
+
+(cherry picked from commit bc17bc7c6a2767e342ebb6d3fd37c8e323c8dd70)
+Origin: upstream, 2.8.12, commit:5df1ec7d9dda53c02f251971e2169690c50211d8
+Bug: https://github.com/libsdl-org/SDL_image/issues/715
+---
+ src/IMG_xpm.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/IMG_xpm.c b/src/IMG_xpm.c
+index 2b2f119..09441b9 100644
+--- a/src/IMG_xpm.c
++++ b/src/IMG_xpm.c
+@@ -157,9 +157,6 @@ static int add_colorhash(struct color_hash *hash,
+     return 1;
+ }
+ 
+-/* fast lookup that works if cpp == 1 */
+-#define QUICK_COLORHASH(hash, key) ((hash)->table[*(Uint8 *)(key)]->color)
+-
+ static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp)
+ {
+     struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)];
+@@ -1132,9 +1129,11 @@ static SDL_Surface *load_xpm(char **xpm, SDL_RWops *src, SDL_bool force_32bit)
+         if (indexed) {
+             /* optimization for some common cases */
+             if (cpp == 1)
+-                for (x = 0; x < w; x++)
+-                    dst[x] = (Uint8)QUICK_COLORHASH(colors,
+-                                 line + x);
++                for (x = 0; x < w; x++) {
++                    /* fast lookup that works if cpp == 1 */
++                    const struct hash_entry *entry = colors->table[*(Uint8 *)(line + x)];
++                    dst[x] = entry ? (Uint8) entry->color : 0;
++                }
+             else
+                 for (x = 0; x < w; x++)
+                     dst[x] = (Uint8)get_colorhash(colors,
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_gif.c libsdl2-image-2.8.8+dfsg/src/IMG_gif.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_gif.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_gif.c	2026-08-23 15:03:00.000000000 +0100
@@ -469,8 +469,10 @@
                 RWSetMsg("ran off the end of my bits");
             return -1;
         }
-        state->buf[0] = state->buf[state->last_byte - 2];
-        state->buf[1] = state->buf[state->last_byte - 1];
+        if (state->last_byte > 2) {
+            state->buf[0] = state->buf[state->last_byte - 2];
+            state->buf[1] = state->buf[state->last_byte - 1];
+        }
 
         if ((ret = GetDataBlock(src, &state->buf[2], state)) > 0)
             count = (unsigned char) ret;
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_lbm.c	2026-08-23 15:03:00.000000000 +0100
@@ -232,6 +232,13 @@
 
     nbplanes = bmhd.planes;
 
+    /* Sanity check: nbplanes must not exceed 8 for paletted images.
+       Higher values cause 1<<nbplanes to exceed the 256-entry palette. */
+    if ( !pbm && nbplanes > 8 && nbplanes != 24 && flagHAM == 0 ) {
+        SDL_SetError("LBM: invalid number of bitplanes (%u)", nbplanes);
+        goto done;
+    }
+
     if ( pbm )                         /* File format : 'Packed Bitmap' */
     {
         bytesperline *= 8;
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_tga.c libsdl2-image-2.8.8+dfsg/src/IMG_tga.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_tga.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_tga.c	2026-08-23 15:03:00.000000000 +0100
@@ -178,6 +178,10 @@
 
     w = LE16(hdr.width);
     h = LE16(hdr.height);
+    if (w == 0 || h == 0) {
+        error = "TGA image with zero width or height";
+        goto error;
+    }
     img = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, format);
     if (img == NULL) {
         error = "Out of memory";
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_xcf.c	2026-08-23 15:03:00.000000000 +0100
@@ -233,7 +233,15 @@
 
   tmp = SDL_ReadBE32(src);
   remaining = SDL_RWsize(src) - SDL_RWtell(src);
-  if (tmp > 0 && (Sint32)tmp <= remaining) {
+  if (tmp == 0) {
+    data = (char *) SDL_malloc(1);
+    if (data) {
+      data[0] = 0;
+    }
+    return data;
+  }
+
+  if ((Sint32)tmp > 0 && (Sint32)tmp <= remaining) {
     data = (char *) SDL_malloc (sizeof (char) * tmp);
     if (data) {
       SDL_RWread(src, data, tmp, 1);
@@ -529,7 +537,7 @@
 }
 
 static unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint64 len, int bpp, int x, int y) {
-  unsigned char * load, * t, * data, * d;
+  unsigned char * load, * t, * data, * data_end, * d;
   int i, size, count, j, length;
   unsigned char val;
 
@@ -544,6 +552,11 @@
   SDL_RWread (src, t, 1, (size_t)len); /* reallen */
 
   data = (unsigned char *) SDL_calloc (1, x*y*bpp);
+  if (!data) {
+    SDL_free(load);
+    return NULL;
+  }
+  data_end = data + x*y*bpp;
   for (i = 0; i < bpp; i++) {
     d    = data + i;
     size = x*y;
@@ -570,6 +583,9 @@
         size -= length;
 
         while (length-- > 0) {
+          if (d >= data_end) {
+            break;
+          }
           *d = *t++;
           d += bpp;
         }
@@ -592,6 +608,9 @@
         val = *t++;
 
         for (j = 0; j < length; j++) {
+          if (d >= data_end) {
+            break;
+          }
           *d = val;
           d += bpp;
         }
@@ -647,6 +666,10 @@
 
     SDL_RWseek(src, layer->hierarchy_file_offset, RW_SEEK_SET);
     hierarchy = read_xcf_hierarchy(src, head);
+    if (!hierarchy) {
+        SDL_SetError("Failed to read XCF image hierarchy");
+        return 1;
+    }
 
     if (hierarchy->bpp > 4) {  /* unsupported. */
         SDL_Log("Unknown Gimp image bpp (%u)\n", (unsigned int) hierarchy->bpp);
@@ -692,6 +715,16 @@
 
             p8 = tile;
             p = (Uint32 *) p8;
+
+            /* Bounds check: reject layer if tile data exceeds buffer */
+            if ((Uint64)ox * oy * hierarchy->bpp > (Uint64)(hierarchy->width * hierarchy->height * hierarchy->bpp)) {
+                SDL_SetError("Gimp image invalid tile");
+                free_xcf_tile(tile);
+                free_xcf_level(level);
+                free_xcf_hierarchy(hierarchy);
+                return 1;
+            }
+
             for (y = ty; y < ty + oy; y++) {
                 if ((y >= (Uint32)surface->h) || ((tx+ox) > (Uint32)surface->w)) {
                     break;
@@ -716,20 +749,26 @@
                     switch (head->image_type) {
                     case IMAGE_INDEXED:
                         for (x = tx; x < tx + ox; x++) {
-                            *row = ((Uint32)(head->cm_map[*p8 * 3]) << 16);
-                            *row |= ((Uint32)(head->cm_map[*p8 * 3 + 1]) << 8);
-                            *row |= ((Uint32)(head->cm_map[*p8++ * 3 + 2]) << 0);
-                            *row |= ((Uint32)*p8++ << 24);
-                            row++;
+                            Uint8 c = *p8++;
+                            Uint8 a = *p8++;
+                            if (c < head->cm_num) {
+                                *row++ = ((Uint32)(head->cm_map[c * 3]) << 16) |
+                                         ((Uint32)(head->cm_map[c * 3 + 1]) << 8) |
+                                         ((Uint32)(head->cm_map[c * 3 + 2]) << 0) |
+                                         ((Uint32)a << 24);
+                            } else {
+                                *row++ = 0;
+                            }
                         }
                         break;
                     case IMAGE_GREYSCALE:
                         for (x = tx; x < tx + ox; x++) {
-                            *row = ((Uint32)*p8 << 16);
-                            *row |= ((Uint32)*p8 << 8);
-                            *row |= ((Uint32)*p8++ << 0);
-                            *row |= ((Uint32)*p8++ << 24);
-                            row++;
+                            Uint8 c = *p8++;
+                            Uint8 a = *p8++;
+                            *row++ = ((Uint32)c << 16) |
+                                     ((Uint32)c << 8) |
+                                     ((Uint32)c << 0) |
+                                     ((Uint32)a << 24);
                         }
                         break;
                     default:
@@ -747,20 +786,24 @@
                     switch (head->image_type) {
                     case IMAGE_INDEXED:
                         for (x = tx; x < tx + ox; x++) {
-                            *row++ = 0xFF000000
-                                | ((Uint32)(head->cm_map[*p8 * 3]) << 16)
-                                | ((Uint32)(head->cm_map[*p8 * 3 + 1]) << 8)
-                                | ((Uint32)(head->cm_map[*p8 * 3 + 2]) << 0);
-                            p8++;
+                            Uint8 c = *p8++;
+                            if (c < head->cm_num) {
+                                *row++ = 0xFF000000 |
+                                         ((Uint32)(head->cm_map[c * 3]) << 16) |
+                                         ((Uint32)(head->cm_map[c * 3 + 1]) << 8) |
+                                         ((Uint32)(head->cm_map[c * 3 + 2]) << 0);
+                            } else {
+                                *row++ = 0;
+                            }
                         }
                         break;
                     case IMAGE_GREYSCALE:
                         for (x = tx; x < tx + ox; x++) {
-                            *row++ = 0xFF000000
-                                | (((Uint32)(*p8)) << 16)
-                                | (((Uint32)(*p8)) << 8)
-                                | (((Uint32)(*p8)) << 0);
-                            ++p8;
+                            Uint8 c = *p8++;
+                            *row++ = 0xFF000000 |
+                                     (((Uint32)c) << 16) |
+                                     (((Uint32)c) << 8) |
+                                     (((Uint32)c) << 0);
                         }
                         break;
                     default:
diff -Nru libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c
--- libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c	2025-02-07 18:01:45.000000000 +0000
+++ libsdl2-image-2.8.8+dfsg/src/IMG_xpm.c	2026-08-23 15:03:00.000000000 +0100
@@ -157,9 +157,6 @@
     return 1;
 }
 
-/* fast lookup that works if cpp == 1 */
-#define QUICK_COLORHASH(hash, key) ((hash)->table[*(Uint8 *)(key)]->color)
-
 static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp)
 {
     struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)];
@@ -1132,9 +1129,11 @@
         if (indexed) {
             /* optimization for some common cases */
             if (cpp == 1)
-                for (x = 0; x < w; x++)
-                    dst[x] = (Uint8)QUICK_COLORHASH(colors,
-                                 line + x);
+                for (x = 0; x < w; x++) {
+                    /* fast lookup that works if cpp == 1 */
+                    const struct hash_entry *entry = colors->table[*(Uint8 *)(line + x)];
+                    dst[x] = entry ? (Uint8) entry->color : 0;
+                }
             else
                 for (x = 0; x < w; x++)
                     dst[x] = (Uint8)get_colorhash(colors,

Reply via email to