39.54 rle.c

/*  
 * rle.cpp  
 *  
 * Run Length Encoding.  
 *  
 * Codifica una secuencia de símbolos usando una codificación de  
 * series. El tamaño del alfabeto es 256 y el tamaño del código usado  
 * para especificar la longitud de la serie es de 8 bits. La longitud  
 * mínima d ela serie es 2. Ejemplos:  
 *  
 * input output  
 * ----- ------  
 * ab    ab  
 * aab   aa0b  
 * aaab  aa1b  
 * aaaab aa2b  
 *  
 * Usos típicos:  
 *  
 * rle < raw-file > compressed-file  
 * rle < raw-file | bwt | mtf | rle | ari > compressed-file  
 *  
 * Referencias:  
 *  
 * M. Nelson and J.-L. Gailly, The Data Compression Book. 1995.  
 */  
 
#include <stdio.h>  
 
void read_and_encode_run(int *symbol, int prev_symbol) {  
  if(*symbol == prev_symbol) {  
    int length = 0;  
    *symbol = getchar();  
 
    while((*symbol != EOF) && (length < 255)) {  
      if(*symbol == prev_symbol) {  
        *symbol = getchar();  
        length++;  
      }  
      else break;  
    }  
    putchar(length);  
    if((length != 255) && (*symbol != EOF)) {  
      putchar(*symbol);  
    }  
  }  
}  
 
void encode_stream() {  
  int prev_symbol = 0;  
  int symbol = getchar();  
  while (symbol != EOF) {  
    putchar(symbol);  
    read_and_encode_run(&symbol, prev_symbol);  
    prev_symbol = symbol;  
    symbol = getchar();  
  }  
}  
 
void read_and_decode_run(int symbol, int prev_symbol) {  
  if(symbol == prev_symbol) {  
    int length = getchar();  
    while(length-- > 0) {  
      putchar(symbol);  
    }  
  }  
}  
 
void decode_stream() {  
  int prev_symbol = 0;  
  int symbol = getchar();;  
  while(symbol != EOF)  {  
    putchar(symbol);  
    read_and_decode_run(symbol, prev_symbol);  
    prev_symbol = symbol;  
    symbol = getchar();  
  }  
}