shithub: imgtools

Download patch

ref: 453dfd1fdd9780c0381cc3fd8c5a63edfb623e3a
parent: d71d5fc296e01ce3c2189087c5ff190676b7564f
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Jan 20 05:09:54 EST 2021

resample: preserve original format if possible, fix alpha channel

--- a/resample.c
+++ b/resample.c
@@ -26,7 +26,7 @@
 static void
 usage(void)
 {
-	fprint(2, "usage: %s [-x size] [-y size] [-f filter] [-c colorspace]\n", argv0);
+	fprint(2, "usage: %s [-P] [-x size] [-y size] [-f filter] [-c colorspace]\n", argv0);
 	exits("usage");
 }
 
@@ -36,12 +36,15 @@
 	Memimage *a, *b;
 	u8int *in, *out;
 	char *flts, *s, *csps;
-	int n, w, h, bp;
-	int ow, oh, obp;
+	int alphai, flags;
+	int w, h, ow, oh;
 	int wp, hp, f, c;
+	int n, bp, to;
 
 	ow = oh = 0;
 	wp = hp = 0;
+	alphai = STBIR_ALPHA_CHANNEL_NONE;
+	flags = STBIR_FLAG_ALPHA_PREMULTIPLIED;
 	flts = filters[STBIR_FILTER_MITCHELL];
 	csps = cspaces[STBIR_COLORSPACE_LINEAR];
 	ARGBEGIN{
@@ -59,6 +62,9 @@
 	case 'c':
 		csps = EARGF(usage());
 		break;
+	case 'P':
+		flags &= ~STBIR_FLAG_ALPHA_PREMULTIPLIED;
+		break;
 	default:
 		usage();
 	}ARGEND
@@ -87,13 +93,55 @@
 	memimageinit();
 	if((a = readmemimage(0)) == nil)
 		sysfatal("memory");
-	if(a->chan != RGB24){
-		if((b = allocmemimage(a->r, RGB24)) == nil)
+
+	bp = 0;
+again:
+	switch(a->chan){
+	case GREY8:
+		bp = 1;
+		break;
+	case RGB24:
+		bp = 3;
+		break;
+	case RGBA32:
+		bp = 4;
+		alphai = 3;
+		break;
+	case ARGB32:
+	case XRGB32:
+		bp = 4;
+		alphai = 0;
+		break;
+
+	case GREY1:
+	case GREY2:
+	case GREY4:
+		to = GREY8;
+		goto convert;
+	case CMAP8:
+	case RGB15:
+	case RGB16:
+		to = RGB24;
+		goto convert;
+	case BGR24:
+		to = RGB24;
+		goto convert;
+	case ABGR32:
+		to = ARGB32;
+		goto convert;
+	case XBGR32:
+		to = XRGB32;
+convert:
+		if((b = allocmemimage(a->r, to)) == nil)
 			sysfatal("memory");
 		memimagedraw(b, a->r, a, ZP, nil, ZP, S);
 		freememimage(a);
 		a = b;
+		goto again;
+	default:
+		sysfatal("invalid chan %#lux", a->chan);
 	}
+
 	w = Dx(a->r);
 	h = Dy(a->r);
 	if(wp)
@@ -106,24 +154,23 @@
 		ow = oh*w/h;
 	if(ow < 1 || oh < 1)
 		sysfatal("invalid size: %dx%d", ow, oh);
-	bp = 3;
 	n = w*h*bp;
 	if((in = malloc(w*h*bp)) == nil)
 		sysfatal("%r");
 	if(unloadmemimage(a, a->r, in, n) < 0)
 		sysfatal("%r");
-	obp = 3;
-	if((out = malloc(ow*oh*obp)) == nil)
+	if((out = malloc(ow*oh*bp)) == nil)
 		sysfatal("memory");
 	stbir_resize_uint8_generic(
 		in, w, h, w*bp,
-		out, ow, oh, ow*obp,
-		3, -1, 0,
+		out, ow, oh, ow*bp,
+		bp, alphai, flags,
 		STBIR_EDGE_CLAMP, f, c,
 		NULL);
-	if((b = allocmemimage(Rect(0,0,ow,oh), RGB24)) == nil)
+	free(in);
+	if((b = allocmemimage(Rect(0,0,ow,oh), a->chan)) == nil)
 		sysfatal("%r");
-	loadmemimage(b, b->r, out, ow*oh*obp);
+	loadmemimage(b, b->r, out, ow*oh*bp);
 	writememimage(1, b);
 
 	exits(nil);