Run-length encoding: Difference between revisions

C (maybe with more than needed)
(Import code from Wikipedia)
 
(C (maybe with more than needed))
Line 9:
: Input: <code>WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW</code>
: Output: <code>12W1B12W3B24W1B14W</code>
 
=={{header|C}}==
 
These functions have no check for the size of the output buffers.
 
'''Encoding function''
 
Since repeat counter must fit a single byte in this implementation, it can't be greater than 255, so a byte repeated more than 255 times generates in the compressed stream more than 2 bytes (4 bytes if the length of the repeated byte sequence is less than 510 and so on)
 
<lang c>int rle_encode(char *out, const char *in, int l)
{
int dl, i;
char cp, c;
 
for(cp=c= *in++, i = 0, dl=0; l>=0 ; c = *in++, l-- ) {
if ( c == cp ) {
i++;
if ( i > 255 ) {
*out++ = 255;
*out++ = c; dl += 2;
i = 1;
}
} else {
*out++ = i;
*out++ = cp; dl += 2;
i = 1;
}
cp = c;
}
return dl;
}</lang>
 
'''Decoding function'''
 
<lang c>int rle_decode(char *out, const char *in, int l)
{
int i, j, tb;
char c;
 
for(tb=0 ; l>=0 ; l -= 2 ) {
i = *in++;
c = *in++;
tb += i;
while(i-- > 0) *out++ = c;
}
return tb;
}</lang>
 
'''Usage example'''
 
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
const char *o = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
 
int main()
{
char *d = malloc(strlen(o));
char *oc = malloc(strlen(o));
int rl = rle_encode(d, o, strlen(o));
/* fwrite(d, 1, rl, stdout); */
 
int ocl = rle_decode(oc, d, rl);
fwrite(oc, 1, ocl, stdout);
 
free(d); free(oc);
return 0;
}</lang>
 
Here encoding and decoding are implementend as "filters" which compress/decompress standard input to standard output writing ASCII strings; they will work as long as the input has no ASCII digits in it, and the compressed/original ratio of a "single group" will be less than or equal to 1 as long as the ASCII decimal representation's length of the repeat counter will be shorter than the length of the "group". It should be so except in the case the group is a single isolated character, e.g. B gives 1B (one byte against two compressed bytes)
 
'''Encoding filter'''
 
<lang c>#include <stdio.h>
 
int main()
{
int i, c, cp;
 
for(cp=c=getchar(), i = 0; c != EOF; c = getchar() ) {
if ( c == cp ) {
i++;
} else {
printf("%d%c", i, cp);
i = 1;
}
cp = c;
}
}</lang>
 
'''Decoding filter'''
 
<lang c>#include <stdio.h>
 
int main()
{
int i, c, j;
 
while( scanf("%d%c", &i, &c) == 2 ) {
for(j=0; j < i; j++) printf("%c", c);
}
}</lang>
 
=={{header|Haskell}}==