ref: fce29312cd3c8240c39e1e7915ef7d6c1e334a7c
parent: f423ec55a7931a11e80de98ac249cb0be4aee077
author: Sigrid Solveig Haflínudóttir <[email protected]>
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