diff options
Diffstat (limited to 'redtools/redrle.c')
-rw-r--r-- | redtools/redrle.c | 74 |
1 files changed, 58 insertions, 16 deletions
diff --git a/redtools/redrle.c b/redtools/redrle.c index e753b3a..b8ec529 100644 --- a/redtools/redrle.c +++ b/redtools/redrle.c @@ -1,5 +1,5 @@ /* - * Copyright © 2011 IIMarckus <iimarckus@gmail.com> + * Copyright © 2011, 2014 IIMarckus <iimarckus@gmail.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,27 +23,50 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> void usage() { - fprintf(stderr, "Usage: redrle [-d] infile outfile\n"); + fprintf(stderr, "Usage: redrle [-dr] infile outfile\n"); exit(1); } +void +squash(int threshold, FILE *f, int lastbyte, int *count, int *xpos) +{ + fputc(lastbyte << 4 | threshold, f); + *xpos += threshold; + *xpos %= 20; + *count -= threshold; +} + int main(int argc, char *argv[]) { FILE *infile, *outfile; + int ch; bool d = false; /* compress or decompress flag */ + bool rows = false; /* compress individual rows or entire file */ + + while ((ch = getopt(argc, argv, "dr")) != -1) { + switch(ch) { + case 'd': + d = true; + break; + case 'r': + rows = true; + break; + default: + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; - if (argc < 3 || argc > 4) + if (argc < 2) { usage(); - - if (strcmp(argv[1], "-d") == 0) { - if (argc != 4) - usage(); - d = true; } infile = fopen(argv[argc - 2], "rb"); @@ -80,17 +103,27 @@ main(int argc, char *argv[]) fputc(byte, outfile); } } else { /* compress */ - int byte, count = 0, lastbyte = 0; + int byte, count = 0, lastbyte = 0, xpos = 0; for (;;) { byte = fgetc(infile); if (feof(infile)) { while (count > 0xF) { - count -= 0xF; - fputc(lastbyte << 4 | 0xF, outfile); + if (rows && 20 - xpos <= 0xF) { + squash(20 - xpos, outfile, + lastbyte, &count, &xpos); + continue; + } + squash(0xF, outfile, lastbyte, &count, + &xpos); } if (count != 0) { - fputc(lastbyte << 4 | count, outfile); + if (rows && 20 - xpos < count) { + squash(20 - xpos, outfile, + lastbyte, &count, &xpos); + } + squash(count, outfile, lastbyte, + &count, &xpos); } break; } @@ -105,12 +138,21 @@ main(int argc, char *argv[]) ++count; else { while (count > 0xF) { - count -= 0xF; - fputc(lastbyte << 4 | 0xF, outfile); + if (rows && 20 - xpos <= 0xF) { + squash(20 - xpos, outfile, + lastbyte, &count, &xpos); + continue; + } + squash(0xF, outfile, lastbyte, &count, + &xpos); } if (count != 0) { - fputc(lastbyte << 4 | count, outfile); - count = 0; + if (rows && 20 - xpos < count) { + squash(20 - xpos, outfile, + lastbyte, &count, &xpos); + } + squash(count, outfile, lastbyte, + &count, &xpos); } lastbyte = byte; |