Login Register






Run Length Encoder filter_list
Author
Message
Run Length Encoder #1
For those of you who read my tutorial on RLE (link), here is some sample C code to accomplish it.

Code:
/* Run Length Encoder/Decoder * by Ethan Laur (phyrrus9) */ #include <stdio.h> int readuntilnext(FILE *in, unsigned char last, unsigned char *oops, unsigned char *n) { int nread; *n = 1; while ((nread = fread(oops, 1, 1, in)) > 0) //read { if (*oops != last || *n > 254) return 1; //return count if different ++*n; //add 1 to count } return 0; } void rleEncode(FILE *in, FILE *out, unsigned char flag) { unsigned char old = 0, buf, num; int i; readuntilnext(in, old, &buf, &num); //first time reads nothing... old = buf; while (readuntilnext(in, old, &buf, &num)) //read { if (num > 3) //then RLE that shit { fputc(flag, out); //place the flag fwrite(&num, 1, 1, out); //place the count fwrite(&old, 1, 1, out); //place the character } else fwrite(&old, 1, 1, out); //place the character old = buf; //do swap } fflush(out); //write caches } void rleDecode(FILE *in, FILE *out, unsigned char flag) { unsigned char buf, num; int i; while (fread(&buf, 1, 1, in) > 0) //while we read something { if (buf == flag) //if the character was the RLE flag { fread(&num, 1, 1, in); //get the number fread(&buf, 1, 1, in); //get the character for (i = 0; i < num; i++) //loop num times fwrite(&buf, 1, 1, out); //output character } else fwrite(&buf, 1, 1, out); //output character } fflush(out); //write any caches to disk } int main(int argc, char ** argv) { FILE *in = fopen(argv[2], "rb"); FILE *out = fopen(argv[3], "wb"); if (argv[1][0] == 'e') rleEncode(in, out, argv[1][1]); else if (argv[1][0] == 'd') rleDecode(in, out, argv[1][1]); fclose(in); fclose(out); }

Reply

RE: Run Length Encoder #2
I'm going to try to port this over to Python. It'll be nice practice.

Reply

RE: Run Length Encoder #3
Not bad, but a few things I noticed:

- You assign to a local variable 'nread' but never use it in any codebranch in the readuntilnext function.
- 'i' is an unused variable in your rleEncode function.
- You should check that the files returned from fopen() are successfully opened and that the function doesn't return a null pointer, especially if you use the pointers right away and call fclose()
Code:
FILE *in = fopen(argv[2], "rb"); FILE *out = fopen(argv[3], "wb");
- You should use the 'argc' parameter to confirm that those indexes is a valid index in 'argv', and check the string length of the first argument at index [1] to validate that enough characters exist to index up to [1].

I may see more things after I look at this some more.

Reply

RE: Run Length Encoder #4
Here's my version:
Code:
#include <stdio.h> #include <stdlib.h> /* DESCRIPTION: Compresses input file to specified output file using * standard RLE encoding for compression. * (Useful for data with frequent runs.) * RETURNS: 0 on failure, 1 on success. * ------------------------------------------------------- */ int rle_compress(FILE *in, FILE *out) { int ch = fgetc(in), tmp, count = 1; while (!feof(in)) { while ((tmp = fgetc(in)) == ch) ++count; if (ferror(out)) return 0; fprintf(out, "%d", count); putc(ch, out); ch = tmp; count = 1; } return 1; } /* DESCRIPTION: Decompresses input file with RLE encoded data to specified * output file. (Ex format: 1Z3D2Y = ZDDDYY) * RETURNS: 0 on failure, 1 on success. * ------------------------------------------------------- */ int rle_decompress(FILE *in, FILE *out) { int i, ch, count; while (!feof(in)) { if (!fscanf(in, " %d", &count) || (ch = fgetc(in)) == EOF) return 0; for (i = 0; i < count; ++i) putc(ch, out); } return 1; } int main(void) { FILE *in = fopen("input.txt", "rb"); FILE *out = fopen("output.txt", "wb"); if (!(in && out)) { perror("fopen"); exit(1); } /* depending on whether input.txt is encoded, or not encoded... */ rle_decompress(in, out); /* or... */ rle_compress(in, out); fclose(in); fclose(out); return 0; }

NOTE: Works only with non-numeric characters. Some adjustments would need to be made to differentiate between the # and the data in the case of digit characters.

Reply