davidsen@crdos1.crd.ge.com (12/17/90)
Posting-number: Volume 15, Issue 87 Submitted-by: davidsen@crdos1.crd.ge.com Archive-name: g3g4/part02 #!/bin/sh # this is part 2 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file g3sdecod.c continued # CurArch=2 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 sed 's/^X//' << 'SHAR_EOF' >> g3sdecod.c X } X } X else /* 01010... */ X { X if (next_bit ()) /* 010101... */ X { X if (next_bit ()) /* 0101011 */ return (25); X else /* 0101010... */ X { X if (next_bit ()) /* 01010101 */ return (52); X else /* 01010100 */ return (51); X } X } X else /* 010100... */ X { X if (next_bit ()) /* 0101001... */ X { X if (next_bit ()) /* 01010011 */ return (50); X else /* 01010010 */ return (49); X } X else /* 0101000 */ return (24); X } X } X } X else /* 0100... */ X { X if (next_bit ()) /* 01001... */ X { X if (next_bit ()) /* 010011... */ X { X if (next_bit ()) /* 0100111 */ return (18); X else /* 0100110... */ X { X if (next_bit ()) /* 01001101... */ X { X if (next_bit ()) /* 010011011 */ return (1728); X else /* 010011010 */ return (1600); X } X else /* 01001100... */ X { X if (next_bit ()) /* 010011001 */ return (1536); X else /* 010011000 */ return (1472); X } X } X } X else /* 010010... */ X { X if (next_bit ()) /* 0100101... */ X { X if (next_bit ()) /* 01001011 */ return (60); X else /* 01001010 */ return (59); X } X else /* 0100100 */ return (27); X } X } X else /* 01000 */ return (11); X } X } X } X else /* 00... */ X { X if (next_bit ()) /* 001... */ X { X if (next_bit ()) /* 0011... */ X { X if (next_bit ()) /* 00111 */ return (10); X else /* 00110... */ X { X if (next_bit ()) /* 001101... */ X { X if (next_bit ()) /* 0011011... */ X { X if (next_bit ()) /* 00110111 */ return (384); X else /* 00110110 */ return (320); X } X else /* 0011010... */ X { X if (next_bit ()) /* 00110101 */ return (0); X else /* 00110100 */ return (63); X } X } X else /* 001100... */ X { X if (next_bit ()) /* 0011001... */ X { X if (next_bit ()) /* 00110011 */ return (62); X else /* 00110010 */ return (61); X } X else /* 0011000 */ return (28); X } X } X } X else /* 0010... */ X { X if (next_bit ()) /* 00101... */ X { X if (next_bit ()) /* 001011... */ X { X if (next_bit ()) /* 0010111 */ return (21); X else /* 0010110... */ X { X if (next_bit ()) /* 00101101 */ return (44); X else /* 00101100 */ return (43); X } X } X else /* 001010... */ X { X if (next_bit ()) /* 0010101... */ X { X if (next_bit ()) /* 00101011 */ return (42); X else /* 00101010 */ return (41); X } X else /* 0010100... */ X { X if (next_bit ()) /* 00101001 */ return (40); X else /* 00101000 */ return (39); X } X } X } X else /* 00100... */ X { X if (next_bit ()) /* 001001... */ X { X if (next_bit ()) /* 0010011 */ return (26); X else /* 0010010... */ X { X if (next_bit ()) /* 00100101 */ return (54); X else /* 00100100 */ return (53); X } X } X else /* 001000 */ return (12); X } X } X } X else /* 000... */ X { X if (next_bit ()) /* 0001... */ X { X if (next_bit ()) /* 00011... */ X { X if (next_bit ()) /* 000111 */ return (1); X else /* 000110... */ X { X if (next_bit ()) /* 0001101... */ X { X if (next_bit ()) /* 00011011 */ return (32); X else /* 00011010 */ return (31); X } X else /* 0001100 */ return (19); X } X } X else /* 00010... */ X { X if (next_bit ()) /* 000101... */ X { X if (next_bit ()) /* 0001011... */ X { X if (next_bit ()) /* 00010111 */ return (38); X else /* 00010110 */ return (37); X } X else /* 0001010... */ X { X if (next_bit ()) /* 00010101 */ return (36); X else /* 00010100 */ return (35); X } X } X else /* 000100... */ X { X if (next_bit ()) /* 0001001... */ X { X if (next_bit ()) /* 00010011 */ return (34); X else /* 00010010 */ return (33); X } X else /* 0001000 */ return (20); X } X } X } X else /* 0000... */ X { X if (next_bit ()) /* 00001... */ X { X if (next_bit ()) /* 000011 */ return (13); X else /* 000010... */ X { X if (next_bit ()) /* 0000101... */ X { X if (next_bit ()) /* 00001011 */ return (48); X else /* 00001010 */ return (47); X } X else /* 0000100 */ return (23); X } X } X else /* 00000... */ X { X if (next_bit ()) /* 000001... */ X { X if (next_bit ()) /* 0000011 */ return (22); X else /* 0000010... */ X { X if (next_bit ()) /* 00000101 */ return (46); X else /* 00000100 */ return (45); X } X } X else /* 000000... */ X { X if (next_bit ()) /* 0000001... */ X { X if (next_bit ()) /* 00000011 */ return (30); X else /* 00000010 */ return (29); X } X else /* 0000 000... */ X { X if (next_bit ()) /* 0000 0001... */ X { X if (next_bit ()) /* 0000 0001 1... */ X { X if (next_bit ()) /* 0000 0001 11... */ X { X if (next_bit ()) /* 0000 0001 111... */ X { X if (next_bit ()) /* 0000 0001 1111 */ return (2560); X else /* 0000 0001 1110 */ return (2496); X } X else /* 0000 0001 110... */ X { X if (next_bit ()) /* 0000 0001 1101 */ return (2432); X else /* 0000 0001 1100 */ return (2368); X } X } X else /* 0000 0001 10... */ X { X if (next_bit ()) /* 0000 0001 101 */ return (1920); X else /* 0000 0001 100 */ return (1856); X } X } X else /* 0000 0001 0... */ X { X if (next_bit ()) /* 0000 0001 01... */ X { X if (next_bit ()) /* 0000 0001 011... */ X { X if (next_bit ()) /* 0000 0001 0111 */ return (2304); X else /* 0000 0001 0110 */ return (2240); X } X else /* 0000 0001 010... */ X { X if (next_bit ()) /* 0000 0001 0101 */ return (2176); X else /* 0000 0001 0100 */ return (2112); X } X } X else /* 0000 0001 00... */ X { X if (next_bit ()) /* 0000 0001 001... */ X { X if (next_bit ()) /* 0000 0001 0011 */ return (2048); X else /* 0000 0001 0010 */ return (1984); X } X else /* 0000 0001 000 */ return (1792); X } X } X } X else /* 0000 0000... */ X { X if (next_bit ()) /* 0000 0000 1 */ return (INVALID_CODE); X else /* 0000 0000 0... */ X { X if (next_bit ()) /* 0000 0000 01 */ return (INVALID_CODE); X else /* 0000 0000 00... */ X { X if (next_bit ()) /* 0000 0000 001 */ X return (INVALID_CODE); X else /* 0000 0000 000... */ X { X if (next_bit ()) /* 0000 0000 0001 */ return (EOL_CODE); X else /* 0000 0000 0000 */ /* return (INVALID_CODE); */ X /* normally this is an invalid code, but *if* we X assume the file has no errors, then we can X greatly simplify pad stripping with the X following... */ X for (;;) if (next_bit ()) return (EOL_CODE); X } X } X } X } X } X } X } X } X } X } X } X} X X/* end $RCSfile: g3sdecod.c $ */ SHAR_EOF chmod 0644 g3sdecod.c || echo "restore of g3sdecod.c fails" sed 's/^X//' << 'SHAR_EOF' > g3sencod.c && X/* $Id: g3sencod.c 1.2 90/06/09 18:22:52 marking Exp $ X * X NAME X * g3sencod.c -- encode group 3 data using nested if statements X * X TYPE X * C procedures X * X SYNOPSIS X * char g3j_initialize (short image_width, short image_length); X * char g3j_encode_new_row (void); X * char g3j_encode_pad (char pad_type); X * char g3j_encode_black (short); X * char g3j_encode_white (short); X * X DESCRIPTION X * These routines are used to encode group 3 and group 4 images. (The X * encoding of group 4 also requires other routines in a separate file.) X * X RETURNS X * X LEGAL X * Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039, X * Scottsdale, Arizona 85252-8039. All rights reserved. X * X * License is granted by the copyright holder to distribute and use this X * code without payment of royalties or the necessity of notification as X * long as this notice (all the text under "LEGAL") is included. X * X * Reference: $Id: g3sencod.c 1.2 90/06/09 18:22:52 marking Exp $ X * X * This program is offered without any warranty of any kind. It includes X * no warranty of merchantability or fitness for any purpose. Testing and X * suitability for any use are the sole responsibility of the user. X * X HISTORY X * $Log: g3sencod.c $ X * Revision 1.2 90/06/09 18:22:52 marking X * clean up comments for release X * X * Revision 1.1 89/06/30 17:00:00 marking X * Initial revision X * X * X NOTES X * 1. Encode a pad to the next byte to flush the output buffer. X * X PORTABILITY X * Tested using Microsoft C 5.1. Some memory models may not work due to X * the large encoding arrays. X * X * There is a non-portable use of "global" variables in the file g3g4.h, X * about which a minority of compilers will justifiably complain. Certain X * variables are declared in g3g4.h without extern keywords. Strictly X * speaking, they should be declared extern in all but one module, but X * that would require complication of g3g4.h. If it gets past your X * compiler and linker, you can probably ignore it. X * X SEE ALSO X * g4sencod.c -- encode group 4 image using nested if statements X * X INFORMATION X * Although there is no support offered with this program, the author will X * endeavor to correct errors. Updates will also be made available from X * time to time. X * X * Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona X * 85252-8039 USA. Replies are not guaranteed to be swift. Beginning X * July 1990, e-mail may be sent to uunet!ipel!marking. X * X * Also beginning in July 1990, this code will be archived at the X * ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number X * for 300/1200/2400 is (602)274-0462. When logging in, specify user X * "public", system "bbs", and password "public". X * X * This code is also available from the C Users Group in volume 317. X * X */ X X#include "g3g4.h" X Xstatic short EOL_code = 0x0010, EOL_length = 12; X Xstatic short encode_black_code (short); Xstatic short encode_white_code (short); X Xchar g3j_initialize (short image_width, short image_length) X{ X initialize_encode (); X return (0); X} X Xchar g3j_encode_new_row (void) X{ X encode_word (EOL_code, EOL_length); X return (0); X} X Xchar g3j_encode_pad (char pad_type) X{ X short bits_to_pad; X switch (pad_type) X { X case PAD_NONE: X break; X case PAD_BYTE: X if (encode_position) /* if not already on a byte boundary */ X encode_word (0, 8 - encode_position); X break; X case PAD_NIBBLE: X bits_to_pad = (8 - encode_position) & 3; X if (bits_to_pad) encode_word (0, bits_to_pad); X break; X case PAD_ODD_NIBBLE: X if (encode_position > 0 && encode_position < 4) X { X bits_to_pad = 4 - encode_position; X encode_word (0, bits_to_pad); X } X else if (encode_position > 4) X { X bits_to_pad = 12 - encode_position; X encode_word (0, bits_to_pad); X } X break; X default: X break; X } X return (0); X} X Xchar g3j_encode_black (short runlength) X{ X runlength = encode_black_code (runlength); X while (runlength) runlength = encode_black_code (runlength); X return (0); X} X Xstatic short encode_black_code (short runlength) X{ X static short term_codes [64] = X { X 0x0DC0, 0x4000, 0xC000, 0x8000, 0x6000, 0x3000, X 0x2000, 0x1800, 0x1400, 0x1000, 0x0800, 0x0A00, X 0x0E00, 0x0400, 0x0700, 0x0C00, 0x05C0, 0x0600, X 0x0200, 0x0CE0, 0x0D00, 0x0D80, 0x06E0, 0x0500, X 0x02E0, 0x0300, 0x0CA0, 0x0CB0, 0x0CC0, 0x0CD0, X 0x0680, 0x0690, 0x06A0, 0x06B0, 0x0D20, 0x0D30, X 0x0D40, 0x0D50, 0x0D60, 0x0D70, 0x06C0, 0x06D0, X 0x0DA0, 0x0DB0, 0x0540, 0x0550, 0x0560, 0x0570, X 0x0640, 0x0650, 0x0520, 0x0530, 0x0240, 0x0370, X 0x0380, 0x0270, 0x0280, 0x0580, 0x0590, 0x02B0, X 0x02C0, 0x05A0, 0x0660, 0x0670 X }; X static short makeup_codes [40] = X { X 0x03C0, 0x0C80, 0x0C90, 0x05B0, 0x0330, 0x0340, X 0x0350, 0x0360, 0x0368, 0x0250, 0x0258, 0x0260, X 0x0268, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, X 0x03B8, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02D0, X 0x02D8, 0x0320, 0x0328, 0x0100, 0x0180, 0x01A0, X 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, X 0x01C0, 0x01D0, 0x01E0, 0x01F0 X }; X static short term_lengths [64] = X { X 10, 3, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, X 10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, X 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, X 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 X }; X static short makeup_lengths [40] = X { X 10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, X 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11, 11, 12, 12, 12, 12, 12, 12, X 12, 12, 12, 12 X }; X short remaining; X if (runlength < 64) X { X encode_word (term_codes [runlength], term_lengths [runlength]); X return (0); X } X else if (runlength < 2561) X { X short x; X x = (runlength - 64) / 64; X encode_word (makeup_codes [x], makeup_lengths [x]); X remaining = runlength - (64 * (1 + x)); X if (!remaining) encode_word (term_codes [0], term_lengths [0]); X return (remaining); X } X else X { X encode_word (makeup_codes [39], makeup_lengths [39]); X return (runlength - 2560); X } X} X Xchar g3j_encode_white (short runlength) X{ X runlength = encode_white_code (runlength); X while (runlength) runlength = encode_white_code (runlength); X return (0); X} X Xstatic short encode_white_code (short runlength) X{ X static short term_codes [64] = X { X 0x3500, 0x1c00, 0x7000, 0x8000, 0xb000, 0xc000, X 0xe000, 0xf000, 0x9800, 0xa000, 0x3800, 0x4000, X 0x2000, 0x0c00, 0xd000, 0xd400, 0xa800, 0xac00, X 0x4e00, 0x1800, 0x1000, 0x2e00, 0x0600, 0x0800, X 0x5000, 0x5600, 0x2600, 0x4800, 0x3000, 0x0200, X 0x0300, 0x1a00, 0x1b00, 0x1200, 0x1300, 0x1400, X 0x1500, 0x1600, 0x1700, 0x2800, 0x2900, 0x2a00, X 0x2b00, 0x2c00, 0x2d00, 0x0400, 0x0500, 0x0a00, X 0x0b00, 0x5200, 0x5300, 0x5400, 0x5500, 0x2400, X 0x2500, 0x5800, 0x5900, 0x5a00, 0x5b00, 0x4a00, X 0x4b00, 0x3200, 0x3300, 0x3400 X }; X static short makeup_codes [40] = X { X 0xd800, 0x9000, 0x5c00, 0x6e00, 0x3600, 0x3700, X 0x6400, 0x6500, 0x6800, 0x6700, 0x6600, 0x6680, X 0x6900, 0x6980, 0x6a00, 0x6a80, 0x6b00, 0x6b80, X 0x6c00, 0x6c80, 0x6d00, 0x6d80, 0x4c00, 0x4c80, X 0x4d00, 0x6000, 0x4d80, 0x0100, 0x0180, 0x01a0, X 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, X 0x01c0, 0x01d0, 0x01e0, 0x01f0 X }; X static short term_lengths [64] = X { X 8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, X 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 X }; X static short makeup_lengths [40] = X { X 5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, X 9, 6, 9, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 X }; X short remaining; X if (runlength < 64) X { X encode_word (term_codes [runlength], term_lengths [runlength]); X return (0); X } X else if (runlength < 2561) X { X short x; X x = (runlength - 64) / 64; X encode_word (makeup_codes [x], makeup_lengths [x]); X remaining = runlength - (64 * (1 + x)); X if (!remaining) encode_word (term_codes [0], term_lengths [0]); X return (remaining); X } X else X { X encode_word (makeup_codes [39], makeup_lengths [39]); X return (runlength - 2560); X } X} X X/* end $RCSfile: g3sencod.c $ */ SHAR_EOF chmod 0644 g3sencod.c || echo "restore of g3sencod.c fails" sed 's/^X//' << 'SHAR_EOF' > g3tdecod.c && X/* $Id: g3tdecod.c 1.2 90/06/09 18:23:04 marking Exp $ X * X NAME X * g3tdecod.c -- decode group 3 data using tables X * X TYPE X * C procedures X * X SYNOPSIS X * char g3i_initialize (short image_width, short image_length); X * char g3i_decode (void); -- for standard group 3 X * char g3i_decode_T (void); -- for TIFF g3 with no EOL chars X * X DESCRIPTION X * In order to acquire data from the image and to return run lengths and X * new line information, these routines invoke procedures provided by the X * caller. These caller-provided procedures are invoked throught pointers X * which have been stuffed by the caller with the procedure addresses. X * To acquire a new data byte, g3i_decode () and g3i_decode_T () call X * (*p_decode_next_byte) (). To report the decoding of a black or white X * run, the routines (*p_decode_black) () or (*p_decode_white) () are X * called. X * X RETURNS X * Initialization always returns zero. X * X * For decoding, X * 0 end of image reached X * -1 on error (bad data) X * The decode loop will be prematurely terminated if decode_return is X * set to not zero, and the value of decode_return will be returned. X * No code here does this, but it might be useful under certain X * circumstances. X * X LEGAL X * Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039, X * Scottsdale, Arizona 85252-8039. All rights reserved. X * X * License is granted by the copyright holder to distribute and use this X * code without payment of royalties or the necessity of notification as X * long as this notice (all the text under "LEGAL") is included. X * X * Reference: $Id: g3tdecod.c 1.2 90/06/09 18:23:04 marking Exp $ X * X * This program is offered without any warranty of any kind. It includes X * no warranty of merchantability or fitness for any purpose. Testing and X * suitability for any use are the sole responsibility of the user. X * X HISTORY X * $Log: g3tdecod.c $ X * Revision 1.2 90/06/09 18:23:04 marking X * clean up comments for release X * X * Revision 1.1 89/06/30 17:00:00 marking X * Initial revision X * X * X NOTES X * X PORTABILITY X * Tested using Microsoft C 5.1. Some memory models may not work due to X * the large decoding arrays. X * X * There is a non-portable use of "global" variables in the file g3g4.h, X * about which a minority of compilers will justifiably complain. Certain X * variables are declared in g3g4.h without extern keywords. Strictly X * speaking, they should be declared extern in all but one module, but X * that would require complication of g3g4.h. If it gets past your X * compiler and linker, you can probably ignore it. X * X SEE ALSO X * g4tdecod.c -- decode group 4 image using tables X * builddec.c -- build image decoding tables X * X INFORMATION X * Although there is no support offered with this program, the author will X * endeavor to correct errors. Updates will also be made available from X * time to time. X * X * Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona X * 85252-8039 USA. Replies are not guaranteed to be swift. Beginning X * July 1990, e-mail may be sent to uunet!ipel!marking. X * X * Also beginning in July 1990, this code will be archived at the X * ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number X * for 300/1200/2400 is (602)274-0462. When logging in, specify user X * "public", system "bbs", and password "public". X * X * This code is also available from the C Users Group in volume 317. X */ X X#include "g3g4.h" X X/* #define TRACE 1 */ X#define TRACE_BEGIN 0 X#define TRACE_END 30000 X Xstatic short bit_number, code_byte; Xstatic unsigned char color, current_row, mode, next_state; Xstatic short column_limit, row_limit; Xstatic short row_number = 0, column_number; X Xextern unsigned char huge horiz_mode [] [256]; Xextern unsigned char huge horiz_mode_next_state [] [256]; X Xstatic short new_row (void); Xstatic short decode_white_run (void); Xstatic short decode_black_run (void); X Xstatic char decode_return; X X/* g3i_decode () successively invokes (*p_decode_next_byte) () for each byte of the X encoded image, and calls (*p_decode_white) () or (*p_decode_black) () as X required to return the image contents on a run-by-run basis. */ X Xchar g3i_decode () X{ X short runlength; X while (!decode_return) X { X if (color == WHITE) X { X runlength = decode_white_run (); X if (runlength == -2) return (-1); X else if (runlength == -1) X { X if (new_row ()) return (0); X } X else X { X column_number += runlength; X (*p_decode_white) ((short) runlength); X color = BLACK; X } X } X else X { X runlength = decode_black_run (); X if (runlength == -2) return (-1); X else if (runlength == -1) X { X if (new_row ()) return (0); X } X else X { X column_number += runlength; X (*p_decode_black) ((short) runlength); X color = WHITE; X } X } X } X return (decode_return); X} X X/* special version for TIFF files with no EOL characters */ Xchar g3i_decode_T () X{ X short runlength; X while (!decode_return) X { X if (color == WHITE) X { X runlength = decode_white_run (); X if (runlength == -2) return (-1); X else if (runlength == -1) X { X if (new_row ()) return (0); X } X else X { X column_number += runlength; X (*p_decode_white) ((short) runlength); X color = BLACK; X if (column_number >= column_limit) X { X if (new_row ()) return (0); X bit_number = 0; X } X } X } X else X { X runlength = decode_black_run (); X if (runlength == -2) return (-1); X else if (runlength == -1) X { X if (new_row ()) return (0); X } X else X { X column_number += runlength; X (*p_decode_black) ((short) runlength); X color = WHITE; X if (column_number >= column_limit) X { X if (new_row ()) return (0); X bit_number = 0; X } X } X } X } X return (decode_return); X} X X/* g3i_initialize () is called to set up to decode a new image. All of the X static data (flags, etc) for g3i_decode () are initialized, allowing the X decoding of multiple images as long as g3i_initialize () is X called before each. */ Xchar g3i_initialize (short image_width, short image_length) X{ X color = WHITE; X bit_number= 0; X column_limit = image_width; X row_limit = image_length; X row_number = 0; X column_number = 0; X decode_return = 0; X return (0); X} X Xstatic short new_row () X{ X if (column_number) X { X (*p_decode_new_row) (); X color = WHITE; X if (++row_number >= row_limit) return (-1); X column_number = 0; X return (0); X } X else return (0); X} X Xstatic short run_length_table [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, X 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, X 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, X 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 128, 192, 256, 320, X 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024, 1088, 1152, 1216, X 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984, X 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560}; X Xstatic short decode_black_run () X{ X short runlength, accum_runlength = 0; X next_state = (unsigned char) (bit_number + 8); X for (;;) /* exit with "return" */ X { X if (!bit_number) code_byte = (*p_decode_next_byte) (); X /* this will fetch a new byte X if the previous codeword ended on a byte boundary */ X mode = horiz_mode [next_state] [code_byte]; X next_state = horiz_mode_next_state [next_state] [code_byte]; X if (mode == 1) return (-2); /* invalid code */ X else if (mode == 210) X { X bit_number = next_state; X return (-1); X } X else if (mode) /* if digestible */ X { X bit_number = next_state; X runlength = run_length_table [mode - 106]; X accum_runlength += runlength; X if (runlength < 64) return (accum_runlength); X next_state += 8; X } X else bit_number = 0; X } X} X Xstatic short decode_white_run () X{ X short runlength, accum_runlength = 0; X next_state = (unsigned char) bit_number; X for (;;) /* exit with "return" */ X { X if (!bit_number) code_byte = (*p_decode_next_byte) (); X /* this will fetch a new byte X if the previous codeword ended on a byte boundary */ X mode = horiz_mode [next_state] [code_byte]; X next_state = horiz_mode_next_state [next_state] [code_byte]; X if (mode == 1) return (-2); /* invalid code */ X else if (mode == 210) X { X bit_number = next_state; X return (-1); X } X else if (mode) /* if digestible */ X { X bit_number = next_state; X runlength = run_length_table [mode - 2]; X accum_runlength += runlength; X if (runlength < 64) return (accum_runlength); X } X else bit_number = 0; X } X} X X/* end $RCSfile: g3tdecod.c $ */ SHAR_EOF chmod 0644 g3tdecod.c || echo "restore of g3tdecod.c fails" sed 's/^X//' << 'SHAR_EOF' > g4sdecod.c && X/* $Id: g4sdecod.c 1.2 90/06/09 18:23:27 marking Exp $ X * X NAME X * g4sdecod.c -- decode group 4 data using nested if statements X * X TYPE X * C procedures X * X SYNOPSIS X * char g4i_initialize (short image_width, short image_length); X * char g4i_decode (void); X * X DESCRIPTION X * In order to acquire data from the image and to return run lengths and X * new line information, these routines invoke procedures provided by the X * caller. These caller-provided procedures are invoked throught pointers X * which have been stuffed by the caller with the procedure addresses. X * To acquire a new data byte, g4i_decode () calls (*p_g4i_next_byte) (). X * To report the decoding of a black or white run, the routines X * (*p_decode_black) () or (*p_decode_white) () are called. X * X RETURNS X * Initialization always returns zero. X * X * For decoding, X * 0 end of image reached X * -1 on error (bad data) X * The decode loop will be prematurely terminated if decode_return is X * set to not zero, and the value of decode_return will be returned. X * No code here does this, but it might be useful under certain X * circumstances. X * X LEGAL X * Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039, X * Scottsdale, Arizona 85252-8039. All rights reserved. X * X * License is granted by the copyright holder to distribute and use this X * code without payment of royalties or the necessity of notification as X * long as this notice (all the text under "LEGAL") is included. X * X * Reference: $Id: g4sdecod.c 1.2 90/06/09 18:23:27 marking Exp $ X * X * This program is offered without any warranty of any kind. It includes X * no warranty of merchantability or fitness for any purpose. Testing and X * suitability for any use are the sole responsibility of the user. X * X HISTORY X * $Log: g4sdecod.c $ X * Revision 1.2 90/06/09 18:23:27 marking X * clean up comments for release X * X * Revision 1.1 90/05/01 02:00:00 marking X * Initial revision X * X * X NOTES X * X PORTABILITY X * Tested using Microsoft C 5.1. Some memory models may not work due to X * the large decoding arrays. X * X * There is a non-portable use of "global" variables in the file g3g4.h, X * about which a minority of compilers will justifiably complain. Certain X * variables are declared in g3g4.h without extern keywords. Strictly X * speaking, they should be declared extern in all but one module, but X * that would require complication of g3g4.h. If it gets past your X * compiler and linker, you can probably ignore it. X * X SEE ALSO X * g3tdecod.c -- decode group 3 image using tables X * builddec.c -- build image decoding tables X * X INFORMATION X * Although there is no support offered with this program, the author will X * endeavor to correct errors. Updates will also be made available from X * time to time. X * X * Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona X * 85252-8039 USA. Replies are not guaranteed to be swift. Beginning X * July 1990, e-mail may be sent to uunet!ipel!marking. X * X * Also beginning in July 1990, this code will be archived at the X * ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number X * for 300/1200/2400 is (602)274-0462. When logging in, specify user X * "public", system "bbs", and password "public". X * X * This code is also available from the C Users Group in volume 317. X */ X X#include "g3g4.h" X X/* #define TRACE 1 */ X X/* implementation limits: Due to the sizes of arrays and variables, and not X due to any restrictions in the algorithm, the following limits exist: X maximum number of pixels per row: 65533 X maximum number of rows per image: none X maximum or minimum k-factor: none X maximum number of runs per row: 16382 white, 16382 black X To increase (or decrease) these limits, it will be necessary to play with X array and variable sizes. On segmented machines (such as the 8086), a X different memory model may be necessary. The algorithm itself has no X limits on image size or complexity, and the stack requirements are in- X sensitive to changes in these limits or to image complexity. */ X X#define EVEN 0 X#define ODD 1 X Xstatic short a0, a1, a2, b0, b1, b2, bit_number, code_byte; Xstatic unsigned char color, current_row, mode; Xstatic unsigned short even_runs [32768], odd_runs [32768]; Xstatic unsigned short even_index, odd_index; Xstatic short column_limit; Xstatic short row_number = 0; X /* Depending as current_row == EVEN or current_row == ODD, the runs of the X current row are represented in even_runs [] or odd_runs []. The white X runs have even subscripts and the black runs have odd subscripts. The X values of the array elements are the offsets of the beginnings of the X corresponding runs from the beginning of the row. As defined by the X specification, X a0 is the reference or starting changing element on the coding line. X It may be considered the "current position". X a1 is the next changing element to the right of a0 on the coding line. X a2 is the next changing element to the right of a1 on the coding line. X b1 is the first changing element on the reference line to the right of X a0 and of opposite color to a0. X b2 is the next changing element to the right of b1 on the reference X line. X Furthermore, X b0 is the "previous" value of b1. X Depending as current_row == EVEN or == ODD, even_index or odd_index is X the subscript of the entry in even_runs [] or odd_runs [] corresponding X to the run containing the current value of a0, and its counterpart cor- X responds to the run containing b1. */ X Xstatic void new_row (void); Xstatic short decode_white_run (void); Xstatic short decode_black_run (void); Xstatic short decode_white_word (void); Xstatic short decode_black_word (void); Xstatic char next_bit (void); Xstatic short null_mode (void); X Xstatic char decode_return; X X/* g4i_decode () successively invokes (*p_decode_next_byte) () for each byte of the X encoded image, and calls (*p_decode_white) () or (*p_decode_black) () as X required to return the image contents on a run-by-run basis. */ Xchar g4i_decode () X{ X /* At the beginning of this routine, we are in the NULL mode, which is to X to say that no codewords are currently understood or digested. The X variable bit_number has been initialized to zero, to indicate that the X next (first) codeword is to begin with bit zero of the next code byte. X This betrays an assumption that all images begin on byte boundaries, a X condition that can be changed by arranging for bit_number to be set X otherwise by g4i_initialize () or elsewhere. */ X while (!decode_return) X { X mode = (unsigned char) null_mode (); X if (current_row == EVEN) X { X b0 = b1; X b1 = odd_runs [odd_index]; X if ((b1 <= a0) && a0) X { X odd_index += 2; X b0 = odd_runs [odd_index - 1]; X b1 = odd_runs [odd_index]; X } X b2 = odd_runs [odd_index + 1]; X } X else /* current_row == ODD */ X { X b0 = b1; X b1 = even_runs [even_index]; X if ((b1 <= a0) && a0) X { X even_index += 2; X b0 = even_runs [even_index - 1]; X b1 = even_runs [even_index]; X } X b2 = even_runs [even_index + 1]; X } X #if defined (TRACE) X if (trace_flag) X { X if (current_row == EVEN) X { X printf ("\n ref_index=%hd b1=%hd b2=%hd a0=%hd curr[%hd]=%hd " X "color=%hd ", X odd_index, b1, b2, a0, even_index, even_runs [even_index], X (short) color); X } X else /* current_row == ODD */ X { X printf ("\n ref_index=%hd b1=%hd b2=%hd a0=%hd curr[%hd]=%hd " X "color=%hd ", X even_index, b1, b2, a0, odd_index, odd_runs [odd_index], X (short) color); X } X } X #endif X switch (mode) X { X case PASS_MODE: /* skip (pass) two color changes on the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" P "); X #endif X if (color == WHITE) (*p_decode_white) ((short) (b2 - a0)); X else /* color == BLACK */ (*p_decode_black) ((short) (b2 - a0)); X a0 = b2; X if (current_row == EVEN) X { X odd_index += 2; X b1 = odd_runs [odd_index]; X } X else /* current_row == ODD */ X { X even_index += 2; X b1 = even_runs [even_index]; X } X break; X case HORIZONTAL_MODE: /* revert to 1-dimensional modified Huffman X encoding for a pair of runs */ X #if defined (TRACE) X if (trace_flag) printf (" H "); X #endif X if (color == WHITE) X { X short black_runlength, white_runlength; X white_runlength = decode_white_run (); X (*p_decode_white) ((short) white_runlength); X a1 = (a0 += white_runlength); X black_runlength = decode_black_run (); X (*p_decode_black) ((short) black_runlength); X a2 = (a0 += black_runlength); X } X else /* color == BLACK */ X { X short black_runlength, white_runlength; X black_runlength = decode_black_run (); X (*p_decode_black) ((short) black_runlength); X a1 = (a0 += black_runlength); X white_runlength = decode_white_run (); X (*p_decode_white) ((short) white_runlength); X a2 = (a0 += white_runlength); X } X if (current_row == EVEN) X { X even_runs [++even_index] = a1; X even_runs [++even_index] = a2; X while (a0 > odd_runs [odd_index]) odd_index += 2; X b1 = odd_runs [odd_index]; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a1; X odd_runs [++odd_index] = a2; X while (a0 > even_runs [even_index]) even_index += 2; X b1 = even_runs [even_index]; X } X break; X case VERTICAL_V0_MODE: /* the next color change begins at the same X location as in the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" V0 "); X #endif X if (color == WHITE) X { X (*p_decode_white) ((short) (b1 - a0)); X color = BLACK; X } X else /* color == BLACK */ X { X (*p_decode_black) ((short) (b1 - a0)); X color = WHITE; X } X a0 = b1; X if (current_row == EVEN) X { X even_runs [++even_index] = a0; X odd_index++; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a0; X even_index++; X } X break; X case VERTICAL_VR1_MODE: /* the next color change begins one pixel to the X right of its location on the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" VR1 "); X #endif X if (color == WHITE) X { X (*p_decode_white) ((short) (b1 - a0 + 1)); X color = BLACK; X } X else /* color == BLACK */ X { X (*p_decode_black) ((short) (b1 - a0 + 1)); X color = WHITE; X } X a0 = b1 + 1; X if (current_row == EVEN) X { X even_runs [++even_index] = a0; X odd_index++; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a0; X even_index++; X } X break; X case VERTICAL_VR2_MODE: /* the next color change begins two pixels to X the right of its location on the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" VR2 "); X #endif X if (color == WHITE) X { X (*p_decode_white) ((short) (b1 - a0 + 2)); X color = BLACK; X } X else /* color == BLACK */ X { X (*p_decode_black) ((short) (b1 - a0 + 2)); X color = WHITE; X } X a0 = b1 + 2; X if (current_row == EVEN) X { X even_runs [++even_index] = a0; X odd_index++; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a0; X even_index++; X } X break; X case VERTICAL_VR3_MODE: /* the next color change begins three pixels to X the right of its location on the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" VR3 "); X #endif X if (color == WHITE) X { X (*p_decode_white) ((short) (b1 - a0 + 3)); X color = BLACK; X } X else /* color == BLACK */ X { X (*p_decode_black) ((short) (b1 - a0 + 3)); X color = WHITE; X } X a0 = b1 + 3; X if (current_row == EVEN) X { X even_runs [++even_index] = a0; X odd_index++; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a0; X even_index++; X } X break; X case VERTICAL_VL1_MODE: /* the next color change begins one pixel to the X left of its location on the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" VL1 "); X #endif X if (color == WHITE) X { X (*p_decode_white) ((short) (b1 - a0 - 1)); X color = BLACK; X } X else /* color == BLACK */ X { X (*p_decode_black) ((short) (b1 - a0 - 1)); X color = WHITE; X } X a0 = b1 - 1; X if (current_row == EVEN) X { X even_runs [++even_index] = a0; X odd_index++; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a0; X even_index++; X } X break; X case VERTICAL_VL2_MODE: /* the next color change begins two pixels to X the left of its location on the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" VL2 "); X #endif X if (color == WHITE) X { X (*p_decode_white) ((short) (b1 - a0 - 2)); X color = BLACK; X } X else /* color == BLACK */ X { X (*p_decode_black) ((short) (b1 - a0 - 2)); X color = WHITE; X } X a0 = b1 - 2; X if (current_row == EVEN) X { X even_runs [++even_index] = a0; X if (a0 < b0) odd_index--; X else odd_index++; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a0; X if (a0 < b0) even_index--; X else even_index++; X } X break; X case VERTICAL_VL3_MODE: /* the next color change begins three pixels to X the left of its location on the previous row */ X #if defined (TRACE) X if (trace_flag) printf (" VL3 "); X #endif X if (color == WHITE) X { X (*p_decode_white) ((short) (b1 - a0 - 3)); X color = BLACK; X } X else /* color == BLACK */ X { X (*p_decode_black) ((short) (b1 - a0 - 3)); X color = WHITE; X } X a0 = b1 - 3; X if (current_row == EVEN) X { X even_runs [++even_index] = a0; X if (a0 < b0) odd_index--; X else odd_index++; X } X else /* current_row == ODD */ X { X odd_runs [++odd_index] = a0; X if (a0 < b0) even_index--; X else even_index++; X } X break; X case EXT_MODE_UNCOMPRESSED: /* enter extension type 7 ("111"), an X uncompressed encoding scheme */ X return (ERROR_UNSUPPORTED_EXTENSION); X break; X case ERROR_MODE: /* The bit pattern found corresponds to an unknown or X invalid codeword. This MAY be one of the seven possible extensions X not defined by the specification. */ X return (ERROR_INVALID_CODEWORD); X break; X case ERROR_MODE_1: /* assumed in this implementation to be equivalent X to EOFB (end-of-facsimile-block) */ X return (RETURN_OK); X break; X default: /* we should never get here; if we do, the tables are bad */ X return (ERROR_PROGRAM_LOGIC); X break; X } X if (a0 >= column_limit) new_row (); X } X return (decode_return); X} X X/* g4i_initialize () is called to set up to decode a new image. All of the X static data (flags, etc) for g4i_decode () are initialized, allowing the X decoding of multiple images in a run as long as g4i_initialize () is X called before each one. */ Xchar g4i_initialize (short image_width, short image_length) X{ X color = WHITE; X bit_number= 0; X current_row = ODD; X even_runs [0] = 0; X even_runs [1] = image_width; /* initial b1 */ X even_runs [2] = image_width; /* initial b2 */ X odd_runs [0] = 0; X a0 = 0; X even_index = 1; odd_index = 0; X column_limit = image_width; X row_number = 0; X b1 = -1; X decode_return = 0; X return (0); X} X Xstatic short null_mode () X{ X if (next_bit ()) /* 1 */ return (VERTICAL_V0_MODE); X else /* 0... */ X { X if (next_bit ()) /* 01... */ X { X if (next_bit ()) /* 011 */ return (VERTICAL_VR1_MODE); X else /* 010 */ return (VERTICAL_VL1_MODE); X } X else /* 00... */ X { X if (next_bit ()) /* 001 */ return (HORIZONTAL_MODE); X else /* 000... */ X { X if (next_bit ()) /* 0001 */ return (PASS_MODE); X else /* 0000... */ X { X if (next_bit ()) /* 0000 1... */ X { X if (next_bit ()) /* 0000 11 */ return (VERTICAL_VR2_MODE); X else /* 0000 10 */ return (VERTICAL_VL2_MODE); X } X else /* 0000 0... */ X { X if (next_bit ()) /* 0000 01... */ X { X if (next_bit ()) /* 0000 011 */ return (VERTICAL_VR3_MODE); X else /* 0000 010 */ return (VERTICAL_VL3_MODE); X } X else /* 0000 00... */ X { X if (next_bit ()) /* 0000 001... */ X { X if (next_bit ()) /* 0000 0011... */ X { X if (next_bit ()) /* 0000 0011 1... */ X { X if (next_bit ()) /* 0000 0011 11 */ X return (EXT_MODE_UNCOMPRESSED); X else /* 0000 0011 10 */ return (ERROR_MODE); X } X else /* 0000 0011 0 */ return (ERROR_MODE); X } X else /* 0000 0010 */ return (ERROR_MODE); X } X else /* 0000 000 */ return (ERROR_MODE_1); X /* under the assumption that there are no errors in the file, X then this bit string can only be the beginning of an X EOFB (end-of-facsimile-block) code */ X } X } X } X } X } X } X return (-1); X} X Xstatic void new_row () X{ X (*p_decode_new_row) (); X color = WHITE; X if (current_row == ODD) X { X current_row = EVEN; X odd_runs [++odd_index] = a0; X odd_runs [++odd_index] = a0; X odd_index = 1; X even_index = 0; X } X else /* current_row == EVEN */ X { X current_row = ODD; X even_runs [++even_index] = a0; X even_runs [++even_index] = a0; X even_index = 1; X odd_index = 0; X } X a0 = 0; X b1 = -1; X #if defined (TRACE) X row_number++; X #endif X} X Xstatic char next_bit (void) X{ X char value; X static unsigned char decode_mask [8] = X { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; X if (!bit_number) code_byte = (*p_decode_next_byte) (); X if ((unsigned char) code_byte & decode_mask [bit_number]) value = 1; X else value = 0; X if (++bit_number > 7) bit_number = 0; X return (value); X} X X/* X * return the length of the next run, assumed to be black X */ X Xstatic short decode_black_run () X{ X short cumulative = 0, code_value; X for (;;) X { X code_value = decode_black_word (); X cumulative += code_value; X if (code_value < 0) return (code_value); X if (code_value < 64) return (cumulative); X } X} X Xstatic short decode_black_word () X{ X if (next_bit ()) /* 1... */ X { X if (next_bit ()) /* 11 */ return (2); X else /* 10 */ return (3); X } X else /* 0... */ X { X if (next_bit ()) /* 01... */ X { X if (next_bit ()) /* 011 */ return (4); X else /* 010 */ return (1); X } X else /* 00... */ X { X if (next_bit ()) /* 001... */ X { X if (next_bit ()) /* 0011 */ return (5); X else /* 0010 */ return (6); X } X else /* 000... */ X { X if (next_bit ()) /* 0001... */ X { X if (next_bit ()) /* 0001 1 */ return (7); X else /* 0001 0... */ X { X if (next_bit ()) /* 0001 01 */ return (8); X else /* 0001 00 */ return (9); X } X } X else /* 0000... */ X { X if (next_bit ()) /* 0000 1... */ X { X if (next_bit ()) /* 0000 11... */ X { X if (next_bit ()) /* 0000 111 */ return (12); X else /* 0000 110... */ X { X if (next_bit ()) /* 0000 1101... */ X { X if (next_bit ()) /* 0000 1101 1... */ X { X if (next_bit ()) /* 0000 1101 11 */ return (0); X else /* 0000 1101 10... */ X { X if (next_bit ()) /* 0000 1101 101... */ X { X if (next_bit ()) /* 0000 1101 1011 */ return (43); X else /* 0000 1101 1010 */ return (42); X } X else /* 0000 1101 100 */ return (21); X } X } X else /* 0000 1101 0... */ X { X if (next_bit ()) /* 0000 1101 01... */ X { X if (next_bit ()) /* 0000 1101 011... */ X { X if (next_bit ()) /* 0000 1101 0111 */ return (39); X else /* 0000 1101 0110 */ return (38); X } X else /* 0000 1101 010... */ X { X if (next_bit ()) /* 0000 1101 0101 */ return (37); X else /* 0000 1101 0100 */ return (36); X } X } X else /* 0000 1101 00... */ X { X if (next_bit ()) /* 0000 1101 001... */ X { X if (next_bit ()) /* 0000 1101 0011 */ return (35); X else /* 0000 1101 0010 */ return (34); X } X else /* 0000 1101 000 */ return (20); X } X } X } X else /* 0000 1100... */ X { X if (next_bit ()) /* 0000 1100 1... */ X { X if (next_bit ()) /* 0000 1100 11... */ X { X if (next_bit ()) /* 0000 1100 111 */ return (19); X else /* 0000 1100 110... */ X { X if (next_bit ()) /* 0000 1100 1101 */ return (29); X else /* 0000 1100 1100 */ return (28); X } X } X else /* 0000 1100 10... */ X { X if (next_bit ()) /* 0000 1100 101.. */ X { X if (next_bit ()) /* 0000 1100 1011 */ return (27); X else /* 0000 1100 1010 */ return (26); X } X else /* 0000 1100 100... */ X { X if (next_bit ()) /* 0000 1100 1001 */ return (192); X else /* 0000 1100 1000 */ return (128); X } X } X } X else /* 0000 1100 0 */ return (15); X } X } X } X else /* 0000 10... */ X { X if (next_bit ()) /* 0000 101 */ return (11); X else /* 0000 100 */ return (10); X } X } X else /* 0000 0... */ X { X if (next_bit ()) /* 0000 01... */ X { X if (next_bit ()) /* 0000 011... */ X { X if (next_bit ()) /* 0000 0111 */ return (14); X else /* 0000 0110... */ X { X if (next_bit ()) /* 0000 0110 1... */ X { X if (next_bit ()) /* 0000 0110 11... */ X { X if (next_bit ()) /* 0000 0110 111 */ return (22); X else /* 0000 0110 110... */ X { X if (next_bit ()) /* 0000 0110 1101 */ return (41); X else /* 0000 0110 1100 */ return (40); X } X } X else /* 0000 0110 10... */ X { X if (next_bit ()) /* 0000 0110 101... */ X { X if (next_bit ()) /* 0000 0110 1011 */ return (33); X else /* 0000 0110 1010 */ return (32); X } X else /* 0000 0110 100... */ X { X if (next_bit ()) /* 0000 0110 1001 */ return (31); X else /* 0000 0110 1000 */ return (30); X } X } X } X else /* 0000 0110 0... */ X { X if (next_bit ()) /* 0000 0110 01... */ X { X if (next_bit ()) /* 0000 0110 011... */ X { X if (next_bit ()) /* 0000 0110 0111 */ return (63); X else /* 0000 0110 0110 */ return (62); X } X else /* 0000 0110 010... */ X { X if (next_bit ()) /* 0000 0110 0101 */ return (49); X else /* 0000 0110 0100 */ return (48); X } X } X else /* 0000 0110 00 */ return (17); X } X } X } X else /* 0000 010... */ X { X if (next_bit ()) /* 0000 0101... */ X { X if (next_bit ()) /* 0000 0101 1... */ X { X if (next_bit ()) /* 0000 0101 11 */ return (16); X else /* 0000 0101 10... */ X { X if (next_bit ()) /* 0000 0101 101... */ X { X if (next_bit ()) /* 0000 0101 1011 */ return (256); X else /* 0000 0101 1010 */ return (61); X } X else /* 0000 0101 100... */ X { X if (next_bit ()) /* 0000 0101 1001 */ return (58); X else /* 0000 0101 1000 */ return (57); X } X } X } X else /* 0000 0101 0... */ X { X if (next_bit ()) /* 0000 0101 01... */ X { X if (next_bit ()) /* 0000 0101 011... */ X { X if (next_bit ()) /* 0000 0101 0111 */ return (47); X else /* 0000 0101 0110 */ return (46); X } X else /* 0000 0101 010... */ X { X if (next_bit ()) /* 0000 0101 0101 */ return (45); X else /* 0000 0101 0100 */ return (44); X } X } X else /* 0000 0101 00... */ X { X if (next_bit ()) /* 0000 0101 001... */ X { X if (next_bit ()) /* 0000 0101 0011 */ return (51); X else /* 0000 0101 0010 */ return (50); X } X else /* 0000 0101 000 */ return (23); X } X } X } X else /* 0000 0100 */ return (13); X } X } X else /* 0000 00... */ X { X if (next_bit ()) /* 0000 001... */ X { X if (next_bit ()) /* 0000 0011... */ X { X if (next_bit ()) /* 0000 0011 1... */ X { X if (next_bit ()) /* 0000 0011 11 */ return (64); X else /* 0000 0011 10... */ X { X if (next_bit ()) /* 0000 0011 101... */ X { X if (next_bit ()) /* 0000 0011 1011... */ X { X if (next_bit ()) /* 0000 0011 1011 1 */ return (1216); X else /* 0000 0011 1011 0 */ return (1152); X } X else /* 0000 0011 1010... */ X { X if (next_bit ()) /* 0000 0011 1010 1 */ return (1088); X else /* 0000 0011 1010 0 */ return (1024); X } X } X else /* 0000 0011 100... */ X { X if (next_bit ()) /* 0000 0011 1001... */ X { X if (next_bit ()) /* 0000 0011 1001 1 */ return (960); X else /* 0000 0011 1001 0 */ return (896); X } X else /* 0000 0011 1000 */ return (54); X } X } X } X else /* 0000 0011 0... */ X { X if (next_bit ()) /* 0000 0011 01... */ X { X if (next_bit ()) /* 0000 0011 011... */ X { X if (next_bit ()) /* 0000 0011 0111 */ return (53); X else /* 0000 0011 0110... */ X { X if (next_bit ()) /* 0000 0011 0110 1 */ return (576); X else /* 0000 0011 0110 0 */ return (512); X } X } X else /* 0000 0011 010... */ X { X if (next_bit ()) /* 0000 0011 0101 */ return (448); X else /* 0000 0011 0100 */ return (384); X } X } X else /* 0000 0011 00... */ X { X if (next_bit ()) /* 0000 0011 001... */ X { X if (next_bit ()) /* 0000 0011 0011 */ return (320); X else /* 0000 0011 0010... */ X { X if (next_bit ()) /* 0000 0011 0010 1 */ return (1728); X else /* 0000 0011 0010 0 */ return (1664); X } X } X else /* 0000 0011 000 */ return (25); X } X } X } X else /* 0000 0010... */ X { X if (next_bit ()) /* 0000 0010 1... */ X { X if (next_bit ()) /* 0000 0010 11... */ X { X if (next_bit ()) /* 0000 0010 111 */ return (24); X else /* 0000 0010 110... */ X { X if (next_bit ()) /* 0000 0010 1101... */ X { X if (next_bit ()) /* 0000 0010 1101 1 */ return (1600); X else /* 0000 0010 1101 0 */ return (1536); X } X else /* 0000 0010 1100 */ return (60); X } X } X else /* 0000 0010 10... */ X { X if (next_bit ()) /* 0000 0010 101... */ X { X if (next_bit ()) /* 0000 0010 1011 */ return (59); X else /* 0000 0010 1010... */ X { X if (next_bit ()) /* 0000 0010 1010 1 */ return (1472); X else /* 0000 0010 1010 0 */ return (1408); X } X } X else /* 0000 0010 100... */ X { X if (next_bit ()) /* 0000 0010 1001... */ X { X if (next_bit ()) /* 0000 0010 1001 1 */ return (1344); X else /* 0000 0010 1001 0 */ return (1280); X } X else /* 0000 0010 1000 */ return (56); X } X } X } X else /* 0000 0010 0... */ X { X if (next_bit ()) /* 0000 0010 01... */ X { X if (next_bit ()) /* 0000 0010 011... */ X { X if (next_bit ()) /* 0000 0010 0111 */ return (55); X else /* 0000 0010 0110... */ X { X if (next_bit ()) /* 0000 0010 0110 1 */ return (832); X else /* 0000 0010 0110 0 */ return (768); X } X } X else /* 0000 0010 010... */ X { X if (next_bit ()) /* 0000 0010 0101... */ X { X if (next_bit ()) /* 0000 0010 0101 1 */ return (704); X else /* 0000 0010 0101 0 */ return (640); X } X else /* 0000 0010 0100 */ return (52); X } X } X else /* 0000 0010 00 */ return (18); X } X } X } X else /* 0000 000... */ X { X if (next_bit ()) /* 0000 0001... */ X { X if (next_bit ()) /* 0000 0001 1... */ X { X if (next_bit ()) /* 0000 0001 11... */ X { X if (next_bit ()) /* 0000 0001 111... */ X { X if (next_bit ()) /* 0000 0001 1111 */ return (2560); X else /* 0000 0001 1110 */ return (2496); X } X else /* 0000 0001 110... */ X { X if (next_bit ()) /* 0000 0001 1101 */ return (2432); X else /* 0000 0001 1100 */ return (2368); X } X } X else /* 0000 0001 10... */ X { X if (next_bit ()) /* 0000 0001 101 */ return (1920); X else /* 0000 0001 100 */ return (1856); X } X } X else /* 0000 0001 0... */ X { X if (next_bit ()) /* 0000 0001 01... */ X { X if (next_bit ()) /* 0000 0001 011... */ X { X if (next_bit ()) /* 0000 0001 0111 */ return (2304); X else /* 0000 0001 0110 */ return (2240); X } X else /* 0000 0001 010... */ X { X if (next_bit ()) /* 0000 0001 0101 */ return (2176); X else /* 0000 0001 0100 */ return (2112); X } X } X else /* 0000 0001 00... */ X { X if (next_bit ()) /* 0000 0001 001... */ X { X if (next_bit ()) /* 0000 0001 0011 */ return (2048); X else /* 0000 0001 0010 */ return (1984); X } X else /* 0000 0001 000 */ return (1792); X } X } X } X else /* 0000 0000... */ X { X if (next_bit ()) /* 0000 0000 1 */ return (INVALID_CODE); X else /* 0000 0000 0... */ X { X if (next_bit ()) /* 0000 0000 01 */ return (INVALID_CODE); X else /* 0000 0000 00... */ X { X if (next_bit ()) /* 0000 0000 001 */ X return (INVALID_CODE); X else /* 0000 0000 000... */ X { X if (next_bit ()) /* 0000 0000 0001 */ return (EOL_CODE); X else /* 0000 0000 0000 */ return (INVALID_CODE); X } X } X } X } X } X } X } X } X } X } X } X} X X/* X * return the length of the next run, assumed to be white X */ X Xstatic short decode_white_run () X{ X short cumulative = 0, code_value; X for (;;) X { X code_value = decode_white_word (); X cumulative += code_value; X if (code_value < 0) return (code_value); X if (code_value < 64) return (cumulative); X } X} X Xstatic short decode_white_word () X{ X if (next_bit ()) /* 1... */ X { X if (next_bit ()) /* 11... */ X { X if (next_bit ()) /* 111... */ X { X if (next_bit ()) /* 1111 */ return (7); X else /* 1110 */ return (6); X } X else /* 110... */ X { X if (next_bit ()) /* 1101... */ X { X if (next_bit ()) /* 1101 1 */ return (64); X else /* 1101 0... */ X { X if (next_bit ()) /* 1101 01 */ return (15); X else /* 1101 00 */ return (14); X } X } X else /* 1100 */ return (5); X } X } X else /* 10... */ X { X if (next_bit ()) /* 101... */ X { X if (next_bit ()) /* 1011 */ return (4); X else /* 1010... */ X { X if (next_bit ()) /* 10101... */ X { X if (next_bit ()) /* 101011 */ return (17); X else /* 101010 */ return (16); X } X else /* 10100 */ return (9); X } X } X else /* 100... */ X { X if (next_bit ()) /* 1001... */ X { X if (next_bit ()) /* 10011 */ return (8); X else /* 10010 */ return (128); X } X else /* 1000 */ return (3); X } X } X } X else /* 0... */ X { X if (next_bit ()) /* 01... */ X { X if (next_bit ()) /* 011... */ X { X if (next_bit ()) /* 0111 */ return (2); X else /* 0110... */ X { X if (next_bit ()) /* 01101... */ X { X if (next_bit ()) /* 011011... */ X { X if (next_bit ()) /* 0110111 */ return (256); X else /* 0110110... */ X { X if (next_bit ()) /* 01101101... */ X { X if (next_bit ()) /* 011011011 */ return (1408); X else /* 011011010 */ return (1344); X } X else /* 01101100... */ X { X if (next_bit ()) /* 011011001 */ return (1280); X else /* 011011000 */ return (1216); X } X } X } X else /* 011010... */ X { X if (next_bit ()) /* 0110101... */ X { X if (next_bit ()) /* 01101011... */ X { X if (next_bit ()) /* 011010111 */ return (1152); X else /* 011010110 */ return (1088); X } X else /* 01101010... */ X { X if (next_bit ()) /* 011010101 */ return (1024); X else /* 011010100 */ return (960); X } X } X else /* 0110100... */ X { X if (next_bit ()) /* 01101001... */ X { X if (next_bit ()) /* 011010011 */ return (896); SHAR_EOF echo "End of part 2, continue with part 3" echo "3" > s2_seq_.tmp exit 0