/* * This is the compress routine. It shows the basic algorithm for * the compression programs used in this article. First, an input * characters is loaded. The modeling routines are called to * convert the character to a symbol, which has a high, low and * range. Finally, the arithmetic coder module is called to * output the symbols to the bit stream. */ void compress() { int i; char c; SYMBOL s; FILE *compressed_file; static char *input = "GLIB BATES"; compressed_file=fopen( "software/benchmarks/data/test.cmp", "wb" ); if ( compressed_file == NULL ) error_exit( "Could not open output file" ); puts( "Compressing..." ); initialize_output_bitstream(); initialize_arithmetic_encoder(); for ( i=0 ; ; ) { c = input[ i++ ]; convert_int_to_symbol( c, &s ); encode_symbol( compressed_file, &s ); if ( c == '\0' ) break; } flush_arithmetic_encoder( compressed_file ); flush_output_bitstream( compressed_file ); fclose( compressed_file); }
/* * The main procedure is similar to the main found in ARITH1E.C. It has * to initialize the coder and the model. It then sits in a loop reading * input symbols and encoding them. One difference is that every 256 * symbols a compression check is performed. If the compression ratio * falls below 10%, a flush character is encoded. This flushes the encod * ing model, and will cause the decoder to flush its model when the * file is being expanded. The second difference is that each symbol is * repeatedly encoded until a successful encoding occurs. When trying to * encode a character in a particular order, the model may have to * transmit an ESCAPE character. If this is the case, the character has * to be retransmitted using a lower order. This process repeats until a * successful match is found of the symbol in a particular context. * Usually this means going down no further than the order -1 model. * However, the FLUSH and DONE symbols drop back to the order -2 model. * */ void CompressFile(FILE *input,BIT_FILE *output,int argc,char *argv[]) { SYMBOL s; int c; int escaped; int flush = 0; long int text_count = 0; initialize_options( argc, argv ); initialize_model(); initialize_arithmetic_encoder(); for ( ; ; ) { if ( ( ++text_count & 0x0ff ) == 0 ) flush = check_compression( input, output ); if ( !flush ) c = getc( input ); else c = FLUSH; if ( c == EOF ) c = DONE; do { escaped = convert_int_to_symbol( c, &s); encode_symbol( output, &s ); } while ( escaped ); if ( c == DONE ) break; if ( c == FLUSH ) { flush_model(); flush = 0; } update_model( c ); add_character_to_model( c ); } flush_arithmetic_encoder( output ); }
static void encode_arith_symbol(MscCoderArithModel *arithModel, PutBitContext *pb, int value) { MscCoderArithSymbol arithSymbol; // convert value to range symbol convert_int_to_symbol(arithModel, value, &arithSymbol); // encode symbol by arith encoder encode_symbol(pb, &arithSymbol); // update arithmetic model update_model(arithModel, value); }