davidsen@crdos1.crd.ge.com (12/17/90)
Posting-number: Volume 15, Issue 86 Submitted-by: davidsen@crdos1.crd.ge.com Archive-name: g3g4/part01 This is a package of Group 3 and Group 4 image utilities submitted to cbip. Since they are all source I'm passing them on to sources.misc. Submitter (add%sciences@ucselx.sdsu.edu) says: This is the first release of the g3g4 utilities. Work in progress to enhance the capabilities of the toolkit includes table encoding of group 3 and group 4 images, and some optimization. #!/bin/sh # shar: Shell Archiver (v1.27) # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # Run the following text with /bin/sh to create: # builddec.c # cg317-0i.001 # g3g4.h # g3sdecod.c # g3sencod.c # g3tdecod.c # g4sdecod.c # g4sencod.c # g4tdecod.c # gnencode.c # read.me # submit.dsk # if test -r s2_seq_.tmp then echo "Must unpack archives in sequence!" next=`cat s2_seq_.tmp`; echo "Please unpack part $next next" exit 1; fi sed 's/^X//' << 'SHAR_EOF' > builddec.c && X/* $Id: builddec.c 1.2 90/06/09 18:25:13 marking Exp $ X * X NAME X * builddec.c -- build decoding tables for group 3 and group 4 images X * X TYPE X * C source for main program and subroutines X * X SYNOPSIS X * builddec X * X DESCRIPTION X * This program builds tables for decoding group 3 and group 4 encoded X * images. The tables are built as the arrays null_mode [] [], X * null_mode_next_state [] [], horiz_mode [] [], and X * horiz_mode_next_state [] []. The output is C source code which must X * be compiled and linked into a decoding program. X * X RETURNS X * zero if no errors detected, nonzero otherwise 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: builddec.c 1.2 90/06/09 18:25:13 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: builddec.c $ X * Revision 1.2 90/06/09 18:25:13 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. Since it is expected that this program will be run X * infrequently, there is no attempt at optimization. X * 2. The tables horiz_mode [] [] and horiz_mode_next_state [] [] X * are used in both group 3 and group 4 decoding. The tables X * null_mode [] [] and null_mode_next_state [] [] are used only X * in decoding group 4. X * 3. On an XT, this can take around 15 minutes. The progress X * messages it displays let you know it's still alive, but X * otherwise can be ignored. X * 4. Most of the documentation for the tables themselves is in X * the decode routines g3tdecod.c and g4tdecod.c. X * X FILES X * Creates the file "tables.c", which is to be compiled and linked into X * the table-driven decoding routine. X * X PORTABILITY X * Tested under Microsoft C 5.1. Should be fairly portable. X * X SEE ALSO X * g3tdecod.c -- decode group 3 image using tables X * g4tdecod.c -- decode group 4 image using tables X * "Decoding Group 3 Images", C Users Journal, June 1990 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/* X * standard headers X */ X X#include <stddef.h> /* common types and macros */ X#include <stdio.h> /* streams and files */ X#include <stdlib.h> /* assorted functions, macros, types */ X X/* X * application X */ X X#include "g3g4.h" /* some #defines */ X X#define INVALID_CODE -1 X#define INCOMPLETE_CODE -2 X#define EOL_CODE -3 X Xunsigned long append_0 (unsigned long); Xunsigned long append_1 (unsigned long); Xshort black_run_length (unsigned long); Xshort search_run_length_table (unsigned long, long *); Xshort white_run_length (unsigned long); X Xunsigned long append_0 (unsigned long prefix) X{ X return (prefix + 0x10000); X} X Xunsigned long append_1 (unsigned long prefix) X{ X unsigned short prefix_length; X static unsigned short prefix_mask [16] = {0x8000, 0x4000, 0x2000, 0x1000, X 0x0800, 0x0400, 0x0200, 0x0100, 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, X 0x0004, 0x0002, 0x0001}; X prefix_length = 0xFF & (unsigned short) (prefix >> 16); X return (prefix + 0x10000 + prefix_mask [prefix_length]); X} X Xshort search_run_length_table (unsigned long prefix, long *p_table) X{ X short table_offset = 0; X long prefix_length, prefix_value; X prefix_length = 0xFF & (prefix >> 16); X prefix_value = 0xFFFF & prefix; X while (p_table [table_offset]) X { X if (p_table [table_offset] == prefix_length X && p_table [table_offset + 1] == prefix_value) X return ((short) p_table [table_offset + 2]); X table_offset += 3; /* move on to next entry */ X } X return (INCOMPLETE_CODE); /* no entry found in table */ X} X Xshort white_run_length (unsigned long prefix) X{ X static long code_table [] = X { X 8, 0x3500, 0, /* 0011 0101 */ X 6, 0x1C00, 1, /* 0001 11 */ X 4, 0x7000, 2, /* 0111 */ X 4, 0x8000, 3, /* 1000 */ X 4, 0xB000, 4, /* 1011 */ X 4, 0xC000, 5, /* 1100 */ X 4, 0xE000, 6, /* 1110 */ X 4, 0xF000, 7, /* 1111 */ X 5, 0x9800, 8, /* 1001 1 */ X 5, 0xA000, 9, /* 1010 0 */ X 5, 0x3800, 10, /* 0011 1 */ X 5, 0x4000, 11, /* 0100 0 */ X 6, 0x2000, 12, /* 0010 00 */ X 6, 0x0C00, 13, /* 0000 11 */ X 6, 0xD000, 14, /* 1101 00 */ X 6, 0xD400, 15, /* 1101 01 */ X 6, 0xA800, 16, /* 1010 10 */ X 6, 0xAC00, 17, /* 1010 11 */ X 7, 0x4E00, 18, /* 0100 111 */ X 7, 0x1800, 19, /* 0001 100 */ X 7, 0x1000, 20, /* 0001 000 */ X 7, 0x2E00, 21, /* 0010 111 */ X 7, 0x0600, 22, /* 0000 011 */ X 7, 0x0800, 23, /* 0000 100 */ X 7, 0x5000, 24, /* 0101 000 */ X 7, 0x5600, 25, /* 0101 011 */ X 7, 0x2600, 26, /* 0010 011 */ X 7, 0x4800, 27, /* 0100 100 */ X 7, 0x3000, 28, /* 0011 000 */ X 8, 0x0200, 29, /* 0000 0010 */ X 8, 0x0300, 30, /* 0000 0011 */ X 8, 0x1A00, 31, /* 0001 1010 */ X 8, 0x1B00, 32, /* 0001 1011 */ X 8, 0x1200, 33, /* 0001 0010 */ X 8, 0x1300, 34, /* 0001 0011 */ X 8, 0x1400, 35, /* 0001 0100 */ X 8, 0x1500, 36, /* 0001 0101 */ X 8, 0x1600, 37, /* 0001 0110 */ X 8, 0x1700, 38, /* 0001 0111 */ X 8, 0x2800, 39, /* 0010 1000 */ X 8, 0x2900, 40, /* 0010 1001 */ X 8, 0x2A00, 41, /* 0010 1010 */ X 8, 0x2B00, 42, /* 0010 1011 */ X 8, 0x2C00, 43, /* 0010 1100 */ X 8, 0x2D00, 44, /* 0010 1101 */ X 8, 0x0400, 45, /* 0000 0100 */ X 8, 0x0500, 46, /* 0000 0101 */ X 8, 0x0A00, 47, /* 0000 1010 */ X 8, 0x0B00, 48, /* 0000 1011 */ X 8, 0x5200, 49, /* 0101 0010 */ X 8, 0x5300, 50, /* 0101 0011 */ X 8, 0x5400, 51, /* 0101 0100 */ X 8, 0x5500, 52, /* 0101 0101 */ X 8, 0x2400, 53, /* 0010 0100 */ X 8, 0x2500, 54, /* 0010 0101 */ X 8, 0x5800, 55, /* 0101 1000 */ X 8, 0x5900, 56, /* 0101 1001 */ X 8, 0x5A00, 57, /* 0101 1010 */ X 8, 0x5B00, 58, /* 0101 1011 */ X 8, 0x4A00, 59, /* 0100 1010 */ X 8, 0x4B00, 60, /* 0100 1011 */ X 8, 0x3200, 61, /* 0011 0010 */ X 8, 0x3300, 62, /* 0011 0011 */ X 8, 0x3400, 63, /* 0011 0100 */ X 5, 0xD800, 64, /* 1101 1 */ X 5, 0x9000, 128, /* 1001 0 */ X 6, 0x5C00, 192, /* 0101 11 */ X 7, 0x6E00, 256, /* 0110 111 */ X 8, 0x3600, 320, /* 0011 0110 */ X 8, 0x3700, 384, /* 0011 0111 */ X 8, 0x6400, 448, /* 0110 0100 */ X 8, 0x6500, 512, /* 0110 0101 */ X 8, 0x6800, 576, /* 0110 1000 */ X 8, 0x6700, 640, /* 0110 0111 */ X 9, 0x6600, 704, /* 0110 0110 0 */ X 9, 0x6680, 768, /* 0110 0110 1 */ X 9, 0x6900, 832, /* 0110 1001 0 */ X 9, 0x6980, 896, /* 0110 1001 1 */ X 9, 0x6A00, 960, /* 0110 1010 0 */ X 9, 0x6A80, 1024, /* 0110 1010 1 */ X 9, 0x6B00, 1088, /* 0110 1011 0 */ X 9, 0x6B80, 1152, /* 0110 1011 1 */ X 9, 0x6C00, 1216, /* 0110 1100 0 */ X 9, 0x6C80, 1280, /* 0110 1100 1 */ X 9, 0x6D00, 1344, /* 0110 1101 0 */ X 9, 0x6D80, 1408, /* 0110 1101 1 */ X 9, 0x4C00, 1472, /* 0100 1100 0 */ X 9, 0x4C80, 1536, /* 0100 1100 1 */ X 9, 0x4D00, 1600, /* 0100 1101 0 */ X 6, 0x6000, 1664, /* 0110 00 */ X 9, 0x4D80, 1728, /* 0100 1101 1 */ X 11, 0x0100, 1792, /* 0000 0001 000 */ X 11, 0x0180, 1856, /* 0000 0001 100 */ X 11, 0x01A0, 1920, /* 0000 0001 101 */ X 12, 0x0120, 1984, /* 0000 0001 0010 */ X 12, 0x0130, 2048, /* 0000 0001 0011 */ X 12, 0x0140, 2112, /* 0000 0001 0100 */ X 12, 0x0150, 2176, /* 0000 0001 0101 */ X 12, 0x0160, 2240, /* 0000 0001 0110 */ X 12, 0x0170, 2304, /* 0000 0001 0111 */ X 12, 0x01C0, 2368, /* 0000 0001 1100 */ X 12, 0x01D0, 2432, /* 0000 0001 1101 */ X 12, 0x01E0, 2496, /* 0000 0001 1110 */ X 12, 0x01F0, 2560, /* 0000 0001 1111 */ X 12, 0x0010, EOL_CODE, /* 0000 0000 0001 */ X 9, 0x0080, INVALID_CODE, /* 0000 0000 1 */ X 10, 0x0040, INVALID_CODE, /* 0000 0000 01 */ X 11, 0x0020, INVALID_CODE, /* 0000 0000 001 */ X 12, 0x0000, INVALID_CODE, /* 0000 0000 0000 */ X 0 /* end-of-table */ X }; X return (search_run_length_table (prefix, code_table)); X} X Xshort black_run_length (unsigned long prefix) X{ X static long code_table [] = X { X 10, 0x0DC0, 0, /* 0000 1101 11 */ X 3, 0x4000, 1, /* 010 */ X 2, 0xC000, 2, /* 11 */ X 2, 0x8000, 3, /* 10 */ X 3, 0x6000, 4, /* 011 */ X 4, 0x3000, 5, /* 0011 */ X 4, 0x2000, 6, /* 0010 */ X 5, 0x1800, 7, /* 0001 1 */ X 6, 0x1400, 8, /* 0001 01 */ X 6, 0x1000, 9, /* 0001 00 */ X 7, 0x0800, 10, /* 0000 100 */ X 7, 0x0A00, 11, /* 0000 101 */ X 7, 0x0E00, 12, /* 0000 111 */ X 8, 0x0400, 13, /* 0000 0100 */ X 8, 0x0700, 14, /* 0000 0111 */ X 9, 0x0C00, 15, /* 0000 1100 0 */ X 10, 0x05C0, 16, /* 0000 0101 11 */ X 10, 0x0600, 17, /* 0000 0110 00 */ X 10, 0x0200, 18, /* 0000 0010 00 */ X 11, 0x0CE0, 19, /* 0000 1100 111 */ X 11, 0x0D00, 20, /* 0000 1101 000 */ X 11, 0x0D80, 21, /* 0000 1101 100 */ X 11, 0x06E0, 22, /* 0000 0110 111 */ X 11, 0x0500, 23, /* 0000 0101 000 */ X 11, 0x02E0, 24, /* 0000 0010 111 */ X 11, 0x0300, 25, /* 0000 0011 000 */ X 12, 0x0CA0, 26, /* 0000 1100 1010 */ X 12, 0x0CB0, 27, /* 0000 1100 1011 */ X 12, 0x0CC0, 28, /* 0000 1100 1100 */ X 12, 0x0CD0, 29, /* 0000 1100 1101 */ X 12, 0x0680, 30, /* 0000 0110 1000 */ X 12, 0x0690, 31, /* 0000 0110 1001 */ X 12, 0x06A0, 32, /* 0000 0110 1010 */ X 12, 0x06B0, 33, /* 0000 0110 1011 */ X 12, 0x0D20, 34, /* 0000 1101 0010 */ X 12, 0x0D30, 35, /* 0000 1101 0011 */ X 12, 0x0D40, 36, /* 0000 1101 0100 */ X 12, 0x0D50, 37, /* 0000 1101 0101 */ X 12, 0x0D60, 38, /* 0000 1101 0110 */ X 12, 0x0D70, 39, /* 0000 1101 0111 */ X 12, 0x06C0, 40, /* 0000 0110 1100 */ X 12, 0x06D0, 41, /* 0000 0110 1101 */ X 12, 0x0DA0, 42, /* 0000 1101 1010 */ X 12, 0x0DB0, 43, /* 0000 1101 1011 */ X 12, 0x0540, 44, /* 0000 0101 0100 */ X 12, 0x0550, 45, /* 0000 0101 0101 */ X 12, 0x0560, 46, /* 0000 0101 0110 */ X 12, 0x0570, 47, /* 0000 0101 0111 */ X 12, 0x0640, 48, /* 0000 0110 0100 */ X 12, 0x0650, 49, /* 0000 0110 0101 */ X 12, 0x0520, 50, /* 0000 0101 0010 */ X 12, 0x0530, 51, /* 0000 0101 0011 */ X 12, 0x0240, 52, /* 0000 0010 0100 */ X 12, 0x0370, 53, /* 0000 0011 0111 */ X 12, 0x0380, 54, /* 0000 0011 1000 */ X 12, 0x0270, 55, /* 0000 0010 0111 */ X 12, 0x0280, 56, /* 0000 0010 1000 */ X 12, 0x0580, 57, /* 0000 0101 1000 */ X 12, 0x0590, 58, /* 0000 0101 1001 */ X 12, 0x02B0, 59, /* 0000 0010 1011 */ X 12, 0x02C0, 60, /* 0000 0010 1100 */ X 12, 0x05A0, 61, /* 0000 0101 1010 */ X 12, 0x0660, 62, /* 0000 0110 0110 */ X 12, 0x0670, 63, /* 0000 0110 0111 */ X 10, 0x03C0, 64, /* 0000 0011 11 */ X 12, 0x0C80, 128, /* 0000 1100 1000 */ X 12, 0x0C90, 192, /* 0000 1100 1001 */ X 12, 0x05B0, 256, /* 0000 0101 1011 */ X 12, 0x0330, 320, /* 0000 0011 0011 */ X 12, 0x0340, 384, /* 0000 0011 0100 */ X 12, 0x0350, 448, /* 0000 0011 0101 */ X 13, 0x0360, 512, /* 0000 0011 0110 0 */ X 13, 0x0368, 576, /* 0000 0011 0110 1 */ X 13, 0x0250, 640, /* 0000 0010 0101 0 */ X 13, 0x0258, 704, /* 0000 0010 0101 1 */ X 13, 0x0260, 768, /* 0000 0010 0110 0 */ X 13, 0x0268, 832, /* 0000 0010 0110 1 */ X 13, 0x0390, 896, /* 0000 0011 1001 0 */ X 13, 0x0398, 960, /* 0000 0011 1001 1 */ X 13, 0x03A0, 1024, /* 0000 0011 1010 0 */ X 13, 0x03A8, 1088, /* 0000 0011 1010 1 */ X 13, 0x03B0, 1152, /* 0000 0011 1011 0 */ X 13, 0x03B8, 1216, /* 0000 0011 1011 1 */ X 13, 0x0290, 1280, /* 0000 0010 1001 0 */ X 13, 0x0298, 1344, /* 0000 0010 1001 1 */ X 13, 0x02A0, 1408, /* 0000 0010 1010 0 */ X 13, 0x02A8, 1472, /* 0000 0010 1010 1 */ X 13, 0x02D0, 1536, /* 0000 0010 1101 0 */ X 13, 0x02D8, 1600, /* 0000 0010 1101 1 */ X 13, 0x0320, 1664, /* 0000 0011 0010 0 */ X 13, 0x0328, 1728, /* 0000 0011 0010 1 */ X 11, 0x0100, 1792, /* 0000 0001 000 */ X 11, 0x0180, 1856, /* 0000 0001 100 */ X 11, 0x01A0, 1920, /* 0000 0001 101 */ X 12, 0x0120, 1984, /* 0000 0001 0010 */ X 12, 0x0130, 2048, /* 0000 0001 0011 */ X 12, 0x0140, 2112, /* 0000 0001 0100 */ X 12, 0x0150, 2176, /* 0000 0001 0101 */ X 12, 0x0160, 2240, /* 0000 0001 0110 */ X 12, 0x0170, 2304, /* 0000 0001 0111 */ X 12, 0x01C0, 2368, /* 0000 0001 1100 */ X 12, 0x01D0, 2432, /* 0000 0001 1101 */ X 12, 0x01E0, 2496, /* 0000 0001 1110 */ X 12, 0x01F0, 2560, /* 0000 0001 1111 */ X 12, 0x0010, EOL_CODE, /* 0000 0000 0001 */ X 9, 0x0080, INVALID_CODE, /* 0000 0000 1 */ X 10, 0x0040, INVALID_CODE, /* 0000 0000 01 */ X 11, 0x0020, INVALID_CODE, /* 0000 0000 001 */ X 12, 0x0000, INVALID_CODE, /* 0000 0000 0000 */ X 0 /* end-of-table */ X }; X return (search_run_length_table (prefix, code_table)); X} X X#define NULL_MODE_PREFIX_LIMIT 200 /* maximum number of null-mode prefixes */ X#define HORIZ_MODE_PREFIX_LIMIT 250 /* maximum number of indigestible X 1-dimensional prefixes */ X Xlong null_mode_prefix [NULL_MODE_PREFIX_LIMIT]; X /* the bit string corresponding to this row of the decoding table */ Xunsigned char null_mode [NULL_MODE_PREFIX_LIMIT] [256]; X /* one of the entries PASS_MODE, HORIZONTAL_MODE, etc, or zero */ Xunsigned char null_mode_next_state [NULL_MODE_PREFIX_LIMIT] [256]; X /* next row of the decoding tables to be used */ Xshort null_mode_prefix_count = 0; X /* number of prefixes or rows in the G4 decoding tables */ X X/* decoding script values for horiz_mode [] []: X 0 - indigestible code X 1 - invalid code or error X 2..105 - white runs X 106..209 - black runs X 210 - EOL (valid only for Group 3) X 211..255 - (undefined) */ Xunsigned char horiz_mode [HORIZ_MODE_PREFIX_LIMIT] [256]; Xunsigned char horiz_mode_next_state [HORIZ_MODE_PREFIX_LIMIT] [256]; X /* if the corresponding horiz_mode [] [] entry is zero ("indigestible"), X this entry is a row number for decoding the next byte; otherwise, it X is the bit number to continue coding the next codeword */ Xlong horiz_mode_prefix [HORIZ_MODE_PREFIX_LIMIT]; X /* the prefixes corresponding to the rows of the decoding table */ Xchar horiz_mode_color [HORIZ_MODE_PREFIX_LIMIT]; X /* color of next run, BLACK or WHITE */ Xshort horiz_mode_prefix_count = 0; X Xstatic unsigned char bit_mask [8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, X 0x02, 0x01}; X Xvoid build_null_mode_tables (void); Xshort find_horiz_mode_prefix (long, char); Xshort find_null_mode_prefix (long); Xshort null_mode_type (long); Xvoid process_horiz_mode_prefixes (void); Xshort horiz_mode_code_black (short); Xshort horiz_mode_code_invalid (void); Xshort horiz_mode_code_indigestible (void); Xshort horiz_mode_code_EOL (void); Xshort horiz_mode_code_white (short); Xvoid write_tables (void); X Xint main (int arg_count, char **p_args, char **p_env) X{ X printf ("g4build\n"); X /* build the null mode decoding tables */ X build_null_mode_tables (); X printf (" %hd null mode prefixes defined\n", null_mode_prefix_count); X /* build the 1D decoding tables */ X printf (" building 1D scripts...\n"); X process_horiz_mode_prefixes (); X printf (" %hd indigestible prefixes defined\n", horiz_mode_prefix_count); X /* create tables.h */ X write_tables (); X exit (0); X} X Xvoid build_null_mode_tables () X{ X short prefix_number; X /* note: the first eight entries correspond to a null prefix and starting X bit numbers 0, 1, ... 7 */ X null_mode_prefix_count = 8; X for (prefix_number = 0; prefix_number < null_mode_prefix_count; X prefix_number++) X { X short byte_value; X for (byte_value = 0; byte_value < 256; byte_value++) X { X short beginning_bit_number, bit_number, mode; X long working_prefix; X char found_code = 0; X if (prefix_number < 8) X { X working_prefix = 0L; X beginning_bit_number = prefix_number; X } X else X { X working_prefix = null_mode_prefix [prefix_number]; X beginning_bit_number = 0; X } X for (bit_number = beginning_bit_number; bit_number < 8 && !found_code; X bit_number++) X { X if (bit_mask [bit_number] & byte_value) X working_prefix = append_1 (working_prefix); X else working_prefix = append_0 (working_prefix); X mode = null_mode_type (working_prefix); X switch (mode) X { X case PASS_MODE: X case HORIZONTAL_MODE: X case VERTICAL_V0_MODE: X case VERTICAL_VR1_MODE: X case VERTICAL_VR2_MODE: X case VERTICAL_VR3_MODE: X case VERTICAL_VL1_MODE: X case VERTICAL_VL2_MODE: X case VERTICAL_VL3_MODE: X case EXT_MODE_UNCOMPRESSED: X case ERROR_MODE: X case ERROR_MODE_1: X found_code = 1; X null_mode [prefix_number] [byte_value] = (unsigned char) mode; X null_mode_next_state [prefix_number] [byte_value] X = (unsigned char) ((bit_number + 1) & 0x7); X /* note: if the bit number is 8, then X the table entry will be zero, which indicates a new byte X is to be fetched during the decoding process */ X break; X default: X break; X } X } X if (!found_code) X { X null_mode_next_state [prefix_number] [byte_value] X = (unsigned char) find_null_mode_prefix (working_prefix); X null_mode [prefix_number] [byte_value] = 0; /* indicating to the X decoder that no digestible state was found */ X } X } X } X} X Xshort find_null_mode_prefix (long prefix) X{ X short j1; X if (prefix == 0L) return (0); X for (j1 = 8; j1 < null_mode_prefix_count; j1++) X if (prefix == null_mode_prefix [j1]) return (j1); X if (null_mode_prefix_count == NULL_MODE_PREFIX_LIMIT) X { X printf ("ERROR: null mode prefix table overflow\n"); X exit (1); X } X null_mode_prefix [null_mode_prefix_count] = prefix; Xprintf ("adding null mode prefix [%hd] 0x%lx\n", null_mode_prefix_count, Xprefix); X null_mode_prefix_count++; X return (null_mode_prefix_count - 1); X} X Xshort find_horiz_mode_prefix (long prefix, char color) X{ X short j1; X for (j1 = 0; j1 < horiz_mode_prefix_count; j1++) X if (prefix == horiz_mode_prefix [j1] && horiz_mode_color [j1] == color) X return (j1); X /* it wasn't found, so add it to the tables */ X /* but first, is there room? */ X if (horiz_mode_prefix_count == HORIZ_MODE_PREFIX_LIMIT) /* we're full */ X { X printf ("ERROR: 1D prefix table overflow\n"); X exit (1); X } X /* OK, there's room... */ X horiz_mode_prefix [horiz_mode_prefix_count] = prefix; X horiz_mode_color [horiz_mode_prefix_count] = color; X horiz_mode_prefix_count++; Xprintf ("\n horiz mode prefix %hd, color %c = 0x%lx ", X(short) (horiz_mode_prefix_count - 1), "WB" [color], prefix); X return (horiz_mode_prefix_count - 1); X} X Xshort null_mode_type (long prefix) X{ X if (prefix == 0x18000L) return (VERTICAL_V0_MODE); /* 1 */ X if (prefix == 0x36000L) return (VERTICAL_VR1_MODE); /* 011 */ X if (prefix == 0x34000L) return (VERTICAL_VL1_MODE); /* 010 */ X if (prefix == 0x32000L) return (HORIZONTAL_MODE); /* 001 */ X if (prefix == 0x41000L) return (PASS_MODE); /* 0001 */ X if (prefix == 0x60C00L) return (VERTICAL_VR2_MODE); /* 0000 11 */ X if (prefix == 0x60800L) return (VERTICAL_VL2_MODE); /* 0000 10 */ X if (prefix == 0x70600L) return (VERTICAL_VR3_MODE); /* 0000 011 */ X if (prefix == 0x70400L) return (VERTICAL_VL3_MODE); /* 0000 010 */ X if (prefix == 0x80200L) return (ERROR_MODE); /* 0000 0010 */ X if (prefix == 0x90300L) return (ERROR_MODE); /* 0000 0011 0 */ X if (prefix == 0xA0380L) return (ERROR_MODE); /* 0000 0011 10 */ X if (prefix == 0xA03C0L) return (EXT_MODE_UNCOMPRESSED); /* 0000 0011 11 */ X if (prefix == 0x70000L) return (ERROR_MODE_1); /* 0000 000 */ X /* under the assumption that there are no errors in the file, then this X bit string can only be the beginning of an EOFB (end-of-facsimile-block) X code */ X return (-1); X} X Xvoid process_horiz_mode_prefixes () X{ X unsigned short code_byte_value; X short prefix_number; X horiz_mode_prefix_count = 16; /* the first 8 are for white, the second 8 are X for black, beginning with bits 0, 1, ... 7 */ X for (prefix_number = 0; prefix_number < horiz_mode_prefix_count; X prefix_number++) X for (code_byte_value = 0; code_byte_value < 256; code_byte_value++) X { X short bits_digested = 0; X short bit_number, beginning_bit_number; X char working_color; X long working_prefix; X if (prefix_number < 8) X { X working_color = WHITE; X working_prefix = 0L; X beginning_bit_number = prefix_number; X } X else if (prefix_number < 16) X { X working_color = BLACK; X working_prefix = 0L; X beginning_bit_number = prefix_number - 8; X } X else X { X working_color = horiz_mode_color [prefix_number]; X working_prefix = horiz_mode_prefix [prefix_number]; X beginning_bit_number = 0; X } X for (bit_number = beginning_bit_number; bit_number < 8 && !bits_digested; X bit_number++) X { X if (bit_mask [bit_number] & code_byte_value) X working_prefix = append_1 (working_prefix); X else working_prefix = append_0 (working_prefix); X if (working_prefix == 0xC0000L) working_prefix = 0xB0000L; X /* This conversion allows for arbitrary strings of zeroes to precede X the end-of-line code 0000 0000 0001. It assumes no errors in the X data, and is based on the assumption that the code replaced (12 X consecutive zeroes) can only be "legally" encountered before the X end-of-line code. This assumption is valid only for a Group 3 X image; the combination will never occur in horizontal mode in a X proper Group 4 image. */ X if (working_color == WHITE) X { X short runlength; X runlength = white_run_length (working_prefix); X if (runlength == INVALID_CODE) X { X horiz_mode [prefix_number] [code_byte_value] X = (unsigned char) horiz_mode_code_invalid (); X horiz_mode_next_state [prefix_number] [code_byte_value] X = (unsigned char) bit_number; X bits_digested = bit_number + 1; X } X else if (runlength == EOL_CODE) /* Group 3 only */ X { X horiz_mode [prefix_number] [code_byte_value] X = (unsigned char) horiz_mode_code_EOL (); X horiz_mode_next_state [prefix_number] [code_byte_value] X = (unsigned char) ((bit_number + 1) & 0x7); X bits_digested = bit_number + 1; X } X else if (runlength != INCOMPLETE_CODE) X { X horiz_mode [prefix_number] [code_byte_value] X = (unsigned char) horiz_mode_code_white (runlength); X horiz_mode_next_state [prefix_number] [code_byte_value] X = (unsigned char) ((bit_number + 1) & 0x7); X bits_digested = bit_number + 1; X } X /* else incomplete code */ X } X else /* working_color == BLACK */ X { X short runlength; X runlength = black_run_length (working_prefix); X if (runlength == INVALID_CODE) X { X horiz_mode [prefix_number] [code_byte_value] X = (unsigned char) horiz_mode_code_invalid (); X horiz_mode_next_state [prefix_number] [code_byte_value] X = (unsigned char) (bit_number + 8); X bits_digested = bit_number + 1; X } X else if (runlength == EOL_CODE) /* Group 3 only */ X { X horiz_mode [prefix_number] [code_byte_value] X = (unsigned char) horiz_mode_code_EOL (); X horiz_mode_next_state [prefix_number] [code_byte_value] X = (unsigned char) ((bit_number + 1) & 0x7); X bits_digested = bit_number + 1; X } X else if (runlength != INCOMPLETE_CODE) X { X horiz_mode [prefix_number] [code_byte_value] X = (unsigned char) horiz_mode_code_black (runlength); X horiz_mode_next_state [prefix_number] [code_byte_value] X = (unsigned char) ((bit_number + 1) & 0x7); X bits_digested = bit_number + 1; X } X /* else incomplete code */ X } X } X if (!bits_digested) /* if no codewords after examining byte */ X { X horiz_mode [prefix_number] [code_byte_value] X = (unsigned char) horiz_mode_code_indigestible (); X horiz_mode_next_state [prefix_number] [code_byte_value] X = (unsigned char) find_horiz_mode_prefix (working_prefix, X working_color); X } X } X} X Xshort horiz_mode_code_black (short runlength) X{ X /* X 0 106 X 1 107 X ... ... X 63 169 X 64 170 X 128 171 X ... ... X 2560 209 X */ X if (runlength < 64) return (runlength + 106); X else return ((runlength / 64) + 169); X} X Xshort horiz_mode_code_invalid () X{ X return (1); X} X Xshort horiz_mode_code_indigestible () X{ X return (0); X} X Xshort horiz_mode_code_EOL () X{ X return (210); X} X Xshort horiz_mode_code_white (short runlength) X{ X /* X 0 2 X 1 3 X ... ... X 63 65 X 64 66 X 128 67 X ... ... X 2560 105 X */ X if (runlength < 64) return (runlength + 2); X else return ((runlength / 64) + 65); X} X Xvoid write_tables () X{ X FILE *p_table_file; X short j1, j2, j3; X p_table_file = fopen ("tables.c", "w+"); X if (p_table_file == NULL) X { X printf ("can't open \"tables.c\"\n"); X exit (1); X } X /* ---------------------------------------- null_mode [] [] */ X fprintf (p_table_file, X "unsigned char null_mode [%hd] [256] = {\n", X null_mode_prefix_count); X for (j1 = 0; j1 < null_mode_prefix_count; j1++) X { X fprintf (p_table_file, "/* %hd */", j1); X j3 = 1; X fprintf (p_table_file, " { "); X for (j2 = 0; j2 < 256; j2++) X { X fprintf (p_table_file, "%hd", (short) null_mode [j1] [j2]); X if (j3++ == 14) X { X j3 = 0; fprintf (p_table_file, ",\n "); X } X else if (j2 != 255) fprintf (p_table_file, ", "); X } X if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, " }\n"); X else fprintf (p_table_file, " },\n"); X } X fprintf (p_table_file, "};\n"); X /* ---------------------------------------- null_mode_next_state [] [] */ X fprintf (p_table_file, X "unsigned char null_mode_next_state [%hd] [256] = {\n", X null_mode_prefix_count); X for (j1 = 0; j1 < null_mode_prefix_count; j1++) X { X fprintf (p_table_file, "/* %hd */", j1); X j3 = 1; X fprintf (p_table_file, " { "); X for (j2 = 0; j2 < 256; j2++) X { X fprintf (p_table_file, "%hd", (short) null_mode_next_state [j1] [j2]); X if (j3++ == 14) X { X j3 = 0; fprintf (p_table_file, ",\n "); X } X else if (j2 != 255) fprintf (p_table_file, ", "); X } X if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, " }\n"); X else fprintf (p_table_file, " },\n"); X } X fprintf (p_table_file, "};\n"); X /* ---------------------------------------- horiz_mode [] [] */ X fprintf (p_table_file, X "unsigned char horiz_mode [%hd] [256] = {\n", X horiz_mode_prefix_count); X for (j1 = 0; j1 < horiz_mode_prefix_count; j1++) X { X j3 = 1; X fprintf (p_table_file, "/* %hd */", j1); X fprintf (p_table_file, " { "); X for (j2 = 0; j2 < 256; j2++) X { X fprintf (p_table_file, "%hd", (short) horiz_mode [j1] [j2]); X if (j3++ == 11) X { X j3 = 0; fprintf (p_table_file, ",\n "); X } X else if (j2 != 255) fprintf (p_table_file, ", "); X } X if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, " }\n"); X else fprintf (p_table_file, " },\n"); X } X fprintf (p_table_file, "};\n"); X /* ---------------------------------------- horiz_mode_next_state [] [] */ X fprintf (p_table_file, X "unsigned char horiz_mode_next_state [%hd] [256] = {\n", X horiz_mode_prefix_count); X for (j1 = 0; j1 < horiz_mode_prefix_count; j1++) X { X fprintf (p_table_file, "/* %hd */", j1); X j3 = 1; X fprintf (p_table_file, " { "); X for (j2 = 0; j2 < 256; j2++) X { X fprintf (p_table_file, "%hd", (short) horiz_mode_next_state [j1] [j2]); X if (j3++ == 14) X { X j3 = 0; fprintf (p_table_file, ",\n "); X } X else if (j2 != 255) fprintf (p_table_file, ", "); X } X if (j1 == horiz_mode_prefix_count - 1) fprintf (p_table_file, " }\n"); X else fprintf (p_table_file, " },\n"); X } X fprintf (p_table_file, "};\n"); X fclose (p_table_file); X} X X/* end $RCSfile: builddec.c $ */ SHAR_EOF chmod 0644 builddec.c || echo "restore of builddec.c fails" sed 's/^X//' << 'SHAR_EOF' > cg317-0i.001 && XSHAR_EOF chmod 0644 cg317-0i.001 || echo "restore of cg317-0i.001 fails" sed 's/^X//' << 'SHAR_EOF' > g3g4.h && X/* $Id: g3g4.h 1.2 90/06/09 18:21:50 marking Exp $ X * X NAME X * g3g4.h -- definitions for decoding group 3 and group 4 images X * X USED WITH X * builddec.c -- build decode tables X * group 3 and group 4 encoding and decoding routines X * X DESCRIPTION X * Common definitions for group 3 and group 4 utilities. 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: g3g4.h 1.2 90/06/09 18:21:50 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 PORTABILITY X * X * There is a non-portable use of "global" variables in this file, X * about which a minority of compilers will justifiably complain. Certain X * variables are declared here without extern keywords. Strictly X * speaking, they should be declared extern in all but one module, but X * that would require complication of this file. If it gets past your X * compiler and linker, you can probably ignore it. X * X HISTORY X * $Log: g3g4.h $ X * Revision 1.2 90/06/09 18:21:50 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 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#define WHITE 0 X#define BLACK 1 X X#define NULL_MODE 0 X#define PASS_MODE 1 X#define HORIZONTAL_MODE 2 X#define VERTICAL_V0_MODE 3 X#define VERTICAL_VR1_MODE 4 X#define VERTICAL_VR2_MODE 5 X#define VERTICAL_VR3_MODE 6 X#define VERTICAL_VL1_MODE 7 X#define VERTICAL_VL2_MODE 8 X#define VERTICAL_VL3_MODE 9 X#define EXT_MODE_UNCOMPRESSED 10 X#define ERROR_MODE 11 X#define ERROR_MODE_1 12 X X#define PASS_CODEWORD 0x1000 X#define HORIZONTAL_CODEWORD 0x2000 X#define VERTICAL_V0_CODEWORD 0x8000 X#define VERTICAL_VR1_CODEWORD 0x6000 X#define VERTICAL_VR2_CODEWORD 0x0C00 X#define VERTICAL_VR3_CODEWORD 0x0600 X#define VERTICAL_VL1_CODEWORD 0x4000 X#define VERTICAL_VL2_CODEWORD 0x0800 X#define VERTICAL_VL3_CODEWORD 0x0400 X X#define PASS_CODELEN 4 X#define HORIZONTAL_CODELEN 3 X#define VERTICAL_V0_CODELEN 1 X#define VERTICAL_VR1_CODELEN 3 X#define VERTICAL_VR2_CODELEN 6 X#define VERTICAL_VR3_CODELEN 7 X#define VERTICAL_VL1_CODELEN 3 X#define VERTICAL_VL2_CODELEN 6 X#define VERTICAL_VL3_CODELEN 7 X X#define RETURN_OK 0 X#define ERROR_NEXT_BYTE 1 /* the routine next_byte () unexpectedly returned X an error or end-of-file before the end of the image (EOFB) was reached */ X#define ERROR_UNSUPPORTED_EXTENSION 2 X#define ERROR_INVALID_CODEWORD 3 X#define ERROR_PROGRAM_LOGIC 4 X X#define EOL_CODE -1 X#define INVALID_CODE -2 X X#define MSB_FIRST 1 X#define LSB_FIRST 2 X X#define PAD_NONE 1 X#define PAD_BYTE 2 X#define PAD_NIBBLE 3 X#define PAD_ODD_NIBBLE 4 X Xchar (*p_decode_black) (short); Xchar (*p_decode_new_row) (void); Xshort (*p_decode_next_byte) (void); Xchar (*p_decode_white) (short); X Xchar g3i_decode_T (void); Xchar g3i_decode (void); Xchar g3i_initialize (short, short); Xchar g4i_decode (void); Xchar g4i_initialize (short, short); X Xchar (*p_encode_next_byte) (unsigned char); X Xchar g3j_encode_black (short); Xchar g3j_encode_white (short); Xchar g3j_encode_new_row (void); Xchar g3j_encode_pad (char); Xchar g3j_initialize (short, short); Xchar g4j_encode_black (short); Xchar g4j_encode_white (short); Xchar g4j_encode_EOFB (void); Xchar g4j_encode_new_row (void); Xchar g4j_initialize (short, short); X X/* internal stuff */ X Xvoid encode_word (unsigned short, short); Xvoid initialize_encode (void); Xshort encode_position; X Xchar output_fill_order, input_fill_order; Xunsigned char encode_buffer; Xunsigned char *decode_mask, *encode_mask, *encode_head_mask, *encode_tail_mask; Xshort pending_black, pending_white; X Xchar trace_flag; /* for debug */ X X/* end $RCSfile: g3g4.h $ */ SHAR_EOF chmod 0644 g3g4.h || echo "restore of g3g4.h fails" sed 's/^X//' << 'SHAR_EOF' > g3sdecod.c && X/* $Id: g3sdecod.c 1.2 90/06/09 18:22:19 marking Exp $ X * X NAME X * g3sdecod.c -- decode group 3 data using nested if statements 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: g3sdecod.c 1.2 90/06/09 18:22:19 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: g3sdecod.c $ X * Revision 1.2 90/06/09 18:22:19 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 * g4sdecod.c -- decode 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 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 horiz_mode [] [256]; Xextern unsigned char horiz_mode_next_state [] [256]; X Xstatic short 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); X Xstatic char decode_return; X X/* g3i_decode () successively invokes (*p_decode_next_byte) () for each byte X of the encoded image, and calls (*p_decode_white) () or (*p_decode_black) () X as 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 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 /* 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/* 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); X else /* 011010010 */ return (832); X } X else /* 01101000 */ return (576); X } X } X } X else /* 01100... */ X { X if (next_bit ()) /* 011001... */ X { X if (next_bit ()) /* 0110011... */ X { X if (next_bit ()) /* 01100111 */ return (640); X else /* 01100110 */ X { X if (next_bit ()) /* 011001101 */ return (768); X else /* 011001100 */ return (704); X } X } X else /* 0110010 */ X { X if (next_bit ()) /* 01100101 */ return (512); X else /* 01100100 */ return (448); X } X } X else /* 011000 */ return (1664); X } X } X } X else /* 010... */ X { X if (next_bit ()) /* 0101... */ X { X if (next_bit ()) /* 01011... */ X { X if (next_bit ()) /* 010111 */ return (192); X else /* 010110... */ X { X if (next_bit ()) /* 0101101... */ X { X if (next_bit ()) /* 01011011 */ return (58); X else /* 01011010 */ return (57); X } X else /* 0101100... */ X { X if (next_bit ()) /* 01011001 */ return (56); X else /* 01011000 */ return (55); X } SHAR_EOF echo "End of part 1, continue with part 2" echo "2" > s2_seq_.tmp exit 0 -- bill davidsen (ibmbin-request@crdgw1.crd.ge.com, uunet!crdgw1!ibmbin-request) moderator c.b.i.p newsgroup and 386users mailing list. binary submissions to ibmbin@crdgw1.crd.ge.com (uunet!crdgw1!ibmbin) "Stupidity, like virtue, is its own reward" -me