shithub: npe

Download patch

ref: fce29312cd3c8240c39e1e7915ef7d6c1e334a7c
parent: f423ec55a7931a11e80de98ac249cb0be4aee077
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Jul 10 11:34:21 EDT 2023

sdl2: SDL_PIXELFORMAT_RGB24 and SDL_SaveBMP

--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -1,4 +1,5 @@
 #include "_sdl.h"
+#include <bio.h>
 
 struct SDL_Window {
 	int dummy;
@@ -28,6 +29,10 @@
 	.format = SDL_PIXELFORMAT_XRGB8888,
 };
 
+static SDL_PixelFormat rgb24 = {
+	.format = SDL_PIXELFORMAT_RGB24,
+};
+
 static SDL_Window onewin;
 static SDL_Renderer oneren;
 static Memimage *back;
@@ -350,6 +355,10 @@
 		s->format->format = SDL_PIXELFORMAT_ARGB8888;
 		s->pixels = i->data->bdata;
 		break;
+	case 24:
+		s->format->format = SDL_PIXELFORMAT_RGB24;
+		s->pixels = calloc(1, n);
+		break;
 	case 8:
 		s->format->format = SDL_PIXELFORMAT_INDEX8;
 		s->format->palette = calloc(1, sizeof(SDL_Palette));
@@ -401,6 +410,8 @@
 		f = &argb8888;
 	else if(fmt == SDL_PIXELFORMAT_XRGB8888)
 		f = &xrgb8888;
+	else if(fmt == SDL_PIXELFORMAT_RGB24)
+		f = &rgb24;
 	else{
 		werrstr("SDL_CreateRGBSurfaceWithFormat: FIXME format %8ux not implemented", fmt);
 		return nil;
@@ -428,6 +439,13 @@
 		for(i = 0; i < dst->n / sizeof(*p); i++)
 			p[i] = color;
 		break;
+	case SDL_PIXELFORMAT_RGB24:
+		for(i = 0; i < dst->n; i += 3){
+			dst->pixels[i+0] = color;
+			dst->pixels[i+1] = color>>8;
+			dst->pixels[i+2] = color>>16;
+		}
+		break;
 	case SDL_PIXELFORMAT_INDEX8:
 		for(i = 0; i < dst->n; i++)
 			dst->pixels[i] = color;
@@ -890,22 +908,41 @@
 int
 SDL_RenderReadPixels(SDL_Renderer *rend, SDL_Rect *rect, Uint32 fmt, void *pixels, int pitch)
 {
-	Rectangle r;
+	Rectangle r, r2;
+	Memimage *m;
+	int n;
 
-	USED(pitch); /* FIXME pitch & fmt */
+	USED(pitch); /* FIXME pitch */
 
-	if(fmt != SDL_PIXELFORMAT_ARGB8888 && fmt != SDL_PIXELFORMAT_XRGB8888){
-		werrstr("SDL_RenderReadPixels: FIXME non-*rgb8888");
-		return -1;
-	}
-
 	if(rect != nil)
 		r = Rect(rect->x, rect->y, rect->x+rect->w, rect->y+rect->h);
 	else
 		r = Rect(0, 0, rend->logiw, rend->logih);
 
-	unloadmemimage(back, r, pixels, Dx(r)*Dy(r)*4);
+	n = Dx(r)*Dy(r);
+	switch(fmt){
+	case SDL_PIXELFORMAT_ARGB8888:
+	case SDL_PIXELFORMAT_XRGB8888:
+		n *= 4;
+		m = back;
+		break;
+	case SDL_PIXELFORMAT_RGB24:
+		n *= 3;
+		r2 = Rect(0,0,Dx(r),Dy(r));
+		if((m = allocmemimage(r2, RGB24)) == nil)
+			return -1;
+		memfillcolor(m, DBlack);
+		memimagedraw(m, r2, back, r.min, nil, ZP, S);
+		break;
+	default:
+		werrstr("SDL_RenderReadPixels: FIXME non-*rgb{8888,24}");
+		return -1;
+	}
 
+	unloadmemimage(m, r, pixels, n);
+	if(m != back)
+		freememimage(m);
+
 	return 0;
 }
 
@@ -1270,10 +1307,46 @@
 int
 SDL_SaveBMP(SDL_Surface *s, const char *file)
 {
-	/* FIXME implement this */
-	USED(s, file);
+	u8int h[54];
+	Biobuf *f;
+	int sz, i;
 
-	return -1;
+	if(s->format->format != SDL_PIXELFORMAT_RGB24){
+		werrstr("SDL_SaveBMP: not rgb24");
+		return -1;
+	}
+	if((f = Bopen(file, OWRITE|OTRUNC)) == nil)
+		return -1;
+	sz = sizeof(h) + s->n;
+	memset(h, 0, sizeof(h));
+	h[0] = 'B';
+	h[1] = 'M';
+	h[0x02+0] = sz;
+	h[0x02+1] = sz>>8;
+	h[0x02+2] = sz>>16;
+	h[0x02+3] = sz>>24;
+	h[0x0a] = sizeof(h);
+	h[0x0e] = sizeof(h) - 14;
+	h[0x12+0] = s->w;
+	h[0x12+1] = s->w>>8;
+	h[0x12+2] = s->w>>16;
+	h[0x12+3] = s->w>>24;
+	h[0x16+0] = s->h;
+	h[0x16+1] = s->h>>8;
+	h[0x16+2] = s->h>>16;
+	h[0x16+3] = s->h>>24;
+	h[0x1a] = 1;
+	h[0x1c] = 24;
+	Bwrite(f, h, sizeof(h));
+	memset(h, 0, 4);
+	for(i = s->h-1; i >= 0; i--){
+		Bwrite(f, s->pixels+i*s->w*3, s->w*3);
+		if(s->w & 3)
+			Bwrite(f, h, 4-(s->w&3));
+	}
+	Bterm(f);
+
+	return 0;
 }
 
 void