Skip to content

Instantly share code, notes, and snippets.

@jibsen
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jibsen/75275f594f2100b5df77 to your computer and use it in GitHub Desktop.
Save jibsen/75275f594f2100b5df77 to your computer and use it in GitHub Desktop.
PackBits RLE compressor
// PackBits RLE compressor
// Usage: packbits c|d input output
// Originally by Matt Mahoney, adapted for PackBits. Public domain.
#include <stdio.h>
int main(int argc, char** argv) {
// Check args
if (argc!=4)
return printf("To compress|decompress: packbits c|d input output\n"), 1;
// Open files
FILE* in=fopen(argv[2], "rb");
if (!in) return perror(argv[2]), 1;
FILE* out=fopen(argv[3], "wb");
if (!out) return perror(argv[3]), 1;
int c, c1=-1; // current and last char
char t[128]; // buffer for literals
int run=0; // current run length
int lrun=0; // current literal run length
// Compress
if (argv[1][0]=='c') {
// RLE encode
do {
c=getc(in);
if (c==c1) {
if (lrun>1) { putc(lrun-2, out); fwrite(t, 1, lrun-1, out); }
lrun=0;
if (++run==128) { putc(-127, out); putc(c1, out); run=0; t[lrun++]=c; }
}
else {
if (run>0) { putc(-run, out); putc(c1, out); run=0; }
if (lrun==128) { putc(127, out); fwrite(t, 1, 128, out); lrun=0; }
t[lrun++]=c;
}
c1=c;
} while (c!=EOF);
if (lrun>1) { putc(lrun-2, out); fwrite(t, 1, lrun-1, out); }
}
// Decompress
else if (argv[1][0]=='d') {
// Decode
while ((c=getc(in))!=EOF) {
if (c>127) {
if (c==128) continue;
run=257-c;
if ((c=getc(in))==EOF) return 1;
for (; run>0; --run) putc(c, out);
}
else {
lrun=c+1;
for (; lrun>0; --lrun) {
if ((c=getc(in))==EOF) return 1;
putc(c, out);
}
}
}
}
// Print result
printf("PRLE %lu -> %lu\n", ftell(in), ftell(out));
fclose(in);
fclose(out);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment