From 8a0fc71b6c2b8b1ebb2fbc9d4ac1ff35a892014b Mon Sep 17 00:00:00 2001
From: Martin Uecker <uecker@tugraz.at>
Date: Tue, 9 Jul 2024 18:18:25 +0200
Subject: [PATCH] resize front

---
 src/num/multind.c | 35 +++++++++++++++++++++++++++++++----
 src/num/multind.h |  1 +
 src/resize.c      | 21 ++++++++++++++++++---
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/src/num/multind.c b/src/num/multind.c
index 58ab077e5..1306891ba 100644
--- a/src/num/multind.c
+++ b/src/num/multind.c
@@ -1277,16 +1277,43 @@ void md_resize_center(int D, const long odim[D], void* optr, const long idim[D],
 
 	for (int i = 0; i < D; i++) {
 
-		if (odim[i] > idim[i]) {
+		if (odim[i] >= idim[i])
+			continue;
 
-			md_clear(D, odim, optr, size);
-			break;
-		}
+		md_clear(D, odim, optr, size);
+		break;
 	}
 
 	md_copy_block(D, pos, odim, optr, idim, iptr, size);
 }
 
+
+
+/**
+ * Resize an array by zero-padding or by truncation at the beginning.
+ *
+ * optr = [0 0 0 0 iptr]
+ *
+ */
+void md_resize_front(int D, const long odim[D], void* optr, const long idim[D], const void* iptr, size_t size)
+{
+	long pos[D];
+	for (int i = 0; i < D; i++)
+		pos[i] = odim[i] - idim[i];
+
+	for (int i = 0; i < D; i++) {
+
+		if (odim[i] <= idim[i])
+			continue;
+
+		md_clear(D, odim, optr, size);
+		break;
+	}
+
+	md_copy_block(D, pos, odim, optr, idim, iptr, size);
+}
+
+
 /**
  * Pad an array on both ends by val.
  *
diff --git a/src/num/multind.h b/src/num/multind.h
index 681cc50ef..1815d874f 100644
--- a/src/num/multind.h
+++ b/src/num/multind.h
@@ -60,6 +60,7 @@ extern void md_reflectpad_center2(int D, const long odim[__VLA(D)], const long o
 extern void md_reflectpad_center(int D, const long odim[__VLA(D)], void* optr, const long idim[__VLA(D)], const void* iptr, size_t size);
 extern void md_resize(int D, const long odim[__VLA(D)], void* optr, const long idim[__VLA(D)], const void* iptr, size_t size);
 extern void md_resize_center(int D, const long odim[__VLA(D)], void* optr, const long idim[__VLA(D)], const void* iptr, size_t size);
+extern void md_resize_front(int D, const long odim[__VLA(D)], void* optr, const long idim[__VLA(D)], const void* iptr, size_t size);
 extern void md_fill2(int D, const long dim[__VLA(D)], const long str[__VLA(D)], void* ptr, const void* iptr, size_t size);
 extern void md_fill(int D, const long dim[__VLA(D)], void* ptr, const void* iptr, size_t size);
 extern void md_slice2(int D, unsigned long flags, const long pos[__VLA(D)], const long dim[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long istr[__VLA(D)], const void* iptr, size_t size);
diff --git a/src/resize.c b/src/resize.c
index 0d91ce279..f14bbf479 100644
--- a/src/resize.c
+++ b/src/resize.c
@@ -48,11 +48,12 @@ int main_resize(int argc, char* argv[argc])
 		ARG_OUTFILE(true, &out_file, "output"),
 	};
 
-	bool center = false;
+	enum mode { FRONT, CENTER, END } mode = END;;
 
 	const struct opt_s opts[] = {
 
-		OPT_SET('c', &center, "center"),
+		OPT_SELECT('c', enum mode, &mode, CENTER, "center"),
+		OPT_SELECT('f', enum mode, &mode, FRONT, "front"),
 	};
 
 	cmdline(&argc, argv, ARRAY_SIZE(args), args, help_str, ARRAY_SIZE(opts), opts);
@@ -81,7 +82,21 @@ int main_resize(int argc, char* argv[argc])
 
 	void* out_data = create_cfl(out_file, N, out_dims);
 
-	(center ? md_resize_center : md_resize)(N, out_dims, out_data, in_dims, in_data, CFL_SIZE);
+	switch (mode) {
+	case FRONT:
+
+		md_resize_front(N, out_dims, out_data, in_dims, in_data, CFL_SIZE);
+		break;
+
+	case CENTER:
+
+		md_resize_center(N, out_dims, out_data, in_dims, in_data, CFL_SIZE);
+		break;
+
+	case END:
+		md_resize(N, out_dims, out_data, in_dims, in_data, CFL_SIZE);
+		break;
+	}
 
 	unmap_cfl(N, in_dims, in_data);
 	unmap_cfl(N, out_dims, out_data);