char *argv[] { int character; int string_code; unsigned int index; InitializeStorage(); InitializeDictionary(); if ( ( string_code = getc( input ) ) == EOF ) string_code = END_OF_STREAM; while ( ( character = getc( input ) ) != EOF ) { index = find_child_node( string_code, character ); if ( DICT( index ).code_value != -1) string_code = DICT( index ).code_value; else { DICT( index ).code_value = next_code++; DICT( index ).parent_code = string_code; DICT( index ).character = (char) character; OutputBits( output, (unsigned long) string_code, current_code_bits ); string_code = character; if ( next_code > MAX_CODE ) { OutputBits( output, (unsigned long) FLUSH_CODE, current_code_bits ); InitializeDictionary(); } else if ( next_code > next_bump_code ) { OutputBits( output, (unsigned long) BUMP_CODE, current_code_bits ); current_code_bits++; next_bump_code <<= 1; next_bump_code |= 1; putc( 'B', stdout ); } } } OutputBits( output, (unsigned long) string_code, current_code_bits ); OutputBits( output, (unsigned long) END_OF_STREAM, current_code_bits); while ( argc— > 0 ) printf( "Unknown argument: %s\n", *argv++ ); }
ubyte *lzw_expand( ubyte *inputbuf, ubyte *outputbuf, int length ) { BIT_BUF *input; unsigned int new_code; unsigned int old_code; int character; unsigned int count; int counter; input = OpenInputBitBuf( inputbuf ); if ( outputbuf == NULL ) outputbuf = (ubyte *)malloc(length*sizeof(ubyte)); InitializeStorage(); counter = 0; for ( ; ; ) { InitializeDictionary(); old_code = (unsigned int) InputBits( input, current_code_bits ); if ( old_code == END_OF_STREAM ) { CloseInputBitBuf( input ); return outputbuf; } character = old_code; if (counter<length) { outputbuf[counter++] = ( ubyte ) old_code; } else { //printf( "ERROR:Tried to write %d\n", old_code ); //exit(1); return 0; } for ( ; ; ) { new_code = (unsigned int) InputBits( input, current_code_bits ); if ( new_code == END_OF_STREAM ) { CloseInputBitBuf( input ); FreeStorage(); return outputbuf; } if ( new_code == FLUSH_CODE ) break; if ( new_code == BUMP_CODE ) { current_code_bits++; continue; } if ( new_code >= next_code ) { decode_stack[ 0 ] = (char) character; count = decode_string( 1, old_code ); } else { count = decode_string( 0, new_code ); } character = decode_stack[ count - 1 ]; while ( count > 0 ) { // This lets the case counter==length pass through. // This is a hack. if (counter<length) { //printf("%x ", ( ubyte ) decode_stack[ count ]); outputbuf[counter++] = ( ubyte ) decode_stack[ --count ]; } else if (counter>length) { printf( "ERROR:Tried to write %d\n", decode_stack[ --count ] ); exit(1); } else count--; } dict[ next_code ].parent_code = old_code; dict[ next_code ].character = (char) character; next_code++; old_code = new_code; } } }
ubyte *lzw_compress( ubyte *inputbuf, ubyte *outputbuf, int input_size, int *output_size ) { BIT_BUF *output; int character; int string_code; unsigned int index; int i; output = OpenOutputBitBuf(); if ( outputbuf == NULL ) { output->buf = (ubyte *)malloc(input_size*sizeof(ubyte)); if (output->buf == NULL) { //printf(" ERROR : OpenOutputBitBuf - Not enough memory to read buffer.\n"); //exit(1); return NULL; } outputbuf = output->buf; } else { output->buf = outputbuf; } InitializeStorage(); InitializeDictionary(); string_code = ( *inputbuf++ ); for ( i=0 ; i<input_size ; i++ ) { if (output->current_byte+4 >= input_size) { CloseOutputBitBuf( output ); FreeStorage(); free( outputbuf ); *output_size = -1; return NULL; } character = ( *inputbuf++ ); index = find_child_node( string_code, character ); if ( dict[ index ].code_value != - 1 ) { string_code = dict[ index ].code_value; } else { dict[ index ].code_value = next_code++; dict[ index ].parent_code = string_code; dict[ index ].character = (char) character; OutputBits( output,(unsigned long) string_code, current_code_bits ); string_code = character; if ( next_code > MAX_CODE ) { OutputBits( output,(unsigned long) FLUSH_CODE, current_code_bits ); InitializeDictionary(); } else if ( next_code > next_bump_code ) { OutputBits( output,(unsigned long) BUMP_CODE, current_code_bits ); current_code_bits++; next_bump_code <<= 1; next_bump_code |= 1; } } } OutputBits( output, (unsigned long) string_code, current_code_bits ); OutputBits( output, (unsigned long) END_OF_STREAM, current_code_bits); *output_size = output->current_byte + 1; CloseOutputBitBuf( output ); FreeStorage(); return outputbuf; }