// SPDX-License-Identifier: WTFPL #include #include #include #include extern char *optarg; #define WIDTH 1500 struct header { char signature[7]; char unknown[4]; } __attribute__((packed)); __attribute__((unused)) const static char sig[] = "SynFax2"; static char *loadfile(char *filename, int *size) { FILE *fp; char *buf = NULL; int filesize; if ((fp = fopen(filename, "r")) == NULL) { printf("loadfile: %s open error\n", filename); goto fin0; } fseek(fp, 0, SEEK_END); filesize = ftell(fp) - sizeof(struct header); fseek(fp, sizeof(struct header), SEEK_SET); *size = ((filesize + WIDTH - 1) / WIDTH) * WIDTH; if (*size < WIDTH || (buf = calloc(*size, 1)) == NULL) goto fin1; fread(buf, filesize, 1, fp); fin1: fclose(fp); fin0: return buf; } static int savefile(char *filename, char *buf, int x, int y) { int result; FILE *fp; if ((fp = fopen(filename, "w")) == NULL) { printf("savefile: %s open error\n", filename); result = -1; goto fin0; } fprintf(fp, "P5\n%d %d\n255\n", x, y); fwrite(buf, x * y, 1, fp); result = 0; fclose(fp); fin0: return result; } static void do_rotate(char *outbuf, char *inbuf, int in_x, int in_y) { int x, y; for (y = 0; y < in_y; y++) { for (x = 0; x < in_x; x++) { outbuf[(in_x - x - 1) * in_y + y] = inbuf[y * in_x + x]; } } } int main(int argc, char *argv[]) { int ch, size, x, y, rotate = 0; char *infile = NULL, *outfile = NULL, *inbuf, *outbuf; while ((ch = getopt(argc, argv, "i:o:r")) != -1) { switch (ch) { case 'i': infile = optarg; break; case 'o': outfile = optarg; break; case 'r': rotate = 1; break; } } if (infile == NULL || outfile == NULL) { printf("usage: %s -i [infile] -o [outfile]\n", argv[0]); goto fin0; } if ((inbuf = loadfile(infile, &size)) == NULL) goto fin0; if (rotate) { x = size / WIDTH; y = WIDTH; if ((outbuf = malloc(size)) == NULL) goto fin1; do_rotate(outbuf, inbuf, y, x); } else { x = WIDTH; y = size / WIDTH; outbuf = inbuf; inbuf = NULL; } if (savefile(outfile, outbuf, x, y)) goto fin2; fin2: free(outbuf); fin1: free(inbuf); fin0: return 0; }