/*----------------------------------------------------------------------*/ /* Copyright (c) 1988-1989 */ /* by CompuServe Inc., Tucson, AZ. All Rights Reserved */ /* RLETIF.C can be copied and distributed freely for any */ /* non-commercial purposes. RLETIF.C can only be incorporated */ /* into commercial software with the permission of CompuServe Inc. */ /*----------------------------------------------------------------------*/ /* RLETIF.C */ /* * ABSTRACT: * This file contains routines to convert Run Length Encoded lines * into one-dimensional group-3 FAX compressed lines. * * See RLETIF.H for a summary of functions. * * AUTHOR: Doug Chinnock * * REVISION HISTORY: * */ #include "cnvhuf.h" #include "rletif.h" #include "writetif.h" /* The five constant tables have the form: | | huffman_code | array_xxx_yyy[ n ]; | | where n is the length of the run or 1/64th of it. */ #include "dehuftab.h" /* Variables used among functions: */ static union { unsigned char TIF_ch[4]; /* Assembly buffer for packed bits */ short int TIF_sh[2]; long int TIF_lg; /* Residue always left justified here */ } TIF_pack; short int TIF_bit_count, TIF_pack_filled; /* Bits filled in TIF_pack */ extern void compress_huffman_line( rle_line *emit_line ) { (*emit_line).rle_color = WHITE; TIF_bit_count = 0, TIF_pack_filled = 0; TIF_write_bits( 12, 0x1 ); /* Output EOL (sync?) */ for ( (*emit_line).rle_pointer = 0; (*emit_line).rle_pointer < (*emit_line).rle_count; (*emit_line).rle_pointer ++ ) { compress_huffman_code( (*emit_line).rle_color, (*emit_line).rle_list[(*emit_line).rle_pointer] ); (*emit_line).rle_color = ! (*emit_line).rle_color; }; TIF_write_bits( 16 - TIF_pack_filled, 0 ); /* Even out bits to even byte */ while ( TIF_bit_count < FAX_min_line ) /* Now pad line as needed */ TIF_write_bits( 8, 0 ); } /* compress_huffman_line */ extern void compress_huffman_code( colors color_of_run, int length_of_color ) { /* First put out makeup codes */ while ( length_of_color > 63 ) { if ( length_of_color <= (1728+63) ) { if ( color_of_run == WHITE ) TIF_write_bits( huf_wht_makeup[length_of_color/64-1].code_bits, huf_wht_makeup[length_of_color/64-1].code_value ); else TIF_write_bits( huf_blk_makeup[length_of_color/64-1].code_bits, huf_blk_makeup[length_of_color/64-1].code_value ); length_of_color %= 64; } else if ( length_of_color <= (2560+63) ) { TIF_write_bits( huf_big_makeup[(length_of_color-1792)/64].code_bits, huf_wht_makeup[(length_of_color-1792)/64].code_value ); length_of_color %= 64; } else { TIF_write_bits( huf_big_makeup[(2560-1792)/64].code_bits, huf_wht_makeup[(2560-1792)/64].code_value ); length_of_color -= 2560; }; }; /* Finally put out termination code */ if ( color_of_run == WHITE ) TIF_write_bits( huf_wht_final[length_of_color].code_bits, huf_wht_final[length_of_color].code_value ); else TIF_write_bits( huf_blk_final[length_of_color].code_bits, huf_blk_final[length_of_color].code_value ); } /* compress_huffman_code */ void TIF_write_bits( short int size_to_write, unsigned int bit_value ) { short int i; bit_value <<= 16 - size_to_write; /* Left justify new data */ for ( i = 0; i < size_to_write; i ++ ) { TIF_pack.TIF_lg >>= 1; if ( (bit_value & 0x8000) != 0 ) TIF_pack.TIF_ch[3] |= 0x80; else TIF_pack.TIF_ch[3] &= 0x7F; bit_value <<= 1; }; TIF_pack_filled += size_to_write; TIF_pack.TIF_lg >>= 32 - TIF_pack_filled; /* Right justify result */ while ( TIF_pack_filled >= 8 ) /* Output any full bytes */ { put_TIF_byte( TIF_pack.TIF_ch[0] ); TIF_pack.TIF_lg >>= 8; TIF_pack_filled -= 8; TIF_bit_count += 8; }; TIF_pack.TIF_lg <<= 32 - TIF_pack_filled; /* Left justify remainder */ } /* TIF_write_bits */