shithub: npe

Download patch

ref: 26ce37c49642e2875a36650734b9619b21c49be5
parent: ab547d8e97c1bbedfff2fe7d5ff18fc3171abc6d
author: qwx <qwx@sciops.net>
date: Fri Mar 6 06:42:10 EST 2026

sdl2: fix double allocation, use palette code in CreateTextureFromSurface, detect invalid texture dimensions

--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -347,6 +347,49 @@
 	return n;
 }
 
+static void
+syncpalette(SDL_Surface *s)
+{
+	SDL_Color *c;
+	Uint8 *to;
+	int j;
+
+	to = ((Memimage*)s->i)->data->bdata;
+	for(j = 0; j < s->n; j++){
+		c = s->format->palette->colors + s->pixels[j];
+		*to++ = c->b;
+		*to++ = c->g;
+		*to++ = c->r;
+		*to++ = c->a;
+	}
+}
+
+static void
+synctopalette(SDL_Surface *s)
+{
+	SDL_Color c, *f;
+	Uint32 *from;
+	int j, k;
+	Memimage *i;
+	SDL_PixelFormat fmt;
+
+	i = s->i;
+	fmt.format = chan2pixel(screen->chan);
+	from = (void*)i->data->bdata;
+	for(j = 0; j < s->n; j++){
+		SDL_GetRGB(from[j], &fmt, &c.r, &c.g, &c.b);
+		for(k = 0; k < s->format->palette->ncolors; k++){
+			f = s->format->palette->colors + k;
+			if(c.r == f->r && c.g == f->g && c.b == f->b)
+				break;
+		}
+		if(k == s->format->palette->ncolors)
+			s->pixels[j] = 0; /* FIXME */
+		else
+			s->pixels[j] = k;
+	}
+}
+
 SDL_Texture *
 SDL_CreateTexture(SDL_Renderer *, Uint32 format, int, int w, int h)
 {
@@ -374,15 +417,23 @@
 SDL_Texture *
 SDL_CreateTextureFromSurface(SDL_Renderer *r, SDL_Surface *s)
 {
+	int fmt;
 	SDL_Texture *t;
 	SDL_Rect re;
 
-	if((t = SDL_CreateTexture(r, s->format->format, 0, s->w, s->h)) != nil){
-		re.x = 0;
-		re.y = 0;
-		re.w = s->w;
-		re.h = s->h;
-		SDL_UpdateTexture(t, &re, s->pixels, s->pitch);
+	if((fmt = s->format->format) == SDL_PIXELFORMAT_INDEX8)
+		fmt = chan2pixel(screen->chan);
+	if((t = SDL_CreateTexture(r, fmt, 0, s->w, s->h)) != nil){
+		if(s->format->format == SDL_PIXELFORMAT_INDEX8){
+			syncpalette(s);
+			memimagedraw(t->m, t->m->r, ((Memimage*)s->i), ZP, nil, ZP, S);
+		}else{
+			re.x = 0;
+			re.y = 0;
+			re.w = s->w;
+			re.h = s->h;
+			SDL_UpdateTexture(t, &re, s->pixels, s->pitch);
+		}
 	}
 
 	return t;
@@ -515,7 +566,6 @@
 		werrstr("SDL_CreateRGBSurface: memory");
 		return nil;
 	}
-	s->i = allocmemimage(Rect(0,0,w,h), chan == CMAP8 ? screen->chan : chan);
 	s->format = calloc(1, sizeof(SDL_PixelFormat));
 	s->format->BytesPerPixel = bpp/8;
 	s->format->format = chan2pixel(chan);
@@ -640,49 +690,6 @@
 	return 0;
 }
 
-static void
-syncpalette(SDL_Surface *s)
-{
-	SDL_Color *c;
-	Uint8 *to;
-	int j;
-
-	to = ((Memimage*)s->i)->data->bdata;
-	for(j = 0; j < s->n; j++){
-		c = s->format->palette->colors + s->pixels[j];
-		*to++ = c->b;
-		*to++ = c->g;
-		*to++ = c->r;
-		*to++ = c->a;
-	}
-}
-
-static void
-synctopalette(SDL_Surface *s)
-{
-	SDL_Color c, *f;
-	Uint32 *from;
-	int j, k;
-	Memimage *i;
-	SDL_PixelFormat fmt;
-
-	i = s->i;
-	fmt.format = chan2pixel(screen->chan);
-	from = (void*)i->data->bdata;
-	for(j = 0; j < s->n; j++){
-		SDL_GetRGB(from[j], &fmt, &c.r, &c.g, &c.b);
-		for(k = 0; k < s->format->palette->ncolors; k++){
-			f = s->format->palette->colors + k;
-			if(c.r == f->r && c.g == f->g && c.b == f->b)
-				break;
-		}
-		if(k == s->format->palette->ncolors)
-			s->pixels[j] = 0; /* FIXME */
-		else
-			s->pixels[j] = k;
-	}
-}
-
 int
 SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 {
@@ -1134,6 +1141,8 @@
 		backcopy = malloc(logiw*logih*4);
 	}
 
+	if(Dx(sr) <= 0 || Dy(sr) <= 0)
+		return 0;
 	if(Dx(dr)/Dx(sr) > 1 || Dy(dr)/Dy(sr) > 1)
 		npe_sdl_scale((u32int*)byteaddr(t->m, ZP), Dx(sr), Dy(sr), (u32int*)byteaddr(back, ZP), logiw, logih);
 	else
--