Run Length Encoder 06-25-2015, 09:00 AM
#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);
}