ref: e432f766e0589685a77ac9f8b0a84be64299f68e
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 char *cspaces[] = { [STBIR_COLORSPACE_LINEAR] = "linear", [STBIR_COLORSPACE_SRGB] = "srgb", }; static void usage(void) { fprint(2, "usage: %s [-x size] [-y size] [-f filter] [-c colorspace]\n", argv0); exits("usage"); } void main(int argc, char **argv) { Memimage *a, *b; u8int *in, *out; char *flts, *s, *csps; int n, w, h, bp; int ow, oh, obp; int wp, hp, f, c; ow = oh = 0; wp = hp = 0; flts = filters[STBIR_FILTER_MITCHELL]; csps = cspaces[STBIR_COLORSPACE_LINEAR]; 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; case 'c': csps = EARGF(usage()); break; default: usage(); }ARGEND if(wp && oh == 0){ oh = ow; hp = 1; }else if(hp && ow == 0){ ow = oh; wp = 1; } 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"); } for(c = 0; c < nelem(cspaces) && strcmp(csps, cspaces[c]) != 0; c++); if(c >= nelem(cspaces)){ fprint(2, "invalid colorspace %s\n", csps); exits("colorspace"); } 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); }