shithub: imgtools

Download patch

ref: f93909b95a5ec11c13bea21d8f024264714f7e57
parent: 172c1e097c06d3a707992034cae962f513c1c73c
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Jan 20 06:27:27 EST 2021

resample: free-form combined crop/resampling

--- a/resample.c
+++ b/resample.c
@@ -40,7 +40,7 @@
 	char *flts, *s, *csps, *e;
 	int n, bp, to, stmode;
 	int alphai, flags;
-	int w, h, ow, oh;
+	int w, h, ow, oh, iw, ih;
 	int wp, hp, f, c;
 	Memimage *a, *b;
 	u8int *in, *out;
@@ -84,7 +84,7 @@
 			if(*e != ',')
 				break;
 		}
-		if(n != 3)
+		if(n != 3 || st[2] <= st[0] || st[3] <= st[1])
 			sysfatal("invalid rect %s", s);
 		break;
 	default:
@@ -91,6 +91,13 @@
 		usage();
 	}ARGEND
 
+	for(f = 0; f < nelem(filters) && (filters[f] == nil || strcmp(flts, filters[f]) != 0); f++);
+	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))
+		sysfatal("invalid colorspace %s", csps);
+
 	if(wp && oh == 0){
 		oh = ow;
 		hp = 1;
@@ -99,13 +106,6 @@
 		wp = 1;
 	}
 
-	for(f = 0; f < nelem(filters) && (filters[f] == nil || strcmp(flts, filters[f]) != 0); f++);
-	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))
-		sysfatal("invalid colorspace %s", csps);
-
 	memimageinit();
 	if((a = readmemimage(0)) == nil)
 		sysfatal("memory");
@@ -112,10 +112,32 @@
 	w = Dx(a->r);
 	h = Dy(a->r);
 
+	if(stmode == Stpixels){
+		iw = st[2]-st[0];
+		ih = st[3]-st[1];
+		st[0] /= (double)w;
+		st[1] /= (double)h;
+		st[2] /= (double)w;
+		st[3] /= (double)h;
+	}else{
+		iw = w;
+		ih = h;
+	}
+
 	if(ow < 1)
-		ow = w;
+		ow = iw;
 	if(oh < 1)
-		oh = h;
+		oh = ih;
+	if(wp)
+		ow = iw*ow/100.0;
+	if(hp)
+		oh = ih*oh/100.0;
+	if(oh == 0)
+		oh = ow*ih/iw;
+	if(ow == 0)
+		ow = oh*iw/ih;
+	if(ow < 1 || oh < 1)
+		sysfatal("invalid size: %dx%d", ow, oh);
 
 	bp = 0;
 again:
@@ -165,24 +187,6 @@
 		sysfatal("invalid chan %#lux", a->chan);
 	}
 
-	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)
-		oh = h*oh/100.0;
-	if(oh == 0)
-		oh = ow*h/w;
-	if(ow == 0)
-		ow = oh*w/h;
-	if(ow < 1 || oh < 1)
-		sysfatal("invalid size: %dx%d", ow, oh);
 	n = w*h*bp;
 	if((in = malloc(w*h*bp)) == nil)
 		sysfatal("%r");