summaryrefslogtreecommitdiff
path: root/redtools/redrle.c
diff options
context:
space:
mode:
Diffstat (limited to 'redtools/redrle.c')
-rw-r--r--redtools/redrle.c74
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;