--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <imago2.h>
+
+void scale_line(uint32_t *dst, uint32_t *src, float scale, int xsz);
+
+int main(int argc, char **argv)
+{
+ uint32_t *img, *newimg, *src, *dst;
+ float scale, y, z;
+ int i, scanline, xsz, ysz;
+
+ if(!argv[1] || !argv[2]) {
+ fprintf(stderr, "usage: %s <srcfile> <dstfile>\n", argv[0]);
+ return 1;
+ }
+
+ if(!(img = img_load_pixels(argv[1], &xsz, &ysz, IMG_FMT_RGBA32))) {
+ fprintf(stderr, "failed to open: %s\n", argv[1]);
+ return 1;
+ }
+
+ if(!(newimg = calloc(1, xsz * ysz * 4))) {
+ perror("malloc failed");
+ return 1;
+ }
+
+ dst = newimg;
+ for(i=0; i<ysz; i++) {
+ y = (float)(i + 1) / (float)ysz;
+ z = 20.0f / y;
+ scale = (float)i / (2.0f * (float)ysz) + 0.5f;
+ scanline = ysz - 1 - (int)(z * ysz / 25.0f) % ysz;
+ src = img + scanline * xsz;
+ scale_line(dst, src, scale, xsz);
+ dst += xsz;
+ }
+
+ if(img_save_pixels(argv[2], newimg, xsz, ysz, IMG_FMT_RGBA32) == -1) {
+ fprintf(stderr, "failed to save: %s\n", argv[2]);
+ return 1;
+ }
+ return 0;
+}
+
+void scale_line(uint32_t *dst, uint32_t *src, float scale, int xsz)
+{
+ int i, idx, newsz;
+ float sx, dx;
+
+ newsz = xsz * scale;
+ dx = 1.0 / scale;
+ sx = xsz - (xsz - newsz) / (2.0f * scale);
+
+ for(i=0; i<xsz; i++) {
+ idx = (int)sx;
+ *dst++ = src[idx % xsz];
+ sx += dx;
+ }
+}