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);