floor tool
[mdlife] / tools / floor / floor.c
diff --git a/tools/floor/floor.c b/tools/floor/floor.c
new file mode 100644 (file)
index 0000000..4db2d22
--- /dev/null
@@ -0,0 +1,62 @@
+#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;
+       }
+}