diff options
Diffstat (limited to 'gs/base/scf.h')
-rw-r--r-- | gs/base/scf.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/gs/base/scf.h b/gs/base/scf.h new file mode 100644 index 000000000..cfcc54f33 --- /dev/null +++ b/gs/base/scf.h @@ -0,0 +1,205 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ + +/* $Id$ */ +/* Common definitions for CCITTFax encoding and decoding filters */ + +#ifndef scf_INCLUDED +# define scf_INCLUDED + +#include "shc.h" + +/* + * The CCITT Group 3 (T.4) and Group 4 (T.6) fax specifications map + * run lengths to Huffman codes. White and black have different mappings. + * If the run length is 64 or greater, two or more codes are needed: + * - One or more 'make-up' codes for 2560 pixels; + * - A 'make-up' code that encodes the multiple of 64; + * - A 'termination' code for the remainder. + * For runs of 63 or less, only the 'termination' code is needed. + */ + +/* ------ Encoding tables ------ */ + +/* + * The maximum possible length of a scan line is determined by the + * requirement that 3 runs have to fit into the stream buffer. + * A run of length N requires approximately ceil(N / 2560) makeup codes, + * hence 1.5 * ceil(N / 2560) bytes. Taking the largest safe stream + * buffer size as 32K, we arrive at the following maximum width: + */ +#if arch_sizeof_int > 2 +# define cfe_max_width (2560 * 32000 * 2 / 3) +#else +# define cfe_max_width (max_int - 40) /* avoid overflows */ +#endif +/* The +5 in cfe_max_code_bytes is a little conservative. */ +#define cfe_max_code_bytes(width) ((width) / 2560 * 3 / 2 + 5) + +typedef hce_code cfe_run; + +/* Codes common to 1-D and 2-D encoding. */ +/* The decoding algorithms know that EOL is 0....01. */ +#define run_eol_code_length 12 +#define run_eol_code_value 1 +extern const cfe_run cf_run_eol; +typedef struct cf_runs_s { + cfe_run termination[64]; + cfe_run make_up[41]; +} cf_runs; +extern const cf_runs + cf_white_runs, cf_black_runs; +extern const cfe_run cf_uncompressed[6]; +extern const cfe_run cf_uncompressed_exit[10]; /* indexed by 2 x length of */ + + /* white run + (1 if next run black, 0 if white) */ +/* 1-D encoding. */ +extern const cfe_run cf1_run_uncompressed; + +/* 2-D encoding. */ +extern const cfe_run cf2_run_pass; + +#define cf2_run_pass_length 4 +#define cf2_run_pass_value 0x1 +#define cf2_run_vertical_offset 3 +extern const cfe_run cf2_run_vertical[7]; /* indexed by b1 - a1 + offset */ +extern const cfe_run cf2_run_horizontal; + +#define cf2_run_horizontal_value 1 +#define cf2_run_horizontal_length 3 +extern const cfe_run cf2_run_uncompressed; + +/* 2-D Group 3 encoding. */ +extern const cfe_run cf2_run_eol_1d; +extern const cfe_run cf2_run_eol_2d; + +/* ------ Decoding tables ------ */ + +typedef hcd_code cfd_node; + +#define run_length value + +/* + * The value in the decoding tables is either a white or black run length, + * or a (negative) exceptional value. + */ +#define run_error (-1) +#define run_zeros (-2) /* EOL follows, possibly with more padding first */ +#define run_uncompressed (-3) +/* 2-D codes */ +#define run2_pass (-4) +#define run2_horizontal (-5) + +#define cfd_white_initial_bits 8 +#define cfd_white_min_bits 4 /* shortest white run */ +extern const cfd_node cf_white_decode[]; + +#define cfd_black_initial_bits 7 +#define cfd_black_min_bits 2 /* shortest black run */ +extern const cfd_node cf_black_decode[]; + +#define cfd_2d_initial_bits 7 +#define cfd_2d_min_bits 4 /* shortest non-H/V 2-D run */ +extern const cfd_node cf_2d_decode[]; + +#define cfd_uncompressed_initial_bits 6 /* must be 6 */ +extern const cfd_node cf_uncompressed_decode[]; + +/* ------ Run detection macros ------ */ + +/* + * For the run detection macros: + * white_byte is 0 or 0xff for BlackIs1 or !BlackIs1 respectively; + * data holds p[-1], inverted if !BlackIs1; + * count is the number of valid bits remaining in the scan line. + */ + +/* Aliases for bit processing tables. */ +#define cf_byte_run_length byte_bit_run_length_neg +#define cf_byte_run_length_0 byte_bit_run_length_0 + +/* Skip over white pixels to find the next black pixel in the input. */ +/* Store the run length in rlen, and update data, p, and count. */ +/* There are many more white pixels in typical input than black pixels, */ +/* and the runs of white pixels tend to be much longer, so we use */ +/* substantially different loops for the two cases. */ + +#define skip_white_pixels(data, p, count, white_byte, rlen)\ +BEGIN\ + rlen = cf_byte_run_length[count & 7][data ^ 0xff];\ + if ( rlen >= 8 ) { /* run extends past byte boundary */\ + if ( white_byte == 0 ) {\ + if ( p[0] ) { data = p[0]; p += 1; rlen -= 8; }\ + else if ( p[1] ) { data = p[1]; p += 2; }\ + else {\ + while ( !(p[2] | p[3] | p[4] | p[5]) )\ + p += 4, rlen += 32;\ + if ( p[2] ) {\ + data = p[2]; p += 3; rlen += 8;\ + } else if ( p[3] ) {\ + data = p[3]; p += 4; rlen += 16;\ + } else if ( p[4] ) {\ + data = p[4]; p += 5; rlen += 24;\ + } else /* p[5] */ {\ + data = p[5]; p += 6; rlen += 32;\ + }\ + }\ + } else {\ + if ( p[0] != 0xff ) { data = (byte)~p[0]; p += 1; rlen -= 8; }\ + else if ( p[1] != 0xff ) { data = (byte)~p[1]; p += 2; }\ + else {\ + while ( (p[2] & p[3] & p[4] & p[5]) == 0xff )\ + p += 4, rlen += 32;\ + if ( p[2] != 0xff ) {\ + data = (byte)~p[2]; p += 3; rlen += 8;\ + } else if ( p[3] != 0xff ) {\ + data = (byte)~p[3]; p += 4; rlen += 16;\ + } else if ( p[4] != 0xff ) {\ + data = (byte)~p[4]; p += 5; rlen += 24;\ + } else /* p[5] != 0xff */ {\ + data = (byte)~p[5]; p += 6; rlen += 32;\ + }\ + }\ + }\ + rlen += cf_byte_run_length_0[data ^ 0xff];\ + }\ + count -= rlen;\ +END + +/* Skip over black pixels to find the next white pixel in the input. */ +/* Store the run length in rlen, and update data, p, and count. */ + +#define skip_black_pixels(data, p, count, white_byte, rlen)\ +BEGIN\ + rlen = cf_byte_run_length[count & 7][data];\ + if ( rlen >= 8 ) {\ + if ( white_byte == 0 )\ + for ( ; ; p += 4, rlen += 32 ) {\ + if ( p[0] != 0xff ) { data = p[0]; p += 1; rlen -= 8; break; }\ + if ( p[1] != 0xff ) { data = p[1]; p += 2; break; }\ + if ( p[2] != 0xff ) { data = p[2]; p += 3; rlen += 8; break; }\ + if ( p[3] != 0xff ) { data = p[3]; p += 4; rlen += 16; break; }\ + }\ + else\ + for ( ; ; p += 4, rlen += 32 ) {\ + if ( p[0] ) { data = (byte)~p[0]; p += 1; rlen -= 8; break; }\ + if ( p[1] ) { data = (byte)~p[1]; p += 2; break; }\ + if ( p[2] ) { data = (byte)~p[2]; p += 3; rlen += 8; break; }\ + if ( p[3] ) { data = (byte)~p[3]; p += 4; rlen += 16; break; }\ + }\ + rlen += cf_byte_run_length_0[data];\ + }\ + count -= rlen;\ +END + +#endif /* scf_INCLUDED */ |