ref: c59921f4e6076fff98a1841c44dd0bad8ed5e1e2
dir: /resample.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#define STBIR_MALLOC(x,u) malloc(x)
#define STBIR_FREE(x,u) free(x)
#define STBIR_ASSERT(x) assert(x)
#define NULL nil
typedef uintptr size_t;
#include "stb_image_resize.h"
static char *filters[] = {
[STBIR_FILTER_BOX] = "box",
[STBIR_FILTER_TRIANGLE] = "triangle",
[STBIR_FILTER_CUBICBSPLINE] = "cubicbspline",
[STBIR_FILTER_CATMULLROM] = "catmullrom",
[STBIR_FILTER_MITCHELL] = "mitchell",
};
static void
usage(void)
{
fprint(2, "usage: %s [-x size] [-y size] [-f filter]\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
Memimage *a, *b;
u8int *in, *out;
char *flts, *s;
int n, w, h, bp;
int ow, oh, obp;
int wp, hp, f;
ow = oh = 0;
wp = hp = 0;
flts = filters[STBIR_FILTER_MITCHELL];
ARGBEGIN{
case 'x':
s = EARGF(usage());
wp = (ow = atoi(s)) > 0 && s[strlen(s)-1] == '%';
break;
case 'y':
s = EARGF(usage());
hp = (oh = atoi(s)) > 0 && s[strlen(s)-1] == '%';
break;
case 'f':
flts = EARGF(usage());
break;
default:
usage();
}ARGEND
if(ow < 1 && oh < 1)
usage();
for(f = 0; f < nelem(filters) && (filters[f] == nil || strcmp(flts, filters[f]) != 0); f++);
if(f >= nelem(filters)){
fprint(2, "invalid filter %s\n", flts);
exits("filter");
}
memimageinit();
if((a = readmemimage(0)) == nil)
sysfatal("memory");
if(a->chan != RGB24){
if((b = allocmemimage(a->r, RGB24)) == nil)
sysfatal("memory");
memimagedraw(b, a->r, a, ZP, nil, ZP, S);
freememimage(a);
a = b;
}
w = Dx(a->r);
h = Dy(a->r);
ow = wp ? w*ow/100.0 : w;
oh = hp ? h*oh/100.0 : h;
if(w < 1 || h < 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)
sysfatal("memory");
stbir_resize_uint8_generic(
in, w, h, w*bp,
out, ow, oh, ow*obp,
3, -1, 0,
STBIR_EDGE_CLAMP, STBIR_FILTER_CATMULLROM, STBIR_COLORSPACE_LINEAR,
NULL);
if((b = allocmemimage(Rect(0,0,ow,oh), RGB24)) == nil)
sysfatal("%r");
loadmemimage(b, b->r, out, ow*oh*obp);
writememimage(1, b);
exits(nil);
}