void CompressFile( FILE *input, BIT_FILE *output, int argc, char *argv[] ){ /* FILE *input; BIT_FILE *output; int argc; char *argv[]; { */ int look_ahead[ BUFFER_SIZE ]; int index; int i; int run_length; for ( i = 0 ; i < BUFFER_SIZE ; i++ ) look_ahead[ i ] = getc( input ); index = 0; for ( ; ; ) { if ( look_ahead[ index ] == EOF ) break; /* * If run has started, I handle it here. I sit in the do loop until * the run is complete, loading new characters all the while. */ if ( silence_run( look_ahead, index ) ) { run_length = 0; do { look_ahead[ index ++ ] = getc( input ); index &= BUFFER_MASK; if ( ++run_length == 255 ) { putc( SILENCE_CODE, output->file ); putc( 255, output->file ); run_length = 0; } } while ( !end_of_silence( look_ahead, index ) ); if ( run_length > 0 ) { putc( SILENCE_CODE, output->file ); putc( run_length, output->file ); } } /* * Eventually, any run of silence is over, and I output some plain codes. * Any code that accidentally matches the silence code gets silently * changed. */ if ( look_ahead[ index ]== SILENCE_CODE ) look_ahead[ index ]--; putc( look_ahead[ index ], output->file ); look_ahead[ index++ ] = getc( input ); index = BUFFER_MASK; } while ( argc-- > 0 ) printf( "Unused argument: %s\n", *argv++ ); }
//void CompressFile( FILE *input, BIT_FILE *output, int argc, char *argv[] ) void CompressFile( FILE *input, BIT_FILE *output, int, char*[]) { int look_ahead[ BUFFER_SIZE ]; int index; int i; int run_length; //Update so Silence and Compand do not conflict int silence_match[6] = { 31, 0, 31, 0, 30, 0 }; // Compand addition int compress[ 256 ]; int steps; int bits; int value; int k; int j; bits = 5; steps = ( 1 << ( bits - 1 ) ); // OutputBits( output, (unsigned long) bits, 8 ); // OutputBits( output, (unsigned long) get_file_length( input ), 32 ); for ( k = steps ; k > 0; k-- ) { value = (int) ( 128.0 * ( pow( 2.0, (double) k / steps ) - 1.0 ) + 0.5 ); for ( j = value ; j > 0 ; j-- ) { compress[ j + 127 ] = k + steps - 1; compress[ 128 - j ] = steps - k; } } for ( i = 0 ; i < BUFFER_SIZE ; i++ ) look_ahead[ i ] = getc( input ); index = 0; for ( ; ; ) { if ( look_ahead[ index ] == EOF ) break; /* * If a run has started, I handle it here. I sit in the do loop until * the run is complete, loading new characters all the while. */ if ( silence_run( look_ahead, index ) ) { run_length = 0; do { look_ahead[ index++ ] = getc( input ); index &= BUFFER_MASK; if ( ++run_length == 255 ) { for( i=0; i<6; i++ ) { OutputBits( output, (unsigned long) silence_match[i], bits ); } OutputBits( output, (unsigned long) run_length, 8 ); } } while ( !end_of_silence( look_ahead, index ) ); if ( run_length > 0 ) { for( i=0; i<6;i++ ) { OutputBits( output, (unsigned long) silence_match[i], bits ); } OutputBits( output, (unsigned long) run_length, 8 ); } } /* * Eventually, any run of silence is over, and I output some plain codes. * Any code that accidentally matches the silence code gets silently changed. */ OutputBits( output, (unsigned long) compress[ look_ahead[ index ] ], bits ); look_ahead[ index++ ] = getc( input ); index &= BUFFER_MASK; } }
void codeSilence (void *inb, void *outb) /*********************************************************************** Silence encoding, takes care of "silence" pieces ************************************************************************ inb input buffer outb output buffer ***********************************************************************/ { memBUFF *inbuff = (memBUFF *) inb; memBUFF *outbuff = (memBUFF *) outb; int look_ahead[LOOKAHSZ]; int index, i, run_length, flag; /* preload the look ahead buffer */ for(i=0; i<LOOKAHSZ; i++) if(buffGetc(inbuff, look_ahead[i]) == MEM_EOB) break; /* if not enough samples, no RLE */ if(i < LOOKAHSZ){ buffMerge(outbuff, inbuff); return; } index = 0; for(;;){ if(look_ahead[index] == MEM_EOB) break; if(silence_run(look_ahead, index)){ run_length = 0; do{ flag = buffGetc(inbuff, look_ahead[index]); if(flag == MEM_EOB) look_ahead[index] = MEM_EOB; index ++; index &= LOOKAHMASK; if(++run_length == MAXLENGTH){ buffPutc(outbuff, SILENCECODE); buffPutc(outbuff, MAXLENGTH); run_length = 0; } } while(!end_of_silence(look_ahead, index)); if(run_length > 0){ buffPutc(outbuff, SILENCECODE); buffPutc(outbuff, run_length); } } if(look_ahead[index] == MEM_EOB) break; /* the silence code in the input get changed */ if(look_ahead[index] == SILENCECODE) look_ahead[index]++; buffPutc(outbuff, look_ahead[index]); /* get a new code */ flag = buffGetc(inbuff, look_ahead[index]); if(flag == MEM_EOB) look_ahead[index] = MEM_EOB; index ++; index &= LOOKAHMASK; } }
void codeSilence (void *inb, void *outb) /*********************************************************************** Silence encoding, takes care of "silence" pieces ************************************************************************ inb input buffer outb output buffer ************************************************************************ Note: To avoid the inefficiency in encoding isolated 0's, I start a run only when there are CODESTARTTHRSHOLD consective 0's. Therefore, a look ahead buffer is needed. The run is stopped as soon as there is a non-0 symbol. ***********************************************************************/ { wpcBUFF *inbuff = (wpcBUFF *) inb; wpcBUFF *outbuff = (wpcBUFF *) outb; int look_ahead[CODELOOKAHSZ]; int index, i, run_length, flag; /* preload the look ahead buffer */ for(i=0; i<CODELOOKAHSZ; i++) if(buffGetc(inbuff, look_ahead[i]) == WPC_EOB) break; /* if not enough samples, no RLE */ if(i < CODELOOKAHSZ){ buffMerge(outbuff, inbuff); return; } index = 0; for(;;){ if(look_ahead[index] == WPC_EOB) break; if(silence_run(look_ahead, index)){ run_length = 0; do{ flag = buffGetc(inbuff, look_ahead[index]); if(flag == WPC_EOB) look_ahead[index] = WPC_EOB; index ++; index &= CODELOOKAHMASK; if(++run_length == CODEMAXLENGTH){ buffPutc(outbuff, CODESILENCECODE); buffPutc(outbuff, CODEMAXLENGTH); run_length = 0; } } while(!end_of_silence(look_ahead, index)); if(run_length > 0){ buffPutc(outbuff, CODESILENCECODE); buffPutc(outbuff, run_length); } } if(look_ahead[index] == WPC_EOB) break; /* the silence code in the input get changed */ if(look_ahead[index] == CODESILENCECODE) look_ahead[index]++; buffPutc(outbuff, look_ahead[index]); /* get a new code */ flag = buffGetc(inbuff, look_ahead[index]); if(flag == WPC_EOB) look_ahead[index] = WPC_EOB; index ++; index &= CODELOOKAHMASK; } }