shithub: imgtools

Download patch

ref: 2386f06afaf4eb894887704805843887798c2943
parent: 453dfd1fdd9780c0381cc3fd8c5a63edfb623e3a
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Wed Jan 20 05:54:18 EST 2021

add -r option to specify source rectangle (crop)

--- a/resample.c
+++ b/resample.c
@@ -10,6 +10,10 @@
 typedef uintptr size_t;
 #include "stb_image_resize.h"
 
+enum {
+	Stpixels,
+};
+
 static char *filters[] = {
     [STBIR_FILTER_BOX] = "box",
     [STBIR_FILTER_TRIANGLE] = "triangle",
@@ -26,7 +30,7 @@
 static void
 usage(void)
 {
-	fprint(2, "usage: %s [-P] [-x size] [-y size] [-f filter] [-c colorspace]\n", argv0);
+	fprint(2, "usage: %s [-P] [-x size] [-y size] [-r x0,y0,x1,y1] [-f filter] [-c colorspace]\n", argv0);
 	exits("usage");
 }
 
@@ -33,13 +37,14 @@
 void
 main(int argc, char **argv)
 {
-	Memimage *a, *b;
-	u8int *in, *out;
-	char *flts, *s, *csps;
+	char *flts, *s, *csps, *e;
+	int n, bp, to, stmode;
 	int alphai, flags;
 	int w, h, ow, oh;
 	int wp, hp, f, c;
-	int n, bp, to;
+	Memimage *a, *b;
+	u8int *in, *out;
+	double st[4];
 
 	ow = oh = 0;
 	wp = hp = 0;
@@ -47,6 +52,11 @@
 	flags = STBIR_FLAG_ALPHA_PREMULTIPLIED;
 	flts = filters[STBIR_FILTER_MITCHELL];
 	csps = cspaces[STBIR_COLORSPACE_LINEAR];
+	st[0] = 0;
+	st[1] = 0;
+	st[2] = 1;
+	st[3] = 1;
+	stmode = -1;
 	ARGBEGIN{
 	case 'x':
 		s = EARGF(usage());
@@ -65,6 +75,18 @@
 	case 'P':
 		flags &= ~STBIR_FLAG_ALPHA_PREMULTIPLIED;
 		break;
+	case 'r':
+		s = EARGF(usage());
+		stmode = Stpixels;
+		e = s;
+		for(n = 0; n < 4; n++, e++){
+			st[n] = strtod(e, &e);
+			if(*e != ',')
+				break;
+		}
+		if(n != 3)
+			sysfatal("invalid rect %s", s);
+		break;
 	default:
 		usage();
 	}ARGEND
@@ -80,15 +102,11 @@
 	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");
-	}
+	if(f >= nelem(filters))
+		sysfatal("invalid filter %s", flts);
 	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");
-	}
+	if(c >= nelem(cspaces))
+		sysfatal("invalid colorspace %s", csps);
 
 	memimageinit();
 	if((a = readmemimage(0)) == nil)
@@ -144,6 +162,14 @@
 
 	w = Dx(a->r);
 	h = Dy(a->r);
+	if(stmode == Stpixels){
+		st[0] /= (double)w;
+		st[1] /= (double)h;
+		st[2] /= (double)w;
+		st[3] /= (double)h;
+		if(st[2] <= st[0] || st[3] <= st[1])
+			sysfatal("invalid rect");
+	}
 	if(wp)
 		ow = w*ow/100.0;
 	if(hp)
@@ -161,12 +187,16 @@
 		sysfatal("%r");
 	if((out = malloc(ow*oh*bp)) == nil)
 		sysfatal("memory");
-	stbir_resize_uint8_generic(
+	stbir_resize_region(
 		in, w, h, w*bp,
 		out, ow, oh, ow*bp,
+		STBIR_TYPE_UINT8,
 		bp, alphai, flags,
-		STBIR_EDGE_CLAMP, f, c,
-		NULL);
+		STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP,
+		f, f,
+		c, nil,
+		st[0], st[1], st[2], st[3]
+	);
 	free(in);
 	if((b = allocmemimage(Rect(0,0,ow,oh), a->chan)) == nil)
 		sysfatal("%r");