Annotation of researchv10no/cmd/bcp/bcp.cpio, revision 1.1.1.1

1.1       root        1: 0707070035351137021006640007620000050000010260220476773366500001100000001573Bfeats.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                      2: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                      3: /* The copyright notice does not imply actual or intended publication. */
                      4: /* AUTHORS:                                            */
                      5: /*     H. S. Baird - ATT-BL MH - first versions        */
                      6: 
                      7: /* Bfeats.h - typedef, constants, and function declarations for Bfeats.
                      8:    INCLUDES
                      9:        Requires prior #include "BMask.h"
                     10:    */
                     11: 
                     12: typedef struct Bfeats {
                     13:        BMask bm;               /* bitmask (1 for each feature) */
                     14:        unsigned short mny;     /* number of feature indices in fa[] */
                     15:        unsigned short *fa;     /* fa[mny] of feature (ss) nos, no dups (malloc) */
                     16:        } Bfeats;
                     17: 
                     18: #define Init_Bfeats {Init_BMask,0,NULL}
                     19: #if MAIN
                     20:        Bfeats empty_Bfeats = Init_Bfeats;
                     21: #else
                     22:        extern Bfeats empty_Bfeats;
                     23: #endif
                     24: 
                     25: Bfeats *alloc_bfeats();
                     26: free_bfeats();
                     27: char *bfeats_toa();
                     28: Bfeats *dup_bfeats();
                     29: 0707070035351137031006640007620000050000010260240476773366500001100000470007Bitmap.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                     30: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                     31: /* The copyright notice does not imply actual or intended publication. */
                     32: /* AUTHORS:                                            */
                     33: /*     H. S. Baird - ATT-BL MH - first versions        */
                     34: /* Bitmap.h:  2-D fixed-sized bitmaps */
                     35: 
                     36: /* BITMAP TEMPLATES: potentially MACHINE-DEPENDENT bit-packing */
                     37: #define Bm_h   54                      /* height (no. bits) */
                     38: #define Bm_il  3                       /* width (no. ints) */
                     39: #define Bm_ex_h        5                       /* extra pixels allowed, top/bottom */
                     40: #define Bm_ex_w        16                      /* extra pixels allowed, left/right */
                     41: 
                     42: #define Bm_wi  ((int)(8*sizeof(int)))  /* width of an int in bits;  sizeof() is
                     43:                                           unsigned: must coerce to signed so can
                     44:                                           compare correctly with negative ints */
                     45: typedef unsigned int Bm_l[Bm_il];      /* bitmap line */
                     46: #define Bm_w   (Bm_wi*Bm_il)           /* width of bitmap (<= # bits in a Bm_l) */
                     47: #define Bm_w_ok (Bm_w+2*Bm_ex_w)       /* OK width (sides truncated to fit) */
                     48: #define Bm_h_ok (Bm_h+2*Bm_ex_h)       /* OK height (top/bot truncated to fit) */
                     49: #define Bm_area (Bm_w*Bm_h)            /* area of bitmap */
                     50: #define Bm_ni  (Bm_il*Bm_h)            /* no. ints in bitmap area */
                     51: #define Bm_ns  (2*Bm_ni)               /* no. of shorts in bitmap area */
                     52: 
                     53: typedef union Bm {             /* the rectangular array of bits */
                     54:        Bm_l l[Bm_h];
                     55:        int unsigned i[Bm_ni];
                     56:        short unsigned s[Bm_ns];
                     57:        } Bm;
                     58: 
                     59: typedef struct Bm_consts {
                     60:        unsigned int mask_all;          /* all bitmap bits set */
                     61:        unsigned int mask[Bm_wi];       /* constant mask bits (in int) */
                     62:        unsigned char Rbits[256];       /* Bytes with bits reversed */
                     63:        unsigned char Nbits[65536];     /* Nbits[i] = no. bits set in
                     64:                                           (unsigned short) i */
                     65:        } Bm_consts;
                     66: 
                     67: /* The following 2076 lines are a static initialization for Bm_consts;
                     68:    it is written by program `mkbmc' which runs function `fwra_bm_consts' */
                     69: #if MAIN
                     70: Bm_consts bm_consts = { 
                     71:  0xffffffff, 
                     72:  { 0x1,0x2,0x4,0x8, 
                     73:    0x10,0x20,0x40,0x80, 
                     74:    0x100,0x200,0x400,0x800, 
                     75:    0x1000,0x2000,0x4000,0x8000, 
                     76:    0x10000,0x20000,0x40000,0x80000, 
                     77:    0x100000,0x200000,0x400000,0x800000, 
                     78:    0x1000000,0x2000000,0x4000000,0x8000000, 
                     79:    0x10000000,0x20000000,0x40000000,0x80000000 }, 
                     80:  { 00,0200,0100,0300,040,0240,0140,0340,020,0220,0120,0320,060,0260,0160,0360, 
                     81:    010,0210,0110,0310,050,0250,0150,0350,030,0230,0130,0330,070,0270,0170,0370, 
                     82:    04,0204,0104,0304,044,0244,0144,0344,024,0224,0124,0324,064,0264,0164,0364, 
                     83:    014,0214,0114,0314,054,0254,0154,0354,034,0234,0134,0334,074,0274,0174,0374, 
                     84:    02,0202,0102,0302,042,0242,0142,0342,022,0222,0122,0322,062,0262,0162,0362, 
                     85:    012,0212,0112,0312,052,0252,0152,0352,032,0232,0132,0332,072,0272,0172,0372, 
                     86:    06,0206,0106,0306,046,0246,0146,0346,026,0226,0126,0326,066,0266,0166,0366, 
                     87:    016,0216,0116,0316,056,0256,0156,0356,036,0236,0136,0336,076,0276,0176,0376, 
                     88:    01,0201,0101,0301,041,0241,0141,0341,021,0221,0121,0321,061,0261,0161,0361, 
                     89:    011,0211,0111,0311,051,0251,0151,0351,031,0231,0131,0331,071,0271,0171,0371, 
                     90:    05,0205,0105,0305,045,0245,0145,0345,025,0225,0125,0325,065,0265,0165,0365, 
                     91:    015,0215,0115,0315,055,0255,0155,0355,035,0235,0135,0335,075,0275,0175,0375, 
                     92:    03,0203,0103,0303,043,0243,0143,0343,023,0223,0123,0323,063,0263,0163,0363, 
                     93:    013,0213,0113,0313,053,0253,0153,0353,033,0233,0133,0333,073,0273,0173,0373, 
                     94:    07,0207,0107,0307,047,0247,0147,0347,027,0227,0127,0327,067,0267,0167,0367, 
                     95:    017,0217,0117,0317,057,0257,0157,0357,037,0237,0137,0337,077,0277,0177,0377 }, 
                     96:  { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 
                     97:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                     98:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                     99:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    100:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    101:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    102:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    103:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    104:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    105:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    106:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    107:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    108:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    109:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    110:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    111:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    112:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    113:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    114:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    115:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    116:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    117:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    118:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    119:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    120:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    121:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    122:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    123:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    124:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    125:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    126:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    127:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    128:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    129:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    130:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    131:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    132:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    133:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    134:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    135:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    136:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    137:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    138:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    139:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    140:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    141:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    142:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    143:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    144:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    145:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    146:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    147:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    148:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    149:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    150:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    151:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    152:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    153:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    154:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    155:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    156:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    157:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    158:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    159:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    160:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    161:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    162:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    163:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    164:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    165:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    166:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    167:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    168:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    169:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    170:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    171:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    172:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    173:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    174:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    175:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    176:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    177:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    178:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    179:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    180:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    181:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    182:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    183:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    184:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    185:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    186:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    187:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    188:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    189:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    190:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    191:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    192:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    193:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    194:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    195:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    196:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    197:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    198:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    199:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    200:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    201:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    202:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    203:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    204:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    205:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    206:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    207:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    208:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    209:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    210:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    211:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    212:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    213:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    214:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    215:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    216:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    217:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    218:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    219:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    220:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    221:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    222:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    223:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    224:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    225:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    226:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    227:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    228:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    229:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    230:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    231:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    232:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    233:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    234:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    235:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    236:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    237:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    238:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    239:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    240:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    241:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    242:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    243:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    244:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    245:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    246:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    247:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    248:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    249:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    250:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    251:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    252:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    253:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    254:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    255:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    256:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    257:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    258:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    259:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    260:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    261:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    262:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    263:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    264:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    265:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    266:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    267:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    268:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    269:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    270:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    271:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    272:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    273:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    274:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    275:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    276:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    277:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    278:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    279:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    280:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    281:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    282:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    283:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    284:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    285:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    286:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    287:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    288:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    289:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    290:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    291:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    292:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    293:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    294:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    295:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    296:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    297:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    298:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    299:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    300:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    301:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    302:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    303:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    304:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    305:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    306:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    307:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    308:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    309:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    310:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    311:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    312:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    313:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    314:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    315:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    316:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    317:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    318:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    319:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    320:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    321:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    322:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    323:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    324:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    325:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    326:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    327:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    328:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    329:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    330:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    331:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    332:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    333:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    334:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    335:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    336:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    337:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    338:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    339:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    340:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    341:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    342:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    343:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    344:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    345:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    346:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    347:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    348:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    349:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    350:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    351:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    352:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    353:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    354:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    355:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    356:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    357:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    358:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    359:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    360:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    361:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    362:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    363:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    364:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    365:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    366:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    367:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    368:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    369:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    370:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    371:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    372:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    373:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    374:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    375:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    376:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    377:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    378:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    379:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    380:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    381:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    382:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    383:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    384:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    385:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    386:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    387:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    388:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    389:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    390:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    391:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    392:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    393:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    394:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    395:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    396:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    397:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    398:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    399:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    400:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    401:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    402:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    403:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    404:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    405:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    406:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    407:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    408:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    409:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    410:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    411:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    412:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    413:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    414:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    415:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    416:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    417:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    418:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    419:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    420:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    421:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    422:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    423:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    424:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    425:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    426:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    427:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    428:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    429:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    430:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    431:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    432:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    433:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    434:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    435:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    436:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    437:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    438:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    439:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    440:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    441:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    442:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    443:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    444:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    445:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    446:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    447:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    448:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    449:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    450:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    451:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    452:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    453:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    454:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    455:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    456:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    457:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    458:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    459:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    460:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    461:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    462:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    463:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    464:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    465:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    466:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    467:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    468:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    469:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    470:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    471:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    472:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    473:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    474:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    475:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    476:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    477:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    478:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    479:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    480:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    481:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    482:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    483:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    484:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    485:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    486:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    487:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    488:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    489:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    490:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    491:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    492:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    493:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    494:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    495:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    496:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    497:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    498:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    499:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    500:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    501:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    502:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    503:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    504:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    505:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    506:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    507:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    508:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    509:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    510:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    511:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    512:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    513:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    514:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    515:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    516:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    517:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    518:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    519:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    520:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    521:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    522:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    523:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    524:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    525:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    526:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    527:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    528:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    529:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    530:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    531:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    532:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    533:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    534:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    535:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    536:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    537:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    538:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    539:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    540:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    541:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    542:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    543:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    544:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    545:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    546:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    547:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    548:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    549:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    550:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    551:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    552:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    553:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    554:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    555:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    556:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    557:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    558:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    559:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    560:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    561:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    562:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    563:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    564:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    565:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    566:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    567:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    568:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    569:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    570:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    571:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    572:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    573:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    574:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    575:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    576:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    577:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    578:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    579:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    580:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    581:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    582:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    583:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    584:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    585:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    586:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    587:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    588:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    589:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    590:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    591:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    592:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    593:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    594:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    595:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    596:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    597:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    598:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    599:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    600:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    601:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    602:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    603:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    604:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    605:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    606:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    607:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                    608:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                    609:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    610:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    611:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    612:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    613:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    614:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    615:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    616:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    617:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    618:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    619:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    620:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    621:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    622:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    623:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    624:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    625:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    626:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    627:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    628:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    629:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    630:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    631:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    632:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    633:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    634:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    635:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    636:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    637:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    638:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    639:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    640:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    641:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    642:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    643:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    644:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    645:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    646:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    647:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    648:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    649:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    650:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    651:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    652:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    653:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    654:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    655:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    656:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    657:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    658:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    659:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    660:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    661:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    662:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    663:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    664:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    665:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    666:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    667:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    668:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    669:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    670:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    671:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    672:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    673:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    674:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    675:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    676:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    677:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    678:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    679:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    680:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    681:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    682:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    683:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    684:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    685:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    686:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    687:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    688:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    689:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    690:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    691:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    692:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    693:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    694:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    695:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    696:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    697:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    698:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    699:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    700:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    701:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    702:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    703:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    704:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    705:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    706:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    707:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    708:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    709:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    710:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    711:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    712:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    713:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    714:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    715:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    716:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    717:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    718:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    719:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    720:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    721:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    722:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    723:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    724:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    725:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    726:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    727:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    728:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    729:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    730:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    731:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    732:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    733:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    734:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    735:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    736:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    737:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    738:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    739:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    740:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    741:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    742:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    743:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    744:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    745:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    746:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    747:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    748:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    749:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    750:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    751:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    752:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    753:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    754:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    755:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    756:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    757:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    758:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    759:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    760:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    761:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    762:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    763:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    764:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    765:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    766:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    767:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    768:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    769:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    770:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    771:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    772:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    773:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    774:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    775:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    776:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    777:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    778:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    779:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    780:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    781:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    782:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    783:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    784:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    785:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    786:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    787:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    788:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    789:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    790:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    791:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    792:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    793:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    794:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    795:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    796:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    797:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    798:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    799:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    800:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    801:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    802:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    803:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    804:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    805:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    806:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    807:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    808:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    809:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    810:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    811:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    812:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    813:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    814:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    815:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    816:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    817:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    818:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    819:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    820:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    821:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    822:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    823:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    824:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    825:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    826:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    827:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    828:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    829:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    830:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    831:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    832:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    833:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    834:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    835:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    836:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    837:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    838:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    839:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    840:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    841:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    842:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    843:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    844:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    845:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    846:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    847:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    848:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    849:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    850:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    851:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    852:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    853:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    854:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    855:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    856:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    857:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    858:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    859:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    860:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    861:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    862:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    863:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                    864:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                    865:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    866:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    867:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    868:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    869:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    870:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    871:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    872:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    873:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    874:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    875:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    876:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    877:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    878:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    879:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    880:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    881:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    882:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    883:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    884:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    885:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    886:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    887:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    888:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    889:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    890:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    891:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    892:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    893:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    894:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    895:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    896:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    897:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    898:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    899:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    900:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    901:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    902:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    903:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    904:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    905:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    906:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    907:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    908:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    909:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    910:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    911:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    912:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    913:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    914:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    915:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    916:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    917:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    918:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    919:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    920:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    921:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    922:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    923:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    924:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    925:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    926:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    927:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    928:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    929:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    930:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    931:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    932:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    933:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    934:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    935:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    936:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    937:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    938:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    939:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    940:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    941:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    942:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    943:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    944:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    945:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    946:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    947:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    948:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    949:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    950:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    951:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    952:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    953:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    954:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    955:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    956:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    957:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    958:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    959:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    960:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    961:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    962:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    963:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    964:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    965:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    966:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    967:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    968:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    969:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    970:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    971:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    972:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    973:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    974:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    975:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    976:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    977:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    978:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    979:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    980:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    981:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    982:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    983:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    984:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                    985:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    986:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    987:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    988:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                    989:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    990:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                    991:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                    992:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                    993:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    994:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    995:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    996:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                    997:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    998:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                    999:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1000:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1001:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1002:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1003:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1004:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1005:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1006:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1007:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1008:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1009:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1010:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1011:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1012:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1013:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1014:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1015:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1016:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1017:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1018:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1019:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1020:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1021:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1022:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1023:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1024:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1025:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1026:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1027:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1028:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1029:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1030:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1031:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1032:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1033:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1034:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1035:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1036:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1037:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1038:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1039:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1040:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1041:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1042:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1043:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1044:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1045:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1046:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1047:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1048:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1049:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1050:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1051:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1052:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1053:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1054:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1055:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1056:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1057:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1058:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1059:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1060:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1061:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1062:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1063:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1064:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1065:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1066:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1067:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1068:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1069:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1070:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1071:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1072:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1073:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1074:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1075:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1076:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1077:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1078:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1079:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1080:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1081:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1082:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1083:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1084:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1085:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1086:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1087:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1088:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1089:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1090:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1091:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1092:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1093:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1094:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1095:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1096:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1097:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1098:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1099:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1100:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1101:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1102:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1103:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1104:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1105:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1106:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1107:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1108:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1109:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1110:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1111:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1112:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1113:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1114:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1115:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1116:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1117:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1118:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1119:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   1120:    1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 
                   1121:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1122:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1123:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1124:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1125:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1126:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1127:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1128:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1129:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1130:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1131:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1132:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1133:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1134:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1135:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1136:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1137:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1138:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1139:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1140:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1141:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1142:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1143:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1144:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1145:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1146:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1147:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1148:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1149:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1150:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1151:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1152:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1153:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1154:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1155:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1156:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1157:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1158:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1159:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1160:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1161:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1162:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1163:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1164:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1165:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1166:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1167:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1168:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1169:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1170:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1171:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1172:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1173:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1174:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1175:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1176:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1177:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1178:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1179:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1180:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1181:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1182:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1183:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1184:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1185:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1186:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1187:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1188:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1189:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1190:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1191:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1192:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1193:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1194:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1195:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1196:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1197:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1198:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1199:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1200:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1201:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1202:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1203:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1204:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1205:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1206:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1207:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1208:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1209:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1210:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1211:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1212:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1213:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1214:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1215:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1216:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1217:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1218:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1219:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1220:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1221:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1222:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1223:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1224:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1225:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1226:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1227:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1228:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1229:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1230:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1231:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1232:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1233:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1234:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1235:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1236:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1237:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1238:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1239:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1240:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1241:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1242:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1243:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1244:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1245:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1246:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1247:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1248:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1249:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1250:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1251:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1252:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1253:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1254:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1255:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1256:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1257:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1258:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1259:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1260:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1261:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1262:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1263:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1264:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1265:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1266:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1267:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1268:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1269:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1270:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1271:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1272:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1273:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1274:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1275:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1276:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1277:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1278:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1279:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1280:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1281:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1282:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1283:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1284:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1285:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1286:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1287:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1288:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1289:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1290:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1291:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1292:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1293:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1294:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1295:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1296:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1297:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1298:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1299:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1300:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1301:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1302:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1303:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1304:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1305:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1306:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1307:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1308:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1309:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1310:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1311:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1312:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1313:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1314:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1315:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1316:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1317:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1318:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1319:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1320:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1321:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1322:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1323:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1324:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1325:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1326:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1327:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1328:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1329:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1330:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1331:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1332:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1333:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1334:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1335:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1336:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1337:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1338:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1339:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1340:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1341:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1342:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1343:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1344:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1345:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1346:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1347:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1348:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1349:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1350:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1351:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1352:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1353:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1354:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1355:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1356:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1357:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1358:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1359:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1360:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1361:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1362:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1363:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1364:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1365:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1366:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1367:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1368:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1369:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1370:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1371:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1372:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1373:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1374:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1375:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1376:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1377:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1378:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1379:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1380:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1381:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1382:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1383:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1384:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1385:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1386:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1387:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1388:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1389:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1390:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1391:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1392:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1393:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1394:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1395:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1396:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1397:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1398:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1399:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1400:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1401:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1402:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1403:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1404:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1405:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1406:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1407:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1408:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1409:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1410:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1411:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1412:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1413:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1414:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1415:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1416:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1417:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1418:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1419:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1420:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1421:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1422:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1423:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1424:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1425:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1426:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1427:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1428:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1429:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1430:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1431:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1432:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1433:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1434:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1435:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1436:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1437:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1438:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1439:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1440:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1441:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1442:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1443:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1444:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1445:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1446:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1447:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1448:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1449:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1450:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1451:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1452:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1453:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1454:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1455:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1456:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1457:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1458:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1459:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1460:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1461:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1462:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1463:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1464:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1465:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1466:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1467:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1468:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1469:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1470:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1471:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1472:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1473:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1474:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1475:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1476:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1477:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1478:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1479:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1480:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1481:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1482:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1483:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1484:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1485:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1486:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1487:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1488:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1489:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1490:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1491:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1492:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1493:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1494:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1495:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1496:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1497:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1498:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1499:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1500:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1501:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1502:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1503:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1504:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1505:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1506:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1507:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1508:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1509:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1510:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1511:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1512:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1513:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1514:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1515:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1516:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1517:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1518:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1519:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1520:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1521:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1522:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1523:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1524:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1525:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1526:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1527:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1528:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1529:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1530:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1531:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1532:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1533:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1534:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1535:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1536:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1537:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1538:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1539:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1540:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1541:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1542:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1543:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1544:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1545:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1546:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1547:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1548:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1549:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1550:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1551:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1552:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1553:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1554:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1555:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1556:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1557:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1558:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1559:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1560:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1561:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1562:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1563:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1564:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1565:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1566:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1567:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1568:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1569:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1570:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1571:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1572:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1573:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1574:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1575:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1576:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1577:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1578:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1579:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1580:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1581:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1582:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1583:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1584:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1585:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1586:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1587:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1588:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1589:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1590:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1591:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1592:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1593:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1594:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1595:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1596:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1597:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1598:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1599:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1600:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1601:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1602:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1603:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1604:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1605:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1606:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1607:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1608:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1609:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1610:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1611:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1612:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1613:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1614:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1615:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1616:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1617:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1618:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1619:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1620:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1621:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1622:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1623:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1624:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1625:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1626:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1627:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1628:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1629:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1630:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1631:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   1632:    2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 
                   1633:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1634:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1635:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1636:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1637:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1638:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1639:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1640:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1641:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1642:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1643:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1644:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1645:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1646:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1647:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1648:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1649:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1650:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1651:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1652:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1653:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1654:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1655:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1656:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1657:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1658:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1659:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1660:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1661:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1662:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1663:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1664:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1665:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1666:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1667:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1668:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1669:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1670:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1671:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1672:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1673:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1674:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1675:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1676:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1677:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1678:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1679:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1680:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1681:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1682:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1683:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1684:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1685:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1686:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1687:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1688:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1689:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1690:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1691:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1692:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1693:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1694:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1695:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1696:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1697:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1698:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1699:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1700:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1701:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1702:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1703:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1704:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1705:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1706:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1707:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1708:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1709:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1710:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1711:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1712:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1713:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1714:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1715:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1716:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1717:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1718:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1719:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1720:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1721:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1722:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1723:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1724:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1725:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1726:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1727:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1728:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1729:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1730:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1731:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1732:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1733:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1734:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1735:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1736:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1737:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1738:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1739:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1740:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1741:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1742:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1743:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1744:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1745:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1746:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1747:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1748:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1749:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1750:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1751:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1752:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1753:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1754:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1755:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1756:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1757:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1758:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1759:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1760:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1761:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1762:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1763:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1764:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1765:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1766:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1767:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1768:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1769:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1770:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1771:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1772:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1773:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1774:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1775:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1776:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1777:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1778:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1779:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1780:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1781:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1782:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1783:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1784:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1785:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1786:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1787:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1788:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1789:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1790:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1791:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1792:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1793:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1794:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1795:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1796:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1797:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1798:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1799:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1800:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1801:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1802:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1803:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1804:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1805:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1806:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1807:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1808:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1809:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1810:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1811:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1812:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1813:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1814:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1815:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1816:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1817:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1818:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1819:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1820:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1821:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1822:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1823:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1824:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1825:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1826:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1827:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1828:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1829:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1830:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1831:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1832:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1833:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1834:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1835:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1836:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1837:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1838:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1839:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1840:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1841:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1842:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1843:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1844:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1845:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1846:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1847:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1848:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1849:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1850:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1851:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1852:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1853:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1854:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1855:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1856:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1857:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1858:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1859:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1860:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1861:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1862:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1863:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1864:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1865:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1866:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1867:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1868:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1869:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1870:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1871:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1872:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1873:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1874:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1875:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1876:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1877:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1878:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1879:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1880:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1881:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1882:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1883:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1884:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1885:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1886:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1887:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   1888:    3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, 
                   1889:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1890:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1891:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1892:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1893:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1894:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1895:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1896:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1897:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1898:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1899:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1900:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1901:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1902:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1903:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1904:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1905:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1906:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1907:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1908:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1909:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1910:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1911:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1912:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1913:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1914:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1915:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1916:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1917:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1918:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1919:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1920:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1921:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1922:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1923:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1924:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1925:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1926:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1927:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1928:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1929:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1930:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1931:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1932:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1933:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1934:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1935:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1936:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1937:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1938:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1939:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1940:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1941:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1942:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1943:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1944:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1945:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1946:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1947:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1948:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1949:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1950:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1951:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1952:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   1953:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1954:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1955:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1956:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1957:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1958:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1959:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1960:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1961:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1962:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1963:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1964:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1965:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1966:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1967:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1968:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1969:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1970:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1971:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1972:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1973:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1974:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1975:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1976:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1977:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1978:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1979:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1980:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1981:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1982:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1983:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   1984:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   1985:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1986:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1987:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1988:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1989:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1990:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1991:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1992:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   1993:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1994:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1995:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1996:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   1997:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1998:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   1999:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2000:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2001:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2002:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2003:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2004:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2005:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2006:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2007:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2008:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2009:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2010:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2011:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2012:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2013:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2014:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2015:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2016:    4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9, 
                   2017:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   2018:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   2019:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2020:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   2021:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2022:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2023:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2024:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   2025:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2026:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2027:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2028:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2029:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2030:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2031:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2032:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   2033:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2034:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2035:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2036:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2037:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2038:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2039:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2040:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2041:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2042:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2043:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2044:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2045:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2046:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2047:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2048:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   2049:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2050:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2051:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2052:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2053:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2054:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2055:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2056:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2057:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2058:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2059:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2060:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2061:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2062:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2063:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2064:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2065:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2066:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2067:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2068:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2069:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2070:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2071:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2072:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2073:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2074:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2075:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2076:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2077:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2078:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2079:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2080:    5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9,6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10, 
                   2081:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2082:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2083:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2084:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2085:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2086:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2087:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2088:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2089:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2090:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2091:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2092:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2093:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2094:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2095:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2096:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2097:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2098:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2099:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2100:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2101:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2102:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2103:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2104:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2105:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2106:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2107:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2108:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2109:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2110:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2111:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2112:    6,7,7,8,7,8,8,9,7,8,8,9,8,9,9,10,7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11, 
                   2113:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2114:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2115:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2116:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2117:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2118:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2119:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2120:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2121:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2122:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2123:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2124:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2125:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2126:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2127:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2128:    7,8,8,9,8,9,9,10,8,9,9,10,9,10,10,11,8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12, 
                   2129:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2130:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2131:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2132:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2133:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2134:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2135:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2136:    8,9,9,10,9,10,10,11,9,10,10,11,10,11,11,12,9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13, 
                   2137:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2138:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2139:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2140:    9,10,10,11,10,11,11,12,10,11,11,12,11,12,12,13,10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14, 
                   2141:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2142:    10,11,11,12,11,12,12,13,11,12,12,13,12,13,13,14,11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15, 
                   2143:    11,12,12,13,12,13,13,14,12,13,13,14,13,14,14,15,12,13,13,14,13,14,14,15,13,14,14,15,14,15,15,16 }
                   2144:    };
                   2145: 
                   2146: #else
                   2147: extern Bm_consts bm_consts;
                   2148: #endif
                   2149: 
                   2150: double Bm_match();
                   2151: char *BM_toa();
                   2152: 0707070035351137041006640007620000050000010260520476773366600001000000207047CCITT.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   2153: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   2154: /* The copyright notice does not imply actual or intended publication. */
                   2155: /* AUTHORS:                                            */
                   2156: /*     H. S. Baird - ATT-BL MH - first versions        */
                   2157: 
                   2158: /* CCITT.c - functions for CCITT compression/decompression of binary images.
                   2159:    The following discussion is a summary of CCITT Recommendations T.4 and T.6
                   2160: on facsimile coding schemes and coding control functions for Group 3 and Group
                   2161: 4 facsimile apparatus (drafted at Malaga-Torremolinos, 1984).  They describe
                   2162: algorithms for invertible (lossless) compression and decompression of bilevel
                   2163: (black-and-white, not grey) 2D rectangular images of arbitrary height and
                   2164: width.  By convention the images are processed top-down, one horizontal scan
                   2165: line at a time.  It is not strictly necessary to know the height of an image
                   2166: before starting compression or decompression.  Width, however, must be known
                   2167: in advance in some cases (discussed below), and must remain constant for the
                   2168: whole image in all cases.  There are three distinct but intimately related
                   2169: standards:  Group 3 1-dimensional, Group 3 2-dimensional, and Group 4.
                   2170: VLSI hardware implementations always include all three.  The Group 3 encodings
                   2171: are used in the vast installed base of FAX machines.  Group 4 is not used
                   2172: in today's FAX machines, but seems to be the default standard in document image
                   2173: archiving applications.
                   2174:        The CCITT Group 3 FAX standard permits either 1-D or 2-D encoding.
                   2175: It is not easy to tell from an encoding which was used.  Both 1-D and 2-D
                   2176: assume fixed scanline length (in pixels), which must be known at encoding time.
                   2177:        Group 3 1-D (g31) code uses fixed ``modified Huffman'' codes for
                   2178: run-lengths, with two different code tables for black and white runs.  Each
                   2179: line is assumed to begin with a (possibly 0-length) white run.  Of course,
                   2180: the colors strictly alternate.  An empty (all-white) line is supposed to be
                   2181: spelled out with a full pixel count, although some decoders won't complain
                   2182: if just a 0-length count is used.  There are provisions for fill bits at the
                   2183: end of lines to allow slow receiving equipment to keep up.  Each line ends with
                   2184: an EOL code on which it may be possible to synchronize after transmission error.
                   2185:        Group 3 2-D (g32) encoding tries to exploit the slowly-changing nature
                   2186: of artwork from line to line.  It is a mixture of 1-D-coded lines and
                   2187: ``2-D''-coded lines describing small local changes relative to the immediately
                   2188: prior ``reference'' line.  1-D coding recurs every few (`k') lines, so that
                   2189: resynchronization is frequently possible.  K is usually 2 or 4, but the
                   2190: standard permits any number, even infinity, since the coding method used on
                   2191: a line is specified by which of two special EOLx codes is used to end the
                   2192: prior line.
                   2193:        CCITT Group 4 (g4) is like Group 3 2-D, but optimized to take advantage
                   2194: of a lossless communications channel or reliable storage medium (such as computer
                   2195: memory), where resynchronization is unnecessary.  Thus the first line is 2-D
                   2196: encoded referenced to an imaginary initial blank line, k is always infinity,
                   2197: and EOL's are not used at all.  It essential that the line-length be known in
                   2198: advance of both encoding and decoding, so that line-breaks can be triggered when
                   2199: that length is exceeded.  End of FAX buffer (end of page) is signaled by a
                   2200: special EOFB code.
                   2201:    On images of printed text and sparse line-graphics, g4-compressed files
                   2202: are often 15-40X smaller than bitmap (packed bits), 5X than bitfile(9.5),
                   2203: 2X than g31, and 2X than rle | pack.
                   2204: PERFORMANCE
                   2205:    On 10 printed A4 pages (business letters, technical reports, etc),
                   2206: at a resolution of 400 dpi:
                   2207:        binary:         2020 Kbytes     CPU secs (to compress binary)
                   2208:         pack:           200 - 380      17
                   2209:        bitfile(9.5):    150 - 360       ?
                   2210:        rle:             100 - 230       7.5
                   2211:         compress:        90 - 155      14
                   2212:        g31:              85 - 190      13
                   2213:        g32:              55 - 110      13
                   2214:        g4:               30 -  70      13
                   2215:    G4-compressed files are 15-40X smaller than binary, 5X than bitfile(9.5),
                   2216: 3.5X than rle, 2X than g31, and 2X than rle | pack.
                   2217: */
                   2218: 
                   2219: #include <stdio.h>
                   2220: #include <string.h>
                   2221: #include <ctype.h>
                   2222: #include "CPU.h"
                   2223: #include "stdocr.h"
                   2224: #include "rle.h"
                   2225: #include "bitio.h"
                   2226: #include "CCITT.h"
                   2227: 
                   2228: #define DEBUG 0                /* 0 disables compilation of all debugging code;
                   2229:                           1 compiles, but must enable particular parts below */
                   2230: #define NEW_TRAIL 1    /* enable new trailing-0 counts (has passed early tests) */
                   2231: #define dbg_trail 0
                   2232: 
                   2233: DST_table *ccitt_table()
                   2234: {   DST_context cx;
                   2235:        if((cx.t = (DST_table *)malloc(sizeof(DST_table)))==NULL)
                   2236:                abort("CCITT.c: build_tbl: can't alloc cx.t");
                   2237:        /* All tables have e[DST_white], e[DST_black], & e[DST_2d] entries */
                   2238:        cx.t->mny=3;
                   2239:        if((cx.t->e=(DST_entry *)malloc(cx.t->mny*sizeof(DST_entry)))==NULL)
                   2240:                abort("CCITT.c: build_tbl: can't alloc cx.t->e[%d]",cx.t->mny);
                   2241: 
                   2242:        cx.s = cx.c = DST_white;
                   2243:        cx.l = 0;
                   2244:        cx.t->e[cx.s].p[0] = '\0';
                   2245:        cx.t->e[cx.s].l = 0;
                   2246:        cx.t->e[cx.s].z = 0;
                   2247:        build_transits(cx);
                   2248: 
                   2249:        cx.s = cx.c = DST_black;
                   2250:        cx.l = 0;
                   2251:        cx.t->e[cx.s].p[0] = '\0';
                   2252:        cx.t->e[cx.s].l = 0;
                   2253:        cx.t->e[cx.s].z = 0;
                   2254:        build_transits(cx);
                   2255: 
                   2256:        cx.s = cx.c = DST_2d;
                   2257:        cx.l = 0;
                   2258:        cx.t->e[cx.s].p[0] = '\0';
                   2259:        cx.t->e[cx.s].l = 0;
                   2260:        cx.t->e[cx.s].z = 0;
                   2261:        build_transits(cx);
                   2262: 
                   2263: #if DEBUG
                   2264:        if(F) ccitt_err_tbl(cx.t);
                   2265: #endif
                   2266:        return(cx.t);
                   2267:        }
                   2268: 
                   2269: DST_state new_state(t)
                   2270:    DST_table *t;
                   2271: {      t->mny++;
                   2272:        if((t->e=(DST_entry *)realloc(t->e,t->mny*sizeof(DST_entry)))==NULL)
                   2273:                abort("can't realloc t->[%d]",t->mny);
                   2274:        return(t->mny-1);
                   2275:        }
                   2276: 
                   2277: /* The entry described by `cx' exists in the table, and its prefix `p' is
                   2278:    setup; create its transitions, and their next entries, recursively.  */
                   2279: build_transits(cx)
                   2280:     DST_context cx;
                   2281: #define entry cx.t->e[cx.s]
                   2282: #define transit entry.t[col]
                   2283: {   DST_color col;
                   2284:     DST_entry ne;      /* next entry */
                   2285:     DST_context ncx;   /* next Context */
                   2286:     char **s,**ss;     /* for searching code */
                   2287:     short *c,*cs;
                   2288:     int si,matching,longer;
                   2289:     char svch,col_str[2];
                   2290:        switch(cx.c) {
                   2291:            case DST_white:
                   2292:                ss=codewht;
                   2293:                cs=bitcwht;
                   2294:                break;
                   2295:            case DST_black:
                   2296:                ss=codeblk;
                   2297:                cs=bitcblk;
                   2298:                break;
                   2299:            case DST_2d:
                   2300:                ss=code2d;
                   2301:                cs=bitc2d;
                   2302:                break;
                   2303:            };
                   2304:        for(col=0;col<=1;col++) {
                   2305:                sprintf(col_str,"%1d",col);
                   2306:                ncx = cx;  ncx.l++; 
                   2307:                /* build a transition */
                   2308:                strcpy(ne.p,entry.p); strcat(ne.p,col_str);
                   2309:                ne.l = ncx.l;
                   2310:                if(col==0) ne.z = entry.z+1; else ne.z = 0;
                   2311:                /* count those that match new prefix */
                   2312:                longer=matching=0;
                   2313:                for(s=ss,c=cs,si=0; (*s)!=NULL; s++,c++,si++) {
                   2314:                        if(*c==ncx.l) {
                   2315:                                if(strcmp(*s,ne.p)==0) {
                   2316:                                        matching++;
                   2317:                                        switch(cx.c) {
                   2318:                                            case DST_white:
                   2319:                                            case DST_black:
                   2320:                                                transit.a = itor(si);
                   2321:                                                break;
                   2322:                                            case DST_2d:
                   2323:                                                transit.a = si;
                   2324:                                                break;
                   2325:                                            };
                   2326:                                        };
                   2327:                                }
                   2328:                        else if(*c>ncx.l) {
                   2329:                                svch=(*s)[ncx.l]; (*s)[ncx.l] = '\0';
                   2330:                                if(strcmp(*s,ne.p)==0) {
                   2331:                                        longer++;
                   2332:                                        };
                   2333:                                (*s)[ncx.l]=svch;
                   2334:                                };
                   2335:                        };
                   2336:                /* analyze results */
                   2337:                if(matching==0&&longer>0) {
                   2338:                        /* no match yet; go deeper */
                   2339:                        transit.a = DST_action_NULL;
                   2340:                        ncx.s = transit.s = new_state(cx.t);
                   2341:                        strcpy(cx.t->e[ncx.s].p,ne.p);
                   2342:                        cx.t->e[ncx.s].l = ne.l;
                   2343:                        cx.t->e[ncx.s].z = ne.z;
                   2344:                        build_transits(ncx);
                   2345:                        }
                   2346:                else if(matching==1&&longer==0) {
                   2347:                        /* unique leaf: good */
                   2348:                        /* picked up action earlier */
                   2349:                        switch(cx.c) {
                   2350:                            case DST_white:
                   2351:                            case DST_black:
                   2352:                                if(transit.a<=63) /* termination code */
                   2353:                                        transit.s = flip_color(cx.c); 
                   2354:                                else /* makeup code */
                   2355:                                        transit.s = cx.c;
                   2356:                                break;
                   2357:                            case DST_2d:
                   2358:                                /* legal end of code */
                   2359:                                transit.s = DST_state_NULL;
                   2360:                                break;
                   2361:                            };
                   2362:                        }
                   2363:                else {  /* illegal transition */
                   2364:                        transit.a = DST_action_ERROR;
                   2365:                        transit.s = DST_state_NULL;
                   2366:                        };
                   2367:                };
                   2368:        }
                   2369: 
                   2370: ccitt_err_tbl(t)
                   2371:     DST_table *t;
                   2372: {   int d;
                   2373:        ccitt_err_state(DST_white,t);
                   2374:        ccitt_err_state(DST_black,t);
                   2375:        ccitt_err_state(DST_2d,t);
                   2376:        }
                   2377: 
                   2378: ccitt_err_state(s,t)
                   2379:     DST_state s;
                   2380:     DST_table *t;
                   2381: {      err("%03d %s %2d %2d%*s %d %03d,%-4d  %d %03d,%-4d",
                   2382:                        s,t->e[s].p,t->e[s].l,t->e[s].z,14-strlen(t->e[s].p)," ",
                   2383:                        0,t->e[s].t[0].s,t->e[s].t[0].a,
                   2384:                        1,t->e[s].t[1].s,t->e[s].t[1].a
                   2385:                        );
                   2386:        if(t->e[s].t[0].s>1) ccitt_err_state(t->e[s].t[0].s,t);
                   2387:        if(t->e[s].t[1].s>1) ccitt_err_state(t->e[s].t[1].s,t);
                   2388:        }
                   2389: 
                   2390: /* Translate a stream of bits in CCITT FAX Group 3 (1-D) compression format
                   2391:    into a sequence of RLE_Lines.  Returns one (RLE_Line *) on each call (or NULL
                   2392:    if EOF or error).  The first pixel (black or white) in each g31 line is
                   2393:    assigned run index 0. */
                   2394: RLE_Line *g31_to_rlel(t,f,bof)
                   2395:     DST_table *t;
                   2396:     BITFILE *f;
                   2397:     boolean bof;       /* beginning of file */
                   2398: #define dbg_g31r_r (0) /* trace each run/EOL/ERR_SYN */
                   2399: #define dbg_g31r_c (0) /* trace each Huffman code (or, fill+EOL)*/
                   2400: #define dbg_g31r_t (0) /* trace each state-transition */
                   2401: {   static DST_context cx;
                   2402:     static RLE_Line rl;
                   2403:     static RLE_Run *r; /* prior, current runs */
                   2404:     int run,biti,sync,si,bitv;
                   2405:     boolean fill;
                   2406: /* color of 1st run in each line */
                   2407: #define g31_first_color DST_white
                   2408: /* reverse Black/White in output image */
                   2409: #define g31_negative 0
                   2410:        if(bof){if(T) { /* sync by skipping initial FILL & EOL code */
                   2411:                        sync=0;  while((bitv=getb(f))==0) sync++;
                   2412:                        if(bitv!=1||sync<11) {
                   2413: #if DEBUG
                   2414:                                if(dbg_g31r_c) {
                   2415:                                        fprintf(stderr,"BOF_ERR ");
                   2416:                                        for(si=0;si<sync;si++) fprintf(stderr,"0");
                   2417:                                        if(bitv==1) fprintf(stderr,"1\n");
                   2418:                                        else fprintf(stderr,"?\n");
                   2419:                                        };
                   2420: #endif
                   2421:                                return(NULL);
                   2422:                                }
                   2423: #if DEBUG
                   2424:                        else if(dbg_g31r_c){
                   2425:                                fprintf(stderr,"BOF_EOL ");
                   2426:                                for(si=0;si<sync;si++) fprintf(stderr,"0");
                   2427:                                fprintf(stderr,"1\n");
                   2428:                                };
                   2429: #endif
                   2430:                        };
                   2431:                /* start file expecting a run-code of a fixed color */
                   2432:                cx.s = cx.c = g31_first_color;
                   2433:                rl.y = -1;      /* assume first line is y==0 */
                   2434:                };
                   2435:        rl.y++;  rl.runs=0;  r = rl.r;  biti=run=0;
                   2436:        while(T) switch(getb(f)) {
                   2437:            case 0 :  /* next bit is 0 */
                   2438:                switch(t->e[cx.s].t[0].a) {
                   2439:                    case DST_action_ERROR:
                   2440:                        /* bad code: try to resynchronize */
                   2441: #if DEBUG
                   2442:                        if(dbg_g31r_t){
                   2443:                                fprintf(stderr,"%s %04d  %s0?...\n",
                   2444:                                        (cx.c==DST_white)? "W": "B",
                   2445:                                        t->e[cx.s].t[0].s,
                   2446:                                        t->e[cx.s].p);
                   2447:                                };
                   2448: #endif
                   2449:                        /* count trailing 0's so far (should be in table) */
                   2450: #if !NEW_TRAIL
                   2451:                        sync=1;
                   2452:                        si=strlen(t->e[cx.s].p)-1;
                   2453:                        while(si>=0&&t->e[cx.s].p[si]=='0') {sync++; si--;};
                   2454:                        fill = (si<0);  /* all 0's:  may be fill bits */
                   2455: #else
                   2456:                        sync=t->e[cx.s].z+1;
                   2457:                        fill = (sync>t->e[cx.s].l); /* all 0's:  maybe fill bits */
                   2458: #endif
                   2459: #if DEBUG
                   2460:                        if(dbg_trail) err("sync %d fill %d",sync,fill);
                   2461:                        if(dbg_g31r_c)fprintf(stderr,"ERR_SYN %s0?",t->e[cx.s].p);
                   2462: #endif
                   2463:                        while(sync<11) {
                   2464:                                switch(bitv=getb(f)) {
                   2465:                                        case 0:  sync++;
                   2466: #if DEBUG
                   2467:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                   2468: #endif
                   2469:                                                break;
                   2470:                                        case 1:  sync=0;  fill=F;
                   2471: #if DEBUG
                   2472:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                   2473: #endif
                   2474:                                                break;
                   2475:                                        case EOF:
                   2476: #if DEBUG
                   2477:                                                if(dbg_g31r_c) fprintf(stderr,"<EOF>\n");
                   2478: #endif
                   2479:                                                return(NULL);  break;
                   2480:                                        };
                   2481:                                };
                   2482:                        /* next `1' will synchronize */
                   2483:                        do {    switch(bitv=getb(f)) {
                   2484:                                        case 0:
                   2485: #if DEBUG
                   2486:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                   2487: #endif
                   2488:                                                break;
                   2489:                                        case 1:
                   2490: #if DEBUG
                   2491:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                   2492: #endif
                   2493:                                                break;
                   2494:                                        case EOF:
                   2495: #if DEBUG
                   2496:                                                if(dbg_g31r_c) fprintf(stderr,"<EOF>\n");
                   2497: #endif
                   2498:                                                return(NULL);  break;
                   2499:                                        };
                   2500:                                }
                   2501:                        while(bitv!=1);
                   2502: #if DEBUG
                   2503:                        if(dbg_g31r_c) fprintf(stderr,"\n");
                   2504:                        if(dbg_g31r_r) {
                   2505:                                if(fill) fprintf(stderr,"FILL_EOL\n");
                   2506:                                else fprintf(stderr,"ERR_SYN_EOL\n");
                   2507:                                };
                   2508: #endif
                   2509:                        /* start next line expecting a run-code of a fixed color */
                   2510:                        cx.s = cx.c = g31_first_color;
                   2511:                        return(&rl);
                   2512:                        break;
                   2513:                    case DST_action_NULL:
                   2514: #if DEBUG
                   2515:                        if(dbg_g31r_t)fprintf(stderr,"%s %04d  %s0\n",
                   2516:                                (cx.c==DST_white)? "W": "B",
                   2517:                                t->e[cx.s].t[0].s,
                   2518:                                t->e[cx.s].p);
                   2519: #endif
                   2520:                        cx.s = t->e[cx.s].t[0].s;
                   2521:                        break;
                   2522:                    case DST_EOL:
                   2523: #if DEBUG
                   2524:                        if(dbg_g31r_c)fprintf(stderr,"EOL     %s0\n",
                   2525:                                t->e[cx.s].p);
                   2526:                        if(dbg_g31r_r)fprintf(stderr,"EOL\n");
                   2527: #endif
                   2528:                        /* start next line expecting a run-code of a fixed color */
                   2529:                        cx.s = cx.c = g31_first_color;
                   2530:                        return(&rl);
                   2531:                        break;
                   2532:                    default:
                   2533: #if DEBUG
                   2534:                        if(dbg_g31r_c)fprintf(stderr,"%s%6d %s0\n",
                   2535:                                (cx.c==DST_white)? "W": "B",
                   2536:                                t->e[cx.s].t[0].a,
                   2537:                                t->e[cx.s].p);
                   2538: #endif
                   2539:                        if(t->e[cx.s].t[0].a<=63) {
                   2540:                                run += t->e[cx.s].t[0].a;
                   2541: #if DEBUG
                   2542:                                if(dbg_g31r_r)fprintf(stderr,"%s%6d\n",
                   2543:                                        (cx.c==DST_white)? "W": "B",
                   2544:                                        run);
                   2545: #endif
                   2546:                                biti += run;
                   2547:                                if(cx.c==DST_black^g31_negative) {
                   2548:                                        /* end of black run */
                   2549:                                        r->xe = biti-1;
                   2550:                                        r++; rl.runs++;
                   2551:                                        }
                   2552:                                else {  /* end of white run */
                   2553:                                        r->xs = biti;
                   2554:                                        };
                   2555:                                cx.c = flip_color(cx.c);
                   2556:                                run = 0;
                   2557:                                }
                   2558:                        else run += t->e[cx.s].t[0].a;
                   2559:                        cx.s = t->e[cx.s].t[0].s;
                   2560:                        break;
                   2561:                    };
                   2562:                break;
                   2563:            case 1:  /* next bit is 1 */
                   2564:                switch(t->e[cx.s].t[1].a) {
                   2565:                    case DST_action_ERROR:
                   2566:                        /* bad code: try to resynchronize */
                   2567: #if DEBUG
                   2568:                        if(dbg_g31r_t){
                   2569:                                fprintf(stderr,"%s %04d  %s1?...\n",
                   2570:                                        (cx.c==DST_white)? "W": "B",
                   2571:                                        t->e[cx.s].t[1].s,
                   2572:                                        t->e[cx.s].p);
                   2573:                                };
                   2574:                        if(dbg_g31r_c)fprintf(stderr,"ERR_SYN %s1?",t->e[cx.s].p);
                   2575: #endif
                   2576:                        /* no trailing 0's; can't be fill bits */
                   2577:                        sync=0;
                   2578:                        while(sync<11) {
                   2579:                                switch(bitv=getb(f)) {
                   2580:                                        case 0:  sync++;
                   2581: #if DEBUG
                   2582:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                   2583: #endif
                   2584:                                                break;
                   2585:                                        case 1:  sync=0;
                   2586: #if DEBUG
                   2587:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                   2588: #endif
                   2589:                                                break;
                   2590:                                        case EOF:
                   2591: #if DEBUG
                   2592:                                                if(dbg_g31r_c)
                   2593:                                                        fprintf(stderr,"<EOF>\n");
                   2594: #endif
                   2595:                                                return(NULL);  break;
                   2596:                                        };
                   2597:                                };
                   2598:                        /* next `1' will synchronize */
                   2599:                        do {    switch(bitv=getb(f)) {
                   2600:                                        case 0:
                   2601: #if DEBUG
                   2602:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                   2603: #endif
                   2604:                                                break;
                   2605:                                        case 1:
                   2606: #if DEBUG
                   2607:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                   2608: #endif
                   2609:                                                break;
                   2610:                                        case EOF:
                   2611: #if DEBUG
                   2612:                                                if(dbg_g31r_c)
                   2613:                                                        fprintf(stderr,"<EOF>\n");
                   2614: #endif
                   2615:                                                return(NULL);  break;
                   2616:                                        };
                   2617:                                }
                   2618:                        while(bitv!=1);
                   2619: #if DEBUG
                   2620:                        if(dbg_g31r_c) fprintf(stderr,"\n");
                   2621:                        if(dbg_g31r_r) fprintf(stderr,"ERR_SYN_EOL\n");
                   2622: #endif
                   2623:                        /* start next line expecting a run-code of a fixed color */
                   2624:                        cx.s = cx.c = g31_first_color;
                   2625:                        return(&rl);
                   2626:                        break;
                   2627:                    case DST_action_NULL:
                   2628: #if DEBUG
                   2629:                        if(dbg_g31r_t)fprintf(stderr,"%s %04d  %s1\n",
                   2630:                                (cx.c==DST_white)? "W": "B",
                   2631:                                t->e[cx.s].t[1].s,
                   2632:                                t->e[cx.s].p);
                   2633: #endif
                   2634:                        cx.s = t->e[cx.s].t[1].s;
                   2635:                        break;
                   2636:                    case DST_EOL:
                   2637: #if DEBUG
                   2638:                        if(dbg_g31r_c)fprintf(stderr,"EOL     %s1\n",
                   2639:                                t->e[cx.s].p);
                   2640:                        if(dbg_g31r_r)fprintf(stderr,"EOL\n");
                   2641: #endif
                   2642:                        /* start next line expecting a run-code of a fixed color */
                   2643:                        cx.s = cx.c = g31_first_color;
                   2644:                        return(&rl);
                   2645:                        break;
                   2646:                    default:
                   2647: #if DEBUG
                   2648:                        if(dbg_g31r_c)fprintf(stderr,"%s%6d %s1\n",
                   2649:                                (cx.c==DST_white)? "W": "B",
                   2650:                                t->e[cx.s].t[1].a,
                   2651:                                t->e[cx.s].p);
                   2652: #endif
                   2653:                        if(t->e[cx.s].t[1].a<=63) {
                   2654:                                run += t->e[cx.s].t[1].a;
                   2655: #if DEBUG
                   2656:                                if(dbg_g31r_r)fprintf(stderr,"%s%6d\n",
                   2657:                                        (cx.c==DST_white)? "W": "B",
                   2658:                                        run);
                   2659: #endif
                   2660:                                biti += run;
                   2661:                                if(cx.c==DST_black^g31_negative) {
                   2662:                                        /* end of black run */
                   2663:                                        r->xe = biti-1;
                   2664:                                        r++; rl.runs++;
                   2665:                                        }
                   2666:                                else {  /* end of white run */
                   2667:                                        r->xs = biti;
                   2668:                                        };
                   2669:                                cx.c = flip_color(cx.c);
                   2670:                                run = 0;
                   2671:                                }
                   2672:                        else run += t->e[cx.s].t[1].a;
                   2673:                        cx.s = t->e[cx.s].t[1].s;
                   2674:                        break;
                   2675:                    };
                   2676:                break;
                   2677:            case EOF:
                   2678:                return(NULL);
                   2679:                break;
                   2680:            default:
                   2681:                return(NULL);
                   2682:                break;
                   2683:            };
                   2684:        /* never come here:  return() variously from cases above */
                   2685:        }
                   2686: 
                   2687: /* Translate a sequence of RLE_Line's (describing a binary image)
                   2688:    into a file (a stream of bits) in CCITT FAX Group 3 (1-D) compression format.
                   2689:    BOF_to_g31() must be called first; then call rlel_to_g31() for each line
                   2690:    (including blank lines); finally, EOF_to_g31() must be called.  Each line's
                   2691:    EOL and the RTC's first EOL are padded so they end on a byte boundary.
                   2692:    */
                   2693: /* debugging flags:  trace to stderr */
                   2694: #define dbg_rg31_e (0) /* entry */
                   2695: #define dbg_rg31_r (0) /* runs */
                   2696: #define dbg_rg31_s (0) /* bitstrings */
                   2697: 
                   2698: #if DEBUG
                   2699: #define bits_g31(bits) { \
                   2700:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   2701:        if(dbg_rg31_s) fprintf(stderr,"%s",(bits)); \
                   2702:        if(dbg_rg31_r) fprintf(stderr," "); \
                   2703:        }
                   2704: #define EOL_g31 { \
                   2705:        if(dbg_rg31_r) fprintf(stderr,"EOL     "); \
                   2706:        bits_g31(EOLSTRING); \
                   2707:        if(dbg_rg31_r) fprintf(stderr,"\n"); \
                   2708:        }
                   2709: #else
                   2710: #define bits_g31(bits) { \
                   2711:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   2712:        }
                   2713: #define EOL_g31 { \
                   2714:        bits_g31(EOLSTRING); \
                   2715:        }
                   2716: #endif
                   2717: 
                   2718: BOF_to_g31(f)
                   2719:     BITFILE *f;        /* state of output bitfile */
                   2720: {   char *cs;
                   2721:        EOL_g31;
                   2722:        }
                   2723: 
                   2724: rlel_to_g31(rl,wid,f)
                   2725:     RLE_Line *rl;      /* line of runs:  if NULL, then blank */
                   2726:     int wid;           /* width of an output line in pixels */
                   2727:     BITFILE *f;                /* state of output bitfile */
                   2728: {   int pi;            /* input pixel index on line */
                   2729:     RLE_Run *rp,*pp,*sp;
                   2730:     int runl,codi;
                   2731:     char *cs,*p01;
                   2732: #if DEBUG
                   2733: #define Wrun_g31(rn) { \
                   2734:        runl=(rn); \
                   2735:        if(dbg_rg31_r) fprintf(stderr,"W %5d ",runl); \
                   2736:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                   2737:        p01=codewht[codi=rtoi(runl)]; bits_g31(p01); \
                   2738:        if(codi>=64) {p01=codewht[runl%64]; bits_g31(p01);}; \
                   2739:        if(dbg_rg31_r) fprintf(stderr,"\n"); \
                   2740:        }
                   2741: #else
                   2742: #define Wrun_g31(rn) { \
                   2743:        runl=(rn); \
                   2744:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                   2745:        p01=codewht[codi=rtoi(runl)]; bits_g31(p01); \
                   2746:        if(codi>=64) {p01=codewht[runl%64]; bits_g31(p01);}; \
                   2747:        }
                   2748: #endif
                   2749: #if DEBUG
                   2750: #define Brun_g31(rn) { \
                   2751:        runl=(rn); \
                   2752:        if(dbg_rg31_r) fprintf(stderr,"B %5d ",runl); \
                   2753:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                   2754:        p01=codeblk[codi=rtoi(runl)]; bits_g31(p01); \
                   2755:        if(codi>=64) {p01=codeblk[runl%64]; bits_g31(p01);}; \
                   2756:        if(dbg_rg31_r) fprintf(stderr,"\n"); \
                   2757:        }
                   2758: 
                   2759: #else
                   2760: #define Brun_g31(rn) { \
                   2761:        runl=(rn); \
                   2762:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                   2763:        p01=codeblk[codi=rtoi(runl)]; bits_g31(p01); \
                   2764:        if(codi>=64) {p01=codeblk[runl%64]; bits_g31(p01);}; \
                   2765:        }
                   2766: #endif
                   2767: #if DEBUG
                   2768:        if(dbg_rg31_e) err("rlel_to_g31(rl[y%d,r%d])",rl->y,rl->runs);
                   2769: #endif
                   2770:        if(rl!=NULL&&rl->runs>0) {
                   2771:                pi=0;   /* bit to write next */
                   2772: #if DEBUG
                   2773:                if(dbg_rg31_e) err("rlel_to_g31(rl[y%d,r%d])",rl->y,rl->runs);
                   2774: #endif
                   2775:                for(sp=(rp=rl->r)+rl->runs; rp<sp; rp++) {
                   2776:                        Wrun_g31(rp->xs-pi);  pi=rp->xs;
                   2777:                        Brun_g31(rp->xe-pi+1);  pi=rp->xe+1;
                   2778:                        };
                   2779:                if((--rp)->xe+1<wid) Wrun_g31(wid-rp->xe-1);
                   2780:                }
                   2781:        else {  
                   2782: #if DEBUG
                   2783:                if(dbg_rg31_e) err("rlel_to_g31(rl[y?,r0])");
                   2784: #endif
                   2785:                Wrun_g31(wid);  /* blank (all-white) scanline */
                   2786:                };
                   2787:        /* fill so that EOL ends on byte boundary */
                   2788:        padb(f,0,8,EOLLENGTH);
                   2789: #if DEBUG
                   2790:        if(dbg_rg31_s) fprintf(stderr,"+0?");
                   2791: #endif
                   2792:        EOL_g31;
                   2793:        }
                   2794: 
                   2795: EOF_to_g31(f)
                   2796:     BITFILE *f;
                   2797: {   char *cs;
                   2798:        /* fill so that EOL ends on byte boundary */
                   2799:        padb(f,0,8,EOLLENGTH);
                   2800: #if DEBUG
                   2801:        if(dbg_rg31_s) fprintf(stderr,"+0?");
                   2802: #endif
                   2803:        /* write RTC */
                   2804:        EOL_g31;
                   2805:        EOL_g31;
                   2806:        EOL_g31;
                   2807:        EOL_g31;
                   2808:        EOL_g31;
                   2809:        EOL_g31;
                   2810:        }
                   2811: 
                   2812: /* Macro for use within g32_to_rlel, to read one 1-D Modified Huffman coded
                   2813:    run-length of a given color, placing the result in a given variable.
                   2814:    Exceptionally, goto trap_eol, trap_eof, or trap_code_err.
                   2815:   */
                   2816: #if DEBUG
                   2817: #define g32_1d_run(C,V) { \
                   2818:        run = 0; \
                   2819:        do {    cx.tr.s = (C); \
                   2820:                do {    px = cx; \
                   2821:                        switch(bitv=getb(f)) { \
                   2822:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                   2823:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                   2824:                            case EOF :  goto trap_eof;  break; \
                   2825:                            }; \
                   2826:                        } \
                   2827:                while(cx.tr.a==DST_action_NULL); \
                   2828:                switch(cx.tr.a) { \
                   2829:                    case DST_EOL : \
                   2830:                        if(dbg_g32r_c)fprintf(stderr,"EOL     %s\n",EOLSTRING); \
                   2831:                        goto trap_eol; \
                   2832:                        break; \
                   2833:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                   2834:                    default : \
                   2835:                        if(dbg_g32r_c)fprintf(stderr,"%s%6d %s%d\n", \
                   2836:                                ((C)==DST_white)? "W": "B", \
                   2837:                                cx.tr.a, \
                   2838:                                t->e[px.tr.s].p, \
                   2839:                                bitv); \
                   2840:                        run += cx.tr.a; \
                   2841:                        break; \
                   2842:                    }; \
                   2843:                } \
                   2844:        while(cx.tr.a>63); \
                   2845:        (V) = run; \
                   2846:        }
                   2847: #else
                   2848: #define g32_1d_run(C,V) { \
                   2849:        run = 0; \
                   2850:        do {    cx.tr.s = (C); \
                   2851:                do {    px = cx; \
                   2852:                        switch(bitv=getb(f)) { \
                   2853:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                   2854:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                   2855:                            case EOF :  goto trap_eof;  break; \
                   2856:                            }; \
                   2857:                        } \
                   2858:                while(cx.tr.a==DST_action_NULL); \
                   2859:                switch(cx.tr.a) { \
                   2860:                    case DST_EOL : \
                   2861:                        goto trap_eol; \
                   2862:                        break; \
                   2863:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                   2864:                    default : \
                   2865:                        run += cx.tr.a; \
                   2866:                        break; \
                   2867:                    }; \
                   2868:                } \
                   2869:        while(cx.tr.a>63); \
                   2870:        (V) = run; \
                   2871:        }
                   2872: #endif
                   2873: 
                   2874: /* Translate a stream of bits in CCITT FAX Group 3 (2-D) compression format
                   2875:    into a sequence of RLE_Lines.  Returns one (RLE_Line *) on each call (or NULL
                   2876:    if EOF or error).  The first pixel (black or white) in each g32 line is
                   2877:    assigned run index 0. */
                   2878: RLE_Line *g32_to_rlel(t,f,bof)
                   2879:     DST_table *t;
                   2880:     BITFILE *f;
                   2881:     boolean bof;       /* beginning of file */
                   2882: #define dbg_g32r_e (0) /* entry/exit */
                   2883: #define dbg_g32r_r (0) /* trace each run/EOL/ERR_SYN */
                   2884: #define dbg_g32r_c (0) /* trace each Huffman code (or, fill+EOL)*/
                   2885: #define dbg_g32r_t (0) /* trace each state-transition */
                   2886: #define g32r_strict (1)        /* 1 is CORRECT: explicitly code the last black pel */
                   2887: {   static RLE_Line rl0,rl1,*prl,*crl; /* prior, current run-lines */
                   2888:     RLE_Line *swrl;
                   2889:     int bitv;          /* the last-read bit value */
                   2890:     DST_context cx,px; /* the current/prior decoding context */
                   2891:     RLE_Run *cr,*pr,*pre;      /* into current/prior rle lines */      
                   2892:     RLE_Run *pra0;     /* rightmost in prior line with xe<=a0 (if none: prl->r) */
                   2893:     int run,sync,si,rtc_eols;
                   2894:     boolean fill;
                   2895:     /* pixel indices (0,1,...):  current-line a*; prior-line b*.
                   2896:        a0 is the index of the most recently completely encoded bit */
                   2897:     int a0,a1,a2,b1,b2;        
                   2898:     DST_color a0_color;  /* a0's color:  same as a2 & b2, opposite of a1 & b1 */
                   2899:     int a01,a12;        /* lengths of runs a0-a1 & a1-a2 */
                   2900: #define g32_first_color DST_white      /* color of 1st run in each line */
                   2901: #define g32_negative (0)       /* if 1, invert Black/White on output */
                   2902: #define swap_rl(f,b) {swrl=(f); (f)=(b); (b)=swrl;}
                   2903: /* detect b1 & b2:  sensitive to a0, a0_color, and prior runs *pr *(pr+1) */
                   2904: #define g32r_find_Bb1Wb2 { \
                   2905:        /* find 1st black changing pel>a0 */ \
                   2906:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                   2907:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                   2908:        /* look beyond pra0 */ \
                   2909:        pr=pra0;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                   2910:        /* move b2 to 1st changing white pel > b1 */ \
                   2911:        if(pr<pre) b2=pr->xe+1; \
                   2912:        else b1=b2=prl->len; \
                   2913:        }
                   2914: #define g32r_find_Wb1Bb2 { \
                   2915:        /* find 1st white changing pel>a0 */ \
                   2916:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                   2917:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                   2918:        /* look beyond pra0 */ \
                   2919:        pr=pra0;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                   2920:        /* move b2 to 1st changing black pel > b1 */ \
                   2921:        if(pr<pre) { \
                   2922:                if((pr+1)<pre) b2=(pr+1)->xs; \
                   2923:                else b2=prl->len; \
                   2924:                } \
                   2925:        else b1=b2=prl->len; \
                   2926:        }
                   2927: #define g32r_find_b1b2 {if(a0_color==DST_white) g32r_find_Bb1Wb2 else g32r_find_Wb1Bb2;}
                   2928: 
                   2929: #if DEBUG
                   2930: if(dbg_g32r_e) fprintf(stderr,"g32_to_rlel(t,bf,bof%d)\n",bof);
                   2931: #endif
                   2932: if(bof){crl= &rl0;  crl->y= -1;  crl->len=0;  crl->runs=0;
                   2933:        prl= &rl1;  prl->y= -1;  prl->len=0;  prl->runs=0;
                   2934:        /* sync by skipping initial FILL & EOL code */
                   2935:        sync=0;  while((bitv=getb(f))==0) sync++;
                   2936:        if(bitv!=1||sync<11) {
                   2937: #if DEBUG
                   2938:                if(dbg_g32r_c) {
                   2939:                        fprintf(stderr,"BOF_ERR ");
                   2940:                        for(si=0;si<sync;si++) fprintf(stderr,"0");
                   2941:                        if(bitv==1) fprintf(stderr,"1\n");
                   2942:                        else fprintf(stderr,"?\n");
                   2943:                        };
                   2944: #endif
                   2945:                return(NULL);
                   2946:                }
                   2947: #if DEBUG
                   2948:        else if(dbg_g32r_c){
                   2949:                fprintf(stderr,"BOF_EOL ");
                   2950:                for(si=0;si<sync;si++) fprintf(stderr,"0");
                   2951:                fprintf(stderr,"1\n");
                   2952:                };
                   2953: #else
                   2954:                ;
                   2955: #endif
                   2956:        prl->y = -1;  crl->y = 0;
                   2957:        }
                   2958: else crl->y = prl->y + 1;
                   2959: 
                   2960: pre = (pra0=pr=prl->r) + prl->runs;    /* prior line */
                   2961: crl->runs=0;  cr=crl->r-1;             /* current line */
                   2962: /* start on an imaginary white pixel just to left of margin */
                   2963: a0= -1;  a0_color = DST_white; 
                   2964: 
                   2965: /* check 1-D / 2-D bit immediately after prior EOL */
                   2966: switch(bitv=getb(f)) {
                   2967:     case 0 :  /* 2-dimensionally encoded line */
                   2968: #if DEBUG
                   2969:        if(dbg_g32r_c) fprintf(stderr,"2D_LINE 0\n");
                   2970: #endif
                   2971:        /* start b1/b2 on prior line's first black pixel, etc;
                   2972:           if none, then place off end of line */
                   2973:        if(pr<pre) {b1=pr->xs; b2=pr->xe+1;} else b1=b2=prl->len;
                   2974:        /* parse a sequence of 2D codes... */
                   2975:        while(T/* exited only via goto trap_* and return */) {
                   2976:                cx.tr.s = DST_2d;  cx.tr.a = DST_action_NULL;
                   2977: #if DEBUG
                   2978:                if(dbg_g32r_t)fprintf(stderr,"(%d,%d)\n",cx.tr.s,cx.tr.a);
                   2979: #endif
                   2980:                do {    switch(bitv=getb(f)) {
                   2981:                            case 0 :
                   2982:                            case 1 :
                   2983:                                cx.tr=t->e[cx.tr.s].t[bitv];
                   2984:                                break;
                   2985:                            case EOF:  goto trap_eof;  break;
                   2986:                            };
                   2987: #if DEBUG
                   2988:                        if(dbg_g32r_t)fprintf(stderr,"%d->(%d,%d)\n",
                   2989:                                        bitv,cx.tr.s,cx.tr.a);
                   2990: #endif
                   2991:                        }
                   2992:                while(cx.tr.a==DST_action_NULL);
                   2993: #if DEBUG
                   2994:                if(dbg_g32r_t)fprintf(stderr,"%s %04d  %s0\n",
                   2995:                        (cx.c==DST_white)? "W": "B",
                   2996:                        cx.tr.s,
                   2997:                        t->e[cx.tr.s].p);
                   2998: #endif
                   2999:                switch(cx.tr.a) {
                   3000:                    case i2D_V0:
                   3001: #if DEBUG
                   3002:                        if(dbg_g32r_c)
                   3003:                                fprintf(stderr,"V0      %s\n",code2d[cx.tr.a]);
                   3004: #endif
                   3005:                        a1=b1;
                   3006:                        /* encode a0 to a1-1 */
                   3007:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3008:                        /* move a0 to a1 */
                   3009:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3010:                        a0_color = flip_color(a0_color);
                   3011:                        /* encode a0 */
                   3012:                        if(a0_color==DST_black)
                   3013:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                   3014: #if g32r_strict
                   3015:                        if(a0==prl->len-1)
                   3016:                                { a0++;  goto trap_expecting_eol; };
                   3017: #endif
                   3018:                        g32r_find_b1b2;
                   3019:                        break;
                   3020:                    case i2D_VR1:
                   3021: #if DEBUG
                   3022:                        if(dbg_g32r_c)
                   3023:                                fprintf(stderr,"VR1     %s\n",code2d[cx.tr.a]);
                   3024: #endif
                   3025:                        a1=b1+1;
                   3026:                        /* encode a0 to a1-1 */
                   3027:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3028:                        /* move a0 to a1 */
                   3029:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3030:                        a0_color = flip_color(a0_color);
                   3031:                        /* encode a0 */
                   3032:                        if(a0_color==DST_black)
                   3033:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                   3034: #if !g32r_strict
                   3035:                        if(a0==prl->len-1)
                   3036:                                { a0++;  goto trap_expecting_eol; };
                   3037: #endif
                   3038:                        g32r_find_b1b2;
                   3039:                        break;
                   3040:                    case i2D_VR2:
                   3041: #if DEBUG
                   3042:                        if(dbg_g32r_c)
                   3043:                                fprintf(stderr,"VR2     %s\n",code2d[cx.tr.a]);
                   3044: #endif
                   3045:                        a1=b1+2;
                   3046:                        /* encode a0 to a1-1 */
                   3047:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3048:                        /* move a0 to a1 */
                   3049:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3050:                        a0_color = flip_color(a0_color);
                   3051:                        /* encode a0 */
                   3052:                        if(a0_color==DST_black)
                   3053:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                   3054: #if !g32r_strict
                   3055:                        if(a0==prl->len-1)
                   3056:                                { a0++;  goto trap_expecting_eol; };
                   3057: #endif
                   3058:                        g32r_find_b1b2;
                   3059:                        break;
                   3060:                    case i2D_VR3:
                   3061: #if DEBUG
                   3062:                        if(dbg_g32r_c)
                   3063:                                fprintf(stderr,"VR3     %s\n",code2d[cx.tr.a]);
                   3064: #endif
                   3065:                        a1=b1+3;
                   3066:                        /* encode a0 to a1-1 */
                   3067:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3068:                        /* move a0 to a1 */
                   3069:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3070:                        a0_color = flip_color(a0_color);
                   3071:                        /* encode a0 */
                   3072:                        if(a0_color==DST_black)
                   3073:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                   3074: #if !g32r_strict
                   3075:                        if(a0==prl->len-1)
                   3076:                                { a0++;  goto trap_expecting_eol; };
                   3077: #endif
                   3078:                        g32r_find_b1b2;
                   3079:                        break;
                   3080:                    case i2D_VL1:
                   3081: #if DEBUG
                   3082:                        if(dbg_g32r_c)
                   3083:                                fprintf(stderr,"VL1     %s\n",code2d[cx.tr.a]);
                   3084: #endif
                   3085:                        if((a1=b1-1)<0) err("g32_to_rlel: VL1 backs up to %d",a1);
                   3086:                        /* encode a0 to a1-1 */
                   3087:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3088:                        /* move a0 to a1 */
                   3089:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3090:                        a0_color = flip_color(a0_color);
                   3091:                        /* encode a0 */
                   3092:                        if(a0_color==DST_black)
                   3093:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                   3094: #if !g32_strict
                   3095:                        if(a0==prl->len-1)
                   3096:                                { a0++;  goto trap_expecting_eol; };
                   3097: #endif
                   3098:                        g32r_find_b1b2;
                   3099:                        break;
                   3100:                    case i2D_VL2:
                   3101: #if DEBUG
                   3102:                        if(dbg_g32r_c)
                   3103:                                fprintf(stderr,"VL2     %s\n",code2d[cx.tr.a]);
                   3104: #endif
                   3105:                        if((a1=b1-2)<0) err("g32_to_rlel: VL2 backs up to %d",a1);
                   3106:                        /* encode a0 to a1-1 */
                   3107:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3108:                        /* move a0 to a1 */
                   3109:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3110:                        a0_color = flip_color(a0_color);
                   3111:                        /* encode a0 */
                   3112:                        if(a0_color==DST_black)
                   3113:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                   3114: #if !g32r_strict
                   3115:                        if(a0==prl->len-1)
                   3116:                                { a0++;  goto trap_expecting_eol; };
                   3117: #endif
                   3118:                        g32r_find_b1b2;
                   3119:                        break;
                   3120:                    case i2D_VL3:
                   3121: #if DEBUG
                   3122:                        if(dbg_g32r_c)
                   3123:                                fprintf(stderr,"VL3     %s\n",code2d[cx.tr.a]);
                   3124: #endif
                   3125:                        if((a1=b1-3)<0) err("g32_to_rlel: VL3 backs up to %d",a1);
                   3126:                        /* encode a0 to a1-1 */
                   3127:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3128:                        /* move a0 to a1 */
                   3129:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3130:                        a0_color = flip_color(a0_color);
                   3131:                        /* encode a0 */
                   3132:                        if(a0_color==DST_black)
                   3133:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                   3134: #if !g32r_strict
                   3135:                        if(a0==prl->len-1)
                   3136:                                { a0++;  goto trap_expecting_eol; };
                   3137: #endif
                   3138:                        g32r_find_b1b2;
                   3139:                        break;
                   3140:                    case i2D_PASS:
                   3141: #if DEBUG
                   3142:                        if(dbg_g32r_c)
                   3143:                                fprintf(stderr,"PASS    %s\n",code2d[cx.tr.a]);
                   3144: #endif
                   3145:                        /* move a0 to b2; no change of color */
                   3146:                        a0=b2;  if(a0>=prl->len) goto trap_expecting_eol;
                   3147:                        if(a0_color==DST_black) cr->xe = a0;
                   3148: #if !g32r_strict
                   3149:                        if(a0==prl->len-1)
                   3150:                                { a0++;  goto trap_expecting_eol; };
                   3151: #endif
                   3152:                        g32r_find_b1b2;
                   3153:                        break;
                   3154:                    case i2D_HORIZ:
                   3155: #if DEBUG
                   3156:                        if(dbg_g32r_c)
                   3157:                                fprintf(stderr,"HORIZ   %s\n",code2d[cx.tr.a]);
                   3158: #endif
                   3159:                        if(a0_color==DST_white) {
                   3160:                                if(a0<0) a0=0;  /* first run in line starts at 0 */
                   3161:                                g32_1d_run(DST_white,a01);  a1 = a0 + a01;
                   3162:                                g32_1d_run(DST_black,a12);  a2 = a1 + a12;
                   3163:                                if(a12>0) /* Black run of >0 length */ {
                   3164:                                        crl->runs++;
                   3165:                                        (++cr)->xs = a1;
                   3166:                                        cr->xe = a2-1;
                   3167:                                        };
                   3168:                                a0 = a2;        /* still white */
                   3169:                                if(a0>=prl->len) goto trap_expecting_eol;
                   3170:                                /* encode a0 */
                   3171: #if !g32r_strict
                   3172:                                if(a0==prl->len-1)
                   3173:                                        { a0++;  goto trap_expecting_eol; };
                   3174: #endif
                   3175:                                g32r_find_Bb1Wb2;
                   3176:                                }
                   3177:                        else {  g32_1d_run(DST_black,a01);  a1 = a0 + a01;
                   3178:                                g32_1d_run(DST_white,a12);  a2 = a1 + a12;
                   3179:                                if(a01>0) /* Black run of >0 length */ {
                   3180:                                        cr->xe = a1 - 1;
                   3181:                                        }
                   3182:                                else {  /* 0-length: very peculiar: ignore */
                   3183:                                        fprintf(stderr,
                   3184:                                           "g32_to_rlel: HORIZ B%d! W%d - ignore\n",
                   3185:                                           a01,a12);
                   3186:                                        cr--; crl->runs--;
                   3187:                                        };
                   3188:                                a0 = a2;        /* still black */
                   3189:                                if(a0>=prl->len) goto trap_expecting_eol;
                   3190:                                /* encode a0 */
                   3191:                                crl->runs++;  (++cr)->xs = a0;
                   3192: #if !g32r_strict
                   3193:                                if(a0==prl->len-1) {
                   3194:                                        cr->xe = a0;
                   3195:                                        a0++;
                   3196:                                        goto trap_expecting_eol;
                   3197:                                        };
                   3198: #endif
                   3199:                                g32r_find_Wb1Bb2;
                   3200:                                };
                   3201:                        break;
                   3202:                    case i2D_EOL:
                   3203: #if DEBUG
                   3204:                        if(dbg_g32r_c)
                   3205:                                fprintf(stderr,"EOL     %s\n",code2d[cx.tr.a]);
                   3206: #endif
                   3207:                        goto trap_eol;
                   3208:                        break;
                   3209:                    case DST_action_ERROR:  goto trap_code_err;  break;
                   3210:                    };
                   3211:                };
                   3212:        break;
                   3213:     case 1 :  /* 1-dimensionally encoded line */
                   3214: #if DEBUG
                   3215:        if(dbg_g32r_c) fprintf(stderr,"1D_LINE 1\n");
                   3216: #endif
                   3217:        /* read a sequence of 1-D runcodes... */
                   3218:        while(T/* exit only via goto trap_X */) {
                   3219:                g32_1d_run(a0_color,a01);
                   3220:                a1 = ((a0>=0)? a0 : 0) + a01;
                   3221:                if(a01>0) {
                   3222:                        /* encode a0 through a1-1 */
                   3223:                        if(a0_color==DST_black^g32_negative) {
                   3224:                                /* output-black run */
                   3225:                                crl->runs++;
                   3226:                                (++cr)->xs=((a0>=0)? a0 : 0);
                   3227:                                cr->xe=a1-1;
                   3228:                                };
                   3229:                        };
                   3230:                a0=a1;
                   3231:                a0_color=flip_color(a0_color);
                   3232:                if(prl->len>0 && a0>=prl->len) goto trap_expecting_eol;
                   3233:                };
                   3234:        break;
                   3235:     case EOF :  goto trap_eof;  break;
                   3236:     };
                   3237: 
                   3238: /* come here via goto's: all these traps return() */
                   3239: 
                   3240: trap_expecting_eol:    /* come here expecting to see EOL or FILL+EOL */
                   3241:        sync=0;  while((bitv=getb(f))==0) sync++;
                   3242:        switch(bitv) {
                   3243:            case 1:
                   3244:                if(sync==11) {
                   3245: #if DEBUG
                   3246:                        if(dbg_g32r_c){
                   3247:                                fprintf(stderr,"EOL     %s\n",EOLSTRING);
                   3248:                                };
                   3249: #endif
                   3250:                        goto trap_eol;
                   3251:                        }
                   3252:                else if(sync>11) {
                   3253: #if DEBUG
                   3254:                        if(dbg_g32r_c){
                   3255:                                fprintf(stderr,"FILLEOL ");
                   3256:                                for(si=0;si<sync-11;si++) fprintf(stderr,"0");
                   3257:                                fprintf(stderr,"+");
                   3258:                                fprintf(stderr,"%s\n",EOLSTRING);
                   3259:                                };
                   3260: #endif
                   3261:                        goto trap_eol;
                   3262:                        }
                   3263:                else {  
                   3264: #if DEBUG
                   3265:                        if(dbg_g32r_c){
                   3266:                                fprintf(stderr,"NOT EOL ");
                   3267:                                for(si=0;si<sync;si++) fprintf(stderr,"0");
                   3268:                                fprintf(stderr,"1?");
                   3269:                                };
                   3270: #endif
                   3271:                        sync=0;
                   3272:                        goto trap_eol_err;
                   3273:                        };
                   3274:                break;
                   3275:            case EOF:  goto trap_eof;  break;
                   3276:            };
                   3277:        goto trap_eol;
                   3278: 
                   3279: trap_code_err:
                   3280:        /* unexpected coding sequence:
                   3281:           'px' holds last decoding context & 'bitv' latest bit value;
                   3282:           will attempt to resynchronize on next EOL */
                   3283: #if DEBUG
                   3284:        if(dbg_g32r_c)fprintf(stderr,"CODERR  %s%d?",
                   3285:                                t->e[px.tr.s].p,bitv);
                   3286: #endif
                   3287:        /* count trailing 0's so far (should be in table) */
                   3288: #if !NEW_TRAIL
                   3289:        if(bitv==0) sync=1; else sync=0;
                   3290:        si=strlen(t->e[px.tr.s].p)-1;
                   3291:        while(si>=0&&t->e[px.tr.s].p[si]=='0') {sync++; si--;};
                   3292:        fill = (si<0);  /* all 0's:  may be fill bits */
                   3293: #else
                   3294:        if(bitv==0) sync=t->e[px.tr.s].z+1; else sync=t->e[px.tr.s].z;
                   3295:        fill = (sync>t->e[px.tr.s].l); /* all 0's:  maybe fill bits */
                   3296: #endif 
                   3297: #if DEBUG
                   3298:        if(dbg_trail)err("sync %d fill %d",sync,fill);
                   3299: #endif
                   3300: trap_eol_err:
                   3301:        while(sync<11) {
                   3302:                switch(bitv=getb(f)) {
                   3303:                        case 0:  sync++;
                   3304: #if DEBUG
                   3305:                                if(dbg_g32r_c) fprintf(stderr,"0");
                   3306: #endif
                   3307:                                break;
                   3308:                        case 1:  sync=0;
                   3309: #if DEBUG
                   3310:                                if(dbg_g32r_c) fprintf(stderr,"1");
                   3311: #endif
                   3312:                                break;
                   3313:                        case EOF:  goto trap_eof;  break;
                   3314:                        };
                   3315:                };
                   3316:        /* next `1' will synchronize */
                   3317:        do {    switch(bitv=getb(f)) {
                   3318:                        case 0:
                   3319: #if DEBUG
                   3320:                                if(dbg_g32r_c) fprintf(stderr,"0");
                   3321: #endif
                   3322:                                break;
                   3323:                        case 1:
                   3324: #if DEBUG
                   3325:                                if(dbg_g32r_c) fprintf(stderr,"1");
                   3326: #endif
                   3327:                                break;
                   3328:                        case EOF:  goto trap_eof;  break;
                   3329:                        };
                   3330:                }
                   3331:        while(bitv!=1);
                   3332: #if DEBUG
                   3333:        if(dbg_g32r_c) fprintf(stderr," EOL\n");
                   3334: #endif
                   3335:        goto trap_eol;
                   3336: 
                   3337: trap_eol:      /* come here having seen (and reported) EOL */
                   3338:        /* learn/check line-length */
                   3339:        if(a0>=0) crl->len=a0; else crl->len=0;
                   3340:        if(crl->len==0) {
                   3341:                /* no pixels coded -- may be the 1st of 6 RTC EOLs */
                   3342:                /* check suffix 1 bit */
                   3343:                if((bitv=getb(f))!=1) goto trap_eol_err;
                   3344:                rtc_eols=1;
                   3345: #if DEBUG
                   3346:                if(dbg_g32r_c)fprintf(stderr,"RTC_EOL +1 (%d)\n",rtc_eols);
                   3347: #endif
                   3348:                do {    sync=0;  while((bitv=getb(f))==0) sync++;
                   3349:                        switch(bitv) {
                   3350:                            case 1:
                   3351:                                if(sync<11) {
                   3352: #if DEBUG
                   3353:                                        if(dbg_g32r_c){
                   3354:                                                fprintf(stderr,"NOT RTC ");
                   3355:                                                for(si=0;si<sync;si++)
                   3356:                                                        fprintf(stderr,"0");
                   3357:                                                fprintf(stderr,"1?\n");
                   3358:                                                };
                   3359: #endif
                   3360:                                        sync=0;
                   3361:                                        goto trap_eol_err;
                   3362:                                        };
                   3363:                                break;
                   3364:                            case EOF:  goto trap_eof;  break;
                   3365:                            };
                   3366:                        /* check suffix 1 bit */
                   3367:                        if((bitv=getb(f))!=1) goto trap_eol_err;
                   3368:                        rtc_eols++;
                   3369: #if DEBUG
                   3370:                        if(dbg_g32r_c) {
                   3371:                                fprintf(stderr,"RTC_EOL ");
                   3372:                                for(si=0;si<sync;si++) fprintf(stderr,"0");
                   3373:                                fprintf(stderr,"1+1  (%d)\n",rtc_eols);
                   3374:                                };
                   3375: #endif
                   3376:                        }
                   3377:                while(rtc_eols<6);
                   3378:                /* normal RTC */
                   3379: #if DEBUG
                   3380:                if(dbg_g32r_c)fprintf(stderr,"RTC\n");
                   3381: #endif
                   3382:                return(NULL);
                   3383:                }
                   3384:        else if(prl->len==0) {
                   3385: #if DEBUG
                   3386:                if(dbg_g32r_c)fprintf(stderr,"LINELEN %d\n",crl->len);
                   3387: #endif
                   3388:                }
                   3389:        else if(crl->len!=prl->len) {
                   3390:                err("g32_to_rlel: y%d: LINELEN changes c%d != p%d ? (force to %d)",
                   3391:                        crl->y,crl->len,prl->len,prl->len);
                   3392:                crl->len = prl->len;
                   3393:                };
                   3394:        swap_rl(crl,prl);
                   3395:        return(prl);
                   3396: 
                   3397: trap_eof:
                   3398: #if DEBUG
                   3399:        if(dbg_g32r_c) fprintf(stderr,"<EOF>\n");
                   3400: #endif
                   3401:        return(NULL);
                   3402: 
                   3403:     }
                   3404: 
                   3405: /* Translate a sequence of RLE_Line's (describing a binary image)
                   3406:    into a file (a stream of bits) in CCITT FAX Group 3 (2-D) compression format.
                   3407:    BOF_to_g32() must be called first;  then call rlel_to_g32() for each line
                   3408:    (including blank lines); finally, EOF_to_g32() must be called.  Each line's
                   3409:    EOL and the RTC's first EOL will be padded so they end on a byte boundary.
                   3410:    */
                   3411: /* debugging flags:  trace to stderr */
                   3412: #define dbg_rg32_e (0) /* entry */
                   3413: #define dbg_rg32_r (0) /* runs */
                   3414: #define dbg_rg32_s (0) /* bitstrings */
                   3415: #define rg32_strict (1)        /* 1 is CORRECT: explicitly code the last black pel */
                   3416: 
                   3417: #if DEBUG
                   3418: #define bits_g32(bits) { \
                   3419:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   3420:        if(dbg_rg32_s) fprintf(stderr,"%s",(bits)); \
                   3421:        if(dbg_rg32_r) fprintf(stderr," "); \
                   3422:        }
                   3423: #else
                   3424: #define bits_g32(bits) { \
                   3425:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   3426:        }
                   3427: #endif
                   3428: #if DEBUG
                   3429: #define EOL_g32 { \
                   3430:        if(dbg_rg32_r) fprintf(stderr,"EOL     "); \
                   3431:        bits_g32(EOLSTRING); \
                   3432:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3433:        }
                   3434: #else
                   3435: #define EOL_g32 { \
                   3436:        bits_g32(EOLSTRING); \
                   3437:        }
                   3438: #endif
                   3439: 
                   3440: BOF_to_g32(f)
                   3441:     BITFILE *f;
                   3442: {   char *cs;
                   3443:        /* a NOP: no header for Group 3 (2-D) */
                   3444: #if DEBUG
                   3445:        if(dbg_rg32_e) fprintf(stderr,"BOF\n");
                   3446: #endif
                   3447:        };
                   3448: 
                   3449: rlel_to_g32(pl,cl,wid,f)
                   3450:     RLE_Line *pl;      /* prior "reference" line: if NULL, use 1-D coding on cl */
                   3451:     RLE_Line *cl;      /* current "coding" line: if NULL, is blank (all white) */
                   3452:     int wid;           /* width of an output line in pixels */
                   3453:     BITFILE *f;
                   3454: {   int runl,codi;
                   3455:     char *cs,*p01;
                   3456: #if DEBUG
                   3457: #define Wrun_g32(rn) { \
                   3458:        runl=(rn); \
                   3459:        if(dbg_rg32_r) fprintf(stderr,"W %5d ",runl); \
                   3460:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   3461:        p01=codewht[codi=rtoi(runl)]; bits_g32(p01); \
                   3462:        if(codi>=64) {p01=codewht[runl%64]; bits_g32(p01);}; \
                   3463:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3464:        }
                   3465: #else
                   3466: #define Wrun_g32(rn) { \
                   3467:        runl=(rn); \
                   3468:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   3469:        p01=codewht[codi=rtoi(runl)]; bits_g32(p01); \
                   3470:        if(codi>=64) {p01=codewht[runl%64]; bits_g32(p01);}; \
                   3471:        }
                   3472: #endif
                   3473: #if DEBUG
                   3474: #define Brun_g32(rn) { \
                   3475:        runl=(rn); \
                   3476:        if(dbg_rg32_r) fprintf(stderr,"B %5d ",runl); \
                   3477:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   3478:        p01=codeblk[codi=rtoi(runl)]; bits_g32(p01); \
                   3479:        if(codi>=64) {p01=codeblk[runl%64]; bits_g32(p01);}; \
                   3480:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3481:        }
                   3482: #else
                   3483: #define Brun_g32(rn) { \
                   3484:        runl=(rn); \
                   3485:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   3486:        p01=codeblk[codi=rtoi(runl)]; bits_g32(p01); \
                   3487:        if(codi>=64) {p01=codeblk[runl%64]; bits_g32(p01);}; \
                   3488:        }
                   3489: #endif
                   3490: #if DEBUG
                   3491: #define V0_g32 { \
                   3492:        if(dbg_rg32_r) fprintf(stderr,"V0      "); \
                   3493:        bits_g32(code2d[i2D_V0]); \
                   3494:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3495:        }
                   3496: #else
                   3497: #define V0_g32 { \
                   3498:        bits_g32(code2d[i2D_V0]); \
                   3499:        }
                   3500: #endif
                   3501: #if DEBUG
                   3502: #define VR1_g32 { \
                   3503:        if(dbg_rg32_r) fprintf(stderr,"VR1     "); \
                   3504:        bits_g32(code2d[i2D_VR1]); \
                   3505:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3506:        }
                   3507: #else
                   3508: #define VR1_g32 { \
                   3509:        bits_g32(code2d[i2D_VR1]); \
                   3510:        }
                   3511: #endif
                   3512: #if DEBUG
                   3513: #define VR2_g32 { \
                   3514:        if(dbg_rg32_r) fprintf(stderr,"VR2     "); \
                   3515:        bits_g32(code2d[i2D_VR2]); \
                   3516:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3517:        }
                   3518: #else
                   3519: #define VR2_g32 { \
                   3520:        bits_g32(code2d[i2D_VR2]); \
                   3521:        }
                   3522: #endif
                   3523: #if DEBUG
                   3524: #define VR3_g32 { \
                   3525:        if(dbg_rg32_r) fprintf(stderr,"VR3     "); \
                   3526:        bits_g32(code2d[i2D_VR3]); \
                   3527:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3528:        }
                   3529: #else
                   3530: #define VR3_g32 { \
                   3531:        bits_g32(code2d[i2D_VR3]); \
                   3532:        }
                   3533: #endif
                   3534: #if DEBUG
                   3535: #define VL1_g32 { \
                   3536:        if(dbg_rg32_r) fprintf(stderr,"VL1     "); \
                   3537:        bits_g32(code2d[i2D_VL1]); \
                   3538:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3539:        }
                   3540: #else
                   3541: #define VL1_g32 { \
                   3542:        bits_g32(code2d[i2D_VL1]); \
                   3543:        }
                   3544: #endif
                   3545: #if DEBUG
                   3546: #define VL2_g32 { \
                   3547:        if(dbg_rg32_r) fprintf(stderr,"VL2     "); \
                   3548:        bits_g32(code2d[i2D_VL2]); \
                   3549:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3550:        }
                   3551: #else
                   3552: #define VL2_g32 { \
                   3553:        bits_g32(code2d[i2D_VL2]); \
                   3554:        }
                   3555: #endif
                   3556: #if DEBUG
                   3557: #define VL3_g32 { \
                   3558:        if(dbg_rg32_r) fprintf(stderr,"VL3     "); \
                   3559:        bits_g32(code2d[i2D_VL3]); \
                   3560:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3561:        }
                   3562: #else
                   3563: #define VL3_g32 { \
                   3564:        bits_g32(code2d[i2D_VL3]); \
                   3565:        }
                   3566: #endif
                   3567: #if DEBUG
                   3568: #define PASS_g32 { \
                   3569:        if(dbg_rg32_r) fprintf(stderr,"PASS    "); \
                   3570:        bits_g32(code2d[i2D_PASS]); \
                   3571:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3572:        }
                   3573: #else
                   3574: #define PASS_g32 { \
                   3575:        bits_g32(code2d[i2D_PASS]); \
                   3576:        }
                   3577: #endif
                   3578: #if DEBUG
                   3579: #define HORIZ_g32 { \
                   3580:        if(dbg_rg32_r) fprintf(stderr,"HORIZ   "); \
                   3581:        bits_g32(code2d[i2D_HORIZ]); \
                   3582:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   3583:        }
                   3584: #else
                   3585: #define HORIZ_g32 { \
                   3586:        bits_g32(code2d[i2D_HORIZ]); \
                   3587:        }
                   3588: #endif
                   3589: #define detect_a1a2_BW { \
                   3590:        /* find leftmost black changing pel > a0 */ \
                   3591:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   3592:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   3593:        /* look beyond cra, until cr->xs>a0 */ \
                   3594:        cr=cra; while(cr<cre && (a1=cr->xs)<=a0) cr++; \
                   3595:        if(cr<cre) a2=cr->xe+1; \
                   3596:        else a1=a2=wid; \
                   3597:        }
                   3598: #define detect_a1a2_WB { \
                   3599:        /* find leftmost white changing pel > a0 */ \
                   3600:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   3601:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   3602:        /* look beyond cra, until cr->xe+1>a0 */ \
                   3603:        cr=cra;  while(cr<cre && (a1=cr->xe+1)<=a0) cr++; \
                   3604:        if(cr<cre) { \
                   3605:                if((cr+1)<cre) a2=(cr+1)->xs; \
                   3606:                else a2=wid; \
                   3607:                } \
                   3608:        else a1=a2=wid; \
                   3609:        }
                   3610: #define detect_a1a2 {if(a0_color==DST_white) detect_a1a2_BW else detect_a1a2_WB;}
                   3611: #define detect_b1b2_BW {\
                   3612:        /* find leftmost black changing pel > a0 */ \
                   3613:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   3614:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   3615:        /* look beyond pra */ \
                   3616:        pr=pra;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                   3617:        /* move b2 to 1st changing white pel > b1 */ \
                   3618:        if(pr<pre) b2=pr->xe+1; \
                   3619:        else b1=b2=wid; \
                   3620:        }
                   3621: #define detect_b1b2_WB {\
                   3622:        /* find leftmost white changing pel > a0 */ \
                   3623:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   3624:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   3625:        /* look beyond pra */ \
                   3626:        pr=pra;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                   3627:        /* move b2 to 1st changing black pel > b1 */ \
                   3628:        if(pr<pre) { \
                   3629:                if((pr+1)<pre) b2=(pr+1)->xs; \
                   3630:                else b2=wid; \
                   3631:                } \
                   3632:        else b1=b2=wid; \
                   3633:        }
                   3634: #define detect_b1b2 {if(a0_color==DST_white) detect_b1b2_BW else detect_b1b2_WB;}
                   3635: 
                   3636: #if DEBUG
                   3637:        if(dbg_rg32_e) err("rlel_to_g32(pl[%d],cl[%d],w%d)",
                   3638:                                (pl==NULL)? -1: pl->runs,
                   3639:                                (cl==NULL)? -1: cl->runs,
                   3640:                                wid);
                   3641: #endif
                   3642:        /* fill so that EOL ends on byte boundary */
                   3643:        padb(f,0,8,EOLLENGTH);
                   3644: #if DEBUG
                   3645:        if(dbg_rg32_s) fprintf(stderr,"FILL  +0?");
                   3646: #endif
                   3647:        EOL_g32;        /* begin with EOL (sic) */
                   3648:        if(pl==NULL) /* use 1-D coding for *cl */ {
                   3649:            int pi;             /* input pixel index on line */
                   3650:            RLE_Run *rp,*pp,*sp;
                   3651:                putb(1,f);
                   3652: #if DEBUG
                   3653:                if(dbg_rg32_r) fprintf(stderr,"1D_LINE 1\n");
                   3654: #endif
                   3655:                if(cl!=NULL&&cl->runs>0) {
                   3656:                        pi=0;   /* bit to write next */
                   3657:                        for(sp=(rp=cl->r)+cl->runs; rp<sp; rp++) {
                   3658:                                Wrun_g32(rp->xs-pi);  pi=rp->xs;
                   3659:                                Brun_g32(rp->xe-pi+1);  pi=rp->xe+1;
                   3660:                                };
                   3661:                        if((--rp)->xe+1<wid) Wrun_g32(wid-rp->xe-1);
                   3662:                        }
                   3663:                else Wrun_g32(wid);  /* blank scanline */
                   3664:                }
                   3665:        else /* use 2-D coding for *cl */ {
                   3666:            RLE_Run *cr,*cre,*pr,*pre;  /* into current/prior rle lines */      
                   3667:            int a0,a1,a2,b1,b2;  /* indices {0,1,...} of pixels */
                   3668:            DST_color a0_color;  /* a0's color:  same as a2 & b2, opp of a1 & b1 */
                   3669:            RLE_Run *cra;   /* rightmost in current st xe<=a0 (none: ==cl->r)  */
                   3670:            RLE_Run *pra;   /* rightmost in prior st xe<=a0 (none: ==pl->r) */
                   3671:            int a01,a12,a1b1;   /* lengths of runs a0-a1 a1-a2 a1-b1 */
                   3672:                putb(0,f);
                   3673: #if DEBUG
                   3674:                if(dbg_rg32_r) fprintf(stderr,"2D_LINE 0\n");
                   3675: #endif
                   3676:                /* start on an imaginary white pixel just to left of margin */
                   3677:                a0= -1;  a0_color = DST_white;  
                   3678:                pre = (pra=pl->r) + pl->runs;   /* prior line's runs */
                   3679:                /* start b1/b2 on prior line's first black pixel, etc;
                   3680:                   if none, then place off end of line */
                   3681:                if(pra<pre) {b1=pra->xs; b2=pra->xe+1;} else b1=b2=wid;
                   3682:                if(cl!=NULL&&cl->runs>0) {
                   3683:                        cre = (cra=cl->r) + cl->runs;
                   3684:                        a1=cra->xs;  a2=cra->xe+1;
                   3685: #if rg32_strict
                   3686:                        while(a0 < wid) {
                   3687: #else
                   3688:                        while(a0 < wid-1) {
                   3689: #endif
                   3690:                                /* a0, a1, a2, b1, b2 are as in CCITT Rec T.4 */
                   3691: #if DEBUG
                   3692:                                if(dbg_rg32_r)
                   3693:                                    fprintf(stderr,"f%d(%d,%d,%d) b%d(%d,%d)\n",
                   3694:                                        cra-(cl->r),a0,a1,a2,pra-(pl->r),b1,b2);
                   3695: #endif
                   3696:                                if(b2<a1) /* PASS mode */ {
                   3697:                                        PASS_g32;
                   3698:                                        a0=b2;
                   3699:                                        /* a0-color, a1, & a2 are unchanged */
                   3700:                                        detect_b1b2;
                   3701:                                        }
                   3702:                                else if((a1b1=(a1-b1))<=3 && a1b1>= -3) {
                   3703:                                        /* VERTICAL mode */
                   3704:                                        switch(a1b1) {
                   3705:                                            case -3:  VL3_g32;  break;
                   3706:                                            case -2:  VL2_g32;  break;
                   3707:                                            case -1:  VL1_g32;  break;
                   3708:                                            case 0:  V0_g32;  break;
                   3709:                                            case 1:  VR1_g32;  break;
                   3710:                                            case 2:  VR2_g32;  break;
                   3711:                                            case 3:  VR3_g32;  break;
                   3712:                                            };
                   3713:                                        a0=a1;  a0_color=flip_color(a0_color);
                   3714:                                        detect_a1a2;
                   3715:                                        detect_b1b2;
                   3716:                                        }
                   3717:                                else {  /* HORIZONTAL mode */
                   3718:                                        HORIZ_g32;
                   3719:                                        a01=a1-a0; if(a0== -1) a01--;
                   3720:                                        a12=a2-a1;
                   3721:                                        if(a0_color==DST_white) {
                   3722:                                                Wrun_g32(a01);
                   3723:                                                Brun_g32(a12);
                   3724:                                                }
                   3725:                                        else {  Brun_g32(a01);
                   3726:                                                Wrun_g32(a12);
                   3727:                                                };
                   3728:                                        a0=a2;
                   3729:                                        /* a0_color is unchanged */
                   3730:                                        detect_a1a2;
                   3731:                                        detect_b1b2;
                   3732:                                        };
                   3733:                                };
                   3734:                        }
                   3735:                else /* current line is blank */ {
                   3736:                        a1=a2=wid;
                   3737: #if rg32_strict
                   3738:                        while(a0 < wid) {
                   3739: #else
                   3740:                        while(a0 < wid-1) {
                   3741: #endif
                   3742:                                /* a0, a1, a2, b1, b2 are as in CCITT Rec. T.4 */
                   3743: #if DEBUG
                   3744:                                if(dbg_rg32_r)
                   3745:                                    fprintf(stderr,"f(%d,%d,%d) b%d(%d,%d)\n",
                   3746:                                        a0,a1,a2,pra-(pl->r),b1,b2);
                   3747: #endif
                   3748:                                if(b2<a1) /* PASS mode */ {
                   3749:                                        PASS_g32;
                   3750:                                        a0=b2;
                   3751:                                        /* a0-color, a1, & a2 are unchanged */
                   3752:                                        detect_b1b2;
                   3753:                                        }
                   3754:                                else if((a1b1=a1-b1)<=3 && a1b1>= -3) {
                   3755:                                        /* VERTICAL mode */
                   3756:                                        switch(a1b1) {
                   3757:                                            case -3:  VL3_g32;  break;
                   3758:                                            case -2:  VL2_g32;  break;
                   3759:                                            case -1:  VL1_g32;  break;
                   3760:                                            case 0:  V0_g32;  break;
                   3761:                                            case 1:  VR1_g32;  break;
                   3762:                                            case 2:  VR2_g32;  break;
                   3763:                                            case 3:  VR3_g32;  break;
                   3764:                                            };
                   3765:                                        a0=a1;  a0_color=flip_color(a0_color);
                   3766:                                        /* a1, & a2 are unchanged */
                   3767:                                        detect_b1b2;
                   3768:                                        }
                   3769:                                else {  /* HORIZONTAL mode */
                   3770:                                        HORIZ_g32;
                   3771:                                        a01=a1-a0; if(a0== -1) a01--;
                   3772:                                        a12=a2-a1;
                   3773:                                        if(a0_color==DST_white) {
                   3774:                                                Wrun_g32(a01);
                   3775:                                                Brun_g32(a12);
                   3776:                                                }
                   3777:                                        else {  Brun_g32(a01);
                   3778:                                                Wrun_g32(a12);
                   3779:                                                };
                   3780:                                        a0=a2;
                   3781:                                        /* a0_color, a1, & a2 are unchanged */
                   3782:                                        detect_b1b2;
                   3783:                                        };
                   3784:                                };
                   3785:                        };
                   3786:                };
                   3787:        }
                   3788: 
                   3789: EOF_to_g32(f)
                   3790:     BITFILE *f;
                   3791: {   char *cs;
                   3792:        padb(f,0,8,EOLLENGTH);  /* fill so that EOL ends on byte boundary */
                   3793: #if DEBUG
                   3794:        if(dbg_rg32_s) fprintf(stderr,"FILL  +0?");
                   3795: #endif
                   3796:        /* write RTC */
                   3797:        EOL_g32;
                   3798:        EOL_g32;
                   3799:        EOL_g32;
                   3800:        EOL_g32;
                   3801:        EOL_g32;
                   3802:        EOL_g32;
                   3803: #if DEBUG
                   3804:        if(dbg_rg32_e) fprintf(stderr,"EOF\n");
                   3805: #endif
                   3806:        }
                   3807: 
                   3808: /* Macro for use within g4_to_rlel, to read one 1-D Modified Huffman coded
                   3809:    run-length of color C, placing the result in variable V.
                   3810:    Exceptionally, goto trap_eol, trap_eof, or trap_code_err.
                   3811:   */
                   3812: #if DEBUG
                   3813: #define g4_1d_run(C,V) { \
                   3814:        run = 0; \
                   3815:        do {    cx.tr.s = (C); \
                   3816:                do {    px = cx; \
                   3817:                        switch(bitv=getb(f)) { \
                   3818:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                   3819:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                   3820:                            case EOF :  goto trap_eof;  break; \
                   3821:                            }; \
                   3822:                        } \
                   3823:                while(cx.tr.a==DST_action_NULL); \
                   3824:                switch(cx.tr.a) { \
                   3825:                    case DST_EOL : \
                   3826:                        if(dbg_g4r_c)fprintf(stderr,"EOL     %s\n",EOLSTRING); \
                   3827:                        goto trap_eol; \
                   3828:                        break; \
                   3829:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                   3830:                    default : \
                   3831:                        if(dbg_g4r_c)fprintf(stderr,"%s%6d %s%d\n", \
                   3832:                                ((C)==DST_white)? "W": "B", \
                   3833:                                cx.tr.a, \
                   3834:                                t->e[px.tr.s].p, \
                   3835:                                bitv); \
                   3836:                        run += cx.tr.a; \
                   3837:                        break; \
                   3838:                    }; \
                   3839:                } \
                   3840:        while(cx.tr.a>63); \
                   3841:        (V) = run; \
                   3842:        }
                   3843: #else
                   3844: #define g4_1d_run(C,V) { \
                   3845:        run = 0; \
                   3846:        do {    cx.tr.s = (C); \
                   3847:                do {    px = cx; \
                   3848:                        switch(bitv=getb(f)) { \
                   3849:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                   3850:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                   3851:                            case EOF :  goto trap_eof;  break; \
                   3852:                            }; \
                   3853:                        } \
                   3854:                while(cx.tr.a==DST_action_NULL); \
                   3855:                switch(cx.tr.a) { \
                   3856:                    case DST_EOL : \
                   3857:                        goto trap_eol; \
                   3858:                        break; \
                   3859:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                   3860:                    default : \
                   3861:                        run += cx.tr.a; \
                   3862:                        break; \
                   3863:                    }; \
                   3864:                } \
                   3865:        while(cx.tr.a>63); \
                   3866:        (V) = run; \
                   3867:        }
                   3868: #endif
                   3869: 
                   3870: /* Translate a stream of bits in CCITT FAX Group 4 compression format, of known
                   3871:    fixed line-length, into a sequence of RLE_Lines.  Returns one (RLE_Line *)
                   3872:    on each call (or NULL if EOF or error).  The first pixel (black or white)
                   3873:    in each g4 line is assigned run index 0.
                   3874:    WARNING:  the RLE_Line returned must NOT be modified by the caller, since
                   3875:    it is used to decode the next line. */
                   3876: RLE_Line *g4_to_rlel(t,f,bof,len)
                   3877:     DST_table *t;
                   3878:     BITFILE *f;
                   3879:     boolean bof;       /* beginning of file */
                   3880:     int len;           /* line-length in pixels (used only on bof) */
                   3881: #define dbg_g4r_e (0)  /* trace entry-to / exit-from function */
                   3882: #define dbg_g4r_r (0)  /* trace each run/EOL/ERR_SYN */
                   3883: #define dbg_g4r_c (0)  /* trace each Huffman code (or, fill+EOL)*/
                   3884: #define dbg_g4r_t (0)  /* trace each state-transition */
                   3885: #define g4r_strict (1) /* 1 is CORRECT: explicitly code the last black pel */
                   3886: {   static RLE_Line rl0,rl1,*prl,*crl; /* prior, current run-lines */
                   3887:     RLE_Line *swrl;
                   3888:     int bitv;                  /* the last-read bit value */
                   3889:     DST_context cx,px;         /* the current/prior decoding context */
                   3890:     RLE_Run *cr,*pr,*pre;      /* into current/prior rle lines */      
                   3891:     RLE_Run *pra0;             /* rightmost in prior line with xe<=a0
                   3892:                                   (if none: prl->r) */
                   3893:     int run,sync,si,rtc_eols;
                   3894:     /* pixel indices (0,1,...):  current-line a*; prior-line b*.
                   3895:        a0 is the index of the most recently completely encoded bit */
                   3896:     int a0,a1,a2,b1,b2;        
                   3897:     DST_color a0_color;  /* a0's color:  same as a2 & b2, opposite of a1 & b1 */
                   3898:     int a01,a12;       /* lengths of runs a0-a1 & a1-a2 */
                   3899: #define g4_first_color (DST_white)     /* color of 1st run in each line */
                   3900: #define g4_negative (0)                /* if 1, invert Black/White on output */
                   3901: #define swap_rl(f,b) {swrl=(f); (f)=(b); (b)=swrl;}
                   3902: /* detect b1 & b2:  sensitive to a0, a0_color, and prior runs *pr *(pr+1) */
                   3903: #define g4r_find_Bb1Wb2 { \
                   3904:        /* find 1st black changing pel>a0 */ \
                   3905:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                   3906:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                   3907:        /* look beyond pra0 */ \
                   3908:        pr=pra0;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                   3909:        /* move b2 to 1st changing white pel > b1 */ \
                   3910:        if(pr<pre) b2=pr->xe+1; \
                   3911:        else b1=b2=prl->len; \
                   3912:        }
                   3913: #define g4r_find_Wb1Bb2 { \
                   3914:        /* find 1st white changing pel>a0 */ \
                   3915:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                   3916:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                   3917:        /* look beyond pra0 */ \
                   3918:        pr=pra0;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                   3919:        /* move b2 to 1st changing black pel > b1 */ \
                   3920:        if(pr<pre) { \
                   3921:                if((pr+1)<pre) b2=(pr+1)->xs; \
                   3922:                else b2=prl->len; \
                   3923:                } \
                   3924:        else b1=b2=prl->len; \
                   3925:        }
                   3926: #define g4r_find_b1b2 { \
                   3927:        if(a0_color==DST_white) g4r_find_Bb1Wb2 else g4r_find_Wb1Bb2; \
                   3928:        if(b1<=a0) err("g4_to_rlel: y%d: b1 %d <= a0 %d ?",crl->y,a0,b1); \
                   3929:        }
                   3930: 
                   3931:        if(bof){/* initial reference line is all white, of known length */
                   3932:                prl= &rl0;  prl->y= -1;  prl->len=len;  prl->runs=0;
                   3933:                /* initial coding line has y-coordinate 0 */
                   3934:                crl= &rl1;  crl->y=0;  crl->len=0;  crl->runs=0;
                   3935:                }
                   3936:        else crl->y = prl->y + 1;
                   3937: #if DEBUG
                   3938:        if(dbg_g4r_e)
                   3939:                fprintf(stderr,
                   3940:                        "g4_to_rlel(t,f,bof%d,len%d) y%d,l%d\n",
                   3941:                        bof,len,prl->y,prl->len);
                   3942: #endif
                   3943:        
                   3944:        pre = (pra0=pr=prl->r) + prl->runs;     /* prior line */
                   3945:        crl->runs=0;  cr=crl->r-1;              /* current line */
                   3946:        /* start on an imaginary white pixel just to left of margin */
                   3947:        a0= -1;  a0_color = DST_white;
                   3948: #if DEBUG
                   3949:        a1=a2=b1=b2=0;  /* immaterial; looks better when debugging */
                   3950: #endif
                   3951: 
                   3952:        /* start b1/b2 on prior line's first black pixel, etc;
                   3953:           if none, then place off end of line */
                   3954:        if(pr<pre) {b1=pr->xs; b2=pr->xe+1;} else b1=b2=prl->len;
                   3955:        /* parse a sequence of 2D codes... */
                   3956:        while(T/* exit only via 'goto trap_X' */) {
                   3957:                /* a0, a1, a2, b1, b2 are as defined in CCITT Rec. T.6 */
                   3958: #if DEBUG
                   3959:                if(dbg_g4r_r)
                   3960:                        fprintf(stderr,"a(%d,%d,%d) b(%d,%d)\n",a0,a1,a2,b1,b2);
                   3961: #endif
                   3962:                cx.tr.s = DST_2d;  cx.tr.a = DST_action_NULL;
                   3963: #if DEBUG
                   3964:                if(dbg_g4r_t)fprintf(stderr,"(%d,%d)\n",cx.tr.s,cx.tr.a);
                   3965: #endif
                   3966:                do {    switch(bitv=getb(f)) {
                   3967:                            case 0 :
                   3968:                            case 1 :
                   3969:                                cx.tr=t->e[cx.tr.s].t[bitv];
                   3970:                                break;
                   3971:                            case EOF:  goto trap_eof;  break;
                   3972:                            };
                   3973: #if DEBUG
                   3974:                        if(dbg_g4r_t)fprintf(stderr,"%d->(%d,%d)\n",
                   3975:                                        bitv,cx.tr.s,cx.tr.a);
                   3976: #endif
                   3977:                        }
                   3978:                while(cx.tr.a==DST_action_NULL);
                   3979: #if DEBUG
                   3980:                if(dbg_g4r_t)fprintf(stderr,"%s %04d  %s0\n",
                   3981:                        (cx.c==DST_white)? "W": "B",
                   3982:                        cx.tr.s,
                   3983:                        t->e[cx.tr.s].p);
                   3984: #endif
                   3985:                switch(cx.tr.a) {
                   3986:                    case i2D_V0:
                   3987: #if DEBUG
                   3988:                        if(dbg_g4r_c)
                   3989:                                fprintf(stderr,"V0      %s\n",code2d[cx.tr.a]);
                   3990: #endif
                   3991:                        a1=b1;
                   3992:                        /* interpret (a0,a1-1] */
                   3993:                        if(a0_color==DST_black) cr->xe=a1-1;
                   3994:                        /* move a0 to a1 */
                   3995:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   3996:                        a0_color = flip_color(a0_color);
                   3997:                        /* interpret a0 */
                   3998:                        if(a0_color==DST_black) {
                   3999:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4000:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4001:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4002:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   4003:                                };
                   4004: #if !g4r_strict
                   4005:                        if(a0==prl->len-1)
                   4006:                                { a0++;  goto trap_expecting_eol; };
                   4007: #endif
                   4008:                        g4r_find_b1b2;
                   4009:                        break;
                   4010:                    case i2D_VR1:
                   4011: #if DEBUG
                   4012:                        if(dbg_g4r_c)
                   4013:                                fprintf(stderr,"VR1     %s\n",code2d[cx.tr.a]);
                   4014: #endif
                   4015:                        a1=b1+1;
                   4016:                        /* encode a0 to a1-1 */
                   4017:                        if(a0_color==DST_black) cr->xe=a1-1;
                   4018:                        /* move a0 to a1 */
                   4019:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   4020:                        a0_color = flip_color(a0_color);
                   4021:                        /* encode a0 */
                   4022:                        if(a0_color==DST_black) {
                   4023:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4024:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4025:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4026:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   4027:                                };
                   4028: #if !g4r_strict
                   4029:                        if(a0==prl->len-1)
                   4030:                                { a0++;  goto trap_expecting_eol; };
                   4031: #endif
                   4032:                        g4r_find_b1b2;
                   4033:                        break;
                   4034:                    case i2D_VR2:
                   4035: #if DEBUG
                   4036:                        if(dbg_g4r_c)
                   4037:                                fprintf(stderr,"VR2     %s\n",code2d[cx.tr.a]);
                   4038: #endif
                   4039:                        a1=b1+2;
                   4040:                        /* encode a0 to a1-1 */
                   4041:                        if(a0_color==DST_black) cr->xe=a1-1;
                   4042:                        /* move a0 to a1 */
                   4043:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   4044:                        a0_color = flip_color(a0_color);
                   4045:                        /* encode a0 */
                   4046:                        if(a0_color==DST_black) {
                   4047:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4048:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4049:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4050:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   4051:                                };
                   4052: #if !g4r_strict
                   4053:                        if(a0==prl->len-1)
                   4054:                                { a0++;  goto trap_expecting_eol; };
                   4055: #endif
                   4056:                        g4r_find_b1b2;
                   4057:                        break;
                   4058:                    case i2D_VR3:
                   4059: #if DEBUG
                   4060:                        if(dbg_g4r_c)
                   4061:                                fprintf(stderr,"VR3     %s\n",code2d[cx.tr.a]);
                   4062: #endif
                   4063:                        a1=b1+3;
                   4064:                        /* encode a0 to a1-1 */
                   4065:                        if(a0_color==DST_black) cr->xe=a1-1;
                   4066:                        /* move a0 to a1 */
                   4067:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   4068:                        a0_color = flip_color(a0_color);
                   4069:                        /* encode a0 */
                   4070:                        if(a0_color==DST_black) {
                   4071:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4072:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4073:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4074:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   4075:                                };
                   4076: #if !g4r_strict
                   4077:                        if(a0==prl->len-1)
                   4078:                                { a0++;  goto trap_expecting_eol; };
                   4079: #endif
                   4080:                        g4r_find_b1b2;
                   4081:                        break;
                   4082:                    case i2D_VL1:
                   4083: #if DEBUG
                   4084:                        if(dbg_g4r_c)
                   4085:                                fprintf(stderr,"VL1     %s\n",code2d[cx.tr.a]);
                   4086: #endif
                   4087:                        if((a1=b1-1)<=a0)
                   4088:                                err("g4_to_rlel: y%d: VL1 a1 %d <= a0 %d ?",
                   4089:                                        crl->y,a1,a0);
                   4090:                        /* encode a0 to a1-1 */
                   4091:                        if(a0_color==DST_black) cr->xe=a1-1;
                   4092:                        /* move a0 to a1 */
                   4093:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   4094:                        a0_color = flip_color(a0_color);
                   4095:                        /* encode a0 */
                   4096:                        if(a0_color==DST_black) {
                   4097:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4098:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4099:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4100:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   4101:                                };
                   4102: #if !g4r_strict
                   4103:                        if(a0==prl->len-1)
                   4104:                                { a0++;  goto trap_expecting_eol; };
                   4105: #endif
                   4106:                        g4r_find_b1b2;
                   4107:                        break;
                   4108:                    case i2D_VL2:
                   4109: #if DEBUG
                   4110:                        if(dbg_g4r_c)
                   4111:                                fprintf(stderr,"VL2     %s\n",code2d[cx.tr.a]);
                   4112: #endif
                   4113:                        if((a1=b1-2)<=a0)
                   4114:                                err("g4_to_rlel: y%d: VL2 a1 %d <= a0 %d ?",
                   4115:                                        crl->y,a1,a0);
                   4116:                        /* encode a0 to a1-1 */
                   4117:                        if(a0_color==DST_black) cr->xe=a1-1;
                   4118:                        /* move a0 to a1 */
                   4119:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   4120:                        a0_color = flip_color(a0_color);
                   4121:                        /* encode a0 */
                   4122:                        if(a0_color==DST_black) { 
                   4123:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4124:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4125:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4126:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   4127:                                };
                   4128: #if !g4r_strict
                   4129:                        if(a0==prl->len-1)
                   4130:                                { a0++;  goto trap_expecting_eol; };
                   4131: #endif
                   4132:                        g4r_find_b1b2;
                   4133:                        break;
                   4134:                    case i2D_VL3:
                   4135: #if DEBUG
                   4136:                        if(dbg_g4r_c)
                   4137:                                fprintf(stderr,"VL3     %s\n",code2d[cx.tr.a]);
                   4138: #endif
                   4139:                        if((a1=b1-3)<=a0)
                   4140:                                err("g4_to_rlel: y%d: VL3 a1 %d <= a0 %d ?",
                   4141:                                        crl->y,a1,a0);
                   4142:                        /* encode a0 to a1-1 */
                   4143:                        if(a0_color==DST_black) cr->xe=a1-1;
                   4144:                        /* move a0 to a1 */
                   4145:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   4146:                        a0_color = flip_color(a0_color);
                   4147:                        /* encode a0 */
                   4148:                        if(a0_color==DST_black) {
                   4149:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4150:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4151:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4152:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   4153:                                };
                   4154: #if !g4r_strict
                   4155:                        if(a0==prl->len-1)
                   4156:                                { a0++;  goto trap_expecting_eol; };
                   4157: #endif
                   4158:                        g4r_find_b1b2;
                   4159:                        break;
                   4160:                    case i2D_PASS:
                   4161: #if DEBUG
                   4162:                        if(dbg_g4r_c)
                   4163:                                fprintf(stderr,"PASS    %s\n",code2d[cx.tr.a]);
                   4164: #endif
                   4165:                        /* move a0 to b2; no change of color */
                   4166:                        a0=b2;  if(a0>=prl->len) goto trap_expecting_eol;
                   4167:                        if(a0_color==DST_black) cr->xe = a0;
                   4168: #if !g4r_strict
                   4169:                        if(a0==prl->len-1)
                   4170:                                { a0++;  goto trap_expecting_eol; };
                   4171: #endif
                   4172:                        g4r_find_b1b2;
                   4173:                        break;
                   4174:                    case i2D_HORIZ:
                   4175: #if DEBUG
                   4176:                        if(dbg_g4r_c)
                   4177:                                fprintf(stderr,"HORIZ   %s\n",code2d[cx.tr.a]);
                   4178: #endif
                   4179:                        if(a0_color==DST_white) {
                   4180:                                if(a0<0) a0=0;  /* first run in line starts at 0 */
                   4181:                                g4_1d_run(DST_white,a01);  a1 = a0 + a01;
                   4182:                                g4_1d_run(DST_black,a12);  a2 = a1 + a12;
                   4183:                                if(a12>0) /* Black run of >0 length */ {
                   4184:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   4185:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   4186:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   4187:                                        crl->runs++; (++cr)->xs = a1; cr->xe = a2-1;
                   4188:                                        };
                   4189:                                a0 = a2;        /* still white */
                   4190:                                if(a0>=prl->len) goto trap_expecting_eol;
                   4191:                                /* encode a0 */
                   4192: #if !g4r_strict
                   4193:                                if(a0==prl->len-1)
                   4194:                                        { a0++;  goto trap_expecting_eol; };
                   4195: #endif
                   4196:                                g4r_find_Bb1Wb2;
                   4197:                                }
                   4198:                        else {  g4_1d_run(DST_black,a01);  a1 = a0 + a01;
                   4199:                                g4_1d_run(DST_white,a12);  a2 = a1 + a12;
                   4200:                                if(a01>0) /* Black run of >0 length */ {
                   4201:                                        cr->xe = a1 - 1;
                   4202:                                        }
                   4203:                                else {  /* 0-length: very peculiar: ignore */
                   4204:                                        fprintf(stderr,
                   4205:                                           "g4_to_rlel: HORIZ B%d! W%d - ignore\n",
                   4206:                                           a01,a12);
                   4207:                                        cr--; crl->runs--;
                   4208:                                        };
                   4209:                                a0 = a2;        /* still black */
                   4210:                                if(a0>=prl->len) goto trap_expecting_eol;
                   4211:                                /* encode a0 */
                   4212:                                crl->runs++;  (++cr)->xs = a0;
                   4213: #if !g4r_strict
                   4214:                                if(a0==prl->len-1) {
                   4215:                                        cr->xe = a0;
                   4216:                                        a0++;
                   4217:                                        goto trap_expecting_eol;
                   4218:                                        };
                   4219: #endif
                   4220:                                g4r_find_Wb1Bb2;
                   4221:                                };
                   4222:                        break;
                   4223:                    case i2D_EOL:
                   4224: #if DEBUG
                   4225:                        if(dbg_g4r_c)
                   4226:                                fprintf(stderr,"EOL     %s\n",code2d[cx.tr.a]);
                   4227: #endif
                   4228:                        goto trap_eol;
                   4229:                        break;
                   4230:                    case DST_action_ERROR:  goto trap_code_err;  break;
                   4231:                    };
                   4232:                };
                   4233: 
                   4234: /* come here via goto's: all these traps return() */
                   4235: 
                   4236: trap_expecting_eol:    /* come here having detected (computed) end-of-line */
                   4237:        /* learn/check/correct line-length */
                   4238:        crl->len = (a0>0)? a0 : 0;
                   4239:        if(crl->len!=prl->len) {
                   4240:                err("g4_to_rlel: y%d: LINELEN changes c%d != p%d ? (force to %d)",
                   4241:                        crl->y,crl->len,prl->len,prl->len);
                   4242:                crl->len = prl->len;
                   4243:                };
                   4244:        swap_rl(crl,prl);
                   4245: #if DEBUG
                   4246:        if(dbg_g4r_e)
                   4247:                fprintf(stderr,
                   4248:                        "exit g4_to_rlel: expg_eol y%d,l%d\n",
                   4249:                        prl->y,prl->len);
                   4250: #endif
                   4251:        return(prl);
                   4252: 
                   4253: trap_eol:  /* come here having seen an EOL code (rare in Group 4) */
                   4254:        /* It must be the first of two EOL codes making up the EOB signal */
                   4255:        /* look for 2nd EOL */
                   4256:        sync=0;  while((bitv=getb(f))==0) sync++;
                   4257:        switch(bitv) {
                   4258:            case 1:
                   4259:                if(sync==11) {
                   4260: #if DEBUG
                   4261:                        if(dbg_g4r_c) {
                   4262:                                fprintf(stderr,"EOB_EOL %s\n",EOLSTRING);
                   4263:                                fprintf(stderr,"EOB\n");
                   4264:                                };
                   4265: #endif
                   4266:                        }
                   4267:                else {  
                   4268: #if DEBUG
                   4269:                        if(dbg_g4r_c){
                   4270:                                fprintf(stderr,"NOT EOB ");
                   4271:                                for(si=0;si<sync;si++)
                   4272:                                        fprintf(stderr,"0");
                   4273:                                fprintf(stderr,"1?\n");
                   4274:                                fprintf(stderr,"ABORT\n");
                   4275:                                };
                   4276: #endif
                   4277:                        };
                   4278:                break;
                   4279:            case EOF:  goto trap_eof;  break;
                   4280:            };
                   4281: #if DEBUG
                   4282:        if(dbg_g4r_e) fprintf(stderr,"exit g4_to_rlel: eol\n");
                   4283: #endif
                   4284:        return(NULL);
                   4285: 
                   4286: trap_code_err:
                   4287:        /* unexpected coding sequence:
                   4288:           'px' holds last decoding context & 'bitv' latest bit value;
                   4289:           will attempt to resynchronize on next EOL */
                   4290: #if DEBUG
                   4291:        if(dbg_g4r_c)fprintf(stderr,"CODERR  %s%d? (px.tr.s=%d)\n",
                   4292:                                t->e[px.tr.s].p,bitv,px.tr.s);
                   4293: #endif
                   4294:        err("g4_to_rlel: code error");
                   4295: #if DEBUG
                   4296:        if(dbg_g4r_e) fprintf(stderr,"exit g4_to_rlel: code_err\n");
                   4297: #endif
                   4298:        return(NULL);
                   4299: 
                   4300: trap_eof:
                   4301: #if DEBUG
                   4302:        if(dbg_g4r_c) fprintf(stderr,"<EOF>\n");
                   4303:        if(dbg_g4r_e) fprintf(stderr,"exit g4_to_rlel: eof\n");
                   4304: #endif
                   4305:        return(NULL);
                   4306: 
                   4307:     }
                   4308: 
                   4309: /* Translate a sequence of RLE_Line's (describing a binary image)
                   4310:    into a file (a stream of bits) in CCITT FAX Group 4 compression format.
                   4311:    BOF_to_g4() must be called first; then call rlel_to_g4() for each line
                   4312:    (including blank lines); finally, EOF_to_g4() must be called.  The EOFB
                   4313:    is padded (suffixed) with 0's to a byte boundary if necessary; no other
                   4314:    filling or padding is performed.
                   4315:    */
                   4316: /* debugging flags:  trace to stderr */
                   4317: #define dbg_rg4_e (0)  /* entry */
                   4318: #define dbg_rg4_r (0)  /* runs */
                   4319: #define dbg_rg4_c (0)  /* codes (bitstrings) */
                   4320: #define rg4_strict (1) /* 1 is CORRECT: explicitly code the last black pel */
                   4321: 
                   4322: #if DEBUG
                   4323: #define bits_g4(bits) { \
                   4324:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   4325:        if(dbg_rg4_c) fprintf(stderr,"%s",(bits)); \
                   4326:        if(dbg_rg4_r) fprintf(stderr," "); \
                   4327:        }
                   4328: #else
                   4329: #define bits_g4(bits) { \
                   4330:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   4331:        }
                   4332: #endif
                   4333: #if DEBUG
                   4334: #define EOFB_g4 { \
                   4335:        if(dbg_rg4_r) fprintf(stderr,"EOFB    "); \
                   4336:        bits_g4(EOFB); \
                   4337:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4338:        }
                   4339: #else
                   4340: #define EOFB_g4 { \
                   4341:        bits_g4(EOFB); \
                   4342:        }
                   4343: #endif
                   4344: 
                   4345: BOF_to_g4(f)
                   4346:     BITFILE *f;
                   4347: {   char *cs;
                   4348:        /* a NOP: no header for Group 4 */
                   4349: #if DEBUG
                   4350:        if(dbg_rg4_e) fprintf(stderr,"BOF\n");
                   4351: #endif
                   4352:        };
                   4353: 
                   4354: rlel_to_g4(pl,cl,wid,f)
                   4355:     RLE_Line *pl;      /* prior "reference" line */
                   4356:     RLE_Line *cl;      /* current "coding" line: if NULL, is blank (all white) */
                   4357:     int wid;           /* width of an output line in pixels */
                   4358:     BITFILE *f;
                   4359: {   int runl,codi;
                   4360:     char *cs,*p01;
                   4361: #if DEBUG
                   4362: #define Wrun_g4(rn) { \
                   4363:        runl=(rn); \
                   4364:        if(dbg_rg4_r) fprintf(stderr,"W %5d ",runl); \
                   4365:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   4366:        p01=codewht[codi=rtoi(runl)]; bits_g4(p01); \
                   4367:        if(codi>=64) {p01=codewht[runl%64]; bits_g4(p01);}; \
                   4368:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4369:        }
                   4370: #else
                   4371: #define Wrun_g4(rn) { \
                   4372:        runl=(rn); \
                   4373:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   4374:        p01=codewht[codi=rtoi(runl)]; bits_g4(p01); \
                   4375:        if(codi>=64) {p01=codewht[runl%64]; bits_g4(p01);}; \
                   4376:        }
                   4377: #endif
                   4378: #if DEBUG
                   4379: #define Brun_g4(rn) { \
                   4380:        runl=(rn); \
                   4381:        if(dbg_rg4_r) fprintf(stderr,"B %5d ",runl); \
                   4382:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   4383:        p01=codeblk[codi=rtoi(runl)]; bits_g4(p01); \
                   4384:        if(codi>=64) {p01=codeblk[runl%64]; bits_g4(p01);}; \
                   4385:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4386:        }
                   4387: #else
                   4388: #define Brun_g4(rn) { \
                   4389:        runl=(rn); \
                   4390:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   4391:        p01=codeblk[codi=rtoi(runl)]; bits_g4(p01); \
                   4392:        if(codi>=64) {p01=codeblk[runl%64]; bits_g4(p01);}; \
                   4393:        }
                   4394: #endif
                   4395: #if DEBUG
                   4396: #define V0_g4 { \
                   4397:        if(dbg_rg4_r) fprintf(stderr,"V0      "); \
                   4398:        bits_g4(code2d[i2D_V0]); \
                   4399:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4400:        }
                   4401: #else
                   4402: #define V0_g4 { \
                   4403:        bits_g4(code2d[i2D_V0]); \
                   4404:        }
                   4405: #endif
                   4406: #if DEBUG
                   4407: #define VR1_g4 { \
                   4408:        if(dbg_rg4_r) fprintf(stderr,"VR1     "); \
                   4409:        bits_g4(code2d[i2D_VR1]); \
                   4410:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4411:        }
                   4412: #else
                   4413: #define VR1_g4 { \
                   4414:        bits_g4(code2d[i2D_VR1]); \
                   4415:        }
                   4416: #endif
                   4417: #if DEBUG
                   4418: #define VR2_g4 { \
                   4419:        if(dbg_rg4_r) fprintf(stderr,"VR2     "); \
                   4420:        bits_g4(code2d[i2D_VR2]); \
                   4421:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4422:        }
                   4423: #else
                   4424: #define VR2_g4 { \
                   4425:        bits_g4(code2d[i2D_VR2]); \
                   4426:        }
                   4427: #endif
                   4428: #if DEBUG
                   4429: #define VR3_g4 { \
                   4430:        if(dbg_rg4_r) fprintf(stderr,"VR3     "); \
                   4431:        bits_g4(code2d[i2D_VR3]); \
                   4432:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4433:        }
                   4434: #else
                   4435: #define VR3_g4 { \
                   4436:        bits_g4(code2d[i2D_VR3]); \
                   4437:        }
                   4438: #endif
                   4439: #if DEBUG
                   4440: #define VL1_g4 { \
                   4441:        if(dbg_rg4_r) fprintf(stderr,"VL1     "); \
                   4442:        bits_g4(code2d[i2D_VL1]); \
                   4443:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4444:        }
                   4445: #else
                   4446: #define VL1_g4 { \
                   4447:        bits_g4(code2d[i2D_VL1]); \
                   4448:        }
                   4449: #endif
                   4450: #if DEBUG
                   4451: #define VL2_g4 { \
                   4452:        if(dbg_rg4_r) fprintf(stderr,"VL2     "); \
                   4453:        bits_g4(code2d[i2D_VL2]); \
                   4454:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4455:        }
                   4456: #else
                   4457: #define VL2_g4 { \
                   4458:        bits_g4(code2d[i2D_VL2]); \
                   4459:        }
                   4460: #endif
                   4461: #if DEBUG
                   4462: #define VL3_g4 { \
                   4463:        if(dbg_rg4_r) fprintf(stderr,"VL3     "); \
                   4464:        bits_g4(code2d[i2D_VL3]); \
                   4465:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4466:        }
                   4467: #else
                   4468: #define VL3_g4 { \
                   4469:        bits_g4(code2d[i2D_VL3]); \
                   4470:        }
                   4471: #endif
                   4472: #if DEBUG
                   4473: #define PASS_g4 { \
                   4474:        if(dbg_rg4_r) fprintf(stderr,"PASS    "); \
                   4475:        bits_g4(code2d[i2D_PASS]); \
                   4476:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4477:        }
                   4478: #else
                   4479: #define PASS_g4 { \
                   4480:        bits_g4(code2d[i2D_PASS]); \
                   4481:        }
                   4482: #endif
                   4483: #if DEBUG
                   4484: #define HORIZ_g4 { \
                   4485:        if(dbg_rg4_r) fprintf(stderr,"HORIZ   "); \
                   4486:        bits_g4(code2d[i2D_HORIZ]); \
                   4487:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   4488:        }
                   4489: #else
                   4490: #define HORIZ_g4 { \
                   4491:        bits_g4(code2d[i2D_HORIZ]); \
                   4492:        }
                   4493: #endif
                   4494: #define detect_a1a2_BW { \
                   4495:        /* find leftmost black changing pel > a0 */ \
                   4496:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   4497:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   4498:        /* look beyond cra, until cr->xs>a0 */ \
                   4499:        cr=cra; while(cr<cre && (a1=cr->xs)<=a0) cr++; \
                   4500:        if(cr<cre) a2=cr->xe+1; \
                   4501:        else a1=a2=wid; \
                   4502:        }
                   4503: #define detect_a1a2_WB { \
                   4504:        /* find leftmost white changing pel > a0 */ \
                   4505:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   4506:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   4507:        /* look beyond cra, until cr->xe+1>a0 */ \
                   4508:        cr=cra;  while(cr<cre && (a1=cr->xe+1)<=a0) cr++; \
                   4509:        if(cr<cre) { \
                   4510:                if((cr+1)<cre) a2=(cr+1)->xs; \
                   4511:                else a2=wid; \
                   4512:                } \
                   4513:        else a1=a2=wid; \
                   4514:        }
                   4515: #define detect_a1a2 {if(a0_color==DST_white) detect_a1a2_BW else detect_a1a2_WB;}
                   4516: #define detect_b1b2_BW {\
                   4517:        /* find leftmost black changing pel > a0 */ \
                   4518:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   4519:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   4520:        /* look beyond pra */ \
                   4521:        pr=pra;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                   4522:        /* move b2 to 1st changing white pel > b1 */ \
                   4523:        if(pr<pre) b2=pr->xe+1; \
                   4524:        else b1=b2=wid; \
                   4525:        }
                   4526: #define detect_b1b2_WB {\
                   4527:        /* find leftmost white changing pel > a0 */ \
                   4528:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   4529:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   4530:        /* look beyond pra */ \
                   4531:        pr=pra;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                   4532:        /* move b2 to 1st changing black pel > b1 */ \
                   4533:        if(pr<pre) { \
                   4534:                if((pr+1)<pre) b2=(pr+1)->xs; \
                   4535:                else b2=wid; \
                   4536:                } \
                   4537:        else b1=b2=wid; \
                   4538:        }
                   4539: #define detect_b1b2 {if(a0_color==DST_white) detect_b1b2_BW else detect_b1b2_WB;}
                   4540: 
                   4541:     RLE_Run *cr,*cre,*pr,*pre; /* into current/prior rle lines */      
                   4542:     int a0,a1,a2,b1,b2;         /* indices {0,1,...} of pixels */
                   4543:     DST_color a0_color;  /* a0's color:  same as a2 & b2, opp of a1 & b1 */
                   4544:     RLE_Run *cra;   /* rightmost in current st xe<=a0 (none: ==cl->r)  */
                   4545:     RLE_Run *pra;   /* rightmost in prior st xe<=a0 (none: ==pl->r) */
                   4546:     int a01,a12,a1b1;  /* lengths of runs a0-a1 a1-a2 a1-b1 */
                   4547: #if DEBUG
                   4548:        if(dbg_rg4_e) err("rlel_to_g4(pl[%d],cl[%d],w%d)",
                   4549:                                (pl==NULL)? -1: pl->runs,
                   4550:                                (cl==NULL)? -1: cl->runs,
                   4551:                                wid);
                   4552: #endif
                   4553:        /* start on an imaginary white pixel just to left of margin */
                   4554:        a0= -1;  a0_color = DST_white;  
                   4555:        pre = (pra=pl->r) + pl->runs;   /* prior line's runs */
                   4556:        /* start b1/b2 on prior line's first black pixel, etc;
                   4557:           if none, then place off end of line */
                   4558:        if(pra<pre) {b1=pra->xs; b2=pra->xe+1;} else b1=b2=wid;
                   4559:        if(cl!=NULL&&cl->runs>0) {
                   4560:                cre = (cra=cl->r) + cl->runs;
                   4561:                a1=cra->xs;  a2=cra->xe+1;
                   4562: #if rg4_strict
                   4563:                while( a0 < wid ) {
                   4564: #else
                   4565:                while( a0 < wid-1 ) {
                   4566: #endif
                   4567:                        /* a0, a1, a2, b1, b2 are as defined in CCITT Rec. T.6 */
                   4568: #if DEBUG
                   4569:                        if(dbg_rg4_r)
                   4570:                            fprintf(stderr,"f%d(%d,%d,%d) b%d(%d,%d)\n",
                   4571:                                cra-(cl->r),a0,a1,a2,pra-(pl->r),b1,b2);
                   4572: #endif
                   4573:                        if(b2<a1) /* PASS mode */ {
                   4574:                                PASS_g4;
                   4575:                                a0=b2;
                   4576:                                /* a0-color, a1, & a2 are unchanged */
                   4577:                                detect_b1b2;
                   4578:                                }
                   4579:                        else if((a1b1=(a1-b1))<=3 && a1b1>= -3) {
                   4580:                                /* VERTICAL mode */
                   4581:                                switch(a1b1) {
                   4582:                                    case -3:  VL3_g4;  break;
                   4583:                                    case -2:  VL2_g4;  break;
                   4584:                                    case -1:  VL1_g4;  break;
                   4585:                                    case 0:  V0_g4;  break;
                   4586:                                    case 1:  VR1_g4;  break;
                   4587:                                    case 2:  VR2_g4;  break;
                   4588:                                    case 3:  VR3_g4;  break;
                   4589:                                    };
                   4590:                                a0=a1;  a0_color=flip_color(a0_color);
                   4591:                                detect_a1a2;
                   4592:                                detect_b1b2;
                   4593:                                }
                   4594:                        else {  /* HORIZONTAL mode */
                   4595:                                HORIZ_g4;
                   4596:                                a01=a1-a0; if(a0== -1) a01--;
                   4597:                                a12=a2-a1;
                   4598:                                if(a0_color==DST_white) {
                   4599:                                        Wrun_g4(a01);
                   4600:                                        Brun_g4(a12);
                   4601:                                        }
                   4602:                                else {  Brun_g4(a01);
                   4603:                                        Wrun_g4(a12);
                   4604:                                        };
                   4605:                                a0=a2;
                   4606:                                /* a0_color is unchanged */
                   4607:                                detect_a1a2;
                   4608:                                detect_b1b2;
                   4609:                                };
                   4610:                        };
                   4611:                }
                   4612:        else /* current line is blank */ {
                   4613:                a1=a2=wid;
                   4614: #if rg4_strict
                   4615:                while( a0 < wid ) {
                   4616: #else
                   4617:                while( a0 < wid-1 ) {
                   4618: #endif
                   4619:                        /* a0, a1, a2, b1, b2 are as defined in CCITT Rec. T.6 */
                   4620: #if DEBUG
                   4621:                        if(dbg_rg4_r)
                   4622:                            fprintf(stderr,"f(%d,%d,%d) b%d(%d,%d)\n",
                   4623:                                a0,a1,a2,pra-(pl->r),b1,b2);
                   4624: #endif
                   4625:                        if(b2<a1) /* PASS mode */ {
                   4626:                                PASS_g4;
                   4627:                                a0=b2;
                   4628:                                /* a0-color, a1, & a2 are unchanged */
                   4629:                                detect_b1b2;
                   4630:                                }
                   4631:                        else if((a1b1=a1-b1)<=3 && a1b1>= -3) {
                   4632:                                /* VERTICAL mode */
                   4633:                                switch(a1b1) {
                   4634:                                    case -3:  VL3_g4;  break;
                   4635:                                    case -2:  VL2_g4;  break;
                   4636:                                    case -1:  VL1_g4;  break;
                   4637:                                    case 0:  V0_g4;  break;
                   4638:                                    case 1:  VR1_g4;  break;
                   4639:                                    case 2:  VR2_g4;  break;
                   4640:                                    case 3:  VR3_g4;  break;
                   4641:                                    };
                   4642:                                a0=a1;  a0_color=flip_color(a0_color);
                   4643:                                /* a1, & a2 are unchanged */
                   4644:                                detect_b1b2;
                   4645:                                }
                   4646:                        else {  /* HORIZONTAL mode */
                   4647:                                HORIZ_g4;
                   4648:                                a01=a1-a0; if(a0== -1) a01--;
                   4649:                                a12=a2-a1;
                   4650:                                if(a0_color==DST_white) {
                   4651:                                        Wrun_g4(a01);
                   4652:                                        Brun_g4(a12);
                   4653:                                        }
                   4654:                                else {  Brun_g4(a01);
                   4655:                                        Wrun_g4(a12);
                   4656:                                        };
                   4657:                                a0=a2;
                   4658:                                /* a0_color, a1, & a2 are unchanged */
                   4659:                                detect_b1b2;
                   4660:                                };
                   4661:                        };
                   4662:                };
                   4663:        }
                   4664: 
                   4665: EOF_to_g4(f)
                   4666:     BITFILE *f;
                   4667: {   char *cs;
                   4668:        /* write EOFB */
                   4669:        EOFB_g4;
                   4670: #if DEBUG
                   4671:        if(dbg_rg4_e) fprintf(stderr,"EOF\n");
                   4672: #endif
                   4673:        }
                   4674: 
                   4675: 0707070035351137051006640007620000050000010261160476773366600001000000024315CCITT.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   4676: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   4677: /* The copyright notice does not imply actual or intended publication. */
                   4678: /* AUTHORS:                                            */
                   4679: /*     H. S. Baird - ATT-BL MH - first versions        */
                   4680: /* CCITT Group 3 FAX compression codes */
                   4681: #define EOLSTRING      "000000000001"
                   4682: #define EOLLENGTH      12              /* length of EOLSTRING */
                   4683: #define MAXCODELEN     24
                   4684: 
                   4685: #define DST_EOL -3
                   4686: 
                   4687: /* translate a runlength value <=2560 to an index into the Huffman code table;
                   4688:    if the index is >=64, then must repeat for (r%64) */
                   4689: #define rtoi(r) (((r)<64)? (r): 64+((r)/64))
                   4690: /* translate an index into the Huffman code table to a runlength value */
                   4691: #define itor(i) (((i)<64)? (i): (((i)>64)? (((i)-64)*64): DST_EOL))
                   4692: 
                   4693: /* Black run code table */
                   4694:   static char *codeblk[] = {
                   4695:        /* code                 run-length value */
                   4696:        "0000110111",           /* 0, */
                   4697:        "010",                  /* 1, */
                   4698:        "11",                   /* 2, */
                   4699:        "10",                   /* 3, */
                   4700:        "011",                  /* 4, */
                   4701:        "0011",                 /* 5, */
                   4702:        "0010",                 /* 6, */
                   4703:        "00011",                /* 7, */
                   4704:        "000101",               /* 8, */
                   4705:        "000100",               /* 9, */
                   4706:        "0000100",              /* 10, */
                   4707:        "0000101",              /* 11, */
                   4708:        "0000111",              /* 12, */
                   4709:        "00000100",             /* 13, */
                   4710:        "00000111",             /* 14, */
                   4711:        "000011000",            /* 15, */
                   4712:        "0000010111",           /* 16, */
                   4713:        "0000011000",           /* 17, */
                   4714:        "0000001000",           /* 18, */
                   4715:        "00001100111",          /* 19, */
                   4716:        "00001101000",          /* 20, */
                   4717:        "00001101100",          /* 21, */
                   4718:        "00000110111",          /* 22, */
                   4719:        "00000101000",          /* 23, */
                   4720:        "00000010111",          /* 24, */
                   4721:        "00000011000",          /* 25, */
                   4722:        "000011001010",         /* 26, */
                   4723:        "000011001011",         /* 27, */
                   4724:        "000011001100",         /* 28, */
                   4725:        "000011001101",         /* 29, */
                   4726:        "000001101000",         /* 30, */
                   4727:        "000001101001",         /* 31, */
                   4728:        "000001101010",         /* 32, */
                   4729:        "000001101011",         /* 33, */
                   4730:        "000011010010",         /* 34, */
                   4731:        "000011010011",         /* 35, */
                   4732:        "000011010100",         /* 36, */
                   4733:        "000011010101",         /* 37, */
                   4734:        "000011010110",         /* 38, */
                   4735:        "000011010111",         /* 39, */
                   4736:        "000001101100",         /* 40, */
                   4737:        "000001101101",         /* 41, */
                   4738:        "000011011010",         /* 42, */
                   4739:        "000011011011",         /* 43, */
                   4740:        "000001010100",         /* 44, */
                   4741:        "000001010101",         /* 45, */
                   4742:        "000001010110",         /* 46, */
                   4743:        "000001010111",         /* 47, */
                   4744:        "000001100100",         /* 48, */
                   4745:        "000001100101",         /* 49, */
                   4746:        "000001010010",         /* 50, */
                   4747:        "000001010011",         /* 51, */
                   4748:        "000000100100",         /* 52, */
                   4749:        "000000110111",         /* 53, */
                   4750:        "000000111000",         /* 54, */
                   4751:        "000000100111",         /* 55, */
                   4752:        "000000101000",         /* 56, */
                   4753:        "000001011000",         /* 57, */
                   4754:        "000001011001",         /* 58, */
                   4755:        "000000101011",         /* 59, */
                   4756:        "000000101100",         /* 60, */
                   4757:        "000001011010",         /* 61, */
                   4758:        "000001100110",         /* 62, */
                   4759:        "000001100111",         /* 63  */
                   4760:        EOLSTRING,              /* EOL */
                   4761:        "0000001111",           /* 64, */
                   4762:        "000011001000",         /* 128, */
                   4763:        "000011001001",         /* 192, */
                   4764:        "000001011011",         /* 256, */
                   4765:        "000000110011",         /* 320, */
                   4766:        "000000110100",         /* 384, */
                   4767:        "000000110101",         /* 448, */
                   4768:        "0000001101100",        /* 512, */
                   4769:        "0000001101101",        /* 576, */
                   4770:        "0000001001010",        /* 640, */
                   4771:        "0000001001011",        /* 704, */
                   4772:        "0000001001100",        /* 768, */
                   4773:        "0000001001101",        /* 832, */
                   4774:        "0000001110010",        /* 896, */
                   4775:        "0000001110011",        /* 960, */
                   4776:        "0000001110100",        /* 1024, */
                   4777:        "0000001110101",        /* 1088, */
                   4778:        "0000001110110",        /* 1152, */
                   4779:        "0000001110111",        /* 1216, */
                   4780:        "0000001010010",        /* 1280, */
                   4781:        "0000001010011",        /* 1344, */
                   4782:        "0000001010100",        /* 1408, */
                   4783:        "0000001010101",        /* 1472, */
                   4784:        "0000001011010",        /* 1536, */
                   4785:        "0000001011011",        /* 1600, */
                   4786:        "0000001100100",        /* 1664, */
                   4787:        "0000001100101",        /* 1728  */
                   4788:                                /* extended length: */
                   4789:        "00000001000",          /* 1792, */
                   4790:        "00000001100",          /* 1856, */
                   4791:        "00000001101",          /* 1920, */
                   4792:        "000000010010",         /* 1984, */
                   4793:        "000000010011",         /* 2048, */
                   4794:        "000000010100",         /* 2112, */
                   4795:        "000000010101",         /* 2176, */
                   4796:        "000000010110",         /* 2240, */
                   4797:        "000000010111",         /* 2304, */
                   4798:        "000000011100",         /* 2368, */
                   4799:        "000000011101",         /* 2432, */
                   4800:        "000000011110",         /* 2496, */
                   4801:        "000000011111",         /* 2560  */
                   4802:        NULL                    /* are there codes beyond 2560? */
                   4803:        };
                   4804: /* No. bits in the codes in the above table */
                   4805:   static short bitcblk[] = {
                   4806:        10,3,2,2,3,4,4,5,6,6,           /*  0 -  9 */
                   4807:        7,7,7,8,8,9,10,10,10,11,        /* 10 - 19 */
                   4808:        11,11,11,11,11,11,12,12,12,12,  /* 20 - 29 */
                   4809:        12,12,12,12,12,12,12,12,12,12,  /* 30 - 39 */
                   4810:        12,12,12,12,12,12,12,12,12,12,  /* 40 - 49 */
                   4811:        12,12,12,12,12,12,12,12,12,12,  /* 50 - 59 */
                   4812:        12,12,12,12,                    /* 60 - 63 */
                   4813:        12,                             /* EOL */
                   4814:        10,                             /* 64 */
                   4815:        12,12,12,12,12,12,              /* 128 - 448 */
                   4816:        13,13,13,13,13,13,13,13,13,     /* 512 - */
                   4817:        13,13,13,13,13,13,13,13,13,
                   4818:        13,13,                          /* - 1728 */
                   4819:        11,11,11,                       /* 1792 - 1920 */
                   4820:        12,12,12,12,12,12,12,12,12,12,  /* 1984 - 2560 */
                   4821:        /* for codes over 2560 */
                   4822:        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
                   4823:        -1
                   4824:        };
                   4825: 
                   4826: /* White run code table */
                   4827:   static char *codewht[] = {
                   4828:        /* code                 run-length value */
                   4829:        "00110101",             /* 0, */
                   4830:        "000111",               /* 1, */
                   4831:        "0111",                 /* 2, */
                   4832:        "1000",                 /* 3, */
                   4833:        "1011",                 /* 4, */
                   4834:        "1100",                 /* 5, */
                   4835:        "1110",                 /* 6, */
                   4836:        "1111",                 /* 7, */
                   4837:        "10011",                /* 8, */
                   4838:        "10100",                /* 9, */
                   4839:        "00111",                /* 10, */
                   4840:        "01000",                /* 11, */
                   4841:        "001000",               /* 12, */
                   4842:        "000011",               /* 13, */
                   4843:        "110100",               /* 14, */
                   4844:        "110101",               /* 15, */
                   4845:        "101010",               /* 16, */
                   4846:        "101011",               /* 17, */
                   4847:        "0100111",              /* 18, */
                   4848:        "0001100",              /* 19, */
                   4849:        "0001000",              /* 20, */
                   4850:        "0010111",              /* 21, */
                   4851:        "0000011",              /* 22, */
                   4852:        "0000100",              /* 23, */
                   4853:        "0101000",              /* 24, */
                   4854:        "0101011",              /* 25, */
                   4855:        "0010011",              /* 26, */
                   4856:        "0100100",              /* 27, */
                   4857:        "0011000",              /* 28, */
                   4858:        "00000010",             /* 29, */
                   4859:        "00000011",             /* 30, */
                   4860:        "00011010",             /* 31, */
                   4861:        "00011011",             /* 32, */
                   4862:        "00010010",             /* 33, */
                   4863:        "00010011",             /* 34, */
                   4864:        "00010100",             /* 35, */
                   4865:        "00010101",             /* 36, */
                   4866:        "00010110",             /* 37, */
                   4867:        "00010111",             /* 38, */
                   4868:        "00101000",             /* 39, */
                   4869:        "00101001",             /* 40, */
                   4870:        "00101010",             /* 41, */
                   4871:        "00101011",             /* 42, */
                   4872:        "00101100",             /* 43, */
                   4873:        "00101101",             /* 44, */
                   4874:        "00000100",             /* 45, */
                   4875:        "00000101",             /* 46, */
                   4876:        "00001010",             /* 47, */
                   4877:        "00001011",             /* 48, */
                   4878:        "01010010",             /* 49, */
                   4879:        "01010011",             /* 50, */
                   4880:        "01010100",             /* 51, */
                   4881:        "01010101",             /* 52, */
                   4882:        "00100100",             /* 53, */
                   4883:        "00100101",             /* 54, */
                   4884:        "01011000",             /* 55, */
                   4885:        "01011001",             /* 56, */
                   4886:        "01011010",             /* 57, */
                   4887:        "01011011",             /* 58, */
                   4888:        "01001010",             /* 59, */
                   4889:        "01001011",             /* 60, */
                   4890:        "00110010",             /* 61, */
                   4891:        "00110011",             /* 62, */
                   4892:        "00110100",             /* 63  */
                   4893:        EOLSTRING,              /* EOL */
                   4894:        "11011",                /* 64, */
                   4895:        "10010",                /* 128, */
                   4896:        "010111",               /* 192, */
                   4897:        "0110111",              /* 256, */
                   4898:        "00110110",             /* 320, */
                   4899:        "00110111",             /* 384, */
                   4900:        "01100100",             /* 448, */
                   4901:        "01100101",             /* 512, */
                   4902:        "01101000",             /* 576, */
                   4903:        "01100111",             /* 640, */
                   4904:        "011001100",            /* 704, */
                   4905:        "011001101",            /* 768, */
                   4906:        "011010010",            /* 832, */
                   4907:        "011010011",            /* 896, */
                   4908:        "011010100",            /* 960, */
                   4909:        "011010101",            /* 1024, */
                   4910:        "011010110",            /* 1088, */
                   4911:        "011010111",            /* 1152, */
                   4912:        "011011000",            /* 1216, */
                   4913:        "011011001",            /* 1280, */
                   4914:        "011011010",            /* 1344, */
                   4915:        "011011011",            /* 1408, */
                   4916:        "010011000",            /* 1472, */
                   4917:        "010011001",            /* 1536, */
                   4918:        "010011010",            /* 1600, */
                   4919:        "011000",               /* 1664, */
                   4920:        "010011011",            /* 1728  */
                   4921:                                /* extended length: */
                   4922:        "00000001000",          /* 1792, */
                   4923:        "00000001100",          /* 1856, */
                   4924:        "00000001101",          /* 1920, */
                   4925:        "000000010010",         /* 1984, */
                   4926:        "000000010011",         /* 2048, */
                   4927:        "000000010100",         /* 2112, */
                   4928:        "000000010101",         /* 2176, */
                   4929:        "000000010110",         /* 2240, */
                   4930:        "000000010111",         /* 2304, */
                   4931:        "000000011100",         /* 2368, */
                   4932:        "000000011101",         /* 2432, */
                   4933:        "000000011110",         /* 2496, */
                   4934:        "000000011111",         /* 2560  */
                   4935:        NULL                    /* are there codes beyond 2560? */
                   4936:        };
                   4937: /* no. bits in the codes in the above table */
                   4938:   static short bitcwht[] = {
                   4939:        8,6,4,4,4,4,4,4,5,5,            /*  0 -  9 */
                   4940:        5,5,6,6,6,6,6,6,7,7,            /* 10 - 19 */
                   4941:        7,7,7,7,7,7,7,7,7,8,            /* 20 - 29 */
                   4942:        8,8,8,8,8,8,8,8,8,8,            /* 30 - 39 */
                   4943:        8,8,8,8,8,8,8,8,8,8,            /* 40 - 49 */
                   4944:        8,8,8,8,8,8,8,8,8,8,            /* 50 - 59 */
                   4945:        8,8,8,8,                        /* 60 - 63 */
                   4946:        12,                             /* EOL */
                   4947:        5,5,                            /* 64,128 */
                   4948:        6,                              /* 192 */
                   4949:        7,                              /* 256 */
                   4950:        8,8,8,8,8,8,                    /* 320 - 640 */
                   4951:        9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,  /* 704 - 1600 */
                   4952:        6,                              /* 1664 */
                   4953:        9,                              /* 1728 */
                   4954:        11,11,11,                       /* 1792,1856,1920 */
                   4955:        12,12,12,12,12,12,12,12,12,12,  /* 1984 - 2560 */
                   4956:        /* for codes over 2560 */
                   4957:        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
                   4958:        -1
                   4959:        };
                   4960: 
                   4961: /* 2-D codes (indices into code2d[] table) */
                   4962: #define i2D_V0 0
                   4963: #define i2D_VR1 1
                   4964: #define i2D_VR2 2
                   4965: #define i2D_VR3 3
                   4966: #define i2D_VL1 4
                   4967: #define i2D_VL2 5
                   4968: #define i2D_VL3 6
                   4969: #define i2D_PASS 7
                   4970: #define i2D_HORIZ 8
                   4971: #define i2D_EOL 9
                   4972: 
                   4973:   static char *code2d[] = {
                   4974:        "1",                    /* V0 */
                   4975:        "011",                  /* VR1 */
                   4976:        "000011",               /* VR2 */
                   4977:        "0000011",              /* VR3 */
                   4978:        "010",                  /* VL1 */
                   4979:        "000010",               /* VL2 */
                   4980:        "0000010",              /* VL3 */
                   4981:        "0001",                 /* PASS */
                   4982:        "001",                  /* HORIZ */
                   4983:        EOLSTRING,              /* EOL */
                   4984:        NULL };
                   4985:   static short bitc2d[] = { 1,3,6,7,3,6,7,4,3,12 };
                   4986: 
                   4987: #define EOL0STRING     "0000000000010"
                   4988: #define EOL1STRING     "0000000000011"
                   4989: #define EOFB           "000000000001000000000001"
                   4990: 
                   4991:   static char *spare1d[] = {
                   4992:        "000000001",            /* 0, */
                   4993:        "0000000001",           /* 0, */
                   4994:        "00000000001",          /* 0  */
                   4995:        NULL };
                   4996:   static char *spare2d[] = {
                   4997:        "0000001",              /* 0, */
                   4998:        "00000001",             /* 0, */
                   4999:        "000000001",            /* 0, */
                   5000:        "0000000001",           /* 0, */
                   5001:        "00000000001",          /* 0  */
                   5002:        NULL };
                   5003: 
                   5004: /* State-transition table for decoding CCITT G3-1 */
                   5005: 
                   5006: /* bit colors; also, starting index in table of 1-D codes*/
                   5007: #define DST_color short
                   5008: #define DST_white 0
                   5009: #define DST_black 1
                   5010: 
                   5011: #define flip_color(c) ((c)? 0: 1)
                   5012: 
                   5013: #define DST_2d 2       /* starting index in table of 2-D codes */
                   5014: 
                   5015: #define DST_state short        /* state-id: index into DST_tbl.e[] */
                   5016: #define DST_state_NULL (-1)
                   5017: #define DST_state_ERROR (-2)
                   5018: 
                   5019: #define DST_action int
                   5020: #define DST_action_NULL (-1)
                   5021: #define DST_action_ERROR (-2)
                   5022: 
                   5023: /* transition in finite-state machine */
                   5024: typedef struct DST_transit {
                   5025:        DST_action a;   /* action to perform */
                   5026:        DST_state s;    /* next state */
                   5027:        } DST_transit;
                   5028: typedef struct DST_entry {
                   5029:        char p[MAXCODELEN+1];   /* code prefix so far (in ASCII) */
                   5030:        short l;                /* strlen(.p) */
                   5031:        short z;                /* no. of trailing "0"'s in .p */
                   5032:        DST_transit t[2];       /* two transitions: on 0 & 1 */
                   5033:        } DST_entry;
                   5034: typedef struct DST_table {
                   5035:        int mny;        /* no. entries so far */
                   5036:        DST_entry *e;   /* array in malloc space:
                   5037:                                e[DST_white] starts white 1-D codes;
                   5038:                                e[DST_black] starts black 1-D codes;
                   5039:                                e[DST_2d] starts 2-D codes */
                   5040:        } DST_table;
                   5041: typedef struct DST_context {
                   5042:        DST_color c;    /* current run-color */
                   5043:        int l;          /* length of current code in bits: 0..(len-1) */
                   5044:        DST_table *t;   /* table */
                   5045:        DST_state s;    /* current state */
                   5046:        DST_transit tr; /* current state/action */
                   5047:        } DST_context;
                   5048: 
                   5049: 
                   5050: DST_table *ccitt_table();
                   5051: RLE_Line *g31_to_rlel();
                   5052: int rlel_to_g31();
                   5053: RLE_Line *g32_to_rlel();
                   5054: int rlel_to_g32();
                   5055: RLE_Line *g4_to_rlel();
                   5056: int rlel_to_g4();
                   5057: 0707070035351137061006640007620000050000010261170476773366600000600000010272CPU.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   5058: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   5059: /* The copyright notice does not imply actual or intended publication. */
                   5060: /* AUTHORS:                                            */
                   5061: /*     H. S. Baird - ATT-BL MH - first versions        */
                   5062: /*     T. Thompson - ATT-BL HO - portable versions     */
                   5063: /*     C. Macey - ATT-DSG LZ - portable versions       */
                   5064: 
                   5065: /* Specify the environment:  CPU, OS, graphics, etc.
                   5066:    This is an attempt to maintain a single master source tailorable at compile
                   5067:    time, while encapsulating as many as possible of the required #if's and
                   5068:    #ifdef's in this one file.
                   5069:    OS-dependent #includes are triggered by these prior statements:
                   5070:        #define LIBC_INCL 1             -- strcpy(), etc
                   5071:        #define VALUES_INCL 1           -- math constants (PI etc)
                   5072:        #define FILE_TREE_INCL 1        -- UNIX file-tree walking
                   5073:    */
                   5074: 
                   5075: /* CPUs with some support: */
                   5076: #define VAX 0
                   5077: #define CRAY 1
                   5078: #define SUN 2          /* including SPARC */
                   5079: #define ATT3B 3
                   5080: #define I386 4
                   5081: #define MIPS 5         /* including SGI */
                   5082: 
                   5083: /*** Select CPU here: */
                   5084: #define CPU VAX
                   5085: 
                   5086: 
                   5087: /* Operating systems with some support: */
                   5088: #define V9_OS 1                /* ATT-BL research UNIX, 9th edition */
                   5089: #define SV_OS 2                /* ATT UNIX System V */
                   5090: #define SUN_OS 3       /* Sun OS 4.x */
                   5091: 
                   5092: /*** Select OS here: */
                   5093: #define OS V9_OS
                   5094: 
                   5095: 
                   5096: /* Graphics display environments with some support: */
                   5097: #define NO_GRAPHICS 0  /* defeat all graphics */
                   5098: #define Y_GRAPHICS 1   /* the Y graphics interface (used in 1127 for Metheus) */
                   5099: #define SUN_GRAPHICS 2 /* Tim Thompson's Sun interface */
                   5100: #define X_GRAPHICS 3    /* Mark Tuomenoksa's X interface */
                   5101: 
                   5102: /*** Select graphics environment here: */
                   5103: #define GRAPHICS Y_GRAPHICS
                   5104: 
                   5105: 
                   5106: /* OCR installation directory */
                   5107: #ifndef OCRDIR
                   5108: #define OCRDIR "/usr/ocr"
                   5109: #endif
                   5110: 
                   5111: /*** Miscellaneous arcane options:  best left alone **/
                   5112: 
                   5113: #define FILE_TREE (1)          /* set to zero to defeat UNIX file tree code */
                   5114: 
                   5115: 
                   5116: /*** END OF SELECTIONS ** The rest of this file merely implements their effects */
                   5117: 
                   5118: /* define byte ordering in CPU */
                   5119: 
                   5120: #if CPU == SUN || CPU == MIPS
                   5121: #define BIG_ENDIAN 1
                   5122: #endif
                   5123: 
                   5124: /* deal with compilers that don't like (void *) */
                   5125: 
                   5126: #if CPU == MIPS
                   5127: #define VOID char
                   5128: #else
                   5129: #define VOID void
                   5130: #endif
                   5131: 
                   5132: /* include libc functions defs, if necessary */
                   5133: 
                   5134: #if LIBC_INCL
                   5135: 
                   5136: #if OS == V9_OS || CPU == CRAY
                   5137: #include <libc.h>
                   5138: #else
                   5139: #if OS == SV_OS || OS == SUN_OS || CPU == MIPS
                   5140: #include <string.h>
                   5141: #endif
                   5142: #endif
                   5143: 
                   5144: #endif
                   5145: 
                   5146: /* include values */
                   5147: 
                   5148: #if VALUES_INCL
                   5149: #include <values.h>
                   5150: #endif
                   5151: 
                   5152: /* UNIX file-tree-walk includes */
                   5153: 
                   5154: #if FILE_TREE_INCL
                   5155: 
                   5156: #if CPU==VAX || CPU==CRAY || CPU==MIPS
                   5157: #include <sys/types.h>
                   5158: #include <sys/stat.h>
                   5159: #include <ftw.h>
                   5160: #else
                   5161: #if CPU==SUN || CPU==I386
                   5162: #include <sys/types.h>
                   5163: #include <sys/stat.h>
                   5164: #include "myftw.h"  /* T. Thompson's version */
                   5165: #endif
                   5166: #endif
                   5167: 
                   5168: #endif
                   5169: 
                   5170: #if CPU==SUN||CPU==ATT3B||CPU==MIPS||CPU==I386
                   5171: #define sgn(V) (((V)>0)? 1: (((V)<0)? -1: 0))
                   5172: #endif 
                   5173: 
                   5174: #if CPU==SUN||CPU==ATT3B||CPU==MIPS
                   5175: /* These are all big-endian machines */
                   5176: #define swapshortin(x) (((x)<<8)&0xff00)|(((x)>>8)&0xff)
                   5177: #define swapintin(x) \
                   5178:                ((((x)<<24)&0xff000000)| \
                   5179:                 (((x)<<8) &0x00ff0000)| \
                   5180:                 (((x)>>8) &0x0000ff00)| \
                   5181:                 (((x)>>24)&0x000000ff))
                   5182: /* The order of bytes in an int */
                   5183: #define INDEX0 3
                   5184: #define INDEX1 2
                   5185: #define INDEX2 1
                   5186: #define INDEX3 0
                   5187: /* disable fast trick for picking out a short from an int */
                   5188: #define USESHIFT       /* cf. skewlib.c */
                   5189: #else
                   5190: #define swapshortin(x) (x)
                   5191: #define swapintin(x) (x)
                   5192: #define INDEX0 0
                   5193: #define INDEX1 1
                   5194: #define INDEX2 2
                   5195: #define INDEX3 3
                   5196: #endif
                   5197: 
                   5198: /* global max no. classes -- gradually being made dynamic everywhere */
                   5199: #if CPU==SUN
                   5200: #define MAX_CL 128
                   5201: #else
                   5202: #define MAX_CL 3200    /* adequate for JIS Level 1 */
                   5203: #endif
                   5204: 
                   5205: /* include char types (is this really necessary?) */
                   5206: 
                   5207: #if CTYPE_INCL
                   5208: 
                   5209: #if CPU == SUN
                   5210: #include <string.h>
                   5211: #else
                   5212: #include <ctype.h>
                   5213: #endif
                   5214: 
                   5215: #endif
                   5216: 
                   5217: /* includes for atan2 special configurations */
                   5218: 
                   5219: #if ATAN_INCL
                   5220: 
                   5221: #if CPU == CRAY
                   5222: #define use_fast_atan2 F
                   5223: #include "CRAY.h"
                   5224: #else
                   5225: #define use_fast_atan2 T
                   5226: #endif
                   5227: 
                   5228: #endif
                   5229: 
                   5230: /* regular expression includes (fix to use standard regexp?) */
                   5231: 
                   5232: #if REGEXP_INCL
                   5233: 
                   5234: #if OS == V9_OS
                   5235: #include <regexp.h>
                   5236: #else
                   5237: #include "regexp.h"
                   5238: #endif
                   5239: 
                   5240: #endif
                   5241: 
                   5242: /* Use of the graphics display */
                   5243: 
                   5244: #if CPU != CRAY
                   5245: #define SHOW_GRAPHICS 1
                   5246: #endif
                   5247: 
                   5248: #ifndef PI
                   5249: #define PI 3.14159265358979323846
                   5250: #endif
                   5251: 0707070035351137071006640007620000050000010261230476773366600001000000027244Coord.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   5252: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   5253: /* The copyright notice does not imply actual or intended publication. */
                   5254: /* AUTHORS:                                            */
                   5255: /*     H. S. Baird - ATT-BL MH - first versions        */
                   5256: /*     T. J. Thompson - ATT-BL HO - improvements       */
                   5257: 
                   5258: /* Coord.c - function bodies for basic Coordinate geometry.
                   5259:    See Coord.h for associated defines, typedefs, etc.
                   5260:    */
                   5261: 
                   5262: #include <stdio.h>
                   5263: #include <math.h>
                   5264: #include <string.h>
                   5265: #define ATAN_INCL 1
                   5266: #include "CPU.h"
                   5267: #include "boole.h"
                   5268: #include "Units.h"
                   5269: #include "Coord.h"
                   5270: 
                   5271: /* Added by Tim Thompson ... */
                   5272: int Readvax = 0;
                   5273: 
                   5274: VOID
                   5275: setreadvax()
                   5276: {
                   5277:        char *getenv();
                   5278:        char *p = getenv("READVAX");
                   5279:        /* any non-null value of READVAX will set it */
                   5280:        if ( p!=NULL && strlen(p)>0 )
                   5281:                Readvax = 1;
                   5282: }
                   5283: 
                   5284: /* ... */
                   5285: 
                   5286: /* Convert a real value, a units specification, and a resolution
                   5287:    into a value in scanner coordinates. */
                   5288: int vto_scoor(v,u,r)
                   5289:     double v;  /* value in special units */
                   5290:     char u;    /* units: one of UNITS (see ric.h) */
                   5291:     int r;     /* resolution in pixels/inch */
                   5292: {   int c;
                   5293:        switch(u) {
                   5294:            case 'i':   /* inches */
                   5295:                c = (int)(v*r + 0.5);
                   5296:                break;
                   5297:            case 'c':   /* cm */
                   5298:                c = (int)((v*r/2.54) + 0.5);
                   5299:                break;
                   5300:            case 'p':   /* points */
                   5301:                c = (int)((v*INCHES_PER_POINT*r) + 0.5);
                   5302:                break;
                   5303:            case 'P':   /* picas */
                   5304:                c = (int)((v*12.0*INCHES_PER_POINT*r) + 0.5);
                   5305:                break;
                   5306:            case 's':   /* scanner pixel (Scoor) */
                   5307:            case 'u':   /* basic unit */
                   5308:                c = (int)(v + 0.5);
                   5309:                break;
                   5310:            default:
                   5311:                c = (int)(v + 0.5);
                   5312:                break;
                   5313:            };
                   5314:        return(c);
                   5315:        }
                   5316: 
                   5317: /* Return pointer to empty Sp from malloc space */
                   5318: Sp *alloc_sp()
                   5319: {   Sp *spp;
                   5320:        if((spp=(Sp *)malloc(sizeof(Sp)))==NULL)
                   5321:                abort("alloc_sp: can't");
                   5322:        *spp = zero_Sp;
                   5323:        return(spp);
                   5324:        }
                   5325: 
                   5326: /* Free Sp from malloc space */
                   5327: free_sp(spp)
                   5328:     Sp *spp;
                   5329: {      free(spp);
                   5330:        }
                   5331: 
                   5332: Sp *ato_sp(s)
                   5333:     char *s;
                   5334: {   char *d;
                   5335:     static Sp p;
                   5336:     char *p_x,*p_y;
                   5337: #define SP_DELIM "(), "
                   5338:        d = strdup(s);
                   5339:        p_x = strtok(d,SP_DELIM);
                   5340:        p_y = strtok((char *)0,SP_DELIM);
                   5341:        if(p_x==NULL||p_y==NULL)
                   5342:                {free(d); return(NULL);};
                   5343:        p.x = atoi(p_x);
                   5344:        p.y = atoi(p_y);
                   5345:        free(d);
                   5346:        return(&p);
                   5347:        }
                   5348: 
                   5349: char *sp_toa(sp)
                   5350:     Sp *sp;
                   5351: #define sp_toa_distinct (5)
                   5352: {   static char s[sp_toa_distinct][40];
                   5353:     static int sp_toa_cur = -1;
                   5354:        sp_toa_cur = (sp_toa_cur+1)%sp_toa_distinct;
                   5355:        sprintf(s[sp_toa_cur],"(%d,%d)",sp->x,sp->y);
                   5356:        return(s[sp_toa_cur]);
                   5357:        }
                   5358: 
                   5359: /* Read a list of Sp's (in ascii) from file *fp, into set *spsp */
                   5360: frda_sps(fp,spsp)
                   5361:     FILE *fp;
                   5362:     Sps *spsp;
                   5363: #define MAX_SPS_LINE (80)
                   5364: {   Sp *spp,**bb;
                   5365:     long seek;
                   5366:     char line[MAX_SPS_LINE+1];
                   5367:        *spsp = empty_Sps;
                   5368:        seek = ftell(fp);
                   5369:        /* count all points quickly, in advance */
                   5370:        while(!feof(fp)) {
                   5371:                line[0] = '\0';
                   5372:                fgets(line,MAX_SPS_LINE,fp);
                   5373:                if(strlen(line)>0) {
                   5374:                        spsp->mny++;
                   5375:                        };
                   5376:                };
                   5377:        if((spsp->pa=(Sp **)malloc((spsp->mny+1)*sizeof(Sp *)))==NULL)
                   5378:                abort("frda_sps: can't alloc spsp->pa[%d]",spsp->mny+1);
                   5379:        /* next, reread points */
                   5380:        fseek(fp,(long)seek,0);
                   5381:        bb=spsp->pa;
                   5382:        while(!feof(fp)) {
                   5383:                line[0] = '\0';
                   5384:                fgets(line,MAX_SPS_LINE,fp);
                   5385:                if(strlen(line)>0) {
                   5386:                        *(spp = alloc_sp()) = *ato_sp(line);
                   5387:                        *(bb++) = spp;
                   5388:                        };
                   5389:                };
                   5390:        *bb = NULL;
                   5391:        }
                   5392: 
                   5393: err_sps(p)
                   5394:     Sps *p;
                   5395: {   int i;
                   5396:     Sp **s;
                   5397:        fprintf(stderr,"Sps: %d points: ",p->mny);
                   5398:        if(p->mny>0) for(s=p->pa; (*s)!=NULL; s++) {
                   5399:                fprintf(stderr,"%s ",sp_toa(*s));
                   5400:                };
                   5401:        fprintf(stderr,"\n");
                   5402:        }
                   5403: 
                   5404: Sp *append_sp_sps(sp,sps)
                   5405:    Sp *sp;
                   5406:    Sps *sps;
                   5407: {      if(sps->mny>0) {
                   5408:                if((sps->pa=(Sp **)realloc(sps->pa,(sps->mny+2)*sizeof(Sp *)))==NULL)
                   5409:                        abort("append_sp_sps: can't realloc sps->pa[%d]",sps->mny+2);
                   5410:                }
                   5411:        else {  sps->mny=0;
                   5412:                if((sps->pa=(Sp **)malloc((sps->mny+2)*sizeof(Sp *)))==NULL)
                   5413:                        abort("append_sp_sps: can't alloc sps->pa[%d]",sps->mny+2);
                   5414:                };
                   5415:        sps->pa[sps->mny++] = sp;
                   5416:        sps->pa[sps->mny] = NULL;
                   5417:        }
                   5418: 
                   5419: /* Return pointer to local static Sps which holds a duplicate of the
                   5420:    given Sps (all contents are freshly malloc'ed) */
                   5421: Sps *dup_sps(old)
                   5422:     Sps *old;
                   5423: {   static Sps new;
                   5424:     Sp **o,**n;
                   5425:        if(old->mny>0) {
                   5426:                new.mny = old->mny;
                   5427:                if((new.pa=(Sp **)malloc((new.mny+1)*sizeof(Sp *)))==NULL)
                   5428:                        abort("dup_sps: can't alloc new.pa[%d]",new.mny+1);
                   5429:                for(o=old->pa,n=new.pa; *o!=NULL; o++,n++) {
                   5430:                        *(*n = alloc_sp()) = **o;
                   5431:                        };
                   5432:                *n = NULL;
                   5433:                }
                   5434:        else new = empty_Sps;
                   5435:        return(&new);
                   5436:        }
                   5437: 
                   5438: free_sps(p)
                   5439:    Sps *p;
                   5440: {      if(p->pa!=NULL) free(p->pa);
                   5441:        *p = empty_Sps;
                   5442:        }
                   5443: 
                   5444: Sp *append_sp_spa(sp,spa)
                   5445:    Sp *sp;
                   5446:    Spa *spa;
                   5447: {      if(spa->mny>0) {
                   5448:                if((spa->a=(Sp *)realloc(spa->a,(spa->mny+1)*sizeof(Sp)))==NULL)
                   5449:                        abort("append_sp_spa: can't alloc spa->a[%d]",spa->mny+1);
                   5450:                }
                   5451:        else {  spa->mny=0;
                   5452:                if((spa->a=(Sp *)malloc((spa->mny+1)*sizeof(Sp)))==NULL)
                   5453:                        abort("append_sp_spa: can't alloc spa->a[%d]",spa->mny+1);
                   5454:                };
                   5455:        spa->a[spa->mny++] = *sp;
                   5456:        }
                   5457: 
                   5458: err_spa(p)
                   5459:     Spa *p;
                   5460: {   int i;
                   5461:     Sp *sp;
                   5462:        fprintf(stderr,"Spa: %d points: ",p->mny);
                   5463:        for(i=0,sp=p->a;i<p->mny;i++,sp++) {
                   5464:                fprintf(stderr,"%s ",sp_toa(sp));
                   5465:                };
                   5466:        fprintf(stderr,"\n");
                   5467:        }
                   5468: 
                   5469: free_spa(p)
                   5470:    Spa *p;
                   5471: {      if(p->a!=NULL) free(p->a);
                   5472:        *p = empty_Spa;
                   5473:        }
                   5474: 
                   5475: /* Rotate the Scanner point `(x,y') about origin `*orp' by angle `ang',
                   5476:    and return pointer to the result.  This is slow, but no matter. */
                   5477: Sp *rotate_Sp(ang,orp,x,y)
                   5478:     double ang;
                   5479:     Sp *orp;
                   5480:     int x,y;
                   5481: {   static Sp res;
                   5482:     Sp of;
                   5483:        of.x = x - orp->x;  of.y = y - orp->y;
                   5484:        res.x = (short)(((cos(ang)*of.x - sin(ang)*of.y)) + orp->x + 0.5);
                   5485:        res.y = (short)(((sin(ang)*of.x + cos(ang)*of.y)) + orp->y + 0.5);
                   5486:        return(&res);
                   5487:        }
                   5488: 
                   5489: /* Horizontally shear the Scanner point `(x,y') about origin `*orp' by shear
                   5490:    angle `ang', and return pointer to the result.  `Ang' is close to 90 degrees.
                   5491:    This is slow, but no matter. */
                   5492: Sp *hshear_Sp(ang,orp,x,y)
                   5493:     double ang;
                   5494:     Sp *orp;
                   5495:     int x,y;
                   5496: {   static Sp res;
                   5497:     Scoor of_y,tr_x;
                   5498:        res.x = (short)(orp->x - (y - orp->y)*tan(ang-(90.0*DtoR)) + 0.5);
                   5499:        res.y = orp->y;
                   5500:        return(&res);
                   5501:        }
                   5502: 
                   5503: /* Return pointer to initialized Edge from malloc space */
                   5504: Edge *alloc_edge()
                   5505: {   Edge *ep;
                   5506:        if((ep=(Edge *)malloc(sizeof(Edge)))==NULL)
                   5507:                abort("alloc_edge: can't");
                   5508:        *ep = empty_Edge;
                   5509:        return(ep);
                   5510:        }
                   5511: 
                   5512: /* Free Edge from malloc space */
                   5513: free_edge(ep)
                   5514:     Edge *ep;
                   5515: {      free(ep);
                   5516:        }
                   5517: 
                   5518: char *edge_toa(ep)
                   5519:        Edge *ep;
                   5520: {   static char s[40];
                   5521:        strcpy(s,sp_toa(&(ep->a)));
                   5522:        strcat(s,"-");
                   5523:        strcat(s,sp_toa(&(ep->b)));
                   5524:        return(s);
                   5525:        }
                   5526: 
                   5527: Edge *ato_edge(s)
                   5528:     char *s;
                   5529: {   char *d;
                   5530:     static Edge e;
                   5531:     char *a_x,*a_y,*b_x,*b_y;
                   5532: #define EDGE_DELIM "(),- "
                   5533:        d = strdup(s);
                   5534:        a_x = strtok(d,EDGE_DELIM);
                   5535:        a_y = strtok((char *)0,EDGE_DELIM);
                   5536:        b_x = strtok((char *)0,EDGE_DELIM);
                   5537:        b_y = strtok((char *)0,EDGE_DELIM);
                   5538:        if(a_x==NULL||a_y==NULL||b_x==NULL||b_y==NULL)
                   5539:                {free(d); return(NULL);};
                   5540:        e.a.x = atoi(a_x);
                   5541:        e.a.y = atoi(a_y);
                   5542:        e.b.x = atoi(b_x);
                   5543:        e.b.y = atoi(b_y);
                   5544:        free(d);
                   5545:        return(&e);
                   5546:        }
                   5547: 
                   5548: /* Return pointer to empty Bbx from malloc space */
                   5549: Bbx *alloc_bbx()
                   5550: {   Bbx *bxp;
                   5551:        if((bxp=(Bbx *)malloc(sizeof(Bbx)))==NULL)
                   5552:                abort("alloc_bbx: can't");
                   5553:        *bxp = empty_Bbx;
                   5554:        return(bxp);
                   5555:        }
                   5556: 
                   5557: /* Free Bbx from malloc space */
                   5558: free_bbx(bxp)
                   5559:     Bbx *bxp;
                   5560: {      free(bxp);
                   5561:        }
                   5562: 
                   5563: char *bbx_toa(bxp)
                   5564:        Bbx *bxp;
                   5565: {   static char s[40];
                   5566:        strcpy(s,sp_toa(&(bxp->a)));
                   5567:        strcat(s,sp_toa(&(bxp->b)));
                   5568:        return(s);
                   5569:        }
                   5570: 
                   5571: Bbx *ato_bbx(s)
                   5572:     char *s;
                   5573: {   char *d;
                   5574:     static Bbx bx;
                   5575:     char *a_x,*a_y,*b_x,*b_y;
                   5576: #define BBX_DELIM "(), "
                   5577:        d = strdup(s);
                   5578:        a_x = strtok(d,BBX_DELIM);
                   5579:        a_y = strtok((char *)0,BBX_DELIM);
                   5580:        b_x = strtok((char *)0,BBX_DELIM);
                   5581:        b_y = strtok((char *)0,BBX_DELIM);
                   5582:        if(a_x==NULL||a_y==NULL||b_x==NULL||b_y==NULL)
                   5583:                {free(d); return(NULL);};
                   5584:        bx.a.x = atoi(a_x);
                   5585:        bx.a.y = atoi(a_y);
                   5586:        bx.b.x = atoi(b_x);
                   5587:        bx.b.y = atoi(b_y);
                   5588:        free(d);
                   5589:        return(&bx);
                   5590:        }
                   5591: 
                   5592: Bbx *expand_bbx(bxp,X)
                   5593:     Bbx *bxp;
                   5594:     int X;             /* expansion code */
                   5595: {   static Bbx xbx;
                   5596:        xbx = *bxp;
                   5597:        switch(X) {
                   5598:            case -3:
                   5599:                xbx.a.x += 2;
                   5600:                xbx.a.y += 2;
                   5601:                xbx.b.x -= 1;
                   5602:                xbx.b.y -= 1;
                   5603:                break;
                   5604:            case -2:
                   5605:                xbx.a.x += 1;
                   5606:                xbx.a.y += 1;
                   5607:                xbx.b.x -= 1;
                   5608:                xbx.b.y -= 1;
                   5609:                break;
                   5610:            case -1:
                   5611:                xbx.a.x += 1;
                   5612:                xbx.a.y += 1;
                   5613:                break;
                   5614:            case 0:
                   5615:                break;
                   5616:            case 1:
                   5617:                xbx.b.x += 1;
                   5618:                xbx.b.y += 1;
                   5619:                break;
                   5620:            case 2:
                   5621:                xbx.a.x -= 1;
                   5622:                xbx.a.y -= 1;
                   5623:                xbx.b.x += 1;
                   5624:                xbx.b.y += 1;
                   5625:                break;
                   5626:            case 3:
                   5627:                xbx.a.x -= 1;
                   5628:                xbx.a.y -= 1;
                   5629:                xbx.b.x += 2;
                   5630:                xbx.b.y += 2;
                   5631:                break;
                   5632:            default:
                   5633:                break;
                   5634:            };
                   5635:        return(&xbx);
                   5636:        }
                   5637: 
                   5638: /* Predicate:  Is most of Bbx 1 inside Bbx 2?  ``Most'' is defined
                   5639:    as more than half of the first Bbx's area inside BBx 2.*/
                   5640: boolean bbx_inside_most(b1,b2)
                   5641:     Bbx *b1,*b2;
                   5642: {   struct {           /* overlap between blob box and selection box */
                   5643:        Bbx bx;         /* Bbx of intersection */
                   5644:        Sp sd;          /* side-lengths of overlap box, >=0 */
                   5645:        long area;      /* area is square pixels, >=0 */
                   5646:        } ov;
                   5647:        if(!bbx_inside_any(b1,b2)) return(F);
                   5648:        else if(bbx_inside_all(b1,b2)) return(T);
                   5649:        else {  /* compute overlap box */
                   5650:                ov.bx.a.x = ((b1)->a.x>(b2)->a.x)? (b1)->a.x: (b2)->a.x;
                   5651:                ov.bx.a.y = ((b1)->a.y>(b2)->a.y)? (b1)->a.y: (b2)->a.y;
                   5652:                ov.bx.b.x = ((b1)->b.x<(b2)->b.x)? (b1)->b.x: (b2)->b.x;
                   5653:                ov.bx.b.y = ((b1)->b.y<(b2)->b.y)? (b1)->b.y: (b2)->b.y;
                   5654:                ov.sd.x = bbx_wid(&ov.bx);  if(ov.sd.x<0) ov.sd.x=0;
                   5655:                ov.sd.y = bbx_hgt(&ov.bx);  if(ov.sd.y<0) ov.sd.y=0;
                   5656:                ov.area = ov.sd.x*ov.sd.y;
                   5657:                return( (ov.area>0) && ( 2*ov.area > bbx_area(b1) ) );
                   5658:                };
                   5659:        }
                   5660: 
                   5661: Bbx *translate_bbx(bxp,off)
                   5662:     Bbx *bxp;
                   5663:     Sp off;
                   5664: {   static Bbx res;
                   5665:        res.a.x = bxp->a.x + off.x;
                   5666:        res.a.y = bxp->a.y + off.y;
                   5667:        res.b.x = bxp->b.x + off.x;
                   5668:        res.b.y = bxp->b.y + off.y;
                   5669:        return(&res);
                   5670:        }
                   5671: 
                   5672: /* Free Bbxs (but not the contents) */
                   5673: free_bbxs(bxsp)
                   5674:     Bbxs *bxsp;
                   5675: {   Bbx **b;
                   5676:        if(bxsp->mny>0) {
                   5677:                if(bxsp->pa!=NULL) free(bxsp->pa);
                   5678:                };
                   5679:        *bxsp = empty_Bbxs;
                   5680:        }
                   5681: 
                   5682: /* Free Bbxs (and the individually-malloc'ed contents) */
                   5683: free_bbxs_etc(bxsp)
                   5684:     Bbxs *bxsp;
                   5685: {   Bbx **b;
                   5686:        if(bxsp->mny>0) {
                   5687:                for(b=bxsp->pa; (*b)!=NULL; b++) free(*b);
                   5688:                if(bxsp->pa!=NULL) free(bxsp->pa);
                   5689:                };
                   5690:        *bxsp = empty_Bbxs;
                   5691:        }
                   5692: 
                   5693: /* Return pointer to local static Bbxs which holds a duplicate of the
                   5694:    given Bbxs (all contents are freshly malloc'ed) */
                   5695: Bbxs *dup_bbxs(old)
                   5696:     Bbxs *old;
                   5697: {   static Bbxs new;
                   5698:     Bbx **o,**n;
                   5699:        if(old->mny>0) {
                   5700:                new.mny = old->mny;
                   5701:                new.alloc = old->alloc;
                   5702:                new.incr = old->incr;
                   5703:                if((new.pa=(Bbx **)malloc((new.alloc)*sizeof(Bbx *)))==NULL)
                   5704:                        abort("dup_bbxs: can't alloc new.pa[%d]",new.alloc);
                   5705:                for(o=old->pa,n=new.pa; *o!=NULL; o++,n++) {
                   5706:                        *(*n = alloc_bbx()) = **o;
                   5707:                        };
                   5708:                *n = NULL;
                   5709:                }
                   5710:        else new = empty_Bbxs;
                   5711:        return(&new);
                   5712:        }
                   5713: 
                   5714: Bbx *append_bbx(bxp,bxsp)
                   5715:    Bbx *bxp;
                   5716:    Bbxs *bxsp;
                   5717: {      if(bxsp->mny>0) {
                   5718:                if((bxsp->mny+2)>bxsp->alloc) {
                   5719:                        bxsp->alloc += bxsp->incr;
                   5720:                        if( ( bxsp->pa =
                   5721:                              (Bbx **)realloc(bxsp->pa,bxsp->alloc*sizeof(Bbx *)) )
                   5722:                            ==NULL )
                   5723:                                abort("append_bbx: can't alloc bxsp->pa[%d]",bxsp->alloc);
                   5724:                        };
                   5725:                }
                   5726:        else {  bxsp->mny=0;
                   5727:                if(bxsp->pa!=NULL) free(bxsp->pa);
                   5728:                bxsp->alloc=0;
                   5729:                while((bxsp->mny+2)>bxsp->alloc) bxsp->alloc += bxsp->incr;
                   5730:                if((bxsp->pa=(Bbx **)malloc(bxsp->alloc*sizeof(Bbx *)))==NULL)
                   5731:                        abort("append_bbx: can't alloc bxsp->a[%d]",bxsp->alloc);
                   5732:                };
                   5733:        bxsp->pa[bxsp->mny++] = bxp;
                   5734:        bxsp->pa[bxsp->mny] = NULL;
                   5735:        }
                   5736: 
                   5737: frda_bbxs(fp,bxsp)
                   5738:     FILE *fp;
                   5739:     Bbxs *bxsp;
                   5740: #define MAX_BBX_LINE (80)
                   5741: {   Bbx *bxp,**bb;
                   5742:     long seek;
                   5743:     char line[MAX_BBX_LINE+1];
                   5744:        *bxsp = empty_Bbxs;
                   5745:        seek = ftell(fp);
                   5746:        /* count all boxes quickly, in advance */
                   5747:        while(!feof(fp)) {
                   5748:                line[0] = '\0';
                   5749:                fgets(line,MAX_BBX_LINE,fp);
                   5750:                if(strlen(line)>0) {
                   5751:                        bxsp->mny++;
                   5752:                        };
                   5753:                };
                   5754:        if((bxsp->pa=(Bbx **)malloc((bxsp->mny+1)*sizeof(Bbx *)))==NULL)
                   5755:                abort("frda_bbxs: can't alloc bxsp->pa[%d]",bxsp->mny+1);
                   5756:        bxsp->alloc = bxsp->mny+1;
                   5757:        /* next, reread boxes */
                   5758:        fseek(fp,(long)seek,0);
                   5759:        bb=bxsp->pa;
                   5760:        while(!feof(fp)) {
                   5761:                line[0] = '\0';
                   5762:                fgets(line,MAX_BBX_LINE,fp);
                   5763:                if(strlen(line)>0) {
                   5764:                        *(bxp = alloc_bbx()) = *ato_bbx(line);
                   5765:                        *(bb++) = bxp;
                   5766:                        };
                   5767:                };
                   5768:        *bb = NULL;
                   5769:        }
                   5770: 
                   5771: fwra_bbxs(fp,bxsp)
                   5772:     FILE *fp;
                   5773:     Bbxs *bxsp;
                   5774: {   Bbx **b;
                   5775:        if(bxsp->mny>0) for(b=bxsp->pa; *b!=NULL; b++) {
                   5776:                fputs(bbx_toa(*b),fp);
                   5777:                fputs("\n",fp);
                   5778:                };
                   5779:        fflush(fp);
                   5780:        }
                   5781: 0707070035351137101006640007620000050000010261240476773366600001000000017772Coord.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   5782: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   5783: /* The copyright notice does not imply actual or intended publication. */
                   5784: /* AUTHORS:                                            */
                   5785: /*     H. S. Baird - ATT-BL MH - first versions        */
                   5786: /* Coord.h - defines, typedefs, Inits, empties, and function declarations
                   5787:    for basic Coordinate geometry data items.
                   5788:    See Coord.c for associated functions.
                   5789:    */
                   5790: 
                   5791: /* Round signed floating-pt no. F:
                   5792:    (a) ROUND - to nearest integer;
                   5793:    (b) ROUND_UP - up to next int;
                   5794:    (c) ROUND_DN - down to prior int.
                   5795:    Evaluates the argument exactly once. */
                   5796: static double _round,_round_up,_round_dn;
                   5797: #define ROUND(F) ((int)(((_round=(F))>=0.0)? _round+0.5: _round-0.5))
                   5798: #define ROUND_UP(F) ((int)(((_round_up=(F))>=0.0)? _round_up+0.999999: _round_up))
                   5799: #define ROUND_DN(F) ((int)(((_round_dn=(F))>=0.0)? _round_dn: _round_dn-0.999999))
                   5800: 
                   5801: /* The basic unit is the scanner pixel, located in the X,Y plane.  As in many
                   5802:    graphics coordinate systems, X increases left-to-right, while Y increases
                   5803:    top-down.  Pixel coordinates are usually integer values.  The physical extent
                   5804:    of integer coordinate `x' along the real X-axis is the half-open interval
                   5805:    [x,x+1), and similarly for Y.  The actual digitizing resolution (e.g.
                   5806:    pixels/inch) represented can vary from document to document, and is almost
                   5807:    always known to the algorithms.  X & Y resolution can be different, though
                   5808:    for simplicity of discussion we will usually assume that they are equal,
                   5809:    i.e. that pixels are square.  Thus pixel (x,y) may be thought of as the region
                   5810:    [x,x+1)X[y,y+1) in the real plane.
                   5811:        Half-pixel resolution is also supported, with its own data types for
                   5812:    clarity.  However, to avoid distracting struggles with the type system, they
                   5813:    are for the most part #defined to be identical to ordinary coordinates.  The
                   5814:    principle effect is that the limits of scanner coordinates have been halved
                   5815:    to allow for safe use of half-pixels everywhere.  (This still permits images
                   5816:    80 inches square at 400 pixels/inch, assuming `short' is at least 16-bit 2's
                   5817:    complement.)
                   5818:        Half-pixel coordinates can also be used to describe boundaries of regions,
                   5819:    as a set of ideal point locations at the corners and edge midpoints of pixels.
                   5820:    The half-pixel data type is used; boundary points are identified by flags
                   5821:    in the Bdy "boundary" structure, and may be displayed differently.   */
                   5822: 
                   5823: #define Scoor short    /* Scanner pixel coordinate value */
                   5824: #define Hcoor Scoor    /* Half-pixel coordinate value */
                   5825: #define Bcoor Hcoor    /* Half-pixel boundary coordinate value */
                   5826: 
                   5827: /* Each Scoor value `v' is associated of course with two Hcoor values `a' < `b'.
                   5828:    Conventionally, the physical extent of the `a' half-coordinate is the real
                   5829:    interval [v,v+0.5), and `b' is [v+0.5,v+1). */
                   5830: #define StoHa(S) ((S)*2)
                   5831: #define StoHb(S) ((S)*2+1)
                   5832: #define HtoS(H) ((H)/2)
                   5833: 
                   5834: /* The 3 half-pixel boundary points of a pixel coordinate `C' are: */
                   5835: #define StoBa(S) (StoHa((S)))          /* minimum of interval */
                   5836: #define StoBb(S) (StoHb((S)))          /* midpoint of interval */
                   5837: #define StoBc(S) (StoHa((S)+1))                /* maximum of interval */
                   5838: 
                   5839: #define Scoor_MIN (SHRT_MIN/2) /* minimum possible value */
                   5840: #define Scoor_MAX (SHRT_MAX/2) /* maximum possible value */
                   5841: 
                   5842: #define Hcoor_MIN (SHRT_MIN)   /* minimum possible value */
                   5843: #define Hcoor_MAX (SHRT_MAX)   /* maximum possible value */
                   5844: 
                   5845: #define fwri_Scoor(F,V) fwri_int2((F),(V))
                   5846: #define frdi_Scoor(F) frdi_int2(F)
                   5847: 
                   5848: #define fwri_Hcoor(F,V) fwri_int2((F),(V))
                   5849: #define frdi_Hcoor(F) frdi_int2(F)
                   5850: 
                   5851: #define fwri_Bcoor(F,V) fwri_int2((F),(V))
                   5852: #define frdi_Bcoor(F) frdi_int2(F)
                   5853: 
                   5854: typedef struct Sp {    /* point: pixel address */
                   5855:        Scoor x;        /* increases left-to-right: Scoor_MIN is left of image */
                   5856:        Scoor y;        /* increases down:  Scoor_MIN is top of image */
                   5857:        } Sp;
                   5858: #define Hp Sp          /* Half-pixel point */
                   5859: 
                   5860: #define Init_Zero_Sp {0,0}
                   5861: #define Init_Min_Sp {Scoor_MIN,Scoor_MIN}
                   5862: #define Init_Max_Sp {Scoor_MAX,Scoor_MAX}
                   5863: 
                   5864: #if MAIN
                   5865: Sp zero_Sp = Init_Zero_Sp;
                   5866: #else
                   5867: extern Sp zero_Sp;
                   5868: #endif
                   5869: 
                   5870: #define fwri_Sp(F,P) { fwri_Scoor((F),(P)->x); fwri_Scoor((F),(P)->y); }
                   5871: #define frdi_Sp(F,P) (feof(F)? 0: ( \
                   5872:        (P)->x=frdi_Scoor(F), \
                   5873:        (P)->y=frdi_Scoor(F), \
                   5874:        (ferror(F)? -errno: 1) ) )
                   5875: 
                   5876: /* Is Sp *p1 exactly equal to Sp *p2? */
                   5877: #define sp_eq(p1,p2) ( \
                   5878:        ((p1)->x == (p2)->x) \
                   5879:         && ((p1)->y == (p2)->y) \
                   5880:        )
                   5881: 
                   5882: typedef struct Sps {   /* Set of Points */
                   5883:        int mny;        /* no. points (mny==0 ==> pa==NULL) */
                   5884:        Sp **pa;        /* NULL-terminated Sp *pa[mny+1] (malloc space)*/
                   5885:        } Sps;
                   5886: 
                   5887: #define Init_Sps {0,NULL}
                   5888: #if MAIN
                   5889: Sps empty_Sps = Init_Sps;
                   5890: #else
                   5891: extern Sps empty_Sps;
                   5892: #endif
                   5893: 
                   5894: typedef struct Spa {   /* array of Points */
                   5895:        int mny;        /* no. points in array */
                   5896:        Sp *a;          /* Sp a[mny] (malloc space)*/
                   5897:        } Spa;
                   5898: /** #define Pointa Spa **/  /* OBSOLESCENT */
                   5899: 
                   5900: #define Init_Spa {0,NULL}
                   5901: #if MAIN
                   5902: Spa empty_Spa = Init_Spa;
                   5903: #else
                   5904: extern Spa empty_Spa;
                   5905: #endif
                   5906: 
                   5907: /* An edge is an ordered pair of vertices. */
                   5908: typedef struct Edge {
                   5909:        Sp a,b;         /* endpoints */
                   5910:        } Edge;
                   5911: 
                   5912: #define Init_Edge {Init_Zero_Sp,Init_Zero_Sp}
                   5913: #if MAIN
                   5914: Edge empty_Edge = Init_Edge;
                   5915: #else
                   5916: extern Edge empty_Edge;
                   5917: #endif
                   5918: 
                   5919: #define fwri_Edge(F,P) { fwri_Sp((F),&((P)->a)); fwri_Sp((F),&((P)->b)); }
                   5920: #define frdi_Edge(F,P) ( feof(F)? 0: ( \
                   5921:        frdi_Sp(F,&((P)->a)), \
                   5922:        frdi_Sp(F,&((P)->b)), \
                   5923:        (ferror(F)? -errno: 1) ) )
                   5924: 
                   5925: /* A bounding box is a rectangle */
                   5926: typedef struct {       /* bounding box: inclusive of boundary values */
                   5927:        Sp a;           /* top-left corner */
                   5928:        Sp b;           /* bottom-right corner */
                   5929:        } Bbx;
                   5930: 
                   5931: typedef struct DSp {   /* point: pixel address */
                   5932:        double x;       /* increases down the page, MinScoor at top */
                   5933:        double y;       /* increases across the page, MinScoor at left */
                   5934:        } DSp;
                   5935: 
                   5936: #define Init_Bbx {Init_Max_Sp,Init_Min_Sp}
                   5937: #define Init_Max_Bbx {Init_Min_Sp,Init_Max_Sp}
                   5938: #if MAIN
                   5939: Bbx empty_Bbx = Init_Bbx;
                   5940: Bbx max_Bbx = Init_Max_Bbx;
                   5941: #else
                   5942: extern Bbx empty_Bbx;
                   5943: extern Bbx max_Bbx;
                   5944: #endif
                   5945: 
                   5946: #define fwri_Bbx(F,P) { fwri_Sp((F),&((P)->a)); fwri_Sp((F),&((P)->b)); }
                   5947: #define frdi_Bbx(F,P) ( feof(F)? 0: ( \
                   5948:        frdi_Sp(F,&((P)->a)), \
                   5949:        frdi_Sp(F,&((P)->b)), \
                   5950:        (ferror(F)? -errno: 1) ) )
                   5951: 
                   5952: /* OBSOLESCENT: */
                   5953: #if MAIN
                   5954: Bbx null_Bbx = {Init_Max_Sp,Init_Min_Sp};
                   5955: #else
                   5956: extern Bbx null_Bbx;
                   5957: #endif
                   5958: 
                   5959: /* height, width, area of Bbx in pixels */
                   5960: #define bbx_hgt(bxp) ((bxp)->b.y-(bxp)->a.y+1)
                   5961: #define bbx_wid(bxp) ((bxp)->b.x-(bxp)->a.x+1)
                   5962: #define bbx_area(bxp) (bbx_hgt((bxp))*bbx_wid((bxp)))
                   5963: 
                   5964: /* Is Bbx *b1 exactly equal to Bbx *b2? */
                   5965: #define bbx_eq(b1,b2) ( \
                   5966:        ((b1)->a.x == (b2)->a.x) \
                   5967:         && ((b1)->a.y == (b2)->a.y) \
                   5968:         && ((b1)->b.x == (b2)->b.x) \
                   5969:         && ((b1)->b.y == (b2)->b.y) \
                   5970:        )
                   5971: 
                   5972: /* Is Bbx *b1 wholly inside Bbx *b2? */
                   5973: #define bbx_inside_all(b1,b2) ( \
                   5974:        ((b1)->a.x >= (b2)->a.x) \
                   5975:         && ((b1)->a.y >= (b2)->a.y) \
                   5976:         && ((b1)->b.x <= (b2)->b.x) \
                   5977:         && ((b1)->b.y <= (b2)->b.y) \
                   5978:        )
                   5979: 
                   5980: /* Is any of Bbx *b1 inside Bbx *b2? */
                   5981: #define bbx_inside_any(b1,b2) ( \
                   5982:        ((b1)->a.x <= (b2)->b.x) \
                   5983:        && ((b1)->a.y <= (b2)->b.y) \
                   5984:        && ((b1)->b.x >= (b2)->a.x) \
                   5985:        && ((b1)->b.y >= (b2)->a.y) \
                   5986:        )
                   5987: 
                   5988: typedef struct Bbxs {  /* A set of Bbxs */
                   5989:        int mny;        /* if mny==0, then pa==NULL */
                   5990:        Bbx **pa;       /* NULL-terminated array (in malloc space) of `mny+1'
                   5991:                           pointers to Bbxs (in malloc space) */
                   5992:        int alloc;      /* no. slots in pa[] actually allocated (>=mny+1) */
                   5993:        int incr;       /* no. slots in pa[] to reallocate at a time */
                   5994:        } Bbxs;
                   5995: 
                   5996: #define Init_Bbxs {0,NULL,0,512}
                   5997: #if MAIN
                   5998: Bbxs empty_Bbxs = Init_Bbxs;
                   5999: #else
                   6000: extern Bbxs empty_Bbxs;
                   6001: #endif
                   6002: 
                   6003: Sp *alloc_sp();
                   6004: free_sp();
                   6005: char *sp_toa();                /* Sp to ascii printable string */
                   6006: Sp *ato_sp();          /* Sp from ascii printable string */
                   6007: frda_sps();
                   6008: Sps *dup_sps();
                   6009: Sp *append_sp_sps();
                   6010: Sp *append_sp_spa();
                   6011: Sp *rotate_Sp();       /* rotate Sp about given fixed-point */
                   6012: Sp *hshear_Sp();       /* horiz-shear Sp about given fixed-point */
                   6013: Edge *alloc_edge();
                   6014: free_edge();
                   6015: char *edge_toa();      /* Edge to ascii printable string */
                   6016: Edge *ato_edge();      /* Edge from ascii printable string */
                   6017: Bbx *alloc_bbx();
                   6018: Bbx *append_bbx();
                   6019: Bbxs *dup_bbxs();
                   6020: char *bbx_toa();       /* Bbx to ascii printable string */
                   6021: Bbx *ato_bbx();                /* Bbx from ascii printable string */
                   6022: Bbx *translate_bbx();
                   6023: boolean bbx_inside_most();     /* Is Bbx 1 mostly inside Bbx 2? */
                   6024: Bbx *expand_bbx();
                   6025: 0707070035351137111006640007620000050000010261300476773366600000700000016417Path.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   6026: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   6027: /* The copyright notice does not imply actual or intended publication. */
                   6028: /* AUTHORS:                                            */
                   6029: /*     H. S. Baird - ATT-BL MH - first versions        */
                   6030: /* Path.c - Path functions */
                   6031: 
                   6032: #include <errno.h>
                   6033: #include <stdio.h>
                   6034: #include <string.h>
                   6035: #define FILE_TREE_INCL 1
                   6036: #include "CPU.h"
                   6037: #include "Path.h"
                   6038: 
                   6039: #define dbg_FTW (0)
                   6040: 
                   6041: /* Return full path string in Path *pp, starting at level `sl';
                   6042:    if the level is too deep or the name at level `sl' is null, return null string.
                   6043:    */
                   6044: char *path_toa(pp,sl)
                   6045:     Path *pp;
                   6046:     int sl;    /* starting level: 0 is first */
                   6047: {   int len,lvl;
                   6048:     static char s[MAX_PATH_DEPTH*(32)];
                   6049:        s[0] = '\0';
                   6050:        if( sl<=pp->level && pp->name[sl]!=NULL && pp->name[sl][0]!='\0' ) {
                   6051:                for(lvl=sl; lvl<=pp->level; lvl++) {
                   6052:                        strcat(s,pp->name[lvl]);
                   6053:                        strcat(s,"/");
                   6054:                        };
                   6055:                };
                   6056:        if((len=strlen(s))>0) s[len-1] = '\0';
                   6057:        return(s);
                   6058:        }
                   6059: 
                   6060: /* no. slashes in a name */
                   6061: int slashes(n)
                   6062:     char *n;
                   6063: {   register int res;
                   6064:     register char *c;
                   6065:        res=0;
                   6066:        c=n;
                   6067:        while(*c!='\0') {
                   6068:                if(*c=='/') res++;
                   6069:                c++;
                   6070:                };
                   6071:        return(res);
                   6072:        }
                   6073: 
                   6074: /* basename */
                   6075: char *bname(n)
                   6076:     char *n;
                   6077: {   register char *res,*c;
                   6078:        res=n-1;
                   6079:        c=n;
                   6080:        while(*c!='\0') {
                   6081:                if(*c=='/') res=c;
                   6082:                c++;
                   6083:                };
                   6084:        return(res+1);
                   6085:        }
                   6086: 
                   6087: #if CPU==VAX || CPU==CRAY
                   6088: 
                   6089: int process_file_tree_node(n,s,code,S)
                   6090:     char *n;
                   6091:     struct stat *s;
                   6092:     int code;
                   6093:     struct FTW *S;
                   6094: /* Uses global `path_process' structure */
                   6095: {   char *out_n;
                   6096:     int persist;
                   6097:     struct stat sbuf;
                   6098:        switch(code) {
                   6099:           case FTW_F:  if(dbg_FTW)err("visit file %s %s %d",n,n+(S->base),S->level);
                   6100:                        if(S->level>0) {
                   6101:                                if(path_process.path.name[S->level]!=NULL)
                   6102:                                        free(path_process.path.name[S->level]);
                   6103:                                path_process.path.name[S->level]=strdup(n+(S->base));
                   6104:                                };
                   6105:                        path_process.path.level = S->level;
                   6106:                        out_n = strdup(path_toa(&path_process.path,0));
                   6107:                        if(dbg_FTW)err("file: %s ==> %s",n,out_n);
                   6108:                        (*path_process.process)(n,out_n,path_process.arg);
                   6109:                        if(out_n!=NULL) free(out_n);
                   6110:                        break;
                   6111:           case FTW_SL: if(dbg_FTW)err("visit link %s %s %d",n,n+(S->base),S->level);
                   6112:                        S->quit = FTW_FOLLOW;    /* follow symbolic link */
                   6113:                        break;
                   6114:           case FTW_D:  /* pre-visit of directory */
                   6115:                        if(dbg_FTW)err("visit dir %s %s %d",n,n+(S->base),S->level);
                   6116:                        if(S->level>0) {
                   6117:                                if(path_process.path.name[S->level]!=NULL)
                   6118:                                        free(path_process.path.name[S->level]);
                   6119:                                path_process.path.name[S->level]=strdup(n+(S->base));
                   6120:                                };
                   6121:                        path_process.path.level = S->level;
                   6122:                        out_n = path_toa(&path_process.path,0);
                   6123:                        if(dbg_FTW)err("dir:   %s --> %s",n,out_n);
                   6124:                        if(out_n[0]=='\0') /* no output name */ break;
                   6125:                        /* ensure directory named out_n exists */
                   6126:                        if(stat(out_n,&sbuf)==0) {
                   6127:                                /* file exists */
                   6128:                                if(!(sbuf.st_mode&S_IFDIR)) {
                   6129:                                        /* not a directory - try to remove */
                   6130:                                        if(unlink(out_n)==0) {
                   6131:                                                if(mkdir(out_n,0777)!=0) {
                   6132:                                                        /* irrecoverable mkdir */
                   6133:                                                        abort("can't mkdir %s",
                   6134:                                                                out_n);
                   6135:                                                        };
                   6136:                                                }
                   6137:                                        else {  /* irrecoverable unlink */
                   6138:                                                abort("can't unlink %s",out_n);
                   6139:                                                };
                   6140:                                        };
                   6141:                                }
                   6142:                        else if(errno==ENOENT) {
                   6143:                                /* file doesn't exist */
                   6144:                                if(mkdir(out_n,0777)!=0) {
                   6145:                                        /* irrecoverable mkdir */
                   6146:                                        abort("can't mkdir %s",out_n);
                   6147:                                        };
                   6148:                                }
                   6149:                        else {  /* irrecoverable stat */
                   6150:                                abort("can't stat %s",out_n);
                   6151:                                };
                   6152:                        break;
                   6153:           case FTW_DP: /* post-visit of directory: ignore it*/
                   6154:                        break;
                   6155:           case FTW_DNR:
                   6156:                        err("can't read dir %s (FTW_DNR) - ignore it",n);
                   6157:                        break;
                   6158:           case FTW_NS:
                   6159:                        err("can't stat %s (FTW_NS) - ignore it",n);
                   6160:                        break;
                   6161:           case FTW_NSL:
                   6162:                        if(0)   /* happens if file is missing */
                   6163:                        err("can't stat symbolic link %s (FTW_NSL) - ignore it",n);
                   6164:                        break;
                   6165:           default:
                   6166:                        err("unexpected FTW code %d - ignore it",code);
                   6167:                        break;
                   6168:           };
                   6169:        return(0);
                   6170:        }
                   6171: 
                   6172: #else
                   6173: #if CPU==MIPS
                   6174: int process_file_tree_node(n,s,code)
                   6175:     char *n;           /* name of the object */
                   6176:     struct stat *s;    /* info. about object */
                   6177:     int code;
                   6178: /* Uses global `path_process' structure */
                   6179: #define lvl path_process.path.level
                   6180: {   char *out_n;
                   6181:     int persist;
                   6182:     struct stat sbuf;
                   6183:     char *bn;
                   6184:        lvl = slashes(n) - path_process.sl0;
                   6185:        bn = bname(n);  
                   6186:        switch(code) {
                   6187:           case FTW_F:  if(dbg_FTW) err("visit file %s, bn %s, lvl %d",n,bn,lvl);
                   6188:                        if(lvl>0) {
                   6189:                                if(path_process.path.name[lvl]!=NULL)
                   6190:                                        free(path_process.path.name[lvl]);
                   6191:                                path_process.path.name[lvl]=strdup(bn);
                   6192:                                };
                   6193:                        out_n = strdup(path_toa(&path_process.path,0));
                   6194:                        if(dbg_FTW)err("file: %s ==> %s",n,out_n);
                   6195:                        (*path_process.process)(n,out_n,path_process.arg);
                   6196:                        if(out_n!=NULL) free(out_n);
                   6197:                        break;
                   6198:           case FTW_D:  /* pre-visit of directory */
                   6199:                        if(dbg_FTW) err("visit dir %s, bn %s, lvl %d",n,bn,lvl);
                   6200:                        if(lvl>0) {
                   6201:                                if(path_process.path.name[lvl]!=NULL)
                   6202:                                        free(path_process.path.name[lvl]);
                   6203:                                path_process.path.name[lvl]=strdup(bn);
                   6204:                                };
                   6205:                        out_n = path_toa(&path_process.path,0);
                   6206:                        if(dbg_FTW)err("dir:  %s --> %s",n,out_n);
                   6207:                        if(out_n[0]=='\0') /* no output name */ break;
                   6208:                        /* ensure directory named out_n exists */
                   6209:                        if(stat(out_n,&sbuf)==0) {
                   6210:                                /* file exists */
                   6211:                                if(!(sbuf.st_mode&S_IFDIR)) {
                   6212:                                        /* not a directory - try to remove */
                   6213:                                        if(unlink(out_n)==0) {
                   6214:                                                if(mkdir(out_n,0777)!=0) {
                   6215:                                                        /* irrecoverable mkdir */
                   6216:                                                        abort("can't mkdir %s",
                   6217:                                                                out_n);
                   6218:                                                        };
                   6219:                                                }
                   6220:                                        else {  /* irrecoverable unlink */
                   6221:                                                abort("can't unlink %s",out_n);
                   6222:                                                };
                   6223:                                        };
                   6224:                                }
                   6225:                        else if(errno==ENOENT) {
                   6226:                                /* file doesn't exist */
                   6227:                                if(mkdir(out_n,0777)!=0) {
                   6228:                                        /* irrecoverable mkdir */
                   6229:                                        abort("can't mkdir %s",out_n);
                   6230:                                        };
                   6231:                                }
                   6232:                        else {  /* irrecoverable stat */
                   6233:                                abort("can't stat %s",out_n);
                   6234:                                };
                   6235:                        break;
                   6236:           case FTW_DNR:
                   6237:                        err("can't read dir %s (FTW_DNR) - ignore it",n);
                   6238:                        break;
                   6239:           case FTW_NS:
                   6240:                        err("can't stat %s (FTW_NS) - ignore it",n);
                   6241:                        break;
                   6242:           default:
                   6243:                        err("unexpected FTW code %d - ignore it",code);
                   6244:                        break;
                   6245:           };
                   6246:        return(0);
                   6247:        }
                   6248: 
                   6249: #endif
                   6250: #endif
                   6251: 
                   6252: /* Process every leaf file (non-directory) in the file-tree rooted at `in_ftn'.
                   6253:    If `in_ftn' is itself a leaf, then only it is processed.  If it is a directory,
                   6254:    then a corresponding file-tree is built, rooted at `out_ftn', and paths
                   6255:    to its leaves created by `mkdir's as required;  for each pair of corresponding
                   6256:    leaf filenames, `process' is called.  The filenames have not yet been opened.
                   6257:    If `out_ftn' is the empty string, then no output file-tree will be generated
                   6258:    and the corresponding output filenames will all be null.  If `in_ftn' is the
                   6259:    empty string, then `process' is called only once, with the input filename
                   6260:    empty.  Pass 'arg' to 'process' as third argument. */
                   6261: process_file_trees(process,in_ftn,out_ftn,arg)
                   6262:     VOID (*process)();
                   6263:     char *in_ftn;      /* may be empty */
                   6264:     char *out_ftn;     /* may be empty */
                   6265:     VOID *arg;         /* passed to '(*process)()' as 3rd argument */
                   6266: /* Uses global `path_process' structure */
                   6267: {   int level;
                   6268:        if(in_ftn[0]=='\0') (*process)(in_ftn,out_ftn,arg);
                   6269:        else {  if(dbg_FTW) err("process_file_trees(%s,%s)",in_ftn,out_ftn);
                   6270:                path_process.path.level = 0;
                   6271:                path_process.path.name[0] = out_ftn;
                   6272:                path_process.sl0 = slashes(in_ftn);
                   6273:                for(level=1; level<MAX_PATH_DEPTH; level++)
                   6274:                        path_process.path.name[level] = NULL;
                   6275:                path_process.process = process;
                   6276:                path_process.arg = arg;
                   6277:                if(ftw(in_ftn,process_file_tree_node,MAX_PATH_DEPTH)<0)
                   6278:                        err("ftw error: errno %d",errno);
                   6279:                };
                   6280:        }
                   6281: 0707070035351137121006640007620000050000010261310476773366700000700000001611Path.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   6282: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   6283: /* The copyright notice does not imply actual or intended publication. */
                   6284: /* AUTHORS:                                            */
                   6285: /*     H. S. Baird - ATT-BL MH - first versions        */
                   6286: 
                   6287: /* Path.h - Path names */
                   6288: 
                   6289: #define MAX_PATH_DEPTH (16)    /* maximum expected names in path */
                   6290: 
                   6291: typedef struct Path {
                   6292:        int level;                      /* current level */
                   6293:        char *name[MAX_PATH_DEPTH];     /* name[0] is output root name;
                   6294:                                           the rest are basenames (both input
                   6295:                                           and output) */
                   6296:        } Path;
                   6297: 
                   6298: typedef struct Path_process {
                   6299:        int sl0;                /* no. slashes in input root name */
                   6300:        Path path;
                   6301:        VOID (*process)();
                   6302:        VOID *arg;              /* passed as 3rd arg to (*process)() */
                   6303:        } Path_process;
                   6304: 
                   6305: Path_process path_process;     /* controls file-tree processing */
                   6306: 
                   6307: char *path_toa();      /* see Path.c */
                   6308: 0707070035351137131006640007620000050000010261330476773367000000700000404335Text.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   6309: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   6310: /* The copyright notice does not imply actual or intended publication. */
                   6311: /* AUTHORS:                                            */
                   6312: /*     H. S. Baird - ATT-BL MH - first versions        */
                   6313: 
                   6314: /* Text.c - functions for Document-image file ("dim" file) handling
                   6315: 
                   6316:    General Introduction
                   6317:    --------------------
                   6318: 
                   6319:    Dim files describe a document as a collection of records of these types:
                   6320:        Page    full page
                   6321:        Block   block (often a column) of text
                   6322:        Txtln   line of text
                   6323:        Word    word
                   6324:        Char    character, isolated symbol, `graph'
                   6325:        Interp  interpretation of a character (result of classification)
                   6326:        Sfeats  scalar features of a character
                   6327:        Shapes  local shape features of a character
                   6328:        Bfeats  binary indicator features of a character
                   6329:        Blob    connected component (maximal subset of 8-connected black pixels)
                   6330:        Lag     line-adjacency graph of runs
                   6331:        Run     horizontal run of black pixels
                   6332:         Pixel   bilevel (black/white) picture element (symbols are expected to
                   6333:                be black against a white background); usually square
                   6334: 
                   6335:    They may be organized hierarchically --
                   6336:        a Page may own :  Blocks, Txtlns, Words, Chars, & Blobs
                   6337:          a Block may own :  Blocks, Txtlns, Words, Chars, & Blobs
                   6338:            a Txtln may own :  Txtlns, Words, Chars, & Blobs
                   6339:              a Word may own :  Words, Chars & Blobs
                   6340:                a Char may own :  Blobs, Interps, Sfeats, Shapes, & Bfeats
                   6341:                  a Blob may own :  Runs (variously represented)
                   6342:                    a Run owns :  black Pixels
                   6343:     Note that the hierarchy is strict except that Blocks, Txtlns, & Words may
                   6344:     own records of their own type.  This serves several functions:
                   6345:     --  a Block may own other Blocks, conventionally nested within it, to
                   6346:        represent a physical or logical page layout decomposition;
                   6347:     --  a Txtln may have alternative interpretations & segmentations into Words;
                   6348:     --  a Word may have alternative segmentations into Chars.
                   6349: 
                   6350:     For each record type R, there should exist these data-structures:
                   6351:        R                       struct
                   6352:        Init_R                  #define'd initialization string
                   6353:        empty_R                 an extern ``empty'' (initialized) instance of R
                   6354:     Also there are library functions (in which _R is spelled in lower-case):
                   6355:        R *alloc_R()            allocate memory and initialize to ``empty''
                   6356:        free_R(R *)             free memory (only of record R, not what it owns)
                   6357:        free_R_etc(R *,ids)     free R and what it owns (as specified by `ids')
                   6358:        R *dup_R(R *)           return distinct copy, with duplicated contents
                   6359:        R *dup_R_etc(R *,ids)   return distinct copy, duplicated contents & parts
                   6360:        char *R_toa(R *)        convert to printable ASCII string
                   6361:        frdb_R(FILE *, R *)     fread R (binary) from file thru pointer
                   6362:        frdb_R_etc(",",ids)     fread R (binary) and what it owns (as specified)
                   6363:        fwrb_R(FILE *, R *)     fwrite R (binary) to file thru pointer
                   6364:        fwrb_R_etc(",",ids)     fwrite R (binary) and what it owns (as specified)
                   6365:     (some of these may be unimplemented if they haven't yet been needed)
                   6366: 
                   6367:     I/O conventions:
                   6368:     -- frd?_... return one of:
                   6369:            1  normal & successful
                   6370:            0  EOF
                   6371:           <0  I/O errors
                   6372:        Quite a few functions don't obey this rule yet.
                   6373:        Many intermediate fns that don't directly perform I/O
                   6374:        don't bother passing back status from fns they call.
                   6375:        Those that perform I/O directly often complain to stderr and exit(2).
                   6376:        The situation is fairly chaotic, and has already caused bugs.
                   6377: 
                   6378:     Generally:
                   6379:     -- An `etc' argument is a set of Ident bits specifying a set of record types;
                   6380:        it is passed along unchanged in calls to other _etc functions.
                   6381:     --  `fwrb_R_etc' fns obey the `etc' instructions carefully,  writing only those
                   6382:        record types specified
                   6383:     --  `frdb_R_etc' fns mostly ignore `etc', blindly reading everything they
                   6384:        see (since they aren't clever enough to skip past yet);  however, the
                   6385:        Blob-reading fns look at the Runs_?? bits to select a main memory
                   6386:        format for Runs
                   6387:     -- `frdb_R_etc' uses alloc_Y to allocate all new Y
                   6388:     -- `fwrb_R_etc', however, does NOT free anything: this must be done explicitly
                   6389:        afterwards.
                   6390: 
                   6391:     Ownership of a set of records is implemented by two fields in the owner record:
                   6392:     (1) a count of the number of members, and (2) either a ``set'' or a ``list''
                   6393:     pointer:
                   6394:        set:  to a NULL-terminated array of pointers to records
                   6395:        list: to the first in a singly-linked, NULL-terminated, chain
                   6396:     sets are used for sets of Blocks, Txtlns, Words, Chars, and Blobs
                   6397:     lists are used for Interpl, and for Blobs owned by Chars, since they tend
                   6398:        to be fewer
                   6399: 
                   6400:     Blobs and Runs are treated more elaborately than other records.  Blobs are
                   6401:     collected in lists when owned by Chars, but in sets otherwise --
                   6402:     the motivation was that the Char lists are usually very short, and the malloc
                   6403:     overhead of creating them might be unpleasant -- however, maintaining two
                   6404:     kinds of sets has caused other headaches; it might be good someday to
                   6405:     abolish lists in favor of sets throughout.
                   6406:     Runs can often be compressed to about half the usual size by using char
                   6407:     fields instead of shorts, and this is done automatically when writing to files.    There is both a set and a list form of Run.
                   6408: 
                   6409:     The peripheral file format is:
                   6410:     - deliberately decoupled from the internal (main memory) format:  i.e.
                   6411:        the main memory structs can be (and are) changed frequently for
                   6412:        purposes of experimentation without forcing frequent reformatting
                   6413:        of the (by now large) backlog of archived files (particularly the
                   6414:        character image databases).  To bring such files up-to-date, the program
                   6415:        `renew' should be used: it must be edited to reflect changes since
                   6416:        the last overhaul of the file format.
                   6417:     - designed to be ``scannable'': that is, one can skip rapidly from record
                   6418:        to record (using the Ident headers) without minding the hierarchy.
                   6419:        This is most useful for the graphics editor "met", where it permits
                   6420:        quick response at the outset.  It is also used widely in the
                   6421:        off-line training programs, where main memory is at a premium.
                   6422:     - machine-independent:  floating-point representations are forced to
                   6423:        fixed point and scaled to integer; all integer representations are
                   6424:        written as a sequence of bytes in a fixed order, via putc()/getc().
                   6425:        fwrite()/fread() are never used for binary I/O.  This seems to work
                   6426:        on virtually all UNIX machines.  See fioi.h.
                   6427: 
                   6428:     CCITT Group 4 encodings have been implemented and are available
                   6429:     as a peripheral file format for Blobs.  They offer a large compression
                   6430:     factor (x8) over RunF and RunFS records, and the CPU overhead is not
                   6431:     excessive.  It turns out that the connectivity information represented
                   6432:     explicitly in Run records but lost in ccitt-g4 can be recovered in linear
                   6433:     time and space (see fix_lag()); in practice the extra recovery time is
                   6434:     negligible and the extra space is 0.  This is possible because Blobs are
                   6435:     known to be connected:  if not, then (I suspect that) superlinear time is
                   6436:     required in general to recover the lag.
                   6437: 
                   6438:   */
                   6439: 
                   6440: #include <stdio.h>
                   6441: #include <math.h>
                   6442: #define LIBC_INCL 1
                   6443: #include "CPU.h"
                   6444: #include "stdocr.h"
                   6445: #include "rle.h"
                   6446: #include "Text.h"
                   6447: #include "bitio.h"
                   6448: #include "CCITT.h"
                   6449: 
                   6450:        long fseek(),lseek();
                   6451: 
                   6452: #define dbg_fwrb T     /* failsafe consistency checking */
                   6453: #define dbg_frdb T     /* failsafe consistency checking */
                   6454: #define dbg_fwrb_runs F        /* announce no. bytes used to write each Blob's Runs */
                   6455: #define dbg_frdb_runs F        /* announce no. bytes used to write each Blob's Runs */
                   6456: 
                   6457: /* return ASCII string describing ident bits */
                   6458: char *ident_toa(id)
                   6459:        Ident id;
                   6460: {      static char s[80];
                   6461:        s[0]='\0';
                   6462:     if((id&IsALL)==IsALL) strcat(s,"ALL");
                   6463:     else {
                   6464:        if(id&IsPage) {
                   6465:                strcat(s,"PG");
                   6466:                if(id&(Page_label)) {
                   6467:                        strcat(s,".");
                   6468:                        if(id&Page_label) strcat(s,"l");
                   6469:                        };
                   6470:                }
                   6471:        if(id&IsBlock) {
                   6472:                strcat(s,"BK");
                   6473:                if(id&(Block_wst|Block_label)) {
                   6474:                        strcat(s,".");
                   6475:                        if(id&Block_wst) strcat(s,"w");
                   6476:                        if(id&Block_label) strcat(s,"l");
                   6477:                        };
                   6478:                };
                   6479:        if(id&IsTxtln) {
                   6480:                strcat(s,"TL");
                   6481:                if(id&(Txtln_basl|Txtln_size|Txtln_label)) {
                   6482:                        strcat(s,".");
                   6483:                        if(id&Txtln_basl) strcat(s,"b");
                   6484:                        if(id&Txtln_size) strcat(s,"s");
                   6485:                        if(id&Txtln_label) strcat(s,"l");
                   6486:                        };
                   6487:                };
                   6488:        if(id&IsWord) {
                   6489:                strcat(s,"WD");
                   6490:                if(id&(Word_spelled|Word_label)) {
                   6491:                        strcat(s,".");
                   6492:                        if(id&Word_spelled) strcat(s,"s");
                   6493:                        if(id&Word_label) strcat(s,"l");
                   6494:                        };
                   6495:                };
                   6496:        if(id&IsWordInterp) {
                   6497:                strcat(s,"WI");
                   6498:                if(id&(Word_spelled|Word_numeric|Word_initcap|Word_allcaps|Word_hyphens|Word_slashes|Word_termhyp|Word_endsent)) {
                   6499:                        strcat(s,".");
                   6500:                        if(id&Word_spelled) strcat(s,"s");
                   6501:                        if(id&Word_numeric) strcat(s,"n");
                   6502:                        if(id&Word_initcap) strcat(s,"i");
                   6503:                        if(id&Word_allcaps) strcat(s,"a");
                   6504:                        if(id&Word_hyphens) strcat(s,"-");
                   6505:                        if(id&Word_slashes) strcat(s,"/");
                   6506:                        if(id&Word_termhyp) strcat(s,"h");
                   6507:                        if(id&Word_endsent) strcat(s,".");
                   6508:                        };
                   6509:                };
                   6510:        if(id&IsChar) {
                   6511:                strcat(s,"CH");
                   6512:                if(id&(Char_spelled|Char_confused|Char_termhyp|Char_omit|Char_label|Char_ranparms)) {
                   6513:                        strcat(s,".");
                   6514:                        if(id&Char_spelled) strcat(s,"s");
                   6515:                        if(id&Char_confused) strcat(s,"c");
                   6516:                        if(id&Char_termhyp) strcat(s,"h");
                   6517:                        if(id&Char_omit) strcat(s,"o");
                   6518:                        if(id&Char_label) strcat(s,"l");
                   6519:                        if(id&Char_ranparms) strcat(s,"r");
                   6520:                        if(id&Char_split) strcat(s,"S");
                   6521:                        if(id&Char_merged) strcat(s,"M");
                   6522:                        };
                   6523:                };
                   6524:        if(id&IsInterp) {
                   6525:                strcat(s,"IN");
                   6526:                if(id&Interp_spelled) {
                   6527:                        strcat(s,".s");
                   6528:                        };
                   6529:                };
                   6530:        if(id&IsBlob) {
                   6531:                strcat(s,"BB");
                   6532:                if( id&(Blob_lm|Blob_rm|Blob_tm|Blob_bm
                   6533:                         |Blob_chopt|Blob_chopb|Blob_chopl|Blob_chopr
                   6534:                         |Blob_small|Blob_local)
                   6535:                         ) {
                   6536:                        strcat(s,".");
                   6537:                        if(id&(Blob_tm|Blob_bm|Blob_lm|Blob_rm)) {
                   6538:                                if(id&Blob_lm) strcat(s,"l");
                   6539:                                if(id&Blob_rm) strcat(s,"r");
                   6540:                                if(id&Blob_tm) strcat(s,"t");
                   6541:                                if(id&Blob_bm) strcat(s,"b");
                   6542:                                };
                   6543:                        if(id&(Blob_chopt|Blob_chopb|Blob_chopl|Blob_chopr)) {
                   6544:                                if(id&Blob_chopl) strcat(s,"L");
                   6545:                                if(id&Blob_chopr) strcat(s,"R");
                   6546:                                if(id&Blob_chopt) strcat(s,"T");
                   6547:                                if(id&Blob_chopb) strcat(s,"B");
                   6548:                                };
                   6549:                        if(id&Blob_small) strcat(s,"s");
                   6550:                        if(id&Blob_local) strcat(s,"o");
                   6551:                        };
                   6552:                }
                   6553:            };
                   6554:        return(s);
                   6555:        }
                   6556: 
                   6557: /* convert a conventional character-code to a record type */
                   6558: Ident cto_ident(c)
                   6559:     char c;
                   6560: {   Ident type;
                   6561:        switch(c) {
                   6562:            case 'b':
                   6563:                type=IsBlob;  break;
                   6564:            case 'B': case 'k':
                   6565:                type=IsBlock;  break;
                   6566:            case 'c':
                   6567:                type=IsChar;  break;
                   6568:            case 'i':
                   6569:                type=IsInterp;  break;
                   6570:            case 'p':  case 'P':
                   6571:                type=IsPage;  break;
                   6572:            case 'r':
                   6573:                type=IsRun;  break;
                   6574:            case 't': case 'l':
                   6575:                type=IsTxtln;  break;
                   6576:            case 'w':
                   6577:                type=IsWord;  break;
                   6578:            case 'y':
                   6579:                type=IsBdy;  break;
                   6580:            };
                   6581:        return(type);
                   6582:        }
                   6583: 
                   6584: Ident cto_flag(c,type)
                   6585:     char c;
                   6586:     Ident type;
                   6587: {   Ident flag;
                   6588:        flag = IsNONE;
                   6589:        if(type&IsPage) {
                   6590:                switch(c) {
                   6591:                        case 'l': flag |= Page_label; break;
                   6592:                        };
                   6593:                }
                   6594:        else if(type&IsBlock) {
                   6595:                switch(c) {
                   6596:                        case 'w': flag |= Block_wst; break;
                   6597:                        case 'l': flag |= Block_label; break;
                   6598:                        };
                   6599:                }
                   6600:        else if(type&IsTxtln) {
                   6601:                switch(c) {
                   6602:                        case 'b': flag |= Txtln_basl; break;
                   6603:                        case 's': flag |= Txtln_size; break;
                   6604:                        case 'l': flag |= Txtln_label; break;
                   6605:                        };
                   6606:                }
                   6607:        else if(type&IsWord) {
                   6608:                switch(c) {
                   6609:                        case 's': flag |= Word_spelled; break;
                   6610:                        case 'n': flag |= Word_numeric; break;
                   6611:                        case 'i': flag |= Word_initcap; break;
                   6612:                        case 'a': flag |= Word_allcaps; break;
                   6613:                        case '-': flag |= Word_hyphens; break;
                   6614:                        case '/': flag |= Word_slashes; break;
                   6615:                        case 'h': flag |= Word_termhyp; break;
                   6616:                        case '.': flag |= Word_endsent; break;
                   6617:                        case 'l': flag |= Word_label; break;
                   6618:                        };
                   6619:                }
                   6620:        else if(type&IsChar) {
                   6621:                switch(c) {
                   6622:                        case 's': flag |= Char_spelled; break;
                   6623:                        case 'c': flag |= Char_confused; break;
                   6624:                        case 'h': flag |= Char_termhyp; break;
                   6625:                        case 'o': flag |= Char_omit; break;
                   6626:                        case 'l': flag |= Char_label; break;
                   6627:                        case 'r': flag |= Char_ranparms; break;
                   6628:                        case 'S': flag |= Char_split; break;
                   6629:                        case 'M': flag |= Char_merged; break;
                   6630:                        };
                   6631:                }
                   6632:        else if(type&IsBlob) {
                   6633:                switch(c) {
                   6634:                        case 'B': flag |= Blob_chopb; break;
                   6635:                        case 'L': flag |= Blob_chopl; break;
                   6636:                        case 'R': flag |= Blob_chopr; break;
                   6637:                        case 'T': flag |= Blob_chopt; break;
                   6638:                        case 'b': flag |= Blob_bm; break;
                   6639:                        case 'l': flag |= Blob_lm; break;
                   6640:                        case 'o': flag |= Blob_local; break;
                   6641:                        case 'r': flag |= Blob_rm; break;
                   6642:                        case 's': flag |= Blob_small; break;
                   6643:                        case 't': flag |= Blob_tm; break;
                   6644:                        };
                   6645:                }
                   6646:        else if(type&IsInterp) {
                   6647:                switch(c) {
                   6648:                        case 's': flag |= Interp_spelled; break;
                   6649:                        };
                   6650:                };
                   6651:        return(flag);
                   6652:        }
                   6653: 
                   6654: #if FRDI
                   6655: /* read only the Ident of the next record; if EOF, return 0 */
                   6656: Ident frdb_ident(fp)
                   6657:     FILE *fp;
                   6658: {   Ident ident;
                   6659:        ident = frdi_Ident(fp);
                   6660: #if dbg_frdb_toa
                   6661:        err("frdb_ident: %s",ident_toa(ident));
                   6662: #endif
                   6663:        if(feof(fp)) return(0);
                   6664:        else return(ident);
                   6665:        }
                   6666: #else
                   6667: /* read only the Ident of the next record; return 0 iff EOF */
                   6668: Ident frdb_ident(fp)
                   6669:     FILE *fp;
                   6670: {   Ident ident;
                   6671:     int stat;
                   6672:        if((stat=fread(&ident,sizeof(Ident),1,fp))!=1) {
                   6673:                if(stat==0) return(0);
                   6674:                else abort("frdb_ident: can't fread, status %d",stat);
                   6675:                };
                   6676:        if( Readvax ) ident = swapintin(ident);
                   6677: #if dbg_frdb_toa
                   6678:        err("frdb_ident: %s",ident_toa(ident));
                   6679: #endif
                   6680:        if(feof(fp)) return(0);
                   6681:        else return(ident);
                   6682:        }
                   6683: #endif
                   6684: 
                   6685: #if FRDI
                   6686: /* read label into malloc space */
                   6687: char *frdb_label(f)
                   6688:     FILE *f;
                   6689: {   register char *res;
                   6690:        res=frdi_str(f);
                   6691: #if dbg_frdb_toa
                   6692:        err("frdb_label: \"%s\"",res);
                   6693: #endif
                   6694:        return(res);
                   6695:        }
                   6696: #else
                   6697: /* read label into malloc space */
                   6698: char *frdb_label(fp)
                   6699:     FILE *fp;
                   6700: {   static char s[MAX_LABEL_LEN];
                   6701:     char *c,*ce,*l;
                   6702:     int ch;
                   6703:        ce=(c=s)+MAX_LABEL_LEN-1;
                   6704:        while((c<ce)&&((ch=getc(fp))!=EOF)&&(ch!='\0')) *(c++) = ch;
                   6705:        *c='\0';
                   6706:        if(c==ce) {
                   6707:                /* label is truncated; find end of it */
                   6708:                while(((ch=getc(fp))!=EOF)&&(ch!='\0')) ;
                   6709:                };
                   6710:        if((l=strdup(s))==NULL)
                   6711:                abort("frdb_label: can't dup char *s[%d]",strlen(s));
                   6712: #if dbg_frdb_toa
                   6713:        err("frdb_label: \"%s\"",l);
                   6714: #endif
                   6715:        return(l);
                   6716:        }
                   6717: #endif
                   6718: 
                   6719: /* skip label */
                   6720: fskb_label(fp)
                   6721:     FILE *fp;
                   6722: {   int ch;
                   6723:        while(((ch=getc(fp))!=EOF)&&(ch!='\0')&&(ch!='\n')) ;
                   6724:        if(ch==EOF) return(0); else return(1);
                   6725:        }
                   6726: 
                   6727: /* Skip the REST of this record (the Ident is assumed to have been read),
                   6728:    and return the Ident of the next record in the file;
                   6729:    else return:
                   6730:         0      EOF
                   6731:        -1      I/O error
                   6732:        -2      not one of: Page, Block, Txtln, Char, Interp
                   6733:    */
                   6734: char *pp_toa(ppp)
                   6735:     Pp *ppp;
                   6736: {    static char s[30];
                   6737:        sprintf(s,"(%0.2f,%0.2f)",ppp->x,ppp->y);
                   6738:        return(s);
                   6739:        }
                   6740: 
                   6741: /* return integer string in the range 00-99 */
                   6742: char *merit_toa(m)
                   6743:     Merit m;
                   6744: {   static char s[3];
                   6745:     int im;
                   6746:        im = (int)(m * 100);
                   6747:        if(im>99) im=99; else if(im<0) im=0;
                   6748:        if(im<10) {
                   6749:                s[0] = '0';
                   6750:                sprintf(s+1,"%d",im);
                   6751:                }
                   6752:        else sprintf(s,"%2d",im);
                   6753:        s[3] = '\0';
                   6754:        return(s);
                   6755:        }
                   6756: 
                   6757: char *pts_toa(p)
                   6758:     Pts p;
                   6759: {   static char s[10];
                   6760:        sprintf(s,"%g",((int)((p*10.0)+0.5))/10.0);
                   6761:        return(s);
                   6762:        }
                   6763: 
                   6764: Bdy *alloc_bdy()
                   6765: {    Bdy *p;
                   6766:        if((p=(Bdy *)malloc(sizeof(Bdy)))==NULL)
                   6767:                abort("alloc_bdy: can't malloc");
                   6768:        else {  *p = empty_Bdy;
                   6769:                return(p);
                   6770:                };
                   6771:        }
                   6772: 
                   6773: Bdys *alloc_bdys()
                   6774: {    Bdys *p;
                   6775:        if((p=(Bdys *)malloc(sizeof(Bdys)))==NULL)
                   6776:                abort("alloc_bdys: can't malloc");
                   6777:        else {  *p = empty_Bdys;
                   6778:                return(p);
                   6779:                };
                   6780:        }
                   6781: 
                   6782: char *bdyedge_toa(bep)
                   6783:     BdyEdge *bep;
                   6784: {   static char s[80];
                   6785:     char aps[20];
                   6786:        strcpy(aps,sp_toa(bep->ap));
                   6787:        sprintf(s,"%s,%s p%d c%s a%0.2f",
                   6788:                aps, sp_toa(bep->bp),
                   6789:                bep->per,
                   6790:                pp_toa(&(bep->ctr)),
                   6791:                (bep->ang/PI)*180.0);
                   6792:        return(s);
                   6793:        }
                   6794: 
                   6795: free_bdyedges(besp)
                   6796:     BdyEdges *besp;
                   6797: {   register BdyEdge *bep,**bepp;
                   6798:        if(besp->pa!=NULL) {
                   6799:                if(besp->mny>0) {
                   6800:                        for(bep= *(bepp=besp->pa); bep!=NULL; bep= *(++bepp))
                   6801:                                free(bep);
                   6802:                        };
                   6803:                free(besp->pa);
                   6804:                };
                   6805:        *besp = empty_BdyEdges;
                   6806:        }
                   6807: 
                   6808: /* Skip past the "TYPE=document-image\n\n" (or "TYPE=dim\n\n") ASCII header from
                   6809:    file *fp, read and check the Doc record, and, if all's well, return 1.
                   6810:    If an immediate EOF, return 0.  If not EOF, and no "TYPE=" header,
                   6811:    leave fp as it was, and return -1.  If a malformed "TYPE=" header, leave fp
                   6812:    as it was, and return -2. */
                   6813: int skip_type(fp)
                   6814:     FILE *fp;
                   6815: {   int ich,stat;
                   6816:     long seek;
                   6817: #define MAX_TYPE_HDR_LEN (100)
                   6818:     char type_eq[MAX_TYPE_HDR_LEN+1];
                   6819:     register char *pcp,*ccp,*ecp;
                   6820:     int version;
                   6821: 
                   6822:        seek = ftell(fp);
                   6823:        /* test for EOF */
                   6824:        if(feof(fp) || (ich=getc(fp))==EOF)
                   6825:                /* premature EOF*/ return(0);
                   6826:        if((type_eq[0]=ich)!='T') {
                   6827:                /* no "TYPE=" header */
                   6828:                ungetc(ich,fp);         /* fast, guaranteed push-back */
                   6829:                return(-1);
                   6830:                };
                   6831:        /* try to read the rest of "TYPE=" */
                   6832:        for(ecp=(ccp=type_eq+1)+4; ccp<ecp; ccp++) {
                   6833:                if(feof(fp) || (ich=getc(fp))==EOF) {
                   6834:                        /* no "TYPE=" header */
                   6835:                        fseek(fp,seek,0);
                   6836:                        return(-1);
                   6837:                        }
                   6838:                else *ccp=ich;
                   6839:                }
                   6840:        *ccp='\0';
                   6841:        /* check for "TYPE=" so far */
                   6842:        if(strcmp(type_eq,"TYPE=")==0) {
                   6843:                /* read rest of ASCII header */
                   6844:                ccp=(pcp=type_eq+3)+1;  ecp=type_eq+MAX_TYPE_HDR_LEN;
                   6845:                do {    ccp++; pcp++;
                   6846:                        if((ich=getc(fp))==EOF) {
                   6847:                                /* malformed "TYPE=" header */
                   6848:                                fseek(fp,seek,0);
                   6849:                                return(-2);
                   6850:                                }
                   6851:                        else *ccp=ich;
                   6852:                        }
                   6853:                while(ccp<ecp && (*ccp!='\n'||*pcp!='\n'));
                   6854:                if(ccp==ecp) {
                   6855:                        /* malformed "TYPE=" header */
                   6856:                        fseek(fp,seek,0);
                   6857:                        return(-2);
                   6858:                        };
                   6859:                *pcp='\0';
                   6860:                /* check that it is "TYPE=document-image\n\n" or "TYPE=dim\n\n" */
                   6861:                if(strcmp(type_eq,"TYPE=document-image")!=0
                   6862:                   && strcmp(type_eq,"TYPE=dim")!=0) {
                   6863:                        /* malformed "TYPE=" header */
                   6864:                        fseek(fp,seek,0);
                   6865:                        return(-2);
                   6866:                        };
                   6867: #if dbg_frdb_toa
                   6868:                err("skip_type: \"%s\\n\\n\"",type_eq);
                   6869: #endif
                   6870:                return(1);      /* normal and successful TYPE= header */
                   6871:                }
                   6872:        else {  /* no "TYPE=" header */
                   6873:                fseek(fp,seek,0);
                   6874:                return(-1);
                   6875:                };
                   6876:        }
                   6877: 
                   6878: Doc *alloc_doc()
                   6879: {    Doc *p;
                   6880:        if((p=(Doc *)malloc(sizeof(Doc)))==NULL)
                   6881:                abort("alloc_doc: can't malloc");
                   6882:        else {  *p = empty_Doc;
                   6883:                return(p);
                   6884:                };
                   6885:        }
                   6886: 
                   6887: char *doc_toa(p)
                   6888:     Doc *p;
                   6889: {    static char s[80];
                   6890:        sprintf(s,"Doc v%d p%d l%s",
                   6891:                p->version,
                   6892:                p->ps.mny,
                   6893:                (p->l!=NULL)? p->l: "");
                   6894:        return(s);
                   6895:        }
                   6896: 
                   6897: #if FWRI
                   6898: /* write the given doc (record only) */
                   6899: fwrb_doc(f,p)
                   6900:     FILE *f;
                   6901:     Doc *p;
                   6902: {   int stat;
                   6903:        fwri_uint1(f,p->version);
                   6904:        fwri_uint2(f,p->ps.mny);
                   6905: #if dbg_fwrb_toa
                   6906:        err("fwrb_doc: %s",doc_toa(p));
                   6907: #endif
                   6908:        if(p->l!=NULL) {
                   6909:                fwri_ch(f,'l');
                   6910:                fwrb_label(f,p->l);
                   6911:                }
                   6912:        else fwri_ch(f,'\0');
                   6913:        }
                   6914: #else
                   6915: fwrb_doc(f,p)
                   6916:     FILE *f;
                   6917:     Doc *p;
                   6918: {}
                   6919: #endif
                   6920: 
                   6921: #if FRDI
                   6922: /* read a Doc record (only) - it must be next in the file;
                   6923:    don't immediately read its parts; return 0 iff immediate EOF.
                   6924:    Check for correct version no: if fails, abort.  */
                   6925: int frdb_doc(f,p)
                   6926:     FILE *f;
                   6927:     Doc *p;
                   6928: {   char qlabel;
                   6929:        *p = empty_Doc;
                   6930:        if(feof(f))
                   6931:                return(0);
                   6932:        p->version=frdi_uint1(f);
                   6933:        p->ps.mny=frdi_uint2(f);
                   6934:        if((qlabel=frdi_ch(f))=='l')
                   6935:                p->l=frdb_label(f);
                   6936: #if dbg_frdb_toa
                   6937:        err("frdb_doc: %s",doc_toa(p));
                   6938: #endif
                   6939:        if(ferror(f)) return(-errno); else return(1);
                   6940:        }
                   6941: #else
                   6942: int frdb_doc(f,p)
                   6943:     FILE *f;
                   6944:     Doc *p;
                   6945: {      return(1);
                   6946:        }
                   6947: #endif
                   6948: 
                   6949: #if FWRI
                   6950: /* Write the initial Doc record */
                   6951: put_doc(f)
                   6952:     FILE *f;
                   6953: {   Doc doc;
                   6954:        doc = empty_Doc;
                   6955:        doc.version = DIM_VERSION;
                   6956:        doc.ps.mny = 1;
                   6957:        fwrb_doc(f,&doc);
                   6958:        }
                   6959: #else
                   6960: put_doc(f)
                   6961:     FILE *f;
                   6962: {}
                   6963: #endif
                   6964: 
                   6965: #if FRDI
                   6966: /* read, check, discard, and skip past the Doc record */
                   6967: int skip_doc(f)
                   6968:     FILE *f;
                   6969: {   Doc doc;
                   6970:        frdb_doc(f,&doc);
                   6971:        if(doc.version!=DIM_VERSION)
                   6972:                abort("skip_doc: version %d != DIM_VERSION %d",
                   6973:                        doc.version,DIM_VERSION);
                   6974:        if(doc.l!=NULL) free(doc.l);
                   6975:        return(1);
                   6976:        }
                   6977: #else
                   6978: int skip_doc(f)
                   6979:     FILE *f;
                   6980: {   Doc doc;
                   6981:        return(1);
                   6982:        }
                   6983: #endif
                   6984: 
                   6985: Page *alloc_page()
                   6986: {    Page *p;
                   6987:        if((p=(Page *)malloc(sizeof(Page)))==NULL)
                   6988:                abort("alloc_page: can't malloc");
                   6989:        alloc_census(Page,1);
                   6990:        *p = empty_Page;
                   6991:        return(p);
                   6992:        }
                   6993: 
                   6994: char *page_toa(p)
                   6995:     Page *p;
                   6996: {    static char s[80];
                   6997:        sprintf(s,"%s bx%s res%d,%d sk%0.2f,sh%0.2f bk%d l%d c%d b%d",
                   6998:                ident_toa(p->ident),
                   6999:                bbx_toa(&(p->bx)),
                   7000:                p->res_x,p->res_y,
                   7001:                (p->skew/PI)*180.0,
                   7002:                (p->shear/PI)*180.0,
                   7003:                p->bks.mny,p->ls.mny,p->cs.mny,p->bs.mny,
                   7004:                (p->l!=NULL)? p->l: "");
                   7005:        return(s);
                   7006:        }
                   7007: 
                   7008: #if FWRI
                   7009: /* write the given page (record only) */
                   7010: fwrb_page(f,p)
                   7011:     FILE *f;
                   7012:     Page *p;
                   7013: {   int stat;
                   7014: #if dbg_fwrb
                   7015:        if(f==stdout||f==stderr||ftell(f)<=0L) {
                   7016:                fprintf(f,"TYPE=dim\n\n");
                   7017: #if dbg_fwrb_toa
                   7018:                err("fwrb_page: \"TYPE=dim\\n\\n\"");
                   7019: #endif
                   7020:                put_doc(f);
                   7021:                };
                   7022:        if((!(p->ident&IsPage))||(p->ident&(IsALL&(~IsPage))))
                   7023:                err("fwrb_page: %s",page_toa(p));
                   7024:        if(p->ident&Page_label && p->l==NULL) {
                   7025:                err("fwrb_page: Page_label set but .l==NULL");
                   7026:                p->ident &= ~Page_label;
                   7027:                };
                   7028: #endif
                   7029:        fwri_Ident(f,p->ident);
                   7030:        fwri_Bbx(f,&(p->bx));
                   7031:        fwri_int2(f,p->res_x);
                   7032:        fwri_int2(f,p->res_y);
                   7033:        fwri_Radians(f,p->skew);
                   7034:        fwri_Radians(f,p->shear);
                   7035:        fwri_uint2(f,p->bks.mny);
                   7036:        fwri_uint2(f,p->ls.mny);
                   7037:        fwri_uint2(f,p->ws.mny);
                   7038:        fwri_uint2(f,p->cs.mny);
                   7039:        fwri_uint3(f,p->bs.mny);
                   7040: #if dbg_fwrb_toa
                   7041:        err("fwrb_page: %s",page_toa(p));
                   7042: #endif
                   7043:        if(p->ident&Page_label) fwrb_label(f,p->l);
                   7044:        }
                   7045: #else
                   7046: /* write the given page (record only) */
                   7047: fwrb_page(fp,pp)
                   7048:     FILE *fp;
                   7049:     Page *pp;
                   7050: {   PageF pf;
                   7051:     int stat;
                   7052: #if dbg_fwrb
                   7053:        if((!(pp->ident&IsPage))||(pp->ident&(IsALL&(~IsPage))))
                   7054:                err("fwrb_page: %s",page_toa(pp));
                   7055: #endif
                   7056:        memset(&pf,'\0',sizeof(pf));
                   7057:        pf.ident = pp->ident;
                   7058:        pf.res_x=pp->res_x;
                   7059:        pf.res_y=pp->res_y;
                   7060:        pf.bx=pp->bx;
                   7061:        pf.skew=pp->skew;
                   7062:        pf.shear=pp->shear;
                   7063:        pf.bkmny=pp->bks.mny;
                   7064:        pf.lmny=pp->ls.mny;
                   7065:        pf.wmny=pp->ws.mny;
                   7066:        pf.cmny=pp->cs.mny;
                   7067:        pf.bmny=pp->bs.mny;
                   7068:        if(fp==stdout||fp==stderr||ftell(fp)<=0L) {
                   7069:                fprintf(fp,"TYPE=document-image\n\n");
                   7070: #if dbg_fwrb_toa
                   7071:                err("fwrb_page: \"TYPE=document-image\\n\\n\"");
                   7072: #endif
                   7073:                };
                   7074:        if((stat=fwrite(&pf,sizeof(PageF),1,fp))!=1)
                   7075:                abort("fwrb_page: can't fwrite - status %d",stat);
                   7076: #if dbg_fwrb_toa
                   7077:        err("fwrb_page: %s",page_toa(pp));
                   7078: #endif
                   7079:        if(pf.ident&Page_label) fwrb_label(fp,pp->l);
                   7080:        }
                   7081: #endif
                   7082: 
                   7083: /* write a page and its specified parts */
                   7084: fwrb_page_etc(fp,pp,etc)
                   7085:     FILE *fp;
                   7086:     Page *pp;
                   7087:     Ident etc;
                   7088: {   static Ident parts = (IsBlock|IsTxtln|IsWord|IsChar|IsBlob);
                   7089:     Page pg;
                   7090:        if((etc&parts)!=parts) /* write selected parts */ {
                   7091:                pg = *pp;
                   7092:                if(!(etc&IsBlock)) pg.bks.mny=0;
                   7093:                if(!(etc&IsTxtln)) pg.ls.mny=0;
                   7094:                if(!(etc&IsWord)) pg.ws.mny=0;
                   7095:                if(!(etc&IsChar)) pg.cs.mny=0;
                   7096:                if(!(etc&IsBlob)) pg.bs.mny=0;
                   7097:                pp = &pg;       /* write modified record */
                   7098:                };
                   7099:        fwrb_page(fp,pp);
                   7100:        fwrb_blocks_etc(fp,pp->bks,etc);
                   7101:        fwrb_txtlns_etc(fp,pp->ls,etc);
                   7102:        fwrb_words_etc(fp,pp->ws,etc);
                   7103:        fwrb_chars_etc(fp,pp->cs,etc);
                   7104:        fwrb_blobs_etc(fp,pp->bs,etc);
                   7105:        }
                   7106: 
                   7107: /* write a page and its specified parts, ASCII (INCOMPLETE) */
                   7108: fwra_page_etc(fp,pp,etc)
                   7109:     FILE *fp;
                   7110:     Page *pp;
                   7111:     Ident etc;
                   7112: {   static Ident parts = (IsBlock|IsTxtln|IsWord|IsChar|IsBlob);
                   7113:     Page pg;
                   7114:        if((etc&parts)!=parts) /* write selected parts */ {
                   7115:                pg = *pp;
                   7116:                if(!(etc&IsBlock)) pg.bks.mny=0;
                   7117:                if(!(etc&IsTxtln)) pg.ls.mny=0;
                   7118:                if(!(etc&IsWord)) pg.ws.mny=0;
                   7119:                if(!(etc&IsChar)) pg.cs.mny=0;
                   7120:                if(!(etc&IsBlob)) pg.bs.mny=0;
                   7121:                pp = &pg;       /* write modified record */
                   7122:                };
                   7123:        if(etc&IsPage) fwrb_page(fp,pp);
                   7124:        fwrb_blocks_etc(fp,pp->bks,etc);
                   7125:        fwrb_txtlns_etc(fp,pp->ls,etc);
                   7126:        fwrb_words_etc(fp,pp->ws,etc);
                   7127:        fwrb_chars_etc(fp,pp->cs,etc);
                   7128:        fwrb_blobs_etc(fp,pp->bs,etc);
                   7129:        }
                   7130: 
                   7131: #if FRDI
                   7132: /* read a Page record (only) - it must be next in the file;
                   7133:    don't immediately read its parts; return 0 iff immediate EOF  */
                   7134: int frdb_page(f,p)
                   7135:     FILE *f;
                   7136:     Page *p;
                   7137: {   char *pfc; /* for debugging */
                   7138:     int stat;
                   7139:        switch(skip_type(f)) {
                   7140:            case 1:  /* "TYPE=" header */
                   7141:                skip_doc(f);
                   7142:                break;
                   7143:            case 0:  /* immediate EOF */
                   7144:                return(0);
                   7145:                break;
                   7146:            case -1:  /* no "TYPE=" header */
                   7147:                break;
                   7148:            case -2:  /* garbled "TYPE=" header */
                   7149:                abort("frdb_page: garbled \"TYPE=\" header");
                   7150:                break;
                   7151:            };
                   7152:        *p = empty_Page;
                   7153:        if(feof(f))
                   7154:                return(0);
                   7155:        p->ident=frdi_Ident(f);
                   7156:        frdi_Bbx(f,&(p->bx));
                   7157:        p->res_x=frdi_int2(f);
                   7158:        p->res_y=frdi_int2(f);
                   7159:        p->skew=frdi_Radians(f);
                   7160:        p->shear=frdi_Radians(f);
                   7161:        p->bks.mny=frdi_uint2(f);
                   7162:        p->ls.mny=frdi_uint2(f);
                   7163:        p->ws.mny=frdi_uint2(f);
                   7164:        p->cs.mny=frdi_uint2(f);
                   7165:        p->bs.mny=frdi_uint3(f);
                   7166: #if dbg_frdb
                   7167:        if((!(p->ident&IsPage))||(p->ident&(IsALL&(~IsPage))))
                   7168:                err("frdb_page: %s",page_toa(p));
                   7169: #endif
                   7170: #if dbg_frdb_toa
                   7171:        err("frdb_page: %s",page_toa(p));
                   7172: #endif
                   7173:        if(p->ident&Page_label) p->l = frdb_label(f);
                   7174:        if(ferror(f)) return(-errno); else return(1);
                   7175:        }
                   7176: #else
                   7177: /* read a Page record (only) - it must be next in the file;
                   7178:    don't immediately read its parts; return T iff not early EOF  */
                   7179: int frdb_page(fp,pp)
                   7180:     FILE *fp;
                   7181:     Page *pp;
                   7182: {   PageF pf;
                   7183:     char *pfc; /* for debugging */
                   7184:     int stat;
                   7185:        if((stat=skip_type(fp))!=1 /* "TYPE=" header */
                   7186:            && stat!=-1 /* no "TYPE=" header */ ) {
                   7187:                /* premature EOF or error */ return(stat);
                   7188:                };
                   7189:        if((stat=fread(&pf,sizeof(PageF),1,fp))!=1)
                   7190:                /* premature EOF*/ return(stat);
                   7191:        pfc = (char *)&pf;
                   7192:        *pp = empty_Page;
                   7193:        pp->ident=pf.ident;
                   7194:        pp->res_x=pf.res_x;
                   7195:        pp->res_y=pf.res_y;
                   7196:        pp->bx=pf.bx;
                   7197:        pp->skew=pf.skew;
                   7198:        pp->shear=pf.shear;
                   7199:        pp->bks.mny = pf.bkmny; pp->bks.bpa=NULL;
                   7200:        pp->ls.mny = pf.lmny;   pp->ls.lpa=NULL;
                   7201:        pp->ws.mny = pf.wmny;   pp->ws.wpa=NULL;
                   7202:        pp->cs.mny = pf.cmny;   pp->cs.cpa=NULL;
                   7203:        pp->bs.mny = pf.bmny;   pp->bs.bpa=NULL;
                   7204: #if dbg_frdb_toa
                   7205:        err("frdb_page: %s",page_toa(pp));
                   7206: #endif
                   7207:        if(pp->ident&Page_label) pp->l = frdb_label(fp);
                   7208: #if dbg_frdb
                   7209:        if((!(pp->ident&IsPage))||(pp->ident&(IsALL&(~IsPage))))
                   7210:                err("frdb_page: %s",page_toa(pp));
                   7211: #endif
                   7212:        return(stat);
                   7213:        }
                   7214: #endif
                   7215: 
                   7216: /* Read a page and selected parts */
                   7217: int frdb_page_etc(fp,pp,etc)
                   7218:     FILE *fp;
                   7219:     Page *pp;
                   7220:     Ident etc;
                   7221: {   int stat;
                   7222:        if((etc&IsALL)==IsALL) {
                   7223:            long here;
                   7224:                /* In order to minimize malloc time to read an often huge file,
                   7225:                   malloc and then free storage roughly equal to what's needed */
                   7226:                if( /* DEFEATED */ F && (here=ftell(fp))>=0 && fseek(fp,0,2)>=0 ) {
                   7227:                        /* *fp is connected to a file, not a pipe */
                   7228:                        free(malloc(ftell(fp)));
                   7229:                        fseek(fp,here,0);
                   7230:                        };
                   7231:                };
                   7232:        if((stat=frdb_page(fp,pp))!=1) return(stat);
                   7233:        if(etc&IsBlock && pp->bks.mny>0)
                   7234:                frdb_blocks_etc(fp,&(pp->bks),etc);
                   7235:        else pp->bks = empty_Blocks;
                   7236:        if(etc&IsTxtln && pp->ls.mny>0)
                   7237:                frdb_txtlns_etc(fp,&(pp->ls),etc);
                   7238:        else pp->ls = empty_Txtlns;
                   7239:        if(etc&IsWord && pp->ws.mny>0)
                   7240:                frdb_words_etc(fp,&(pp->ws),etc);
                   7241:        else pp->ws = empty_Words;
                   7242:        if(etc&IsChar && pp->cs.mny>0)
                   7243:                frdb_chars_etc(fp,&(pp->cs),etc);
                   7244:        else pp->cs = empty_Chars;
                   7245:        if(etc&IsBlob && pp->bs.mny>0)
                   7246:                frdb_blobs_etc(fp,&(pp->bs),etc);
                   7247:        else pp->bs = empty_Blobs;
                   7248:        return(1/*normal return*/);
                   7249:        }
                   7250: 
                   7251: free_page_etc(p,etc)
                   7252:     Page *p;
                   7253:     Ident etc;
                   7254: {      free_blocks_etc(&(p->bks),etc);
                   7255:        free_txtlns_etc(&(p->ls),etc);
                   7256:        free_words_etc(&(p->ws),etc);
                   7257:        free_chars_etc(&(p->cs),etc);
                   7258:        free_blobs_etc(&(p->bs),etc);
                   7259:        if(p->ident&Page_label && p->l!=NULL) {
                   7260:                free(p->l);  p->l=NULL;  p->ident &= ~Page_label;
                   7261:                };
                   7262:        if(etc&IsPage) {
                   7263:                free(p);
                   7264:                free_census(Page,1);
                   7265:                };
                   7266:        }
                   7267: 
                   7268: /* return a pointer to a distinct and duplicate copy of record Page *p,
                   7269:    created out of malloc space */
                   7270: Page *dup_page(p)
                   7271:     Page *p;
                   7272: {   Page *dup;
                   7273:        dup=alloc_page();  *dup = *p;  return(dup);
                   7274:        }
                   7275: 
                   7276: /* Return a pointer to a distinct and duplicate copy of Page *p, and its parts
                   7277:    as specified by `etc', created out of malloc space. */
                   7278: Page *dup_page_etc(p,etc)
                   7279:     Page *p;
                   7280:     Ident etc;
                   7281: {   Page *dup;
                   7282:        dup = dup_page(p);
                   7283:        if(etc&IsBlob&&dup->bs.mny>0) dup->bs = *dup_blobs_etc(&(p->bs),etc);
                   7284:        else dup->bs = empty_Blobs;
                   7285:        if(etc&IsChar&&dup->cs.mny>0) dup->cs = *dup_chars_etc(&(p->cs),etc);
                   7286:        else dup->cs = empty_Chars;
                   7287:        if(etc&IsWord&&dup->ws.mny>0) dup->ws = *dup_words_etc(&(p->ws),etc);
                   7288:        else dup->ws = empty_Words;
                   7289:        if(etc&IsTxtln&&dup->ls.mny>0) dup->ls = *dup_txtlns_etc(&(p->ls),etc);
                   7290:        else dup->ls = empty_Txtlns;
                   7291:        if(etc&IsBlock&&dup->bks.mny>0) dup->bks = *dup_blocks_etc(&(p->bks),etc);
                   7292:        else dup->bks = empty_Blocks;
                   7293:        return(dup);
                   7294:        }
                   7295: 
                   7296: Block *alloc_block()
                   7297: {    Block *p;
                   7298:        if((p=(Block *)malloc(sizeof(Block)))==NULL)
                   7299:                abort("alloc_block: can't malloc");
                   7300:        alloc_census(Block,1);
                   7301:        *p = empty_Block;
                   7302:        return(p);
                   7303:        }
                   7304: 
                   7305: char *block_toa(p)
                   7306:     Block *p;
                   7307: {   static char s[80];
                   7308:        sprintf(s,"%s bx%s sk%0.2f,sh%0.2f wst%0.2f m%s bk%d l%d w%d c%d b%d",
                   7309:                ident_toa(p->ident),
                   7310:                bbx_toa(&(p->bx)),
                   7311:                p->skew/DtoR,
                   7312:                p->shear/DtoR,
                   7313:                p->wst,
                   7314:                merit_toa(p->m),
                   7315:                p->bks.mny,p->ls.mny,p->ws.mny,p->cs.mny,p->bs.mny,
                   7316:                (p->l!=NULL)? p->l: "");
                   7317:        return(s);
                   7318:        }
                   7319: 
                   7320: #if FWRI
                   7321: fwrb_block(f,p)
                   7322:     FILE *f;
                   7323:     Block *p;
                   7324: {   int stat;
                   7325: #if dbg_fwrb
                   7326:        if((!(p->ident&IsBlock))||(p->ident&(IsALL&(~IsBlock))))
                   7327:                err("fwrb_block: %s",block_toa(p));
                   7328:        if(p->ident&Block_label && p->l==NULL) {
                   7329:                err("fwrb_page: Block_label set but .l==NULL");
                   7330:                p->ident &= ~Block_label;
                   7331:                };
                   7332: #endif
                   7333:        fwri_Ident(f,p->ident);
                   7334:        fwri_Bbx(f,&(p->bx));
                   7335:        fwri_Radians(f,p->skew);
                   7336:        fwri_Radians(f,p->shear);
                   7337:        fwri_Ems(f,p->wst);
                   7338:        fwri_Merit(f,p->m);
                   7339:        fwri_uint2(f,p->bks.mny);
                   7340:        fwri_uint2(f,p->ls.mny);
                   7341:        fwri_uint2(f,p->ws.mny);
                   7342:        fwri_uint2(f,p->cs.mny);
                   7343:        fwri_uint3(f,p->bs.mny);
                   7344: #if dbg_fwrb_toa
                   7345:        err("fwrb_block: %s",block_toa(p));
                   7346: #endif
                   7347:        if(p->ident&Block_label) fwrb_label(f,p->l);
                   7348:        }
                   7349: #else
                   7350: fwrb_block(fp,bkp)
                   7351:     FILE *fp;
                   7352:     Block *bkp;
                   7353: {   BlockF bf;
                   7354:     int stat;
                   7355: #if dbg_fwrb
                   7356:        if((!(bkp->ident&IsBlock))||(bkp->ident&(IsALL&(~IsBlock))))
                   7357:                err("fwrb_block: %s",block_toa(bkp));
                   7358: #endif
                   7359:        memset(&bf,'\0',sizeof(bf));
                   7360:        bf.ident = bkp->ident;
                   7361:        bf.bx = bkp->bx;
                   7362:        bf.wst = bkp->wst;
                   7363:        bf.skew = bkp->skew;
                   7364:        bf.shear = bkp->shear;
                   7365:        bf.lmny = bkp->ls.mny;
                   7366:        bf.wmny = bkp->ws.mny;
                   7367:        bf.cmny = bkp->cs.mny;
                   7368:        bf.bmny = bkp->bs.mny;
                   7369: #if dbg_fwrb_toa
                   7370:        err("fwrb_block: %s",block_toa(bkp));
                   7371: #endif
                   7372:        if((stat=fwrite(&bf,sizeof(BlockF),1,fp))!=1)
                   7373:                abort("fwrb_block: can't fwrite - status %d",stat);
                   7374:        }
                   7375: #endif
                   7376: 
                   7377: fwrb_blocks_etc(fp,bks,etc)
                   7378:     FILE *fp;
                   7379:     Blocks bks;
                   7380:     Ident etc;
                   7381: {   register Block *bkp,**bkpp;
                   7382:        if(bks.mny>0) for(bkp= *(bkpp=bks.bpa); bkp!=NULL; bkp= *(++bkpp))
                   7383:                fwrb_block_etc(fp,bkp,etc);
                   7384:        }
                   7385: 
                   7386: fwrb_block_etc(fp,bkp,etc)
                   7387:     FILE *fp;
                   7388:     Block *bkp;
                   7389:     Ident etc;
                   7390: {   static Ident parts = (IsTxtln|IsWord|IsChar|IsBlob);
                   7391:     Block bk;
                   7392:        if((etc&parts)!=parts) /* write selected parts */ {
                   7393:                bk = *bkp;
                   7394:                if(!(etc&IsTxtln)) bk.ls.mny=0;
                   7395:                if(!(etc&IsWord)) bk.ws.mny=0;
                   7396:                if(!(etc&IsChar)) bk.cs.mny=0;
                   7397:                if(!(etc&IsBlob)) bk.bs.mny=0;
                   7398:                bkp = &bk;      /* write modified record */
                   7399:                };
                   7400:        fwrb_block(fp,bkp);
                   7401:        fwrb_txtlns_etc(fp,bkp->ls,etc);
                   7402:        fwrb_words_etc(fp,bkp->ws,etc);
                   7403:        fwrb_chars_etc(fp,bkp->cs,etc);
                   7404:        fwrb_blobs_etc(fp,bkp->bs,etc);
                   7405:        }
                   7406: 
                   7407: #if FRDI
                   7408: int frdb_block(f,p)
                   7409:     FILE *f;
                   7410:     Block *p;
                   7411: {      *p = empty_Block;
                   7412:        if(feof(f))
                   7413:                return(0);
                   7414:        p->ident=frdi_Ident(f);
                   7415:        frdi_Bbx(f,&(p->bx));
                   7416:        p->skew=frdi_Radians(f);
                   7417:        p->shear=frdi_Radians(f);
                   7418:        p->wst=frdi_Ems(f);
                   7419:        p->m=frdi_Merit(f);
                   7420:        p->bks.mny=frdi_uint2(f);
                   7421:        p->ls.mny=frdi_uint2(f);
                   7422:        p->ws.mny=frdi_uint2(f);
                   7423:        p->cs.mny=frdi_uint2(f);
                   7424:        p->bs.mny=frdi_uint3(f);
                   7425: #if dbg_frdb_toa
                   7426:        err("frdb_block: %s",block_toa(p));
                   7427: #endif
                   7428: #if dbg_frdb
                   7429:        if((!(p->ident&IsBlock))||(p->ident&(IsALL&(~IsBlock))))
                   7430:                err("frdb_block: %s",block_toa(p));
                   7431: #endif
                   7432:        if(p->ident&Block_label) p->l = frdb_label(f);
                   7433:        if(ferror(f)) return(-errno); else return(1);
                   7434:        }
                   7435: #else
                   7436: int frdb_block(fp,bkp)
                   7437:     FILE *fp;
                   7438:     Block *bkp;
                   7439: {   BlockF bf;
                   7440:     int stat;
                   7441:        if((stat=fread(&bf,sizeof(BlockF),1,fp))!=1)
                   7442:                abort("frdb_block: can't fread - status %d",stat);
                   7443:        *bkp = empty_Block;
                   7444:        bkp->ident = bf.ident;
                   7445:        bkp->bx = bf.bx;
                   7446:        bkp->skew = bf.skew;
                   7447:        bkp->shear = bf.shear;
                   7448:        bkp->wst = bf.wst;
                   7449:        bkp->ls.mny = bf.lmny;
                   7450:        bkp->ws.mny = bf.wmny;
                   7451:        bkp->cs.mny = bf.cmny;
                   7452:        bkp->bs.mny = bf.bmny;
                   7453: #if dbg_frdb
                   7454:        if((!(bkp->ident&IsBlock))||(bkp->ident&(IsALL&(~IsBlock))))
                   7455:                err("frdb_block: %s",block_toa(bkp));
                   7456: #endif
                   7457: #if dbg_frdb_toa
                   7458:        err("frdb_block: %s",block_toa(bkp));
                   7459: #endif
                   7460:        if(bkp->ident&Block_label) bkp->l = frdb_label(fp);
                   7461:        if(ferror(fp)) return(-errno); else return(1);
                   7462:        }
                   7463: #endif
                   7464: 
                   7465: frdb_block_etc(fp,bkp,etc)
                   7466:     FILE *fp;
                   7467:     Block *bkp;
                   7468:     Ident etc;
                   7469: {   BlockF bf;
                   7470:     int stat;
                   7471:        frdb_block(fp,bkp);
                   7472:        if(etc&IsTxtln && bkp->ls.mny>0)
                   7473:                frdb_txtlns_etc(fp,&(bkp->ls),etc);
                   7474:        else bkp->ls = empty_Txtlns;
                   7475:        if(etc&IsWord && bkp->ws.mny>0)
                   7476:                frdb_words_etc(fp,&(bkp->ws),etc);
                   7477:        else bkp->ws = empty_Words;
                   7478:        if(etc&IsChar && bkp->cs.mny>0)
                   7479:                frdb_chars_etc(fp,&(bkp->cs),etc);
                   7480:        else bkp->cs = empty_Chars;
                   7481:        if(etc&IsBlob && bkp->bs.mny>0)
                   7482:                frdb_blobs_etc(fp,&(bkp->bs),etc);
                   7483:        else bkp->bs = empty_Blobs;
                   7484:        if(ferror(fp)) return(-errno); else return(1);
                   7485:        }
                   7486: 
                   7487: /* read number of blocks, and their parts */
                   7488: frdb_blocks_etc(fp,bksp,etc)
                   7489:     FILE *fp;
                   7490:     Blocks *bksp;
                   7491:     Ident etc;
                   7492: {   int bi;
                   7493:     register Block *bkp,**bkpp;
                   7494:        if(bksp->mny<=0) {
                   7495:                *bksp = empty_Blocks;
                   7496:                return(1);
                   7497:                };
                   7498: 
                   7499:        if((bkpp=bksp->bpa=(Block **)malloc((bksp->mny+1)*sizeof(Block *)))==NULL)
                   7500:                abort("can't alloc Blocks.bpa array");
                   7501:        for(bi=0; bi<bksp->mny; bi++) {
                   7502:                *(bkpp++) = bkp = alloc_block();
                   7503:                frdb_block_etc(fp,bkp,etc);
                   7504:                };
                   7505:        *bkpp = NULL;
                   7506:        if(ferror(fp)) return(-errno); else return(1);
                   7507:        }
                   7508: 
                   7509: free_block_etc(p,etc)
                   7510:     Block *p;
                   7511:     Ident etc;
                   7512: {      free_txtlns_etc(&(p->ls),etc);
                   7513:        free_words_etc(&(p->ws),etc);
                   7514:        free_chars_etc(&(p->cs),etc);
                   7515:        free_blobs_etc(&(p->bs),etc);
                   7516:        if(p->ident&Block_label && p->l!=NULL) {
                   7517:                free(p->l);  p->l=NULL;  p->ident &= ~Block_label;
                   7518:                };
                   7519:        if(etc&IsBlock) {
                   7520:                free(p);
                   7521:                free_census(Block,1);
                   7522:                };
                   7523:        }
                   7524: 
                   7525: /* Unconditionally free the malloc-space array of pointers, and empty the set.
                   7526:    Don't free the records that it owned.
                   7527:    */
                   7528: free_blocks(p)
                   7529:     Blocks *p;
                   7530: {      if(p->bpa!=NULL) { free(p->bpa);  p->bpa = NULL; }
                   7531:        p->mny = 0;
                   7532:        }
                   7533: 
                   7534: free_blocks_etc(p,etc)
                   7535:     Blocks *p;
                   7536:     Ident etc;
                   7537: {   register Block *bkp,**bkpp;
                   7538:        if(p->mny>0&&(etc&IsBlock))
                   7539:                for(bkp= *(bkpp=p->bpa); bkp!=NULL; bkp= *(++bkpp))
                   7540:                        free_block_etc(bkp,etc);
                   7541:        free_blocks(p);
                   7542:        }
                   7543: 
                   7544: /* return a pointer to a distinct and duplicate copy of *bkp,
                   7545:    created out of malloc space */
                   7546: Block *dup_block(bkp)
                   7547:     Block *bkp;
                   7548: {   Block *dup;
                   7549:        dup=alloc_block();
                   7550:        *dup = *bkp;
                   7551:        return(dup);
                   7552:        }
                   7553: 
                   7554: /* Return a pointer to a distinct and duplicate copy of *bkp, and its parts
                   7555:    as specified by `etc', created out of malloc space. */
                   7556: Block *dup_block_etc(bkp,etc)
                   7557:     Block *bkp;
                   7558:     Ident etc;
                   7559: {   Block *dup;
                   7560:        dup = dup_block(bkp);
                   7561:        if(etc&IsBlob&&dup->bs.mny>0) dup->bs = *dup_blobs_etc(&(bkp->bs),etc);
                   7562:        else dup->bs = empty_Blobs;
                   7563:        if(etc&IsChar&&dup->cs.mny>0) dup->cs = *dup_chars_etc(&(bkp->cs),etc);
                   7564:        else dup->cs = empty_Chars;
                   7565:        if(etc&IsWord&&dup->ws.mny>0) dup->ws = *dup_words_etc(&(bkp->ws),etc);
                   7566:        else dup->ws = empty_Words;
                   7567:        if(etc&IsTxtln&&dup->ls.mny>0) dup->ls = *dup_txtlns_etc(&(bkp->ls),etc);
                   7568:        else dup->ls = empty_Txtlns;
                   7569:        return(dup);
                   7570:        }
                   7571: 
                   7572: /* Return a pointer to a distinct local static duplicate of non-empty *bksp.
                   7573:    Its bkpa array is created newly out of malloc space.
                   7574:    If etc&IsBlock, all its Blocks are also duplicated,
                   7575:    else the contents of bkpa point to the old unduplicated Blocks.
                   7576:    */
                   7577: Blocks *dup_blocks_etc(bksp,etc)
                   7578:     Blocks *bksp;
                   7579:     Ident etc;         /* parts to duplicate */
                   7580: {   static Blocks dup;
                   7581:     register Block **bkpp,**dpp;
                   7582:        if((dup.mny = bksp->mny)<=0) dup = empty_Blocks;
                   7583:        else {  if((dup.bpa=(Block **)malloc((dup.mny+1)*sizeof(Block *)))==NULL)
                   7584:                        abort("can't dup bks.bpa");
                   7585:                for(bkpp=bksp->bpa,dpp=dup.bpa; *bkpp!=NULL; bkpp++,dpp++) {
                   7586:                        if(etc&IsBlock) *dpp = dup_block_etc(*bkpp,etc);
                   7587:                        else *dpp = *bkpp;
                   7588:                        };
                   7589:                *dpp = NULL;
                   7590:                };
                   7591:        return(&dup);
                   7592:        }
                   7593: 
                   7594: /* Append a block to the end of a blocks set. 
                   7595:    Return appended Block *. */
                   7596: Block *append_block(bkp,bksp)
                   7597:     Block *bkp;
                   7598:     Blocks *bksp;
                   7599: {   register Block *rp,**rpp,**npp;
                   7600:        if(bksp->mny==0) {
                   7601:                if((bksp->bpa=(Block **)malloc(2*sizeof(Block *)))==NULL)
                   7602:                        abort("append_block: can't malloc bksp->bpa");
                   7603:                }
                   7604:        else {  if((bksp->bpa=(Block **)realloc(
                   7605:                                bksp->bpa,
                   7606:                                (bksp->mny+2)*sizeof(Block *))
                   7607:                                )==NULL)
                   7608:                        abort("append_block: can't realloc bksp->bpa");
                   7609:                };
                   7610:        bksp->bpa[bksp->mny] = bkp;
                   7611:        bksp->bpa[++bksp->mny] = NULL;
                   7612:        return(bkp);
                   7613:        }
                   7614: 
                   7615: /* remove a block from a blocks set */
                   7616: remove_block(bkp,bksp)
                   7617:     Block *bkp;
                   7618:     Blocks *bksp;
                   7619: {   register Block *rp,**rpp,**npp;
                   7620:        if(bksp->mny==0) err("can't remove Block - Blocks empty");
                   7621:        else {  for(rp= *(rpp=bksp->bpa); rp!=NULL; rp= *(++rpp)) if(rp==bkp) break;
                   7622:                if(rp==NULL) err("can't remove Block - not found");
                   7623:                else {  /* move later entries up */
                   7624:                        npp=rpp+1;
                   7625:                        do *(rpp++)= *(npp++); while ((*rpp)!=NULL);
                   7626:                        if((--(bksp->mny))==0) {free(bksp->bpa); bksp->bpa=NULL;};
                   7627:                        /* don't bother to realloc downwards */
                   7628:                        };
                   7629:                };
                   7630:        }
                   7631: 
                   7632: ConstPitch *alloc_constpitch()
                   7633: {    ConstPitch *p;
                   7634:        if((p=(ConstPitch *)malloc(sizeof(ConstPitch)))==NULL)
                   7635:                abort("can't alloc ConstPitch");
                   7636:        else {  *p = empty_ConstPitch;
                   7637:                return(p);
                   7638:                };
                   7639:        }
                   7640: 
                   7641: char *constpitch_toa(p)
                   7642:     ConstPitch *p;
                   7643: {    static char s[80];
                   7644:        sprintf(s,"{w%.3f,o%d,r%.1f}",
                   7645:                p->w,p->o,p->r);
                   7646:        return(s);
                   7647:        }
                   7648: 
                   7649: free_constpitch(p)
                   7650:     ConstPitch *p;
                   7651: {      free(p);
                   7652:        }
                   7653: 
                   7654: Txtln *alloc_txtln()
                   7655: {    Txtln *p;
                   7656:        if((p=(Txtln *)malloc(sizeof(Txtln)))==NULL)
                   7657:                abort("can't alloc Txtln");
                   7658:        alloc_census(Txtln,1);
                   7659:        *p = empty_Txtln;
                   7660:        return(p);
                   7661:        }
                   7662: 
                   7663: char *txtln_toa(p)
                   7664:     Txtln *p;
                   7665: {    static char s[80];
                   7666:        sprintf(s,"%s bx%s sz%s ba%d cw%s m%s l%d w%d c%d b%d %s",
                   7667:                ident_toa(p->ident),
                   7668:                bbx_toa(&(p->bx)),
                   7669:                pts_toa(p->size),
                   7670:                p->basl,
                   7671:                /** proj omitted **/
                   7672:                ((p->cp!=NULL)? constpitch_toa(p->cp): "0"),
                   7673:                merit_toa(p->m),
                   7674:                p->ls.mny,p->ws.mny,p->cs.mny,p->bs.mny,
                   7675:                (p->l!=NULL)? p->l: "");
                   7676:        return(s);
                   7677:        }
                   7678: 
                   7679: #if FWRI
                   7680: fwrb_txtln(f,p)
                   7681:     FILE *f;
                   7682:     Txtln *p;
                   7683: {
                   7684: #if dbg_fwrb
                   7685:        if((!(p->ident&IsTxtln))||(p->ident&(IsALL&(~IsTxtln))))
                   7686:                err("fwrb_txtln: %s",txtln_toa(p));
                   7687:        if(p->ident&Txtln_label && p->l==NULL) {
                   7688:                err("fwrb_page: Txtln_label set but .l==NULL");
                   7689:                p->ident &= ~Txtln_label;
                   7690:                };
                   7691: #endif
                   7692:        fwri_Ident(f,p->ident);
                   7693:        fwri_Bbx(f,&(p->bx));
                   7694:        fwri_Pts(f,p->size);
                   7695:        fwri_Scoor(f,p->basl);
                   7696:        /* fwri_?(f,p->proj); */
                   7697:        /* fwri_ConstPitch(f,p->cp); */
                   7698:        fwri_Merit(f,p->m);
                   7699:        fwri_uint2(f,p->ls.mny);
                   7700:        fwri_uint2(f,p->ws.mny);
                   7701:        fwri_uint2(f,p->cs.mny);
                   7702:        fwri_uint3(f,p->bs.mny);
                   7703: #if dbg_fwrb_toa
                   7704:        err("fwrb_txtln: %s",txtln_toa(p));
                   7705: #endif
                   7706:        if(p->ident&Txtln_label) fwrb_label(f,p->l);
                   7707:        }
                   7708: #else
                   7709: fwrb_txtln(fp,lp)
                   7710:     FILE *fp;
                   7711:     Txtln *lp;
                   7712: {   TxtlnF lf;
                   7713:     int stat;
                   7714: #if dbg_fwrb
                   7715:        if((!(lp->ident&IsTxtln))||(lp->ident&(IsALL&(~IsTxtln))))
                   7716:                err("fwrb_txtln: %s",txtln_toa(lp));
                   7717: #endif
                   7718:        memset(&lf,'\0',sizeof(lf));
                   7719:        lf.ident = lp->ident;
                   7720:        lf.bx = lp->bx;
                   7721:        lf.basl = lp->basl;
                   7722:        lf.size = lp->size;
                   7723:        if(lp->proj!=NULL) lf.pmny = lp->bx.b.y - lp->bx.a.y + 1;
                   7724:        else lf.pmny = 0;
                   7725:        /* ignore lp->cp for now */
                   7726:        lf.wmny = lp->ws.mny;
                   7727:        lf.cmny = lp->cs.mny;
                   7728:        lf.bmny = lp->bs.mny;
                   7729:        if((stat=fwrite(&lf,sizeof(TxtlnF),1,fp))!=1)
                   7730:                abort("can't write TxtlnF, status %d",stat);
                   7731: #if dbg_fwrb_toa
                   7732:        err("fwrb_txtln: %s",txtln_toa(lp));
                   7733: #endif
                   7734:        if(lf.ident&Txtln_label) fwrb_label(fp,lp->l);
                   7735:        }
                   7736: #endif
                   7737: 
                   7738: fwrb_txtlns_etc(fp,ls,etc)
                   7739:     FILE *fp;
                   7740:     Txtlns ls;
                   7741:     Ident etc;
                   7742: {   register Txtln *lp,**lpp;
                   7743:        if(ls.mny>0) for(lp= *(lpp=ls.lpa); lp!=NULL; lp= *(++lpp))
                   7744:                fwrb_txtln_etc(fp,lp,etc);
                   7745:        }
                   7746: 
                   7747: fwrb_txtln_etc(fp,lp,etc)
                   7748:     FILE *fp;
                   7749:     Txtln *lp;
                   7750:     Ident etc;
                   7751: {   static Ident parts = (IsWord|IsChar|IsBlob);
                   7752:     Txtln tl;
                   7753:        if((etc&parts)!=parts) /* write selected parts */ {
                   7754:                tl = *lp;
                   7755:                if(!(etc&IsWord)) tl.ws.mny=0;
                   7756:                if(!(etc&IsChar)) tl.cs.mny=0;
                   7757:                if(!(etc&IsBlob)) tl.bs.mny=0;
                   7758:                lp = &tl;       /* write modified record */
                   7759:                };
                   7760:        fwrb_txtln(fp,lp);
                   7761:        if(lp->proj!=NULL) {/* write projection array someday */};
                   7762:        fwrb_words_etc(fp,lp->ws,etc);
                   7763:        fwrb_chars_etc(fp,lp->cs,etc);
                   7764:        fwrb_blobs_etc(fp,lp->bs,etc);
                   7765:        }
                   7766: 
                   7767: #if FRDI
                   7768: int frdb_txtln(f,p)
                   7769:     FILE *f;
                   7770:     Txtln *p;
                   7771: {      *p = empty_Txtln;
                   7772:        if(feof(f))
                   7773:                return(0);
                   7774:        p->ident=frdi_Ident(f);
                   7775:        frdi_Bbx(f,&(p->bx));
                   7776:        p->size=frdi_Pts(f);
                   7777:        p->basl=frdi_Scoor(f);
                   7778:        /* p->proj=frdi_?(f); */
                   7779:        /* p->cp=frdi_ConstPitch(f); */
                   7780:        p->m=frdi_Merit(f);
                   7781:        p->ls.mny=frdi_uint2(f);
                   7782:        p->ws.mny=frdi_uint2(f);
                   7783:        p->cs.mny=frdi_uint2(f);
                   7784:        p->bs.mny=frdi_uint3(f);
                   7785: #if dbg_frdb
                   7786:        if((!(p->ident&IsTxtln))||(p->ident&(IsALL&(~IsTxtln))))
                   7787:                err("frdb_txtln: %s",txtln_toa(p));
                   7788: #endif
                   7789: #if dbg_frdb_toa
                   7790:        err("frdb_txtln: %s",txtln_toa(p));
                   7791: #endif
                   7792:        if(p->ident&Txtln_label) p->l = frdb_label(f);
                   7793:        if(ferror(f)) return(-errno); else return(1);
                   7794:        }
                   7795: #else
                   7796: int frdb_txtln(fp,lp)
                   7797:     FILE *fp;
                   7798:     Txtln *lp;
                   7799: {   TxtlnF lf;
                   7800:     int stat;
                   7801:        if((stat=fread(&lf,sizeof(TxtlnF),1,fp))!=1)
                   7802:                abort("can't read TxtlnF, status %d",stat);
                   7803:        *lp = empty_Txtln;
                   7804:        lp->ident = lf.ident;
                   7805:        lp->bx = lf.bx;
                   7806:        lp->basl = lf.basl;
                   7807:        lp->size = lf.size;
                   7808:        if(lf.pmny>0) lp->proj=(short *)malloc(lf.pmny);
                   7809:        else lp->proj = NULL;
                   7810:        lp->cp = NULL;
                   7811:        lp->ws.mny = lf.wmny;
                   7812:        lp->cs.mny = lf.cmny;
                   7813:        lp->bs.mny = lf.bmny;
                   7814: #if dbg_frdb
                   7815:        if((!(lp->ident&IsTxtln))||(lp->ident&(IsALL&(~IsTxtln))))
                   7816:                err("frdb_txtln: %s",txtln_toa(lp));
                   7817: #endif
                   7818: #if dbg_frdb_toa
                   7819:        err("frdb_txtln: %s",txtln_toa(lp));
                   7820: #endif
                   7821:        if(lp->ident&Txtln_label) lp->l = frdb_label(fp);
                   7822:        if(ferror(fp)) return(-errno); else return(1);
                   7823:        }
                   7824: #endif
                   7825: 
                   7826: frdb_txtln_etc(fp,lp,etc)
                   7827:     FILE *fp;
                   7828:     Txtln *lp;
                   7829:     Ident etc;
                   7830: {   TxtlnF lf;
                   7831:     int stat;
                   7832:        frdb_txtln(fp,lp);
                   7833:        if(lp->proj!=NULL) {/* read projection array someday */};
                   7834:        if(etc&IsWord && lp->ws.mny>0)
                   7835:                frdb_words_etc(fp,&(lp->ws),etc);
                   7836:        else lp->ws = empty_Words;
                   7837:        if(etc&IsChar && lp->cs.mny>0)
                   7838:                frdb_chars_etc(fp,&(lp->cs),etc);
                   7839:        else lp->cs = empty_Chars;
                   7840:        if(etc&IsBlob && lp->bs.mny>0)
                   7841:                frdb_blobs_etc(fp,&(lp->bs),etc);
                   7842:        else lp->bs = empty_Blobs;
                   7843:        if(ferror(fp)) return(-errno); else return(1);
                   7844:        }
                   7845: 
                   7846: /* read number of txtlns, and parts */
                   7847: frdb_txtlns_etc(fp,lsp,etc)
                   7848:     FILE *fp;
                   7849:     Txtlns *lsp;
                   7850:     Ident etc;
                   7851: {   int li;
                   7852:     register Txtln *lp,**lpp;
                   7853:        if(lsp->mny<=0) {
                   7854:                *lsp = empty_Txtlns;
                   7855:                return(1);
                   7856:                };
                   7857:        if((lpp=lsp->lpa=(Txtln **)malloc((lsp->mny+1)*sizeof(Txtln *)))==NULL)
                   7858:                abort("can't alloc Txtlns.lpa array");
                   7859:        for(li=0; li<lsp->mny; li++) {
                   7860:                *(lpp++) = lp = alloc_txtln();
                   7861:                frdb_txtln_etc(fp,lp,etc);
                   7862:                };
                   7863:        *lpp = NULL;
                   7864:        if(ferror(fp)) return(-errno); else return(1);
                   7865:        }
                   7866: 
                   7867: /* Append a txtln to the end of a txtlns set. 
                   7868:    Do NOT maintain Txtlns in order sorted ascending on Txtln.bx.a.y.
                   7869:    Return appended Txtln *. */
                   7870: Txtln *append_txtln(lp,lsp)
                   7871:     Txtln *lp;
                   7872:     Txtlns *lsp;
                   7873: {   register Txtln *rp,**rpp,**npp;
                   7874:        if(lsp->mny==0) {
                   7875:                if((lsp->lpa=(Txtln **)malloc(2*sizeof(Txtln *)))==NULL)
                   7876:                        abort("append_txtln: can't malloc lsp->lpa");
                   7877:                }
                   7878:        else {  if((lsp->lpa=(Txtln **)realloc(
                   7879:                                lsp->lpa,
                   7880:                                (lsp->mny+2)*sizeof(Txtln *))
                   7881:                                )==NULL)
                   7882:                        abort("append_txtln: can't realloc lsp->lpa");
                   7883:                };
                   7884:        lsp->lpa[lsp->mny] = lp;
                   7885:        lsp->lpa[++lsp->mny] = NULL;
                   7886:        return(lp);
                   7887:        }
                   7888: 
                   7889: /* remove a txtln from a txtlns set */
                   7890: remove_txtln(lp,lsp)
                   7891:     Txtln *lp;
                   7892:     Txtlns *lsp;
                   7893: {   register Txtln *rp,**rpp,**npp;
                   7894:        if(lsp->mny==0) err("can't remove Txtln - Txtlns empty");
                   7895:        else {  for(rp= *(rpp=lsp->lpa); rp!=NULL; rp= *(++rpp)) if(rp==lp) break;
                   7896:                if(rp==NULL) err("can't remove Txtln - not found");
                   7897:                else {  /* move later entries up */
                   7898:                        npp=rpp+1;
                   7899:                        do *(rpp++)= *(npp++); while ((*rpp)!=NULL);
                   7900:                        if((--(lsp->mny))==0) {free(lsp->lpa); lsp->lpa=NULL;};
                   7901:                        /* don't bother to realloc downwards */
                   7902:                        };
                   7903:                };
                   7904:        }
                   7905: 
                   7906: free_txtln_etc(p,etc)
                   7907:     Txtln *p;
                   7908:     Ident etc;
                   7909: {      free_words_etc(&(p->ws),etc);
                   7910:        free_chars_etc(&(p->cs),etc);
                   7911:        free_blobs_etc(&(p->bs),etc);
                   7912:        if(p->ident&Txtln_label && p->l!=NULL) {
                   7913:                free(p->l);  p->l=NULL;  p->ident &= ~Txtln_label;
                   7914:                };
                   7915:        if(etc&IsTxtln) {
                   7916:                if(p->l!=NULL) free(p->l);
                   7917:                free(p);
                   7918:                free_census(Txtln,1);
                   7919:                };
                   7920:        }
                   7921: 
                   7922: /* Unconditionally free the malloc-space array of pointers, and empty the set.
                   7923:    Don't free the records that it owned.
                   7924:    */
                   7925: free_txtlns(lsp)
                   7926:     Txtlns *lsp;
                   7927: {      if(lsp->lpa!=NULL) { free(lsp->lpa); lsp->lpa = NULL; }
                   7928:        lsp->mny = 0;
                   7929:        }
                   7930: 
                   7931: free_txtlns_etc(lsp,etc)
                   7932:     Txtlns *lsp;
                   7933:     Ident etc;
                   7934: {   register Txtln *lp,**lpp;
                   7935:        if(lsp->mny>0&&(etc&IsTxtln))
                   7936:                for(lp= *(lpp=lsp->lpa); lp!=NULL; lp= *(++lpp))
                   7937:                        free_txtln_etc(lp,etc);
                   7938:        free_txtlns(lsp);
                   7939:        }
                   7940: 
                   7941: /* return a pointer to a distinct and duplicate copy of *lp,
                   7942:    created out of malloc space */
                   7943: Txtln *dup_txtln(lp)
                   7944:     Txtln *lp;
                   7945: {   Txtln *dup;
                   7946:        if((dup=(Txtln *)malloc(sizeof(Txtln)))==NULL)
                   7947:                abort("can't dup Txtln");
                   7948:        alloc_census(Txtln,1);
                   7949:        *dup = *lp;
                   7950:        return(dup);
                   7951:        }
                   7952: 
                   7953: /* Return a pointer to a distinct and duplicate copy of *lp, and its parts
                   7954:    as specified by `etc', created out of malloc space. */
                   7955: Txtln *dup_txtln_etc(lp,etc)
                   7956:     Txtln *lp;
                   7957:     Ident etc;
                   7958: {   Txtln *dup;
                   7959:        dup = dup_txtln(lp);
                   7960:        if(etc&IsBlob&&dup->bs.mny>0) dup->bs = *dup_blobs_etc(&(lp->bs),etc);
                   7961:        else dup->bs = empty_Blobs;
                   7962:        if(etc&IsChar&&dup->cs.mny>0) dup->cs = *dup_chars_etc(&(lp->cs),etc);
                   7963:        else dup->cs = empty_Chars;
                   7964:        if(etc&IsWord&&dup->ws.mny>0) dup->ws = *dup_words_etc(&(lp->ws),etc);
                   7965:        else dup->ws = empty_Words;
                   7966:        return(dup);
                   7967:        }
                   7968: 
                   7969: /* Return a pointer to a distinct local static duplicate of non-empty *lsp.
                   7970:    Its lpa array is created newly out of malloc space.
                   7971:    If etc&IsTxtln, all its Txtlns are also duplicated,
                   7972:    else the contents of lpa point to the old unduplicated Txtlns.
                   7973:    */
                   7974: Txtlns *dup_txtlns_etc(lsp,etc)
                   7975:     Txtlns *lsp;
                   7976:     Ident etc;         /* parts to duplicate */
                   7977: {   static Txtlns dup;
                   7978:     register Txtln **lpp,**dpp;
                   7979:        if((dup.mny = lsp->mny)<=0) dup = empty_Txtlns;
                   7980:        else {  if((dup.lpa=(Txtln **)malloc((dup.mny+1)*sizeof(Txtln *)))==NULL)
                   7981:                        abort("can't dup ls.lpa");
                   7982:                for(lpp=lsp->lpa,dpp=dup.lpa; *lpp!=NULL; lpp++,dpp++) {
                   7983:                        if(etc&IsTxtln) *dpp = dup_txtln_etc(*lpp,etc);
                   7984:                        else *dpp = *lpp;
                   7985:                        };
                   7986:                *dpp = NULL;
                   7987:                };
                   7988:        return(&dup);
                   7989:        }
                   7990: 
                   7991: Word *alloc_word()
                   7992: {    Word *p;
                   7993:        if((p=(Word *)malloc(sizeof(Word)))==NULL)
                   7994:                abort("can't alloc Word");
                   7995:        alloc_census(Word,1);
                   7996:        *p = empty_Word;
                   7997:        return(p);
                   7998:        }
                   7999: 
                   8000: char *word_toa(p)
                   8001:     Word *p;
                   8002: {    static char s[80];
                   8003:        sprintf(s,"%s bx%s ws%0.2f c%d b%d m%s w%d",
                   8004:                ident_toa(p->ident),
                   8005:                bbx_toa(&(p->bx)),
                   8006:                p->wsp,
                   8007:                p->cs.mny,p->bs.mny,merit_toa(p->m),p->ws.mny);
                   8008:        return(s);
                   8009:        }
                   8010: 
                   8011: /* Are two Words identical?  A not quite exhaustively-detailed test. */
                   8012: boolean eq_word(w1,w2)
                   8013:     Word *w1,*w2;
                   8014: {   register Char **c1,**c2;
                   8015:        if(w1->cs.mny!=w2->cs.mny) return(F);
                   8016:        for(c1=w1->cs.cpa,c2=w2->cs.cpa; *c1!=NULL; c1++,c2++) {
                   8017:                if((*c1)->area!=(*c2)->area) return(F);
                   8018:                if(!bbx_eq(&((*c1)->bx),&((*c2)->bx))) return(F);
                   8019:                if((*c1)->bmny!=(*c2)->bmny) return(F);
                   8020:                };
                   8021:        /* don't bother to compare Blob lists in detail (they aren't
                   8022:           in any particular order). */
                   8023:        return(T);
                   8024:        }
                   8025: 
                   8026: /* Compute a hash key for this Word that is likely to indicate whether or
                   8027:    not it is geometrically identical to another Word. */
                   8028: int hash_word(w)
                   8029:     Word *w;
                   8030: {   register int k;
                   8031:     register Char **c;
                   8032:        if(w->cs.mny==0) return(0);
                   8033:        k = w->bx.a.x * w->bx.a.y * w->bx.b.x * w->bx.b.y;
                   8034:        for(c=w->cs.cpa; (*c)!=NULL; c++) {
                   8035:                k += (*c)->bx.a.x * (*c)->bx.a.y * (*c)->bx.b.x
                   8036:                        * (*c)->bx.b.y * (*c)->bmny * (*c)->area;
                   8037:                };
                   8038:        return(k);
                   8039:        }
                   8040: 
                   8041: #if FWRI
                   8042: fwrb_word(f,p)
                   8043:     FILE *f;
                   8044:     Word *p;
                   8045: {
                   8046: #if dbg_fwrb
                   8047:        if((!(p->ident&IsWord))||(p->ident&(IsALL&(~IsWord))))
                   8048:                err("fwrb_word: %s",word_toa(p));
                   8049:        if(p->ident&Word_label && p->l==NULL) {
                   8050:                err("fwrb_page: Word_label set but .l==NULL");
                   8051:                p->ident &= ~Word_label;
                   8052:                };
                   8053: #endif
                   8054:        fwri_Ident(f,p->ident);
                   8055:        fwri_Bbx(f,&(p->bx));
                   8056:        fwri_int2(f,p->wsp*UCHAR_MAX);
                   8057:        fwri_Merit(f,p->m);
                   8058:        fwri_Prob(f,p->p);
                   8059:        fwri_uint2(f,p->ws.mny);
                   8060:        fwri_uint2(f,p->cs.mny);
                   8061:        fwri_uint3(f,p->bs.mny);
                   8062:        /* fwri_int4(f,p->hash); */
                   8063: #if dbg_fwrb_toa
                   8064:        err("fwrb_word: %s",word_toa(p));
                   8065: #endif
                   8066:        if(p->ident&Word_label) fwrb_label(f,p->l);
                   8067:        }
                   8068: #else
                   8069: fwrb_word(fp,wp)
                   8070:     FILE *fp;
                   8071:     Word *wp;
                   8072: {   WordF wf;
                   8073:     int stat;
                   8074: #if dbg_fwrb
                   8075:        if((!(wp->ident&IsWord))||(wp->ident&(IsALL&(~IsWord))))
                   8076:                err("fwrb_word: %s",word_toa(wp));
                   8077: #endif
                   8078:        memset(&wf,'\0',sizeof(wf));
                   8079:        wf.ident = wp->ident;
                   8080:        wf.bx = wp->bx;
                   8081:        wf.wsp = wp->wsp;
                   8082:        wf.m = wp->m;
                   8083:        wf.wmny = wp->ws.mny;
                   8084:        wf.cmny = wp->cs.mny;
                   8085:        wf.bmny = wp->bs.mny;
                   8086:        if((stat=fwrite(&wf,sizeof(WordF),1,fp))!=1)
                   8087:                abort("can't write WordF, status %d",stat);
                   8088: #if dbg_fwrb_toa
                   8089:        err("fwrb_word: %s",word_toa(wp));
                   8090: #endif
                   8091:        if(wf.ident&Word_label) fwrb_label(fp,wp->l);
                   8092:        }
                   8093: #endif
                   8094: 
                   8095: fwrb_words_etc(fp,ws,etc)
                   8096:     FILE *fp;
                   8097:     Words ws;
                   8098:     Ident etc;
                   8099: {   register Word *wp,**wpp;
                   8100:        if(ws.mny>0) for(wp= *(wpp=ws.wpa); wp!=NULL; wp= *(++wpp))
                   8101:                fwrb_word_etc(fp,wp,etc);
                   8102:        }
                   8103: 
                   8104: fwrb_word_etc(fp,wp,etc)
                   8105:     FILE *fp;
                   8106:     Word *wp;
                   8107:     Ident etc;
                   8108: {   static Ident parts = (IsWord|IsChar|IsBlob);
                   8109:     Word wd;
                   8110:        if((etc&parts)!=parts) /* write selected parts */ {
                   8111:                wd = *wp;
                   8112:                if(!(etc&IsWord)) wd.ws.mny=0;
                   8113:                if(!(etc&IsChar)) wd.cs.mny=0;
                   8114:                if(!(etc&IsBlob)) wd.bs.mny=0;
                   8115:                wp = &wd;       /* write modified record */
                   8116:                };
                   8117:        fwrb_word(fp,wp);
                   8118:        if(etc&IsWord) fwrb_words_etc(fp,wp->ws,IsALL);
                   8119:        fwrb_chars_etc(fp,wp->cs,etc);
                   8120:        fwrb_blobs_etc(fp,wp->bs,etc);
                   8121:        }
                   8122: 
                   8123: #if FRDI
                   8124: int frdb_word(f,p)
                   8125:     FILE *f;
                   8126:     Word *p;
                   8127: {      *p = empty_Word;
                   8128:        if(feof(f))
                   8129:                return(0);
                   8130:        p->ident=frdi_Ident(f);
                   8131:        frdi_Bbx(f,&(p->bx));
                   8132:        p->wsp=frdi_int2(f)/(float)UCHAR_MAX;
                   8133:        p->m=frdi_Merit(f);
                   8134:        p->p=frdi_Prob(f);
                   8135:        p->ws.mny=frdi_uint2(f);
                   8136:        p->cs.mny=frdi_uint2(f);
                   8137:        p->bs.mny=frdi_uint3(f);
                   8138:        /* p->hash=frdi_int4(f); */
                   8139: #if dbg_frdb
                   8140:        if((!(p->ident&IsWord))||(p->ident&(IsALL&(~IsWord))))
                   8141:                err("frdb_word: %s",word_toa(p));
                   8142: #endif
                   8143: #if dbg_frdb_toa
                   8144:        err("frdb_word: %s",word_toa(p));
                   8145: #endif
                   8146:        if(p->ident&Word_label) p->l = frdb_label(f);
                   8147:        if(ferror(f)) return(-errno); else return(1);
                   8148:        }
                   8149: #else
                   8150: int frdb_word(fp,wp)
                   8151:     FILE *fp;
                   8152:     Word *wp;
                   8153: {   WordF wf;
                   8154:     int stat;
                   8155:        if((stat=fread(&wf,sizeof(WordF),1,fp))!=1)
                   8156:                abort("can't read WordF, status %d",stat);
                   8157:        *wp = empty_Word;
                   8158:        wp->ident = wf.ident;
                   8159:        wp->bx = wf.bx;
                   8160:        wp->wsp = wf.wsp;
                   8161:        wp->m = wf.m;
                   8162:        wp->ws.mny = wf.wmny;
                   8163:        wp->cs.mny = wf.cmny;
                   8164:        wp->bs.mny = wf.bmny;
                   8165: #if dbg_frdb
                   8166:        if((!(wp->ident&IsWord))||(wp->ident&(IsALL&(~IsWord))))
                   8167:                err("frdb_word: %s",word_toa(wp));
                   8168: #endif
                   8169: #if dbg_frdb_toa
                   8170:        err("frdb_word: %s",word_toa(wp));
                   8171: #endif
                   8172:        if(wp->ident&Word_label) wp->l = frdb_label(fp);
                   8173:        if(ferror(fp)) return(-errno); else return(1);
                   8174:        }
                   8175: #endif
                   8176: 
                   8177: frdb_word_etc(fp,wp,etc)
                   8178:     FILE *fp;
                   8179:     Word *wp;
                   8180:     Ident etc;
                   8181: {   WordF cf;
                   8182:     int stat;
                   8183:        frdb_word(fp,wp);
                   8184:        frdb_words_etc(fp,&(wp->ws),IsALL); /* rd alternatives entirely, if any */
                   8185:        if(etc&IsChar && wp->cs.mny>0)
                   8186:                frdb_chars_etc(fp,&(wp->cs),etc);
                   8187:        else wp->cs = empty_Chars;
                   8188:        if(etc&IsBlob && wp->bs.mny>0)
                   8189:                frdb_blobs_etc(fp,&(wp->bs),etc);
                   8190:        else wp->bs = empty_Blobs;
                   8191:        if(ferror(fp)) return(-errno); else return(1);
                   8192:        }
                   8193: 
                   8194: /* read words, and their parts */
                   8195: frdb_words_etc(fp,wsp,etc)
                   8196:     FILE *fp;
                   8197:     Words *wsp;
                   8198:     Ident etc;
                   8199: {   int wi;
                   8200:     register Word *wp,**wpp;
                   8201:        if(wsp->mny<=0) {
                   8202:                *wsp = empty_Words;
                   8203:                return(1);
                   8204:                };
                   8205:        if((wpp=wsp->wpa=(Word **)malloc((wsp->mny+1)*sizeof(Word *)))==NULL)
                   8206:                abort("can't alloc Words.wpa array");
                   8207:        for(wi=0; wi<wsp->mny; wi++) {
                   8208:                *(wpp++) = wp = alloc_word();
                   8209:                frdb_word_etc(fp,wp,etc);
                   8210:                };
                   8211:        *wpp = NULL;
                   8212:        if(ferror(fp)) return(-errno); else return(1);
                   8213:        }
                   8214: 
                   8215: /* remove a word from a words set */
                   8216: remove_word(wp,wsp)
                   8217:     Word *wp;
                   8218:     Words *wsp;
                   8219: {   register Word *rp,**rpp,**npp;
                   8220:        if(wsp->mny==0) err("can't remove Word - Words empty");
                   8221:        else {  for(rp= *(rpp=wsp->wpa); rp!=NULL; rp= *(++rpp)) if(rp==wp) break;
                   8222:                if(rp==NULL) err("can't remove Word - not found");
                   8223:                else {  /* move later entries up */
                   8224:                        npp=rpp+1;
                   8225:                        do *(rpp++)= *(npp++); while ((*rpp)!=NULL);
                   8226:                        if((--(wsp->mny))==0) {free(wsp->wpa); wsp->wpa=NULL;};
                   8227:                        /* don't bother to realloc downwards */
                   8228:                        };
                   8229:                };
                   8230:        }
                   8231: 
                   8232: /* Remove a Word from a Txtln's Words set.
                   8233:    Shrink the Txtln's Bbx if the Word abuts it on the left or right.
                   8234:    Ensure that the first Word in the line has wsp==0.0
                   8235:    BUG:  doesn't update wsp of trailing Word */
                   8236: remove_word_txtln(wp,lp)
                   8237:     Word *wp;
                   8238:     Txtln *lp;
                   8239: {   register Word *cwp,**wpp;
                   8240:        remove_word(wp,&(lp->ws));
                   8241:        if(lp->ws.mny>0) {
                   8242:                if(wp->bx.a.x==lp->bx.a.x || wp->bx.b.x==lp->bx.b.x) {
                   8243:                        /* recompute possibly shrunken bx */
                   8244:                        lp->bx=empty_Bbx;
                   8245:                        for(cwp= *(wpp=lp->ws.wpa); cwp!=NULL; cwp= *(++wpp))
                   8246:                                merge_bbx(&(cwp->bx),&(lp->bx));
                   8247:                        };
                   8248:                (lp->ws.wpa[0])->wsp=0.0;
                   8249:                };
                   8250:        }
                   8251: 
                   8252: /* Append a word to the end of a words set.
                   8253:    Do NOT maintain set in order ascending on Word.bx.a.x.
                   8254:    Return the appended Word. */
                   8255: Word *append_word(wp,wsp)
                   8256:     Word *wp;
                   8257:     Words *wsp;
                   8258: {      if(wsp->mny==0) {
                   8259:                if((wsp->wpa=(Word **)malloc(2*sizeof(Word *)))==NULL)
                   8260:                        abort("append_word: can't malloc wsp->wpa");
                   8261:                }
                   8262:        else {  if((wsp->wpa=(Word **)realloc(
                   8263:                                wsp->wpa,
                   8264:                                (wsp->mny+2)*sizeof(Word *))
                   8265:                                )==NULL)
                   8266:                        abort("append_word: can't realloc wsp->wpa");
                   8267:                };
                   8268:        wsp->wpa[wsp->mny++] = wp;
                   8269:        wsp->wpa[wsp->mny] = NULL;
                   8270:        return(wp);
                   8271:        }
                   8272: 
                   8273: /* Insert a Word into a Words set.  Words is assumed to be sorted ascending
                   8274:    on Word.bx.a.x, and this order is maintained.
                   8275:    Words with equal Word.bx.a.x are stored in the order that they were
                   8276:    inserted:  so that the first one inserted remains the first among equals
                   8277:    (this feature is important for certain WordSet applications).
                   8278:    Return inserted (Word *) */
                   8279: Word *insert_word(wp,wsp)
                   8280:     Word *wp;
                   8281:     Words *wsp;
                   8282: {   register Word **wpp,*nwp,*pwp;
                   8283:        if(wsp->mny==0) {
                   8284:                if((wsp->wpa=(Word **)malloc(2*sizeof(Word *)))==NULL)
                   8285:                        abort("insert_word: can't malloc wsp->wpa");
                   8286:                wsp->wpa[wsp->mny] = wp;
                   8287:                }
                   8288:        else {  if((wpp=wsp->wpa=(Word **)realloc(
                   8289:                                wsp->wpa,
                   8290:                                (wsp->mny+2)*sizeof(Word *))
                   8291:                                )==NULL)
                   8292:                        abort("insert_word: can't realloc wsp->wpa");
                   8293:                while(((*wpp)!=NULL)&&(*wpp)->bx.a.x<=wp->bx.a.x) wpp++;
                   8294:                /* **wpp is now 1st entry > *wp in sorted order; insert
                   8295:                   new word just before it */
                   8296:                pwp=wp;
                   8297:                do {    nwp= *wpp;
                   8298:                        *(wpp++)=pwp;
                   8299:                        pwp=nwp;
                   8300:                        }
                   8301:                while(pwp!=NULL);
                   8302:                };
                   8303:        wsp->wpa[++wsp->mny] = NULL;
                   8304:        return(wp);
                   8305:        }
                   8306: 
                   8307: /* Insert a Word into the Words owned by a given Txtln,
                   8308:    maintaining the Txtln's Bbx and sorted order in the Words set.
                   8309:    Return the inserted Word * */
                   8310: Word *insert_word_txtln(wp,lp)
                   8311:     Word *wp;
                   8312:     Txtln *lp;
                   8313: {      merge_bbx(&(wp->bx),&(lp->bx));
                   8314:        return(insert_word(wp,&(lp->ws)));
                   8315:        }
                   8316: 
                   8317: /* Free wordinterp and its parts as specified in etc.
                   8318:    Always free its strings (if any).
                   8319:    If etc&IsWordInterp, free the record itself also.
                   8320: */
                   8321: free_wordinterp_etc(p,etc)
                   8322:     WordInterp *p;
                   8323:     Ident etc;
                   8324: {      if(p->s!=NULL) { free(p->s);  p->s=NULL; };
                   8325:        if(p->pp!=NULL) { free(p->pp);  p->pp=NULL; };
                   8326:        if(p->by!=NULL) { free(p->by);  p->by=NULL; };
                   8327:        if(p->po!=NULL) { free(p->po);  p->po=NULL; };
                   8328:        if(p->ps!=NULL) { free(p->ps);  p->ps=NULL; };
                   8329:        if(etc&IsWordInterp) free(p);
                   8330:        }
                   8331: 
                   8332: /* Duplicate (return ptr to local static copy of) a WordInterp.
                   8333:    Always free its strings (if any).
                   8334:    'etc' is ignored.
                   8335: */
                   8336: WordInterp *dup_wordinterp_etc(p,etc)
                   8337:     WordInterp *p;
                   8338:     Ident etc;
                   8339: {   static WordInterp d;
                   8340:        d = *p;
                   8341:        if(p->s!=NULL) d.s = strdup(p->s);
                   8342:        if(p->pp!=NULL) d.pp = strdup(p->pp);
                   8343:        if(p->by!=NULL) d.by = strdup(p->by);
                   8344:        if(p->po!=NULL) d.po = strdup(p->po);
                   8345:        if(p->ps!=NULL) d.ps = strdup(p->ps);
                   8346:        return(&d);
                   8347:        }
                   8348: 
                   8349: /* Unconditionally free the malloc-space array of pointers, and empty the set.
                   8350:    Don't free the records that it owned.
                   8351:    */
                   8352: free_words(wsp)
                   8353:     Words *wsp;
                   8354: {      if(wsp->wpa!=NULL) { free(wsp->wpa); wsp->wpa = NULL; }
                   8355:        wsp->mny = 0;
                   8356:        }
                   8357: 
                   8358: free_words_etc(wsp,etc)
                   8359:     Words *wsp;
                   8360:     Ident etc;
                   8361: {   register Word *wp,**wpp;
                   8362:     int wi;
                   8363:        if(wsp->mny>0&&(etc&IsWord))
                   8364:                for(wp= *(wpp=wsp->wpa); wp!=NULL; wp= *(++wpp))
                   8365:                        free_word_etc(wp,etc);
                   8366:        free_words(wsp);
                   8367:        }
                   8368: 
                   8369: /* return a pointer to a distinct and duplicate copy of *wp,
                   8370:    created out of malloc space */
                   8371: Word *dup_word(wp)
                   8372:     Word *wp;
                   8373: {   Word *dup;
                   8374:        if((dup=(Word *)malloc(sizeof(Word)))==NULL)
                   8375:                abort("can't dup Word");
                   8376:        alloc_census(Word,1);
                   8377:        *dup = *wp;
                   8378:        return(dup);
                   8379:        }
                   8380: 
                   8381: /* Return a pointer to a distinct and duplicate copy of *wp, and ALL it owns,
                   8382:    created out of malloc space. (HOW they are duplicated is controlled by flags
                   8383:    in etc.) */
                   8384: Word *dup_word_etc(wp,etc)
                   8385:     Word *wp;
                   8386:     Ident etc;
                   8387: {   Word *dup;
                   8388:        dup = dup_word(wp);
                   8389:        if(dup->ws.mny>0) dup->ws = *dup_words_etc(&(wp->ws),etc);
                   8390:        else dup->ws = empty_Words;
                   8391:        if(dup->cs.mny>0) dup->cs = *dup_chars_etc(&(wp->cs),etc);
                   8392:        else dup->cs = empty_Chars;
                   8393:        if(dup->bs.mny>0) dup->bs = *dup_blobs_etc(&(wp->bs),etc);
                   8394:        else dup->bs = empty_Blobs;
                   8395:        return(dup);
                   8396:        }
                   8397: 
                   8398: /* Return a pointer to a distinct local static duplicate of non-empty *wsp.
                   8399:    Its wpa array is created newly out of malloc space.
                   8400:    If etc&IsWord, all its Words are also duplicated,
                   8401:    else the contents of wpa point to the old unduplicated Words.
                   8402:    */
                   8403: Words *dup_words_etc(wsp,etc)
                   8404:     Words *wsp;
                   8405:     Ident etc;         /* parts to duplicate */
                   8406: {   static Words dup;
                   8407:     register Word **wpp,**dpp;
                   8408:        if((dup.mny=wsp->mny)<=0) dup = empty_Words;
                   8409:        else {  if((dup.wpa=(Word **)malloc((dup.mny+1)*sizeof(Word *)))==NULL)
                   8410:                        abort("can't dup ws.wpa");
                   8411:                for(wpp=wsp->wpa,dpp=dup.wpa; *wpp!=NULL; wpp++,dpp++) {
                   8412:                        if(etc&IsWord) *dpp = dup_word_etc(*wpp,etc);
                   8413:                        else *dpp = *wpp;
                   8414:                        };
                   8415:                *dpp = NULL;
                   8416:                };
                   8417:        return(&dup);
                   8418:        }
                   8419: 
                   8420: WordInterp *alloc_wordinterp()
                   8421: {    WordInterp *p;
                   8422:        if((p=(WordInterp *)malloc(sizeof(WordInterp)))==NULL)
                   8423:                abort("can't alloc WordInterp");
                   8424:        else {  *p = empty_WordInterp;
                   8425:                return(p);
                   8426:                };
                   8427:        }
                   8428: 
                   8429: char *wordinterp_toa(p)
                   8430:     WordInterp *p;
                   8431: {    static char s[80];
                   8432:        sprintf(s,"%s %s %s|%s|%s|%s",
                   8433:                ident_toa(p->ident),
                   8434:                ((p->s!=NULL)? p->s: ""),
                   8435:                ((p->pp!=NULL)? p->pp: ""),
                   8436:                ((p->by!=NULL)? p->by: ""),
                   8437:                ((p->po!=NULL)? p->po: ""),
                   8438:                ((p->ps!=NULL)? p->ps: "")
                   8439:                );
                   8440:        return(s);
                   8441:        }
                   8442: 
                   8443: /* Free Word and its parts, as specified by etc.
                   8444:    Always free the pointer-arrays of ws, cs & bs.
                   8445:    If etc&IsWord, free all Words in ws also.
                   8446:    If etc&IsChar, free all Chars in cs also.
                   8447:    If etc&IsBlob, free all Blobs in bs also.
                   8448: */
                   8449: free_word_etc(p,etc)
                   8450:     Word *p;
                   8451:     Ident etc;
                   8452: #define dbg_fwe (F)
                   8453: {      if(dbg_fwe) {
                   8454:                err("free_word_etc: %s",word_toa(p));
                   8455:                err("free_word_etc: %s",ident_toa(etc));
                   8456:                err_census_all;
                   8457:                };
                   8458:        free_words_etc(&(p->ws),IsALL);
                   8459:        free_chars_etc(&(p->cs),etc);
                   8460:        free_blobs_etc(&(p->bs),etc);
                   8461:        if(p->ident&Word_label && p->l!=NULL) {
                   8462:                free(p->l);  p->l=NULL;  p->ident &= ~Word_label;
                   8463:                };
                   8464:        if(etc&IsWord) free_word(p);
                   8465:        if(dbg_fwe) err_census_all;
                   8466:        }
                   8467: 
                   8468: free_word(wp)
                   8469:     Word *wp;
                   8470: {      free(wp);
                   8471:        free_census(Word,1);
                   8472:        }
                   8473: 
                   8474: fwrb_sfeats(fp,sfv)
                   8475:     FILE *fp;
                   8476:     SFv sfv;
                   8477: {   register Pval *vp,*vq;
                   8478:        for(vq=(vp=sfv)+SF_MNY; vp<vq; vp++)
                   8479:                fwri_int3(fp,USHRT_MAX*(*vp)+0.5);
                   8480: #if dbg_fwrb_toa
                   8481:        /** err("fwrb_sfeats: %s",sfeats_toa(sfv)); **/
                   8482: #endif
                   8483:        }
                   8484: 
                   8485: int frdb_sfeats(fp,sfv)
                   8486:     FILE *fp;
                   8487:     SFv sfv;
                   8488: {   register Pval *vp,*vq;
                   8489:        for(vq=(vp=sfv)+SF_MNY; vp<vq; vp++)
                   8490:                *vp = frdi_int3(fp)/((Pval)USHRT_MAX);
                   8491: #if dbg_frdb_toa
                   8492:        /** err("frdb_sfeats: %s",sfeats_toa(sfv)); **/
                   8493: #endif
                   8494:        }
                   8495: 
                   8496: /* return ptr to local static copy of Shapes of given size */
                   8497: Shapes *alloc_shapes(mny)
                   8498:     int mny;
                   8499: {   static Shapes shs;
                   8500:        shs.mny = shs.alloc = mny;
                   8501:        if((shs.sa=(Nb_s *)malloc(shs.alloc*sizeof(Nb_s)))==NULL)
                   8502:                abort("can't alloc Shapes.sa[%d]",shs.alloc);
                   8503:        return(&shs);
                   8504:        }
                   8505: 
                   8506: fwrb_shapes(fp,p)
                   8507:     FILE *fp;
                   8508:     Shapes *p; /* on entry, p->mny has already been written */
                   8509: {   int dim;
                   8510:     register Nb_s *sp,*sq;
                   8511:     register Pval *vp;
                   8512:        if(p->mny>0&&p->sa!=NULL) {
                   8513:                for(sq=(sp=p->sa)+p->mny; sp<sq; sp++) {
                   8514:                        dim=Sh_dim[sp->t&(~Sh_tiny)];
                   8515:                        fwri_uint1(fp,(sp->t&0x7F)|((sp->t&Sh_tiny)?0x80:0x00));
                   8516:                        fwri_int2(fp,(*(vp=sp->p))*SHRT_MAX);
                   8517:                        if(dim>1) { fwri_int2(fp,(*(++vp))*SHRT_MAX);
                   8518:                         if(dim>2) { fwri_int2(fp,(*(++vp))*SHRT_MAX);
                   8519:                          if(dim>3) { fwri_int2(fp,(*(++vp))*SHRT_MAX);
                   8520:                                } } };
                   8521:                        };
                   8522:                };
                   8523: #if dbg_fwrb_toa
                   8524:        /** err("fwrb_shapes: %s",shapes_toa(p)); **/
                   8525: #endif
                   8526:        }
                   8527: 
                   8528: int frdb_shapes(fp,p)
                   8529:     FILE *fp;
                   8530:     Shapes *p; /* on entry, p->mny has already been read */
                   8531: {   register Nb_s *sp,*sq;
                   8532:     register Pval *vp;
                   8533:     uint1 ui1;
                   8534:     int dim;
                   8535:     
                   8536:        if(p->mny>0) {
                   8537:                *p = *alloc_shapes(p->mny);
                   8538:                for(sq=(sp=p->sa)+p->mny; sp<sq; sp++) {
                   8539:                        ui1 = frdi_uint1(fp);
                   8540:                        sp->t = ui1&0x7F|((ui1&0x80)?Sh_tiny:0);
                   8541:                        dim=Sh_dim[sp->t&(~Sh_tiny)];
                   8542:                        *(vp=sp->p) = ((float)frdi_int2(fp))/SHRT_MAX;
                   8543:                        if(dim>1) { *(++vp) = ((float)frdi_int2(fp))/SHRT_MAX;
                   8544:                         if(dim>2) { *(++vp) = ((float)frdi_int2(fp))/SHRT_MAX;
                   8545:                          if(dim>3) { *(++vp) = ((float)frdi_int2(fp))/SHRT_MAX;
                   8546:                                } } };
                   8547:                        };
                   8548:                }
                   8549:        else {  p->alloc = 0;
                   8550:                if(p->sa!=NULL) free(p->sa);
                   8551:                p->sa = NULL;
                   8552:                };
                   8553: #if dbg_frdb_toa
                   8554:        /** err("frdb_shapes: %s",shapes_toa(p)); **/
                   8555: #endif
                   8556:        }
                   8557: 
                   8558: fwra_shapes_etc(fp,p,t)
                   8559:     FILE *fp;
                   8560:     Shapes *p;
                   8561:     char *t;   /* string of shape types (empty => all) */
                   8562: {   Nb_s *s;
                   8563:     int i,j;
                   8564:     char a[80],f[10];
                   8565:        for(i=0,s=p->sa; i<p->mny; i++,s++) {
                   8566:                if(t[0]=='\0'||strchr(t,Sh_nam[s->t&(~Sh_tiny)])!=NULL) {
                   8567:                        sprintf(a,"%c%c ",
                   8568:                                Sh_nam[s->t&(~Sh_tiny)],
                   8569:                                (s->t&Sh_tiny)?'\'':' '
                   8570:                                );
                   8571:                        for(j=0;j<Sh_dim[s->t&(~Sh_tiny)];j++) {
                   8572:                                sprintf(f," %0.3f",s->p[j]);
                   8573:                                strcat(a,f);
                   8574:                                };
                   8575:                        fprintf(fp,"%s\n",a);
                   8576:                        };
                   8577:                };
                   8578:        }
                   8579: 
                   8580: err_shapes(shp)
                   8581:     Shapes *shp;
                   8582: {   int si,di;
                   8583:     Nb_s *sp;
                   8584:        fprintf(stderr,"shapes %d:\n",shp->mny);
                   8585:        for(si=0,sp=shp->sa; si<shp->mny; si++,sp++) {
                   8586:                fprintf(stderr,"  %c",Sh_nam[sp->t]);
                   8587:                for(di=0; di<Sh_dim[sp->t]; di++)
                   8588:                        fprintf(stderr," %6.3f",sp->p[di]);
                   8589:                fprintf(stderr,"\n");
                   8590:                };
                   8591:        }
                   8592: 
                   8593: /* Unconditionally free the malloc-space array of pointers, and empty the set.
                   8594:    Don't free the records that it owned.
                   8595:    */
                   8596: free_shapes(shp)
                   8597:     Shapes *shp;
                   8598: {      if(shp->sa!=NULL) {
                   8599:                if(shp->alloc<=0) abort("can't free unalloc'ed shapes");
                   8600:                else { free(shp->sa); shp->sa=NULL; };
                   8601:                };
                   8602:        shp->mny = shp->alloc = 0;
                   8603:        }
                   8604: 
                   8605: /* functions for RanParms */
                   8606: 
                   8607: RanParms *alloc_ranparms()
                   8608: {    RanParms *rp;
                   8609:        if((rp=(RanParms *)malloc(sizeof(RanParms)))==NULL)
                   8610:                abort("alloc_ranparms: can't alloc");
                   8611:        *rp = empty_RanParms;
                   8612:        return(rp);
                   8613:        }
                   8614: 
                   8615: free_ranparms(ran)
                   8616:     RanParms *ran;
                   8617: {      free(ran);
                   8618:        }
                   8619: 
                   8620: RanParms *dup_ranparms(p)
                   8621:     RanParms *p;
                   8622: {   RanParms *dup;
                   8623:        dup = alloc_ranparms();
                   8624:        *dup = *p;
                   8625:        return(dup);
                   8626:        }
                   8627: 
                   8628: char *ranparms_toa(ran,select)
                   8629:     RanParms *ran;
                   8630:     char *select;      /* a string, subset of: "*rpabejkstxy" if "*" or "" ALL */
                   8631: {   static char s[200];
                   8632:     char p[20];
                   8633:     char *cp;
                   8634:     static char select_all[] = "abejkprstxy";
                   8635:        s[0]='\0';
                   8636:        if(select[0]=='*'||select[0]=='\0') select=select_all;
                   8637:        for(cp=select; *cp!='\0'; cp++) {
                   8638:            switch(*cp) {
                   8639:                case 'a':  sprintf(p,"a%0.3f ",ran->skew/DtoR);  strcat(s,p);  break;
                   8640:                case 'b':  sprintf(p,"b%0.3f ",ran->bhgt);  strcat(s,p);  break;
                   8641:                case 'e':  sprintf(p,"e%0.3f ",ran->blur);  strcat(s,p);  break;
                   8642:                case 'j':  sprintf(p,"j%0.3f ",ran->jitter);  strcat(s,p);  break;
                   8643:                case 'k':  sprintf(p,"k%0.3f ",ran->kern);  strcat(s,p);  break;
                   8644:                case 'p':  sprintf(p,"p%g ",ran->size);  strcat(s,p);  break;
                   8645:                case 'r':  sprintf(p,"r%d,%d ",ran->res_x,ran->res_y);  strcat(s,p);  break;
                   8646:                case 's':  sprintf(p,"s%0.4f ",ran->speckle);  strcat(s,p);  break;
                   8647:                case 't':  sprintf(p,"t%0.3f ",ran->thresh);  strcat(s,p);  break;
                   8648:                case 'x':  sprintf(p,"x%0.3f ",ran->xscale);  strcat(s,p);  break;
                   8649:                case 'y':  sprintf(p,"y%0.3f ",ran->yscale);  strcat(s,p);  break;
                   8650:                };
                   8651:            };
                   8652:        return(s);
                   8653:        }
                   8654: 
                   8655: RanParms *ato_ranparms(s)
                   8656:     char *s;
                   8657: {   static RanParms ran;
                   8658:     char *f,n,*v;
                   8659: #define TOKEN_SEP "=, \n"
                   8660:        f=strtok(s,TOKEN_SEP);
                   8661:        while(f!=NULL&&strlen(f)>0) {
                   8662:                n=f[0];  v=f+1;
                   8663:                switch(n) {
                   8664:                    case 'r':   /* res */
                   8665:                        ran.res_x = atoi(v);
                   8666:                        v=strtok((char *)0,TOKEN_SEP);
                   8667:                        ran.res_y = atoi(v);
                   8668:                        break;
                   8669:                    case 'p':   ran.size = atof(v);  break;
                   8670:                    case 'a':   ran.skew = atof(v)*DtoR;  break;
                   8671:                    case 'b':   ran.bhgt = atof(v);  break;
                   8672:                    case 'e':   ran.blur = atof(v);  break;
                   8673:                    case 'j':   ran.jitter = atof(v);  break;
                   8674:                    case 'k':   ran.kern = atof(v);  break;
                   8675:                    case 's':   ran.speckle = atof(v);  break;
                   8676:                    case 't':   ran.thresh = atof(v);  break;
                   8677:                    case 'x':   ran.xscale = atof(v);  break;
                   8678:                    case 'y':   ran.yscale = atof(v);  break;
                   8679:                    };
                   8680:                f=strtok((char *)0,TOKEN_SEP);
                   8681:                };
                   8682:        return(&ran);
                   8683:        }
                   8684: 
                   8685: #if FWRI
                   8686: fwrb_ranparms(f,p)
                   8687:     FILE *f;
                   8688:     RanParms *p;
                   8689: {      fwri_int2(f,p->res_x);
                   8690:        fwri_int2(f,p->res_y);
                   8691:        fwri_Pts(f,p->size);
                   8692:        fwri_Radians(f,p->skew);
                   8693:        fwri_Ems(f,p->bhgt);
                   8694:        fwri_int3(f,p->blur*10000.0);
                   8695:        fwri_int3(f,p->jitter*10000.0);
                   8696:        fwri_int3(f,p->kern*10000.0);
                   8697:        fwri_int3(f,p->speckle*10000.0);
                   8698:        fwri_int3(f,p->thresh*10000.0);
                   8699:        fwri_int3(f,p->xscale*10000.0);
                   8700:        fwri_int3(f,p->yscale*10000.0);
                   8701: #if dbg_fwrb_toa
                   8702:        err("fwrb_ranparms: %s",ranparms_toa(p));
                   8703: #endif
                   8704:        }
                   8705: #else
                   8706: fwrb_ranparms(f,p)
                   8707:     FILE *f;
                   8708:     RanParms *p;
                   8709: {      if((fwrite(p,sizeof(RanParms),1,f))!=1) return(0);
                   8710: #if dbg_fwrb_toa
                   8711:        err("fwrb_ranparms: %s",ranparms_toa(p));
                   8712: #endif
                   8713:        }
                   8714: #endif
                   8715: 
                   8716: #if FRDI
                   8717: int frdb_ranparms(f,p)
                   8718:     FILE *f;
                   8719:     RanParms *p;
                   8720: {      *p = empty_RanParms;
                   8721:        if(feof(f))
                   8722:                return(0);
                   8723:        p->res_x=frdi_int2(f);
                   8724:        p->res_y=frdi_int2(f);
                   8725:        p->size=frdi_Pts(f);
                   8726:        p->skew=frdi_Radians(f);
                   8727:        p->bhgt=frdi_Ems(f);
                   8728:        p->blur=frdi_int3(f)/10000.0;
                   8729:        p->jitter=frdi_int3(f)/10000.0;
                   8730:        p->kern=frdi_int3(f)/10000.0;
                   8731:        p->speckle=frdi_int3(f)/10000.0;
                   8732:        p->thresh=frdi_int3(f)/10000.0;
                   8733:        p->xscale=frdi_int3(f)/10000.0;
                   8734:        p->yscale=frdi_int3(f)/10000.0;
                   8735: #if dbg_frdb_toa
                   8736:        err("frdb_ranparms: %s",ranparms_toa(p));
                   8737: #endif
                   8738:        if(ferror(f)) return(-errno); else return(1);
                   8739:        }
                   8740: #else
                   8741: int frdb_ranparms(fp,ran)
                   8742:     FILE *fp;
                   8743:     RanParms *ran;
                   8744: {      if((fread(ran,sizeof(RanParms),1,fp))<1) return(0);
                   8745: #if dbg_frdb_toa
                   8746:        err("frdb_ranparms: %s",ranparms_toa(ran));
                   8747: #endif
                   8748:        }
                   8749: #endif
                   8750: 
                   8751: Char *alloc_char()
                   8752: {    Char *p;
                   8753:        if((p=(Char *)malloc(sizeof(Char)))==NULL)
                   8754:                abort("can't alloc Char");
                   8755:        alloc_census(Char,1);
                   8756:        *p = empty_Char;
                   8757:        return(p);
                   8758:        }
                   8759: 
                   8760: char *char_toa(cp)
                   8761:     Char *cp;
                   8762: {   static char s[100],bfs[24];
                   8763:        if(cp->bfsp==NULL) strcpy(bfs,"0");
                   8764:        else if(cp->bfsp->bm.n==0) strcpy(bfs,"0");
                   8765:        else if(cp->bfsp->bm.mny==0) sprintf(bfs,"%d",cp->bfsp->bm.n);
                   8766:        else sprintf(bfs,"%d,%d",cp->bfsp->bm.n,cp->bfsp->bm.mny);
                   8767:        sprintf(s,"%s bx%s w%d,h%d cs%d bl%d ar%d pe%d sf%d sh%d bf%s i%d",
                   8768:                ident_toa(cp->ident),
                   8769:                bbx_toa(&(cp->bx)),
                   8770:                bbx_wid(&cp->bx),bbx_hgt(&cp->bx),
                   8771:                cp->csp,
                   8772:                cp->bmny,
                   8773:                cp->area,cp->per,
                   8774:                (cp->sfv==NULL)? 0: 1,
                   8775:                cp->sh.mny,
                   8776:                bfs,
                   8777:                cp->il.mny
                   8778:                );
                   8779:        return(s);
                   8780:        }
                   8781: 
                   8782: /* compute the centroid of the Char (offset from bx.a) */
                   8783: Pp *char_centroid(cp)
                   8784:     Char *cp;
                   8785: {   static Pp c;
                   8786:     Pp *bc;    /* blob centroid */
                   8787:     Blob *bp;
                   8788:     int bi;
                   8789:        c.x = c.y = 0.0;
                   8790:        for(bi=0, bp=cp->fi; bi<cp->bmny; bi++, bp=bp->n) {
                   8791:                bc = blob_centroid(bp);
                   8792:                c.x += bp->area * (bc->x + (cp->bx.a.x - cp->bx.a.x));
                   8793:                c.y += bp->area * (bc->y + (cp->bx.a.y - cp->bx.a.y));
                   8794:                };
                   8795:        c.x /= cp->area;
                   8796:        c.y /= cp->area;
                   8797:        return(&c);
                   8798:        }
                   8799: 
                   8800: #if FWRI
                   8801: fwrb_char(f,p)
                   8802:     FILE *f;
                   8803:     Char *p;
                   8804: {
                   8805: #if dbg_fwrb
                   8806:        if((!(p->ident&IsChar))||(p->ident&(IsALL&(~IsChar))))
                   8807:                err("fwrb_char: %s",char_toa(p));
                   8808:        if(p->ident&Char_label && p->l==NULL) {
                   8809:                err("fwrb_page: Char_label set but .l==NULL");
                   8810:                p->ident &= ~Char_label;
                   8811:                };
                   8812:        if(p->ident&Char_ranparms && p->rp==NULL) {
                   8813:                err("fwrb_page: Char_ranparms set but .rp==NULL");
                   8814:                p->ident &= ~Char_ranparms;
                   8815:                };
                   8816: #endif
                   8817:        fwri_Ident(f,p->ident);
                   8818:        fwri_Bbx(f,&(p->bx));
                   8819:        fwri_Scoor(f,p->csp);
                   8820:        fwri_uint4(f,p->area);
                   8821:        fwri_uint4(f,p->per);
                   8822:        fwri_Scoor(f,p->basl);
                   8823:        fwri_uint3(f,p->bmny);
                   8824:        fwri_uint2(f,p->il.mny);
                   8825:        fwri_uint1(f,(p->sfv!=NULL)?SF_MNY:0);
                   8826:        fwri_uint2(f,p->sh.mny);
                   8827:        fwri_uint2(f,(p->bfsp!=NULL)?p->bfsp->bm.n:0);
                   8828: #if dbg_fwrb_toa
                   8829:        err("fwrb_char: %s",char_toa(p));
                   8830: #endif
                   8831:        if(p->ident&Char_label) fwrb_label(f,p->l);
                   8832:        if(p->ident&Char_ranparms) fwrb_ranparms(f,p->rp);
                   8833:        }
                   8834: #else
                   8835: fwrb_char(fp,cp)
                   8836:     FILE *fp;
                   8837:     Char *cp;
                   8838: {   CharF cf;
                   8839:     int stat;
                   8840: #if dbg_fwrb
                   8841:        if((!(cp->ident&IsChar))||(cp->ident&(IsALL&(~IsChar))))
                   8842:                err("fwrb_char: %s",char_toa(cp));
                   8843: #endif
                   8844:        memset(&cf,'\0',sizeof(cf));
                   8845:        if(cp->ident&Char_ranparms && cp->rp==NULL)
                   8846:                cp->ident &= ~Char_ranparms;
                   8847:        cf.ident = cp->ident | IsChar;
                   8848:        cf.bx = cp->bx;
                   8849:        cf.csp = cp->csp;
                   8850:        cf.area = cp->area;
                   8851:        cf.per = cp->per;
                   8852:        /* basl omitted */
                   8853:        cf.bmny = cp->bmny;
                   8854:        cf.imny = cp->il.mny;
                   8855:        cf.sfmny = (cp->sfv!=NULL)?SF_MNY:0;
                   8856:        cf.shmny = cp->sh.mny;
                   8857:        if(cp->bfsp!=NULL) cf.bfmny = cp->bfsp->bm.n; else cf.bfmny=0;
                   8858:        if((stat=fwrite(&cf,sizeof(CharF),1,fp))!=1)
                   8859:                abort("can't write CharF, status %d",stat);
                   8860: #if dbg_fwrb_toa
                   8861:        err("fwrb_char: %s",char_toa(cp));
                   8862: #endif
                   8863:        if(cf.ident&Char_ranparms) fwrb_ranparms(fp,cp->rp);
                   8864:        if(cf.ident&Char_label) fwrb_label(fp,cp->l);
                   8865:        }
                   8866: #endif
                   8867: 
                   8868: fwrb_chars_etc(fp,cs,etc)
                   8869:     FILE *fp;
                   8870:     Chars cs;
                   8871:     Ident etc;
                   8872: {   register Char *cp,**cpp;
                   8873:        if(cs.mny>0) for(cp= *(cpp=cs.cpa); cp!=NULL; cp= *(++cpp))
                   8874:                fwrb_char_etc(fp,cp,etc);
                   8875:        }
                   8876: 
                   8877: fwrb_char_etc(fp,cp,etc)
                   8878:     FILE *fp;
                   8879:     Char *cp;
                   8880:     Ident etc;
                   8881: {   static Ident parts = (IsInterp|IsBlob|IsShapes|IsBfeats|IsSfeats);
                   8882:     Char ch;
                   8883:        if((etc&parts)!=parts) /* write selected parts */ {
                   8884:                ch = *cp;
                   8885:                if(!(etc&IsInterp)) ch.il.mny=0;
                   8886:                if(!(etc&IsBlob)) ch.bmny=0;
                   8887:                if(!(etc&IsSfeats)) ch.sfv = NULL;
                   8888:                if(!(etc&IsShapes)) ch.sh = empty_Shapes;
                   8889:                if(!(etc&IsBfeats)) ch.bfsp = NULL;
                   8890:                cp = &ch;       /* write modified record */
                   8891:                };
                   8892:        fwrb_char(fp,cp);
                   8893:        if(cp->sfv!=NULL) fwrb_sfeats(fp,cp->sfv);
                   8894:        if(cp->sh.mny>0) fwrb_shapes(fp,&(cp->sh));
                   8895: #if CPU!=CRAY
                   8896:        if(cp->bfsp!=NULL) fwrb_bfeats(fp,cp->bfsp);
                   8897: #endif
                   8898:        fwrb_interpl_etc(fp,cp->il,etc);
                   8899:        if(cp->bmny>0) fwrb_blobl_etc(fp,cp->bmny,cp->fi,etc);
                   8900:        }
                   8901: 
                   8902: #if FRDI
                   8903: int frdb_char(f,p)
                   8904:     FILE *f;
                   8905:     Char *p;
                   8906: {   int sf_mny,bf_mny;
                   8907:        *p = empty_Char;
                   8908:        if(feof(f))
                   8909:                return(0);
                   8910:        p->ident=frdi_Ident(f);
                   8911:        frdi_Bbx(f,&(p->bx));
                   8912:        p->csp=frdi_Scoor(f);
                   8913:        p->area=frdi_uint4(f);
                   8914:        p->per=frdi_uint4(f);
                   8915:        p->basl=frdi_Scoor(f);
                   8916:        p->bmny=frdi_uint3(f);
                   8917:        p->il.mny=frdi_uint2(f);
                   8918:        if((sf_mny=frdi_uint1(f))>0) {
                   8919:                if((p->sfv=(Pval *)malloc(sf_mny*sizeof(Pval)))==NULL)
                   8920:                        abort("frdb_char: can't alloc p->sfv[%d]",sf_mny);
                   8921:                memset(p->sfv,'\0',sf_mny*sizeof(Pval));
                   8922:                };
                   8923:        p->sh.mny=frdi_uint2(f);
                   8924:        if((bf_mny=frdi_uint2(f))>0) {
                   8925:                p->bfsp = alloc_bfeats(bf_mny,0);
                   8926:                };
                   8927: #if dbg_frdb
                   8928:        if((!(p->ident&IsChar))||(p->ident&(IsALL&(~IsChar))))
                   8929:                err("frdb_char: %s",char_toa(p));
                   8930: #endif
                   8931: #if dbg_frdb_toa
                   8932:        err("frdb_char: %s",char_toa(p));
                   8933: #endif
                   8934:        if(p->ident&Char_label) p->l = frdb_label(f);
                   8935:        if(p->ident&Char_ranparms) {
                   8936:                p->rp = alloc_ranparms();
                   8937:                frdb_ranparms(f,p->rp);
                   8938:                };
                   8939:        if(ferror(f)) return(-errno); else return(1);
                   8940:        }
                   8941: #else
                   8942: int frdb_char(fp,cp)
                   8943:     FILE *fp;
                   8944:     Char *cp;
                   8945: {   CharF cf;
                   8946:     int stat;
                   8947:        if((stat=fread(&cf,sizeof(CharF),1,fp))!=1)
                   8948:                abort("frdb_char: can't read CharF, status %d",stat);
                   8949:        *cp = empty_Char;
                   8950:        cp->ident = cf.ident;
                   8951:        cp->bx = cf.bx;
                   8952:        cp->csp = cf.csp;
                   8953:        cp->area = cf.area;
                   8954:        cp->per = cf.per;
                   8955:        cp->basl = 0;
                   8956:        cp->bmny = cf.bmny;
                   8957:        cp->il.mny = cf.imny;
                   8958:        if(cf.sfmny>0) {
                   8959:                if((cp->sfv=(Pval *)malloc(SF_MNY*sizeof(Pval)))==NULL)
                   8960:                        abort("frdb_char: can't alloc cp->sfv[%d]",SF_MNY);
                   8961:                memset(cp->sfv,'\0',SF_MNY*sizeof(Pval));
                   8962:                }
                   8963:        else cp->sfv = NULL;
                   8964:        cp->sh.mny = cf.shmny;
                   8965: #if CPU!=CRAY
                   8966: #if dbg_frdb
                   8967:        if((!(cp->ident&IsChar))||(cp->ident&(IsALL&(~IsChar))))
                   8968:                err("frdb_char: %s",char_toa(cp));
                   8969: #endif
                   8970: #endif
                   8971: #if dbg_frdb_toa
                   8972:        err("frdb_char: %s",char_toa(cp));
                   8973: #endif
                   8974:        if(cp->ident&Char_ranparms) {
                   8975:                cp->rp = alloc_ranparms();
                   8976:                frdb_ranparms(fp,cp->rp);
                   8977:                };
                   8978:        if(cp->ident&Char_label) cp->l = frdb_label(fp);
                   8979: #if CPU!=CRAY
                   8980:        if(cf.bfmny>0) cp->bfsp = alloc_bfeats(cf.bfmny,0);
                   8981:        else 
                   8982: #endif
                   8983:             cp->bfsp = NULL;
                   8984:        if(ferror(fp)) return(-errno); else return(1);
                   8985:        }
                   8986: #endif
                   8987: 
                   8988: frdb_char_etc(fp,cp,etc)
                   8989:     FILE *fp;
                   8990:     Char *cp;
                   8991:     Ident etc;
                   8992: {      frdb_char(fp,cp);
                   8993:        if(cp->sfv!=NULL) frdb_sfeats(fp,cp->sfv);
                   8994:        if(cp->sh.mny>0) frdb_shapes(fp,&(cp->sh));
                   8995: #if CPU!=CRAY
                   8996:        if(cp->bfsp!=NULL) {
                   8997:                frdb_bfeats(fp,cp->bfsp);
                   8998:                };
                   8999: #endif
                   9000:        if(cp->il.mny>0) {
                   9001:                frdb_interpl_etc(fp,&(cp->il),etc);
                   9002:                /**if(!(etc&IsInterp)) free_interpl_etc(&(cp->il),IsALL);**/
                   9003:                };
                   9004:        if(etc&IsBlob && cp->bmny>0)
                   9005:                frdb_blobl_etc(fp,cp->bmny,&(cp->fi),etc);
                   9006:        else { cp->bmny = 0; cp->fi = NULL; };
                   9007:        if(ferror(fp)) return(-errno); else return(1);
                   9008:        }
                   9009: 
                   9010: /* read a set of chars, and parts */
                   9011: frdb_chars_etc(fp,csp,etc)
                   9012:     FILE *fp;
                   9013:     Chars *csp;
                   9014:     Ident etc;
                   9015: {   int ci;
                   9016:     register Char *cp,**cpp;
                   9017:        if(csp->mny<=0) {
                   9018:                *csp = empty_Chars;
                   9019:                return(1);
                   9020:                };
                   9021:        if((cpp=csp->cpa=(Char **)malloc((csp->mny+1)*sizeof(Char *)))==NULL)
                   9022:                abort("frdb_chars_etc:  can't alloc Chars.cpa array");
                   9023:        for(ci=0; ci<csp->mny; ci++) {
                   9024:                *(cpp++) = cp = alloc_char();
                   9025:                frdb_char_etc(fp,cp,etc);
                   9026:                };
                   9027:        *cpp = NULL;
                   9028:        if(ferror(fp)) return(-errno); else return(1);
                   9029:        }
                   9030: 
                   9031: /* return a pointer to a distinct and duplicate copy of *cp;
                   9032:    it is created out of malloc space.
                   9033:    RanParms & label are treated as an integral part of the Char. */
                   9034: Char *dup_char(cp)
                   9035:     Char *cp;
                   9036: {   Char *dup;
                   9037:        if((dup=(Char *)malloc(sizeof(Char)))==NULL)
                   9038:                abort("can't dup Char");
                   9039:        alloc_census(Char,1);
                   9040:        *dup = *cp;
                   9041:        if(dup->ident&Char_label && dup->l!=NULL)
                   9042:                dup->l = strdup(cp->l);
                   9043:        else {dup->ident &= ~Char_label; dup->l = NULL;};
                   9044:        if(dup->ident&Char_ranparms && dup->rp!=NULL)
                   9045:                dup->rp = dup_ranparms(cp->rp);
                   9046:        else {dup->ident &= ~Char_ranparms; dup->rp = NULL;};
                   9047:        return(dup);
                   9048:        }
                   9049: 
                   9050: /* return a pointer to a distinct and duplicate copy of *cp and those of
                   9051:    its lists as specified by etc.  (Does not conform to practice for dup_word_etc.)
                   9052:    */
                   9053: Char *dup_char_etc(cp,etc)
                   9054:     Char *cp;
                   9055:     Ident etc;
                   9056: {   Char *dup;
                   9057:        dup = dup_char(cp);
                   9058:        if(dup->bmny>0&&etc&IsBlob) dup->fi = dup_blobl_etc(cp->fi,etc);
                   9059:        else {dup->bmny=0; dup->fi=NULL;};
                   9060:        if(dup->il.mny>0&&etc&IsInterp) dup->il = *dup_interpl_etc(&(cp->il),etc);
                   9061:        else dup->il = empty_Interpl;
                   9062:        /**
                   9063:        if(dup->sfv!=NULL>0&&etc&IsSfeats) dup->sfv = dup_sfeats(cp->sfv);
                   9064:        else dup->sfv = NULL;
                   9065:        if(dup->sh.mny>0&&etc&IsShapes) dup->sh = *dup_shapes(&cp->sh);
                   9066:        else dup->sh = empty_Shapes;
                   9067:        **/
                   9068: #if CPU!=CRAY
                   9069:        if(dup->bfsp!=NULL>0&&etc&IsBfeats) dup->bfsp = dup_bfeats(cp->bfsp);
                   9070:        else 
                   9071: #endif
                   9072:             dup->bfsp = NULL;
                   9073:        return(dup);
                   9074:        }
                   9075: 
                   9076: /* Return a pointer to a local static duplicate of non-empty *csp.
                   9077:    Its cpa array is new, created out of malloc space.
                   9078:    If etc&IsChar, all its Characters are also duplicated,
                   9079:    else the contents of cpa point to the old unduplicated Chars.
                   9080:    */
                   9081: Chars *dup_chars_etc(csp,etc)
                   9082:     Chars *csp;
                   9083:     Ident etc;         /* parts to duplicate */
                   9084: {   static Chars dup;
                   9085:     register Char **cpp,**dpp;
                   9086:        if((dup.mny=csp->mny)<=0) dup = empty_Chars;
                   9087:        else {  if((dup.cpa=(Char **)malloc((dup.mny+1)*sizeof(Char *)))==NULL)
                   9088:                        abort("can't dup cs.cpa");
                   9089:                for(cpp=csp->cpa,dpp=dup.cpa; (*cpp)!=NULL; cpp++,dpp++) {
                   9090:                        if(etc&IsChar) *dpp = dup_char_etc(*cpp,etc);
                   9091:                        else *dpp = *cpp;
                   9092:                        };
                   9093:                *dpp = NULL;
                   9094:                };
                   9095:        return(&dup);
                   9096:        }
                   9097: 
                   9098: err_chars(p)
                   9099:     Chars *p;
                   9100: {   register Char **cpp;
                   9101:        fprintf(stderr,"Chars %d: ",p->mny);
                   9102:        if(p->mny>0) for(cpp=p->cpa; (*cpp)!=NULL; cpp++)
                   9103:                fprintf(stderr,"%X ",*cpp);
                   9104:        fprintf(stderr,"\n");
                   9105:        }
                   9106: 
                   9107: /* Make a Char out of a single Blob.  Return a freshly-allocated Char
                   9108:    that owns the given Blob as is (not duplicated, copied or freed).
                   9109:    The Blob's next pointer is set to NULL. */
                   9110: Char *char_of_blob(b)
                   9111:     Blob *b;
                   9112: {   Char *c;
                   9113:        c=alloc_char();
                   9114:        c->bx = b->bx;
                   9115:        c->area = b->area;
                   9116:        c->per = b->per;
                   9117:        c->bmny = 1;
                   9118:        c->fi = b;
                   9119:        b->n = NULL;
                   9120:        return(c);
                   9121:        }
                   9122: 
                   9123: Interp *alloc_interp()
                   9124: {   Interp *new;
                   9125:        if((new=(Interp *)malloc(sizeof(Interp)))==NULL)
                   9126:                abort("alloc_interp: can't malloc");
                   9127:        alloc_census(Interp,1);
                   9128:        *new = empty_Interp;
                   9129:        return(new);
                   9130:        }
                   9131: 
                   9132: Interp *dup_interp(ip)
                   9133:     Interp *ip;
                   9134: {   Interp *dup;
                   9135:        if((dup=(Interp *)malloc(sizeof(Interp)))==NULL)
                   9136:                abort("dup_interp: can't malloc");
                   9137:        alloc_census(Interp,1);
                   9138:        *dup = *ip;
                   9139:        return(dup);
                   9140:        }
                   9141: 
                   9142: /* Print the interpl */
                   9143: fwra_interpl(fp,ilp)
                   9144:     FILE *fp;
                   9145:     Interpl *ilp;
                   9146: {   register Interp *cp;
                   9147:        fprintf(fp,"Interpl[%d] ",ilp->mny);
                   9148:        for(cp=ilp->fi; cp!=NULL; cp=cp->n) {
                   9149:                fprintf(fp," %s --",interp_toa(cp));
                   9150:                };
                   9151:        fprintf(fp,"\n");
                   9152:        }
                   9153: 
                   9154: /* Print the interpl very briefly */
                   9155: fwra_interpl_brief(fp,ilp)
                   9156:     FILE *fp;
                   9157:     Interpl *ilp;
                   9158: {   register Interp *ip;
                   9159:        for(ip=ilp->fi; ip!=NULL; ip=ip->n) {
                   9160:                fprintf(fp,"%s %s  ",ip->ci.c,merit_toa(ip->m));
                   9161:                };
                   9162:        fprintf(fp,"\n");
                   9163:        }
                   9164: 
                   9165: err_interpl(ilp)
                   9166:     Interpl *ilp;
                   9167: {      fwra_interpl(stderr,ilp);
                   9168:        }
                   9169: 
                   9170: /* return the address of a local static copy of the given Interpl,
                   9171:    for which each Interp is a duplicate of those in the given list */
                   9172: Interpl *dup_interpl_etc(ilp,etc)
                   9173:     Interpl *ilp;
                   9174:     Ident etc;
                   9175: {   static Interpl lis;
                   9176:     register Interp *cp,*pp,*dp;
                   9177:        lis = *ilp;
                   9178:        if(ilp->fi==NULL) return(NULL);
                   9179:        for(pp=NULL,cp=ilp->fi; cp!=NULL; pp=dp,cp=cp->n) {
                   9180:                dp=dup_interp(cp);
                   9181:                if(pp==NULL) lis.fi = dp;
                   9182:                else pp->n = dp;
                   9183:                };
                   9184:        pp->n=NULL;
                   9185:        return(&lis);
                   9186:        }
                   9187: 
                   9188: /* Return a pointer to a local static duplicate of *isp.
                   9189:    Its pa array is new, created out of malloc space.
                   9190:    If etc&IsInterp, all its Interps are also duplicated,
                   9191:    else the contents of pa point to the old unduplicated Interps.
                   9192:    */
                   9193: Interps *dup_interps_etc(isp,etc)
                   9194:     Interps *isp;
                   9195:     Ident etc;         /* parts to duplicate */
                   9196: {   static Interps dup;
                   9197:     register Interp **ipp,**dpp;
                   9198:        dup = *isp;
                   9199:        if(dup.mny<=0) dup = empty_Interps;
                   9200:        else {  if((dup.pa=(Interp **)malloc((dup.mny+1)*sizeof(Interp *)))==NULL)
                   9201:                        abort("can't dup (Interp *)is.pa[%d]",(dup.mny+1));
                   9202:                for(ipp=isp->pa,dpp=dup.pa; *ipp!=NULL; ipp++,dpp++) {
                   9203:                        if(etc&IsInterp) *dpp = dup_interp(*ipp);
                   9204:                        else *dpp = *ipp;
                   9205:                        };
                   9206:                *dpp = NULL;
                   9207:                };
                   9208:        return(&dup);
                   9209:        }
                   9210: 
                   9211: free_interps_etc(isp,etc)
                   9212:     Interps *isp;
                   9213:     Ident etc;         /* parts to free */
                   9214: {   register Interp **ipp,**dpp;
                   9215:        if(etc&IsInterp) {
                   9216:                /* free contents */
                   9217:                for(ipp=isp->pa; *ipp!=NULL; ipp++) free_interp(*ipp);
                   9218:                };
                   9219:        if(isp->pa!=NULL) { free(isp->pa); isp->pa = NULL; };
                   9220:        isp->mny = 0;
                   9221:        }
                   9222: 
                   9223: /* remove a char from a chars set */
                   9224: remove_char(cp,csp)
                   9225:     Char *cp;
                   9226:     Chars *csp;
                   9227: {   register Char *rp,**rpp,**npp;
                   9228:        if(csp->mny==0) err("remove_char: can't - Chars empty");
                   9229:        else {  for(rp= *(rpp=csp->cpa); rp!=NULL; rp= *(++rpp)) if(rp==cp) break;
                   9230:                if(rp==NULL) err("remove_char: can't - not found");
                   9231:                else {  /* move later entries up */
                   9232:                        npp=rpp+1;
                   9233:                        do *(rpp++)= *(npp++); while ((*rpp)!=NULL);
                   9234:                        if((--(csp->mny))==0) {free(csp->cpa); csp->cpa=NULL;};
                   9235:                        /* don't bother to realloc downwards */
                   9236:                        };
                   9237:                };
                   9238:        }
                   9239: 
                   9240: /* Append a char to the end of a chars set. 
                   9241:    Do NOT attempt to maintain Chars in order sorted ascending on Char.bx.a.x.
                   9242:    Return appended Char *. */
                   9243: Char *append_char(cp,csp)
                   9244:     Char *cp;
                   9245:     Chars *csp;
                   9246: {   register Char *rp,**rpp,**npp;
                   9247:        if(csp->mny==0) {
                   9248:                if((csp->cpa=(Char **)malloc(2*sizeof(Char *)))==NULL)
                   9249:                        abort("append_char: can't malloc csp->cpa[%d]",2);
                   9250:                }
                   9251:        else {  if((csp->cpa=(Char **)realloc(
                   9252:                                csp->cpa,
                   9253:                                (csp->mny+2)*sizeof(Char *))
                   9254:                                )==NULL)
                   9255:                        abort("append_char: can't realloc csp->cpa[%d]",
                   9256:                                (csp->mny+2));
                   9257:                };
                   9258:        csp->cpa[csp->mny] = cp;
                   9259:        csp->cpa[++csp->mny] = NULL;
                   9260:        return(cp);
                   9261:        }
                   9262: 
                   9263: /* Insert a Char into a Chars set.  Chars is assumed to be sorted ascending
                   9264:    on on Char.bx.a.x, and this order is maintained.
                   9265:    Return inserted Char * */
                   9266: Char *insert_char(cp,csp)
                   9267:     Char *cp;
                   9268:     Chars *csp;
                   9269: {   register Char **cpp,*ncp,*pcp;
                   9270:        if(csp->mny==0) {
                   9271:                if((csp->cpa=(Char **)malloc(2*sizeof(Char *)))==NULL)
                   9272:                        abort("insert_char: can't malloc csp->cpa[%d]",2);
                   9273:                csp->cpa[csp->mny] = cp;
                   9274:                }
                   9275:        else {  if((cpp=csp->cpa=(Char **)realloc(
                   9276:                                csp->cpa,
                   9277:                                (csp->mny+2)*sizeof(Char *))
                   9278:                                )==NULL)
                   9279:                        abort("insert_char: can't realloc csp->cpa[%d]",csp->mny+2);
                   9280:                while(((*cpp)!=NULL)&&(*cpp)->bx.a.x<cp->bx.a.x) cpp++;
                   9281:                /* **cpp is now 1st entry >= *cp in sorted order */
                   9282:                pcp=cp;
                   9283:                do {    ncp= *cpp;
                   9284:                        *(cpp++)=pcp;
                   9285:                        pcp=ncp;
                   9286:                        }
                   9287:                while(pcp!=NULL);
                   9288:                };
                   9289:        csp->cpa[++csp->mny] = NULL;
                   9290:        return(cp);
                   9291:        }
                   9292: 
                   9293: /* Append the contents of a "source" chars set to a "destination" chars set.
                   9294:    Merely copy (Char *) pointers:  don't duplicate Chars.
                   9295:    Do NOT attempt to maintain Chars in order sorted ascending on Char.bx.a.x.
                   9296:    Return destination (Chars *). */
                   9297: Chars *append_chars(s,d)
                   9298:     Chars *s;  /* source */
                   9299:     Chars *d;  /* destination */
                   9300: {   register Char *rp,**rpp,**npp;
                   9301:        if(s->mny==0) return(d);
                   9302:        if(d->mny==0) {
                   9303:                if((d->cpa=(Char **)malloc((s->mny+1)*sizeof(Char *)))==NULL)
                   9304:                        abort("append_chars: can't malloc d->cpa[%d]",2);
                   9305:                }
                   9306:        else {  if((d->cpa=(Char **)realloc(
                   9307:                                d->cpa,
                   9308:                                (d->mny+s->mny+1)*sizeof(Char *))
                   9309:                                )==NULL)
                   9310:                        abort("append_chars: can't realloc d->cpa[%d]",
                   9311:                                (d->mny+s->mny+1));
                   9312:                };
                   9313:        memcpy(d->cpa+d->mny,s->cpa,(s->mny+1)*sizeof(Char *));
                   9314:        d->mny += s->mny;
                   9315:        return(d);
                   9316:        }
                   9317: 
                   9318: /* Insert a Char into the Chars owned by a given Word,
                   9319:    maintaining order in set, and updating the Word's bx */
                   9320: Char *insert_char_word(cp,wp)
                   9321:     Char *cp;
                   9322:     Word *wp;
                   9323: {      merge_bbx(&(cp->bx),&(wp->bx));
                   9324:        return(insert_char(cp,&(wp->cs)));
                   9325:        }
                   9326: 
                   9327: free_char_etc(p,etc)
                   9328:     Char *p;   /* !=NULL */
                   9329:     Ident etc;
                   9330: {      if(etc&IsBlob) free_blobl_etc(&(p->bmny),&(p->fi),etc);
                   9331:        if(etc&IsInterp) free_interpl(&(p->il));
                   9332:        if(etc&IsSfeats && p->sfv!=NULL) { free(p->sfv); p->sfv=NULL; };
                   9333:        if(etc&IsShapes) free_shapes(&(p->sh));
                   9334: #if CPU!=CRAY
                   9335:        if(etc&IsBfeats && p->bfsp!=NULL) { free_bfeats(p->bfsp); p->bfsp=NULL; };
                   9336: #endif
                   9337:        if(etc&IsChar) {
                   9338:                if(p->ident&Char_label && p->l!=NULL) {
                   9339:                        free(p->l);  p->l=NULL;
                   9340:                        p->ident &= ~Char_label;
                   9341:                        };
                   9342:                if(p->ident&Char_ranparms && p->rp!=NULL) {
                   9343:                        free_ranparms(p->rp);  p->rp=NULL;
                   9344:                        p->ident &= ~Char_ranparms;
                   9345:                        };
                   9346:                free(p);
                   9347:                free_census(Char,1);
                   9348:                };
                   9349:        }
                   9350: 
                   9351: /* Unconditionally free the malloc-space array of pointers, and empty the set.
                   9352:    Don't free the records that it owned.
                   9353:    */
                   9354: free_chars(csp)
                   9355:     Chars *csp;
                   9356: {      if(csp->cpa!=NULL) { free(csp->cpa); csp->cpa = NULL; }
                   9357:        csp->mny = 0;
                   9358:        }
                   9359: 
                   9360: free_chars_etc(csp,etc)
                   9361:     Chars *csp;
                   9362:     Ident etc;
                   9363: {   register Char *cp,**cpp;
                   9364:        if(csp->mny>0&&(etc&IsChar))
                   9365:                for(cp= *(cpp=csp->cpa); cp!=NULL; cp= *(++cpp))
                   9366:                        free_char_etc(cp,etc);
                   9367:        free_chars(csp);
                   9368:        }
                   9369: 
                   9370: /** Blob handling:
                   9371:        alloc_blob_pool(sz,debug) - create pool of free blob records
                   9372:        free_blob_pool() - free the pool
                   9373: Blob   *alloc_blob() - allocate a new blob (in pool)
                   9374:        free_blob(bp) -  free a specified blob
                   9375:        free_blob_runs(bp) - free a blob & the runs in its blob set
                   9376:        free_blobl_etc(int *,Blob **,etc) - free blobs etc in char's blob list
                   9377:        out_blob(bp) - print (ascii) to stdout
                   9378:        fwrb_blob(fp,bp) - write binary Blob (only) to fp
                   9379:         fwrb_blob_etc(fp,bp,etc) - write binary Blob & specified parts to fp
                   9380:         frdb_blob_etc(fp,bp,etc) - read binary Blob & parts in specified form
                   9381:        frdb_runfs(fp,bp,max) - read *bp's (binary) RunF's from fp
                   9382:        err_blob(s,bp) - print (ascii) to stderr
                   9383:        err_blob_runs(s,bp) - print Blob & its Runs (ascii) to stderr
                   9384:        err_blob_runfs(s,bp) - print Blob & its RunFs (ascii) to stderr
                   9385:        err_blob_briefly(s,bp) - print (ascii) to stderr
                   9386:        err_blobf(s,bp) - print file-format blob (ascii) to stderr
                   9387:        err_blob_stats() - report blob statistics
                   9388:        blob_small(bp) - test whether its runs' data can be compressed to chars
                   9389:  BUGS
                   9390:      most fread/fwrite/fseek should be read/write/lseek, for speed
                   9391:      -- but how to choose?
                   9392:  **/
                   9393: 
                   9394: /* make (empty) pool of `size' Blobs (return F if can't allocate) */
                   9395: boolean alloc_blob_pool(size,dbg)
                   9396:     int size;
                   9397:     boolean dbg;
                   9398: {   register Blob *cbp, *cbq, *pbp;
                   9399:        blob_max=size;
                   9400:        if((blob_pool=(Blob *)malloc(blob_max*sizeof(Blob)))==NULL) return(F);
                   9401:        blob_debug = dbg;
                   9402:        pbp= &blob_fr;
                   9403:        /* link up all blobs into free list using only first-ptrs */
                   9404:        for(cbq=(cbp=blob_pool)+blob_max; cbp<cbq; cbp++) {
                   9405:                pbp->n = cbp;
                   9406:                pbp = cbp;
                   9407:                };
                   9408:        pbp->n = NULL;  /* marks end of free list */
                   9409:        blob_fr_mny = blob_max;  blob_hi=0;  blob_chopped = 0;
                   9410:        hi_blob_no = 0;
                   9411:        return(T);
                   9412:        }
                   9413: 
                   9414: free_blob_pool()
                   9415: {      free(blob_pool);
                   9416:        }
                   9417: 
                   9418: Blob *alloc_blob()
                   9419: {    Blob *p;
                   9420:        if((p=(Blob *)malloc(sizeof(Blob)))==NULL)
                   9421:                abort("alloc_blob: can't");
                   9422:        alloc_census(Blob,1);
                   9423:        *p = empty_Blob;
                   9424:        return(p);
                   9425:        }
                   9426: 
                   9427: /* Unconditionally free this Blob record. */
                   9428: free_blob(bp)
                   9429:     Blob *bp;
                   9430: {      free(bp);
                   9431:        free_census(Blob,1);
                   9432:        }
                   9433: 
                   9434: /* Allocate new Blob record and assign to it the next blob no */
                   9435: Blob *alloc_pool_blob()
                   9436: {      register Blob *bp;
                   9437:        if((bp = blob_fr.n)==NULL) {
                   9438:                err("too many alloc_blob() calls - aborting:");
                   9439: #ifdef STATS
                   9440:                err_blob_stats();
                   9441: #endif
                   9442:                exit(1);
                   9443:                };
                   9444:        blob_fr.n = bp->n;
                   9445: #ifdef STATS
                   9446:        blob_fr_mny--;
                   9447:        if(blob_hi<(blob_max-blob_fr_mny)) blob_hi = blob_max-blob_fr_mny;
                   9448: #endif
                   9449:        bp->no = hi_blob_no++;
                   9450:        return(bp);
                   9451:        }
                   9452: 
                   9453: free_pool_blob(bp)
                   9454:        Blob *bp;
                   9455: {
                   9456:        if(blob_debug&&bp==NULL) abort("free_pool_blob: can't free a NULL Blob");
                   9457: #ifdef STATS
                   9458:        blob_fr_mny++;
                   9459:        if(blob_debug&&(blob_fr_mny>blob_max)) {
                   9460:                err("free_pool_blob: too many free_blob() calls - aborting:");
                   9461: #ifdef STATS
                   9462:                err_blob_stats();
                   9463: #endif
                   9464:                exit(1);
                   9465:                };
                   9466: #endif
                   9467:        bp->n = blob_fr.n;
                   9468:        blob_fr.n = bp;
                   9469:        }
                   9470: 
                   9471: /* free the runs belonging to this blob */
                   9472: free_runs(bp)
                   9473:     Blob *bp;
                   9474: {   register Run *crp,*nrp;
                   9475:        if(bp->ident&Runs_ff) {
                   9476:                if(bp->r.ff!=NULL) free(bp->r.ff);
                   9477:                bp->r.ff=NULL;
                   9478:                }
                   9479:        else if(bp->ident&Runs_f) {
                   9480:                for(crp=bp->r.f; crp!=NULL; crp=nrp) {
                   9481:                        nrp=crp->n;
                   9482:                        free_run(crp);
                   9483:                        };
                   9484:                }
                   9485:        else if(bp->ident&Runs_seek) /* none to free */ ;
                   9486:        }
                   9487: 
                   9488: /* free blob *bp and those parts (runs) specified */
                   9489: free_blob_etc(bp,etc)
                   9490:     Blob *bp;
                   9491:     Ident etc;
                   9492: {      if(etc&IsRun) free_runs(bp);
                   9493:        if(etc&IsBlob) free_blob(bp);
                   9494:        }
                   9495: 
                   9496: /* return a pointer to a distinct and duplicate copy of *bp;
                   9497:    it is created out of malloc space */
                   9498: Blob *dup_blob(bp)
                   9499:     Blob *bp;
                   9500: {   Blob *dup;
                   9501:        if((dup=(Blob *)malloc(sizeof(Blob)))==NULL)
                   9502:                abort("dup_blob: can't malloc");
                   9503:        alloc_census(Blob,1);
                   9504:        *dup = *bp;
                   9505:        return(dup);
                   9506:        }
                   9507: 
                   9508: /* return a pointer to a distinct and duplicate copy of *bp and what it owns,
                   9509:    as described by etc; created out of malloc space */
                   9510: Blob *dup_blob_etc(bp,etc)
                   9511:     Blob *bp;
                   9512:     Ident etc;
                   9513: {   Blob *dup;
                   9514:        dup = dup_blob(bp);
                   9515:        if(bp->runs>0) {
                   9516:                if(bp->ident&Runs_ff) {
                   9517:                    int ri;
                   9518:                    RunF *rp,*drp;
                   9519:                        if((dup->r.ff=
                   9520:                            (RunF *)malloc(bp->runs*sizeof(RunF)))==NULL)
                   9521:                                abort("dup_blob_etc: can't malloc RunF[%d]",
                   9522:                                        bp->runs);
                   9523:                        for(ri=0,rp=bp->r.ff,drp=dup->r.ff; ri<bp->runs; ri++)
                   9524:                                *(drp++) = *(rp++);
                   9525:                        }
                   9526:                else abort("dup_blob_etc: only Runs_ff implemented");
                   9527:                };
                   9528:        return(dup);
                   9529:        }
                   9530: 
                   9531: /* Return a pointer to a local static duplicate of non-empty *bsp.
                   9532:    Its bpa array is created newly out of malloc space.
                   9533:    If etc&IsBlob, all its Blobs are also fresh duplicates,
                   9534:    else the contents of bpa point to the old unduplicated Blobs.
                   9535:    */
                   9536: Blobs *dup_blobs_etc(bsp,etc)
                   9537:     Blobs *bsp;
                   9538:     Ident etc;         /* parts to duplicate */
                   9539: {   static Blobs dup;
                   9540:     register Blob **bpp,**dpp;
                   9541:        if((dup.mny = bsp->mny)<=0) dup = empty_Blobs;
                   9542:        else {  if((dup.bpa=(Blob **)malloc((dup.mny+1)*sizeof(Blob *)))==NULL)
                   9543:                        abort("dup_blobs_etc: can't malloc bs.bpa[%d]",dup.mny+1);
                   9544:                for(bpp=bsp->bpa,dpp=dup.bpa; *bpp!=NULL; bpp++,dpp++) {
                   9545:                        if(etc&IsBlob) *dpp = dup_blob_etc(*bpp,etc);
                   9546:                        else *dpp = *bpp;
                   9547:                        };
                   9548:                *dpp = NULL;
                   9549:                };
                   9550:        return(&dup);
                   9551:        }
                   9552: 
                   9553: /* Split the given Blobs into two, *b0 & *b1, according to the value 0 or !0
                   9554:    respectively returned by the function s(b,a) applied to each Blob *b and
                   9555:    blind argument *a.
                   9556:    s() will be evaluated exactly once for each Blob, and the Blob's will be
                   9557:    assigned in the order found in the original Blobs.  Only pointers to Blob's
                   9558:    are created;  the Blob's themselves are not duplicated.  The original Blobs
                   9559:    record is unchanged.
                   9560:    */
                   9561: split_blobs(b,s,a,b0,b1)
                   9562:     Blobs *b;
                   9563:     int (*s)();
                   9564:     VOID *a;           /* passed transparently to s() */
                   9565:     Blobs *b0,*b1;
                   9566: {   char *sel,*sp;
                   9567:     register Blob *bp,**bpp;
                   9568:     Blob **b0pp;
                   9569:     Blob **b1pp;
                   9570:        *b0 = *b1 = empty_Blobs;
                   9571:        if(b->mny<=0) return;
                   9572:        if((sel=(char *)malloc(b->mny))==NULL)
                   9573:                abort("split_blobs: can't malloc sel[%d]",b->mny);
                   9574:        for(bp= *(bpp=b->bpa),sp=sel; bp!=NULL; bp= *(++bpp),sp++)
                   9575:                if(*sp = s(bp,a)) b1->mny++; else b0->mny++;
                   9576:        if(b0->mny>0)
                   9577:                if((b0->bpa=(Blob **)malloc((b0->mny+1)*sizeof(Blob *)))==NULL)
                   9578:                        abort("split_blobs: can't malloc b0->bpa[%d]",b0->mny+1);
                   9579:        if(b1->mny>0)
                   9580:                if((b1->bpa=(Blob **)malloc((b1->mny+1)*sizeof(Blob *)))==NULL)
                   9581:                        abort("split_blobs: can't malloc b1->bpa[%d]",b1->mny+1);
                   9582:        b0pp=b0->bpa;
                   9583:        b1pp=b1->bpa;
                   9584:        for(bp= *(bpp=b->bpa),sp=sel; bp!=NULL; bp= *(++bpp),sp++)
                   9585:                if(*sp) *(b1pp++)=bp; else *(b0pp++)=bp;
                   9586:        if(b0->mny>0) *b0pp=NULL;
                   9587:        if(b1->mny>0) *b1pp=NULL;
                   9588:        free(sel);
                   9589:        }
                   9590: 
                   9591: /* Return the address of the first in a list of Blobs, duplicated from
                   9592:    the given list. */
                   9593: Blob *dup_blobl_etc(bp,etc)
                   9594:     Blob *bp;
                   9595:     Ident etc;
                   9596: {   Blob *fi,*cp,*pp,*dp;
                   9597:        if(bp==NULL) return(NULL);
                   9598:        for(pp=NULL,cp=bp; cp!=NULL; pp=dp,cp=cp->n) {
                   9599:                dp=dup_blob_etc(cp,etc);
                   9600:                if(pp==NULL) fi = dp;
                   9601:                else pp->n = dp;
                   9602:                };
                   9603:        pp->n=NULL;
                   9604:        return(fi);
                   9605:        }
                   9606: 
                   9607: /* Prepend this blob to the given Char's bloblist; update Char's bx, area, & per.
                   9608:    Inverse of `remove_blobl()'. */
                   9609: Blob *insert_blobl(bp,cp)
                   9610:     Blob *bp;
                   9611:     Char *cp;
                   9612: {   register Blob *pbp,*nbp;
                   9613:        if(cp->bmny>0) bp->n = cp->fi;
                   9614:        else bp->n = NULL;
                   9615:        cp->fi = bp;
                   9616:        cp->bmny++;
                   9617:        merge_bbx(&(bp->bx),&(cp->bx));
                   9618:        cp->area += bp->area;
                   9619:        cp->per += bp->per;
                   9620:        return(bp);
                   9621:        }
                   9622: 
                   9623: /* Remove this blob from a char's bloblist; update Char's bx, area, per.
                   9624:    Inverse of `insert_blobl()'. */
                   9625: remove_blobl(bp,cp)
                   9626:     Blob *bp;
                   9627:     Char *cp;
                   9628: {   Blob *rp,*pp;
                   9629:     Bbx bx;            /* Char's new Bbx */
                   9630:        if(cp->bmny==1) {  /* frequent case */
                   9631:                cp->fi=NULL; cp->bmny=0;
                   9632:                }
                   9633:        else if(cp->bmny>1){
                   9634:                bx=empty_Bbx;
                   9635:                pp=NULL;
                   9636:                for(rp=cp->fi; rp!=NULL; pp=rp,rp=rp->n) {
                   9637:                        if(rp==bp) break;
                   9638:                        else {  if(bx.a.x > rp->bx.a.x) bx.a.x = rp->bx.a.x;
                   9639:                                if(bx.a.y > rp->bx.a.y) bx.a.y = rp->bx.a.y;
                   9640:                                if(bx.b.x < rp->bx.b.x) bx.b.x = rp->bx.b.x;
                   9641:                                if(bx.b.y < rp->bx.b.y) bx.b.y = rp->bx.b.y;
                   9642:                                };
                   9643:                        };
                   9644:                if(rp!=NULL) {  /* remove from list */
                   9645:                        if(pp==NULL) cp->fi=bp->n;
                   9646:                        else pp->n=bp->n;
                   9647:                        cp->bmny--;
                   9648:                        for(rp=bp->n; rp!=NULL; rp=rp->n) {
                   9649:                                if(bx.a.x > rp->bx.a.x) bx.a.x = rp->bx.a.x;
                   9650:                                if(bx.a.y > rp->bx.a.y) bx.a.y = rp->bx.a.y;
                   9651:                                if(bx.b.x < rp->bx.b.x) bx.b.x = rp->bx.b.x;
                   9652:                                if(bx.b.y < rp->bx.b.y) bx.b.y = rp->bx.b.y;
                   9653:                                };
                   9654:                        cp->bx = bx;
                   9655:                        }
                   9656:                else err("remove_blobl: can't - not found");
                   9657:                }
                   9658:        else err("remove_blobl: can't - Blobl empty");
                   9659:        cp->area -= bp->area;
                   9660:        cp->per -= bp->per;
                   9661:        }
                   9662: 
                   9663: /* prepend this blob to the given Blob list */
                   9664: Blob *prepend_blobl(bp,blp)
                   9665:     Blob *bp;
                   9666:     Blobl *blp;
                   9667: {   register Blob *pbp,*nbp;
                   9668:        if(blp->mny>0) bp->n = blp->fi;
                   9669:        else {  bp->n = NULL;
                   9670:                blp->la = bp;
                   9671:                };
                   9672:        blp->fi = bp;
                   9673:        blp->mny++;
                   9674:        return(bp);
                   9675:        }
                   9676: 
                   9677: /* append this blob to the given Blob list */
                   9678: Blob *append_blobl(bp,blp)
                   9679:     Blob *bp;
                   9680:     Blobl *blp;
                   9681: {   register Blob *pbp,*nbp;
                   9682:        if(blp->mny==0) blp->fi = bp;
                   9683:        else blp->la->n = bp;
                   9684:        blp->la = bp;
                   9685:        bp->n = NULL;
                   9686:        blp->mny++;
                   9687:        return(bp);
                   9688:        }
                   9689: 
                   9690: /* remove a blob from a blobs set */
                   9691: remove_blob(bp,bsp)
                   9692:     Blob *bp;
                   9693:     Blobs *bsp;
                   9694: {   register Blob *rp,**rpp,**npp;
                   9695:        if(bsp->mny==0) err("remove_blob: can't - Blobs empty");
                   9696:        else {  for(rp= *(rpp=bsp->bpa); rp!=NULL; rp= *(++rpp)) if(rp==bp) break;
                   9697:                if(rp==NULL) err("remove_blob: can't - not found");
                   9698:                else {  /* move later entries up */
                   9699:                        npp=rpp+1;
                   9700:                        do *(rpp++)= *(npp++); while ((*rpp)!=NULL);
                   9701:                        if((--(bsp->mny))==0) {free(bsp->bpa); bsp->bpa=NULL;};
                   9702:                        /* don't bother to realloc downwards */
                   9703:                        };
                   9704:                };
                   9705:        }
                   9706: 
                   9707: /* Append a blob to the end of a blobs set. 
                   9708:    Return appended Blob *. */
                   9709: Blob *append_blob(p,sp)
                   9710:     Blob *p;
                   9711:     Blobs *sp;
                   9712: {   register Blob *rp,**rpp,**npp;
                   9713:        if(sp->mny==0) {
                   9714:                if((sp->bpa=(Blob **)malloc(2*sizeof(Blob *)))==NULL)
                   9715:                        abort("append_blob: can't malloc sp->bpa[2]");
                   9716:                }
                   9717:        else {  if((sp->bpa=(Blob **)realloc(
                   9718:                                sp->bpa,
                   9719:                                (sp->mny+2)*sizeof(Blob *))
                   9720:                                )==NULL)
                   9721:                        abort("append_blob: can't realloc sp->bpa[%d]",sp->mny+2);
                   9722:                };
                   9723:        sp->bpa[sp->mny] = p;
                   9724:        sp->bpa[++sp->mny] = NULL;
                   9725:        return(p);
                   9726:        }
                   9727: 
                   9728: /* Append Blobs *p1 to Blobs *p2.  On return, *p1 is unchanged, *p2 is in general
                   9729:    longer, and all the Blob's owned by *p1 are now also owned by *p2. */
                   9730: append_blobs_blobs(p1,p2)
                   9731:     Blobs *p1,*p2;
                   9732: {   int mny;
                   9733:     register Blob **pp1,**pp2;
                   9734:        if(p1->mny==0) return;
                   9735:        if(p2->mny==0) { *p2 = *dup_blobs_etc(p1,IsNONE); return; };
                   9736:        mny = p2->mny + p1->mny;
                   9737:        if((p2->bpa=(Blob **)realloc(p2->bpa,(mny+1)*sizeof(Blob *)))==NULL)
                   9738:                abort("append_blobs_blobs: can't realloc p2->bpa[%d]",mny+1);
                   9739:        pp1=p1->bpa;  pp2=p2->bpa+p2->mny;  while(*pp1!=NULL) *(pp2++) = *(pp1++);
                   9740:        *pp2 = NULL;
                   9741:        p2->mny = mny;
                   9742:        }
                   9743: 
                   9744: free_blobl_etc(mnyp,fip,etc)
                   9745:     int *mnyp;
                   9746:     Blob **fip;
                   9747:     Ident etc;
                   9748: {   register Blob *bp,*nbp;
                   9749:        if(*mnyp>0) {
                   9750:                for(bp= *fip; bp != NULL; bp=nbp)
                   9751:                        { nbp=bp->n; free_blob_etc(bp,etc); };
                   9752:                };
                   9753:        *mnyp=0;
                   9754:        *fip=NULL;
                   9755:        }
                   9756: 
                   9757: /* Unconditionally free the malloc-space array of pointers, and empty the set.
                   9758:    Don't free the records that it owned.
                   9759:    */
                   9760: free_blobs(bsp)
                   9761:     Blobs *bsp;
                   9762: {      if(bsp->bpa!=NULL) { free(bsp->bpa); bsp->bpa=NULL; };
                   9763:        bsp->mny = 0;
                   9764:        }
                   9765: 
                   9766: free_blobs_etc(bsp,etc)
                   9767:    Blobs *bsp;
                   9768:    Ident etc;
                   9769: {  register Blob *bp, **bpp;
                   9770:        if(bsp->mny>0&&(etc&IsBlob)) for(bp= *(bpp=bsp->bpa); bp!=NULL; bp= *(++bpp))
                   9771:                free_blob_etc(bp,etc);
                   9772:        free_blobs(bsp);
                   9773:        }
                   9774: 
                   9775: Blobs *blobl_to_blobs(blp)
                   9776:     Blobl *blp;
                   9777: {   static Blobs bs;
                   9778:     register Blob *bp,**bpp;
                   9779:        bs = empty_Blobs;
                   9780:        bs.mny = blp->mny;
                   9781:        if(bs.mny>0) {
                   9782:                if((bs.bpa=(Blob **)malloc((bs.mny+1)*sizeof(Blob *)))==NULL)
                   9783:                        abort("blobl_to_blobs: can't malloc Blobs.bpa[%d]",bs.mny+1);
                   9784:                for(bp=blp->fi,bpp=bs.bpa; bp!=NULL; bp=bp->n,bpp++)
                   9785:                        *bpp = bp;
                   9786:                *bpp = NULL;
                   9787:                };
                   9788:        return(&bs);
                   9789:        }
                   9790: 
                   9791: int bp_tod(bp)
                   9792:     Blob *bp;
                   9793: {      if(bp==NULL) return(-2);
                   9794:        else return(bp-blob_pool);
                   9795:        }
                   9796: 
                   9797: /* test whether for this Blob, each runs's data fields could all be compressed
                   9798:    from a short to a char */
                   9799: boolean blob_small(bp)
                   9800:     Blob *bp;
                   9801: {      if(bp->runs>255) return(F);
                   9802:        if(bbx_wid(&bp->bx)>255) return(F);
                   9803:        if(bbx_hgt(&bp->bx)>255) return(F);
                   9804:        return(T);
                   9805:        }
                   9806: 
                   9807: char *blob_toa(bp)
                   9808:     Blob *bp;
                   9809: {   char s1[80];
                   9810:     static char s[80];
                   9811:     Scoor hgt,wid;
                   9812:        if(bp==NULL) strcpy(s,"NULL");
                   9813:        else {  hgt = bp->bx.b.y - bp->bx.a.y + 1;
                   9814:                wid = bp->bx.b.x - bp->bx.a.x + 1;
                   9815:                sprintf(s1,"%s bx%s w%d,h%d ar%d pe%d r.",
                   9816:                        ident_toa(bp->ident),
                   9817:                        bbx_toa(&(bp->bx)),
                   9818:                        wid,
                   9819:                        hgt,
                   9820:                        bp->area,
                   9821:                        bp->per
                   9822:                        );
                   9823:                if(bp->ident&Runs_f) strcat(s1,"f");
                   9824:                else if(bp->ident&Runs_ff) strcat(s1,"ff");
                   9825:                else if(bp->ident&Runs_seek) strcat(s1,"sk");
                   9826:                else if(bp->ident&Runs_g4) strcat(s1,"g");
                   9827:                else strcat(s1,"?");
                   9828:                sprintf(s,"%s%d",s1,bp->runs);
                   9829:                };
                   9830:        return(s);
                   9831:        }
                   9832: 
                   9833: /* compute the centroid of the Blob, w.r.t bx.a */
                   9834: Pp *blob_centroid(bp)
                   9835:     Blob *bp;
                   9836: {   static Pp c;
                   9837:     RunF *rfp;
                   9838:     int ri,area;
                   9839:        c.x = c.y = 0.0;
                   9840:        if(bp->ident&Runs_ff) {
                   9841:                for(ri=0, rfp=bp->r.ff; ri<bp->runs; ri++, rfp++) {
                   9842:                        c.x += (area=(rfp->xe-rfp->xs+1)) * (rfp->xe+rfp->xs);
                   9843:                        c.y += area * rfp->y;
                   9844:                        };
                   9845:                c.x /= 2.0*bp->area;
                   9846:                c.y /= bp->area;
                   9847:                }
                   9848:        else abort("blob_centroid: only Runs_ff supported");
                   9849:        return(&c);
                   9850:        }
                   9851: 
                   9852: /* write (printably) to stdout */
                   9853: out_blob(bp)
                   9854:     Blob *bp;
                   9855: {   Run *crp;
                   9856:     static char pad[] = "     ";
                   9857:     short y;
                   9858:        if(bp==NULL) fprintf(stderr,"Bb NULL.\n");
                   9859:        else fprintf(stdout,"%s\n",blob_toa(bp));
                   9860:        fprintf(stdout,"%sy%d:",pad,bp->bx.a.y);
                   9861:        for(crp=bp->r.f,y=crp->y; crp!=NULL; crp=crp->n) {
                   9862:                if(crp->y!=y) {
                   9863:                        fprintf(stdout,"\n%sy%d:",pad,crp->y);
                   9864:                        y=crp->y;
                   9865:                        };
                   9866:                fprintf(stdout," [%d,%d]",crp->xs,crp->xe);
                   9867:                };
                   9868:        fprintf(stdout,"\n");
                   9869:        }
                   9870: 
                   9871: #if FWRI
                   9872: /* Write blob record (only) to FILE *f.
                   9873:    Check whether Blob is ``small'' and label *p accordingly. */
                   9874: fwrb_blob(f,p)
                   9875:     FILE *f;
                   9876:     Blob *p;
                   9877: {
                   9878: #if dbg_fwrb
                   9879:        if((!(p->ident&IsBlob))||(p->ident&(IsALL&(~IsBlob))))
                   9880:                err("fwrb_blob: %s",blob_toa(p));
                   9881: #endif
                   9882:        if(blob_small(p)) p->ident |= Blob_small; else p->ident &= ~Blob_small;
                   9883:        fwri_Ident(f,p->ident);
                   9884:        /* fwri_Seq(f,p->no); */
                   9885:        fwri_Bbx(f,&(p->bx));
                   9886:        fwri_uint4(f,p->area);
                   9887:        fwri_uint4(f,p->per);
                   9888:        /* don't write .n */
                   9889:        fwri_Merit(f,p->m);
                   9890:        fwri_uint3(f,p->runs);
                   9891:        fwri_uint2(f,((p->bdsp==NULL)? 0: p->bdsp->mny));
                   9892: #if dbg_fwrb_toa
                   9893:        err("fwrb_blob: %s",blob_toa(p));
                   9894: #endif
                   9895:        }
                   9896: #else
                   9897: /* Write blob record (only) to FILE *fp.
                   9898:    Check whether Blob is ``small'' and label *bp accordingly. */
                   9899: fwrb_blob(fp,bp)
                   9900:     FILE *fp;
                   9901:     Blob *bp;
                   9902: {   BlobF bf;
                   9903: #if dbg_fwrb
                   9904:        if((!(bp->ident&IsBlob))||(bp->ident&(IsALL&(~IsBlob))))
                   9905:                err("fwrb_blob: %s",blob_toa(bp));
                   9906: #endif
                   9907:        memset(&bf,'\0',sizeof(bf));
                   9908:        if(blob_small(bp)) bp->ident |= Blob_small;
                   9909:        else bp->ident &= ~Blob_small;
                   9910:        bf.ident = bp->ident;
                   9911:        bf.bx=bp->bx;
                   9912:        bf.area=bp->area;
                   9913:        bf.per=bp->per;
                   9914:        bf.runs=bp->runs;
                   9915:        if(bp->bdsp==NULL) bf.bdys=0;
                   9916:        else bf.bdys=bp->bdsp->mny;
                   9917:        if(blob_debug) err_blobf("",&bf);
                   9918:        if(fwrite(&bf,sizeof(BlobF),1,fp)!=1)
                   9919:                abort("fwrb_blob: can't fwrite");
                   9920: #if dbg_fwrb_toa
                   9921:        err("fwrb_blob: %s",blob_toa(bp));
                   9922: #endif
                   9923:        }
                   9924: #endif
                   9925: 
                   9926: /* Write detailed description of Runs to stderr. */
                   9927: Blob *err_runs(name,bp)
                   9928:     char *name;
                   9929:     Blob *bp;
                   9930: {   Run *rp;
                   9931:     RunF *rfp,*rfe;
                   9932:     int ri;
                   9933:        if(bp->ident&Runs_f) {
                   9934:                fprintf(stderr,"%s Runs_f[%d] in %s:\n",
                   9935:                        name,bp->runs,bbx_toa(&bp->bx));
                   9936:                for(rp=bp->r.f,ri=0; rp!=NULL; rp=rp->n,ri++) { 
                   9937:                        fprintf(stderr,"  %2d: %d[%d,%d]\n",
                   9938:                                ri,rp->y,rp->xs,rp->xe);
                   9939:                        };
                   9940:                }
                   9941:        else if(bp->ident&Runs_ff) {
                   9942:                fprintf(stderr,"%s Runs_ff[%d] in %s: ",
                   9943:                        name,bp->runs,bbx_toa(&(bp->bx)));
                   9944:                for(rfe=(rfp=bp->r.ff)+bp->runs,ri=0; rfp<rfe; rfp++,ri++) {    
                   9945:                        fprintf(stderr," %d:%d[%d,%d]",
                   9946:                                ri,rfp->y,rfp->xs,rfp->xe);
                   9947:                        };
                   9948:                fprintf(stderr,"\n");
                   9949:                }
                   9950:        else if(bp->ident&Runs_seek) {
                   9951:                goto unsupported;
                   9952:                }
                   9953:        else {  goto unsupported;
                   9954:                };
                   9955:        return;
                   9956: unsupported:
                   9957:        abort("err_runs: %s unsupported",ident_toa(bp->ident));
                   9958:        }
                   9959: 
                   9960: /* Convert the type of Runs in *bp to the type specified by id.
                   9961:    Supported:  only bp->ident&Runs_f to id&Runs_ff.
                   9962:    Return pointer to local static duplicate of *bp.
                   9963:    */
                   9964: Blob *runs_to_runs(bp,id)
                   9965:     Blob *bp;
                   9966:     Ident id;
                   9967: {   static Blob b;
                   9968:     register Run *rp;
                   9969:     RunF *rfp;
                   9970: 
                   9971:        b = *bp;
                   9972:        if(bp->ident&Runs_f) {
                   9973:                if(id&Runs_ff) {
                   9974:                        b.ident &= ~(Runs_f|Blob_small);
                   9975:                        b.ident |= Runs_ff;
                   9976:                        if(blob_small(bp)) b.ident |= Blob_small;
                   9977:                        if((b.r.ff=(RunF *)malloc(b.runs*sizeof(RunF)))==NULL)
                   9978:                                abort("runs_to_runs: can't malloc Blob.r.ff[%d]",
                   9979:                                                b.runs);                                                        for(rp=bp->r.f,rfp=b.r.ff; rp!=NULL; rp=rp->n,rfp++) {  
                   9980:                                /* y, xs, xe will be relative to Blob.bx.a */
                   9981:                                rfp->y = rp->y - bp->bx.a.y;
                   9982:                                rfp->xs = rp->xs - bp->bx.a.x;
                   9983:                                rfp->xe = rp->xe - bp->bx.a.x;
                   9984:                                /* above,below connecting indices are relative to
                   9985:                                   the sequence no. of this run (ac>0 & bc>0) */
                   9986:                                if((rfp->ad = rp->ad)!=0)
                   9987:                                        rfp->ac = rp->u.no - rp->ac->u.no;
                   9988:                                else rfp->ac = 0;
                   9989:                                if((rfp->bd = rp->bd)!=0)
                   9990:                                        rfp->bc = rp->bc->u.no - rp->u.no;
                   9991:                                else rfp->bc = 0;
                   9992:                                if(0) err_runf("   ",rfp);
                   9993:                                };
                   9994:                        }
                   9995:                else {  goto unsupported;
                   9996:                        };
                   9997:                }
                   9998:        else if(bp->ident&Runs_ff) {
                   9999:                if(bp->ident&Blob_small) {
                   10000:                        goto unsupported;
                   10001:                        }
                   10002:                else {  goto unsupported;
                   10003:                        };
                   10004:                }
                   10005:        else if(bp->ident&Runs_seek) {
                   10006:                goto unsupported;
                   10007:                }
                   10008:        else {  goto unsupported;
                   10009:                };
                   10010:        return(&b);
                   10011: 
                   10012: unsupported:
                   10013:        abort("runs_to_runs: %s --> %s unsupported",
                   10014:                ident_toa(bp->ident),ident_toa(id));
                   10015:        }
                   10016: 
                   10017: #if CPU!=CRAY
                   10018: /* Write these RunFs to FILE *fp in CCITT Group 4 format.
                   10019:    BUG:  uses bitio to one end of a pipe, just to store the entire
                   10020:    byte-stream so it can be counted; then, it is copied to *fp.
                   10021:    This fails on large bitmaps since the space available for pipe
                   10022:    buffering is limited by system constraints and can run out at any
                   10023:    time (symptom: the user process hangs in I state).  Also, since
                   10024:    it relies so heavily on streams, it may not prove to be very portable.
                   10025:    Should be rewritten with an expandable byte-buffer of some kind,
                   10026:    which requires that the `putting' function in bitio be user-selectable.
                   10027:    */
                   10028: fwrb_runfs_g4(fp,bxp,runs,ff)
                   10029:     FILE *fp;
                   10030:     Bbx *bxp;
                   10031:     int runs;
                   10032:     RunF *ff;
                   10033: #define dbg_fwrb_runfs_g4_detail F
                   10034: {   RLE_Line l0,l1;
                   10035:     RLE_Line *cl,*pl,*swap;    /* current/prior/swap line */
                   10036:     int wid,hgt;               /* width,height of rectangular box of pixels */
                   10037:     BITFILE *bf;
                   10038:     int iri;
                   10039:     RunF *irp;
                   10040:     RLE_Run *crp;
                   10041:     static int pipe_fd[2] = {-1,-1};
                   10042:     static FILE *pipe_fp[2] = {NULL,NULL};
                   10043:     unsigned long bytes,bi;
                   10044:     int och;
                   10045:        /* buffer g4 code in a pipe in order to count it */
                   10046:        if(pipe_fd[0]==-1) {
                   10047:                pipe(pipe_fd);
                   10048:                if((pipe_fp[0] = fdopen(pipe_fd[0],"r"))==NULL)
                   10049:                        abort("fwrb_runfs_g4: can't open pipe \"r\", fd=%d",
                   10050:                                pipe_fd[0]);
                   10051:                if((pipe_fp[1] = fdopen(pipe_fd[1],"w"))==NULL)
                   10052:                        abort("fwrb_runfs_g4: can't open pipe \"w\", fd=%d",
                   10053:                                pipe_fd[1]);
                   10054:                /* leave this pipe open for the duration of the process */
                   10055:                };
                   10056:        /* treat pipe_fp[1] as a sequence of bits */
                   10057:        if((bf=bopen(pipe_fp[1],"w"))==NULL)
                   10058:                abort("fwrb_runfs_g4: can't open bitfile");
                   10059:        wid = bbx_wid(bxp);  hgt=bbx_hgt(bxp);
                   10060:        BOF_to_g4(bf);
                   10061:        cl= &l0;  pl= &l1;  cl->len = pl->len = wid;  cl->y=0;  pl->runs=0;
                   10062:        iri=0;  irp=ff;
                   10063:        do {    /* build current RLE_Line */
                   10064:                crp=cl->r;
                   10065:                while(iri<runs&&irp->y==cl->y) {
                   10066:                        crp->xs=irp->xs;
                   10067:                        crp->xe=irp->xe;
                   10068:                        if(dbg_fwrb_runfs_g4_detail)
                   10069:                                err("i%d:  y%d x[%d,%d]",
                   10070:                                        iri,cl->y,crp->xs,crp->xe);
                   10071:                        iri++; irp++; crp++;
                   10072:                        };
                   10073:                cl->runs = crp-cl->r;
                   10074:                /* write current RLE_line to file */
                   10075:                rlel_to_g4(pl,cl,wid,bf);
                   10076:                /* save current line as prior */
                   10077:                swap=pl;  pl=cl;  cl=swap;  cl->runs=0;  cl->y=pl->y+1;
                   10078:                }
                   10079:        while(cl->y<hgt);
                   10080:        /** By policy, don't append EOFB (i.e. omit EOF_to_g4(bf)) **/
                   10081:        bytes = bclose(bf);
                   10082:        if(dbg_fwrb_runs) err("fwrb_runfs_g4: %d bytes",bytes);
                   10083: #if FWRI
                   10084:        fwri_uint4(fp,bytes);
                   10085: #else
                   10086:        fwrite(&bytes,sizeof(bytes),1,fp);
                   10087: #endif
                   10088:        /* copy contents in pipe to fp */
                   10089:        fflush(pipe_fp[1]);
                   10090:        for(bi=0;bi<bytes;bi++) {
                   10091:                putc(och=getc(pipe_fp[0]),fp);
                   10092: #if dbg_fwrb_runs
                   10093:                fprintf(stderr,"%02x",(unsigned char)och);
                   10094: #endif
                   10095:                };
                   10096:        if(dbg_fwrb_runs) fprintf(stderr,"\n");
                   10097:        }
                   10098: #else
                   10099: fwrb_runfs_g4(fp,bxp,runs,ff)
                   10100:     FILE *fp;
                   10101:     Bbx *bxp;
                   10102:     int runs;
                   10103:     RunF *ff;
                   10104: {      abort("fwrb_runfs_g4: unimplemented on Cray");
                   10105:        }
                   10106: #endif
                   10107: 
                   10108: #if CPU != CRAY
                   10109: /* Read a connected group of Runs in CCITT Group 4 format, into an array of RunFs.
                   10110:    Return:  1 if normal & successful, 0 if EOF, and -1 if error.
                   10111:    */
                   10112: int frdb_g4_runfs(fp,bxp,runs,ff)
                   10113:     FILE *fp;
                   10114:     Bbx *bxp;  /* their bounding box, shrink-wrapped to fit exactly */
                   10115:     int runs;  /* expect exactly this number of runs */
                   10116:     RunF *ff;  /* space for `runs' RunFs */
                   10117: #define dbg_frdb_g4_runfs_detail F
                   10118: {   RLE_Line *cl;      /* current line */
                   10119:     int wid,hgt;       /* width,height of rectangular box of pixels */
                   10120:     int y;             /* height of current line */
                   10121:     boolean bof;
                   10122:     BITFILE *bf;
                   10123:     static DST_table *tbl = NULL;
                   10124:     int iri;
                   10125:     RLE_Run *irp;
                   10126:     int ori;
                   10127:     RunF *orp;
                   10128:     unsigned long bytes,g4_bytes;
                   10129: #if FRDI
                   10130:        bytes=frdi_uint4(fp);
                   10131: #else
                   10132:        fread(&bytes,sizeof(bytes),1,fp);
                   10133: #endif
                   10134:        if(dbg_frdb_runs) err("frdb_g4_runfs: %d bytes",bytes);
                   10135:        /* read FILE *fp as a sequence of bits */
                   10136:        if((bf=bopen(fp,"r"))==NULL)
                   10137:                abort("frdb_g4_runfs: can't open bitfile");
                   10138:        if(tbl==NULL) {
                   10139:                tbl=ccitt_table();
                   10140:                if(dbg_frdb_g4_runfs_detail) ccitt_err_tbl(tbl);
                   10141:                };
                   10142:        wid=bbx_wid(bxp);  hgt=bbx_hgt(bxp);
                   10143:        y=0;  bof=T;  ori=0;  orp=ff;
                   10144:        while((y<hgt)&&(cl=g4_to_rlel(tbl,bf,bof,wid))!=NULL) {
                   10145:                /* copy runs to RunF ff[] */
                   10146:                for(iri=0,irp=cl->r; iri<cl->runs; iri++,irp++) {
                   10147:                        if(dbg_frdb_g4_runfs_detail)
                   10148:                                err("o%d i%d:  y%d x[%d,%d]",
                   10149:                                        ori,iri,y,irp->xs,irp->xe);
                   10150:                        if(ori<runs) {
                   10151:                                orp->y = y;  orp->xs = irp->xs;  orp->xe = irp->xe;
                   10152:                                orp++;
                   10153:                                }
                   10154:                        else err("frdb_g4_runfs: too many runs: ori%d >= runs%d",
                   10155:                                ori,runs);
                   10156:                        ori++;
                   10157:                        };
                   10158:                y++;  bof=F;
                   10159:                };
                   10160:        if(cl==NULL) {
                   10161:                err("frdb_g4_runfs: unexpected EOF");
                   10162:                return(0);
                   10163:                };
                   10164:        /* recover connectivity among runs, on the assumption that they
                   10165:           are still in increasing lexicographic order on (y,xs) */
                   10166:        fix_lag(orp-ff,(char *)ff,Runs_ff);
                   10167:        if(ori!=runs) {
                   10168:                err("frdb_g4_runfs: expected %d runs, but read %d",runs,ori);
                   10169:                return(-1);
                   10170:                };
                   10171:        if((g4_bytes=bclose(bf))!=bytes) {
                   10172:                err("frdb_g4_runfs: expected %d bytes, but read %d",
                   10173:                        bytes,g4_bytes);
                   10174:                return(-1);
                   10175:                };
                   10176:        if(ferror(fp)) return(-errno); else return(1);
                   10177:        }
                   10178: #else
                   10179: int frdb_g4_runfs(fp,bxp,runs,ff)
                   10180:     FILE *fp;
                   10181:     Bbx *bxp;  /* exact bounding box, shrink-wrapped to fit */
                   10182:     int runs;  /* expect exactly this number of runs */
                   10183:     RunF *ff;  /* space for `runs' RunFs */
                   10184: {      abort("frdb_g4_runfs:  unimplemented on Cray");
                   10185:        }
                   10186: #endif
                   10187: 
                   10188: /* Write blob, etc to FILE *fp in binary format.
                   10189:    If !(etc&IsBlob), then do nothing.
                   10190:    else write Blob record and:
                   10191:      If etc&IsRun, then also try to write Runs:
                   10192:        If Blob.runs==0, write no runs.
                   10193:        else
                   10194:           if etc&Runs_g4, write in CCITT G4 format
                   10195:                compact but needs large streams; may not port well;
                   10196:           else write in Runs_ff format
                   10197:                if blob is small enough, use compressed RunFS form on output.
                   10198: 
                   10199:     */
                   10200: fwrb_blob_etc(fp,bp,etc)
                   10201:     FILE *fp;
                   10202:     Blob *bp;
                   10203:     Ident etc;
                   10204: {   Ident sv_ident;
                   10205:     int sv_runs;
                   10206:     Run *rp;
                   10207:     RunF rf;
                   10208:     register RunF *rfp, *rfq;
                   10209:     RunFS *rsp;
                   10210: #if FWRI
                   10211:     RunFS rfs;
                   10212: #else
                   10213:     static RunFS rfsa[256];
                   10214: #endif
                   10215:     int ri;
                   10216:        if(!(etc&IsBlob)) return;
                   10217: 
                   10218:        sv_ident = bp->ident;
                   10219:         sv_runs = bp->runs;
                   10220:        if(etc&IsRun) {
                   10221:                /* decide which Runs_* bits should be set on output */
                   10222:                bp->ident &= ~(Runs_f|Runs_ff|Runs_seek|Runs_g4);
                   10223:                if(etc&Runs_g4) {
                   10224:                        bp->ident |= Runs_g4;
                   10225:                        }
                   10226:                else {  /* assume Runs_ff is wanted */
                   10227:                        bp->ident |= Runs_ff;
                   10228:                        };
                   10229:                }
                   10230:        else {  bp->ident &= ~(IsRun|Runs_f|Runs_ff|Runs_seek|Runs_g4);
                   10231:                bp->runs = 0;
                   10232:                };
                   10233:        fwrb_blob(fp,bp);
                   10234:        bp->ident = sv_ident;
                   10235:        bp->runs = sv_runs;
                   10236: 
                   10237:        if(bp->runs==0) return;
                   10238: 
                   10239:        if(etc&Runs_g4) {
                   10240:                /* write CCITT Group 4 encoding for Runs */
                   10241:                if(bp->ident&Runs_ff) {
                   10242:                        fwrb_runfs_g4(fp,&(bp->bx),bp->runs,bp->r.ff);
                   10243:                        }
                   10244:                else abort("fwrb_blob_etc: etc&Runs_g4 but !(id&Runs_ff)");
                   10245:                }
                   10246:        else {  /* Assume Runs_ff format is desired */
                   10247:                if(bp->ident&Runs_f) {
                   10248:                        rp=bp->r.f;     
                   10249:                        if(bp->ident&Blob_small) { /* use compressed Run records */
                   10250:                                if(blob_debug) err("small");
                   10251:                                /* can use small local static array */
                   10252: #if FWRI
                   10253:                                rsp= &rfs;
                   10254: #else
                   10255:                                rsp=rfsa;
                   10256: #endif
                   10257:                                while(rp!=NULL) {
                   10258:                                        /* y, xs, xe will be relative to Blob.bx.a */
                   10259:                                        rsp->y = rp->y - bp->bx.a.y;
                   10260:                                        rsp->xs = rp->xs - bp->bx.a.x;
                   10261:                                        rsp->xe = rp->xe - bp->bx.a.x;
                   10262:                                        /* above,below connecting run indices are relative to
                   10263:                                           the sequence no. of this run (ac>0 & bc>0) */
                   10264:                                        if((rsp->ad = rp->ad)!=0)
                   10265:                                                rsp->ac = rp->u.no - rp->ac->u.no;
                   10266:                                        else rsp->ac = 0;
                   10267:                                        if((rsp->bd = rp->bd)!=0)
                   10268:                                                rsp->bc = rp->bc->u.no - rp->u.no;
                   10269:                                        else rsp->bc = 0;
                   10270:                                        if(blob_debug) err_runfs("  ",rsp);
                   10271:                                        rp=rp->n;
                   10272: #if FWRI
                   10273:                                        fwri_RunFS(fp,rsp);
                   10274: #else
                   10275:                                        rsp++;
                   10276: #endif
                   10277:                                        };
                   10278: #if !FWRI
                   10279:                                if(fwrite(rfsa,sizeof(RunFS),bp->runs,fp)!=bp->runs)
                   10280:                                        abort("fwrb_blob_etc: can't fwrite RunFS[%d]",bp->runs);
                   10281:                                if(dbg_fwrb_runs)
                   10282:                                        err("fwrb_blob_etc: %d bytes",bp->runs*sizeof(RunFS));
                   10283: #endif
                   10284:                                }
                   10285:                        else {  if(blob_debug) err("large");
                   10286:                                while(rp!=NULL) {       
                   10287:                                        /* y, xs, xe will be relative to Blob.bx.a */
                   10288:                                        rf.y = rp->y - bp->bx.a.y;
                   10289:                                        rf.xs = rp->xs - bp->bx.a.x;
                   10290:                                        rf.xe = rp->xe - bp->bx.a.x;
                   10291:                                        /* above,below connecting run indices are relative to
                   10292:                                           the sequence no. of this run (ac>0 & bc>0) */
                   10293:                                        if((rf.ad = rp->ad)!=0)
                   10294:                                                rf.ac = rp->u.no - rp->ac->u.no;
                   10295:                                        else rf.ac = 0;
                   10296:                                        if((rf.bd = rp->bd)!=0)
                   10297:                                                rf.bc = rp->bc->u.no - rp->u.no;
                   10298:                                        else rf.bc = 0;
                   10299:                                        if(blob_debug) err_runf("   ",&rf);
                   10300:                
                   10301:                                        /* since there may be many, won't use a local array */
                   10302: #if FWRI
                   10303:                                        fwri_RunF(fp,&rf);
                   10304: #else
                   10305:                                        if(fwrite(&rf,sizeof(RunF),1,fp)!=1)
                   10306:                                                abort("fwrb_blob_etc: can't fwrite RunF");
                   10307: #endif
                   10308:                                        rp=rp->n;
                   10309:                                        };
                   10310:                                if(dbg_fwrb_runs)
                   10311:                                        err("fwrb_blob_etc: %d bytes",bp->runs*sizeof(RunF));
                   10312:                                };
                   10313:                        }
                   10314:                else if(bp->ident&Runs_ff) {
                   10315:                        if(bp->ident&Blob_small) { /* use compressed Run records */
                   10316:                                if(blob_debug) err("small");
                   10317:                                /* can use small local static array */
                   10318: #if FWRI
                   10319:                                rsp= &rfs;
                   10320: #else
                   10321:                                rsp=rfsa;
                   10322: #endif
                   10323:                                for(rfp=bp->r.ff,ri=0; ri<bp->runs; rfp++,ri++) {
                   10324:                                        rsp->y = rfp->y;
                   10325:                                        rsp->xs = rfp->xs;
                   10326:                                        rsp->xe = rfp->xe;
                   10327:                                        rsp->ad = rfp->ad;
                   10328:                                        rsp->bd = rfp->bd;
                   10329:                                        rsp->ac = rfp->ac;
                   10330:                                        rsp->bc = rfp->bc;
                   10331: #if FWRI
                   10332:                                        fwri_RunFS(fp,rsp);
                   10333: #else
                   10334:                                        rsp++;
                   10335: #endif
                   10336:                                        };
                   10337: #if !FWRI
                   10338:                                if(fwrite(rfsa,sizeof(RunFS),bp->runs,fp)!=bp->runs)
                   10339:                                        abort("fwrb_blob_etc: can't fwrite RunFS[%d]",bp->runs);
                   10340:                                if(dbg_fwrb_runs)
                   10341:                                        err("fwrb_blob_etc: %d bytes",bp->runs*sizeof(RunFS));
                   10342: #endif
                   10343:                                }
                   10344:                        else {  if(blob_debug) err("large");
                   10345: #if FWRI
                   10346:                                for(rfq=(rfp=bp->r.ff)+bp->runs; rfp<rfq; rfp++) {
                   10347:                                        fwri_RunF(fp,rfp);
                   10348:                                        };
                   10349: 
                   10350: #else
                   10351:                                if(fwrite(bp->r.ff,sizeof(RunF),bp->runs,fp)!=bp->runs)
                   10352:                                        abort("fwrb_blob_etc: can't fwrite RunF[%d]",bp->runs);
                   10353:                                if(dbg_fwrb_runs)
                   10354:                                        err("fwrb_blob_etc: %d bytes",bp->runs*sizeof(RunF));
                   10355: #endif
                   10356:                                };
                   10357:                        };
                   10358:                }; 
                   10359:        }
                   10360: 
                   10361: /* Read a given Blob's RunF's (binary) from FILE *fp; return F on EOF.
                   10362:    If bp->runs<=max, read the RunF's into bp->r.ff, and set Runs_ff bit.
                   10363:    otherwise ignore them all and set bp->r.ff==NULL.  */
                   10364: int frdb_runfs(fp,bp,max)
                   10365:     FILE *fp;
                   10366:     Blob *bp;  /* *bp's fields already set up */
                   10367:     int max;   /* maximum no. RunF records expected */
                   10368: {   register RunFS *rsp,*rsq;
                   10369:     static RunFS rfsa[256];
                   10370:     register RunF *rfp,*rfq;
                   10371:        if(bp->r.ff!=NULL && bp->runs <= max) {
                   10372:                bp->ident |= Runs_ff;  bp->ident &= ~(Runs_f|Runs_seek);
                   10373:                if(bp->ident&Blob_small) {
                   10374:                        if(blob_debug) err("small");
                   10375: #if FRDI
                   10376:                        for(rsq=(rsp=rfsa)+bp->runs; rsp<rsq; rsp++) {
                   10377:                                frdi_RunFS(fp,rsp);
                   10378:                                };
                   10379: #else
                   10380:                        if(fread(rfsa,sizeof(RunFS),bp->runs,fp) < bp->runs)
                   10381:                                return(0);
                   10382: #endif
                   10383:                        /* copy compressed RunFS's into RunF's */
                   10384:                        for(rsq=(rsp=rfsa)+bp->runs,rfp=bp->r.ff;
                   10385:                               rsp<rsq;
                   10386:                                  rsp++,rfp++) {
                   10387:                                /* beware sign extension from unsigned chars */
                   10388:                                if(blob_debug) err_runfs("   ",rsp);
                   10389:                                rfp->y = 0377&rsp->y;
                   10390:                                rfp->xs = 0377&rsp->xs;
                   10391:                                rfp->xe = 0377&rsp->xe;
                   10392:                                rfp->ad = 0377&rsp->ad;
                   10393:                                rfp->bd = 0377&rsp->bd;
                   10394:                                rfp->ac = 0377&rsp->ac;
                   10395:                                rfp->bc = 0377&rsp->bc;
                   10396:                                };
                   10397:                        }
                   10398:                else {  if(blob_debug) err("large");
                   10399: #if FRDI
                   10400:                        for(rfq=(rfp=bp->r.ff)+bp->runs; rfp<rfq; rfp++)
                   10401:                                frdi_RunF(fp,rfp);
                   10402: #else
                   10403:                        if(fread(bp->r.ff,sizeof(RunF),bp->runs,fp) != bp->runs)
                   10404:                                return(F);
                   10405: #endif
                   10406:                        };
                   10407:                }
                   10408:        else {  bp->ident &= ~(Runs_ff|Runs_f);
                   10409:                bp->ident |= Runs_seek;
                   10410:                bp->r.seek=ftell(fp);
                   10411:                /* skip past excessive no. of runs */
                   10412: /** What if FRDI?? **/
                   10413:                if(bp->ident&Blob_small)
                   10414:                        fseek(fp,(long)((bp->runs)*sizeof(RunFS)),1);
                   10415:                else
                   10416:                        fseek(fp,(long)((bp->runs)*sizeof(RunF)),1);
                   10417:                };
                   10418:        if(ferror(fp)) return(-errno); else return(1);
                   10419:        }
                   10420: 
                   10421: #if FRDI
                   10422: /* read a Blob record (only) into *p */
                   10423: int frdb_blob(f,p)
                   10424:     FILE *f;
                   10425:     Blob *p;
                   10426: {   int bdy_mny;
                   10427:        *p = empty_Blob;
                   10428:        if(feof(f))
                   10429:                return(0);
                   10430:        p->ident=frdi_Ident(f);
                   10431:        /* p->no=frdi_Seq(f); */
                   10432:        frdi_Bbx(f,&(p->bx));
                   10433:        p->area=frdi_uint4(f);
                   10434:        p->per=frdi_uint4(f);
                   10435:        /* don't read .n */
                   10436:        p->m=frdi_Merit(f);
                   10437:        p->runs=frdi_uint3(f);
                   10438:        if((bdy_mny=frdi_uint2(f))>0) {
                   10439:                p->bdsp = alloc_bdys();
                   10440:                p->bdsp->mny = bdy_mny;
                   10441:                };
                   10442: #if dbg_frdb
                   10443:        if((!(p->ident&IsBlob))||(p->ident&(IsALL&(~IsBlob))))
                   10444:                err("frdb_blob: %s",blob_toa(p));
                   10445: #endif
                   10446: #if dbg_frdb_toa
                   10447:        err("frdb_blob: %s",blob_toa(p));
                   10448: #endif
                   10449:        if(ferror(f))
                   10450:                return(-errno);
                   10451:        else return(1);
                   10452:        }
                   10453: #else
                   10454: /* read a Blob record (only) into *bp;  return F if EOF */
                   10455: int frdb_blob(fp,bp)
                   10456:     FILE *fp;
                   10457:     Blob *bp;
                   10458: {   BlobF bf;
                   10459:        if(fread(&bf,sizeof(BlobF),1,fp)!=1) return(0);
                   10460:        if(blob_debug) err_blobf("bf",&bf);
                   10461:        bp->ident=bf.ident;
                   10462:        bp->no = 0;
                   10463:        bp->bx=bf.bx;
                   10464:        bp->area=bf.area;
                   10465:        /*bp->per=bf.per;*/
                   10466:        bp->runs=bf.runs;
                   10467:        /*bp->bdys=bf.bdys;*/
                   10468:        bp->n = NULL;
                   10469:        bp->r.f = NULL;
                   10470:        bp->bdsp = NULL;
                   10471: #if dbg_frdb
                   10472:        if((!(bp->ident&IsBlob))||(bp->ident&(IsALL&(~IsBlob))))
                   10473:                err("frdb_blob: %s",blob_toa(bp));
                   10474: #endif
                   10475: #if dbg_frdb_toa
                   10476:        err("frdb_blob: %s",blob_toa(bp));
                   10477: #endif
                   10478:        if(ferror(fp)) return(-errno); else return(1);
                   10479:        }
                   10480: #endif
                   10481: 
                   10482: err_blob(s,bp)
                   10483:     char *s;
                   10484:     Blob *bp;
                   10485: {      fprintf(stderr,"%s ",s);
                   10486:        if(bp==NULL) fprintf(stderr,"Blob NULL.\n");
                   10487:        else fprintf(stderr,
                   10488:                "Blob %d: x[%d,%d],y[%d,%d] ar%d ft%s r(#%d f%d)\n",
                   10489:                bp->no,bp->bx.a.x,bp->bx.b.x,bp->bx.a.y,bp->bx.b.y,
                   10490:                bp->area,ident_toa(bp->ident),bp->runs,rp_tod(bp->r.f));
                   10491:        }
                   10492: 
                   10493: err_blob_runs(s,bp)
                   10494:     char *s;
                   10495:     Blob *bp;
                   10496: {   Run *crp;
                   10497:     char cs[20];
                   10498:        fprintf(stderr,"%s ",s);
                   10499:        err_blob(s,bp);
                   10500:        if(bp!=NULL&&bp->runs>0&&bp->r.f!=NULL) {
                   10501:                sprintf(cs,"%*s",strlen(s)+2," ");
                   10502:                for(crp=bp->r.f; crp!=NULL; crp=crp->n) err_run(cs,crp);
                   10503:                };
                   10504:        }
                   10505: 
                   10506: err_blob_runfs(s,bp)
                   10507:     char *s;
                   10508:     Blob *bp;
                   10509: {   RunF *crp;
                   10510:     int ri;
                   10511:     char cs[20];
                   10512:        fprintf(stderr,"%s ",s);
                   10513:        err_blob_briefly("",bp);
                   10514:        if(bp!=NULL&&bp->runs>0&&bp->r.ff!=NULL) {
                   10515:                sprintf(cs,"%*s",strlen(s)+2," ");
                   10516:                for(crp=bp->r.ff,ri=0; ri<bp->runs; crp++,ri++) err_runf(cs,crp);
                   10517:                };
                   10518:        }
                   10519: 
                   10520: err_blobf(s,bp)
                   10521:     char *s;
                   10522:     BlobF *bp;
                   10523: {   Run *crp;
                   10524:     char cs[20];
                   10525:        fprintf(stderr,"%s ",s);
                   10526:        if(bp==NULL) fprintf(stderr,"BlobF NULL.\n");
                   10527:        else fprintf(stderr,
                   10528:                "BlobF: x[%d,%d],y[%d,%d] ar%d ft%s #r%d\n",
                   10529:                bp->bx.a.x,bp->bx.b.x,bp->bx.a.y,bp->bx.b.y,
                   10530:                bp->area,ident_toa(bp->ident),bp->runs);
                   10531:        }
                   10532: 
                   10533: err_blob_briefly(s,bp)
                   10534:     char s[];
                   10535:     Blob *bp;
                   10536: {   Run *crp;
                   10537:        if(bp==NULL) err("%s Blob NULL.",s);
                   10538:        else { fprintf(stderr,
                   10539:                        "%s Blob #%d: bx(%d,%d),(%d,%d) ar%d f%s runs%d ",
                   10540:                        s,
                   10541:                        bp->no,
                   10542:                        bp->bx.a.x,bp->bx.a.y,bp->bx.b.x,bp->bx.b.y,
                   10543:                        bp->area,
                   10544:                        ident_toa(bp->ident),
                   10545:                        bp->runs);
                   10546:                fprintf(stderr,"\n");
                   10547:                };
                   10548:        }
                   10549: 
                   10550: err_blob_stats()
                   10551: {      err("Blob stats:  %d now, %d total, %d hi-water\n",
                   10552:                        blob_max-blob_fr_mny,hi_blob_no+1,blob_hi);
                   10553:        }
                   10554: 
                   10555: /* write blob list starting at fi */
                   10556: fwrb_blobl_etc(fp,mny,fi,etc)
                   10557:     FILE *fp;
                   10558:     int mny;
                   10559:     Blob *fi;
                   10560:     Ident etc;
                   10561: {   int bi;
                   10562:     Blob *bp;
                   10563:        if(mny>0) for(bi=0,bp=fi; bi<mny; bi++,bp=bp->n) {
                   10564:                if(bp!=NULL) fwrb_blob_etc(fp,bp,etc);
                   10565:                else {  err("fwrb_blobl_etc: bmny==%d but %dth (Blob *) is NULL",
                   10566:                                mny,bi);
                   10567:                        break;
                   10568:                        };
                   10569:                };
                   10570:        }
                   10571: 
                   10572: fwrb_blobs_etc(fp,bs,etc)
                   10573:     FILE *fp;
                   10574:     Blobs bs;
                   10575:     Ident etc;
                   10576: {   register Blob *bp,**bpp;
                   10577:        if(bs.mny==0) return;
                   10578:        for(bp= *(bpp=bs.bpa); bp!=NULL; bp= *(++bpp))
                   10579:                fwrb_blob_etc(fp,bp,etc);
                   10580:        }
                   10581: 
                   10582: /* read a set of blobs, and their parts */
                   10583: frdb_blobs_etc(fp,bsp,etc)
                   10584:     FILE *fp;
                   10585:     Blobs *bsp;
                   10586:     Ident etc;         /* read only the parts indicated */
                   10587: {   int bi;
                   10588:     register Blob *bp,**bpp;
                   10589:        if(bsp->mny<=0) {
                   10590:                *bsp = empty_Blobs;
                   10591:                return(1);
                   10592:                };
                   10593: 
                   10594:        if((bpp=bsp->bpa=(Blob **)malloc((bsp->mny+1)*sizeof(Blob *)))==NULL)
                   10595:                abort("frdb_blobs_etc: can't alloc Blobs.bpa[%d]",bsp->mny+1);
                   10596:        for(bi=0; bi<bsp->mny; bi++) {
                   10597:                *(bpp++) = bp = alloc_blob();
                   10598:                if(!frdb_blob_etc(fp,bp,etc))
                   10599:                        abort("frdb_blobs_etc: unexpected EOF");
                   10600:                };
                   10601:        *bpp = NULL;
                   10602:        if(ferror(fp)) return(-errno); else return(1);
                   10603:        }
                   10604: 
                   10605: /* Read a blob record into *bp, and then read its parts as specified by etc.
                   10606:    If there aren't any runs, return normally.
                   10607:    If etc&IsRun is false, then set Runs_seek and proceed as described below.
                   10608:    If etc&Runs_ff, then the contents of r.ff is examined:
                   10609:        if NULL, then space is allocated here for `runs' RunF's;
                   10610:        if non-NULL, then on the assumption that it points to space for
                   10611:        at least `runs' many, they are read into it.
                   10612:    If etc&Runs_seek, then the ftell value is placed in r.seek,
                   10613:        and the runs are simply skipped over.
                   10614:    The Runs_f (list) option is unimplemented.
                   10615:    The Blob is marked with the appropriate Runs_X bit.
                   10616:    Return:  1 if normal & successful, 0 if EOF, and -1 if error.
                   10617:     */
                   10618: int frdb_blob_etc(fp,bp,etc)
                   10619:     FILE *fp;
                   10620:     Blob *bp;
                   10621:     Ident etc;
                   10622: {   int stat;
                   10623:        if((stat=frdb_blob(fp,bp))!=1)
                   10624:                return(stat);
                   10625:        if(bp->runs<=0) {
                   10626:                bp->runs = 0;
                   10627:                bp->r.ff = NULL;
                   10628:                bp->ident &= ~(Runs_f|Runs_seek|Runs_g4);
                   10629:                bp->ident |= Runs_ff;
                   10630:                return(1);
                   10631:                };
                   10632: 
                   10633:        if(!(etc&IsRun)) {
                   10634:                etc |= IsRun|Runs_seek;
                   10635:                etc &= ~(Runs_f|Runs_ff|Runs_g4);
                   10636:                };
                   10637:        if (!(etc&(Runs_f|Runs_ff|Runs_g4|Runs_seek)) || etc&Runs_ff) {
                   10638:                /* Want to deliver Runs in Runf ff[] format */
                   10639:                if(bp->r.ff==NULL) {
                   10640:                        if( (bp->r.ff=
                   10641:                            (RunF *)malloc(bp->runs*sizeof(RunF)))==NULL)
                   10642:                                abort("frdb_blob_etc: can't alloc r.ff[%d]",bp->runs);
                   10643:                        };
                   10644:                if(bp->ident&Runs_g4) {
                   10645:                        /* Runs are in CCITT Group 4 format */
                   10646:                        stat=frdb_g4_runfs(fp,&(bp->bx),bp->runs,bp->r.ff);
                   10647:                        }
                   10648:                else {  /* Runs are in RunF or RunFS format */
                   10649:                        stat=frdb_runfs(fp,bp,bp->runs);
                   10650:                        };
                   10651:                bp->ident |= Runs_ff;  bp->ident &= ~(Runs_f|Runs_seek|Runs_g4);
                   10652:                return(stat);
                   10653:                }
                   10654:        else if(etc&Runs_seek) {
                   10655:                bp->ident |= Runs_seek;  bp->ident &= ~(Runs_ff|Runs_f);
                   10656:                bp->r.seek=ftell(fp);   /* save seek addr */
                   10657:                /* skip past runs */
                   10658:                if(bp->ident&Blob_small)
                   10659:                        fseek(fp,(long)((bp->runs)*sizeof(RunFS)),1);
                   10660:                else    fseek(fp,(long)((bp->runs)*sizeof(RunF)),1);
                   10661:                }
                   10662:        else /* (etc&Runs_f) || (etc&Runs_g4) */ {
                   10663:                abort("frdb_blob_etc:  Runs_f & Runs_g4 etc option unimplemented");
                   10664:                };
                   10665:        if(ferror(fp)) return(-errno); else return(1);
                   10666:        }
                   10667: 
                   10668: /* read a number of blobs, and their parts, into linked-list (mny, *fi);
                   10669:    return T iff not EOF  */
                   10670: boolean frdb_blobl_etc(fp,bmny,fip,etc)
                   10671:     FILE *fp;
                   10672:     int bmny;
                   10673:     Blob **fip;
                   10674:     Ident etc;
                   10675: {   int bi;
                   10676:     register Blob *bp,**bpp;
                   10677:     RunF *rp;
                   10678:     int stat;
                   10679:        if(bmny<=0) return(1);
                   10680:        bi=0; bpp=fip;
                   10681:        do {    bp=alloc_blob();
                   10682:                if((stat=frdb_blob_etc(fp,bp,etc))!=1) return(stat);
                   10683:                *bpp=bp;  bpp= &(bp->n);
                   10684:                }
                   10685:        while((++bi)<bmny);
                   10686:        *bpp=NULL;
                   10687:        if(ferror(fp)) return(-errno); else return(1);
                   10688:        }
                   10689: 
                   10690: char *interp_toa(ip)
                   10691:     Interp *ip;
                   10692: {   static char s[80];
                   10693:     char ms[3],shs[3],szs[3],hts[3],prs[3];
                   10694:        strcpy(ms,merit_toa(ip->m));
                   10695:        strcpy(shs,merit_toa(ip->mshap));
                   10696:        strcpy(szs,merit_toa(ip->msize));
                   10697:        strcpy(hts,merit_toa(ip->mbhgt));
                   10698:        strcpy(prs,merit_toa(ip->p));
                   10699:        sprintf(s,"%s %s sz%s ba%d m%s (sh%s sz%s ht%s) p%s",
                   10700:                ident_toa(ip->ident),
                   10701: #if CPU!=CRAY
                   10702:                classid_toa(&(ip->ci)),
                   10703: #else
                   10704:                ip->ci.c,
                   10705: #endif
                   10706:                pts_toa(ip->size),
                   10707:                ip->basl,
                   10708:                ms,shs,szs,hts,prs);
                   10709:        return(s);
                   10710:        }
                   10711: 
                   10712: frdb_interpl_etc(fp,ilp,etc)
                   10713:     FILE *fp;
                   10714:     Interpl *ilp;
                   10715:     Ident etc;
                   10716: {   int ii,stat;
                   10717:     Interp *ip,*pp;
                   10718:        if(ilp->mny<=0) {
                   10719:                *ilp = empty_Interpl;
                   10720:                return(1);
                   10721:                };
                   10722: 
                   10723:        for(ii=0; ii<ilp->mny; ii++) {
                   10724:                ip=alloc_interp();
                   10725:                if(ii==0) ilp->fi = ip;
                   10726:                else pp->n = ip;
                   10727:                if((stat=frdb_interp(fp,ip))!=1) return(stat);
                   10728:                pp=ip;
                   10729:                };
                   10730:        ip->n = NULL;
                   10731:        if(ferror(fp)) return(-errno); else return(1);
                   10732:        }
                   10733: 
                   10734: #if FRDI
                   10735: int frdb_interp(f,p)
                   10736:     FILE *f;
                   10737:     Interp *p;
                   10738: {   int stat;
                   10739:        *p = empty_Interp;
                   10740:        if(feof(f))
                   10741:                return(0);
                   10742:        p->ident=frdi_Ident(f);
                   10743:        frdi_ClassId(f,&(p->ci));
                   10744:        p->mshap=frdi_Merit(f);
                   10745:        p->size=frdi_Pts(f);
                   10746:        p->msize=frdi_Merit(f);
                   10747:        p->basl=frdi_Scoor(f);
                   10748:        p->mbhgt=frdi_Merit(f);
                   10749:        p->m=frdi_Merit(f);
                   10750:        p->p=frdi_Prob(f);
                   10751: #if dbg_frdb
                   10752:        if((!(p->ident&IsInterp))||(p->ident&(IsALL&(~IsInterp))))
                   10753:                err("frdb_interp: %s",interp_toa(p));
                   10754: #endif
                   10755:        if(ferror(f)) return(-errno); else return(1);
                   10756:        }
                   10757: #else
                   10758: int frdb_interp(fp,ip)
                   10759:     FILE *fp;
                   10760:     Interp *ip;
                   10761: {   InterpF inf;
                   10762:     int stat;
                   10763:        if((stat=fread(&inf,sizeof(InterpF),1,fp))!=1) {
                   10764:                err("can't fread InterpF, status %d",stat);
                   10765:                return(stat);
                   10766:                };
                   10767:        *ip = empty_Interp;
                   10768:        ip->ident = inf.ident;
                   10769:        ip->ci = inf.ci;
                   10770:        ip->clp = NULL;
                   10771:        ip->clsp = NULL;
                   10772:        ip->mshap = inf.mshap;
                   10773:        ip->size = inf.size;
                   10774:        ip->msize = inf.msize;
                   10775:        ip->basl = inf.basl;
                   10776:        ip->mbhgt = inf.mbhgt;
                   10777:        ip->m = inf.m;
                   10778: #if dbg_frdb
                   10779:        if((!(ip->ident&IsInterp))||(ip->ident&(IsALL&(~IsInterp))))
                   10780:                err("frdb_interp: %s",interp_toa(ip));
                   10781: #endif
                   10782:        if(ferror(fp)) return(-errno); else return(1);
                   10783:        }
                   10784: #endif
                   10785: 
                   10786: free_interpl(ilp)
                   10787:     Interpl *ilp;
                   10788: {   int ii;
                   10789:     Interp *ip,*np;
                   10790:        if(ilp->mny>0) {
                   10791:                for(ip=ilp->fi; ip!=NULL; ip=np) { np=ip->n; free_interp(ip); }
                   10792:                ilp->mny=0;
                   10793:                };
                   10794:        ilp->fi=NULL;
                   10795:        };
                   10796: 
                   10797: fwrb_interpl_etc(fp,is,etc)
                   10798:     FILE *fp;
                   10799:     Interpl is;
                   10800:     Ident etc;
                   10801: {   Interp *ip;
                   10802:     int ii;
                   10803:        if(is.mny>0) for(ii=0,ip=is.fi; ii<is.mny; ii++,ip=ip->n)
                   10804:                fwrb_interp_etc(fp,ip,etc);
                   10805:        }
                   10806: 
                   10807: /* remove this Interp from the Interp-list */
                   10808: remove_interpl(ip,ilp)
                   10809:     Interp *ip;
                   10810:     Interpl *ilp;
                   10811: {   Interp *rp,*pp;
                   10812:        if(ilp->mny==1) {  /* frequent case */
                   10813:                ilp->fi=NULL; ilp->mny=0;
                   10814:                }
                   10815:        else if(ilp->mny>1){
                   10816:                pp=NULL;
                   10817:                for(rp=ilp->fi; rp!=ip&&rp!=NULL; pp=rp,rp=rp->n) ;
                   10818:                if(rp!=NULL) {  /* remove from list */
                   10819:                        if(pp==NULL) ilp->fi=ip->n;
                   10820:                        else pp->n=ip->n;
                   10821:                        ilp->mny--;
                   10822:                        }
                   10823:                else err("remove_interpl: can't - not found");
                   10824:                }
                   10825:        else err("remove_interpl: can't - Interpl empty");
                   10826:        }
                   10827: 
                   10828: /* prepend this Interp to the Interp-list */
                   10829: prepend_interpl(ip,ilp)
                   10830:     Interp *ip;
                   10831:     Interpl *ilp;
                   10832: {   Interp *rp,*pp;
                   10833:        ip->n = ilp->fi;
                   10834:        ilp->fi = ip;
                   10835:        ilp->mny++;
                   10836:        }
                   10837: 
                   10838: fwrb_interp_etc(fp,ip,etc)
                   10839:     FILE *fp;
                   10840:     Interp *ip;
                   10841:     Ident etc;
                   10842: {      fwrb_interp(fp,ip);
                   10843:        }
                   10844: 
                   10845: #if FWRI
                   10846: fwrb_interp(f,p)
                   10847:     FILE *f;
                   10848:     Interp *p;
                   10849: {   InterpF inf;
                   10850:     int stat;
                   10851: #if dbg_fwrb
                   10852:        if((!(p->ident&IsInterp))||(p->ident&(IsALL&(~IsInterp))))
                   10853:                err("fwrb_interp: %s",interp_toa(p));
                   10854: #endif
                   10855:        fwri_Ident(f,p->ident);
                   10856:        fwri_ClassId(f,&(p->ci));
                   10857:        fwri_Merit(f,p->mshap);
                   10858:        fwri_Pts(f,p->size);
                   10859:        fwri_Merit(f,p->msize);
                   10860:        fwri_Scoor(f,p->basl);
                   10861:        fwri_Merit(f,p->mbhgt);
                   10862:        fwri_Merit(f,p->m);
                   10863:        fwri_Prob(f,p->p);
                   10864: #if dbg_fwrb_toa
                   10865:        err("fwrb_interp: %s",interp_toa(p));
                   10866: #endif
                   10867:        }
                   10868: #else
                   10869: fwrb_interp(fp,ip)
                   10870:     FILE *fp;
                   10871:     Interp *ip;
                   10872: {   InterpF inf;
                   10873:     int stat;
                   10874: #if dbg_fwrb
                   10875:        if((!(ip->ident&IsInterp))||(ip->ident&(IsALL&(~IsInterp))))
                   10876:                err("fwrb_interp: %s",interp_toa(ip));
                   10877: #endif
                   10878:        memset(&inf,'\0',sizeof(inf));
                   10879:        inf.ident = ip->ident;
                   10880:        inf.ci = ip->ci;
                   10881:        inf.mshap = ip->mshap;
                   10882:        inf.size = ip->size;
                   10883:        inf.msize = ip->msize;
                   10884:        inf.basl = ip->basl;
                   10885:        inf.mbhgt = ip->mbhgt;
                   10886:        inf.m = ip->m;
                   10887:        if((stat=fwrite(&inf,sizeof(InterpF),1,fp))!=1)
                   10888:                abort("fwrb_interp: can't fwrite, status %d",stat);
                   10889: #if dbg_fwrb_toa
                   10890:        err("fwrb_interp: %s",interp_toa(ip));
                   10891: #endif
                   10892:        }
                   10893: #endif
                   10894: 
                   10895: /** Run handling:
                   10896:        alloc_run_pool -create pool of free run records
                   10897:        free_run_pool - free entire pool
                   10898:        alloc_run -     allocate a new run from pool
                   10899:        free_run -      free a specified run (into pool)
                   10900:        err_run -       print Run (ascii) to stderr
                   10901:        err_runb -      print Run (ascii) to stderr (after added to blob set)
                   10902:        err_runf -      print RunF (ascii) to stderr (after added to blob set)
                   10903:        err_runfs -     print RunFS (ascii) to stderr (after added to blob set)
                   10904:        err_run_stats - report statistics to stderr
                   10905:    **/
                   10906: 
                   10907: /* RunPool functions: variable-size pool, speed-optimized alloc/free */
                   10908: 
                   10909: /* Initialize pool of Runs with increment `incr' (return F if can't allocate) */
                   10910: boolean alloc_run_pool(incr,dbg)
                   10911:     int incr;
                   10912:     boolean dbg;       /* trace actions on Runs */
                   10913: {   register Run *crp, *prp;
                   10914:     register int i;
                   10915:        _RunPool.incr = incr;
                   10916:        _RunPool.pools = 1;
                   10917:        if((_RunPool.pool=(Run **)malloc(_RunPool.pools*sizeof(Run *)))==NULL)
                   10918:                return(F);
                   10919:        if((_RunPool.pool[_RunPool.pools-1] =
                   10920:            (Run *)malloc(_RunPool.incr*sizeof(Run)))==NULL) {
                   10921:                free(_RunPool.pool);
                   10922:                return(F);
                   10923:                };
                   10924:        _RunPool.next = 0;
                   10925:        _RunPool.free = NULL;
                   10926: #if STATS
                   10927:        _RunPool.total = 0;
                   10928: #endif
                   10929:        _RunPool.dbg = dbg;
                   10930:        if(_RunPool.dbg) err("alloc_run_pool: incr%d",_RunPool.incr);
                   10931:        return(T);
                   10932:        }
                   10933: 
                   10934: free_run_pool()
                   10935: {   register int i;
                   10936:        for(i=0; i<_RunPool.pools; i++) free(_RunPool.pool[i]);
                   10937:        free(_RunPool.pool);
                   10938:        }
                   10939: 
                   10940: /* The ``hard'' case of allocating runs from RunPool: can't be inline */
                   10941: Run *hard_alloc_run()
                   10942: {      _RunPool.pools++;
                   10943:        if((_RunPool.pool=
                   10944:                (Run **)realloc(_RunPool.pool,_RunPool.pools*sizeof(Run *)))==NULL)
                   10945:                abort("alloc_Run: can't realloc");
                   10946:        if((_RunPool.cur=_RunPool.pool[_RunPool.pools-1] =
                   10947:            (Run *)malloc(_RunPool.incr*sizeof(Run)))==NULL)
                   10948:                abort("alloc_Run: can't malloc");
                   10949:        _RunPool.next=1;
                   10950:        *(_RunPool.cur) = empty_Run;
                   10951:        return(_RunPool.cur);
                   10952:        }
                   10953: 
                   10954: int rp_tod(rp)
                   10955:     Run *rp;
                   10956: {      return((int)rp);
                   10957:        }
                   10958: 
                   10959: char *runf_toa(rp)
                   10960:     RunF *rp;
                   10961: {  static char s[80];
                   10962:    char s1[80];
                   10963:        strcpy(s,"RunF ");
                   10964:        if(rp==NULL) strcat(s,"NULL");
                   10965:        else {  sprintf(s1,
                   10966:                        "y%d,x[%d,%d] lag(ad%d,bd%d ac%d,bc%d)",
                   10967:                        rp->y,rp->xs,rp->xe, 
                   10968:                        rp->ad,rp->bd, rp->ac,rp->bc );
                   10969:                strcat(s,s1);
                   10970:                };
                   10971:        return(s);
                   10972:        }
                   10973: 
                   10974: char *runfs_toa(rp)
                   10975:     RunFS *rp;
                   10976: {  static char s[80];
                   10977:    char s1[80];
                   10978:        strcpy(s,"RunFS ");
                   10979:        if(rp==NULL) strcat(s,"NULL");
                   10980:        else {  sprintf(s1,
                   10981:                        "y%d,x[%d,%d] lag(ad%d,bd%d ac%d,bc%d)",
                   10982:                        rp->y,rp->xs,rp->xe, 
                   10983:                        rp->ad,rp->bd, rp->ac,rp->bc );
                   10984:                strcat(s,s1);
                   10985:                };
                   10986:        return(s);
                   10987:        }
                   10988: 
                   10989: err_run(s,rp)
                   10990:        char *s;
                   10991:        Run *rp;
                   10992: {      fprintf(stderr,"%s ",s);
                   10993:        if(rp==NULL) fprintf(stderr,"Run NULL.\n");
                   10994:        else fprintf(stderr,
                   10995:                "Run %d: y%d,x[%d,%d] l(n%d) t(o%x ad%d,bd%d ac%d,bc%d)\n",
                   10996:                rp_tod(rp), rp->y,rp->xs,rp->xe, 
                   10997:                rp_tod(rp->n),
                   10998: #if CPU!=CRAY
                   10999:                (int)rp->u.o,
                   11000: #else
                   11001:                0,
                   11002: #endif
                   11003:                rp->ad,rp->bd,
                   11004:                rp_tod(rp->ac),
                   11005:                rp_tod(rp->bc) );
                   11006:        }
                   11007: 
                   11008: /* print Run after it has been added to Blob set */
                   11009: err_runb(s,rp)
                   11010:        char *s;
                   11011:        Run *rp;
                   11012: {      fprintf(stderr,"%s ",s);
                   11013:        if(rp==NULL) fprintf(stderr,"Run NULL.\n");
                   11014:        else fprintf(stderr,
                   11015:                "Run %d: y%d,x[%d,%d] l(n%d) t(no%d ad%d,bd%d ac%d,bc%d)\n",
                   11016:                rp_tod(rp), rp->y,rp->xs,rp->xe, 
                   11017:                rp_tod(rp->n),
                   11018:                rp->u.no, rp->ad,rp->bd, rp_tod(rp->ac),rp_tod(rp->bc) );
                   11019:        }
                   11020: 
                   11021: err_runf(s,rp)
                   11022:        char *s;
                   11023:        RunF *rp;
                   11024: {      fprintf(stderr,"%s ",s);
                   11025:        if(rp==NULL) fprintf(stderr,"RunF NULL.\n");
                   11026:        else fprintf(stderr,
                   11027:                "RunF: y%d,x[%d,%d] t(ad%d,bd%d ac%d,bc%d)\n",
                   11028:                rp->y,rp->xs,rp->xe, 
                   11029:                rp->ad,rp->bd, rp->ac,rp->bc );
                   11030:        }
                   11031: 
                   11032: err_runfs(s,rp)
                   11033:        char *s;
                   11034:        RunFS *rp;
                   11035: {   RunF rf;
                   11036:        rf.y = 0377&rp->y;
                   11037:        rf.xs = 0377&rp->xs;
                   11038:        rf.xe = 0377&rp->xe;
                   11039:        rf.ad = 0377&rp->ad;
                   11040:        rf.bd = 0377&rp->bd;
                   11041:        rf.ac = 0377&rp->ac;
                   11042:        rf.bc = 0377&rp->bc;
                   11043:        err_runf(s,&rf);
                   11044:        }
                   11045: 
                   11046: int runs_of_blob(p,ra,max)
                   11047:     Blob *p;
                   11048:     RLE_Yrun *ra;
                   11049:     int max;
                   11050: {   int runs,ri;
                   11051:     RunF *rfp;
                   11052:        runs = p->runs;
                   11053:        if(runs>max) {
                   11054:                err("runs_of_blob: max exceeded - skip this blob");
                   11055:                runs = 0;
                   11056:                }
                   11057:        else if(runs>0) {
                   11058:                if(p->ident&Runs_ff) {
                   11059:                        for(ri=0,rfp=p->r.ff; ri<runs; ri++,rfp++) {
                   11060:                                ra->y = p->bx.a.y + rfp->y;
                   11061:                                ra->xs = p->bx.a.x + rfp->xs;
                   11062:                                ra->xe = p->bx.a.x + rfp->xe;
                   11063:                                ra++;
                   11064:                                };
                   11065:                        }
                   11066:                else {  err("runs_of_blob: handle only Runs_ff - skip this blob");
                   11067:                        runs = 0;
                   11068:                        };
                   11069:                };
                   11070:        return(runs);
                   11071:        }
                   11072: 
                   11073: int no_runs_of_blobl(p)
                   11074:     Blobl *p;
                   11075: {   int runs;
                   11076:     Blob *pp;
                   11077:        runs = 0;
                   11078:        if(p->mny>0) for(pp=p->fi; pp!=NULL; pp=pp->n) runs += pp->runs;
                   11079:        return(runs);
                   11080:        }
                   11081: 
                   11082: int runs_of_blobl(p,ra,max)
                   11083:     Blobl *p;
                   11084:     RLE_Yrun *ra;
                   11085:     int max;
                   11086: {   int runs;
                   11087:     Blob *pp;
                   11088:        runs = 0;
                   11089:        if(p->mny>0) for(pp=p->fi; pp!=NULL; pp=pp->n)
                   11090:                runs += runs_of_blob(pp,ra+runs,max-runs);
                   11091:        return(runs);
                   11092:        }
                   11093: 
                   11094: int no_runs_of_char(p)
                   11095:     Char *p;
                   11096: {   int runs;
                   11097:     Blobl bl;
                   11098:        runs = 0;
                   11099:        bl.mny = p->bmny;  bl.fi = p->fi;
                   11100:        runs += no_runs_of_blobl(&bl);
                   11101:        return(runs);
                   11102:        }
                   11103: 
                   11104: int runs_of_char(p,ra,max)
                   11105:     Char *p;
                   11106:     RLE_Yrun *ra;
                   11107:     int max;
                   11108: {   int runs;
                   11109:     Blobl bl;
                   11110:        runs = 0;
                   11111:        bl.mny = p->bmny;  bl.fi = p->fi;
                   11112:        runs += runs_of_blobl(&bl,ra,max);
                   11113:        return(runs);
                   11114:        }
                   11115: 
                   11116: /* ascending lexicographic order on y,xs */
                   11117: int rn_asc(r1,r2)
                   11118:    RLE_Yrun *r1,*r2;
                   11119: {      if(r1->y < r2->y) return(-1);
                   11120:        else if(r1->y==r2->y) {
                   11121:                if(r1->xs < r2->xs) return(-1);
                   11122:                else if (r1->xs == r2->xs) return(0);
                   11123:                else return(1);
                   11124:                }
                   11125:        else return(1);
                   11126:        }
                   11127: 
                   11128: RLE_Lines *rlines_of_char(chp)
                   11129:     Char *chp;
                   11130: {   static RLE_Lines rls;
                   11131:     int no_runs,cy,ri;
                   11132:     RLE_Run *lr;
                   11133:     RLE_Yrun *ra,*cr;
                   11134:     RLE_Line *cl;
                   11135:        /* count runs */
                   11136:        no_runs = no_runs_of_char(chp);
                   11137:        /* allocate runs array */
                   11138:        if((ra=(RLE_Yrun *)malloc(no_runs*sizeof(RLE_Yrun)))==NULL)
                   11139:                abort("rlines_of_char: can't malloc ra[%d]",no_runs);
                   11140:        runs_of_char(chp,ra,no_runs);
                   11141:        /* sort runs ascending on (y,xs) */
                   11142:        qsort(ra,no_runs,sizeof(RLE_Yrun),rn_asc);
                   11143:        /* count RLE_lines.mny */
                   11144:        rls.mny = 0; cy=Scoor_MIN;
                   11145:        for(ri=0,cr=ra; ri<no_runs; ri++,cr++)
                   11146:                if(cr->y!=cy) {
                   11147:                        rls.mny++;
                   11148:                        cy = cr->y;
                   11149:                        };
                   11150:        /* allocate RLE_lines */
                   11151:        if((rls.rla=(RLE_Line *)malloc(rls.mny*sizeof(RLE_Line)))==NULL)
                   11152:                abort("rlines_of_page: can't malloc rls.rla[%d]",rls.mny);
                   11153:        /* fill in RLE_lines */
                   11154:        cy=Scoor_MIN;  cl=rls.rla-1;
                   11155:        for(ri=0,cr=ra; ri<no_runs; ri++,cr++) {
                   11156:                if(cr->y!=cy) {
                   11157:                        cl++;
                   11158:                        cl->y = cy = cr->y;
                   11159:                        cl->runs = 0;
                   11160:                        lr = cl->r;
                   11161:                        };
                   11162:                lr->xs = cr->xs;  lr->xe = cr->xe;  lr++;  cl->runs++;
                   11163:                };
                   11164:        free(ra);
                   11165:        return(&rls);
                   11166:        }
                   11167: 
                   11168: int asc_merit(m1,m2)
                   11169:     Merit *m1,*m2;
                   11170: {      if(*m1 < *m2) return(-1);
                   11171:        else if(*m1 > *m2) return(1);
                   11172:        else return(0);
                   11173:        }
                   11174: 
                   11175: /* Word merit is computed as a function of the merit of its Chars.
                   11176:    No Chars forces merit to 0.0.
                   11177:    The result is dominated by the weakest merit in the Word, slightly
                   11178:    improved by the others. */
                   11179: Merit wordmerit(w)
                   11180:     Word *w;
                   11181: {   register Char *cp,**cpp;
                   11182:     static int m_alloc = 0;
                   11183:     static Merit *ma;  /* ma[m_alloc] */
                   11184:     int mi;
                   11185:     Merit m;
                   11186:     double wgt,sumwgt;
                   11187:     
                   11188:        if(w->cs.mny<=0) return(0.0);
                   11189:        if(w->cs.mny>m_alloc) {
                   11190:                if(m_alloc==0) {
                   11191:                        m_alloc=w->cs.mny;
                   11192:                        if((ma=(Merit *)malloc(m_alloc*sizeof(Merit)))==NULL)
                   11193:                                abort("wordmerit: can't malloc ma[%d]",m_alloc);
                   11194:                        }
                   11195:                else {  m_alloc=w->cs.mny;
                   11196:                        if((ma=(Merit *)realloc(ma,m_alloc*sizeof(Merit)))==NULL)
                   11197:                                abort("wordmerit: can't realloc ma[%d]",m_alloc);
                   11198:                        };
                   11199:                };
                   11200:        for(cp= *(cpp=w->cs.cpa),mi=0; cp!=NULL; cp= *(++cpp),mi++) {
                   11201:                if(cp->area==0 || cp->il.mny==0) ma[mi]=0.0;
                   11202:                else ma[mi] = cp->il.fi->m;
                   11203:                };
                   11204:        qsort(ma,w->cs.mny,sizeof(Merit),asc_merit);
                   11205: #define DOM (5.0)
                   11206:        /* The worst merit is DOM times more significant than second worst, which
                   11207:           is DOM times more significant than the third worst, and so on.
                   11208:           */
                   11209:        m=ma[0];  sumwgt=wgt=1.0;
                   11210:        for(mi=1; mi<w->cs.mny; mi++) {
                   11211:                m += ma[mi]*(wgt /= DOM);  sumwgt += wgt;
                   11212:                };
                   11213:        m /= sumwgt;
                   11214:        return(m);
                   11215:        }
                   11216: 
                   11217: WordSet *alloc_wordset(top,cut,cap)
                   11218:     double top;                /* initial maximum merit (is never reduced) */
                   11219:     double cut;                /* cut ratio:  don't keep merit < cut*top */
                   11220:     int cap;           /* capacity: maximum no. at a time (0 ==> no limit) */
                   11221: {   WordSet *res;
                   11222:        if((res=(WordSet *)malloc(sizeof(WordSet)))==NULL)
                   11223:                abort("alloc_wordset: can't");
                   11224:        *res = empty_WordSet;
                   11225:        res->top = top;
                   11226:        res->cut = cut;
                   11227:        if((res->cap = cap)==0) res->cap=INT_MAX;
                   11228:        return(res);
                   11229:        }
                   11230: 
                   11231: int free_wordset_etc(s,etc)
                   11232:     WordSet *s;
                   11233:     Ident etc;
                   11234: {   int high;
                   11235:        free_words_etc(&(s->ws),etc);
                   11236:        high = s->high;
                   11237:        free(s);
                   11238:        return(high);
                   11239:        }
                   11240: 
                   11241: /* Find the maximum-merit word in the set; among ties, pick the first seen. */
                   11242: Word *find_max_wordset(s)
                   11243:     WordSet *s;
                   11244: {   register Word *max,**wpp;
                   11245:        max=NULL;
                   11246:        if(s->ws.mny>0) for(wpp=s->ws.wpa; *wpp!=NULL; wpp++) {
                   11247:                if(max==NULL || max->m < (*wpp)->m) max=(*wpp);
                   11248:                };
                   11249:        return(max);
                   11250:        }
                   11251: 
                   11252: /* Find the maximum-merit word in the set; among ties, pick the last seen. */
                   11253: Word *find_min_wordset(s)
                   11254:     WordSet *s;
                   11255: {   register Word *min,**wpp;
                   11256:        min=NULL;
                   11257:        if(s->ws.mny>0) for(wpp=s->ws.wpa; *wpp!=NULL; wpp++) {
                   11258:                if(min==NULL || min->m >= (*wpp)->m) min=(*wpp);
                   11259:                };
                   11260:        return(min);
                   11261:        }
                   11262: 
                   11263: /* Insert a Word (without duplicating it).
                   11264:    Update top, min, max, & high.
                   11265:    If the new word's merit is equal to the current maximum, it does not become
                   11266:    become the new maximum.
                   11267:    If the new word's merit is equal to the current minimum, it becomes
                   11268:    the new minimum.
                   11269:    */
                   11270: put_wordset(w,s)
                   11271:     Word *w;   /* must have w->m set up */
                   11272:     WordSet *s;
                   11273: {      insert_word(w,&(s->ws));
                   11274:        if(max_wordset(s)==NULL || max_wordset(s)->m < w->m) {
                   11275:                max_wordset(s) = w;
                   11276:                if(s->top < max_wordmerit(s)) s->top = max_wordmerit(s);
                   11277:                };
                   11278:        if(min_wordset(s)==NULL || min_wordset(s)->m >= w->m)
                   11279:                min_wordset(s) = w;
                   11280:        if(s->high < s->ws.mny) s->high = s->ws.mny;
                   11281:        }
                   11282: 
                   11283: /* Remove a Word (without freeing it). Maintain min/max, but don't prune items.
                   11284:    Also, don't lower top or high. */
                   11285: Word *get_wordset(w,s)
                   11286:     Word *w;
                   11287:     WordSet *s;
                   11288: {      if(w==NULL || s->ws.mny==0) return(NULL);
                   11289:        remove_word(w,&s->ws);
                   11290:        if(s->ws.mny==0) {
                   11291:                max_wordset(s) = NULL;
                   11292:                min_wordset(s) = NULL;
                   11293:                }
                   11294:        else {  if(w==max_wordset(s)) max_wordset(s) = find_max_wordset(s);
                   11295:                if(w==min_wordset(s)) min_wordset(s) = find_min_wordset(s);
                   11296:                };
                   11297:        return(w);
                   11298:        }
                   11299: 
                   11300: /* Remove a Word (without freeing it).  Maintain min/max.  Don't lower top. */
                   11301: Word *remove_wordset(w,s,n)
                   11302:     Word *w;
                   11303:     WordSet *s;
                   11304:     char *n;
                   11305: {   register Word *gw;
                   11306: #if dbg_ws
                   11307:        if(w!=NULL) err("remove_wordset: %X %s",w,word_toa(w));
                   11308:        else err("remove_wordset: NULL");
                   11309: #endif
                   11310:        gw=get_wordset(w,s);
                   11311: #if dbg_ws
                   11312:        err_wordset(s,n);
                   11313: #endif
                   11314:        return(gw);
                   11315:        }
                   11316: 
                   11317: /* Check whether a given Word is identical to any already in a given set.
                   11318:    Word *w must have its hash key set up. */
                   11319: boolean member_wordset(w,s)
                   11320:     Word *w;
                   11321:     WordSet *s;
                   11322: {   register Word **ww;
                   11323:        if(s->ws.mny>0) {
                   11324:                for(ww=s->ws.wpa; (*ww)!=NULL; ww++) {
                   11325:                        if(w->hash==(*ww)->hash && eq_word(w,(*ww)))
                   11326:                                return(T);
                   11327:                        };
                   11328:                };
                   11329:        return(F);
                   11330:        }
                   11331: 
                   11332: /* Insert a Word into a set, maintaining uniqueness, a ``range'' property, and
                   11333:    a maximum capacity.
                   11334:    Uniqueness is maintained by refusing to insert words that are identical
                   11335:    (eq_word()) to a word already in the set (or in set `u').
                   11336:    The range property is that every word in the set must have merit no less
                   11337:    than `s->cut' times the lifetime maximum for the set `s->top'.
                   11338:    Maximum capacity is maintained as follows:  if insertion would mean more
                   11339:    members than `cap', then either (a) the insertion is refused (if its
                   11340:    merit is less than the current `min', or (b) the current `min' is deleted
                   11341:    (and silently freed in its entirety), and the insertion occurs.
                   11342:    The inserted Word is not duplicated.  If, as a result of an insertion,
                   11343:    some of its words no longer satisfy the range property, they are silently
                   11344:    removed (and freed in their entirety).
                   11345:    Return T iff the Word is actually inserted.
                   11346:    */
                   11347: boolean insert_wordset(w,s,n,u)
                   11348:     Word *w;
                   11349:     WordSet *s;
                   11350:     char *n;   /* name of set `s' */
                   11351:     WordSet *u;        /* if !=NULL, also check uniqueness here */
                   11352: {   Word *fr;
                   11353: #if dbg_ws
                   11354:        err("insert_wordset: %X %s",w,word_toa(w));
                   11355: #endif
                   11356:        if((w->m = wordmerit(w)) >= (s->cut * s->top)) {
                   11357:                w->hash = hash_word(w);
                   11358:                if(member_wordset(w,s) || (u!=NULL&&member_wordset(w,u)))
                   11359:                        /* don't insert */
                   11360:                        return(F);
                   11361:                if(s->ws.mny==s->cap) /* at capacity */ {
                   11362:                        if(w->m <= min_wordmerit(s)) /* too poor */ return(F);
                   11363:                        else {  fr = remove_wordset(min_wordset(s),s);
                   11364:                                free_word_etc(fr,IsALL);
                   11365:                                };
                   11366:                        };
                   11367:                put_wordset( w, s );
                   11368:                if(max_wordset(s)==w) /* this has become the new maximum */ {
                   11369:                        while(min_wordmerit(s) < (s->cut * s->top)) {
                   11370:                                fr = remove_wordset(min_wordset(s),s);
                   11371:                                free_word_etc(fr,IsALL);
                   11372:                                };
                   11373:                        };
                   11374: #if dbg_ws
                   11375:                err_wordset(s,n);
                   11376: #endif
                   11377:                return(T);
                   11378:                }
                   11379:        else {
                   11380: #if dbg_ws
                   11381:                err_wordset(s,n);
                   11382: #endif
                   11383:                return(F);
                   11384:                };
                   11385:        }
                   11386: 
                   11387: err_wordset(s,n)
                   11388:     WordSet *s;
                   11389:     char *n;   /* name of set */
                   11390: {   char m1[10],m2[10];
                   11391:     register Word *wp,**wpp;
                   11392:        fprintf( stderr,"WordSet %s: t%g c%g [%s/%X,%s/%X] m%d h%d: ",
                   11393:                n,
                   11394:                s->top,s->cut,
                   11395:                strcpy(m1,merit_toa(max_wordmerit(s))),max_wordset(s),
                   11396:                strcpy(m2,merit_toa(min_wordmerit(s))),min_wordset(s),
                   11397:                s->ws.mny,s->high );
                   11398:        if(s->ws.mny>0) for(wp= *(wpp=s->ws.wpa); wp!=NULL; wp= *(++wpp))
                   11399:                fprintf(stderr,"%X/%s/%d ",wp,merit_toa(wp->m),wp->cs.mny);
                   11400:        fprintf(stderr,"\n");
                   11401:        }
                   11402: 
                   11403: translate_txtln(lp,off)
                   11404:     Txtln *lp;
                   11405:     Sp off;
                   11406: {      lp->bx = *translate_bbx(&lp->bx,off);
                   11407:        lp->basl += off.y;
                   11408:        translate_chars(lp->cs,off);
                   11409:        }
                   11410: 
                   11411: translate_chars(csp,off)
                   11412:     Chars *csp;
                   11413:     Sp off;
                   11414: {   register Char *cp,**cpp;
                   11415:        for(cp= *(cpp=csp->cpa); cp!=NULL; cp= *(++cpp))
                   11416:                translate_char(cp,off);
                   11417:        }
                   11418: 
                   11419: translate_char(cp,off)
                   11420:     Char *cp;
                   11421:     Sp off;
                   11422: {      cp->bx = *translate_bbx(&cp->bx,off);
                   11423:        translate_blobl(cp,off);
                   11424:        }
                   11425: 
                   11426: translate_blobs(b,off)
                   11427:     Blobs *b;
                   11428:     Sp off;
                   11429: {   register Blob *bp,**bpp;
                   11430:        if(b->mny>0) for ( bp= *(bpp=b->bpa); bp!=NULL; bp= *(++bpp) )
                   11431:                translate_blob(bp,off);
                   11432:        }
                   11433: 
                   11434: translate_blobl(cp,off)
                   11435:     Char *cp;
                   11436:     Sp off;
                   11437: {   int bi;
                   11438:     register Blob *bp;
                   11439:        for(bi=0,bp=cp->fi; bi<cp->bmny&&bp!=NULL; bi++,bp=bp->n)
                   11440:                translate_blob(bp,off);
                   11441:        }
                   11442: 
                   11443: translate_blob(bp,off)
                   11444:     Blob *bp;
                   11445:     Sp off;
                   11446: {      bp->bx = *translate_bbx(&bp->bx,off);
                   11447:        }
                   11448: 
                   11449: 0707070035351137141006640007620000050000010262240476773367000000700000107063Text.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   11450: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   11451: /* The copyright notice does not imply actual or intended publication. */
                   11452: /* AUTHORS:                                            */
                   11453: /*     H. S. Baird - ATT-BL MH - first versions        */
                   11454: 
                   11455: /* Text.h - typedefs, constants, and function declarations for document-images
                   11456:        (see Text.c for companion functions.)
                   11457:    INCLUDES
                   11458:        requires prior:
                   11459:                #include "stdocr.h"
                   11460:  */
                   11461: 
                   11462: #define dbg_fwrb_toa (F)       /* err("%s",R_toa()) for each record written */
                   11463: #define dbg_frdb_toa (F)       /* err("%s",R_toa()) for each record read */
                   11464: 
                   11465: #define DIM_VERSION (0)                /* current version no. of Dim-file format */
                   11466: 
                   11467: #include "Bfeats.h"
                   11468: 
                   11469: #define Ident int      /* identification bits [MUST BE >=32 bits] */
                   11470: 
                   11471: #define fwri_Ident(F,V) fwri_uint4((F),(V))
                   11472: #define frdi_Ident(F) frdi_uint4(F)
                   11473: 
                   11474: /* Ident bits */
                   11475: /* identifies external file record type(s) */
                   11476: #define IsPage         04000000000
                   11477: #define IsBlock                02000000000
                   11478: #define IsTxtln                01000000000
                   11479: #define IsWord         00020000000
                   11480: #define IsChar         00400000000
                   11481: #define IsBlob         00200000000
                   11482: #define IsRun          00100000000     /* should be IsRuns or IsLag */
                   11483: #define IsRuns         (IsRun)
                   11484: #define IsInterp       00040000000     /* Char interpretation */
                   11485: #define IsBdy          00010000000
                   11486: #define IsShapes       00004000000
                   11487: #define IsLag          00002000000
                   11488: #define IsBfeats       00001000000
                   11489: #define IsSfeats       00000400000
                   11490: #define IsWordInterp   00000200000
                   11491: /* Runs:  set in Blob records' ids.
                   11492:    At most one of these may be set in main memory.
                   11493:    Only Runs_ff or Runs_g4 may be set in peripheral file format. */
                   11494: #define Runs_f         00000010000     /* Runs are in list, starting *.r.f */
                   11495: #define Runs_ff                00000020000     /* RunFs are in array, at *.r.ff */
                   11496: #define Runs_seek      00000040000     /* Runs are still in file, at *.seek */
                   11497: #define Runs_g4                00000100000     /* Runs are in CCITT Group 4 format */
                   11498: 
                   11499: /* CCITT Group 4 format in peripheral files consists of (a) an unsigned long count,
                   11500:    then (b) that many bytes of Group 4 encoding exactly as in CCITT
                   11501:    Recommendation T.6, except that no EOFB code is appended, since the end of
                   11502:    the bitmap can be detected using the bounding box of the owning Blob.
                   11503:    Instead, the last scan line of the bitmap is merely padded to the nearest
                   11504:    full byte with '0' bits.  This compresses the representation by about
                   11505:    a factor of 8 on average, compared to RunF/RunFS encoding. */
                   11506: 
                   11507: #define IsALL (IsPage|IsBlock|IsTxtln|IsWord|IsChar|IsBlob|IsRun|IsBdy|IsInterp|IsShapes|IsLag|IsBfeats|IsSfeats|IsWordInterp)
                   11508: #define IsNONE         0
                   11509: 
                   11510: 
                   11511: /* Enable optional debugging-support code to maintain a count of selected record
                   11512:    types that are allocated using alloc_* free_* and dup_* functions.  The counts
                   11513:    are in units of records, not bytes.  By design, has no effect at all on
                   11514:    correctness.  */
                   11515: #define ALLOC_CENSUS (0)
                   11516: 
                   11517: #if ALLOC_CENSUS
                   11518: 
                   11519: typedef struct Census {
                   11520:        int Page_mny;
                   11521:        int Block_mny;
                   11522:        int Txtln_mny;
                   11523:        int Word_mny;
                   11524:        int Char_mny;
                   11525:        int Blob_mny;
                   11526:        int Run_mny;
                   11527:        int Interp_mny;
                   11528:        int Bfeats_mny;
                   11529:        int BMask_mny;
                   11530:        } Census;
                   11531: 
                   11532: #define Init_Census {0,0,0,0,0,0,0,0,0,0}
                   11533: #if MAIN
                   11534: Census empty_Census = Init_Census;
                   11535: Census _CENSUS = Init_Census;
                   11536: #else
                   11537: extern Census empty_Census;
                   11538: extern Census _CENSUS;
                   11539: #endif
                   11540: 
                   11541: #define alloc_census(id,n) _CENSUS./**/id/**/_mny += (n)
                   11542: #define free_census(id,n) _CENSUS./**/id/**/_mny -= (n)
                   11543: #define err_census(S,C) err("%s P%d B%d l%d w%d c%d b%d r%d i%d bf%d bm%d",\
                   11544:        S,(C)->Page_mny,(C)->Block_mny,(C)->Txtln_mny,(C)->Word_mny,\
                   11545:        (C)->Char_mny,(C)->Blob_mny,(C)->Run_mny,(C)->Interp_mny,\
                   11546:        (C)->Bfeats_mny,(C)->BMask_mny )
                   11547: #define err_census_all err_census("allocated: ",&(_CENSUS))
                   11548: #define err_census_rec(rp) { \
                   11549:        Census *cs;  cs = (Census *)census_rec((rp)); \
                   11550:        err_census(ident_toa((rp)->ident),cs); \
                   11551:        }
                   11552: #else
                   11553: 
                   11554: #define alloc_census(i,n)
                   11555: #define free_census(i,n)
                   11556: #define err_census(s,c)
                   11557: #define err_census_all
                   11558: #define err_census_rec(r)
                   11559: 
                   11560: #endif
                   11561: 
                   11562: 
                   11563: /* Most record types can own an ASCII label, which is simply a
                   11564:    '\0'-terminated string.  Its uses are varied. */
                   11565: #define MAX_LABEL_LEN 128      /* maximum no. characters in a label string */
                   11566: 
                   11567: #if FWRI
                   11568: 
                   11569: #if dbg_fwrb_toa
                   11570: #define fwrb_label(F,L) { \
                   11571:        fwri_str((F),(L)); \
                   11572:        err("fwrb_label: \"%s\"",(L)); \
                   11573:        }
                   11574: #else
                   11575: #define fwrb_label(F,L) { \
                   11576:        fwri_str((F),(L)); \
                   11577:        }
                   11578: #endif
                   11579: 
                   11580: #else
                   11581: 
                   11582: #if dbg_fwrb_toa
                   11583: #define fwrb_label(F,L) { \
                   11584:        fputs((L),(F)); \
                   11585:        fputc('\0',(F)); \
                   11586:        err("fwrb_label: \"%s\"",(L)); \
                   11587:        }
                   11588: #else
                   11589: #define fwrb_label(F,L) { \
                   11590:        fputs((L),(F)); \
                   11591:        fputc('\0',(F)); \
                   11592:        }
                   11593: #endif
                   11594: 
                   11595: #endif
                   11596: 
                   11597: char *frdb_label();
                   11598: 
                   11599: /* A boundary is an ordered list of vertices.
                   11600:    In some uses, it is assumed to close:  in this case, the first point
                   11601:    is not repeated at the end.
                   11602:    `vn' counts the no. vertices.  bdy_trace omits consecutive duplicates and
                   11603:    compresses horizontal and vertical runs.
                   11604:    `per' counts the no. of pixels on the 8-connected boundary.  An attempt has been
                   11605:    made not to count consecutive duplicate pixels, but this may be buggy.
                   11606:    `ren' counts the number of run-ends touched.  Each run contributes two ends,
                   11607:    even if it is one pixel long.  The sum of ren-counts among all bdys for a blob
                   11608:    should equal exactly twice the no. runs.
                   11609:    Note that vn<=per and vn<=2*ren, and (probably) ren<=per.
                   11610:    A ``smoothed'' version (courtesy of John Hobby) may be given in s[],
                   11611:    expressed in fractional pixels.
                   11612:    */
                   11613: typedef struct Bdy {
                   11614:        Ident ident;    /* shows type of boundary */
                   11615:        Bbx bx;         /* bounding box (usually relative to blob's bx.a) */
                   11616:        long per;       /* no. pixels in 8-connected perimeter */
                   11617:        int ren;        /* no. run-ends touched */
                   11618:        int vn;         /* no. distinct vertices in v[] */
                   11619:        Sp *v;          /* array of vn+1 vertices, v[0]==v[vn] (malloc space) */
                   11620:        short fr;       /* fraction of pixels used in smoothed outline */
                   11621:        int sn;         /* no. distinct smoothed vertices in s[] */
                   11622:        Sp *s;          /* array of sn+1 vertices, s[0]==s[sn] (malloc space) */
                   11623:        int an;         /* no. vertices in polygonal approximation */
                   11624:        Sp **ap;        /* approx'n: array of an ptrs into v[] (in malloc space) */
                   11625:        float err;      /* error tolerance used for approximation */
                   11626:        int hn;         /* no. vertices in convex hull of polygonal approx'n */
                   11627:        Sp ***hpp;      /* convex hull: array of hn ptrs into ap[] (malloc) */
                   11628:        struct Bdy *n;  /* for use when a member of a linked-list */
                   11629:        } Bdy;
                   11630: 
                   11631: #define Init_Bdy {IsBdy,Init_Bbx,0,0,0,NULL,1,0,NULL,0,NULL,0.0,0,NULL,NULL}
                   11632: #if MAIN
                   11633: Bdy empty_Bdy = Init_Bdy;
                   11634: #else
                   11635: extern Bdy empty_Bdy;
                   11636: #endif
                   11637: 
                   11638: #define Bdy_verts      00000000001     /* vertices */
                   11639: #define Bdy_approx     00000000002     /* polygonal approx'n */
                   11640: #define Bdy_hull       00000000004     /* convex hull */
                   11641: #define Bdy_ALL                (Bdy_verts|Bdy_approx|Bdy_hull)
                   11642: #define Bdy_ccw                00000000100     /* winding order is counter-clockwise*/
                   11643: #define Bdy_half       00000000200     /* uses half-pixel boundary points */
                   11644: 
                   11645: /* A boundaries-set is an ordered list of boundaries.
                   11646:    In some uses, they are used to enclose a connected region:  in this case,
                   11647:    all are closed, and the first is conventionally the exterior and the others
                   11648:    are interior boundaries.  The interior is then always to the left
                   11649:    of the boundary:  that is, the exterior boundary is oriented counter-
                   11650:    clockwise, and the interior boundaries clockwise */
                   11651: typedef struct Bdys {
                   11652:        int mny;        /* no. boundaries */
                   11653:        long per;       /* perimeter of all bdys */
                   11654:        Bdy *b;         /* array of boundaries (malloc space) (sometimes first) */
                   11655:        } Bdys;
                   11656: 
                   11657: #define Init_Bdys {0,0,NULL}
                   11658: #if MAIN
                   11659: Bdys empty_Bdys = Init_Bdys;
                   11660: #else
                   11661: extern Bdys empty_Bdys;
                   11662: #endif
                   11663: 
                   11664: /* A boundary edge is an ordered pair of vertices along a boundary.  It implicitly
                   11665:    describes an 8-connected sequence of pixels from a to b, inclusive.  Also
                   11666:    used for straight-line approximations to the set of pixels, and the convex hull
                   11667:    of such an approximation. */
                   11668: typedef struct BdyEdge {
                   11669:        Bdy *byp;       /* boundary to which it belongs */
                   11670:        Sp *ap,*bp;     /* ptrs into byp->v */
                   11671:        long per;       /* perimeter:  no. 8-connected pixels */
                   11672:        Pp ctr;         /* centroid */
                   11673:        Radians ang;    /* ls-fitted angle (directed roughly from a to b) */
                   11674:        Pp a;           /* endpoints a & b (with sub-pixel precision) */
                   11675:        Pp b;
                   11676:        } BdyEdge;
                   11677: 
                   11678: #define Init_BdyEdge {NULL,NULL,NULL,0,Init_Zero_Pp,0.0,Init_Zero_Pp,Init_Zero_Pp}
                   11679: #if MAIN
                   11680: BdyEdge empty_BdyEdge = Init_BdyEdge;
                   11681: #else
                   11682: extern BdyEdge empty_BdyEdge;
                   11683: #endif
                   11684: 
                   11685: /* Ordered set of BdyEdges */
                   11686: typedef struct BdyEdges {
                   11687:        int mny;
                   11688:        BdyEdge **pa;   /* NULL-terminated array of pointers to BdyEdges */
                   11689:        } BdyEdges;
                   11690: 
                   11691: #define Init_BdyEdges {0,NULL}
                   11692: #if MAIN
                   11693: BdyEdges empty_BdyEdges = Init_BdyEdges;
                   11694: #else
                   11695: extern BdyEdges empty_BdyEdges;
                   11696: #endif
                   11697: 
                   11698: /* Moments of a region (or boundary-list) of pixels */
                   11699: 
                   11700: typedef struct Moments {
                   11701:        /* 0th moment */
                   11702:        int M00;        /* area: sum of 1 */
                   11703:        /* 1st moments */
                   11704:        int M10;        /* sum of xi */
                   11705:        int M01;        /* sum of yi */
                   11706:        Pp c;           /* centroid: M10/M00, M01/M00 */
                   11707:        /* 2nd moments (relative to centroid) */
                   11708:        float M20;      /* sum of rxi*rxi */
                   11709:        float M11;      /* sum of rxi*ryi */
                   11710:        float M02;      /* sum of ryi*ryi */
                   11711:        Radians a;      /* orientation angle, in [-PI/2,PI/2) (radians) */
                   11712:        Pp d;           /* directional vector of principal axis */
                   11713:        } Moments;
                   11714: 
                   11715: #define Init_Moments {0,0,0,{0.0,0.0},0.0,0.0,0.0,0.0,{0.0,0.0}}
                   11716: #if MAIN
                   11717: Moments zero_Moments = Init_Moments;
                   11718: #else
                   11719: extern Moments zero_Moments;
                   11720: #endif
                   11721: 
                   11722: /* functions in Text.c */
                   11723: Bdy *alloc_bdy();
                   11724: Bdys *alloc_bdys();
                   11725: 
                   11726: /* functions in Bdy.c */
                   11727: Bdys *dup_bdys_etc();
                   11728: Bdy *dup_bdy_etc();
                   11729: Bdys *boundaries();
                   11730: char *moments_toa();
                   11731: Moments *bdy_moments();
                   11732: boolean fit_bdyedge();
                   11733: BdyEdge *dup_bdyedge();
                   11734: BdyEdge *append_bdyedge();
                   11735: remove_bdyedge();
                   11736: free_bdyedges();
                   11737: BdyEdges *dup_bdyedges();
                   11738: 
                   11739: /* Each Run is initially inserted into a `line set', owned by its scan Line.
                   11740:    Later, as connections are discovered, it joins a `tree set'.
                   11741:    When the forest of trees of which it is a part is finally complete, the Run
                   11742:    is removed from its `line set', and added to a `blob set'.
                   11743:    */
                   11744: 
                   11745: typedef struct Run {   /* internal (main memory) record */
                   11746:        Scoor y, xs, xe;        /* coordinates of black interval (y,[xs,xe]) */
                   11747:        struct Run *n;          /* line & blob sets: next Run */
                   11748:        unsigned short ad, bd;  /* tree set: above,below degrees (no. conn'd)*/
                   11749:        struct Run *ac, *bc;    /* tree set: above,below leftmost connections */
                   11750:        union { struct Tree *o; /* tree set: owner Tree */
                   11751:                int no;         /* blob set: sequence no. 0,1,... in set */
                   11752:                } u;            /* (overlain fields) */
                   11753:        } Run;
                   11754: 
                   11755: #define Init_Run {0,0,0,NULL,0,0,NULL,NULL}
                   11756: #if MAIN
                   11757: Run empty_Run = Init_Run;
                   11758: #else
                   11759: extern Run empty_Run;
                   11760: #endif
                   11761: 
                   11762: /* Peripheral file format.  `ac' and `bc' are relative to the position
                   11763:    of this run in the canonical run order. */
                   11764: typedef struct RunF {  /* external (peripheral file) record (full size) */
                   11765:        Scoor y, xs, xe;        /* coordinates of black interval (y,[xs,xe]) */
                   11766:        unsigned short ad, bd;  /* above,below degrees */
                   11767:        unsigned short ac, bc;  /* above,below leftmost connections (indices) */
                   11768:        } RunF;
                   11769: 
                   11770: #define Init_RunF {0,0,0,0,0,0,0}
                   11771: #if MAIN
                   11772: RunF empty_RunF = Init_RunF;
                   11773: #else
                   11774: extern RunF empty_RunF;
                   11775: #endif
                   11776: 
                   11777: #define fwri_RunF(F,P) { \
                   11778:        fwri_Scoor((F),(P)->y); \
                   11779:        fwri_Scoor((F),(P)->xs); \
                   11780:        fwri_Scoor((F),(P)->xe); \
                   11781:        fwri_uint2((F),(P)->ad); \
                   11782:        fwri_uint2((F),(P)->bd); \
                   11783:        fwri_uint2((F),(P)->ac); \
                   11784:        fwri_uint2((F),(P)->bc); \
                   11785:        }
                   11786: 
                   11787: #define frdi_RunF(F,P) ( feof(F)? 0 : ( \
                   11788:        (P)->y=frdi_Scoor(F), \
                   11789:        (P)->xs=frdi_Scoor(F), \
                   11790:        (P)->xe=frdi_Scoor(F), \
                   11791:        (P)->ad=frdi_uint2(F), \
                   11792:        (P)->bd=frdi_uint2(F), \
                   11793:        (P)->ac=frdi_uint2(F), \
                   11794:        (P)->bc=frdi_uint2(F), \
                   11795:        (ferror(F)? -errno: 1) ) )
                   11796: 
                   11797: /* In `well-behaved' text, the overwhelming majority of Blobs are small
                   11798:    enough that all their Runs can be encoded using character data fields,
                   11799:    a factor of two saving, which is important since a dense IEEE proceedings
                   11800:    page blob file would otherwise require 2.3Mbytes */
                   11801: typedef struct RunFS { /* external (peripheral file) record (small size) */
                   11802:        unsigned char y, xs, xe;/* coordinates of black interval (y,[xs,xe]) */
                   11803:        unsigned char ad, bd;   /* above,below degrees */
                   11804:        unsigned char ac, bc;   /* above,below leftmost connections (indices) */
                   11805:        } RunFS;
                   11806: 
                   11807: #define Init_RunFS {0,0,0,0,0,0,0}
                   11808: #if MAIN
                   11809: RunFS empty_RunFS = Init_RunFS;
                   11810: #else
                   11811: extern RunFS empty_RunFS;
                   11812: #endif
                   11813: 
                   11814: #define fwri_RunFS(F,P) { \
                   11815:        fwri_uint1((F),(P)->y); \
                   11816:        fwri_uint1((F),(P)->xs); \
                   11817:        fwri_uint1((F),(P)->xe); \
                   11818:        fwri_uint1((F),(P)->ad); \
                   11819:        fwri_uint1((F),(P)->bd); \
                   11820:        fwri_uint1((F),(P)->ac); \
                   11821:        fwri_uint1((F),(P)->bc); \
                   11822:        }
                   11823: 
                   11824: #define frdi_RunFS(F,P) ( feof(F)? 0: ( \
                   11825:        (P)->y=frdi_uint1(F), \
                   11826:        (P)->xs=frdi_uint1(F), \
                   11827:        (P)->xe=frdi_uint1(F), \
                   11828:        (P)->ad=frdi_uint1(F), \
                   11829:        (P)->bd=frdi_uint1(F), \
                   11830:        (P)->ac=frdi_uint1(F), \
                   11831:        (P)->bc=frdi_uint1(F), \
                   11832:        (ferror(F)? -errno: 1) ) )
                   11833: 
                   11834: /* Set of runs.  PROPOSED NEW FORMAT.  Not yet incorporated widely. */
                   11835: typedef struct Runs {
                   11836:        Ident ident;    /* IsRuns & Runs_fi, Runs_ff, Runs_fs, or Runs_sk flags */
                   11837:        int mny;        /* no. runs */
                   11838:        union { /* access to runs */
                   11839:                struct Run *fi;   /* first run of singly-linked list */
                   11840:                struct RunF *ff;  /* top of RunF[mny] array */
                   11841:                struct RunFS *fs; /* top of RunFS[mny] array */
                   11842:                long sk;          /* seek(F,seek,0) will find them in file F */
                   11843:                } r;
                   11844:        } Runs;
                   11845: 
                   11846: #define Init_Runs {IsRuns,0}   /* NOTE: can't initialize union */
                   11847: #if MAIN
                   11848: Runs empty_Runs = Init_Runs;
                   11849: #else
                   11850: extern Runs empty_Runs;
                   11851: #endif
                   11852: 
                   11853: /* INTERNAL management */
                   11854: 
                   11855: #if !MAIN
                   11856: extern
                   11857: #endif
                   11858: struct {
                   11859:        int incr;               /* size of each pool[i] */
                   11860:        int pools;              /* no. of pools allocated */
                   11861:        Run **pool;             /* malloc space Run pool[pools][0..incr-1] */
                   11862:        int next;               /* the next avail Run is:  pool[pools-1][next] */
                   11863:        Run *free;              /* head of free lifo list (NULL if none) */
                   11864:        Run *cur;               /* most-recently allocated Run */
                   11865:        int total;              /* total no. ever allocated */
                   11866:        boolean dbg;
                   11867:        } _RunPool
                   11868: #if MAIN
                   11869:        = {0,0,NULL,0,NULL,NULL,0,F}
                   11870: #endif
                   11871: ;
                   11872: 
                   11873: /* Run management routines (Text.c) */
                   11874: boolean        alloc_run_pool();
                   11875:        free_run_pool();
                   11876: Run    *hard_alloc_run();
                   11877:        err_run();
                   11878:        err_runb();
                   11879:        err_runf();
                   11880:        err_runfs();
                   11881:        err_run_stats();
                   11882: 
                   11883: /* Allocate a Run from the RunPool (returns (Run *)) -- mostly inline */
                   11884: #define alloc_run() ( _RunPool.total++, (_RunPool.free!=NULL)? \
                   11885:        (_RunPool.cur=_RunPool.free,_RunPool.free=_RunPool.cur->n, \
                   11886:                *(_RunPool.cur)=empty_Run,_RunPool.cur): \
                   11887:        ( (_RunPool.next<_RunPool.incr)? \
                   11888:          (_RunPool.cur=_RunPool.pool[_RunPool.pools-1]+(_RunPool.next++), \
                   11889:                *(_RunPool.cur)=empty_Run,_RunPool.cur): \
                   11890:          hard_alloc_run() ) )
                   11891: 
                   11892: /* Free a Run back into the RunPool -- entirely inline */
                   11893: #define free_run(rp) { (rp)->n = _RunPool.free; _RunPool.free = (rp); }
                   11894: 
                   11895: /* EXTERNAL file format:
                   11896:    If BlobF.runs is zero, then conventionally the Runs have simply been omitted.
                   11897:    The RunF.y, RunF.xs, & RunF.xe coordinates are offsets from BlobF.bx.a 
                   11898:    (their blob's left-top corner).  RunF.ac & RunF.bc index into an array of
                   11899:    only those RunF records belonging to the current BlobF, in ascending
                   11900:    lexicographic order on (RunF.y,RunF.xs) -- so that they are in the range
                   11901:    [0,BlobF.runs-1].
                   11902:  IMPROVEMENTS:
                   11903:   */
                   11904: 
                   11905: /* some subroutines are too lazy to handle indefinitely large blobs */
                   11906: #define Runs_Max 10000 
                   11907: 
                   11908: /* A Blob is (formally) a maximal 8-connected set of black pixels.
                   11909:    The connectivity algorithm finds them in strictly increasing order on
                   11910:    (y,xe) of its Run with highest (y,xe).
                   11911:    */
                   11912: 
                   11913: typedef struct Blob {  /* internal (main memory) record */
                   11914:        Ident ident;    /* identification bits */
                   11915:        Seq no;         /* blob sequence no */
                   11916:        Bbx bx;
                   11917:        long area;
                   11918:        long per;
                   11919:        struct Blob *n; /* free set: next blob */
                   11920:        Merit m;        /* Only used locally (not for peripheral file) */
                   11921:        Runs *rsp;      /* runs (not yet used) */
                   11922:        Bdys *bdsp;     /* boundaries (in malloc space); NULL if none */
                   11923:        /* presently in use (but planned to be replaced by Runs) */
                   11924:        int runs;
                   11925:        union { /* to find runs */
                   11926:                struct Run *f;          /* blob set: first run */
                   11927:                struct RunF *ff;        /* top of RunF array */
                   11928:                long seek;              /* seek(f,seek,0) will find them */
                   11929:                } r;
                   11930:        } Blob;
                   11931: 
                   11932: #define Init_Blob {IsBlob,0,Init_Bbx,0,0,NULL,0.0,NULL,NULL,0,}
                   11933: #if MAIN
                   11934: Blob empty_Blob = Init_Blob;
                   11935: #else
                   11936: extern Blob empty_Blob;
                   11937: #endif
                   11938: 
                   11939: typedef struct Blobs { /* Blob set */
                   11940:        int mny;        /* the number of pointers in set */
                   11941:        Blob **bpa;     /* pts to NULL-terminated array[mny+1] of pointers */
                   11942:        } Blobs;
                   11943: 
                   11944: #define Init_Blobs {0,NULL}
                   11945: #if MAIN
                   11946: Blobs empty_Blobs = Init_Blobs;
                   11947: #else
                   11948: extern Blobs empty_Blobs;
                   11949: #endif
                   11950: 
                   11951: /* Singly-linked list of Blobs.  Only forward `next' links Blob.n are used. */
                   11952: typedef struct Blobl { /* Blob list */
                   11953:        int mny;        /* the number in set */
                   11954:        Blob *fi;       /* to first */
                   11955:        Blob *la;       /* to last */
                   11956:        } Blobl;
                   11957: 
                   11958: #define Init_Blobl {0,NULL,NULL}
                   11959: #if MAIN
                   11960: Blobl empty_Blobl = Init_Blobl;
                   11961: #else
                   11962: extern Blobl empty_Blobl;
                   11963: #endif
                   11964: 
                   11965: typedef struct BlobF { /* external file format */
                   11966:        Ident ident;    /* identification bits: IsBlob must be set */
                   11967:        Bbx bx;
                   11968:        long area;
                   11969:        long per;
                   11970:        int runs;       /* no. runs to follow */
                   11971:        short bdys;     /* no. bdys to follow */
                   11972:        } BlobF;
                   11973: 
                   11974: /* Blob identification bits */
                   11975: #define Blob_lm                00000000001     /* touches left margin */
                   11976: #define Blob_rm                00000000002     /* touches right margin */
                   11977: #define Blob_tm                00000000004     /* touches top margin */
                   11978: #define Blob_bm                00000000010     /* touches bottom margin */
                   11979: #define Blob_chopt     00000000020     /* chopped (at the top) */
                   11980: #define Blob_chopb     00000000040     /* chopped (at the bottom) */
                   11981: #define Blob_chopl     00000002000     /* chopped (at the left) */
                   11982: #define Blob_chopr     00000004000     /* chopped (at the right) */
                   11983: #define Blob_small     00000000200     /* its runs (can be) compressed x2 */
                   11984: #define Blob_local     00000000400     /* unassigned:  avail for local pgm use */
                   11985: 
                   11986: /* INTERNAL management: */
                   11987: 
                   11988: int hi_blob_no;                /* current highest blob no */
                   11989: 
                   11990: /* Blobs are allocated from a pool of free ones */
                   11991: int blob_max;
                   11992: Blob *blob_pool;
                   11993: Blob blob_fr;          /* head of list of free blobs */
                   11994: int blob_fr_mny;
                   11995: int blob_hi;           /* high-water mark in blob pool */
                   11996: int blob_chopped;      /* total no. of blobs that were chopped */
                   11997: boolean blob_debug;    /* debug traces? */
                   11998: 
                   11999: /* EXTERNAL file format:
                   12000:    A Blob file consists of an arbitrary number of:
                   12001:        BlobF record, followed by BlobF.runs instances of:
                   12002:            RunF record
                   12003:    If BlobF.runs is zero, then conventionally the Runs have simply been omitted.
                   12004:    The RunF.y, RunF.xs, & RunF.xe coordinates are relative offsets from BlobF.bx.a 
                   12005:    (their blob's left-top corner).  RunF.ac & RunF.bc index into an array of
                   12006:    only those RunF records belonging to the current BlobF, in ascending
                   12007:    lexicographic order on (RunF.y,RunF.xs) -- so that they are in the range
                   12008:    [0,BlobF.runs-1].  If ad(or, bd)==0, the ac(or, bc) is undefined (conn sets
                   12009:    them conventionally to 0).
                   12010:    */
                   12011: 
                   12012: /* Blob management routines (conBlob.c) */
                   12013: Blob   *alloc_blob();
                   12014:        free_blob();
                   12015: boolean        alloc_blob_pool();
                   12016:        free_blob_pool();
                   12017: Blob   *alloc_pool_blob();
                   12018:        free_pool_blob();
                   12019:        out_blob();
                   12020:         fwrb_blob_etc();
                   12021: boolean frdb_blob_etc();
                   12022: boolean        frdb_runfs();
                   12023:        err_blob();
                   12024:        err_blob_runs();
                   12025:        err_blob_runfs();
                   12026:        err_blob_briefly();
                   12027:        err_blobf();
                   12028:        err_blob_stats();
                   12029: boolean        blob_small();
                   12030: 
                   12031: /* Compute height-above-baseline in ems of Char *cp w.r.t. Txtln *lp,
                   12032:    on a page of y-resolution res.  The txtln's `basl' & `size' must be set up. */
                   12033: #define char_bhgt(cp,lp,res) \
                   12034:        ((((cp)->bx.b.y - (lp)->basl)/(double)(res)*INS_PER_PT*(lp)->size))
                   12035: 
                   12036: /* an Interpretation of a Char */
                   12037: typedef struct Interp {
                   12038:        Ident ident;
                   12039:        struct Cl *clp;         
                   12040:        struct Class *clsp;
                   12041:        ClassId ci;             /* class id (font, size, name, variant) */
                   12042:        Merit mshap;            /* shape merit in [0,1] */
                   12043:        Pts size;               /* implied text size */
                   12044:        Merit msize;            /* size merit in [0,1] */
                   12045:        Scoor basl;             /* implied absolute baseline location */
                   12046:        Merit mbhgt;            /* height-above-baseline merit in [0,1] */
                   12047:        Merit m;                /* match merit (due to mshap, msize, & mbhgt) */
                   12048:        Prob p;                 /* approximate probability */
                   12049:        struct Interp *n;       /* next in singly-linked list */
                   12050:        } Interp;
                   12051: 
                   12052: #define Init_Interp {IsInterp,NULL,NULL,Init_ClassId,0.0,0.0,0.0,0,0.0,0.0,0.0,NULL}
                   12053: #if MAIN
                   12054: Interp empty_Interp = Init_Interp;
                   12055: #else
                   12056: extern Interp empty_Interp;
                   12057: #endif
                   12058: 
                   12059: /* Interp.ident flags: */
                   12060: #define Interp_spelled 00000000001     /* has passed a spelling check */
                   12061: 
                   12062: #define free_interp(i) {free((i)); free_census(Interp,1); }
                   12063: 
                   12064: typedef struct InterpF {
                   12065:        Ident ident;
                   12066:        ClassId ci;             /* class id (font, size, name, variant) */
                   12067:        Merit mshap;            /* shape merit */
                   12068:        Pts size;               /* implied text size (in points) */
                   12069:        Merit msize;            /* size merit */
                   12070:        Scoor basl;             /* implied baseline location */
                   12071:        Merit mbhgt;            /* height-above-baseline merit */
                   12072:        Merit m;                /* match merit (due to shp, siz, hgt) */
                   12073:        } InterpF;
                   12074: 
                   12075: /* a list of interpretations */
                   12076: typedef struct Interpl {
                   12077:        short mny;              /* no. in list */
                   12078:        struct Interp *fi;      /* first in list (mny==0 -> fi==NULL) */
                   12079:        } Interpl;
                   12080: 
                   12081: #define Init_Interpl {0,NULL}
                   12082: #if MAIN
                   12083: Interpl empty_Interpl = Init_Interpl;
                   12084: #else
                   12085: extern Interpl empty_Interpl;
                   12086: #endif
                   12087: 
                   12088: /* a set of interpretations */
                   12089: typedef struct Interps {
                   12090:        short mny;              /* no. in set */
                   12091:        struct Interp **pa;     /* NULL-terminated array of ptrs (malloc spc) */
                   12092:        Merit m;                /* combined merit (normalized product) */
                   12093:        } Interps;
                   12094: 
                   12095: #define Init_Interps {0,NULL,0.0}
                   12096: #if MAIN
                   12097: Interps empty_Interps = Init_Interps;
                   12098: #else
                   12099: extern Interps empty_Interps;
                   12100: #endif
                   12101: 
                   12102: typedef struct Shapes {
                   12103:        short mny;      /* no. items in set */
                   12104:        short alloc;    /* no. items that can fit in array (alloc>=mny) */
                   12105:        Nb_s *sa;       /* ptr to contiguous array (malloc space) */
                   12106:        } Shapes;
                   12107: 
                   12108: #define Init_Shapes {0,0,NULL}
                   12109: #if MAIN
                   12110: Shapes empty_Shapes = Init_Shapes;
                   12111: #else
                   12112: extern Shapes empty_Shapes;
                   12113: #endif
                   12114: 
                   12115: #define SH_INCR (20)   /* Shapes are allocated by this increment */
                   12116: 
                   12117: #define init_sh(sh) { \
                   12118:        (sh)->alloc = SH_INCR; \
                   12119:        if(((sh)->sa=(Nb_s *)malloc((sh)->alloc*sizeof(Nb_s)))==NULL) \
                   12120:                abort("can't alloc sh->sa[%d]",(sh)->alloc); \
                   12121:        (sh)->mny = 0; \
                   12122:        }
                   12123: 
                   12124: #define add_sh(s,sh) { \
                   12125:        if((sh)->mny==(sh)->alloc) { \
                   12126:                (sh)->alloc += SH_INCR; \
                   12127:                if(((sh)->sa=(Nb_s *)realloc((sh)->sa,(sh)->alloc*sizeof(Nb_s)))==NULL) \
                   12128:                        abort("can't alloc (sh)->sa[%d]",(sh)->alloc); \
                   12129:                }; \
                   12130:        (sh)->sa[(sh)->mny++] = *(s); \
                   12131:        }
                   12132: 
                   12133: /* Parameters governing the pseudo-random generation of a Char image
                   12134:    using a 1st-order statistical model of imaging. */ 
                   12135: typedef struct RanParms {
                   12136:        short res_x;    /* -r resolution (scanner pels/inch) */
                   12137:        short res_y;    /*    (for now, equal to res_x) */
                   12138:        Pts size;       /* -p size of text */
                   12139:        Radians skew;   /* -a skew angle */
                   12140:        Ems bhgt;       /* -b height above baseline */
                   12141:        float blur;     /* -e blurring std err (scanner pels) */
                   12142:        float jitter;   /* -j jitter std err (scanner pels) */
                   12143:        float kern;     /* -k kerning std err (scanner pels) */
                   12144:        float speckle;  /* -s pel-wise additive noise std err (scanner pels) */
                   12145:        float thresh;   /* -t threshold for binarization */
                   12146:        float xscale;   /* -x horizontal scaling (dimensionless) */
                   12147:        float yscale;   /* -y vertical scaling (dimensionless) */
                   12148:        } RanParms;
                   12149: #define Init_RanParms {0,0,0.0,0.0,0.0,0.7,0.0,0.0,0.125,0.25,1.0,1.0}
                   12150: #if MAIN
                   12151: RanParms empty_RanParms = Init_RanParms;
                   12152: #else
                   12153: extern RanParms empty_RanParms;
                   12154: #endif
                   12155: 
                   12156: RanParms *alloc_ranparms();
                   12157: RanParms *dup_ranparms();
                   12158: char *ranparms_toa();
                   12159: RanParms *ato_ranparms();
                   12160: fwrb_ranparms();
                   12161: int frdb_ranparms();
                   12162: 
                   12163: /* Char - a character:  isolated, elementary symbol of the writing system;
                   12164:    linguists might call this a `graph' */
                   12165: typedef struct Char {
                   12166:        Ident ident;            /* feature bits */
                   12167:        Bbx bx;
                   12168:        Scoor csp;              /* space before character in Txtln (abs. coords) */
                   12169:        long area;              /* no. pixels */
                   12170:        long per;               /* perimeter (all bdys) */
                   12171:        Scoor basl;             /* baseline (absolute coordinates, local copy) */
                   12172:        /* next should be Blobl */
                   12173:        int bmny;               /* no. blobs in Char */
                   12174:        struct Blob *fi;        /* 1st in list (p.n ptrs) (bmny==0 -> fi==NULL) */
                   12175:        Pval *sfv;              /* scalar-features (SFv) */
                   12176:        Shapes sh;              /* set of shapes (size- & loc'n-invariant) */
                   12177:        Bfeats *bfsp;           /* binary features */
                   12178:        RanParms *rp;           /* randomizing parameters */
                   12179:        Interpl il;             /* interpretations */
                   12180:        char *l;                /* label (ASCII string in malloc space) */
                   12181:        } Char;
                   12182: 
                   12183: #define Init_Char {IsChar,Init_Bbx,0,0L,0L,Scoor_MIN,0,NULL,NULL,Init_Shapes,NULL,NULL,Init_Interpl,NULL}
                   12184: #if MAIN
                   12185: Char empty_Char = Init_Char;
                   12186: #else
                   12187: extern Char empty_Char;
                   12188: #endif
                   12189: 
                   12190: /* Char.ident flags: */
                   12191: #define Char_spelled   00000000001     /* Its 1st Interp is in correct spelling */
                   12192: #define Char_confused  00000000002     /* The classifier may have confused this */
                   12193: #define Char_termhyp   00000000004     /* a terminal hyphen of its Word */
                   12194: #define Char_omit      00000000010     /* can be omitted */
                   12195: #define Char_label     00000000020     /* has an ASCII string label */
                   12196: #define Char_ranparms  00000000040     /* has RanParms */
                   12197: #define Char_split     00000000100     /* resulted from splitting a Char */
                   12198: #define Char_merged    00000000200     /* resulted from merging Chars */
                   12199: 
                   12200: typedef struct Chars {
                   12201:        int mny;        /* mny==0 -> cpa==NULL */
                   12202:        Char **cpa;     /* pts to NULL-term'd array of ptrs (in malloc space) */
                   12203:        } Chars;
                   12204: 
                   12205: #define Init_Chars {0,NULL}
                   12206: #if MAIN
                   12207: Chars empty_Chars = Init_Chars;
                   12208: #else
                   12209: extern Chars empty_Chars;
                   12210: #endif
                   12211: 
                   12212: /* CharF - Char external file format */
                   12213: typedef struct CharF {
                   12214:        Ident ident;            /* feature bits: IsChar must be set */
                   12215:        Bbx bx;
                   12216:        Scoor csp;              /* space before character in Txtln (abs. coords) */
                   12217:        long area;
                   12218:        long per;
                   12219:        short bmny;             /* no. blobs to follow */
                   12220:        short imny;             /* no. interpretations (follows immediately) */
                   12221:        short sfmny;            /* no. scalar features (follows immediately) */
                   12222:        short shmny;            /* no. shape features (follows immediately) */
                   12223:        short bfmny;            /* no. binary features (follows immediately) */
                   12224:        /* if ident&Char_ranparms, RanParms follows CharF */
                   12225:        /* if ident&Char_label, label follows CharF ('\0'-terminated string) */
                   12226:        } CharF;
                   12227: 
                   12228: Char *alloc_char();            /* in Text.c */
                   12229: Char *append_char();
                   12230: Char *insert_char();
                   12231: Char *insert_char_word();
                   12232: Char *dup_char();
                   12233: Char *dup_char_etc();
                   12234: Chars *append_chars();
                   12235: Chars *dup_chars_etc();
                   12236: 
                   12237: typedef struct Words {
                   12238:        int mny;                /* mny==0 -> wpa==NULL */
                   12239:        struct Word **wpa;      /* pts to NULL-term'd array of ptrs */
                   12240:        } Words;
                   12241: 
                   12242: #define Init_Words {0,NULL}
                   12243: #if MAIN
                   12244: Words empty_Words = Init_Words;
                   12245: #else
                   12246: extern Words empty_Words;
                   12247: #endif
                   12248: 
                   12249: /* Word - one or more Chars lying in a textline close together.
                   12250:    wsp (word space) is always >=0 and is scaled by xheight (of Txtln) */
                   12251: typedef struct Word {
                   12252:        Ident ident;            /* feature bits */
                   12253:        Bbx bx;
                   12254:        float wsp;              /* space before word (multiple of wst*em) */
                   12255:        Merit m;                /* Word merit (function of its Char's merits) */
                   12256:        Prob p;                 /* probability */
                   12257:        Words ws;               /* set of alternative segmentations */
                   12258:        Chars cs;
                   12259:        Blobs bs;
                   12260:        char *l;                /* label (ASCII string in malloc space) */
                   12261:        int hash;               /* hash key for fast equality checking */
                   12262:        } Word;
                   12263: 
                   12264: #define Init_Word {IsWord,Init_Bbx,0.0,0.0,0.0,Init_Words,Init_Chars,Init_Blobs,NULL,0}
                   12265: #if MAIN
                   12266: Word empty_Word = Init_Word;
                   12267: #else
                   12268: extern Word empty_Word;
                   12269: #endif
                   12270: 
                   12271: /* Word-interpretation (as printable ASCII string).
                   12272:    All string fields must point to malloc-space strings.
                   12273:    */
                   12274: typedef struct WordInterp {
                   12275:        Ident ident;    /* identifies word type */
                   12276:        char *s;        /* entire string = pp+by+po+ps */
                   12277:        char *pp;       /* punctuation prefix */
                   12278:        char *by;       /* body of word */
                   12279:        char *po;       /* possessive ('s 'S) or negative (n't N'T) suffix */
                   12280:        char *ps;       /* punctuation suffix */
                   12281:        } WordInterp;
                   12282: 
                   12283: #define Init_WordInterp {IsWordInterp,NULL,NULL,NULL,NULL,NULL}
                   12284: #if MAIN
                   12285: WordInterp empty_WordInterp = Init_WordInterp;
                   12286: #else
                   12287: extern WordInterp empty_WordInterp;
                   12288: #endif
                   12289: 
                   12290: WordInterp *dup_wordinterp_etc();
                   12291: 
                   12292: /* Word.ident & WordInterp.ident flags: */
                   12293: #define Word_spelled   00000000001     /* by spells correctly */
                   12294: #define Word_wf                00000000002     /* s is well-formed */
                   12295: #define Word_ok                00000000004     /* s is ok ("acceptable") */
                   12296: #define Word_numeric   00000000010     /* by is numeric */
                   12297: #define Word_initcap   00000000020     /* by has initial capital */
                   12298: #define Word_allcaps   00000000040     /* by is all caps */
                   12299: #define Word_hyphens   00000000100     /* by has imbedded hyphens */
                   12300: #define Word_slashes   00000000200     /* by has imbedded slashes */
                   12301: #define Word_endsent   00000000400     /* end of sentence: ps has .!? */
                   12302: #define Word_termhyp   00000001000     /* some interpretation ends with hyphen */
                   12303: #define Word_label     00000002000     /* has an ASCII string label */
                   12304: #define Word_allalp    00000004000     /* s is all alphabetic */
                   12305: #define Word_bodalp    00000010000     /* by is all alphabetic */
                   12306: 
                   12307: /* WordF - Word external file format */
                   12308: typedef struct WordF {
                   12309:        Ident ident;            /* feature bits: IsWord must be set */
                   12310:        Bbx bx;
                   12311:        float wsp;              /* space before word (multiple of thr) */
                   12312:        float m;                /* merit */
                   12313:        short wmny;             /* no. Words (in Word.ws) to follow this Word */
                   12314:        short cmny;             /* no. Chars to follow this Word */
                   12315:        short bmny;             /* no. Blobs to follow this Word */
                   12316:        /* if ident&Word_label, label follows WordF ('\0'-terminated string) */
                   12317:        } WordF;
                   12318: 
                   12319: /* constant pitch model for a Txtln */
                   12320: typedef struct ConstPitch {
                   12321:        Ems w;          /* Character pitch */
                   12322:        Scoor o;        /* origin (one of the character break points) */
                   12323:        float r;        /* max/min autocorrelation ratio - the larger the better */
                   12324:        } ConstPitch;
                   12325: 
                   12326: #define Init_ConstPitch {0.0,0,0.0}
                   12327: #if MAIN
                   12328: ConstPitch empty_ConstPitch = Init_ConstPitch;
                   12329: #else
                   12330: extern ConstPitch empty_ConstPitch;
                   12331: #endif
                   12332: 
                   12333: typedef struct Txtlns {
                   12334:        short mny;
                   12335:        struct Txtln **lpa;     /* to array of Txtln's (if mny==0, lpa==NULL) */
                   12336:        } Txtlns;
                   12337: 
                   12338: #define Init_Txtlns {0,NULL}
                   12339: #if MAIN
                   12340: Txtlns empty_Txtlns = Init_Txtlns;
                   12341: #else
                   12342: extern Txtlns empty_Txtlns;
                   12343: #endif
                   12344: 
                   12345: /* Text Line */
                   12346: #define Txtln_label    00000000004     /* has an ASCII string label */
                   12347: #define Txtln_size     00000000002     /* dominant text size chosen */
                   12348: #define Txtln_basl     00000000001     /* dominant baseline chosen */
                   12349: 
                   12350: typedef struct Txtln {
                   12351:        Ident ident;
                   12352:        Bbx bx;
                   12353:        Pts size;       /* dominant text size (0 means unknown) */
                   12354:        Scoor basl;     /* dominant baseline (absolute y coordinate) */
                   12355:        short *proj;    /* ptr to malloc space projection array */
                   12356:        ConstPitch *cp; /* ptr to malloc space constant-pitch model */
                   12357:        Merit m;        /* merit */
                   12358:        Txtlns ls;      /* alternative Txtln segmentations */
                   12359:        Words ws;       /* sorted asc. on x */
                   12360:        Chars cs;       /* sorted asc. on bx.a.x */
                   12361:        Blobs bs;       /* misc. non-char blobs */
                   12362:        char *l;        /* label (ASCII string in malloc space) */
                   12363:        } Txtln;
                   12364: 
                   12365: #define Init_Txtln {IsTxtln,Init_Bbx,0.0,0,NULL,NULL,0.0,Init_Txtlns,Init_Words,Init_Chars,Init_Blobs,NULL}
                   12366: #if MAIN
                   12367: Txtln empty_Txtln = Init_Txtln;
                   12368: #else
                   12369: extern Txtln empty_Txtln;
                   12370: #endif
                   12371: 
                   12372: /* Text Line */
                   12373: typedef struct TxtlnF {
                   12374:        Ident ident;    /* IsTxtln must be set */
                   12375:        Bbx bx;
                   12376:        Scoor basl;     /* baseline (absolute y coordinate) */
                   12377:        Pts size;       /* text size (<=0.0 means none is known) */
                   12378:        short pmny;     /* no. shorts in projection array to follow */
                   12379:        float m;        /* merit */
                   12380:        short lmny;     /* no. alternative txtlns to follow */
                   12381:        short wmny;     /* no. words to follow */
                   12382:        short cmny;     /* no. chars to follow */
                   12383:        int bmny;       /* no. blobs to follow */
                   12384:        /* if ident&Txtln_label, label follows TxtlnF ('\0'-terminated string) */
                   12385:        } TxtlnF;
                   12386: 
                   12387: /* blocks of text */
                   12388: typedef struct Blocks {
                   12389:        short mny;              /* if mny==0, bpa==NULL */
                   12390:        struct Block **bpa;     /* to NULL-term'd array of ptrs */
                   12391:        } Blocks;
                   12392: 
                   12393: #define Init_Blocks {0,NULL}
                   12394: #if MAIN
                   12395: Blocks empty_Blocks = Init_Blocks;
                   12396: #else
                   12397: extern Blocks empty_Blocks;
                   12398: #endif
                   12399: 
                   12400: /* block of text */
                   12401: typedef struct Block {
                   12402:        Ident ident;
                   12403:        Bbx bx;         /* bounding box of block */
                   12404:        Radians skew;   /* skew angle (as correction to Page.skew) */
                   12405:        Radians shear;  /* shear angle (as correction to Page.shear) */
                   12406:        Ems wst;        /* word-space threshhold */
                   12407:        Merit m;        /* merit */
                   12408:        Blocks bks;     /* Blocks nested within this one */
                   12409:        Txtlns ls;
                   12410:        Words ws;
                   12411:        Chars cs;
                   12412:        Blobs bs;
                   12413:        char *l;        /* label (ASCII string in malloc space) */
                   12414:        } Block;
                   12415: 
                   12416: #define Init_Block {IsBlock,Init_Bbx,0.0,0.0,0.0,0.0,Init_Blocks,Init_Txtlns,Init_Words,Init_Chars,Init_Blobs,NULL}
                   12417: #if MAIN
                   12418: Block empty_Block = Init_Block;
                   12419: #else
                   12420: extern Block empty_Block;
                   12421: #endif
                   12422: 
                   12423: /* Ident bits for Blocks */
                   12424: #define Block_wst      00000000001     /* word-space-thresh set up */
                   12425: #define Block_label    00000000002     /* has an ASCII string label */
                   12426: 
                   12427: #define Block_mb (1)
                   12428: 
                   12429: /* block of text */
                   12430: typedef struct BlockF {
                   12431:        Ident ident;    /* IsBlock must be set */
                   12432:        Bbx bx;
                   12433:        Ems wst;        /* word-space threshold */
                   12434:        float skew;
                   12435:        float shear;
                   12436: #if Block_mb
                   12437:        float m;
                   12438:        short bkmny;
                   12439: #endif
                   12440:        short lmny;
                   12441:        short wmny;
                   12442:        int cmny;
                   12443:        int bmny;
                   12444:        /* if ident&Block_label, label follows BlockF ('\0'-terminated string) */
                   12445:        } BlockF;
                   12446: 
                   12447: /* page */
                   12448: typedef struct Page {
                   12449:        Ident ident;
                   12450:        Bbx bx;                 /* extreme indices in pixels */
                   12451:        short res_x;            /* resolution in pixels/inch:  x & y */
                   12452:        short res_y;
                   12453:        Radians skew;           /* skew angle */
                   12454:        Radians shear;          /* shear correction */
                   12455:        Blocks bks;             /* blocks */
                   12456:        Txtlns ls;              /* textlines (those not in any block) */
                   12457:        Words ws;               /* words (not in any textline) */
                   12458:        Chars cs;               /* chars (not in any word) */
                   12459:        Blobs bs;               /* blobs (not in any char) */
                   12460:        char *l;                /* label (ASCII string in malloc space) */
                   12461:        } Page;
                   12462: 
                   12463: #define Init_Page {IsPage,Init_Bbx,0,0,0.0,0.0,Init_Blocks,Init_Txtlns,Init_Words,Init_Chars,Init_Blobs,NULL}
                   12464: #if MAIN
                   12465: Page empty_Page = Init_Page;
                   12466: #else
                   12467: extern Page empty_Page;
                   12468: #endif
                   12469: 
                   12470: #define Page_label     00000000001     /* has a label */
                   12471: 
                   12472: /* Pages of text */
                   12473: typedef struct Pages {
                   12474:        unsigned short mny;     /* if mny==0, pa==NULL */
                   12475:        struct Page **pa;       /* to NULL-term'd array of ptrs */
                   12476:        } Pages;
                   12477: 
                   12478: #define Init_Pages {0,NULL}
                   12479: #if MAIN
                   12480: Pages empty_Pages = Init_Pages;
                   12481: #else
                   12482: extern Pages empty_Pages;
                   12483: #endif
                   12484: 
                   12485: typedef struct PageF {
                   12486:        Ident ident;            /* IsPage bit must be set */
                   12487:        short res_x,res_y;      /* resolution in pixels/inch:  x & y */
                   12488:        Bbx bx;                 /* extreme indices in pixels */
                   12489:        float skew;             /* original page skew angle, radians */
                   12490:        float shear;            /* original page shear angle, radians */
                   12491:        short bkmny;            /* no. blocks */
                   12492:        short lmny;             /* no. textlines (not in any block) */
                   12493:        short wmny;             /* no. words (not in any textline) */
                   12494:        int cmny;               /* no. chars (not in any word) */
                   12495:        int bmny;               /* no. blobs (not in any char)) */
                   12496:        /* if ident&Page_label, label follows PageF ('\0'-terminated string) */
                   12497:        } PageF;
                   12498: 
                   12499: #define Page_new       00000000001     /* Page is in ``new'' format */
                   12500: 
                   12501: /* Each Dim-file begins with a Doc record */
                   12502: typedef struct Doc {
                   12503:        unsigned short version;         /* file format version number */
                   12504:        Pages ps;
                   12505:        char *l;                /* ASCII label */
                   12506:        } Doc;
                   12507: 
                   12508: #define Init_Doc {0,Init_Pages,NULL}
                   12509: #if MAIN
                   12510: Doc empty_Doc = Init_Doc;
                   12511: #else
                   12512: extern Doc empty_Doc;
                   12513: #endif
                   12514: 
                   12515: char *ident_toa();
                   12516: Ident cto_ident();
                   12517: Ident cto_flag();
                   12518: char *merit_toa();
                   12519: Page *alloc_page();
                   12520: char *page_toa();
                   12521: Page *dup_page();
                   12522: Page *dup_page_etc();
                   12523: Block *alloc_block();
                   12524: char *block_toa();
                   12525: Block *dup_block();
                   12526: Block *dup_block_etc();
                   12527: Block *append_block();
                   12528: Blocks *dup_blocks_etc();
                   12529: ConstPitch *alloc_constpitch();
                   12530: char *constpitch_toa();
                   12531: Txtln *alloc_txtln();
                   12532: char *txtln_toa();
                   12533: Word *alloc_word();
                   12534: char *word_toa();
                   12535: boolean eq_word();
                   12536: int hash_word();
                   12537: Char *alloc_char();
                   12538: char *char_toa();
                   12539: Pp *char_centroid();
                   12540: Char *char_of_blob();
                   12541: char *interp_toa();
                   12542: char *blob_toa();
                   12543: Pp *blob_centroid();
                   12544: char *runf_toa();
                   12545: char *runfs_toa();
                   12546: char *pp_toa();
                   12547: char *bdyedge_toa();
                   12548: Blob *dup_blob();
                   12549: Blob *dup_blob_etc();
                   12550: Blob *dup_blobl_etc();
                   12551: Blob *runs_to_runs();
                   12552: Blobs *dup_blobs_etc();
                   12553: Blobs *blobl_to_blobs();
                   12554: Interp *alloc_interp();
                   12555: Interp *dup_interp();
                   12556: Interpl *dup_interpl_etc();
                   12557: Interps *dup_interps_etc();
                   12558: Word *append_word();
                   12559: Word *insert_word();
                   12560: Word *insert_word_txtln();
                   12561: Word *dup_word();
                   12562: Word *dup_word_etc();
                   12563: Words *dup_words_etc();
                   12564: Txtln *dup_txtln();
                   12565: Txtln *dup_txtln_etc();
                   12566: Txtlns *dup_txtlns_etc();
                   12567: Block *dup_block();
                   12568: Block *dup_block_etc();
                   12569: Radians add_ang();
                   12570: Radians subtract_ang();
                   12571: 
                   12572: /* in-line macroes */
                   12573: 
                   12574: /* Merge the `source' Bbx into the `destination' Bbx, expanding the dest Bbx
                   12575:    as required.  The source Bbx is unmodified.  Usage:
                   12576:        merge_bbx(s,d)
                   12577:            Bbx *s,*d;
                   12578: */
                   12579: #define merge_bbx(s,d) { \
                   12580:        if((s)->a.x < (d)->a.x) (d)->a.x = (s)->a.x; \
                   12581:        if((s)->a.y < (d)->a.y) (d)->a.y = (s)->a.y; \
                   12582:        if((s)->b.x > (d)->b.x) (d)->b.x = (s)->b.x; \
                   12583:        if((s)->b.y > (d)->b.y) (d)->b.y = (s)->b.y; \
                   12584:        }
                   12585: 
                   12586: /* Experimental implementation of a data structure for maintaining a set
                   12587:    of distinct Words whose merit falls within a dynamically-varying range.
                   12588:    This implementation is worst-case quadratic time.
                   12589:    BUGS:  insert_wordset shouldn't duplicate the word.
                   12590:    */
                   12591: 
                   12592: #define dbg_ws (0)     /* if !=0, enable WordSet debugging tracing */
                   12593: 
                   12594: typedef struct WordSet {
                   12595:        double cut;     /* cut-fraction */
                   12596:        int cap;        /* capacity: maximum number permitted at any time */
                   12597:        double top;     /* maximum merit seen since allocation */
                   12598:        Words ws;       /* sorted by top-choice merit */
                   12599:        Word *max,*min; /* maximum/minimum entries currently in ws */
                   12600:        int high;       /* high-water:  max. no. entries in history */
                   12601:        } WordSet;
                   12602: #define Init_WordSet {1.0,INT_MAX,0.0,Init_Words,NULL,NULL,0}
                   12603: #if MAIN
                   12604: WordSet empty_WordSet = Init_WordSet;
                   12605: #else
                   12606: extern WordSet empty_WordSet;
                   12607: #endif
                   12608: 
                   12609: #define size_wordset(s) ((s)->ws.mny)
                   12610: #define top_wordset(s) ((s)->top)
                   12611: #define max_wordset(s) ((s)->max)
                   12612: #define min_wordset(s) ((s)->min)
                   12613: #define max_wordmerit(s) ((max_wordset((s))!=NULL)? (max_wordset((s)))->m: 0.0)
                   12614: #define min_wordmerit(s) ((min_wordset((s))!=NULL)? (min_wordset((s)))->m: 0.0)
                   12615: 
                   12616: Merit wordmerit();
                   12617: WordSet *alloc_wordset();
                   12618: boolean insert_wordset();
                   12619: Word *remove_wordset();
                   12620: int free_wordset_etc();
                   12621: err_wordset();
                   12622: 0707070035351137151006640007620000050000010263160476773367000001000000001554Units.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   12623: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   12624: /* The copyright notice does not imply actual or intended publication. */
                   12625: /* AUTHORS:                                            */
                   12626: /*     H. S. Baird - ATT-BL MH - first versions        */
                   12627: 
                   12628: #define UNITS "icpPsu" /* units notation for:  inches, cm, points, picas,
                   12629:                           scanner pixel (Scoor), and basic unit (also Scoor) */
                   12630: 
                   12631: #define INCHES_PER_POINT (0.0138)      /* cf. Chicago Manual of Style */
                   12632: 
                   12633: #define RADIANS_PER_DEGREE (PI/180.0)
                   12634: #define DtoR (RADIANS_PER_DEGREE)      /* degrees * DtoR = radians */
                   12635: 
                   12636: #define Radians double         /* angle in radians */
                   12637: 
                   12638: /* machine-independent I/O has a resolution of 0.1 second of arc */
                   12639: #define fwri_Radians(F,V) fwri_int3((F),(V)*2062648.1)
                   12640: #define frdi_Radians(F) (frdi_int3(F)/(Radians)2062648.1)
                   12641: 0707070035351137161006640007620000050000010263200476773367000001000000012421abort.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   12642: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   12643: /* The copyright notice does not imply actual or intended publication. */
                   12644: /* AUTHORS:                                            */
                   12645: /*     H. S. Baird - ATT-BL MH - first versions        */
                   12646: 
                   12647: /* abort.h - three terse message, warning, and abort functions.
                   12648:        out(s,a,...)     print message to stdout
                   12649:        err(s,a,...)     print warning to stderr
                   12650:        abort(s,a,...)   complain to stderr and exit abnormally.
                   12651:    The 's' argument is a printf string, and the 'a',... are (up to 15) arguments
                   12652:    matching %-fields.  These routines prefix the program name and append `\n' to
                   12653:    the printf string, then write to:
                   12654:          `out': stdout
                   12655:          `err' & `abort': stderr
                   12656:    Abort also says " - abort", and exits abnormally.
                   12657:    This #include should be preceded by `#define CMDNAME "xxx"'  so that `xxx:'
                   12658:    will be prefixed to msg and abort strings. */
                   12659: 
                   12660: #ifndef CMDNAME
                   12661: #define CMDNAME "hsb"
                   12662: #endif
                   12663: 
                   12664: #define MSGMAX 120
                   12665: 
                   12666: #ifndef boolean
                   12667: #define boolean int
                   12668: #define T 1
                   12669: #define F 0
                   12670: #endif
                   12671: 
                   12672: /* WARNING: these function-call versions do not port well:
                   12673:    e.g. floating-point arguments are botched on MIPS and SGI machines */
                   12674: 
                   12675: out(s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15)
                   12676:     char *s;
                   12677: {   static char m[MSGMAX];
                   12678:        strcpy(m,CMDNAME);
                   12679:        strcat(m,": ");
                   12680:        strcat(m,s);
                   12681:        strcat(m,"\n");
                   12682:        fprintf(stdout,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15);
                   12683:        }
                   12684: 
                   12685: err(s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15)
                   12686:     char *s;
                   12687: {   char m[MSGMAX];
                   12688:        strcpy(m,CMDNAME);
                   12689:        strcat(m,": ");
                   12690:        strcat(m,s);
                   12691:        strcat(m,"\n");
                   12692:        fprintf(stderr,m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15);
                   12693:        }
                   12694: 
                   12695: abort(s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15)
                   12696:     char *s;
                   12697: {   static char m[MSGMAX];
                   12698:        strcpy(m,s);
                   12699:        strcat(m," - abort");
                   12700:        err(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15);
                   12701:        exit(1);
                   12702:        }
                   12703: 
                   12704: /* These hybrid macro/function forms ports well, but are awkward to use... */
                   12705: 
                   12706: char *_F(s)
                   12707:    char *s;
                   12708: {  static char m[MSGMAX];
                   12709:        strcpy(m,CMDNAME);
                   12710:        strcat(m,": ");
                   12711:        strcat(m,s);
                   12712:        strcat(m,"\n");
                   12713:        return(m);
                   12714:        }
                   12715: 
                   12716: #define out0(Z) fprintf(stdout,_F(Z))
                   12717: #define out1(Z,A) fprintf(stdout,_F(Z),A)
                   12718: #define out2(Z,A,B) fprintf(stdout,_F(Z),A,B)
                   12719: #define out3(Z,A,B,C) fprintf(stdout,_F(Z),A,B,C)
                   12720: #define out4(Z,A,B,C,D) fprintf(stdout,_F(Z),A,B,C,D)
                   12721: #define out5(Z,A,B,C,D,E) fprintf(stdout,_F(Z),A,B,C,D,E)
                   12722: #define out6(Z,A,B,C,D,E,F) fprintf(stdout,_F(Z),A,B,C,D,E,F)
                   12723: #define out7(Z,A,B,C,D,E,F,G) fprintf(stdout,_F(Z),A,B,C,D,E,F,G)
                   12724: #define out8(Z,A,B,C,D,E,F,G,H) fprintf(stdout,_F(Z),A,B,C,D,E,F,G,H)
                   12725: #define out9(Z,A,B,C,D,E,F,G,H,I) fprintf(stdout,_F(Z),A,B,C,D,E,F,G,H,I)
                   12726: #define out10(Z,A,B,C,D,E,F,G,H,I,J) fprintf(stdout,_F(Z),A,B,C,D,E,F,G,H,I,J)
                   12727: #define out11(Z,A,B,C,D,E,F,G,H,I,J,K) fprintf(stdout,_F(Z),A,B,C,D,E,F,G,H,I,J,K)
                   12728: 
                   12729: #define err0(Z) fprintf(stderr,_F(Z))
                   12730: #define err1(Z,A) fprintf(stderr,_F(Z),A)
                   12731: #define err2(Z,A,B) fprintf(stderr,_F(Z),A,B)
                   12732: #define err3(Z,A,B,C) fprintf(stderr,_F(Z),A,B,C)
                   12733: #define err4(Z,A,B,C,D) fprintf(stderr,_F(Z),A,B,C,D)
                   12734: #define err5(Z,A,B,C,D,E) fprintf(stderr,_F(Z),A,B,C,D,E)
                   12735: #define err6(Z,A,B,C,D,E,F) fprintf(stderr,_F(Z),A,B,C,D,E,F)
                   12736: #define err7(Z,A,B,C,D,E,F,G) fprintf(stderr,_F(Z),A,B,C,D,E,F,G)
                   12737: #define err8(Z,A,B,C,D,E,F,G,H) fprintf(stderr,_F(Z),A,B,C,D,E,F,G,H)
                   12738: #define err9(Z,A,B,C,D,E,F,G,H,I) fprintf(stderr,_F(Z),A,B,C,D,E,F,G,H,I)
                   12739: #define err10(Z,A,B,C,D,E,F,G,H,I,J) fprintf(stderr,_F(Z),A,B,C,D,E,F,G,H,I,J)
                   12740: #define err11(Z,A,B,C,D,E,F,G,H,I,J,K) fprintf(stderr,_F(Z),A,B,C,D,E,F,G,H,I,J,K)
                   12741: 
                   12742: char *_G(s)
                   12743:    char *s;
                   12744: {  static char m[MSGMAX];
                   12745:        strcpy(m,CMDNAME);
                   12746:        strcat(m,": ");
                   12747:        strcat(m,s);
                   12748:        strcat(m," - abort\n");
                   12749:        return(m);
                   12750:        }
                   12751: 
                   12752: #define abort0(Z) fprintf(stderr,_G(Z))
                   12753: #define abort1(Z,A) fprintf(stderr,_G(Z),A)
                   12754: #define abort2(Z,A,B) fprintf(stderr,_G(Z),A,B)
                   12755: #define abort3(Z,A,B,C) fprintf(stderr,_G(Z),A,B,C)
                   12756: #define abort4(Z,A,B,C,D) fprintf(stderr,_G(Z),A,B,C,D)
                   12757: #define abort5(Z,A,B,C,D,E) fprintf(stderr,_G(Z),A,B,C,D,E)
                   12758: #define abort6(Z,A,B,C,D,E,F) fprintf(stderr,_G(Z),A,B,C,D,E,F)
                   12759: #define abort7(Z,A,B,C,D,E,F,G) fprintf(stderr,_G(Z),A,B,C,D,E,F,G)
                   12760: #define abort8(Z,A,B,C,D,E,F,G,H) fprintf(stderr,_G(Z),A,B,C,D,E,F,G,H)
                   12761: #define abort9(Z,A,B,C,D,E,F,G,H,I) fprintf(stderr,_G(Z),A,B,C,D,E,F,G,H,I)
                   12762: #define abort10(Z,A,B,C,D,E,F,G,H,I,J) fprintf(stderr,_G(Z),A,B,C,D,E,F,G,H,I,J)
                   12763: #define abort11(Z,A,B,C,D,E,F,G,H,I,J,K) fprintf(stderr,_G(Z),A,B,C,D,E,F,G,H,I,J,K)
                   12764: 
                   12765: boolean ask_more()
                   12766: {   FILE *tty;
                   12767:     char reply[20];
                   12768:     static int skip = 0;
                   12769:        if(skip<=0) {
                   12770:                fputs("MORE? ",(tty=fopen("/dev/tty","w")));  fclose(tty);
                   12771:                fgets(reply,20,(tty=fopen("/dev/tty","r")));  fclose(tty);
                   12772:                switch (reply[0]) {
                   12773:                        case '\0': case 'y': case 'Y':
                   12774:                                return(T);
                   12775:                        case 'n': case 'N': case 'q': case 'Q':
                   12776:                                return(F);
                   12777:                        case '0': case '1': case '2': case '3': case '4':
                   12778:                        case '5': case '6': case '7': case '8': case '9':
                   12779:                                skip = atoi(reply);
                   12780:                                return(T);
                   12781:                        case '*':
                   12782:                                skip = INT_MAX;
                   12783:                                return(T);
                   12784:                        default:
                   12785:                                skip = 0;
                   12786:                                return(T);
                   12787:                        };
                   12788:                }
                   12789:        else skip--;
                   12790:        return(T);
                   12791:        }
                   12792: 
                   12793: boolean ask_quit()
                   12794: {   FILE *tty;
                   12795:     char reply[20];
                   12796:        fputs("QUIT? ",(tty=fopen("/dev/tty","w")));  fclose(tty);
                   12797:        fgets(reply,20,(tty=fopen("/dev/tty","r")));  fclose(tty);
                   12798:        switch (reply[0]) {
                   12799:                case 'y': case 'Y':
                   12800:                        return(F);
                   12801:                case 'n': case 'N': case 'q': case 'Q':
                   12802:                        return(T);
                   12803:                };
                   12804:        return(F);
                   12805:        }
                   12806: 
                   12807: 0707070035351137171006640007620000050000010263220476773367100000600000171751bcp.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   12808: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   12809: /* The copyright notice does not imply actual or intended publication. */
                   12810: /* AUTHORS:                                            */
                   12811: /*     H. S. Baird - ATT-BL MH - first versions        */
                   12812: /*     T. J. ThompsonT - ATT-BL HO - extensions        */
                   12813: 
                   12814: /* bcp.c - translate among binary image file formats, optionally trimming,
                   12815:        shifting, scaling, and rotating the image on the fly.  Scaling is by
                   12816:        arbitrary real factors, separately in X & Y.  Rotation is still crude and
                   12817:        slow.
                   12818:    USAGE:
                   12819:        bcp [options...] [I [O]]
                   12820:    I/O:
                   12821:        If O is omitted, all output is concatenated to stdout.
                   12822:        If I is also omitted, all input is read from stdin.
                   12823:        If I is a filename, it is the sole input;  but, if it is a directory name,
                   12824:        then every leaf of its file tree is processed in turn; and, in this case,
                   12825:        if O also is specified, it is forced to become the root directory
                   12826:        of an isomorphic tree of output files (this use of Unix file trees
                   12827:        may be defeated using compile-time option FILE_TREE).
                   12828: 
                   12829:        [PROPOSED:  An input file may be a catenation of pages.  These may vary
                   12830:        in TYPE and other parameters.  They will all be translated to the same
                   12831:        output type, and catenated to one file, each with a complete translated
                   12832:        header.  Generally, a complete picfile header must be repeated at the
                   12833:        top of each page:  exceptions include TYPE=cdf, which packs pages in its
                   12834:        own peculiar way.]
                   12835: 
                   12836:    OPTIONS:
                   12837:        NOTE:  lengths, distances, and pixel indices are assumed to be in
                   12838:        units of pixels (scanner units), unless one of "icpPs" is appended,
                   12839:        meaning inches, cm, points, picas, or (explicitly) scanner pixels.
                   12840:         This applies to option:  -w (seems buggy).
                   12841: 
                   12842:        -B[io]  read/write bitfile(9.5) format (doesn't use TYPE= header).
                   12843:                [doesn't run-length encode yet:  may be bulky.]
                   12844:        -M      write TYPE=bitmap format.
                   12845:        -P      write Postscript format (only on Suns; by Tim Thompson, ATT-BL HO)
                   12846:        -Rx[,y] force output resolutions to x,y (overrides -xX[,Y]) (pixels/inch).
                   12847:                Requires a RES=X Y line in the header.
                   12848:        -R=     Force the output resolution to be equal to the greater of
                   12849:                the input resolutions.
                   12850:        -S      write Sun rasterfile format (only on Suns; by Tim Thompson,
                   12851:                ATT-BL HO)
                   12852:        -Tt     when reading TYPE=dump, binarize the image by thresholding each
                   12853:                pixel value as follows:  (pixel<t)? black: white. (default: -T128)
                   12854:        -Ww     shrink-wrap output around black artwork, surrounding it with equal
                   12855:                margins of width w (pixels), then translate so that the left-top
                   12856:                corner of the margin box is at 0,0 (works only with TYPE=document-
                   12857:                image input). (w must be >= 0)
                   12858:        -Zx[,y] set input resolution to RES=x y (overriding existing RES, if any)
                   12859:        -b      write binary format (TYPE=binary)
                   12860:        -d?     trace to stderr:
                   12861:                -dR     comment on any change in resolution
                   12862:                -dc     point out oddities in cdf files which are, by default,
                   12863:                        silently corrected
                   12864:                -dh     file headers (a good first debugging step)
                   12865:                -dm     margins
                   12866:                -dr     runs (exhaustive, voluminous)
                   12867:                -ds     status and summary statistics (brief)
                   12868:        -g31    write CCITT FAX Group 3 1-dim encoding
                   12869:          -31     ditto
                   12870:        -g32    write CCITT FAX Group 3 2-dim encoding (see also -k option)
                   12871:          -32     ditto
                   12872:        -g4     write CCITT FAX Group 4 encoding (the default output format)
                   12873:          -4      ditto
                   12874:        -kK     set the 'k' for g32 encoding on output (default: -k4)
                   12875:        -oX,Y   offset the result by X,Y (merely shift the bounding box)
                   12876:        -p      write TYPE=dump NCHAN=1 format; input binary pixels
                   12877:                are mapped to grey as follows: (pixel==white)? 255: 0.
                   12878:        -r      write rle format (this is Pavlidis' obsolescent OCR format) 
                   12879:        -t[lrbN] top of the page is really at the left/right/bottom;
                   12880:                after all other transformations are carried out, the image
                   12881:                will be rotated to bring the real top of page to the top.
                   12882:                By arbitrary convention, the top-left corner of the rotated
                   12883:                image will be equal to the top-left corner of the image
                   12884:                resulting from all the other transformations.
                   12885:                [UNFINISHED, UNDER DEVELOPMENT:  -tr & -tb; -tN, where N is a
                   12886:                numeric string, is interpreted as a counterclockwise rotation by
                   12887:                N degrees: for now, only handle +/-20 degrees.  The present code
                   12888:                for -tN is slow and subject to aliasing.]
                   12889:        -v      reverse video:  swap black and white
                   12890:        -wL,T,R,B  specify window to select:
                   12891:                (L,T) is the left-top (origin) and (R,B) the OPEN right-bottom
                   12892:                corner (i.e. the corner coordinates are not included.)   A '%'
                   12893:                argument defaults to the input window parameter.
                   12894:                [NOTE: since non-zero L,T windows are still not everywhere well
                   12895:                supported (by pcp, met, etc), it might be best to shift the
                   12896:                new L,T to 0,0 on output -- but this is not done now.]
                   12897:        -xX[,Y] expansion factor(s), horizontally and vertically;
                   12898:                if only one is specified, they are assumed equal
                   12899:                (default: -x1.0,1.0)  May be overridden by -Rx[,y].
                   12900:                Requires a RES=X Y line in the header.
                   12901: DESCRIPTION
                   12902:         This translates among these formats of binary images:
                   12903:    ccitt-g31, ccitt-g32, ccitt-g4, picture (TYPE=dump NCHAN=1), binary, rle, 
                   12904:    bitfile(9.5), cdf, Sun rasterfile (TYPE=bitmap), and Postscript.  All require
                   12905:    a TYPE= header in picfile format (see below), except bitfile(9.5) (as a result,
                   12906:    to read these, must use special option: -Bi).  Most require WINDOW=ox oy cx cy
                   12907:    and RES=x y header lines also.
                   12908:        Optionally, the image may be modified on the fly by the following
                   12909:    operations performed in this order:
                   12910:        trimming - a subset of the input image is selected (-w option)
                   12911:        shifting - the origin is shifted (-o)
                   12912:        scaling - real scaling factors are applied, in X & Y separately (-x, -R)
                   12913:        rotation - by 90, 180, 270 degrees - UNDER DEVELOPMENT (-t option)
                   12914:        reverse-video - swap black and white (-v option)
                   12915:    Note that scaling changes the effective digitizing resolution by arbitrary
                   12916:    real factors (expansion or contraction), in X and Y separately.  Presently,
                   12917:    this is accomplished naively by replication or deletion of pixels.  If it is
                   12918:    ever desired to apply more interesting image-processing techniques (such as
                   12919:    smoothing and resampling), the required changes may be safely confined to
                   12920:    functions transform_rlels() (in bcp.c) & transform_rlel() (in rlelib.c).
                   12921:    Accepts TYPE=document-image (or TYPE=dim), flattening its hierarchy,
                   12922:    and writes it out as a single page image.
                   12923: PICFILE FORMAT (briefly summarized; see picture(5))
                   12924:    Each picture file comprises an ASCII header followed by binary data.
                   12925:    The header is terminated by two newlines (an empty line).  A typical header is:
                   12926:         TYPE=ccitt-g4
                   12927:         WINDOW=0 0 640 480
                   12928:         RES=300 300
                   12929:                        (note the final empty line)
                   12930:    TYPE must come first.  The other lines may come in any order.  WINDOW gives
                   12931:    the x,y coordinates of the upper left corner (inclusive) and lower right
                   12932:    corners (exclusive).  Typically, an image of WxH pixels will be described
                   12933:    by WINDOW=0 0 W H.  RES=X Y gives the digitizing resolution horizontally and
                   12934:    vertically, in integral pixels/inch.  Supported TYPEs include:
                   12935: 
                   12936:    dump     A two-dimensional array of pixel structures.  NCHAN=1 is required:
                   12937:            one byte per pixel.  On input, the grey pixel values are thresholded
                   12938:            to binary (see option -T).  On output, black is 0 and white is 255.
                   12939: 
                   12940:    bitmap   One bit/pixel, packed into bytes high-order bit first.  Black is `1'.
                   12941:            Each horizontal row is padded to a 16-bit boundary with `0'.
                   12942:            (This is identical to Sun rasterfile format, except for the ASCII
                   12943:            header.)
                   12944: 
                   12945:    ccitt-g4 CCITT FAX Group 4 compressed image.  Similarly, ccitt-g31 means
                   12946:            Group 3/1-D and ccitt-g32 means Group 3/2-D.
                   12947: 
                   12948:    (Obsolescent 112 formats:
                   12949:     rle            A run-length coding, better for binary images (see rle.h).
                   12950:     binary  1 bit/pixel, packed into bytes low-order bit first.  Black is `1'.
                   12951:            Each horizontal row is padded to a full byte with `0'.)
                   12952: 
                   12953:     NOTE:  bitfile(9.5) doesn't use an ASCII header.
                   12954: 
                   12955:    (Odd formats in use outside 112, sometimes very heavily:
                   12956:     cdf            supported on input only, and only the first page of several.
                   12957:     tiff    not yet supported.)
                   12958: 
                   12959: IMPLEMENTATION STATUS
                   12960:         CCITT FAX ``uncompressed'' (or, ``transparent'') mode is not implemented,
                   12961:    either while encoding or decoding.
                   12962:        Cdf is an input-only option;  Sun rasterfile and Postscript are output-only options.
                   12963:    Postscript output is useful only for very small images.
                   12964:         Rotations are only partially implemented, and are slow.
                   12965: 
                   12966: KNOWN BUGS (30 May 89)
                   12967:        WINDOW=OX OY CX CY where OX or OY are non-zero is not handled correctly
                   12968:    for every combination of file types.
                   12969:        Unit gets passed wrongly to vto_scoor().
                   12970:        Rle can't be both inout and output (design flaw: they share a buffer).
                   12971:        Beware off-by-one errors (top or bottom line omitted); has not been
                   12972:    carefully checked for all file type combinations.
                   12973: 
                   12974: AUTHORS
                   12975:        Dec 1988 - Henry S. Baird (AT&T Bell Labs MH) - first working draft
                   12976:        Mar 1989 - Tim Thompson (BL HO) - extensions for SunOS, bug fixes, etc
                   12977: */
                   12978: 
                   12979: #include <stdio.h>
                   12980: #include <string.h>
                   12981: #include <ctype.h>
                   12982: #include "CPU.h"
                   12983: #define MAIN 1
                   12984: #include "stdocr.h"
                   12985: #include "rle.h"
                   12986: #include "pic.h"
                   12987: #include "Text.h"
                   12988:    /* Ugly stubs just to prevent Text.h dragging in many other *.h & *.o files */
                   12989:    Bfeats *alloc_bfeats(){}; free_bfeats(){}; Bfeats *dup_bfeats(){};
                   12990:    fwrb_bfeats(){}; frdb_bfeats(){}; fix_lag(){}; char *classid_toa(){};
                   12991: #include "Bitmap.h"
                   12992: #include "CCITT.h"
                   12993: #include "bitio.h"
                   12994: #if FILE_TREE
                   12995: #include "Path.h"
                   12996: #endif
                   12997: #define CMDNAME "bcp"
                   12998: #include "abort.h"
                   12999: 
                   13000: double atof(),sin(),cos();
                   13001: char *strchr();
                   13002: 
                   13003: /* Runtime options values */
                   13004: static struct {
                   13005:        boolean from_bitfile;   /* -Bi */
                   13006:        boolean to_bitfile;     /* -Bo */
                   13007:        boolean to_bitmap;      /* -M */
                   13008:        boolean to_g31;         /* -g31 or -31 */
                   13009:        boolean to_g32;         /* -g32 or -32 */
                   13010:        boolean to_g4;          /* -g4 or -4 */
                   13011:        boolean to_rle;         /* -r */
                   13012:        boolean to_bin;         /* -b */
                   13013:        boolean to_pic;         /* -p */
                   13014:        boolean to_post;        /* -P */
                   13015:        boolean to_rast;        /* -S */
                   13016:        boolean omit_hdr;       /* -O */
                   13017:        Sp out_res;             /* -R (-1 = unspecified; -2 = force-equal) */
                   13018:        Scoor shrinkwrap;       /* -W (-1 = unspecified) */
                   13019:        Sp in_res;              /* -Z (SHRT_MIN,SHRT_MIN = unspecified) */
                   13020:        int g32_k;              /* -k */
                   13021:        int metheus;            /* -m */
                   13022:        Sp offset;              /* -o */
                   13023:        boolean dbg_any;
                   13024:        boolean dbg_R;          /* -dR */
                   13025:        boolean dbg_c;          /* -dc */
                   13026:        boolean dbg_h;          /* -dh */
                   13027:        boolean dbg_m;          /* -dm */
                   13028:        boolean dbg_r;          /* -dr */
                   13029:        boolean dbg_s;          /* -ds */
                   13030:        boolean show;           /* -s */
                   13031:        char top;               /* -tT takes on values: 't', 'l', 'r', 'b', 'a' */
                   13032:        float top_angle;        /* -t angular value (set if top=='a') (Radians) */
                   13033:        int thresh;             /* -Tt */
                   13034:        boolean reverse;        /* -v */
                   13035:        char *optarg_l;         /* -w?,,, */
                   13036:        char *optarg_t;         /* -w,?,, */
                   13037:        char *optarg_r;         /* -w,,?, */
                   13038:        char *optarg_b;         /* -w,,,? */
                   13039:        Bbx trim;               /* output margins resulting from -w */
                   13040:        Pp expand;              /* -x */
                   13041:        char *in_fn;
                   13042:        char *out_fn;
                   13043: } _O = {
                   13044:        F, F, F, F, F, T, F, F, F, F, F,
                   13045:        F, {-1,-1}, -1, {SHRT_MIN,SHRT_MIN}, 4, -1, Init_Zero_Sp,
                   13046:        F, F, F, F, F, F, F, F,
                   13047:        't',0.0,
                   13048:        128,
                   13049:        F,
                   13050:        NULL, NULL, NULL, NULL,
                   13051:        Init_Max_Bbx,
                   13052:        {1.0,1.0},
                   13053:        NULL, NULL };   
                   13054: 
                   13055: parse_args(arc,arv)
                   13056:     int arc; char **arv;
                   13057: {      /* getopt support */
                   13058:        int optch;
                   13059:        extern int optind;
                   13060:        extern char *optarg;
                   13061: 
                   13062:     char *metheus_ev,metheus_digit;
                   13063:     char *fs;
                   13064: 
                   13065:        /* default metheus number */
                   13066:        if((metheus_ev=(char *)getenv("FB"))!=NULL) {
                   13067:                metheus_digit = metheus_ev[(int)strlen(metheus_ev)-1];
                   13068:                if((int)isdigit(metheus_digit)) {
                   13069:                        _O.metheus = (metheus_digit - '0');
                   13070:                        };
                   13071:                };
                   13072: 
                   13073:        while((optch=getopt(arc,arv,"B:MOPR:ST:W:Z:3:4bd:g:k:m:o:prst:vw:x:"))!=EOF)
                   13074:                switch(optch) {
                   13075:                        case 'B':
                   13076:                                switch(*optarg) {
                   13077:                                    case 'o':
                   13078:                                        _O.to_bitfile = T;
                   13079:                                        _O.to_g4 = F;
                   13080:                                        break;
                   13081:                                    case 'i':
                   13082:                                        _O.from_bitfile = T;
                   13083:                                        break;
                   13084:                                    default:
                   13085:                                        abort("option -B%s is illegal",optarg);
                   13086:                                        break;
                   13087:                                    };
                   13088:                                break;
                   13089:                        case 'M':  _O.to_bitmap = T;  _O.to_g4 = F; break;
                   13090:                        case 'O':  _O.omit_hdr = T; break;
                   13091:                        case 'P':
                   13092: #if CPU==SUN
                   13093:                                _O.to_post = T;  _O.to_g4 = F;
                   13094: #else
                   13095:                                abort("-P option available only on Suns");
                   13096: #endif
                   13097:                                break;
                   13098:                        case 'R':
                   13099:                                if(*optarg=='=') {
                   13100:                                        _O.out_res.x = _O.out_res.y = -2;
                   13101:                                        fs=NULL;
                   13102:                                        }
                   13103:                                else if((fs=strtok(optarg,","))!=NULL) {
                   13104:                                        if(strcmp(fs,"%")!=0) {
                   13105:                                                _O.out_res.x = atoi(fs);
                   13106:                                                };
                   13107:                                        };
                   13108:                                if(fs!=NULL&&(fs=strtok((char *)0,","))!=NULL) {
                   13109:                                        if(strcmp(fs,"%")!=0) {
                   13110:                                                _O.out_res.y = atoi(fs);
                   13111:                                                };
                   13112:                                        }
                   13113:                                else _O.out_res.y = _O.out_res.x;
                   13114:                                break;
                   13115:                        case 'S':
                   13116: #if CPU==SUN
                   13117:                                _O.to_rast = T;  _O.to_g4 = F;
                   13118: #else
                   13119:                                abort("-S option available only on Suns");
                   13120: #endif
                   13121:                                break;
                   13122:                        case 'T':  _O.thresh=atoi(optarg);  break;
                   13123:                        case 'W':  _O.shrinkwrap=atoi(optarg);
                   13124:                                if(_O.shrinkwrap<0) {
                   13125:                                        err("-W%d must be >=0; force to -W0",
                   13126:                                                _O.shrinkwrap);
                   13127:                                        _O.shrinkwrap=0;
                   13128:                                        };
                   13129:                                break;
                   13130:                        case 'Z':
                   13131:                                if((fs=strtok(optarg,","))!=NULL) {
                   13132:                                        if(strcmp(fs,"%")!=0) {
                   13133:                                                _O.in_res.x = atoi(fs);
                   13134:                                                };
                   13135:                                        };
                   13136:                                if(fs!=NULL&&(fs=strtok((char *)0,","))!=NULL) {
                   13137:                                        if(strcmp(fs,"%")!=0) {
                   13138:                                                _O.in_res.y = atoi(fs);
                   13139:                                                };
                   13140:                                        }
                   13141:                                else _O.in_res.y = _O.in_res.x;
                   13142:                                break;
                   13143:                        case '3':
                   13144:                                switch (*optarg) {
                   13145:                                    case '1':
                   13146:                                        _O.to_g31=T;
                   13147:                                        _O.to_g4=F;
                   13148:                                        break;
                   13149:                                    case '2':
                   13150:                                        _O.to_g32=T;
                   13151:                                        _O.to_g4=F;
                   13152:                                        break;
                   13153:                                    default:
                   13154:                                        abort("bad option: -g3%s",optarg);
                   13155:                                        break;
                   13156:                                    };
                   13157:                                break;
                   13158:                        case '4':  _O.to_g4=T;  break;
                   13159:                        case 'b':
                   13160:                                _O.to_bin=T;
                   13161:                                _O.to_g4=F;
                   13162:                                break;
                   13163:                        case 'd':
                   13164:                                _O.dbg_any=T;
                   13165:                                switch(*optarg) {
                   13166:                                    case 'R':  _O.dbg_R = T;  break;
                   13167:                                    case 'c':  _O.dbg_c = T;  break;
                   13168:                                    case 'h':  _O.dbg_h = T;  break;
                   13169:                                    case 'm':  _O.dbg_m = T;  break;
                   13170:                                    case 'r':  _O.dbg_r = T;  break;
                   13171:                                    case 's':  _O.dbg_s = T;  break;
                   13172:                                    };
                   13173:                                break;
                   13174:                        case 'g':  
                   13175:                                switch (optarg[0]) {
                   13176:                                    case '3':
                   13177:                                        switch (optarg[1]) {
                   13178:                                            case '1':
                   13179:                                                _O.to_g31=T;
                   13180:                                                _O.to_g4=F;
                   13181:                                                break;
                   13182:                                            case '2':
                   13183:                                                _O.to_g32=T;
                   13184:                                                _O.to_g4=F;
                   13185:                                                break;
                   13186:                                            default:
                   13187:                                                abort("bad option: -g%s",optarg);
                   13188:                                                break;
                   13189:                                            };
                   13190:                                        break;
                   13191:                                    case '4':  _O.to_g4=T;  break;
                   13192:                                    default:
                   13193:                                        abort("bad option: -g%s",optarg);
                   13194:                                        break;
                   13195:                                    };
                   13196:                                break;
                   13197:                        case 'k':  _O.g32_k = atoi(optarg); break;
                   13198:                        case 'm':  _O.metheus = atoi(optarg); break;
                   13199:                        case 'o':
                   13200:                                if((fs=strtok(optarg,","))!=NULL) {
                   13201:                                        if(strcmp(fs,"%")!=0)
                   13202:                                                _O.offset.x = atoi(fs);
                   13203:                                        };
                   13204:                                if(fs!=NULL&&(fs=strtok((char *)0,","))!=NULL) {
                   13205:                                        if(strcmp(fs,"%")!=0)
                   13206:                                                _O.offset.y = atoi(fs);
                   13207:                                        };
                   13208:                                break;
                   13209:                        case 'p':
                   13210:                                _O.to_pic=T;
                   13211:                                _O.to_g4=F;
                   13212:                                break;
                   13213:                        case 'r':
                   13214:                                _O.to_rle = T;
                   13215:                                _O.to_g4 = F;
                   13216:                                break;
                   13217:                        case 's':  _O.show = T;  break;
                   13218:                        case 't':  _O.top = *optarg;
                   13219:                                if(strchr("0123456789.+-",_O.top)!=NULL) {
                   13220:                                        _O.top = 'a';   /* angular value */
                   13221:                                        _O.top_angle = atof(optarg)*DtoR;
                   13222:                                        };
                   13223:                                break;
                   13224:                        case 'v':  _O.reverse = T;  break;
                   13225:                        case 'w':
                   13226:                                if( (fs=strtok(optarg,","))!=NULL
                   13227:                                        && strlen(fs)>0 && strcmp(fs,"%")!=0 )
                   13228:                                                _O.optarg_l = strdup(fs);
                   13229:                                if( fs!=NULL && (fs=strtok((char *)0,","))!=NULL
                   13230:                                        && strlen(fs)>0 && strcmp(fs,"%")!=0 )
                   13231:                                                _O.optarg_t = strdup(fs);
                   13232:                                if( fs!=NULL && (fs=strtok((char *)0,","))!=NULL
                   13233:                                        && strlen(fs)>0 && strcmp(fs,"%")!=0 )
                   13234:                                                _O.optarg_r = strdup(fs);
                   13235:                                if( fs!=NULL && (fs=strtok((char *)0,","))!=NULL
                   13236:                                        && strlen(fs)>0 && strcmp(fs,"%")!=0 )
                   13237:                                                _O.optarg_b = strdup(fs);
                   13238:                                break;
                   13239:                        case 'x':
                   13240:                                if((fs=strtok(optarg,","))!=NULL) {
                   13241:                                        if(strcmp(fs,"%")!=0) {
                   13242:                                                if(*fs=='/')
                   13243:                                                  _O.expand.x = 1.0/atof(fs+1);
                   13244:                                                else _O.expand.x = atof(fs);
                   13245:                                                if(_O.expand.x<=0.0)
                   13246:                                                  _O.expand.x=1.0;
                   13247:                                                };
                   13248:                                        };
                   13249:                                if(fs!=NULL&&(fs=strtok((char *)0,","))!=NULL) {
                   13250:                                        if(strcmp(fs,"%")!=0) {
                   13251:                                                if(*fs=='/')
                   13252:                                                  _O.expand.y = 1.0/atof(fs+1);
                   13253:                                                else _O.expand.y = atof(fs);
                   13254:                                                if(_O.expand.y<=0.0)
                   13255:                                                  _O.expand.y=1.0;
                   13256:                                                };
                   13257:                                        }
                   13258:                                else _O.expand.y = _O.expand.x;
                   13259:                                break;
                   13260:                        default: break;
                   13261:                        };
                   13262:        switch(arc-optind) {
                   13263:            case 2:
                   13264:                _O.out_fn = strdup(arv[optind+1]);
                   13265:            case 1:     
                   13266:                _O.in_fn = strdup(arv[optind]);
                   13267:            case 0:
                   13268:                break;
                   13269:            default:
                   13270:                abort("<= two filenames expected");
                   13271:                break;
                   13272:            };
                   13273:        if(_O.show&&_O.metheus==-1) {
                   13274:                err("FB=/dev/omM not specified, using /dev/om0");
                   13275:                _O.metheus = 0;
                   13276:                };
                   13277:        }
                   13278: 
                   13279: unimplemented()
                   13280: {      abort("unimplemented");
                   13281:        }
                   13282: 
                   13283: typedef struct Copy_arg {
                   13284:        boolean bop;    /* beginning of page */
                   13285:        PIC_hdr *ph;
                   13286:        int wid;        /* bbx_wid(&(ph->bx)) (for speed) */
                   13287:        BITFILE *bf;
                   13288:        DST_table *tbl; /* for CCITT input */
                   13289:        int k;          /* CCITT Group 3 2-D k */
                   13290:        int thresh;     /* for input pic files */
                   13291:        RLE_Lines rles; /* for TYPE=document-image or TYPE=dim */
                   13292:        } Copy_arg;
                   13293: #define Init_Copy_arg {T,NULL,INT_MIN,NULL,NULL,4,128,Init_RLE_Lines}
                   13294: #if MAIN
                   13295: Copy_arg empty_Copy_arg = Init_Copy_arg;
                   13296: #else
                   13297: extern Copy_arg empty_Copy_arg;
                   13298: #endif
                   13299: 
                   13300: /* SOURCES:  return the next RLE_Line from the given file type, with run indices
                   13301:    shifted to lie within [ a->ph->bx.a.x, a->ph->bx.b.x ].
                   13302:    **** BUGS:  not all handle non-zero a->ph->bx.a.x yet.
                   13303:    */
                   13304: 
                   13305: /* Handles non-zero a->ph->bx.a.x. */
                   13306: RLE_Line *cdf_mrlc_source(a)
                   13307:     Copy_arg *a;
                   13308: #define dbg_cdf (0)
                   13309: {   static RLE_Line rl;
                   13310:     int n;     /* no. pixels decoded */
                   13311:     int col;   /* color:  0=white, 1=black */
                   13312:     int byte;  /* input byte */
                   13313:     int nb;    /* no. bytes read for this line */
                   13314:     int ni;    /* nibble index: 0=1st (low-order), 1=2nd(high-order) */
                   13315:     int nib;   /* current nibble */
                   13316:     int mult;  /* multiplier for current nibble */
                   13317:     int run;   /* no. pixels in current run */
                   13318:     RLE_Run *rp;
                   13319: #define toggle_color() {if(col) col=0; else col=1;}
                   13320: /* get next byte into `byte' */
                   13321: #define getbyte()  { \
                   13322:        if((byte=getc(a->ph->fp))==EOF) goto eof; nb++; \
                   13323:        if(dbg_cdf) err("byte0x%x",byte); \
                   13324:        }
                   13325: /* get next nibble into `nib' */
                   13326: #define getnib()  { \
                   13327:        if(ni) { getbyte();  ni=0;  nib=byte&0x0F; } \
                   13328:        else { ni=1;  nib=(byte>>4); } \
                   13329:        if(dbg_cdf) err("nib0x%x byte0x%x ni%d",nib,byte,ni); \
                   13330:        }
                   13331: /* get next run into `run' */
                   13332: #define getrun()  { \
                   13333:        run=0;  mult=1; \
                   13334:        do {getnib();  run += mult * (nib&0x07);  mult *= 8;} while(nib&0x08); \
                   13335:        if(dbg_cdf) err("run%d %c",run,((col)? 'B': 'W')); \
                   13336:        }
                   13337:        a->bop = F;
                   13338:        n=0; col=0; ni=1; nb=0; rp=rl.r;
                   13339:        do {    getrun();
                   13340:                if(col) {/* black run */
                   13341:                        if(run>0) { /* ... of >0 length */
                   13342:                                rp->xs = a->ph->bx.a.x + n+1;
                   13343:                                rp->xe = a->ph->bx.a.x + (n+=run);
                   13344:                                if((rp-rl.r)>0 && ((rp-1)->xe >= rp->xs-1) ) {
                   13345:                                        if(_O.dbg_c) err("cdf_mrlc_source: abutting black runs [%d,%d] & [%d,%d] - merged",
                   13346:                                                (rp-1)->xs,(rp-1)->xe,
                   13347:                                                rp->xs,rp->xe );
                   13348:                                        /* merge with prior black run */
                   13349:                                        (rp-1)->xe = rp->xe;
                   13350:                                        }
                   13351:                                else rp++;
                   13352:                                }
                   13353:                        else {  /* zero-length black run */
                   13354:                                if( _O.dbg_c && (rp-rl.r)>0 )
                   13355:                                        err("cdf_mrlc_source: zero-length black run [%d,%d] in middle of line - ignored",
                   13356:                                        n,n);
                   13357:                                };
                   13358:                        }
                   13359:                else {  /* white run */
                   13360:                        n+=run;
                   13361:                        };
                   13362:                toggle_color();
                   13363:                }
                   13364:        while(n<a->wid);
                   13365:        /* read 2 EOL nibbles */
                   13366:        getnib(); getnib();
                   13367:        rl.runs = rp - rl.r;
                   13368:        rl.len = a->wid;
                   13369:        if(rl.runs>0 && rl.r[rl.runs-1].xe>=a->wid) {
                   13370:                if(_O.dbg_c)
                   13371:                    err("cdf_mrlc_source: run [%d,%d] in line of length %d - truncated",
                   13372:                        rl.r[rl.runs-1].xs,rl.r[rl.runs-1].xe,a->wid);
                   13373:                rl.r[rl.runs-1].xe = a->wid-1;
                   13374:                if(rl.r[rl.runs-1].xs>rl.r[rl.runs-1].xe) {
                   13375:                        rl.runs--;
                   13376:                        };
                   13377:                };
                   13378:        rl.y = a->ph->cy++;
                   13379:        if(_O.dbg_r) nerr_RLE_Line("cdf_source: ",&rl);
                   13380:        return(&rl);
                   13381: 
                   13382: eof:   if(dbg_cdf)
                   13383:                err("cdf_mrlc_source: unexpected EOF, input line %d",a->ph->cy);
                   13384:        return(NULL);
                   13385:        }
                   13386: 
                   13387: int no_runs_of_page(p)
                   13388:     Page *p;
                   13389: {   int runs;
                   13390:        runs = 0;
                   13391:        runs += no_runs_of_blocks(&p->bks);
                   13392:        runs += no_runs_of_txtlns(&p->ls);
                   13393:        runs += no_runs_of_words(&p->ws);
                   13394:        runs += no_runs_of_chars(&p->cs);
                   13395:        runs += no_runs_of_blobs(&p->bs);
                   13396:        return(runs);
                   13397:        }
                   13398: 
                   13399: int runs_of_page(p,ra,max)
                   13400:     Page *p;
                   13401:     RLE_Yrun *ra;
                   13402:     int max;
                   13403: {   int runs;
                   13404:        runs = 0;
                   13405:        runs += runs_of_blocks(&p->bks,ra,max);
                   13406:        runs += runs_of_txtlns(&p->ls,ra+runs,max-runs);
                   13407:        runs += runs_of_words(&p->ws,ra+runs,max-runs);
                   13408:        runs += runs_of_chars(&p->cs,ra+runs,max-runs);
                   13409:        runs += runs_of_blobs(&p->bs,ra+runs,max-runs);
                   13410:        return(runs);
                   13411:        }
                   13412: 
                   13413: int no_runs_of_blocks(p)
                   13414:     Blocks *p;
                   13415: {   int runs;
                   13416:     Block *pp,**ppp;
                   13417:        runs = 0;
                   13418:        if(p->mny>0) for(pp= *(ppp=p->bpa); pp!=NULL; pp= *(++ppp))
                   13419:                runs += no_runs_of_block(pp);
                   13420:        return(runs);
                   13421:        }
                   13422: 
                   13423: int runs_of_blocks(p,ra,max)
                   13424:     Blocks *p;
                   13425:     RLE_Yrun *ra;
                   13426:     int max;
                   13427: {   int runs;
                   13428:     Block *pp,**ppp;
                   13429:        runs = 0;
                   13430:        if(p->mny>0) for(pp= *(ppp=p->bpa); pp!=NULL; pp= *(++ppp))
                   13431:                runs += runs_of_block(pp,ra+runs,max-runs);
                   13432:        return(runs);
                   13433:        }
                   13434: 
                   13435: int no_runs_of_block(p)
                   13436:     Block *p;
                   13437: {   int runs;
                   13438:        runs = 0;
                   13439:        runs += no_runs_of_txtlns(&p->ls);
                   13440:        runs += no_runs_of_words(&p->ws);
                   13441:        runs += no_runs_of_chars(&p->cs);
                   13442:        runs += no_runs_of_blobs(&p->bs);
                   13443:        return(runs);
                   13444:        }
                   13445: 
                   13446: int runs_of_block(p,ra,max)
                   13447:     Block *p;
                   13448:     RLE_Yrun *ra;
                   13449:     int max;
                   13450: {   int runs;
                   13451:        runs = 0;
                   13452:        runs += runs_of_txtlns(&p->ls,ra+runs,max-runs);
                   13453:        runs += runs_of_words(&p->ws,ra+runs,max-runs);
                   13454:        runs += runs_of_chars(&p->cs,ra+runs,max-runs);
                   13455:        runs += runs_of_blobs(&p->bs,ra+runs,max-runs);
                   13456:        return(runs);
                   13457:        }
                   13458: 
                   13459: int no_runs_of_txtlns(p)
                   13460:     Txtlns *p;
                   13461: {   int runs;
                   13462:     Txtln *pp,**ppp;
                   13463:        runs = 0;
                   13464:        if(p->mny>0) for(pp= *(ppp=p->lpa); pp!=NULL; pp= *(++ppp))
                   13465:                runs += no_runs_of_txtln(pp);
                   13466:        return(runs);
                   13467:        }
                   13468: 
                   13469: int runs_of_txtlns(p,ra,max)
                   13470:     Txtlns *p;
                   13471:     RLE_Yrun *ra;
                   13472:     int max;
                   13473: {   int runs;
                   13474:     Txtln *pp,**ppp;
                   13475:        runs = 0;
                   13476:        if(p->mny>0) for(pp= *(ppp=p->lpa); pp!=NULL; pp= *(++ppp))
                   13477:                runs += runs_of_txtln(pp,ra+runs,max-runs);
                   13478:        return(runs);
                   13479:        }
                   13480: 
                   13481: int no_runs_of_txtln(p)
                   13482:     Txtln *p;
                   13483: {   int runs;
                   13484:        runs = 0;
                   13485:        runs += no_runs_of_words(&p->ws);
                   13486:        runs += no_runs_of_chars(&p->cs);
                   13487:        runs += no_runs_of_blobs(&p->bs);
                   13488:        return(runs);
                   13489:        }
                   13490: 
                   13491: int runs_of_txtln(p,ra,max)
                   13492:     Txtln *p;
                   13493:     RLE_Yrun *ra;
                   13494:     int max;
                   13495: {   int runs;
                   13496:        runs = 0;
                   13497:        runs += runs_of_words(&p->ws,ra+runs,max-runs);
                   13498:        runs += runs_of_chars(&p->cs,ra+runs,max-runs);
                   13499:        runs += runs_of_blobs(&p->bs,ra+runs,max-runs);
                   13500:        return(runs);
                   13501:        }
                   13502: 
                   13503: int no_runs_of_words(p)
                   13504:     Words *p;
                   13505: {   int runs;
                   13506:     Word *pp,**ppp;
                   13507:        runs = 0;
                   13508:        if(p->mny>0) for(pp= *(ppp=p->wpa); pp!=NULL; pp= *(++ppp))
                   13509:                runs += no_runs_of_word(pp);
                   13510:        return(runs);
                   13511:        }
                   13512: 
                   13513: int runs_of_words(p,ra,max)
                   13514:     Words *p;
                   13515:     RLE_Yrun *ra;
                   13516:     int max;
                   13517: {   int runs;
                   13518:     Word *pp,**ppp;
                   13519:        runs = 0;
                   13520:        if(p->mny>0) for(pp= *(ppp=p->wpa); pp!=NULL; pp= *(++ppp))
                   13521:                runs += runs_of_word(pp,ra+runs,max-runs);
                   13522:        return(runs);
                   13523:        }
                   13524: 
                   13525: int no_runs_of_word(p)
                   13526:     Word *p;
                   13527: {   int runs;
                   13528:        runs = 0;
                   13529:        runs += no_runs_of_chars(&p->cs);
                   13530:        runs += no_runs_of_blobs(&p->bs);
                   13531:        return(runs);
                   13532:        }
                   13533: 
                   13534: int runs_of_word(p,ra,max)
                   13535:     Word *p;
                   13536:     RLE_Yrun *ra;
                   13537:     int max;
                   13538: {   int runs;
                   13539:        runs = 0;
                   13540:        runs += runs_of_chars(&p->cs,ra+runs,max-runs);
                   13541:        runs += runs_of_blobs(&p->bs,ra+runs,max-runs);
                   13542:        return(runs);
                   13543:        }
                   13544: 
                   13545: int no_runs_of_chars(p)
                   13546:     Chars *p;
                   13547: {   int runs;
                   13548:     Char *pp,**ppp;
                   13549:        runs = 0;
                   13550:        if(p->mny>0) for(pp= *(ppp=p->cpa); pp!=NULL; pp= *(++ppp))
                   13551:                runs += no_runs_of_char(pp);
                   13552:        return(runs);
                   13553:        }
                   13554: 
                   13555: int runs_of_chars(p,ra,max)
                   13556:     Chars *p;
                   13557:     RLE_Yrun *ra;
                   13558:     int max;
                   13559: {   int runs;
                   13560:     Char *pp,**ppp;
                   13561:        runs = 0;
                   13562:        if(p->mny>0) for(pp= *(ppp=p->cpa); pp!=NULL; pp= *(++ppp))
                   13563:                runs += runs_of_char(pp,ra+runs,max-runs);
                   13564:        return(runs);
                   13565:        }
                   13566: 
                   13567: int no_runs_of_blobs(p)
                   13568:     Blobs *p;
                   13569: {   int runs;
                   13570:     Blob *pp,**ppp;
                   13571:        runs = 0;
                   13572:        if(p->mny>0) for(pp= *(ppp=p->bpa); pp!=NULL; pp= *(++ppp))
                   13573:                runs += pp->runs;
                   13574:        return(runs);
                   13575:        }
                   13576: 
                   13577: int runs_of_blobs(p,ra,max)
                   13578:     Blobs *p;
                   13579:     RLE_Yrun *ra;
                   13580:     int max;
                   13581: {   int runs;
                   13582:     Blob *pp,**ppp;
                   13583:        runs = 0;
                   13584:        if(p->mny>0) for(pp= *(ppp=p->bpa); pp!=NULL; pp= *(++ppp))
                   13585:                runs += runs_of_blob(pp,ra+runs,max-runs);
                   13586:        return(runs);
                   13587:        }
                   13588: 
                   13589: /* ascending lexicographic order on y,xs */
                   13590: int local_rn_asc(r1,r2)
                   13591:    RLE_Yrun *r1,*r2;
                   13592: {      if(r1->y < r2->y) return(-1);
                   13593:        else if(r1->y==r2->y) {
                   13594:                if(r1->xs < r2->xs) return(-1);
                   13595:                else if (r1->xs == r2->xs) return(0);
                   13596:                else return(1);
                   13597:                }
                   13598:        else return(1);
                   13599:        }
                   13600: 
                   13601: RLE_Lines *rle_lines_of_page(pgp)
                   13602:     Page *pgp;
                   13603: {   static RLE_Lines rls;
                   13604:     int no_runs,cy,ri;
                   13605:     RLE_Yrun *ra,*cr;
                   13606:     RLE_Run *lr;
                   13607:     RLE_Line *cl;
                   13608:        /* count runs */
                   13609:        no_runs = no_runs_of_page(pgp);
                   13610:        if(_O.dbg_r) err("no_runs %d",no_runs);
                   13611:        /* allocate runs array */
                   13612:        if((ra=(RLE_Yrun *)malloc(no_runs*sizeof(RLE_Yrun)))==NULL)
                   13613:                abort("rle_lines_of_page: can't malloc ra[%d]",no_runs);
                   13614:        runs_of_page(pgp,ra,no_runs);
                   13615:        /* sort runs ascending on (y,xs) */
                   13616:        qsort(ra,no_runs,sizeof(RLE_Yrun),local_rn_asc);
                   13617:        /* count RLE_lines.mny */
                   13618:        rls.mny = 0; cy=INT_MIN;
                   13619:        for(ri=0,cr=ra; ri<no_runs; ri++,cr++)
                   13620:                if(cr->y!=cy) {
                   13621:                        rls.mny++;
                   13622:                        cy = cr->y;
                   13623:                        };
                   13624:        /* allocate RLE_lines */
                   13625:        if((rls.rla=(RLE_Line *)malloc(rls.mny*sizeof(RLE_Line)))==NULL)
                   13626:                abort("rle_lines_of_page: can't malloc rls.rla[%d]",rls.mny);
                   13627:        /* fill in RLE_lines */
                   13628:        cy=INT_MIN;  cl=rls.rla-1;
                   13629:        for(ri=0,cr=ra; ri<no_runs; ri++,cr++) {
                   13630:                if(cr->y!=cy) {
                   13631:                        cl++;
                   13632:                        cl->y = cy = cr->y;
                   13633:                        cl->runs = 0;
                   13634:                        lr = cl->r;
                   13635:                        };
                   13636:                lr->xs = cr->xs;  lr->xe = cr->xe;  lr++;  cl->runs++;
                   13637:                };
                   13638:        free(ra);
                   13639:        return(&rls);
                   13640:        }
                   13641: 
                   13642: Bbx *bbx_of_rle_lines(rlsp)
                   13643:     RLE_Lines *rlsp;
                   13644: {   static Bbx res;
                   13645:     Bbx r;
                   13646:     int li,ri;
                   13647:     RLE_Line *lp;
                   13648:     RLE_Run *rp;
                   13649:        res = empty_Bbx;
                   13650:        for(li=0,lp=rlsp->rla; li<rlsp->mny; li++,lp++) {
                   13651:                r.a.y = r.b.y = lp->y;
                   13652:                for(ri=0,rp=lp->r; ri<lp->runs; ri++,rp++) {
                   13653:                        r.a.x = rp->xs;
                   13654:                        r.b.x = rp->xe;
                   13655:                        merge_bbx(&r,&res);
                   13656:                        };
                   13657:                };
                   13658:        return(&res);
                   13659:        }
                   13660: 
                   13661: translate_rle_lines(r,p)
                   13662:     RLE_Lines *r;
                   13663:     Sp p;
                   13664: {   int li,ri;
                   13665:     RLE_Line *lp;
                   13666:     RLE_Run *rp;
                   13667:        for(li=0,lp=r->rla; li<r->mny; li++,lp++) {
                   13668:                lp->y += p.y;
                   13669:                for(ri=0,rp=lp->r; ri<lp->runs; ri++,rp++) {
                   13670:                        rp->xs += p.x;
                   13671:                        rp->xe += p.x;
                   13672:                        };
                   13673:                };
                   13674:        }
                   13675: 
                   13676: RLE_Line *binary_source(a)
                   13677:     Copy_arg *a;
                   13678: {   static RLE_Line rl;
                   13679:     unsigned char *inline;
                   13680:        a->bop = F;
                   13681:        if(PIC_rline(a->ph,&inline)==1) {
                   13682:                rl.runs =
                   13683:                    rlbr(inline,0,a->ph->bx.b.x-a->ph->bx.a.x,a->ph->bx.a.x,rl.r);
                   13684:                rl.y = a->ph->cy;
                   13685:                rl.len = a->wid;
                   13686:                if(_O.dbg_r) nerr_RLE_Line("binary_source: ",&rl);
                   13687:                return(&rl);
                   13688:                }
                   13689:        else {  if(_O.dbg_r) nerr_RLE_Line("binary_source: ",NULL);
                   13690:                return(NULL);
                   13691:                };
                   13692:        }
                   13693: 
                   13694: RLE_Line *bitmap_source(a)
                   13695:     Copy_arg *a;
                   13696: {   static RLE_Line rl;
                   13697:     unsigned char *inline;
                   13698:     register unsigned char *cp,*ep,*rb;
                   13699:        a->bop = F;
                   13700:        if(PIC_rline(a->ph,&inline)==1) {
                   13701:                /* reverse bit order in each byte */
                   13702:                rb=bm_consts.Rbits;
                   13703:                ep=(cp=inline)+a->ph->bpl;
                   13704:                while(cp<ep) { *cp = rb[*cp]; cp++; };
                   13705:                rl.runs =
                   13706:                    rlbr(inline,0,a->ph->bx.b.x-a->ph->bx.a.x,a->ph->bx.a.x,rl.r);
                   13707:                rl.y = a->ph->cy;
                   13708:                rl.len = a->wid;
                   13709:                if(_O.dbg_r) nerr_RLE_Line("bitmap_source: ",&rl);
                   13710:                return(&rl);
                   13711:                }
                   13712:        else {  if(_O.dbg_r) nerr_RLE_Line("binary_source: ",NULL);
                   13713:                return(NULL);
                   13714:                };
                   13715:        }
                   13716: 
                   13717: RLE_Line *bitfile_source(a)
                   13718:     Copy_arg *a;
                   13719: #define dbg_Bi (F)
                   13720: {   static RLE_Line rl;
                   13721:     unsigned char *cp,*ep,*pp;
                   13722:     int ch,ci;
                   13723:        a->bop = F;
                   13724:        /* copy current line to prior */
                   13725:        memcpy(a->ph->pline,a->ph->line,a->ph->bpl);
                   13726:        /* read one binary raster line */
                   13727:        ep=(cp=a->ph->line)+a->ph->bpl;
                   13728:        while(cp<ep) {
                   13729:                if((ch=getc(a->ph->fp))!=EOF) {
                   13730:                        if(ch<127) {
                   13731:                                if(dbg_Bi) err("cb: %o",ch);
                   13732:                                if((fread(cp,1,2*ch,a->ph->fp))==2*ch) {
                   13733:                                        cp += 2*ch;
                   13734:                                        }
                   13735:                                else return(NULL);
                   13736:                                }
                   13737:                        else {  ch &= 0x7F;
                   13738:                                if(dbg_Bi) err("cb: 0200+%o",ch);
                   13739:                                if((fread(cp,1,2,a->ph->fp))==2) {
                   13740:                                        cp += 2;
                   13741:                                        for(ci=0;ci<ch-1;ci++,cp+=2) {
                   13742:                                                *cp = *(cp-2);
                   13743:                                                *(cp+1) = *(cp-1);
                   13744:                                                };
                   13745:                                        }
                   13746:                                else return(NULL);
                   13747:                                };
                   13748:                        }
                   13749:                else return(NULL);
                   13750:                };
                   13751:        /* reverse bit-order, & xor with prior line */
                   13752:        for(ep=(cp=a->ph->line)+a->ph->bpl,pp=a->ph->pline; cp<ep; cp++,pp++) {
                   13753:                *cp = bm_consts.Rbits[*cp] ^ *pp;
                   13754:                if(dbg_Bi) err("db: %o = ?? ^ %o",*cp,*pp);
                   13755:                };
                   13756:        rl.runs =
                   13757:            rlbr(a->ph->line,0,a->ph->bx.b.x-a->ph->bx.a.x,a->ph->bx.a.x,rl.r);
                   13758:        rl.y = ++a->ph->cy;
                   13759:        rl.len = a->wid;
                   13760:        if(_O.dbg_r) nerr_RLE_Line("bitfile_source: ",&rl);
                   13761:        return(&rl);
                   13762:        }
                   13763: 
                   13764: RLE_Line *dim_source(a)
                   13765:     Copy_arg *a;
                   13766: {   static RLE_Line *rlp,*rlq,rl;
                   13767:        if(a->bop) {
                   13768:                a->ph->cy = a->ph->bx.a.y-1;
                   13769:                rlq=(rlp=a->rles.rla)+a->rles.mny;
                   13770:                };
                   13771:        if(_O.dbg_r) {
                   13772:                err("dim_source: a->bop %d a->ph->cy %d",a->bop,a->ph->cy);
                   13773:                nerr_RLE_Line("*rlp",rlp);
                   13774:                };
                   13775:        a->bop = F;
                   13776:        a->ph->cy++;
                   13777:        if(rlp<rlq) {
                   13778:                if(a->ph->cy < rlp->y) {
                   13779:                        rl.y = a->ph->cy;
                   13780:                        rl.runs = 0;
                   13781:                        rl.len = a->wid;
                   13782:                        if(_O.dbg_r) nerr_RLE_Line("dim_source: ",&rl);
                   13783:                        return(&rl);
                   13784:                        }
                   13785:                else if(a->ph->cy == rlp->y) {
                   13786:                        rlp->len = a->wid;
                   13787:                        rlp++;
                   13788:                        if(_O.dbg_r) nerr_RLE_Line("dim_source: ",rlp-1);
                   13789:                        return(rlp-1);
                   13790:                        }
                   13791:                else {  while(rlp<rlq && a->ph->cy>rlp->y) rlp++;
                   13792:                        if(rlp>=rlq) {
                   13793:                                if(_O.dbg_r) nerr_RLE_Line("dim_source: NULL");
                   13794:                                return(NULL);
                   13795:                                }
                   13796:                        else {  rlp->len = a->wid;
                   13797:                                rlp++;
                   13798:                                if(_O.dbg_r) nerr_RLE_Line("dim_source: ",rlp-1);
                   13799:                                return(rlp-1);
                   13800:                                };
                   13801:                        };
                   13802:                }
                   13803:        else {  if(_O.dbg_r) nerr_RLE_Line("dim_source: NULL");
                   13804:                return(NULL);
                   13805:                };
                   13806:        }
                   13807: 
                   13808: RLE_Line *rle_source(a)
                   13809:     Copy_arg *a;
                   13810: {   static RLE_Line *rl;
                   13811:        a->bop = F;
                   13812:        if((rl=RLE_get_Line(a->ph->bx.a.x,a->ph->bx.b.x))!=NULL) {
                   13813:                a->ph->cy = rl->y;
                   13814:                rl->len = a->wid;
                   13815:                if(_O.dbg_r) nerr_RLE_Line("rle_source: ",rl);
                   13816:                return(rl);
                   13817:                }
                   13818:        else {  if(_O.dbg_r) nerr_RLE_Line("rle_source: ",NULL);
                   13819:                return(NULL);
                   13820:                };
                   13821:        }
                   13822: 
                   13823: /* Read next line of runs from pic file, with runs shifted to lie in the range
                   13824:    [ a->ph->bx.a.x, a->ph->bx.b.x ]. */
                   13825: RLE_Line *pic_source(a)
                   13826:     Copy_arg *a;
                   13827: {   static RLE_Line rl;
                   13828:     unsigned char *inline;
                   13829:        a->bop = F;
                   13830:        if(PIC_rline(a->ph,&inline)==1) {
                   13831:                rl.runs = trcr(inline,
                   13832:                        0,a->ph->bx.b.x-a->ph->bx.a.x,a->ph->bx.a.x,
                   13833:                        a->thresh,rl.r);
                   13834:                rl.y = a->ph->cy;
                   13835:                rl.len = a->wid;
                   13836:                if(_O.dbg_r) nerr_RLE_Line("pic_source: ",&rl);
                   13837:                return(&rl);
                   13838:                }
                   13839:        else {  if(_O.dbg_r) nerr_RLE_Line("pic_source: ",NULL);
                   13840:                return(NULL);
                   13841:                };
                   13842:        }
                   13843: 
                   13844: /* Read next line of runs from g31 file, with runs shifted to lie in the range
                   13845:    [ a->ph->bx.a.x, a->ph->bx.b.x ]. */
                   13846: RLE_Line *g31_source(a)
                   13847:     Copy_arg *a;
                   13848: {   static RLE_Line *rlp,rl;
                   13849:     RLE_Run *rp,*ep,*np;
                   13850:        if((rlp=g31_to_rlel(a->tbl,a->bf,a->bop))!=NULL) {
                   13851:                a->bop = F;
                   13852:                rlp->y = ++a->ph->cy;
                   13853:                rlp->len = a->wid;
                   13854:                if(a->ph->bx.a.x!=0) {
                   13855:                        /* must shift run indices */
                   13856:                        rl.y = rlp->y;
                   13857:                        rl.len = rlp->len;
                   13858:                        if((rl.runs=rlp->runs)>0) {
                   13859:                                for(ep=(rp=rlp->r)+rlp->runs,np=rl.r; rp<ep; rp++,np++ ) {
                   13860:                                        np->xs = rp->xs + a->ph->bx.a.x;
                   13861:                                        np->xe = rp->xe + a->ph->bx.a.x;
                   13862:                                        };
                   13863:                                };
                   13864:                        if(_O.dbg_r) nerr_RLE_Line("g31_source: ",&rl);
                   13865:                        return(&rl);
                   13866:                        }
                   13867:                else {  if(_O.dbg_r) nerr_RLE_Line("g31_source: ",rlp);
                   13868:                        return(rlp);
                   13869:                        };
                   13870:                }
                   13871:        else {  if(_O.dbg_r) nerr_RLE_Line("g31_source: ",NULL);
                   13872:                return(NULL);
                   13873:                };
                   13874:        }
                   13875: 
                   13876: /* Read next line of runs from g32 file, with runs shifted to lie in the range
                   13877:    [ a->ph->bx.a.x, a->ph->bx.b.x ]. */
                   13878: RLE_Line *g32_source(a)
                   13879:     Copy_arg *a;
                   13880: {   static RLE_Line *rlp,rl;
                   13881:     RLE_Run *rp,*ep,*np;
                   13882:        if((rlp=g32_to_rlel(a->tbl,a->bf,a->bop))!=NULL) {
                   13883:                a->bop = F;
                   13884:                rlp->y = ++a->ph->cy;
                   13885:                rlp->len = a->wid;
                   13886:                if(a->ph->bx.a.x!=0) {
                   13887:                        /* must shift run indices */
                   13888:                        if(_O.dbg_r) err("g32_source: shift +%d",a->ph->bx.a.x);
                   13889:                        rl.y = rlp->y;
                   13890:                        rl.len = rlp->len;
                   13891:                        if((rl.runs=rlp->runs)>0) {
                   13892:                                for(ep=(rp=rlp->r)+rlp->runs,np=rl.r; rp<ep; rp++,np++ ) {
                   13893:                                        np->xs = rp->xs + a->ph->bx.a.x;
                   13894:                                        np->xe = rp->xe + a->ph->bx.a.x;
                   13895:                                        };
                   13896:                                };
                   13897:                        if(_O.dbg_r) nerr_RLE_Line("g32_source: ",&rl);
                   13898:                        return(&rl);
                   13899:                        }
                   13900:                else {  if(_O.dbg_r) nerr_RLE_Line("g32_source: ",rlp);
                   13901:                        return(rlp);
                   13902:                        };
                   13903:                }
                   13904:        else {  if(_O.dbg_r) nerr_RLE_Line("g32_source: ",NULL);
                   13905:                return(NULL);
                   13906:                };
                   13907:        }
                   13908: 
                   13909: /* Read next line of runs from g4 file, after shifting runs to lie in the range
                   13910:    [ a->ph->bx.a.x, a->ph->bx.b.x ]. */
                   13911: RLE_Line *g4_source(a)
                   13912:     Copy_arg *a;
                   13913: {   static RLE_Line *rlp,rl;
                   13914:     RLE_Run *rp,*ep,*np;
                   13915:        if((rlp=g4_to_rlel(a->tbl,a->bf,a->bop,a->wid))!=NULL) {
                   13916:                a->bop = F;
                   13917:                rlp->y = ++a->ph->cy;
                   13918:                rlp->len = a->wid;
                   13919:                if(a->ph->bx.a.x!=0) { /* shift runs */
                   13920:                        rl.y = rlp->y;
                   13921:                        rl.len = rlp->len;
                   13922:                        if((rl.runs=rlp->runs)>0) {
                   13923:                                for(ep=(rp=rlp->r)+rlp->runs,np=rl.r; rp<ep; rp++,np++ ) {
                   13924:                                        np->xs = rp->xs + a->ph->bx.a.x;
                   13925:                                        np->xe = rp->xe + a->ph->bx.a.x;
                   13926:                                        };
                   13927:                                };
                   13928:                        if(_O.dbg_r) nerr_RLE_Line("g4_source: ",&rl);
                   13929:                        return(&rl);
                   13930:                        }
                   13931:                else {  if(_O.dbg_r) nerr_RLE_Line("g4_source: ",rlp);
                   13932:                        return(rlp);
                   13933:                        };
                   13934:                }
                   13935:        else {  a->bop = F;
                   13936:                if(_O.dbg_r) nerr_RLE_Line("g4_source: ",NULL);
                   13937:                return(NULL);
                   13938:                };
                   13939:        }
                   13940: 
                   13941: binary_sink(rl,a)
                   13942:     RLE_Line *rl;
                   13943:     Copy_arg *a;
                   13944: {   int stat;
                   13945:        if(_O.dbg_r) nerr_RLE_Line("binary_sink: ",rl);
                   13946:        if(a->bop) { PIC_put_hdr(a->ph); a->bop=F; }
                   13947:        if(rl!=NULL) {
                   13948:                memset(a->ph->line,'\0',a->ph->bpl);
                   13949:                if(rl->runs>0) {
                   13950:                    /* convert *rl to binary, using ``little-endian'' bit-order */
                   13951:                    brrl(rl->runs,rl->r,a->ph->bx.a.x,a->ph->bx.b.x,0,a->ph->line);
                   13952:                    };
                   13953:                if((stat=PIC_wline(a->ph,a->ph->line))!=1)
                   13954:                        abort("binary_sink: can't write: stat %d",stat);
                   13955:                };
                   13956:        return(1);
                   13957:        }
                   13958: 
                   13959: bitmap_sink(rl,a)
                   13960:     RLE_Line *rl;
                   13961:     Copy_arg *a;
                   13962: {   int stat;
                   13963:        if(_O.dbg_r) nerr_RLE_Line("bitmap_sink: ",rl);
                   13964:        if(a->bop) { PIC_put_hdr(a->ph); a->bop=F; }
                   13965:        if(rl!=NULL) {
                   13966:                memset(a->ph->line,'\0',a->ph->bpl);
                   13967:                if(rl->runs>0) {
                   13968:                    /* convert *rl to binary, using ``big-endian'' bit-order */
                   13969:                    brrlb(rl->runs,rl->r,a->ph->bx.a.x,a->ph->bx.b.x,0,a->ph->line);
                   13970:                    };
                   13971:                if((stat=PIC_wline(a->ph,a->ph->line))!=1)
                   13972:                        abort("bitmap_sink: can't write: stat %d",stat);
                   13973:                };
                   13974:        return(1);
                   13975:        }
                   13976: 
                   13977: /* Write bitfile(9.5) format */
                   13978: bitfile_sink(rl,a)
                   13979:     RLE_Line *rl;
                   13980:     Copy_arg *a;
                   13981: #define dbg_Bo (F)
                   13982: {   int stat;
                   13983:     int ci,towrite;
                   13984:     register unsigned char uc,*cp,*pp,*ep;
                   13985:        if(_O.dbg_r||dbg_Bo) nerr_RLE_Line("bitfile_sink: ",rl);
                   13986:        if(a->bop) { PIC_put_hdr(a->ph); a->bop=F; }
                   13987:        if(rl!=NULL) {
                   13988:                /* copy current to prior */
                   13989:                memcpy(a->ph->pline,a->ph->line,a->ph->bpl);
                   13990:                memset(a->ph->line,'\0',a->ph->bpl);
                   13991:                if(rl->runs>0) {
                   13992:                        /* convert *rl to binary, using ``big-endian'' bit-order */
                   13993:                        brrlb(rl->runs,rl->r,
                   13994:                                a->ph->bx.a.x,a->ph->bx.b.x,
                   13995:                                0,a->ph->line);
                   13996:                        if(dbg_Bo) {
                   13997:                            unsigned char *cb,*eb;
                   13998:                                fprintf(stderr,"a->ph->line: ");
                   13999:                                for(eb=(cb=a->ph->line)+a->ph->bpl;cb<eb;cb++)
                   14000:                                        fprintf(stderr,"%02X",*cb);
                   14001:                                fprintf(stderr,"\n");
                   14002:                                };
                   14003:                        };
                   14004:                /* break up output into blocks of 2*126 bytes;
                   14005:                   SHOULD also try run-length coding */
                   14006:                ci=0;  while((towrite=a->ph->bpl-ci) > 0) {
                   14007:                        if(towrite >= 2*127) towrite=2*126;
                   14008:                        /* write control byte for block */
                   14009:                        uc = towrite/2;
                   14010:                        if(dbg_Bo) err("cb: %02X",uc);
                   14011:                        putc(uc,a->ph->fp);
                   14012:                        for(ep=(cp=a->ph->line+ci)+towrite,pp=a->ph->pline+ci;
                   14013:                             cp<ep; cp++,pp++) {
                   14014:                                /* write XOR byte */
                   14015:                                uc = *cp ^ *pp;
                   14016:                                if(dbg_Bo) err("db %d: %02X = c%02X ^ p%02X",cp-a->ph->line,uc,*cp,*pp);
                   14017:                                putc(uc,a->ph->fp);
                   14018:                                };
                   14019:                        ci += towrite;
                   14020:                        };
                   14021:                }
                   14022:        else {  free(a->ph->line);  a->ph->line=NULL;
                   14023:                free(a->ph->pline);  a->ph->pline=NULL;
                   14024:                fflush(a->ph->fp);
                   14025:                };
                   14026:        }
                   14027: 
                   14028: rle_sink(rl,a)
                   14029:     RLE_Line *rl;
                   14030:     Copy_arg *a;
                   14031: {      if(_O.dbg_r) nerr_RLE_Line("rle_sink: ",rl);
                   14032:        if(a->bop) {
                   14033:            RIC_hdr rh;
                   14034:                rh.bx = a->ph->bx;
                   14035:                rh.res_x = a->ph->res_x;
                   14036:                rh.res_y = a->ph->res_y;
                   14037:                RLE_put_hdr(fileno(a->ph->fp),&rh,1);
                   14038:                a->ph->cy = a->ph->bx.a.y-1;
                   14039:                a->bop=F;
                   14040:                };
                   14041:        if(rl!=NULL) {
                   14042:                if(rl->runs>0) RLE_put_Line(fileno(a->ph->fp),rl);
                   14043:                a->ph->cy++;
                   14044:                }
                   14045:        else RLE_close(fileno(a->ph->fp));
                   14046:        return(1);
                   14047:        }
                   14048: 
                   14049: /* Write next line of runs to g31 file, after shifting runs to lie in the range
                   14050:    [ 0, a->ph->bx.b.x - a->ph->bx.a.x ]. */
                   14051: g31_sink(rl,a)
                   14052:     RLE_Line *rl;
                   14053:     Copy_arg *a;
                   14054: {   int stat;
                   14055:     RLE_Line crl;
                   14056:     RLE_Run *rp,*ep,*np;
                   14057:        if(_O.dbg_r) nerr_RLE_Line("g31_sink: ",rl);
                   14058:        if(a->bop) {
                   14059:                PIC_put_hdr(a->ph);
                   14060:                /* treat FILE *a->ph->fp as a sequence of bits */
                   14061:                if((a->bf=bopen(a->ph->fp,"w"))==NULL)
                   14062:                        abort("g31_sink: can't open bitfile");
                   14063:                BOF_to_g31(a->bf);
                   14064:                a->bop=F;
                   14065:                };
                   14066:        if(rl!=NULL) {
                   14067:                /* check that rl->len is consistent with a->ph */
                   14068:                if(rl->len != a->ph->bx.b.x - a->ph->bx.a.x + 1) {
                   14069:                        err("g31_sink: rl->len %d != wid(a->ph.bx) %d",
                   14070:                                rl->len, a->ph->bx.b.x - a->ph->bx.a.x + 1);
                   14071:                        rl->len = a->ph->bx.b.x - a->ph->bx.a.x + 1;
                   14072:                        };
                   14073:                if(rl->runs>0) {
                   14074:                        if(a->ph->bx.a.x!=0) { /* shift runs */
                   14075:                                crl.y = rl->y;
                   14076:                                crl.len = rl->len;
                   14077:                                crl.runs = rl->runs;
                   14078:                                for(ep=(rp=rl->r)+rl->runs,np=crl.r;
                   14079:                                     rp<ep;
                   14080:                                      rp++,np++) {
                   14081:                                        np->xs = rp->xs - a->ph->bx.a.x;
                   14082:                                        np->xe = rp->xe - a->ph->bx.a.x;
                   14083:                                        };
                   14084:                                rlel_to_g31(&crl,crl.len,a->bf);
                   14085:                                }
                   14086:                        else rlel_to_g31(rl,rl->len,a->bf);
                   14087:                        }
                   14088:                else rlel_to_g31(NULL,rl->len,a->bf);
                   14089:                a->ph->cy++;
                   14090:                }
                   14091:        else {  EOF_to_g31(a->bf);
                   14092:                bclose(a->bf);
                   14093:                };
                   14094:        return(1);
                   14095:        }
                   14096: 
                   14097: /* Write next line of runs to g32 file, after shifting runs to lie in the range
                   14098:    [ 0, a->ph->bx.b.x - a->ph->bx.a.x ]. */
                   14099: g32_sink(rl,a)
                   14100:     RLE_Line *rl;
                   14101:     Copy_arg *a;
                   14102: {   static RLE_Line prl;
                   14103:     RLE_Line *pl;
                   14104:     RLE_Line crl;
                   14105:     RLE_Run *rp,*ep,*np;
                   14106:        if(_O.dbg_r) nerr_RLE_Line("g32_sink: ",rl);
                   14107:        if(a->bop) {
                   14108:                PIC_put_hdr(a->ph);
                   14109:                /* treat FILE *a->ph->fp as a sequence of bits */
                   14110:                if((a->bf=bopen(a->ph->fp,"w"))==NULL)
                   14111:                        abort("can't open bitfile");
                   14112:                BOF_to_g32(a->bf);
                   14113:                a->bop=F;
                   14114:                prl.runs = 0;
                   14115:                };
                   14116:        if(rl!=NULL) {
                   14117:                /* check that rl->len is consistent with a->ph */
                   14118:                if(rl->len != a->ph->bx.b.x - a->ph->bx.a.x + 1) {
                   14119:                        err("g32_sink: rl->len %d != wid(a->ph.bx) %d",
                   14120:                                rl->len, a->ph->bx.b.x - a->ph->bx.a.x + 1);
                   14121:                        rl->len = a->ph->bx.b.x - a->ph->bx.a.x + 1;
                   14122:                        };
                   14123:                prl.len = rl->len;
                   14124:                prl.y = rl->y - 1;
                   14125:                if(((a->ph->cy+1-a->ph->bx.a.y)%a->k)==0) pl=NULL; else pl=&prl;
                   14126:                if(rl->runs>0) {
                   14127:                        if(a->ph->bx.a.x!=0) { /* shift runs */
                   14128:                                crl.y = rl->y;
                   14129:                                crl.len = rl->len;
                   14130:                                crl.runs = rl->runs;
                   14131:                                for(ep=(rp=rl->r)+rl->runs,np=crl.r;
                   14132:                                     rp<ep;
                   14133:                                      rp++,np++) {
                   14134:                                        np->xs = rp->xs - a->ph->bx.a.x;
                   14135:                                        np->xe = rp->xe - a->ph->bx.a.x;
                   14136:                                        };
                   14137:                                rlel_to_g32(pl,&crl,crl.len,a->bf);
                   14138:                                prl.y=crl.y;
                   14139:                                prl.len=crl.len;
                   14140:                                prl.runs=crl.runs;
                   14141:                                memcpy(prl.r,crl.r,2*prl.runs*sizeof(short));
                   14142:                                }
                   14143:                        else {  rlel_to_g32(pl,rl,rl->len,a->bf);
                   14144:                                prl.y=rl->y;
                   14145:                                prl.len=rl->len;
                   14146:                                prl.runs=rl->runs;
                   14147:                                memcpy(prl.r,rl->r,2*prl.runs*sizeof(short));
                   14148:                                };
                   14149:                        }
                   14150:                else {  rlel_to_g32(pl,NULL,rl->len,a->bf);
                   14151:                        prl.y=rl->y;
                   14152:                        prl.len=rl->len;
                   14153:                        prl.runs=0;
                   14154:                        }
                   14155:                a->ph->cy++;
                   14156:                }
                   14157:        else {  EOF_to_g32(a->bf);
                   14158:                bclose(a->bf);
                   14159:                prl.runs = 0;
                   14160:                };
                   14161:        return(1);
                   14162:        }
                   14163: 
                   14164: /* Write next line of runs to g4 file, after shifting runs to lie in the range
                   14165:    [ 0, a->ph->bx.b.x - a->ph->bx.a.x ]. */
                   14166: g4_sink(rl,a)
                   14167:     RLE_Line *rl;
                   14168:     Copy_arg *a;
                   14169: {   static RLE_Line prl;
                   14170:     RLE_Line crl;
                   14171:     RLE_Run *rp,*ep,*np;
                   14172:        if(_O.dbg_r) nerr_RLE_Line("g4_sink: ",rl);
                   14173:        if(a->bop) {
                   14174:                PIC_put_hdr(a->ph);
                   14175:                /* treat FILE *a->ph->fp as a sequence of bits */
                   14176:                if((a->bf=bopen(a->ph->fp,"w"))==NULL)
                   14177:                        abort("can't open bitfile");
                   14178:                BOF_to_g4(a->bf);
                   14179:                a->bop=F;
                   14180:                prl.runs = 0;
                   14181:                };
                   14182:        if(rl!=NULL) {
                   14183:                /* check that rl->len is consistent with a->ph */
                   14184:                if(rl->len != a->ph->bx.b.x - a->ph->bx.a.x + 1) {
                   14185:                        err("g4_sink: rl->len %d != wid(a->ph.bx) %d",
                   14186:                                rl->len, a->ph->bx.b.x - a->ph->bx.a.x + 1);
                   14187:                        rl->len = a->ph->bx.b.x - a->ph->bx.a.x + 1;
                   14188:                        };
                   14189:                if(rl->runs>0) {
                   14190:                        if(a->ph->bx.a.x!=0) { /* shift runs */
                   14191:                                crl.y = rl->y;
                   14192:                                crl.len = rl->len;
                   14193:                                crl.runs = rl->runs;
                   14194:                                for(ep=(rp=rl->r)+rl->runs,np=crl.r;
                   14195:                                     rp<ep;
                   14196:                                      rp++,np++) {
                   14197:                                        np->xs = rp->xs - a->ph->bx.a.x;
                   14198:                                        np->xe = rp->xe - a->ph->bx.a.x;
                   14199:                                        };
                   14200:                                rlel_to_g4(&prl,&crl,crl.len,a->bf);
                   14201:                                prl.y=crl.y;
                   14202:                                prl.len=crl.len;
                   14203:                                prl.runs=crl.runs;
                   14204:                                memcpy(prl.r,crl.r,2*prl.runs*sizeof(short));
                   14205:                                }
                   14206:                        else {  rlel_to_g4(&prl,rl,rl->len,a->bf);
                   14207:                                prl.y=rl->y;
                   14208:                                prl.len=rl->len;
                   14209:                                prl.runs=rl->runs;
                   14210:                                memcpy(prl.r,rl->r,2*prl.runs*sizeof(short));
                   14211:                                };
                   14212:                        }
                   14213:                else {  rlel_to_g4(&prl,NULL,rl->len,a->bf);
                   14214:                        prl.runs=0;
                   14215:                        }
                   14216:                a->ph->cy++;
                   14217:                }
                   14218:        else {  EOF_to_g4(a->bf);
                   14219:                bclose(a->bf);
                   14220:                prl.runs = 0;
                   14221:                };
                   14222:        return(1);
                   14223:        }
                   14224: 
                   14225: pic_sink(rl,a)
                   14226:     RLE_Line *rl;
                   14227:     Copy_arg *a;
                   14228: {   int stat;
                   14229:        if(_O.dbg_r) nerr_RLE_Line("pic_sink: ",rl);
                   14230:        if(a->bop) {
                   14231:                PIC_put_hdr(a->ph);
                   14232:                a->bop=F;
                   14233:                };
                   14234:        if(rl!=NULL) {
                   14235:                crrl(rl->runs,rl->r,0,a->ph->bx.b.x-a->ph->bx.a.x,a->ph->line);
                   14236:                if((stat=PIC_wline(a->ph,a->ph->line))!=1)
                   14237:                        abort("pic_sink: can't write: stat %d",stat);
                   14238:                };
                   14239:        return(1);
                   14240:        }
                   14241: 
                   14242: #if CPU==SUN
                   14243: post_sink(rl,a)
                   14244:     RLE_Line *rl;
                   14245:     Copy_arg *a;
                   14246: {   int stat;
                   14247:        if(_O.dbg_r) nerr_RLE_Line("post_sink: ",rl);
                   14248:        if (a->bop) {
                   14249:                PIC_put_hdr(a->ph);     /* needed for allocation of h->line? */
                   14250:                POST_start(a->ph);
                   14251:                a->bop = F;
                   14252:                };
                   14253:        if(rl!=NULL) {
                   14254:                memset(a->ph->line,'\0',a->ph->bpl);
                   14255:                if(rl->runs>0) {
                   14256:                    /* convert *rl to binary, using ``little-endian'' bit-order */
                   14257:                    brrl(rl->runs,rl->r,a->ph->bx.a.x,a->ph->bx.b.x,0,a->ph->line);
                   14258:                    };
                   14259:                if((stat=POST_wline(a->ph,a->ph->line))!=1)
                   14260:                        abort("post_sink: can't write: stat %d",stat);
                   14261:                }
                   14262:        else {  POST_end();
                   14263:                };
                   14264:        return(1);
                   14265:        }
                   14266: #else
                   14267: post_sink() {abort("-P postscript output unimplemented");};
                   14268: #endif
                   14269: 
                   14270: #if CPU==SUN
                   14271: rast_sink(rl,a)
                   14272:     RLE_Line *rl;
                   14273:     Copy_arg *a;
                   14274: {   int stat;
                   14275:        if(_O.dbg_r) nerr_RLE_Line("rast_sink: ",rl);
                   14276:        if (a->bop) {
                   14277:                PIC_put_hdr(a->ph);     /* needed for allocation of h->line? */
                   14278:                RAST_start(a->ph);
                   14279:                a->bop = F;
                   14280:                };
                   14281:        if(rl!=NULL) {
                   14282:                memset(a->ph->line,'\0',a->ph->bpl);
                   14283:                if(rl->runs>0) {
                   14284:                    /* convert *rl to binary, using ``little-endian'' bit-order */
                   14285:                    brrl(rl->runs,rl->r,a->ph->bx.a.x,a->ph->bx.b.x,0,a->ph->line);
                   14286:                    };
                   14287:                if((stat=RAST_wline(a->ph,a->ph->line))!=1)
                   14288:                        abort("rast_sink: can't write: stat %d",stat);
                   14289:                }
                   14290:        else {  RAST_end();
                   14291:                };
                   14292:        return(1);
                   14293:        }
                   14294: #else
                   14295: rast_sink() {abort("-S sunraster output unimplemented");};
                   14296: #endif
                   14297: 
                   14298: /* Save RLE_Line *rl in buffer, as packed binary, using ``little-endian''
                   14299:    bit-packing order, rounding each line to the nearest int for speed.
                   14300:    If a->bop, malloc a complete, contiguous buffer holding the entire page,
                   14301:    and initialize its contents to zeroes.
                   14302:    On each call with rl!=NULL, convert the given line to binary & save in buffer.
                   14303:    When called with rl==NULL but a!=NULL, signalling end-of-page, do nothing.
                   14304:    Normally, return kludgey (unsigned int *)1, like other sink functions.
                   14305:    When called with rl==NULL && a==NULL, return pointer to buffer.
                   14306:    It is the responsibility of the calling code to free the buffer. */
                   14307: unsigned int *binary_buffer(rl,a)
                   14308:     RLE_Line *rl;
                   14309:     Copy_arg *a;
                   14310: {   static unsigned int *buf = NULL;
                   14311:     static int ipl = 0;        /* ints/line */
                   14312:     int bufsz;         /* (bytes) */
                   14313:     unsigned int *result;
                   14314: #define BITS_PER_INT (8*sizeof(int))
                   14315:        if(a!=NULL && a->bop) {
                   14316:                /* round up to int boundary */
                   14317:                ipl = (bbx_wid(&(a->ph->bx))+BITS_PER_INT-1)/BITS_PER_INT;
                   14318:                bufsz = sizeof(int)*ipl*bbx_hgt(&(a->ph->bx));
                   14319:                if((buf=(unsigned int *)malloc(bufsz))==NULL)
                   14320:                        abort("binary_buffer: can't alloc int buf[%d]",bufsz/sizeof(int));
                   14321:                memset(buf,'\0',bufsz);
                   14322:                a->bop=F;
                   14323:                };
                   14324:        if(rl!=NULL) {
                   14325:                /* convert *rl to binary, using ``little-endian'' bit-order */
                   14326:                if(rl->runs>0) {
                   14327:                        /* *rl --> binary, with ``little-endian'' bit-order */
                   14328: #if BIG_ENDIAN
                   14329:                        brrlb( rl->runs, rl->r, a->ph->bx.a.x, a->ph->bx.b.x,
                   14330:                                0, buf+(ipl*(rl->y-a->ph->bx.a.y)) );
                   14331: #else
                   14332:                        brrl( rl->runs, rl->r, a->ph->bx.a.x, a->ph->bx.b.x,
                   14333:                                0, buf+(ipl*(rl->y-a->ph->bx.a.y)) );
                   14334: #endif
                   14335:                        };
                   14336:                return((unsigned int *)1);
                   14337:                }
                   14338:        else {  if(a!=NULL) return((unsigned int *)1);
                   14339:                else {  result = buf;
                   14340:                        buf = NULL;  ipl = 0;
                   14341:                        return(result);
                   14342:                        };
                   14343:                };
                   14344:        }
                   14345: 
                   14346: /* Rotate binary buffer *buf (whose shape is specified by a->ph->bx),
                   14347:    through angle tra->rot, and write the resulting stream of RLE_Line's to
                   14348:    sink() one at a time, along with a rotated version of *a as the 2nd argument.
                   14349:    Only PI/2 is supported; UNDER DEVELOPMENT:  other multiples of PI/2 and
                   14350:    small arbitrary angles. */
                   14351: rotate_binary_buffer(buf,tra,sink,a)
                   14352:     unsigned int *buf;
                   14353:     Transform_rlel_arg *tra;
                   14354:     int (*sink)();     /* takes args:  (RLE_Line *), and int */
                   14355:     Copy_arg *a;
                   14356: {   register int ipl;          /* ints/line in binary buffer */
                   14357:     Copy_arg ra;               /* rotated */
                   14358:     RLE_Line rl;
                   14359: #define TINY_ANG (PI/1000)
                   14360:        /* round up to int boundary */
                   14361:        ipl = (bbx_wid(&(a->ph->bx))+BITS_PER_INT-1)/BITS_PER_INT;
                   14362:        ra = *a;
                   14363:        ra.bop=T;
                   14364:        if((ra.ph = (PIC_hdr *)malloc(sizeof(PIC_hdr)))==NULL)
                   14365:                abort("rotate_binary_buffer: can't malloc ra.ph");
                   14366:        *(ra.ph) = *(a->ph);
                   14367:        /* by arbitrary convention, rotated bx.a will coincide with input bx.a */
                   14368:        if(tra->rot <= PI/2+TINY_ANG && tra->rot >= PI/2-TINY_ANG) {
                   14369:            int ey,ii;
                   14370:            register RLE_Run *rp;
                   14371:            register unsigned int *cb,*eb,bm,obm;
                   14372:            register short rx;
                   14373:                ra.ph->bx.b.x = a->ph->bx.a.x + bbx_hgt(&(a->ph->bx)) - 1;
                   14374:                ra.ph->bx.b.y = a->ph->bx.a.y + bbx_wid(&(a->ph->bx)) - 1;
                   14375:                rl.len = ra.wid = bbx_wid(&(ra.ph->bx));
                   14376:                rl.y = ra.ph->bx.a.y;  ey=ra.ph->bx.b.y;
                   14377:                ii=0;  bm=01;
                   14378:                do {    obm=0;  /* assume 0 left of margin */
                   14379:                        rp=rl.r-1;
                   14380:                        rx=ra.ph->bx.a.x;
                   14381:                        cb=(eb=buf+ii)+((rl.len-1)*ipl);
                   14382:                        do {    if((*cb & bm)!=obm) {
                   14383:                                        if(obm) { rp->xe=rx-1;  obm=0; }
                   14384:                                        else { (++rp)->xs=rx;  obm=bm; };
                   14385:                                        };
                   14386:                                rx++;
                   14387:                                }
                   14388:                        while( (cb -= ipl) >= eb );
                   14389:                        if(obm) rp->xe=rx-1;
                   14390:                        rl.runs = rp - rl.r + 1;
                   14391:                        sink(&rl,&ra);
                   14392:                        if((bm<<=1)==0) {ii++; bm=01;};
                   14393:                        }
                   14394:                while((++rl.y)<=ey);
                   14395:                }
                   14396:        else if(tra->rot <= PI+TINY_ANG && tra->rot >= PI-TINY_ANG) {
                   14397:                rl.len = ra.wid;
                   14398:                abort("rotate_binary_buffer: tra->rot==%g deg unimplemented",
                   14399:                        tra->rot/DtoR);
                   14400:                }
                   14401:        else if(tra->rot <= 3*PI/2+TINY_ANG && tra->rot >= 3*PI/2-TINY_ANG) {
                   14402:                ra.ph->bx.b.x = a->ph->bx.a.x + bbx_hgt(&(a->ph->bx)) - 1;
                   14403:                ra.ph->bx.b.y = a->ph->bx.a.y + bbx_wid(&(a->ph->bx)) - 1;
                   14404:                rl.len = ra.wid = bbx_wid(&(ra.ph->bx));
                   14405:                abort("rotate_binary_buffer: tra->rot==%g deg unimplemented",
                   14406:                        tra->rot/DtoR);
                   14407:                }
                   14408:        else if(tra->rot <= 20.0*DtoR && tra->rot >= -20.0*DtoR) {
                   14409:            /* rotation by ``small'' angle */
                   14410:            Sp ce;              /* center of image to be rotated */
                   14411:            double rcos,rsin;   /* real rotation vector (cos,sin) */
                   14412:            double irx,iry;     /* current rotated pixel location */
                   14413:            register int sx,sy,ex,ey,rx,ry;
                   14414:            register RLE_Run *rp;
                   14415:            register int pel,opel;
                   14416:            register int orx,ory;
                   14417:                if(0) err("rotate_binary_buffer: tra->rot==%g deg under development",
                   14418:                        tra->rot/DtoR);
                   14419:                /* conventionally, keep the same window as the input image,
                   14420:                   while rotating about its midpoint */
                   14421:                rl.len = ra.wid = bbx_wid(&(ra.ph->bx));
                   14422:                sx = ra.ph->bx.a.x;  ex = ra.ph->bx.b.x;
                   14423:                sy = ra.ph->bx.a.y;  ey = ra.ph->bx.b.y;
                   14424:                ce.x = sx + bbx_wid(&(ra.ph->bx))/2;
                   14425:                ce.y = sy + bbx_hgt(&(ra.ph->bx))/2;
                   14426:                rcos = cos(tra->rot);  rsin = sin(tra->rot);
                   14427:                for(ory=sy; ory<=ey; ory++) {
                   14428:                        opel=0; /* left of output margin: assume pel==0 */
                   14429:                        rp=rl.r-1;
                   14430:                        irx = ((rcos*(sx - ce.x) - rsin*(ory - ce.y))) + ce.x;
                   14431:                        iry = ((rsin*(sx - ce.x) + rcos*(ory - ce.y))) + ce.y;
                   14432:                        for(orx=sx; orx<=ex; orx++) {
                   14433:                                rx = (int)(irx + 0.5);  ry = (int)(iry + 0.5);
                   14434:                                if(rx<sx || rx>ex || ry<sy || ry>ey)
                   14435:                                        /* outside input image:  assume pel==0 */
                   14436:                                        pel=0;
                   14437:                                else /* look at bit within input image */ {
                   14438:                                    int ix,iy,bx;
                   14439:                                        iy = (ry-sy)*ipl;
                   14440:                                        ix = rx/BITS_PER_INT;
                   14441:                                        bx = rx%BITS_PER_INT;
                   14442: #if BIG_ENDIAN
                   14443:                                        pel = (buf[ iy + ix ] & (01<<(BITS_PER_INT-bx-1))) ? 1 : 0;
                   14444: #else
                   14445:                                        pel = (buf[ iy + ix ] & (01<<bx)) ? 1 : 0;
                   14446: #endif
                   14447:                                        };
                   14448:                                if(pel!=opel) {
                   14449:                                        if(opel) { rp->xe=orx-1;  opel=0; }
                   14450:                                        else { (++rp)->xs=orx;  opel=pel; };
                   14451:                                        };
                   14452:                                /* step one pel to the right in output image */
                   14453:                                irx += rcos;  iry += rsin;
                   14454:                                };
                   14455:                        if(opel) rp->xe=orx-1;
                   14456:                        rl.runs = rp - rl.r + 1;
                   14457:                        rl.y = ory;
                   14458:                        sink(&rl,&ra);
                   14459:                        };
                   14460:                }
                   14461:        else {  abort("rotate_binary_buffer: tra->rot==%g deg unimplemented",
                   14462:                        tra->rot/DtoR);
                   14463:                };
                   14464:        sink(NULL,&ra); /* signal end-of-page */
                   14465:        }
                   14466: 
                   14467: /* Copy a source of RLE_Lines to a sink of RLE_Lines, transforming them
                   14468:    by trimming, shifting, scaling, truncation, and rotation.
                   14469:       The source is function ir(), which returns non-empty lines only,
                   14470:    or NULL on end of page.  It is passed `bop=T' on beginning of page.
                   14471:    On return from ir(), ia->ph->cy holds the index of the line, whose height is
                   14472:    guaranteed to lie in the range [ia->ph->bx.a.y,ia->ph->bx.b.y].
                   14473:    All input runs are guaranteed to lie in [ia->ph->bx.a.x,ia->ph->bx.b.x].
                   14474:    The maximum length (in pels) of each source line is ia->wid.
                   14475:       The sink function or() takes two arguments:
                   14476:        RLE_Line *rl;   ==NULL on end-of-page
                   14477:        Copy_arg *a;
                   14478:    The lines sent to the sink must be in unbroken ascending integer 
                   14479:    sequence of rl->y (thus blank lines must be explicitly sent).   At all times,
                   14480:    oa->ph->cy is the line last written.  After the first call to or(),
                   14481:    oa->ph->cy lies in the range [oa->ph->bx.a.y,oa->ph->bx.b.y].
                   14482:       Trimming, shifting, scaling, and truncation are performed either
                   14483:    here or in  function transform_rlel().  Rotation is handled specially:
                   14484:    the complete output image (after all other transformations have been
                   14485:    performed) is saved in an intermediate buffer (as packed binary), then
                   14486:    rotated.  Rotation is much slower than the other operations, mainly due
                   14487:    to the necessity of touching every pixel.  (Manhattan rotations might be
                   14488:    faster if the buffer held RLE_lines, but then it would be next-to-impossible
                   14489:    to extend to arbitrary rotations someday.)
                   14490:    */
                   14491: transform_rlels(ir,ia,or,oa,tra)
                   14492:     RLE_Line *(*ir)(); /* return next RLE_Line */
                   14493:     Copy_arg *ia;      /* used here (bop & wid) & passed to ir() */
                   14494:     int (*or)();       /* write next RLE_Line */
                   14495:     Copy_arg *oa;      /* used here (bop && ph->bx.*.y) & passed to or() */
                   14496:     Transform_rlel_arg *tra;
                   14497: {   RLE_Line *irl,*orl;
                   14498:     static RLE_Line rl0 = Init_RLE_Line;  /* empty line */
                   14499:     int tr_y;          /* transformed y */
                   14500:     int (*sv_or)();
                   14501:        if(tra->rot!=0.0) {
                   14502:                /* if must rotate the image, first buffer the entire
                   14503:                   set of output RLE_Lines */
                   14504:                sv_or = or;
                   14505:                or = (int (*)())binary_buffer;
                   14506:                };
                   14507:        /* signal beginning of page; reset in source() & sink() functions */
                   14508:        ia->bop=oa->bop=T;      
                   14509:        /* set first output line number to write */
                   14510:        tra->dy = (tra->sy = oa->ph->bx.a.y);
                   14511:        while((irl=ir(ia))!=NULL) {
                   14512:                if(F&&_O.dbg_r) nerr_RLE_Line("trans.i: ",irl);
                   14513:                /* trim input lines' Y */
                   14514:                if(irl->y < tra->tr.a.y) continue;
                   14515:                if(irl->y > tra->tr.b.y) break;
                   14516:                /* compute the output Y that is equal to the last
                   14517:                   of the group of transformed equivalent Y's */
                   14518:                tr_y = (int)((irl->y + tra->off.y + 1)*tra->scl.y) - 1;
                   14519:                /* truncate if necessary */
                   14520:                if(tr_y>oa->ph->bx.b.y) tr_y = oa->ph->bx.b.y;
                   14521:                /* supply implicit blank line(s) of the same length */
                   14522:                while(tra->sy < tr_y) {
                   14523:                        rl0.len = ia->wid;
                   14524:                        transform_rlel(&rl0,tra,or,oa);
                   14525:                        };
                   14526:                irl->len = ia->wid;
                   14527:                transform_rlel(irl,tra,or,oa);
                   14528:                };
                   14529:        /* supply terminating blank line(s) of the same length */
                   14530:        while(tra->sy < oa->ph->bx.b.y) {
                   14531:                rl0.len = ia->wid;
                   14532:                transform_rlel(&rl0,tra,or,oa);
                   14533:                };
                   14534:        transform_rlel(NULL,tra,or,oa);   /* signal end of page */
                   14535:        /* read input until end of page occurs; this is required
                   14536:           to support catenated pages */
                   14537:        while(irl!=NULL) irl=ir(ia);
                   14538:        if(tra->rot!=0.0) {
                   14539:            unsigned int *buf;
                   14540:                buf = binary_buffer(NULL,NULL);
                   14541:                if(buf!=NULL) { 
                   14542:                        rotate_binary_buffer(buf,tra,sv_or,oa);
                   14543:                        free(buf);
                   14544:                        };
                   14545:                };
                   14546:        }
                   14547: 
                   14548: process_page(i,o)
                   14549:     Copy_arg *i,*o;
                   14550: {   RLE_Line *(*source)();
                   14551:     int (*sink)();
                   14552:     char unit,*up,cpy[40];             /* units character */
                   14553:     Transform_rlel_arg tra;
                   14554: 
                   14555:        i->wid = bbx_wid(&(i->ph->bx));
                   14556: 
                   14557:        _O.trim = max_Bbx;      /* start by trimming nothing */
                   14558:        /* translate units in option arguments */
                   14559:        if(_O.optarg_l!=NULL) {
                   14560:                strcpy(cpy,_O.optarg_l);
                   14561:                if((up=strpbrk(cpy,UNITS))!=NULL) {
                   14562:                        unit= *up;  *up='\0';
                   14563:                        _O.trim.a.x=vto_scoor(atof(cpy),unit,i->ph->res_x);
                   14564:                        }
                   14565:                else /* assume scanner coordinates */
                   14566:                        _O.trim.a.x=atoi(cpy);
                   14567:                };
                   14568:        if(_O.optarg_r!=NULL) {
                   14569:                strcpy(cpy,_O.optarg_r);
                   14570:                if((up=strpbrk(cpy,UNITS))!=NULL) {
                   14571:                        unit= *up;  *up='\0';
                   14572:                        _O.trim.b.x=vto_scoor(atof(cpy),unit,i->ph->res_x);
                   14573:                        }
                   14574:                else /* assume scanner coordinates */
                   14575:                        _O.trim.b.x=atoi(cpy);
                   14576:                _O.trim.b.x--;  /* -w coordinate is open, Bbx is closed */
                   14577:                };
                   14578:        if(_O.optarg_t!=NULL) {
                   14579:                strcpy(cpy,_O.optarg_t);
                   14580:                if((up=strpbrk(cpy,UNITS))!=NULL) {
                   14581:                        unit= *up;  *up='\0';
                   14582:                        _O.trim.a.y=vto_scoor(atof(cpy),unit,i->ph->res_y);
                   14583:                        }
                   14584:                else /* assume scanner coordinates */
                   14585:                        _O.trim.a.y=atoi(cpy);
                   14586:                };
                   14587:        if(_O.optarg_b!=NULL) {
                   14588:                strcpy(cpy,_O.optarg_b);
                   14589:                if((up=strpbrk(cpy,UNITS))!=NULL) {
                   14590:                        unit= *up;  *up='\0';
                   14591:                        _O.trim.b.y=vto_scoor(atof(cpy),unit,i->ph->res_y);
                   14592:                        }
                   14593:                else /* assume scanner coordinates */
                   14594:                        _O.trim.b.y=atoi(cpy);
                   14595:                _O.trim.b.y--;  /* -w coordinate is open, Bbx is closed */
                   14596:                };
                   14597:        /* Modified output margins may lie OUTSIDE the input window as well
                   14598:           as within it. */
                   14599:        if(_O.trim.a.x==Scoor_MIN) _O.trim.a.x=i->ph->bx.a.x;
                   14600:        if(_O.trim.b.x==Scoor_MAX) _O.trim.b.x=i->ph->bx.b.x;
                   14601:        if(_O.trim.a.y==Scoor_MIN) _O.trim.a.y=i->ph->bx.a.y;
                   14602:        if(_O.trim.b.y==Scoor_MAX) _O.trim.b.y=i->ph->bx.b.y;
                   14603:        if(_O.dbg_m) err("trim: %s",bbx_toa(&(_O.trim)));
                   14604: 
                   14605:        if(strcmp(i->ph->type,"binary")==0) { source = binary_source; }
                   14606:        else if(strcmp(i->ph->type,"bitmap")==0) { source = bitmap_source; }
                   14607:        else if(strcmp(i->ph->type,"bitfile")==0) { source = bitfile_source; }
                   14608:        else if(strcmp(i->ph->type,"document-image")==0) { source = dim_source; }
                   14609:        else if(strcmp(i->ph->type,"dim")==0) { source = dim_source; }
                   14610:        else if(strcmp(i->ph->type,"rle")==0) {
                   14611:            RIC_hdr rh;
                   14612:                /* reopen RLE file to use system I/O (awkward, obsolescent) */
                   14613:                lseek(fileno(i->ph->fp),0L,0);
                   14614:                RLE_open(fileno(i->ph->fp),&rh);
                   14615:                i->ph->cy = i->ph->bx.a.y-1;
                   14616:                source = rle_source;
                   14617:                }
                   14618:        else if(strcmp(i->ph->type,"pico")==0
                   14619:                ||strcmp(i->ph->type,"dump")==0) {
                   14620:                i->thresh = _O.thresh;
                   14621:                source = pic_source;
                   14622:                }
                   14623:        else if(strcmp(i->ph->type,"ccitt-g31")==0) {
                   14624:                if((i->bf=bopen(i->ph->fp,"r"))==NULL)
                   14625:                        abort("can't open bitfile");
                   14626:                i->tbl = ccitt_table();
                   14627:                source = g31_source;
                   14628:                }
                   14629:        else if(strcmp(i->ph->type,"ccitt-g32")==0) {
                   14630:                if((i->bf=bopen(i->ph->fp,"r"))==NULL)
                   14631:                        abort("can't open bitfile");
                   14632:                i->tbl = ccitt_table();
                   14633:                source = g32_source;
                   14634:                }
                   14635:        else if(strcmp(i->ph->type,"ccitt-g4")==0) {
                   14636:                if((i->bf=bopen(i->ph->fp,"r"))==NULL)
                   14637:                        abort("can't open bitfile");
                   14638:                i->tbl = ccitt_table();
                   14639:                source = g4_source;
                   14640:                }
                   14641:        else if(strcmp(i->ph->type,"cdf-mrlc")==0) { source = cdf_mrlc_source; }
                   14642:        else abort("Input file TYPE=%s unsupported",i->ph->type);
                   14643: 
                   14644:        if(_O.dbg_h) err("In %s",PIC_hdr_toa(i->ph));
                   14645: 
                   14646:        /* Adjudicate -R and -x options */
                   14647:        if(_O.out_res.x==-2) {
                   14648:                /* -R= specified:  force resolutions to be equal to the greater */
                   14649:                if(i->ph->res_x < i->ph->res_y) {
                   14650:                        _O.out_res.x = _O.out_res.y = i->ph->res_y;
                   14651:                        }
                   14652:                else if(i->ph->res_y < i->ph->res_x) {
                   14653:                        _O.out_res.x = _O.out_res.y = i->ph->res_x;
                   14654:                        }
                   14655:                else _O.out_res.x = _O.out_res.y = i->ph->res_x;
                   14656:                };
                   14657:        if(_O.out_res.x!=-1) {  /* -Rx specified; override -xX */
                   14658:                _O.expand.x = ((double)_O.out_res.x)/i->ph->res_x;
                   14659:                if(_O.dbg_R && _O.expand.x!=1.0)
                   14660:                        err("horizontal resolution changed: x%g (%d -> %d)",
                   14661:                                _O.expand.x,i->ph->res_x,_O.out_res.x);
                   14662:                };
                   14663:        if(_O.out_res.y!=-1) {  /* -R,y specified; override -x,Y */
                   14664:                _O.expand.y = ((double)_O.out_res.y)/i->ph->res_y;
                   14665:                if(_O.dbg_R && _O.expand.y!=1.0)
                   14666:                        err("vertical resolution changed: x%g (%d -> %d)",
                   14667:                                _O.expand.y,i->ph->res_y,_O.out_res.y);
                   14668:                };
                   14669: 
                   14670:        /* Setup image transformation parameters */
                   14671:        tra = empty_Transform_rlel_arg;
                   14672:        tra.tr = _O.trim;
                   14673:        tra.off = _O.offset;
                   14674:        tra.scl = _O.expand;
                   14675:        tra.wh.x = bbx_wid(&(tra.tr));
                   14676:        tra.wh.y = bbx_hgt(&(tra.tr));
                   14677:        tra.rev = _O.reverse;
                   14678:        if(tra.scl.x!=1.0) {
                   14679:                tra.wh.x = (int)(tra.wh.x*tra.scl.x+0.5);
                   14680:                };
                   14681:        if(tra.scl.y!=1.0) {
                   14682:                tra.wh.y = (int)(tra.wh.y*tra.scl.y+0.5);
                   14683:                };
                   14684:        switch(_O.top) {
                   14685:            case 't':  /* default */ break;
                   14686:            case 'l':  /* top is really at left */
                   14687:                tra.rot = (Radians)(PI/2);
                   14688:                break;
                   14689:            case 'b':  /* top is really at bottom */
                   14690:                tra.rot = (Radians)(PI);
                   14691:                break;
                   14692:            case 'r':  /* top is really at right */
                   14693:                tra.rot = (Radians)((3*PI)/2);
                   14694:                break;
                   14695:            case 'a':  /* rotation angle given */
                   14696:                tra.rot = _O.top_angle;
                   14697:                break;
                   14698:            };
                   14699:        /* is the transform the identity? (speed-optimized special case) */
                   14700:        tra.ident = ( (bbx_eq(&(tra.tr),&(i->ph->bx)))
                   14701:                        && (tra.scl.x==1.0)
                   14702:                        && (tra.scl.y==1.0)
                   14703:                        && (tra.off.x==0)
                   14704:                        && (tra.off.y==0)
                   14705:                        && (tra.rot==0.0) );
                   14706: 
                   14707:        /* compute transformed output box & resolution;
                   14708:           don't rotate here (see transform_rlels()) */
                   14709:        if(tra.ident) {
                   14710:                o->ph->bx = i->ph->bx;
                   14711:                o->ph->res_x = i->ph->res_x;
                   14712:                o->ph->res_y = i->ph->res_y;
                   14713:                }
                   14714:        else {  o->ph->bx = tra.tr;
                   14715:                o->ph->bx.a.x += tra.off.x;
                   14716:                o->ph->bx.b.x += tra.off.x;
                   14717:                o->ph->bx.a.y += tra.off.y;
                   14718:                o->ph->bx.b.y += tra.off.y;
                   14719:                if(tra.scl.x!=1.0) {
                   14720:                        o->ph->bx.a.x = tra.scl.x*o->ph->bx.a.x;
                   14721:                        o->ph->bx.b.x = o->ph->bx.a.x + tra.wh.x-1;
                   14722:                        };
                   14723:                if(tra.scl.y!=1.0) {
                   14724:                        o->ph->bx.a.y = tra.scl.y*o->ph->bx.a.y;
                   14725:                        o->ph->bx.b.y = o->ph->bx.a.y + tra.wh.y-1;
                   14726:                        };
                   14727:                o->ph->res_x = (i->ph->res_x*tra.scl.x + 0.5);
                   14728:                o->ph->res_y = (i->ph->res_y*tra.scl.y + 0.5);
                   14729:                };
                   14730: 
                   14731:        if(_O.to_bin)
                   14732:                { strcpy(o->ph->type,"binary"); sink = binary_sink; }
                   14733:        else if(_O.to_bitfile)
                   14734:                { strcpy(o->ph->type,"bitfile"); sink = bitfile_sink; }
                   14735:        else if(_O.to_bitmap)
                   14736:                { strcpy(o->ph->type,"bitmap"); sink = bitmap_sink; }
                   14737:        else if (_O.to_rle) {
                   14738:                if(strcmp(i->ph->type,"rle")==0)
                   14739:                        abort("can't both read and write TYPE=rle - sorry");
                   14740:                strcpy(o->ph->type,"rle"); sink = rle_sink;
                   14741:                }
                   14742:        else if(_O.to_g31) { strcpy(o->ph->type,"ccitt-g31"); sink = g31_sink; }
                   14743:        else if(_O.to_g32) {
                   14744:                strcpy(o->ph->type,"ccitt-g32");
                   14745:                o->k = _O.g32_k;
                   14746:                sink = g32_sink;
                   14747:                }
                   14748:        else if(_O.to_g4) { strcpy(o->ph->type,"ccitt-g4");  sink = g4_sink; }
                   14749:        else if(_O.to_pic) { strcpy(o->ph->type,"dump");  sink = pic_sink; }
                   14750: #if CPU==SUN
                   14751:        else if(_O.to_post) { strcpy(o->ph->type,"postscript"); sink = post_sink; }
                   14752: #endif
                   14753: #if CPU==SUN
                   14754:        else if(_O.to_rast) { strcpy(o->ph->type,"sunraster"); sink = rast_sink; }
                   14755: #endif
                   14756:        if(i->ph->misc!=NULL) {
                   14757:                o->ph->misc = i->ph->misc;
                   14758:                i->ph->misc = NULL;
                   14759:                };
                   14760:        if(_O.dbg_h) err("Out %s",PIC_hdr_toa(o->ph));
                   14761: 
                   14762:        transform_rlels(source,i,sink,o,&tra);
                   14763: 
                   14764:        /* Synchronize filedes pointer with stream pointer */
                   14765:        lseek(fileno(o->ph->fp),o->ph->seek = ftell(o->ph->fp),0);
                   14766:        }
                   14767: 
                   14768: /* A file may be a catenation of pages. */
                   14769: process_fps(i,o)
                   14770:     FILE *i,*o;
                   14771: {   Copy_arg ia,oa;
                   14772:     int stat;
                   14773:        ia = oa = empty_Copy_arg;
                   14774:        ia.ph = alloc_PIC_hdr(i);
                   14775:        oa.ph = alloc_PIC_hdr(o);
                   14776: 
                   14777:        stat=PIC_get_hdr(ia.ph);
                   14778:        if(_O.dbg_h && stat!=1) err("PIC_get_hdr() returns status %d",stat);
                   14779: 
                   14780:        /* enforce bitfile(9) I/O restrictions */
                   14781:        if(_O.from_bitfile && strcmp(ia.ph->type,"bitfile")!=0)
                   14782:                abort("-Bi requires input to be bitfile(9.5) format");
                   14783:        if(!_O.from_bitfile && strcmp(ia.ph->type,"bitfile")==0) {
                   14784:                /* TYPE= is missing, erroneously:  refuse to recognize it */
                   14785:                abort("TYPE=... header is missing");
                   14786:                };
                   14787: 
                   14788:        if(strcmp(ia.ph->type,"document-image")==0
                   14789:           || strcmp(ia.ph->type,"dim")==0) {
                   14790:            Page pg;
                   14791:                skip_doc(i);
                   14792:                if(frdb_page_etc(i,&pg,IsALL)==1) {
                   14793:                        ia.ph->bx = pg.bx;
                   14794:                        ia.ph->res_x = pg.res_x;
                   14795:                        ia.ph->res_y = pg.res_y;
                   14796:                        ia.rles = *rle_lines_of_page(&pg);
                   14797:                        if(_O.shrinkwrap!=-1) {
                   14798:                            Sp trans;
                   14799:                                ia.ph->bx = *bbx_of_rle_lines(&ia.rles);
                   14800:                                ia.ph->bx.a.x -= _O.shrinkwrap;
                   14801:                                ia.ph->bx.a.y -= _O.shrinkwrap;
                   14802:                                ia.ph->bx.b.x += _O.shrinkwrap;
                   14803:                                ia.ph->bx.b.y += _O.shrinkwrap;
                   14804:                                if(bbx_area(&(ia.ph->bx))<=0)
                   14805:                                    abort("-W%d shrinks to nothing",_O.shrinkwrap);
                   14806:                                trans.x = -ia.ph->bx.a.x; trans.y = -ia.ph->bx.a.y;
                   14807:                                translate_rle_lines(&ia.rles,trans);
                   14808:                                ia.ph->bx.b.x = bbx_wid(&ia.ph->bx)-1;
                   14809:                                ia.ph->bx.b.y = bbx_hgt(&ia.ph->bx)-1;
                   14810:                                ia.ph->bx.a.x = ia.ph->bx.a.y = 0;
                   14811:                                };
                   14812:                        free_page_etc(&pg,IsALL&(~IsPage));
                   14813:                        }
                   14814:                else {  free_page_etc(&pg,IsALL&(~IsPage));
                   14815:                        abort("can't read document-image file");
                   14816:                        };
                   14817:                };
                   14818:        if(_O.in_res.x!=SHRT_MIN&&_O.in_res.y!=SHRT_MIN) {
                   14819:                /* force input RES to given values */
                   14820:                if(ia.ph->res_x!=0 || ia.ph->res_y!=0) {
                   14821:                        err("input: RES=%d %d overridden by -Z%d,%d\n",
                   14822:                                ia.ph->res_x,ia.ph->res_y,_O.in_res.x,_O.in_res.y);
                   14823:                        };
                   14824:                ia.ph->res_x = _O.in_res.x;
                   14825:                ia.ph->res_y = _O.in_res.y;
                   14826:                };
                   14827:        if(ia.ph->res_x<=0 || ia.ph->res_y<=0)
                   14828:                err("input: RES=%d %d may cause problems (set using -Zx,y)",
                   14829:                        ia.ph->res_x,ia.ph->res_y);
                   14830: 
                   14831:        while(strlen(ia.ph->type)>0 && stat==1 && !feof(i)
                   14832:                && !ferror(i) && !ferror(o)) {
                   14833:                process_page(&ia,&oa);
                   14834:                if( strcmp(ia.ph->type,"cdf")==0
                   14835:                    || strcmp(ia.ph->type,"cdf-mrlc")==0 ) {
                   14836:                        stat=CDF_next_page(ia.ph);
                   14837:                        }
                   14838:                else {  if((stat=PIC_get_hdr(ia.ph))==1) {
                   14839:                                /* enforce bitfile(9) I/O restrictions */
                   14840:                                if(_O.from_bitfile && strcmp(ia.ph->type,"bitfile")!=0)
                   14841:                                        abort("-Bi means input must be picfile");
                   14842:                                if(!_O.from_bitfile && strcmp(ia.ph->type,"bitfile")==0) {
                   14843:                                        /* TYPE= is missing, erroneously:  silently quit */
                   14844:                                        if(_O.dbg_h) err("strange input before normal EOF - ignored");
                   14845:                                        strcpy(ia.ph->type,"");
                   14846:                                        };
                   14847:                                };
                   14848:                        };
                   14849:                if(_O.dbg_h && stat!=1)
                   14850:                        err("PIC_get_hdr() returns status %d",stat);
                   14851:                };
                   14852: 
                   14853:        /* EOF or error */
                   14854:        free_PIC_hdr(ia.ph);
                   14855:        free_PIC_hdr(oa.ph);
                   14856:        }
                   14857: 
                   14858: #if FILE_TREE
                   14859: /* Process filenames:  if NULL, use stdin/stdout;  if files, read them;
                   14860:    if directories, create a parallel file tree and process the leaves
                   14861:    pairwise. */
                   14862: process_fns(i,o)
                   14863:     char *i;           /* may be NULL; not yet fopened for read */
                   14864:     char *o;           /* may be NULL; not yet fopened for write */
                   14865: #define dbg_ft (F)
                   14866: {   FILE *i_fp;
                   14867:     FILE *o_fp;
                   14868:     char *branch;
                   14869:        if(dbg_ft) err("processs(\"%s\",\"%s\")",i,o);
                   14870:        branch=path_toa(&path_process.path,1);
                   14871:        if(dbg_ft&&branch[0]!='\0') err("%s",branch);
                   14872:        if(i==NULL||i[0]=='\0') i_fp=stdin;
                   14873:        else if( (i_fp=fopen(i,"r"))==NULL ) {
                   14874:                err("can't open input file %s - skip it",i);
                   14875:                return;
                   14876:                };
                   14877:        if(o==NULL||o[0]=='\0') o_fp=stdout;
                   14878:        else if( (o_fp=fopen(o,"w"))==NULL ) {
                   14879:                err("can't open output file %s - skip it",o);
                   14880:                return;
                   14881:                };
                   14882:        process_fps(i_fp,o_fp);
                   14883:        if(i_fp!=stdin) fclose(i_fp);
                   14884:        if(o_fp!=stdout) fclose(o_fp); else fflush(o_fp);
                   14885:        };
                   14886: #else
                   14887: /* Process filenames:  if NULL, use stdin/stdout;  if files, open and process them.
                   14888:    */
                   14889: process_fns(i_fn,o_fn)
                   14890:     char *i_fn;                /* may be NULL; not yet fopened for read */
                   14891:     char *o_fn;                /* may be NULL; not yet fopened for write */
                   14892: {   FILE *i_fp;
                   14893:     FILE *o_fp;
                   14894:        if(i_fn==NULL||strlen(i_fn)==0) i_fp = stdin;
                   14895:        else {  if((i_fp=fopen(i_fn,"r"))==NULL)
                   14896:                        abort("can't open input file %s",i_fn);
                   14897:                };
                   14898:        if(o_fn==NULL||strlen(o_fn)==0) o_fp = stdout;
                   14899:        else {  if((o_fp=fopen(o_fn,"w"))==NULL)
                   14900:                        abort("can't open output file %s",o_fn);
                   14901:                };
                   14902:        process_fps(i_fp,o_fp);
                   14903:        if(i_fp!=stdin) fclose(i_fp);
                   14904:        if(o_fp!=stdout) fclose(o_fp); else fflush(o_fp);
                   14905:        };
                   14906: #endif
                   14907: 
                   14908: main(arc,arv)
                   14909:     int arc; char **arv;
                   14910: {      parse_args(arc,arv);
                   14911: #if FILE_TREE
                   14912:        process_file_trees(process_fns,_O.in_fn,_O.out_fn);
                   14913: #else
                   14914:        process_fns(_O.in_fn,_O.out_fn);
                   14915: #endif
                   14916:        }
                   14917: 
                   14918: nerr_RLE_Line(s,rl)
                   14919:     char *s;
                   14920:     RLE_Line *rl;
                   14921: {   RLE_Run *r;
                   14922:     int ri;
                   14923:        if(rl==NULL) fprintf(stderr,"%15s RLEL NULL.\n",s);
                   14924:        else {  fprintf(stderr,"%15s RLEL y%d r%d l%d: ",s,rl->y,rl->runs,rl->len);
                   14925:                for(ri=0,r=rl->r; ri<rl->runs; ri++,r++)
                   14926:                        fprintf(stderr,"[%d,%d] ",r->xs,r->xe);
                   14927:                fprintf(stderr,"\n");
                   14928:                };
                   14929:        }
                   14930: 0707070035351137201006640007620000050000010263350476773367100001000000030702bitio.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   14931: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   14932: /* The copyright notice does not imply actual or intended publication. */
                   14933: /* AUTHORS:                                            */
                   14934: /*     H. S. Baird - ATT-BL MH - first versions        */
                   14935: 
                   14936: /* bitio.h - view a stream file as a sequence of binary values, hiding the
                   14937:    bit- and byte-packing format of the file.  The format of input and output
                   14938:    files may differ.   Reading and writing are performed by macroes for speed;
                   14939:    the price for this is that the file formats must be fixed at compile time.
                   14940: 
                   14941: SYNOPSIS
                   14942:        #include <stdio.h>
                   14943:        #include "bitio.h"
                   14944: 
                   14945:        BITFILE *bopen(stream,type);
                   14946:            FILE *stream;
                   14947:            char *type;
                   14948: 
                   14949:        int getb(bitfile);
                   14950:            BITFILE *bitfile;
                   14951: 
                   14952:        putb(bit,bitfile);
                   14953:            int bit;
                   14954: 
                   14955:        padb(bitfile,bit,bdy,len);
                   14956:            int bit,bdy,len;
                   14957: 
                   14958:        char *bbuffer(bitfile);
                   14959: 
                   14960:        unsigned long bsize(bitfile);
                   14961:        
                   14962:        unsigned long bflush(bitfile);
                   14963: 
                   14964:        unsigned long bclose(bitfile);
                   14965: 
                   14966: COMPILER DEPENDENCIES
                   14967:    The compiler's data types must include:
                   14968:        unsigned char:  8 bits each
                   14969:        unsigned short: 2 unsigned chars each
                   14970:        unsigned int:   2 unsigned shorts each
                   14971: DESCRIPTION
                   14972:        Bopen views the named stream file as a bit file to be read (if type is "r")
                   14973:    or written (if type is "w" or "wb").   The stream file must already have been
                   14974:    fopen(3)ed, and the first bit to be read/written will be the first bit in its
                   14975:    next byte in getc(3)/putc(3) order.  Bopen returns a pointer which identifies
                   14976:    the bitfile to the other functions.  System or stream I/O to/from the
                   14977:    associated stream should not be used until after bclose is called.
                   14978:        If bopen's type is "wb", then the entire output stream will be buffered
                   14979:    in main memory until bflush or bclose are called.  At any time, bbuffer
                   14980:    returns this buffer's address and bsize its length in bytes.
                   14981:        Getb returns the next bit from the named bitfile.  It returns EOF on
                   14982:    end of file or read error.  EOF may occur on a byte, short, or int boundary,
                   14983:    depending on file format.
                   14984:        Putb appends the given bit to the named bitfile.
                   14985:        Padb writes 'bit' enough times (possibly 0) so that if a bitstring
                   14986:    of length 'len' were written next it would end on a 'bdy'-bit boundary
                   14987:    (may do the wrong thing if 'bdy' doesn't divide UINT_MAX).
                   14988:        Bflush ensures that all written bits have been written to the stream
                   14989:    via putc(3).  The output is padded with 0 bits to a byte, short, or int
                   14990:    boundary, depending on file format.  It returns the number of bytes (not bits)
                   14991:    written since bopen or the last bflush.  The bitfile remains open.  It does not
                   14992:    fflush(3) the associated stream.  
                   14993:        Bclose causes a bflush and frees all buffers.  It returns the total
                   14994:    number of bytes (not bits) read/written since bopen.  It fflush(3)'es,
                   14995:    but does not fclose(3) the associated stream.
                   14996: 
                   14997:         Bitfile formats are selected at compile time: see `FORMAT:' at the
                   14998:    end of this file.  The formats for input and output may differ.  Formats
                   14999:    include:
                   15000:    a   each bit is an ASCII character: '0' or '1', in putc(3) order; not padded.
                   15001:    0   the low-order (0001) bit in each byte is first ("little-endian"), and
                   15002:        bytes are in putc(3) order; EOF and padding at a byte boundary.
                   15003:    1   the high-order (0200) bit in each byte is first ("big-endian"), and
                   15004:        bytes are in putc(3) order; EOF and padding at a byte boundary.
                   15005:    10  the low-order (0001) bit in each byte is first ("little-endian"), but
                   15006:        bytes are reversed (in each pair) from putc(3) order;  EOF and padding
                   15007:        at a short boundary.
                   15008:    11  the high-order (0200) bit in each byte is first ("big-endian"), but
                   15009:        bytes are reversed (in each pair) from putc(3) order; EOF and padding
                   15010:        at a short boundary.
                   15011:    Planned (data structures are in place; code will be implemented if needed):
                   15012:    100 the low-order (0001) bit in each byte is first ("little-endian"), and
                   15013:        bytes (in each pair) are in putc(3) order; but shorts (in each pair)
                   15014:        are reversed from putc(3) order;  EOF and padding at an int boundary.
                   15015:    101, 110, 111 - by obvious analogy
                   15016: BUGS
                   15017:        Putting to an input bitfile or getting from an output bitfile is
                   15018:    erroneous, but is not checked for.
                   15019: */
                   15020: 
                   15021: #define BUFFERED (T)   /* enable buffering of output */
                   15022: 
                   15023: typedef struct BITFILE {
                   15024:        FILE *fp;               /* associated stream */
                   15025:        char type;              /* one of 'r','w' */
                   15026:        int ic;                 /* byte just read */
                   15027:        unsigned long nb;       /* no. bytes read/written since bopen */
                   15028:        unsigned long alloc;    /* no. bytes allocated in buffer */
                   15029:        char *buf;              /* buffer (in malloc space) */
                   15030:        char *cp;               /* next char in buffer */
                   15031:        unsigned int n;         /* no. bits written so far (mod UINT_MAX) */
                   15032:        unsigned char cm;       /* single-bit mask */
                   15033:        unsigned short sm;      /* single-bit mask */
                   15034:        unsigned int im;        /* single-bit mask */
                   15035:        union { struct {        /* used to reorder char & short order */
                   15036:                        union { struct {
                   15037:                                        unsigned char c0;
                   15038:                                        unsigned char c1;
                   15039:                                        } cc;
                   15040:                                unsigned short s;
                   15041:                                } s0;
                   15042:                        union { struct {
                   15043:                                        unsigned char c0;
                   15044:                                        unsigned char c1;
                   15045:                                        } cc;
                   15046:                                unsigned short s;
                   15047:                                } s1;
                   15048:                        } ss;
                   15049:                unsigned int i;
                   15050:                } i;
                   15051:        } BITFILE;
                   15052: #define Init_BITFILE {NULL,'\0',0,0L,0L,NULL,NULL,0,0,0}
                   15053: #if MAIN
                   15054: BITFILE empty_BITFILE = Init_BITFILE;
                   15055: #else
                   15056: extern BITFILE empty_BITFILE;
                   15057: #endif
                   15058: 
                   15059: /* Code common to all formats: */
                   15060: #if MAIN
                   15061: BITFILE *bopen_rw(s,t)
                   15062:     FILE *s;
                   15063:     char *t;
                   15064: {   BITFILE *f;
                   15065:        if((f=(BITFILE *)malloc(sizeof(BITFILE)))==NULL) {
                   15066:                err("bopen: can't alloc");
                   15067:                return(NULL);
                   15068:                };
                   15069:        *f = empty_BITFILE;
                   15070:        f->fp = s;
                   15071:        f->type = *t;
                   15072:        return(f);
                   15073:        }
                   15074: #else
                   15075: BITFILE *bopen_rw();
                   15076: #endif
                   15077: 
                   15078: #define bbuffer(f) ((f)->buf)
                   15079: #define bsize(f) ((bbuffer(f)!=NULL)? ((f)->cp - (f)->buf): 0L)
                   15080: 
                   15081: #if !BUFFERED
                   15082: #define bputc(c,f) putc((c),(f)->fp)
                   15083: #define bbflush(f) (0L)
                   15084: #else
                   15085: #define BITFILE_incr (512)     /* buffer allocations are in these increments */
                   15086: 
                   15087: #if MAIN
                   15088: brealloc(f)
                   15089:     BITFILE *f;
                   15090: {   int nbuf;  /* no. bytes in buffer */
                   15091:        nbuf = bsize(f);
                   15092:        f->alloc += BITFILE_incr;
                   15093:        if((f->buf=(char *)realloc(f->buf,f->alloc))==NULL)
                   15094:                abort("");
                   15095:        f->cp = f->buf + nbuf;
                   15096:        }
                   15097: #endif
                   15098: 
                   15099: #define bputc(c,f) { \
                   15100:        if((f)->buf==NULL) putc((c),(f)->fp); \
                   15101:        else {  if(bsize(f)==(f)->alloc) brealloc(f); \
                   15102:                *(++((f)->cp))=(c); \
                   15103:                } \
                   15104:        }
                   15105: 
                   15106: #if MAIN
                   15107: unsigned long bbflush(f)
                   15108:     BITFILE *f;                /* f->buf!=NULL && bsize(f)>0 */
                   15109: {   register char *cp,*cq;
                   15110:     unsigned long nbuf;
                   15111:        nbuf = bsize(f);
                   15112:        for(cq=(cp=f->buf)+nbuf; cp<cq; cp++) putc(*cp,f->fp);
                   15113:        f->cp=f->buf;
                   15114:        return(nbuf);
                   15115:        }
                   15116: #else
                   15117: unsigned long bbflush();
                   15118: #endif
                   15119: #endif
                   15120: 
                   15121: /* Code particular to each format: */
                   15122: 
                   15123: /* Format a:  ASCII file, one printable char ('0' or '1') per bit: */
                   15124: #define bopen_r_a(s) bopen_rw((s),"r")
                   15125: #define bopen_w_a(s) bopen_rw((s),"w")
                   15126: #define getb_a(f) ( (((f)->ic=getc((f)->fp))!=EOF)? \
                   15127:                        ((f)->nb++, \
                   15128:                         ((f)->ic=='0')? \
                   15129:                                0: \
                   15130:                                (((f)->ic=='1')? 1: EOF)): \
                   15131:                        EOF )
                   15132: #define putb_a(b,f) { if((b)) bputc('1',f); else bputc('0',f); (f)->nb++; }
                   15133: #define bflush_a(f) ( (bsize(f)>0)? bbflush(f): (0L) )
                   15134: 
                   15135: /* Format 0:  the low-order bit (0001) in each byte is first ("little-endian"),
                   15136:    and bytes are in putc(3) order; */
                   15137: #if MAIN
                   15138: BITFILE *bopen_r_0(s)
                   15139:     FILE *s;
                   15140: {   BITFILE *f;
                   15141:        if((f=bopen_rw(s,"r"))!=NULL) {
                   15142:                f->cm=0000;
                   15143:                };
                   15144:        return(f);
                   15145:        }
                   15146: #else
                   15147: BITFILE *bopen_r_0();
                   15148: #endif
                   15149: #if MAIN
                   15150: BITFILE *bopen_w_0(s)
                   15151:     FILE *s;
                   15152: {   BITFILE *f;
                   15153:        if((f=bopen_rw(s,"w"))!=NULL) {
                   15154:                f->i.ss.s0.cc.c0=0000;
                   15155:                f->cm=0001;
                   15156:                };
                   15157:        return(f);
                   15158:        }
                   15159: #else
                   15160: BITFILE *bopen_w_0();
                   15161: #endif
                   15162: #define getb_0(f) ( ((f)->cm)? \
                   15163:                        ( ((f)->cm&(f)->ic)? \
                   15164:                                ((f)->cm<<=1,1): \
                   15165:                                ((f)->cm<<=1,0) ): \
                   15166:                        ( (((f)->ic=getc((f)->fp))==EOF)? \
                   15167:                                EOF: \
                   15168:                                ( (f)->nb++, \
                   15169:                                  (f)->cm=0001, \
                   15170:                                  ((f)->cm&(f)->ic)? \
                   15171:                                        ((f)->cm<<=1,1): \
                   15172:                                        ((f)->cm<<=1,0) ) ) )
                   15173: #define putb_0(b,f) { \
                   15174:        if((b)) (f)->i.ss.s0.cc.c0 |= (f)->cm; \
                   15175:        if( !((f)->cm<<=1) ) { \
                   15176:                bputc((f)->i.ss.s0.cc.c0,f); \
                   15177:                (f)->nb++; \
                   15178:                (f)->i.ss.s0.cc.c0=0000; (f)->cm=0001; \
                   15179:                }; \
                   15180:        (f)->n++; \
                   15181:        }
                   15182: #define bflush_0(f) (padb((f),0,8,0), (bsize(f)>0)? bbflush(f): 0L)
                   15183: 
                   15184: /* Format 1:  the high-order bit (0200) in each byte is first ("big-endian"), and
                   15185:    bytes are in putc(3) order; */
                   15186: #if MAIN
                   15187: BITFILE *bopen_r_1(s)
                   15188:     FILE *s;
                   15189: {   BITFILE *f;
                   15190:        if((f=bopen_rw(s,"r"))!=NULL) {
                   15191:                f->cm=0000;
                   15192:                };
                   15193:        return(f);
                   15194:        }
                   15195: #else
                   15196: BITFILE *bopen_r_1();
                   15197: #endif
                   15198: #if MAIN
                   15199: BITFILE *bopen_w_1(s)
                   15200:     FILE *s;
                   15201: {   BITFILE *f;
                   15202:        if((f=bopen_rw(s,"w"))!=NULL) {
                   15203:                f->i.ss.s0.cc.c0=0000;
                   15204:                f->cm=0200;
                   15205:                };
                   15206:        return(f);
                   15207:        }
                   15208: #else
                   15209: BITFILE *bopen_w_1();
                   15210: #endif
                   15211: #define getb_1(f) ( ((f)->cm)? \
                   15212:                        ( ((f)->cm&(f)->ic)? \
                   15213:                                ((f)->cm>>=1,1): \
                   15214:                                ((f)->cm>>=1,0) ): \
                   15215:                        ( (((f)->ic=getc((f)->fp))==EOF)? \
                   15216:                                EOF: \
                   15217:                                ( (f)->nb++, \
                   15218:                                  (f)->cm=0200, \
                   15219:                                  ((f)->cm&(f)->ic)? \
                   15220:                                        ((f)->cm>>=1,1): \
                   15221:                                        ((f)->cm>>=1,0) ) ) )
                   15222: #define putb_1(b,f) { \
                   15223:        if((b)) (f)->i.ss.s0.cc.c0 |= (f)->cm; \
                   15224:        if( !((f)->cm>>=1) ) { \
                   15225:                bputc((f)->i.ss.s0.cc.c0,f); \
                   15226:                (f)->nb++; \
                   15227:                (f)->i.ss.s0.cc.c0=0000; (f)->cm=0200; \
                   15228:                }; \
                   15229:        (f)->n++; \
                   15230:        }
                   15231: #define bflush_1(f) (padb((f),0,8,0), (bsize(f)>0)? bbflush(f): 0L)
                   15232: 
                   15233: /* Format 10: the low-order (0001) bit in each byte is first ("little-endian"), and
                   15234:    bytes are reversed (in each pair) from putc(3) order;
                   15235:  */
                   15236: #if MAIN
                   15237: BITFILE *bopen_r_10(s)
                   15238:     FILE *s;
                   15239: {   BITFILE *f;
                   15240:        if((f=bopen_rw(s,"r"))!=NULL) {
                   15241:                f->sm=0000000;
                   15242:                };
                   15243:        return(f);
                   15244:        }
                   15245: #else
                   15246: BITFILE *bopen_r_10();
                   15247: #endif
                   15248: #if MAIN
                   15249: BITFILE *bopen_w_10(s)
                   15250:     FILE *s;
                   15251: {   BITFILE *f;
                   15252:        if((f=bopen_rw(s,"w"))!=NULL) {
                   15253:                f->i.ss.s0.s=0000000;
                   15254:                f->sm=0000001;
                   15255:                };
                   15256:        return(f);
                   15257:        }
                   15258: #else
                   15259: BITFILE *bopen_w_10();
                   15260: #endif
                   15261: #define getb_10(f) ( ((f)->sm)? \
                   15262:                        ( ((f)->sm&(f)->i.ss.s0.s)? \
                   15263:                                ((f)->sm<<=1,1): \
                   15264:                                ((f)->sm<<=1,0) ): \
                   15265:                        ( (((f)->ic=getc((f)->fp))==EOF)? \
                   15266:                                EOF: \
                   15267:                                ( (f)->nb++, \
                   15268:                                  (f)->i.ss.s0.cc.c1=(f)->ic&0377, \
                   15269:                                  ( (((f)->ic=getc((f)->fp))==EOF)? \
                   15270:                                        EOF: \
                   15271:                                        ( (f)->nb++, \
                   15272:                                          (f)->i.ss.s0.cc.c0=(f)->ic&0377, \
                   15273:                                          (f)->sm=0000001, \
                   15274:                                          ((f)->sm&(f)->i.ss.s0.s)? \
                   15275:                                                ((f)->sm<<=1,1): \
                   15276:                                                ((f)->sm<<=1,0) ) ) ) ) )
                   15277: #define putb_10(b,f) { \
                   15278:        if((b)) (f)->i.ss.s0.s |= (f)->sm; \
                   15279:        if( !((f)->sm<<=1) ) { \
                   15280:                bputc((f)->i.ss.s0.cc.c1,f); \
                   15281:                (f)->nb++; \
                   15282:                bputc((f)->i.ss.s0.cc.c0,f); \
                   15283:                (f)->nb++; \
                   15284:                (f)->i.ss.s0.s=0000000; (f)->sm=0000001; \
                   15285:                }; \
                   15286:        (f)->n++; \
                   15287:        }
                   15288: #define bflush_10(f) (padb((f),0,16,0), (bsize(f)>0)? bbflush(f): 0L)
                   15289: 
                   15290: /* Format 11:  the high-order (0200) bit in each byte is first ("little-endian"),
                   15291:    and bytes are reversed (in each pair) from putc(3) order.
                   15292:  */
                   15293: #if MAIN
                   15294: BITFILE *bopen_r_11(s)
                   15295:     FILE *s;
                   15296: {   BITFILE *f;
                   15297:        if((f=bopen_rw(s,"r"))!=NULL) {
                   15298:                f->sm=0000000;
                   15299:                };
                   15300:        return(f);
                   15301:        }
                   15302: #else
                   15303: BITFILE *bopen_r_11();
                   15304: #endif
                   15305: #if MAIN
                   15306: BITFILE *bopen_w_11(s)
                   15307:     FILE *s;
                   15308: {   BITFILE *f;
                   15309:        if((f=bopen_rw(s,"w"))!=NULL) {
                   15310:                f->i.ss.s0.s=0000000;
                   15311:                f->sm=0100000;
                   15312:                };
                   15313:        return(f);
                   15314:        }
                   15315: #else
                   15316: BITFILE *bopen_w_11();
                   15317: #endif
                   15318: #define getb_11(f) ( ((f)->sm)? \
                   15319:                        ( ((f)->sm&(f)->i.ss.s0.s)? \
                   15320:                                ((f)->sm>>=1,1): \
                   15321:                                ((f)->sm>>=1,0) ): \
                   15322:                        ( (((f)->ic=getc((f)->fp))==EOF)? \
                   15323:                                EOF: \
                   15324:                                ( (f)->nb++, \
                   15325:                                  (f)->i.ss.s0.cc.c0=(f)->ic&0377, \
                   15326:                                  ( (((f)->ic=getc((f)->fp))==EOF)? \
                   15327:                                        EOF: \
                   15328:                                        ( (f)->nb++, \
                   15329:                                          (f)->i.ss.s0.cc.c1=(f)->ic&0377, \
                   15330:                                          (f)->sm=0100000, \
                   15331:                                          ((f)->sm&(f)->i.ss.s0.s)? \
                   15332:                                                ((f)->sm>>=1,1): \
                   15333:                                                ((f)->sm>>=1,0) ) ) ) ) )
                   15334: #define putb_11(b,f) { \
                   15335:        if((b)) (f)->i.ss.s0.s |= (f)->sm; \
                   15336:        if( !((f)->sm>>=1) ) { \
                   15337:                bputc((f)->i.ss.s0.cc.c0,f); \
                   15338:                (f)->nb++; \
                   15339:                bputc((f)->i.ss.s0.cc.c1,f); \
                   15340:                (f)->nb++; \
                   15341:                (f)->i.ss.s0.s=0000000; (f)->sm=0100000; \
                   15342:                }; \
                   15343:        (f)->n++; \
                   15344:        }
                   15345: #define bflush_11(f) (padb((f),0,16,0), (bsize(f)>0)? bbflush(f): 0L)
                   15346: 
                   15347: /**************************************************************/
                   15348: /* FORMAT: may be selected here (input and output may differ) */
                   15349: 
                   15350: /* Input: */
                   15351: #define bopen_r(s) bopen_r_0((s))
                   15352: #define getb(f) getb_0(f)
                   15353: /* Output: */
                   15354: #define bopen_w(s) bopen_w_0((s))
                   15355: #define putb(b,f) putb_0((b),(f))
                   15356: #define bflush(f) bflush_0(f)
                   15357: 
                   15358: /**************************************************************/
                   15359: 
                   15360: /* Code common to all formats: */
                   15361: #if MAIN
                   15362: BITFILE *bopen(s,t)
                   15363:     FILE *s;
                   15364:     char *t;
                   15365: {   BITFILE *res;
                   15366:        if(*(t)=='r') res=bopen_r(s);
                   15367:        else if(*(t)=='w') {
                   15368:                res=bopen_w(s);
                   15369: #if BUFFERED
                   15370:                if(*(t+1)=='b') {
                   15371:                        res->alloc = BITFILE_incr;
                   15372:                        if((res->buf=(char *)malloc(res->alloc))==NULL)
                   15373:                                abort("bopen: can't alloc buffer");
                   15374:                        res->cp = res->buf;
                   15375:                        };
                   15376: #endif
                   15377:                }
                   15378:        else abort("bopen: bad type: \"%s\"",t);
                   15379:        return(res);
                   15380:        }
                   15381: #else
                   15382: BITFILE *bopen();
                   15383: #endif
                   15384: 
                   15385: #if MAIN
                   15386: padb(f,b,B,l)
                   15387:     BITFILE *f;
                   15388:     char b;
                   15389:     int l,B;
                   15390: {      while(((f)->n+(l))%(B)) putb((b),(f));
                   15391:        }
                   15392: #endif
                   15393: 
                   15394: #if MAIN
                   15395: unsigned long bclose(f)
                   15396:     BITFILE *f;
                   15397: {   unsigned long nb,nbuf;
                   15398:        if(f->type=='w') {
                   15399:                nbuf=bflush(f);
                   15400:                fflush(f->fp);
                   15401: #if BUFFERED
                   15402:                if(f->buf!=NULL) { free(f->buf); f->buf=NULL; }
                   15403: #endif
                   15404:                };
                   15405:        nb=f->nb;
                   15406:        free(f);
                   15407:        return(nb);
                   15408:        }
                   15409: #else
                   15410: unsigned long bclose();
                   15411: #endif
                   15412: 0707070035350557131006640007620000050000010263430476773367100001000000000615boole.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   15413: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   15414: /* The copyright notice does not imply actual or intended publication. */
                   15415: /* AUTHORS:                                            */
                   15416: /*     H. S. Baird - ATT-BL MH - first versions        */
                   15417: /* boole.h */
                   15418: 
                   15419: #define boolean int
                   15420: #define T 1
                   15421: #define F 0
                   15422: 0707070035350321011006640007620000050000010263450476773367100000700000020537fioi.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   15423: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   15424: /* The copyright notice does not imply actual or intended publication. */
                   15425: /* AUTHORS:                                            */
                   15426: /*     H. S. Baird - ATT-BL MH - first versions        */
                   15427: 
                   15428: /* fioi.h - buffered I/O of machine-, OS-, and compiler-independent binary values.
                   15429: 
                   15430:    Machine-, OS-, and compiler-independence of 'fioi' functions require that:
                   15431:       1) chars are exactly 8 bits and their contents are invariant under I/O;
                   15432:       2) the order of chars, as written by putc() and read by getc(), is
                   15433:         also invariant, across all machines, OS, and compilers.
                   15434:    Both of these requirements are customarily met by UNIX OS & tools.
                   15435: 
                   15436:    All values are written/read as a stream of char's, ultimately
                   15437:    using putc() & getc() macroes.
                   15438:    To maximize speed, macroes are used wherever possible:
                   15439:    -  the first argument F of each macro is a stream (FILE *).
                   15440:    -  write macroes have the form fwri_TYPE(F,value); `value' is assigned to
                   15441:       a variable of type TYPE before it is written (so compiler-dependent type
                   15442:       coercions may apply).
                   15443:    - read macroes have the form frdi_TYPE(F), returning a value of type TYPE.
                   15444:    Arguments to these macroes are evaluated exactly once.
                   15445:    */
                   15446: 
                   15447: /** MACHINE-DEPENDENT CUSTOMIZATION OF TYPES **/
                   15448: /* For each machine, all these types must be supported in the sense that
                   15449:    some roughly-equivalent machine-supported type exists.  If an exact
                   15450:    equivalent doesn't exist, pick the shortest that is at least as long
                   15451:    (in no. bytes), if possible.  If there is no machine representation
                   15452:    at least as long as specified, the only penalty will be the inevitable one:
                   15453:    when a value is read, it may be truncated to the maximum value that can be
                   15454:    represented.
                   15455:    */
                   15456: #define int1 char              /* 8-bit signed 2's complement integer */
                   15457: #define int2 short             /* 16-bit signed 2's complement integer */
                   15458: #define int3 int               /* 24-bit signed 2's complement integer */
                   15459: #define int4 int               /* 32-bit signed 2's complement integer */
                   15460: #define int8 long              /* 64-bit signed 2's complement integer */
                   15461: #define uint1 unsigned char    /* 8-bit unsigned integer */
                   15462: #define uint2 unsigned short   /* 16-bit unsigned integer */
                   15463: #define uint3 unsigned int     /* 24-bit unsigned integer */
                   15464: #define uint4 unsigned int     /* 32-bit unsigned integer */
                   15465: #define uint8 unsigned long    /* 64-bit unsigned integer */
                   15466: 
                   15467: /* IEEE 64-bit floating point format */
                   15468: typedef struct Ieeed {
                   15469:        int8 l;
                   15470:        int8 h;
                   15471:        } Ieeed;
                   15472: 
                   15473: /* Cope with unsigned chars on 3B2 & compensate for bug on MIPS */
                   15474: #if CPU!=ATT3B && CPU!=MIPS
                   15475: #define toint1(c) (int1)(c)
                   15476: #else
                   15477: #if MAIN
                   15478: int toint1(c)
                   15479:     register int c;
                   15480: {      if ( ((1<<7)&c) !=0 ) return(c-256);
                   15481:        else return c;
                   15482:        }
                   15483: #else
                   15484: extern int toint1();
                   15485: #endif
                   15486: #endif
                   15487: 
                   15488: /** THE REST OF THIS FILE IS MACHINE-, OS-, and COMPILER-INDEPENDENT **/
                   15489: 
                   15490: typedef struct Fioi {
                   15491:        int1 i1;
                   15492:        int2 i2;
                   15493:        int3 i3;
                   15494:        int4 i4;
                   15495:        int8 i8;
                   15496:        uint1 ui1;
                   15497:        uint2 ui2;
                   15498:        uint3 ui3;
                   15499:        uint4 ui4;
                   15500:        uint8 ui8;
                   15501:        char str[100];
                   15502:        } Fioi;
                   15503: #define Init_Fioi {0,0,0,0,0,0,0,0,0,0,""}
                   15504: #if MAIN
                   15505: Fioi _Fioi = Init_Fioi;
                   15506: #else
                   15507: extern Fioi _Fioi;
                   15508: #endif
                   15509: 
                   15510: /* Characters */
                   15511: #define fwri_ch(F,V) putc((V),(F))
                   15512: #define frdi_ch(F) getc((F))
                   15513: 
                   15514: #if T  /* TRANSITIONAL:  used to read:  "#if FWRI" */
                   15515: /* Strings are '\0'-terminated both in main memory & in peripheral files. */
                   15516: #define fwri_str(F,S) { fputs((S),(F)); putc('\0',(F)); }
                   15517: #else
                   15518: /* Strings are '\0'-terminated in the variable and '\n'-terminated in the file.
                   15519:    BAD, OBSOLESCENT POLICY:  both should use '\0'-termination */
                   15520: #define fwri_str(F,S) { fputs((S),(F)); putc('\n',(F)); }
                   15521: #endif
                   15522: 
                   15523: #define MAX_FIO_STRLEN (128)
                   15524: 
                   15525: #if T  /* TRANSITIONAL:  used to read:  "#if FRDI" */
                   15526: 
                   15527: /* Strings are '\0'-terminated both in main memory & in peripheral files. */
                   15528: /*** TRANSITIONAL PATCH:  accept '\n' as a terminator also;  this will be disabled
                   15529:      as soon as all classifier tables have been recreated with FWRI==T. ***/
                   15530: /* Read string of maximum length MAX_FIO_STRLEN; return pointer to malloc space */
                   15531: #if MAIN
                   15532: char *frdi_str(f)
                   15533:     FILE *f;
                   15534: {   static char s[MAX_FIO_STRLEN+1];
                   15535:     register int ch;
                   15536:     register char *c,*ce;
                   15537:     char *res;
                   15538:        ce=(c=s)+MAX_FIO_STRLEN;
                   15539:        while((c<ce)&&((ch=getc(f))!=EOF)&&(ch!='\0')&&(ch!='\n')) *(c++) = ch;
                   15540:        *c='\0';
                   15541:        if(c==ce) /* label is truncated; find end of it */ {
                   15542:                while(((ch=getc(f))!=EOF)&&(ch!='\0')&&(ch!='\n')) ;
                   15543:                };
                   15544:        if((res=(char *)strdup(s))==NULL)
                   15545:                abort("frdi_str: can't dup char *s[%d]",strlen(s));
                   15546:        return(res);
                   15547:        }
                   15548: #else
                   15549: char *frdi_str();
                   15550: #endif
                   15551: /* 's' is an already-allocated buffer of known length >=N (including '\0') */
                   15552: #if MAIN
                   15553: int frdi_strn(f,s,n)
                   15554:     FILE *f;
                   15555:     char s[];
                   15556:     int n;
                   15557: {   register int ch;
                   15558:     register char *c,*ce;
                   15559:        ce=(c=s)+n-1;
                   15560:        while((c<ce)&&((ch=getc(f))!=EOF)&&(ch!='\0')&&(ch!='\n')) *(c++) = ch;
                   15561:        *c='\0';
                   15562:        if(c==ce) /* label is truncated; find end of it */ {
                   15563:                while(((ch=getc(f))!=EOF)&&(ch!='\0')&&(ch!='\n')) ;
                   15564:                };
                   15565:        if(ch==EOF) return(0); else if(ferror(f)) return(-errno); else return(1);
                   15566:        }
                   15567: #else
                   15568: int frdi_strn();
                   15569: #endif
                   15570: 
                   15571: #else
                   15572: 
                   15573: /* Strings are '\0'-terminated in the variable and '\n'-terminated in the file.
                   15574:    BAD, OBSOLESCENT POLICY:  both should use '\0'-termination */
                   15575: /* Read string of maximum length MAX_FIO_STRLEN; return pointer to malloc space */
                   15576: #if MAIN
                   15577: char *frdi_str(f)
                   15578:     FILE *f;
                   15579: {   static char s[MAX_FIO_STRLEN+1];
                   15580:     register int ch;
                   15581:     register char *c,*ce;
                   15582:     char *res;
                   15583:        ce=(c=s)+MAX_FIO_STRLEN;
                   15584:        while((c<ce)&&((ch=getc(f))!=EOF)&&(ch!='\n')) *(c++) = ch;
                   15585:        *c='\0';
                   15586:        if(c==ce) /* label is truncated; find end of it */ {
                   15587:                while(((ch=getc(f))!=EOF)&&(ch!='\n')) ;
                   15588:                };
                   15589:        if((res=(char *)strdup(s))==NULL)
                   15590:                abort("frdi_str: can't dup char *s[%d]",strlen(s));
                   15591:        return(res);
                   15592:        }
                   15593: #else
                   15594: char *frdi_str();
                   15595: #endif
                   15596: /* S is an already-allocated buffer of known length >=N (including '\0') */
                   15597: #define frdi_strn(F,S,N) ( feof(F)? 0 : ( \
                   15598:        fgets((S),(N),(F)), \
                   15599:        ( (((S)[strlen((S))-1])=='\n')? (S)[strlen((S))-1]='\0': 1 ), \
                   15600:        (ferror(F)? -errno: 1) ) )
                   15601: 
                   15602: #endif
                   15603: 
                   15604: /* Integers (unsigned and signed) are written low-order byte first. */
                   15605: #define fwri_uint1(F,V) fwri_ch((F),(uint1)(V))
                   15606: #define frdi_uint1(F) ((uint1)frdi_ch((F)))
                   15607: 
                   15608: #define fwri_uint2(F,V) { fwri_uint1((F),_Fioi.ui2=(V)); \
                   15609:                        fwri_uint1((F),_Fioi.ui2>>8); }
                   15610: #define frdi_uint2(F) ((uint2)( _Fioi.ui2=frdi_uint1((F)), \
                   15611:                        (frdi_uint1((F))<<8)|_Fioi.ui2 ))
                   15612: 
                   15613: #define fwri_uint3(F,V) { fwri_uint2((F),_Fioi.ui3=(V)); \
                   15614:                        fwri_uint1((F),_Fioi.ui3>>16); }
                   15615: #define frdi_uint3(F) ((uint3)( _Fioi.ui3=frdi_uint2((F)), \
                   15616:                        (frdi_uint1((F))<<16)|_Fioi.ui3 ))
                   15617: 
                   15618: #define fwri_uint4(F,V) { fwri_uint2((F),_Fioi.ui4=(V)); \
                   15619:                        fwri_uint2((F),_Fioi.ui4>>16); }
                   15620: #define frdi_uint4(F) ((uint4)( _Fioi.ui4=frdi_uint2((F)), \
                   15621:                        (frdi_uint2((F))<<16)|_Fioi.ui4 ))
                   15622: 
                   15623: #define fwri_uint8(F,V) { fwri_uint4((F),_Fioi.ui8=(V)); \
                   15624:                        fwri_uint4((F),_Fioi.ui8>>32); }
                   15625: #define frdi_uint8(F) ((uint8)( _Fioi.ui8=frdi_uint4((F)), \
                   15626:                        (frdi_uint4((F))<<32)|_Fioi.ui8 ))
                   15627: 
                   15628: /* Signed integers are assumed to be 2's complement.
                   15629:    Note the suppression of inappropriate sign-extensions using judicious
                   15630:    unsigned reads. */
                   15631: 
                   15632: #define fwri_int1(F,V) fwri_ch((F),_Fioi.i1=(V))
                   15633: #define frdi_int1(F) (toint1(frdi_ch((F))))
                   15634: 
                   15635: #define fwri_int2(F,V) { fwri_int1((F),_Fioi.i2=(V)); \
                   15636:                        fwri_int1((F),_Fioi.i2>>8); }
                   15637: #define frdi_int2(F) ((int2)( _Fioi.i2=frdi_uint1((F)), \
                   15638:                        (frdi_int1((F))<<8)|_Fioi.i2 ))
                   15639: 
                   15640: #define fwri_int3(F,V) { fwri_int2((F),_Fioi.i3=(V)); \
                   15641:                        fwri_int1((F),_Fioi.i3>>16); }
                   15642: #define frdi_int3(F) ((int3)( _Fioi.i3=frdi_uint2((F)), \
                   15643:                        (frdi_int1((F))<<16)|_Fioi.i3 ))
                   15644: 
                   15645: #define fwri_int4(F,V) { fwri_int2((F),_Fioi.i4=(V)); \
                   15646:                        fwri_int2((F),_Fioi.i4>>16); }
                   15647: #define frdi_int4(F) ((int4)( _Fioi.i4=frdi_uint2((F)), \
                   15648:                        (frdi_int2((F))<<16)|_Fioi.i4 ))
                   15649: 
                   15650: #define fwri_int8(F,V) { fwri_int4((F),_Fioi.i8=(V)); \
                   15651:                        fwri_int4((F),_Fioi.i8>>32); }
                   15652: #define frdi_int8(F) ((int8)( _Fioi.i8=frdi_uint4((F)), \
                   15653:                        (frdi_int4((F))<<32)|_Fioi.i8 ))
                   15654: 
                   15655: 
                   15656: /* Floating point */
                   15657: #if MAIN
                   15658: /* See Marsha Grabow & George Gilmer & KT */
                   15659: void
                   15660: dtoieeed(ieee,native)
                   15661:     Ieeed *ieee;
                   15662:     double native;
                   15663: {
                   15664:        double fr, ho, f;
                   15665:        int iexp;
                   15666: 
                   15667:        if(native < 0) {
                   15668:                dtoieeed(ieee, -native);
                   15669:                ieee->h |= 0x80000000L;
                   15670:                return;
                   15671:        }
                   15672:        if(native == 0) {
                   15673:                ieee->l = 0;
                   15674:                ieee->h = 0;
                   15675:                return;
                   15676:        }
                   15677:        fr = frexp(native, &iexp);
                   15678:        f = 2097152L;           /* shouldnt use fp constants here */
                   15679:        fr = modf(fr*f, &ho);
                   15680:        ieee->h = ho;
                   15681:        ieee->h &= 0xfffffL;
                   15682:        ieee->h |= (iexp+1022L) << 20;
                   15683:        f = 65536L;
                   15684:        fr = modf(fr*f, &ho);
                   15685:        ieee->l = ho;
                   15686:        ieee->l <<= 16;
                   15687:        ieee->l |= (long)(fr*f);
                   15688: }
                   15689: #else
                   15690: void dtoieeed();
                   15691: #endif
                   15692: 0707070035350321111006640007620000050000010263500476773367100000700000002300font.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   15693: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   15694: /* The copyright notice does not imply actual or intended publication. */
                   15695: /* AUTHORS:                                            */
                   15696: /*     H. S. Baird - ATT-BL MH - first versions        */
                   15697: /* font.h - typedefs, etc for font-characteristic functions:
                   15698:    The baseline is defined by the locus of bottoms of all characters that
                   15699:    have no descenders and are not punctuation.
                   15700:    The top is the top of characters without risers (negative).
                   15701:    The `rise' is the (negative) height of risers (above baseline), and `descent'
                   15702:    is the positive) distance below baseline.
                   15703:     */
                   15704: 
                   15705: /* font attributes, in absolute scanner coordinates */
                   15706: typedef struct FontAttr {
                   15707:        Scoor body;             /* point size */
                   15708:        Scoor xhgt;             /* x-height */
                   15709:        Scoor ascd;             /* height of ascenders (above xheight, >0) */
                   15710:        Scoor caph;             /* capital height (above baseline, >0) */
                   15711:        Scoor desc;             /* height of descenders (below baseline, >0) */
                   15712:        Scoor doth;             /* height of punctuation dots */
                   15713:        } FontAttr;
                   15714: 
                   15715: #ifdef MAIN
                   15716: FontAttr *ps_to_attr();        /* pointsize, digit'n resol'n --> attributes */
                   15717: xhgt_to_ps();
                   15718: caph_to_ps();
                   15719: #endif
                   15720: 0707070035350320471006640007620000050000010263510476773367200000700000124016jslr.c/* AT&T PROPRIETARY:  Developed at AT&T Expense        */
                   15721: /* AUTHORS:                                            */
                   15722: /*     H. S. Baird - ATT-BL MH - first versions        */
                   15723: /* rlbr - run-length encode a binary raster line
                   15724:   `rasp' is a raster line of bits.  rasp[0] is the leftmost byte in the line and
                   15725:    the 001 bit is the leftmost bit in each byte ("little-endian").
                   15726:    Analyzes the line into a series of runs of `1's, placing them into array
                   15727:    `runs'.  Observes margins:  starts at `lm' bit and continues through `rm'; bits
                   15728:    outside margins are assumed 0.   A `run' is two shorts (the starting &
                   15729:    ending indices of the run of `1's, inclusive).  The indices are shifted
                   15730:    so that the index of `lm' becomes `olm'.  Returns the number of runs.
                   15731:    NOTES:
                   15732:        The contents of the raster-line are restored to their orginal
                   15733:    state on return. The user must ensure that:
                   15734:        (1) margins fall within `rasp';
                   15735:        (2) `rasp' has one extra byte at the end for use by this routine; and
                   15736:        (3) `runs' is big enough to hold the worst-case no. of runs that could
                   15737:             result, which is (rm-lm)/2+1.
                   15738:    */
                   15739: 
                   15740: int rlbr(rasp,lm,rm,olm,runp)
                   15741:        char unsigned rasp[];   /* binary raster line (with 1 extra byte at end) */
                   15742:        int lm,rm;      /* left,right margin bit indices within raster */
                   15743:        int olm;        /* on output, `lm' index has become `olm' */
                   15744:        short runp[];   /* array of run-segments [xs,xe] (pairs of short) */
                   15745: {      register char unsigned *bp,*ep; /* byte pointers into raster line */
                   15746:        register short cb;      /* x_coordinate of 1st bit of current byte */
                   15747:        register short *xp;     /* ptr to x-coordinate in run-length array */
                   15748:        register short prior;   /* prior bit, coded 0400 or 0000 */
                   15749: 
                   15750:        char unsigned *lbp,*rbp;        /* ptrs to margin bytes */
                   15751:        int lo,ro;                      /* `offset' of margin bits in bytes */
                   15752:        char unsigned svlb,svrb,svrrb;  /* unmodified copies of margin bytes */
                   15753:        
                   15754:        if(lm>rm) return(0);
                   15755:        /* compute margins' bytes, save copies, set bits outside margins to 0 */
                   15756:        lbp=rasp+(lm/8);  svlb= *lbp;
                   15757:        /* force bits left of lm to 0 */
                   15758:        lo=lm%8;  if(lo>0) *lbp &= (0377<<lo);
                   15759:        rbp=rasp+(rm/8); svrb= *rbp;
                   15760:        /* force bits right of rm to 0 */
                   15761:        ro=rm%8;  if(ro<7) *rbp &= (0377>>(7-ro));
                   15762:        /* place a 0000 byte to right of margin byte, to force good termination */
                   15763:        svrrb= *(rbp+1);  *(rbp+1)='\0';
                   15764: 
                   15765:        /* MAIN LOOP */
                   15766:        prior=0000;     /* act as if there's a 0 byte to left of margin byte */
                   15767:        xp=runp;
                   15768:        bp=lbp;
                   15769:        ep=rbp+2;
                   15770:        cb=(-lo+olm);
                   15771:        do {    switch( prior | *(bp++) ) {
                   15772:                        /* contents of rlbr.c1 come below here */
                   15773: case 00: break;
                   15774: case 01: *(xp++)=cb; *(xp++)=cb; break;
                   15775: case 02: *(xp++)=cb+1; *(xp++)=cb+1; break;
                   15776: case 03: *(xp++)=cb; *(xp++)=cb+1; break;
                   15777: case 04: *(xp++)=cb+2; *(xp++)=cb+2; break;
                   15778: case 05: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; break;
                   15779: case 06: *(xp++)=cb+1; *(xp++)=cb+2; break;
                   15780: case 07: *(xp++)=cb; *(xp++)=cb+2; break;
                   15781: case 010: *(xp++)=cb+3; *(xp++)=cb+3; break;
                   15782: case 011: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; break;
                   15783: case 012: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; break;
                   15784: case 013: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; break;
                   15785: case 014: *(xp++)=cb+2; *(xp++)=cb+3; break;
                   15786: case 015: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; break;
                   15787: case 016: *(xp++)=cb+1; *(xp++)=cb+3; break;
                   15788: case 017: *(xp++)=cb; *(xp++)=cb+3; break;
                   15789: case 020: *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15790: case 021: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15791: case 022: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15792: case 023: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15793: case 024: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15794: case 025: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15795: case 026: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15796: case 027: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; break;
                   15797: case 030: *(xp++)=cb+3; *(xp++)=cb+4; break;
                   15798: case 031: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; break;
                   15799: case 032: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; break;
                   15800: case 033: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; break;
                   15801: case 034: *(xp++)=cb+2; *(xp++)=cb+4; break;
                   15802: case 035: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; break;
                   15803: case 036: *(xp++)=cb+1; *(xp++)=cb+4; break;
                   15804: case 037: *(xp++)=cb; *(xp++)=cb+4; break;
                   15805: case 040: *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15806: case 041: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15807: case 042: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15808: case 043: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15809: case 044: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15810: case 045: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15811: case 046: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15812: case 047: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15813: case 050: *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15814: case 051: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15815: case 052: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15816: case 053: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15817: case 054: *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15818: case 055: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15819: case 056: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15820: case 057: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; break;
                   15821: case 060: *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15822: case 061: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15823: case 062: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15824: case 063: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15825: case 064: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15826: case 065: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15827: case 066: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15828: case 067: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; break;
                   15829: case 070: *(xp++)=cb+3; *(xp++)=cb+5; break;
                   15830: case 071: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   15831: case 072: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   15832: case 073: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   15833: case 074: *(xp++)=cb+2; *(xp++)=cb+5; break;
                   15834: case 075: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; break;
                   15835: case 076: *(xp++)=cb+1; *(xp++)=cb+5; break;
                   15836: case 077: *(xp++)=cb; *(xp++)=cb+5; break;
                   15837: case 0100: *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15838: case 0101: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15839: case 0102: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15840: case 0103: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15841: case 0104: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15842: case 0105: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15843: case 0106: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15844: case 0107: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15845: case 0110: *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15846: case 0111: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15847: case 0112: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15848: case 0113: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15849: case 0114: *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15850: case 0115: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15851: case 0116: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15852: case 0117: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15853: case 0120: *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15854: case 0121: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15855: case 0122: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15856: case 0123: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15857: case 0124: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15858: case 0125: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15859: case 0126: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15860: case 0127: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15861: case 0130: *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15862: case 0131: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15863: case 0132: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15864: case 0133: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15865: case 0134: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15866: case 0135: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15867: case 0136: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15868: case 0137: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; break;
                   15869: case 0140: *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15870: case 0141: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15871: case 0142: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15872: case 0143: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15873: case 0144: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15874: case 0145: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15875: case 0146: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15876: case 0147: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15877: case 0150: *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15878: case 0151: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15879: case 0152: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15880: case 0153: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15881: case 0154: *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15882: case 0155: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15883: case 0156: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15884: case 0157: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; break;
                   15885: case 0160: *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15886: case 0161: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15887: case 0162: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15888: case 0163: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15889: case 0164: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15890: case 0165: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15891: case 0166: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15892: case 0167: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   15893: case 0170: *(xp++)=cb+3; *(xp++)=cb+6; break;
                   15894: case 0171: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   15895: case 0172: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   15896: case 0173: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   15897: case 0174: *(xp++)=cb+2; *(xp++)=cb+6; break;
                   15898: case 0175: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+6; break;
                   15899: case 0176: *(xp++)=cb+1; *(xp++)=cb+6; break;
                   15900: case 0177: *(xp++)=cb; *(xp++)=cb+6; break;
                   15901: case 0200: *(xp++)=cb+7; prior=0400; break;
                   15902: case 0201: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+7; prior=0400; break;
                   15903: case 0202: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+7; prior=0400; break;
                   15904: case 0203: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+7; prior=0400; break;
                   15905: case 0204: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+7; prior=0400; break;
                   15906: case 0205: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+7; prior=0400; break;
                   15907: case 0206: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+7; prior=0400; break;
                   15908: case 0207: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+7; prior=0400; break;
                   15909: case 0210: *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15910: case 0211: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15911: case 0212: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15912: case 0213: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15913: case 0214: *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15914: case 0215: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15915: case 0216: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15916: case 0217: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+7; prior=0400; break;
                   15917: case 0220: *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15918: case 0221: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15919: case 0222: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15920: case 0223: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15921: case 0224: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15922: case 0225: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15923: case 0226: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15924: case 0227: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15925: case 0230: *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15926: case 0231: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15927: case 0232: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15928: case 0233: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15929: case 0234: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15930: case 0235: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15931: case 0236: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15932: case 0237: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+7; prior=0400; break;
                   15933: case 0240: *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15934: case 0241: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15935: case 0242: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15936: case 0243: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15937: case 0244: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15938: case 0245: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15939: case 0246: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15940: case 0247: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15941: case 0250: *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15942: case 0251: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15943: case 0252: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15944: case 0253: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15945: case 0254: *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15946: case 0255: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15947: case 0256: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15948: case 0257: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15949: case 0260: *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15950: case 0261: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15951: case 0262: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15952: case 0263: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15953: case 0264: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15954: case 0265: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15955: case 0266: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15956: case 0267: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15957: case 0270: *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15958: case 0271: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15959: case 0272: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15960: case 0273: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15961: case 0274: *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15962: case 0275: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15963: case 0276: *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15964: case 0277: *(xp++)=cb; *(xp++)=cb+5; *(xp++)=cb+7; prior=0400; break;
                   15965: case 0300: *(xp++)=cb+6; prior=0400; break;
                   15966: case 0301: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+6; prior=0400; break;
                   15967: case 0302: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+6; prior=0400; break;
                   15968: case 0303: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+6; prior=0400; break;
                   15969: case 0304: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; prior=0400; break;
                   15970: case 0305: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; prior=0400; break;
                   15971: case 0306: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+6; prior=0400; break;
                   15972: case 0307: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+6; prior=0400; break;
                   15973: case 0310: *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15974: case 0311: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15975: case 0312: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15976: case 0313: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15977: case 0314: *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15978: case 0315: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15979: case 0316: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15980: case 0317: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+6; prior=0400; break;
                   15981: case 0320: *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15982: case 0321: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15983: case 0322: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15984: case 0323: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15985: case 0324: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15986: case 0325: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15987: case 0326: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15988: case 0327: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15989: case 0330: *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15990: case 0331: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15991: case 0332: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15992: case 0333: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15993: case 0334: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15994: case 0335: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15995: case 0336: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15996: case 0337: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+6; prior=0400; break;
                   15997: case 0340: *(xp++)=cb+5; prior=0400; break;
                   15998: case 0341: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+5; prior=0400; break;
                   15999: case 0342: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; prior=0400; break;
                   16000: case 0343: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+5; prior=0400; break;
                   16001: case 0344: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; prior=0400; break;
                   16002: case 0345: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; prior=0400; break;
                   16003: case 0346: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; prior=0400; break;
                   16004: case 0347: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; prior=0400; break;
                   16005: case 0350: *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16006: case 0351: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16007: case 0352: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16008: case 0353: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16009: case 0354: *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16010: case 0355: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16011: case 0356: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16012: case 0357: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; prior=0400; break;
                   16013: case 0360: *(xp++)=cb+4; prior=0400; break;
                   16014: case 0361: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+4; prior=0400; break;
                   16015: case 0362: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; prior=0400; break;
                   16016: case 0363: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+4; prior=0400; break;
                   16017: case 0364: *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; prior=0400; break;
                   16018: case 0365: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; prior=0400; break;
                   16019: case 0366: *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; prior=0400; break;
                   16020: case 0367: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; prior=0400; break;
                   16021: case 0370: *(xp++)=cb+3; prior=0400; break;
                   16022: case 0371: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+3; prior=0400; break;
                   16023: case 0372: *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; prior=0400; break;
                   16024: case 0373: *(xp++)=cb; *(xp++)=cb+1; *(xp++)=cb+3; prior=0400; break;
                   16025: case 0374: *(xp++)=cb+2; prior=0400; break;
                   16026: case 0375: *(xp++)=cb; *(xp++)=cb; *(xp++)=cb+2; prior=0400; break;
                   16027: case 0376: *(xp++)=cb+1; prior=0400; break;
                   16028: case 0377: *(xp++)=cb; prior=0400; break;
                   16029: 
                   16030: case 0400: *(xp++)=cb-1; prior=0000; break;
                   16031: case 0401: *(xp++)=cb; prior=0000; break;
                   16032: case 0402: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; prior=0000; break;
                   16033: case 0403: *(xp++)=cb+1; prior=0000; break;
                   16034: case 0404: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; prior=0000; break;
                   16035: case 0405: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; prior=0000; break;
                   16036: case 0406: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; prior=0000; break;
                   16037: case 0407: *(xp++)=cb+2; prior=0000; break;
                   16038: case 0410: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; prior=0000; break;
                   16039: case 0411: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; prior=0000; break;
                   16040: case 0412: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; prior=0000; break;
                   16041: case 0413: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; prior=0000; break;
                   16042: case 0414: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; prior=0000; break;
                   16043: case 0415: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; prior=0000; break;
                   16044: case 0416: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; prior=0000; break;
                   16045: case 0417: *(xp++)=cb+3; prior=0000; break;
                   16046: case 0420: *(xp++)=cb-1; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16047: case 0421: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16048: case 0422: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16049: case 0423: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16050: case 0424: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16051: case 0425: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16052: case 0426: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16053: case 0427: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; prior=0000; break;
                   16054: case 0430: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+4; prior=0000; break;
                   16055: case 0431: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; prior=0000; break;
                   16056: case 0432: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; prior=0000; break;
                   16057: case 0433: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; prior=0000; break;
                   16058: case 0434: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+4; prior=0000; break;
                   16059: case 0435: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; prior=0000; break;
                   16060: case 0436: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+4; prior=0000; break;
                   16061: case 0437: *(xp++)=cb+4; prior=0000; break;
                   16062: case 0440: *(xp++)=cb-1; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16063: case 0441: *(xp++)=cb; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16064: case 0442: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16065: case 0443: *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16066: case 0444: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16067: case 0445: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16068: case 0446: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16069: case 0447: *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16070: case 0450: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16071: case 0451: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16072: case 0452: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16073: case 0453: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16074: case 0454: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16075: case 0455: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16076: case 0456: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16077: case 0457: *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; prior=0000; break;
                   16078: case 0460: *(xp++)=cb-1; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16079: case 0461: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16080: case 0462: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16081: case 0463: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16082: case 0464: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16083: case 0465: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16084: case 0466: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16085: case 0467: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; prior=0000; break;
                   16086: case 0470: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+5; prior=0000; break;
                   16087: case 0471: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; prior=0000; break;
                   16088: case 0472: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; prior=0000; break;
                   16089: case 0473: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; prior=0000; break;
                   16090: case 0474: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+5; prior=0000; break;
                   16091: case 0475: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; prior=0000; break;
                   16092: case 0476: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+5; prior=0000; break;
                   16093: case 0477: *(xp++)=cb+5; prior=0000; break;
                   16094: case 0500: *(xp++)=cb-1; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16095: case 0501: *(xp++)=cb; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16096: case 0502: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16097: case 0503: *(xp++)=cb+1; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16098: case 0504: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16099: case 0505: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16100: case 0506: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16101: case 0507: *(xp++)=cb+2; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16102: case 0510: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16103: case 0511: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16104: case 0512: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16105: case 0513: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16106: case 0514: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16107: case 0515: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16108: case 0516: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16109: case 0517: *(xp++)=cb+3; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16110: case 0520: *(xp++)=cb-1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16111: case 0521: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16112: case 0522: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16113: case 0523: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16114: case 0524: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16115: case 0525: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16116: case 0526: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16117: case 0527: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16118: case 0530: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16119: case 0531: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16120: case 0532: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16121: case 0533: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16122: case 0534: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16123: case 0535: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16124: case 0536: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16125: case 0537: *(xp++)=cb+4; *(xp++)=cb+6; *(xp++)=cb+6; prior=0000; break;
                   16126: case 0540: *(xp++)=cb-1; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16127: case 0541: *(xp++)=cb; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16128: case 0542: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16129: case 0543: *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16130: case 0544: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16131: case 0545: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16132: case 0546: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16133: case 0547: *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16134: case 0550: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16135: case 0551: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16136: case 0552: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16137: case 0553: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16138: case 0554: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16139: case 0555: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16140: case 0556: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16141: case 0557: *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+6; prior=0000; break;
                   16142: case 0560: *(xp++)=cb-1; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16143: case 0561: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16144: case 0562: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16145: case 0563: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16146: case 0564: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16147: case 0565: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16148: case 0566: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16149: case 0567: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; prior=0000; break;
                   16150: case 0570: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+6; prior=0000; break;
                   16151: case 0571: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+6; prior=0000; break;
                   16152: case 0572: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; prior=0000; break;
                   16153: case 0573: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; prior=0000; break;
                   16154: case 0574: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+6; prior=0000; break;
                   16155: case 0575: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+6; prior=0000; break;
                   16156: case 0576: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+6; prior=0000; break;
                   16157: case 0577: *(xp++)=cb+6; prior=0000; break;
                   16158: case 0600: *(xp++)=cb-1; *(xp++)=cb+7; break;
                   16159: case 0601: *(xp++)=cb; *(xp++)=cb+7; break;
                   16160: case 0602: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+7; break;
                   16161: case 0603: *(xp++)=cb+1; *(xp++)=cb+7; break;
                   16162: case 0604: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+7; break;
                   16163: case 0605: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+7; break;
                   16164: case 0606: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+7; break;
                   16165: case 0607: *(xp++)=cb+2; *(xp++)=cb+7; break;
                   16166: case 0610: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16167: case 0611: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16168: case 0612: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16169: case 0613: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16170: case 0614: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16171: case 0615: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16172: case 0616: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16173: case 0617: *(xp++)=cb+3; *(xp++)=cb+7; break;
                   16174: case 0620: *(xp++)=cb-1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16175: case 0621: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16176: case 0622: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16177: case 0623: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16178: case 0624: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16179: case 0625: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16180: case 0626: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16181: case 0627: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16182: case 0630: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16183: case 0631: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16184: case 0632: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16185: case 0633: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16186: case 0634: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16187: case 0635: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16188: case 0636: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16189: case 0637: *(xp++)=cb+4; *(xp++)=cb+7; break;
                   16190: case 0640: *(xp++)=cb-1; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16191: case 0641: *(xp++)=cb; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16192: case 0642: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16193: case 0643: *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16194: case 0644: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16195: case 0645: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16196: case 0646: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16197: case 0647: *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16198: case 0650: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16199: case 0651: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16200: case 0652: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16201: case 0653: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16202: case 0654: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16203: case 0655: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16204: case 0656: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16205: case 0657: *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16206: case 0660: *(xp++)=cb-1; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16207: case 0661: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16208: case 0662: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16209: case 0663: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16210: case 0664: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16211: case 0665: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16212: case 0666: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16213: case 0667: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16214: case 0670: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16215: case 0671: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16216: case 0672: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16217: case 0673: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16218: case 0674: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16219: case 0675: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16220: case 0676: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16221: case 0677: *(xp++)=cb+5; *(xp++)=cb+7; break;
                   16222: case 0700: *(xp++)=cb-1; *(xp++)=cb+6; break;
                   16223: case 0701: *(xp++)=cb; *(xp++)=cb+6; break;
                   16224: case 0702: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+6; break;
                   16225: case 0703: *(xp++)=cb+1; *(xp++)=cb+6; break;
                   16226: case 0704: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; break;
                   16227: case 0705: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+6; break;
                   16228: case 0706: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+6; break;
                   16229: case 0707: *(xp++)=cb+2; *(xp++)=cb+6; break;
                   16230: case 0710: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16231: case 0711: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16232: case 0712: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16233: case 0713: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16234: case 0714: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16235: case 0715: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16236: case 0716: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16237: case 0717: *(xp++)=cb+3; *(xp++)=cb+6; break;
                   16238: case 0720: *(xp++)=cb-1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16239: case 0721: *(xp++)=cb; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16240: case 0722: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16241: case 0723: *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16242: case 0724: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16243: case 0725: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16244: case 0726: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16245: case 0727: *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16246: case 0730: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16247: case 0731: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16248: case 0732: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16249: case 0733: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16250: case 0734: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16251: case 0735: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16252: case 0736: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16253: case 0737: *(xp++)=cb+4; *(xp++)=cb+6; break;
                   16254: case 0740: *(xp++)=cb-1; *(xp++)=cb+5; break;
                   16255: case 0741: *(xp++)=cb; *(xp++)=cb+5; break;
                   16256: case 0742: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+5; break;
                   16257: case 0743: *(xp++)=cb+1; *(xp++)=cb+5; break;
                   16258: case 0744: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; break;
                   16259: case 0745: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+5; break;
                   16260: case 0746: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+5; break;
                   16261: case 0747: *(xp++)=cb+2; *(xp++)=cb+5; break;
                   16262: case 0750: *(xp++)=cb-1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16263: case 0751: *(xp++)=cb; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16264: case 0752: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16265: case 0753: *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16266: case 0754: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16267: case 0755: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16268: case 0756: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16269: case 0757: *(xp++)=cb+3; *(xp++)=cb+5; break;
                   16270: case 0760: *(xp++)=cb-1; *(xp++)=cb+4; break;
                   16271: case 0761: *(xp++)=cb; *(xp++)=cb+4; break;
                   16272: case 0762: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+4; break;
                   16273: case 0763: *(xp++)=cb+1; *(xp++)=cb+4; break;
                   16274: case 0764: *(xp++)=cb-1; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; break;
                   16275: case 0765: *(xp++)=cb; *(xp++)=cb+2; *(xp++)=cb+2; *(xp++)=cb+4; break;
                   16276: case 0766: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+2; *(xp++)=cb+4; break;
                   16277: case 0767: *(xp++)=cb+2; *(xp++)=cb+4; break;
                   16278: case 0770: *(xp++)=cb-1; *(xp++)=cb+3; break;
                   16279: case 0771: *(xp++)=cb; *(xp++)=cb+3; break;
                   16280: case 0772: *(xp++)=cb-1; *(xp++)=cb+1; *(xp++)=cb+1; *(xp++)=cb+3; break;
                   16281: case 0773: *(xp++)=cb+1; *(xp++)=cb+3; break;
                   16282: case 0774: *(xp++)=cb-1; *(xp++)=cb+2; break;
                   16283: case 0775: *(xp++)=cb; *(xp++)=cb+2; break;
                   16284: case 0776: *(xp++)=cb-1; *(xp++)=cb+1; break;
                   16285: case 0777: break;
                   16286: 
                   16287:                        /* contents of jslr.c1 come above here */
                   16288:                        };
                   16289:                cb += 8;
                   16290:                }
                   16291:        while(bp<ep);
                   16292:        /* restore margin bytes */
                   16293:        *lbp = svlb;
                   16294:        *rbp = svrb;
                   16295:        *(rbp+1) = svrrb;
                   16296:        return((xp-runp)/2);
                   16297:        };
                   16298: 0707070035350320511006640007620000050000010263540476773367200001100000001652limits.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   16299: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   16300: /* The copyright notice does not imply actual or intended publication. */
                   16301: /* AUTHORS:                                            */
                   16302: /*     H. S. Baird - ATT-BL MH - first versions        */
                   16303: /* Extreme values of integral types (conforms to Oct 1, 86 draft ANSI C std) */
                   16304: #define CHAR_BIT 8
                   16305: #define SCHAR_MIN -128
                   16306: #define SCHAR_MAX 127
                   16307: #define UCHAR_MIN 0
                   16308: #define UCHAR_MAX 255
                   16309: #define CHAR_MIN SCHAR_MIN     /* type char sign-extends */
                   16310: #define CHAR_MAX SCHAR_MAX     /* type char sign-extends */
                   16311: 
                   16312: #define SHRT_MIN -32768
                   16313: #define SHRT_MAX 32767
                   16314: #define USHRT_MIN 0
                   16315: #define USHRT_MAX 65535
                   16316: 
                   16317: #define INT_MIN -2147483648
                   16318: #define INT_MAX 2147483647
                   16319: #define UINT_MIN 0
                   16320: #define UINT_MAX 4294967295
                   16321: 
                   16322: #define LONG_MIN -2147483648
                   16323: #define LONG_MAX 2147483647
                   16324: #define ULONG_MIN 0
                   16325: #define ULONG_MAX 4294967295
                   16326: 0707070035351106241006640007620000050000010263560476773367300001000000025436myftw.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   16327: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   16328: /* The copyright notice does not imply actual or intended publication. */
                   16329: /* AUTHORS:                                            */
                   16330: /*     H. S. Baird - ATT-BL MH - first versions        */
                   16331: /*
                   16332:  *     ftw - file tree walk
                   16333:  *
                   16334:  *     int ftw (path, fn, depth)  char *path; int (*fn)(); int depth;
                   16335:  *
                   16336:  *     Given a path name, ftw starts from the file given by that path
                   16337:  *     name and visits each file and directory in the tree beneath
                   16338:  *     that file.  If a single file has multiple links within the
                   16339:  *     structure, it will be visited once for each such link.
                   16340:  *     For each object visited, fn is called with four arguments.
                   16341:  *     The fourth can often be ignored; it is a pointer, say S,
                   16342:  *     declared "struct FTW *S", discussed in more detail below.
                   16343:  *     The first contains the path name of the object, the second
                   16344:  *     contains a pointer to a stat buffer which will usually hold
                   16345:  *     appropriate information for the object and the third contains
                   16346:  *     an integer value giving additional information about the
                   16347:  *     object, as follows:
                   16348:  *
                   16349:  *             FTW_F   The object is a file for which stat was
                   16350:  *                     successful.  It does not guarantee that the
                   16351:  *                     file can actually be read.
                   16352:  *
                   16353:  *             FTW_D   The object is a directory for which stat and
                   16354:  *                     open for read were both successful.  This is
                   16355:  *                     a preorder visit -- objects in the directory
                   16356:  *                     are yet to be visited.
                   16357:  *
                   16358:  *             FTW_DNR The object is a directory for which stat
                   16359:  *                     succeeded, but which cannot be read.  Because
                   16360:  *                     the directory cannot be read, fn will not be
                   16361:  *                     called for any descendants of this directory.
                   16362:  *
                   16363:  *             FTW_DP  The object is a directory for which stat and
                   16364:  *                     open for read were both successful.  This is
                   16365:  *                     a postorder visit -- everything in the directory
                   16366:  *                     has already been visited.
                   16367:  *
                   16368:  *             FTW_NS  Lstat failed on the object.  If errno is EACCES,
                   16369:  *                     then the failure stems from lack of
                   16370:  *                     appropriate permission.  This indication will
                   16371:  *                     be given, for example, for each file in a directory
                   16372:  *                     with read but no execute permission.  Whenever
                   16373:  *                     stat fails, it is not possible to determine
                   16374:  *                     whether this object is a file or a directory.
                   16375:  *                     The stat buffer passed to fn will contain garbage.
                   16376:  *
                   16377:  *             FTW_SL  The object is a symbolic link.  Set S->quit
                   16378:  *                     (a component of the structure pointed to by
                   16379:  *                     the fourth parameter to fn) to FTW_FOLLOW to
                   16380:  *                     have the link followed and the object to which
                   16381:  *                     it points visited.
                   16382:  *
                   16383:  *             FTW_NSL Lstat succeeded, but stat failed on the object.
                   16384:  *                     This is only possible when following a symbolic
                   16385:  *                     link.
                   16386:  *
                   16387:  *     Among the components of the structure to which the fourth
                   16388:  *     parameter, S, to fn points is S->quit.  If the caller sets
                   16389:  *     S->quit to FTW_SKR, then no more files in the current directory
                   16390:  *     will be visited.  (The current directory is the one containing
                   16391:  *     the object being visited.)  If the third parameter to fn is
                   16392:  *     FTW_D and the caller sets S->quit to FTW_SKD, then this directory
                   16393:  *     (the one named in the first parameter to fn) will be skipped.
                   16394:  *
                   16395:  *     Other components pointed to by the fourth parameter S are
                   16396:  *     the current recursion level S->level (top level = 0) and
                   16397:  *     the offset S->base in the pathname of the current object
                   16398:  *     (the first parameter to fn) of the object's base name.
                   16399:  *     By expanding the definition of struct FTW given below and
                   16400:  *     including the files included below, one can arrange for
                   16401:  *     S to point to a larger structure, components of which can
                   16402:  *     be initialized (for example) on calls to fn with third
                   16403:  *     parameter FTW_D.
                   16404:  *
                   16405:  *     If fn returns nonzero, ftw stops and returns the same value
                   16406:  *     to its caller.  Ftw only initiates a nonzero return if malloc
                   16407:  *     fails; in this case ftw sets errno to ENOMEM and returns -1.
                   16408:  *
                   16409:  *     The third argument to ftw does not limit the depth to which
                   16410:  *     ftw will go.  Rather, it limits the depth to which ftw will
                   16411:  *     go before it starts recycling file descriptors.  In general,
                   16412:  *     it is necessary to use a file descriptor for each level of the
                   16413:  *     tree, but they can be recycled for deep trees by saving the position,
                   16414:  *     closing, re-opening, and seeking.  It is possible to start
                   16415:  *     recycling file descriptors by sensing when we have run out, but
                   16416:  *     in general this will not be terribly useful if fn expects to be
                   16417:  *     able to open files.  We could also figure out how many file descriptors
                   16418:  *     are available and guarantee a certain number to fn, but we would not
                   16419:  *     know how many to guarantee, and we do not want to impose the extra
                   16420:  *     overhead on a caller who knows how many are available without
                   16421:  *     having to figure it out.
                   16422:  *
                   16423:  *     It is possible for ftw to die with a memory fault in the event
                   16424:  *     of a file system so deeply nested that the stack overflows.
                   16425:  */
                   16426: 
                   16427: #include <sys/types.h>
                   16428: #include <sys/stat.h>
                   16429: #include "myftw.h"     /* not <ftw.h>, for portability to Suns */
                   16430: /*
                   16431:  * Struct FTW (whose definition starts at the end of ftw.h) must
                   16432:  * must include at least the integers quit, base, and level.
                   16433:  */
                   16434: 
                   16435: #define FTW_PATHLEN0 1000
                   16436: #define FTW_PATHINC 1000
                   16437: #ifndef S_IFLNK
                   16438: #define lstat stat
                   16439: #endif
                   16440: #ifdef S_IFSOCK
                   16441: #include <sys/dir.h>
                   16442: #else
                   16443: #include "ndir.h"
                   16444: #endif
                   16445: #ifndef ENOMEM
                   16446: #include <errno.h>
                   16447: #endif
                   16448: 
                   16449:        extern int errno;
                   16450: 
                   16451: /*
                   16452:  *  Each generation of ftw1 (the real ftw) allocates one copy, R, of the
                   16453:  *  following structure; it passes a pointer to this structure when it
                   16454:  *  recursively invokes itself.  These structures are chained together,
                   16455:  *  so that if it becomes necessary to recycle file descriptors, then
                   16456:  *  the oldest descriptor (the one at the shallowest depth still open)
                   16457:  *  can be recycled.
                   16458:  */
                   16459: 
                   16460:        struct FTW_rec {
                   16461:                struct FTW_rec *prev;
                   16462:                long here;      /* seek to here when reopening at this level */
                   16463:                DIR *fd;        /* file descriptor at this level */
                   16464:                };
                   16465: 
                   16466: /*
                   16467:  *  One instance, T, of the following structure is allocated by ftw; a
                   16468:  *  pointer to it is passed to all generations of ftw1 (the real ftw).
                   16469:  *  T could often be a global variable, but this way the parameter fn
                   16470:  *  can invoke ftw for an independent tree walk.
                   16471:  *  Component T->path points to storage for the object path-names;
                   16472:  *  this storage may be relocated by realloc if T->path needs to be
                   16473:  *  more than T->pathlast characters long.
                   16474:  *  T->path[T->pathnext] is the next free character in the pathnames.
                   16475:  *  T->depth = parameter depth to ftw.  T->lastout is the deepest level at
                   16476:  *  which a file descriptor has been recycled.
                   16477:  */
                   16478: 
                   16479:        struct FTW_top {
                   16480:                int (*fn)();
                   16481:                char *path;
                   16482:                unsigned pathlast, pathnext;
                   16483:                int lastout;
                   16484:                int depth;
                   16485:                };
                   16486: 
                   16487: static ftw_1_();
                   16488: 
                   16489: int
                   16490: ftw (path, fn, depth)
                   16491:        char *path;
                   16492:        int (*fn)();
                   16493:        int depth;
                   16494: {
                   16495:        struct FTW_top T;
                   16496:        struct FTW_rec R;
                   16497:        struct FTW S;
                   16498:        int rc;
                   16499:        char *malloc(), *strcpy();
                   16500: 
                   16501:        T.depth = depth;
                   16502:        T.lastout = -1;
                   16503:        T.fn = fn;
                   16504:        S.quit = 0;
                   16505:        S.level = -1;
                   16506: 
                   16507:        /* initialize S.base, T.pathnext... */
                   16508:                {
                   16509:                register char c, *p, *q;
                   16510:                for (p = q = path; c = *p; p++) if (c == '/') q = p + 1;
                   16511:                S.base = q - path;
                   16512:                T.pathnext = p - path;
                   16513:                }
                   16514: 
                   16515:        T.pathlast = T.pathnext + FTW_PATHLEN0;
                   16516:        T.path = malloc(T.pathlast);
                   16517:        if (!T.path) { errno = ENOMEM; return -1; }
                   16518:        strcpy(T.path, path);
                   16519:        rc = ftw_1_(&R, &T, 0, &S);
                   16520:        free(T.path);
                   16521:        return rc;
                   16522: }
                   16523: 
                   16524: int
                   16525: static
                   16526: ftw_1_ (R, T, level, S1)
                   16527:        register struct FTW_rec *R;
                   16528:        register struct FTW_top *T;
                   16529:        int level;
                   16530:        struct FTW *S1;
                   16531: {
                   16532:        int rc, n;
                   16533:        DIR *fd;
                   16534:        struct direct *dirp;
                   16535:        char *component, *path;
                   16536:        struct stat sb;
                   16537:        struct FTW_rec mr;
                   16538:        unsigned nextsave;
                   16539:        struct FTW S;
                   16540:        char *realloc();
                   16541:        long lseek();
                   16542: 
                   16543:        mr.prev = R;
                   16544:        path = T->path;
                   16545:        S.level = level;
                   16546:        S.quit = 0;
                   16547:        S.base = S1->base;
                   16548: 
                   16549:        /* Try to get file status.  If unsuccessful, errno will say why. */
                   16550:        if (lstat(path, &sb) < 0) {
                   16551:                rc = (*T->fn) (path, &sb, FTW_NS, &S);
                   16552:                S1->quit = S.quit;
                   16553:                return rc;
                   16554:                };
                   16555: 
                   16556:        /*
                   16557:         *      The stat succeeded, so we know the object exists.
                   16558:         *      If not a directory, call the user function and return.
                   16559:         */
                   16560: #ifdef S_IFLNK
                   16561:        if ((sb.st_mode & S_IFMT) == S_IFLNK) {
                   16562:                rc = (*T->fn) (path, &sb, FTW_SL, &S);
                   16563:                S1->quit = S.quit;
                   16564:                if (rc || S.quit == FTW_SKR) return rc;
                   16565:                if (S.quit != FTW_FOLLOW) return 0;
                   16566:                S1->quit = S.quit = 0;
                   16567:                if (stat(path, &sb) < 0) {
                   16568:                        rc = (*T->fn) (path, &sb, FTW_NSL, &S);
                   16569:                        S1->quit = S.quit;
                   16570:                        return rc;
                   16571:                        };
                   16572:                }
                   16573: #endif
                   16574:                
                   16575:        if ((sb.st_mode & S_IFMT) != S_IFDIR) {
                   16576:                rc = (*T->fn) (path, &sb, FTW_F, &S);
                   16577:                S1->quit = S.quit;
                   16578:                return rc;
                   16579:                }
                   16580: 
                   16581:        /*
                   16582:         *      The object was a directory.
                   16583:         *
                   16584:         *      Open a file to read the directory
                   16585:         */
                   16586:        mr.fd = fd = opendir(path);
                   16587: 
                   16588:        /*
                   16589:         *      Call the user function, telling it whether
                   16590:         *      the directory can be read.  If it can't be read
                   16591:         *      call the user function or indicate an error,
                   16592:         *      depending on the reason it couldn't be read.
                   16593:         */
                   16594:        if (!fd) {
                   16595:                rc = (*T->fn) (path, &sb, FTW_DNR, &S);
                   16596:                S1->quit = S.quit;
                   16597:                return rc;
                   16598:                }
                   16599: 
                   16600:        /* We could read the directory.  Call user function. */
                   16601:        rc = (*T->fn) (path, &sb, FTW_D, &S);
                   16602:        if (rc != 0)
                   16603:                goto rtrn;
                   16604:        if (S.quit == FTW_SKD) goto rtrn;
                   16605:        if (S.quit == FTW_SKR) {S1->quit = FTW_SKR; goto rtrn;}
                   16606: 
                   16607:        /* Make sure path is big enough to hold generated pathnames. */
                   16608: 
                   16609:        n = nextsave = T->pathnext;
                   16610:        if (n + MAXNAMLEN + 1 >= T->pathlast) {
                   16611:                T->pathlast += FTW_PATHINC;
                   16612:                path = T->path = realloc(T->path, T->pathlast);
                   16613:                if (!path) {
                   16614:                        errno = ENOMEM;
                   16615:                        rc = -1;
                   16616:                        goto rtrn;
                   16617:                        }
                   16618:                }
                   16619:        
                   16620:        /* Create a prefix to which we will append component names */
                   16621: 
                   16622:        if (n > 0 && path[n-1] != '/') path[n++] = '/';
                   16623:        component = path + n;
                   16624: 
                   16625:        /*
                   16626:         *      Read the directory one component at a time.
                   16627:         *      We must ignore "." and "..", but other than that,
                   16628:         *      just create a path name and call self to check it out.
                   16629:         */
                   16630:        while (dirp = readdir(fd)) {
                   16631:                if (dirp->d_ino != 0
                   16632:                    && strcmp (dirp->d_name, ".") != 0
                   16633:                    && strcmp (dirp->d_name, "..") != 0) {
                   16634:                        int i;
                   16635:                        struct FTW_rec *pr;
                   16636: 
                   16637:                        /* Append the component name to the working path */
                   16638:                        strcpy(component, dirp->d_name);
                   16639:                        T->pathnext = n + strlen(dirp->d_name);
                   16640: 
                   16641:                        /*
                   16642:                         *      If we are about to exceed our depth,
                   16643:                         *      remember where we are and close the file.
                   16644:                         */
                   16645:                        if (level - T->lastout >= T->depth) {
                   16646:                                pr = &mr;
                   16647:                                i = T->lastout++;
                   16648:                                while (++i < level) pr = pr->prev;
                   16649:                                pr->here = telldir(pr->fd);
                   16650:                                closedir(pr->fd);
                   16651:                        }
                   16652: 
                   16653:                        /*
                   16654:                         *      Do a recursive call to process the file.
                   16655:                         */
                   16656:                        S.quit = 0;
                   16657:                        S.base = n;
                   16658:                        rc = ftw_1_(&mr, T, level+1, &S);
                   16659:                        if (rc != 0 || S.quit == FTW_SKR) {
                   16660:                                if (level > T->lastout) closedir(fd);
                   16661:                                T->pathnext = nextsave;
                   16662:                                return rc;
                   16663:                        }
                   16664: 
                   16665:                        /*
                   16666:                         *      If we closed the file, try to reopen it.
                   16667:                         */
                   16668:                        if (level <= T->lastout) {
                   16669:                                char c = path[nextsave];
                   16670:                                path[nextsave] = 0;
                   16671:                                T->lastout = level - 1;
                   16672:                                mr.fd = fd = opendir(path);
                   16673:                                if (!fd) {
                   16674:                                        rc = (*T->fn) (path, &sb, FTW_DNR, &S);
                   16675:                                        S1->quit = S.quit;
                   16676:                                        T->pathnext = nextsave;
                   16677:                                        return rc;
                   16678:                                        }
                   16679:                                path[nextsave] = c;
                   16680:                                seekdir(fd, mr.here);
                   16681:                                }
                   16682:                        }
                   16683:                }
                   16684:        T->pathnext = nextsave;
                   16685:        path[nextsave] = 0;
                   16686: 
                   16687:        /*
                   16688:         *      We got out of the subdirectory loop.  Call the user
                   16689:         *      function again at the end and clean up.
                   16690:         */
                   16691: 
                   16692:        rc = (*T->fn) (path, &sb, FTW_DP, &S);
                   16693:        S1->quit = S.quit;
                   16694: rtrn:
                   16695:        closedir(fd);
                   16696:        return rc;
                   16697: }
                   16698: 0707070035350320551006640007620000050000010263640476773367300001000000002137myftw.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   16699: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   16700: /* The copyright notice does not imply actual or intended publication. */
                   16701: /* AUTHORS:                                            */
                   16702: /*     H. S. Baird - ATT-BL MH - first versions        */
                   16703: /*
                   16704:  *     Codes for the third argument to the user-supplied function
                   16705:  *     which is passed as the second argument to ftw...
                   16706:  */
                   16707: 
                   16708: #define        FTW_F   0       /* file */
                   16709: #define        FTW_D   1       /* directory */
                   16710: #define        FTW_DNR 2       /* directory without read permission */
                   16711: #define        FTW_NS  3       /* unknown type, stat failed */
                   16712: #define FTW_DP 4       /* directory, postorder visit */
                   16713: #define FTW_SL 5       /* symbolic link */
                   16714: #define FTW_NSL 6      /* stat failed (errno = ENOENT) on symbolic link */
                   16715: 
                   16716: /*     Values the user-supplied function may wish to assign to
                   16717:        component quit of struct FTW...
                   16718:  */
                   16719: 
                   16720: #define FTW_SKD 1      /* skip this directory (2nd par = FTW_D) */
                   16721: #define FTW_SKR 2      /* skip rest of current directory */
                   16722: #define FTW_FOLLOW 3   /* follow symbolic link */
                   16723: 
                   16724: struct FTW { int quit, base, level;
                   16725: #ifndef FTW_more_to_come
                   16726:        };
                   16727: #endif
                   16728: 0707070035350320571006640007620000050000010263660476773367300000600000003730pic.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   16729: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   16730: /* The copyright notice does not imply actual or intended publication. */
                   16731: /* AUTHORS:                                            */
                   16732: /*     H. S. Baird - ATT-BL MH - first versions        */
                   16733: 
                   16734: /* pic.h -  picture files.  See man page for picfile(5).
                   16735:    They have an ascii header, terminated by \n\n; see PIC_hdr for its data fields.
                   16736:    The rest is binary scanner data. Each `PIC_hdr.bpl' bytes holds one scan-line's
                   16737:    pixels, 1 bit/pixel.  A `1' bit means black.  The order of the bytes in a line
                   16738:    is left-to-right across the page.  The low-order bit in a byte is the left-most.
                   16739:    Conventionally, X-coordinates start at 0, at the left of the page, and
                   16740:    increase to the right.  Y-coordinates start at 0 at the top of the page,
                   16741:    and increase down.
                   16742:    NOTE:  must be preceded by #include "Coord.h"
                   16743:    */
                   16744: 
                   16745: typedef struct PIC_hdr {
                   16746:        /* Contents of picfile ASCII header (or other structure) */
                   16747:        char type[40];          /* "rle" "dump" "binary" "ccitt-g4" "imdir" etc */
                   16748:        Bbx bx;                 /* WINDOW (bounding box) */
                   16749:        short res_x;            /* resolution in pixels/inch (x,y may differ) */
                   16750:        short res_y;
                   16751:        char *parms;            /* PARMS= string */
                   16752:        char *misc;             /* all other unexpected header lines, catenated */
                   16753:        /* the following are used by I/O routines */
                   16754:        FILE *fp;
                   16755:        long seek;              /* current seek address */
                   16756:        int bpl;                /* bytes per line (in file) */
                   16757:        unsigned char *line;    /* one line of picture (malloc space) */
                   16758:        unsigned char *pline;   /* prior line of picture (malloc space) */
                   16759:        Scoor cy;               /* index no. of *line */
                   16760:        } PIC_hdr;
                   16761: #define Init_PIC_hdr {"",Init_Bbx,0,0,NULL,NULL,NULL,0L,0,NULL,NULL,0}
                   16762: #if MAIN
                   16763:     PIC_hdr empty_PIC_hdr = Init_PIC_hdr;
                   16764: #else
                   16765:     extern PIC_hdr empty_PIC_hdr;
                   16766: #endif
                   16767: 
                   16768: /* these functions are in /usr/hsb/ocr/piclib.c */
                   16769: PIC_hdr *alloc_PIC_hdr();
                   16770: int PIC_get_hdr();
                   16771: PIC_put_hdr();
                   16772: err_PIC_line();
                   16773: PIC_skip();
                   16774: int PIC_rline();
                   16775: int PIC_wline();
                   16776: char *PIC_hdr_toa();
                   16777: 0707070035350320561006640007620000050000010263700476773367300001100000044413piclib.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   16778: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   16779: /* The copyright notice does not imply actual or intended publication. */
                   16780: /* AUTHORS:                                            */
                   16781: /*     H. S. Baird - ATT-BL MH - first versions        */
                   16782: 
                   16783: /* piclib.c - picture-file public functions.
                   16784:    alloc_PIC_hdr()     - allocate initialized PIC_hdr, associate with FILE *
                   16785:    free_PIC_hdr()      - free PIC_hdr & all malloc'ed fields
                   16786:    PIC_get_hdr()       - get picture-file header
                   16787:    PIC_rline()         - read one line of picture data
                   16788:    PIC_put_hdr()       - get picture-file header
                   16789:    PIC_wline()         - write one line of picture data
                   16790:    err_PIC_Line()      - print line on stderr
                   16791:    PIC_hdr_toa()       - PIC_hdr to ascii printable string
                   16792:    (PIC_* functions use system I/O, for speed)
                   16793:    */
                   16794: 
                   16795: #include <stdio.h>
                   16796: #include <math.h>
                   16797: #include <string.h>
                   16798: #include "boole.h"
                   16799: #include "limits.h"    /* numeric extreme values */
                   16800: #include "Units.h"
                   16801: #include "Coord.h"
                   16802: #include "pic.h"
                   16803: 
                   16804: #define PIC_debug (0)
                   16805: double atof();
                   16806: 
                   16807: PIC_hdr *alloc_PIC_hdr( fp )
                   16808:     FILE *fp;  /* already-open file descr */
                   16809: {   PIC_hdr *h;
                   16810:        if((h=(PIC_hdr *)malloc(sizeof(PIC_hdr)))==NULL)
                   16811:                abort("piclib: alloc_PIC_hdr: can't alloc");
                   16812:        *h = empty_PIC_hdr;
                   16813:        h->fp = fp;
                   16814:        return(h);
                   16815:        }
                   16816: 
                   16817: free_PIC_hdr( h )
                   16818:     PIC_hdr *h;
                   16819: {      if(h->parms!=NULL) free(h->parms);
                   16820:        if(h->line!=NULL) free(h->line);
                   16821:        if(h->pline!=NULL) free(h->pline);
                   16822:        if(h->misc!=NULL) free(h->misc);
                   16823:        free(h);
                   16824:        }
                   16825: 
                   16826: /* system I/O variation on fgets(3), except it replaces \n with \0,
                   16827:    and returns the number of chars read (including \0) */
                   16828: int PIC_fgets(bf,max,fd)
                   16829:        char *bf;
                   16830:        int max;
                   16831:        int fd;
                   16832: {   char *cp;
                   16833:     int stat,mny;
                   16834:        cp=bf; mny=0;
                   16835:        while(((stat=read(fd,cp,1))==1)&&(++mny<max)&&((*cp)!='\n')) cp++;
                   16836:        if(stat!=1) return(stat);
                   16837:        else if(mny>=max) return(-1);
                   16838:        *cp='\0';
                   16839:        return(mny);
                   16840:        }
                   16841: 
                   16842: /* Read picture file header from file descr fileno(h->fp), set up the rest of the
                   16843:    header, and return status:  1 OK, 0 EOF, <0 error */
                   16844: int PIC_get_hdr( h )
                   16845:     PIC_hdr *h;
                   16846: #define HL_MAX 300
                   16847: #define HTERM "=,      \n"     /* terminations for header words: "=,<sp><tab>" */
                   16848: {   char *cp,*parm,hline[HL_MAX],oline[HL_MAX],*hl;
                   16849:     int status,nrd,ch,mny;
                   16850:        /* synchronize FILE * ptr with file descr ptr */
                   16851:        fseek(h->fp,h->seek = lseek(fileno(h->fp),0L,1),0);
                   16852:        hline[0]='\0';
                   16853:        if((mny=read(fileno(h->fp),hline,5))!=5)
                   16854:                return(0);
                   16855:        if(!(hline[0]=='T' && hline[1]=='Y' && hline[2]=='P'
                   16856:                && hline[3]=='E' && hline[4]=='=')) {
                   16857:                /* no "TYPE=" header; don't accept */
                   16858:                if(0) /* don't accept */ {
                   16859:                        if(PIC_debug)
                   16860:                                err("PIC_get_hdr: can't find TYPE=... header");
                   16861:                        return(-1);
                   16862:                        }
                   16863:                else /* accept as bitfile format (OBSOLESCENT) */ {
                   16864:                        strcpy(h->type,"bitfile");
                   16865:                        h->res_x = h->res_y = 0;
                   16866:                        fseek(h->fp,h->seek+2L,0);      /* back up to byte no. 2 */
                   16867:                        /* read window */
                   16868:                        if((ch=getc(h->fp))!=EOF) { h->bx.a.x = ch;
                   16869:                         if((ch=getc(h->fp))!=EOF) { h->bx.a.x += (ch<<8);
                   16870:                          if((ch=getc(h->fp))!=EOF) { h->bx.a.y = ch;
                   16871:                           if((ch=getc(h->fp))!=EOF) { h->bx.a.y += (ch<<8);
                   16872:                            if((ch=getc(h->fp))!=EOF) { h->bx.b.x = ch;
                   16873:                             if((ch=getc(h->fp))!=EOF) { h->bx.b.x += (ch<<8);
                   16874:                              if((ch=getc(h->fp))!=EOF) { h->bx.b.y = ch;
                   16875:                               if((ch=getc(h->fp))!=EOF) { h->bx.b.y += (ch<<8); }}}}}}}}
                   16876:                        else return(0/*EOF*/);
                   16877:                        h->bx.b.x--;  h->bx.b.y--;
                   16878:                        /* synchronize file descr ptr with FILE * ptr */
                   16879:                        lseek(fileno(h->fp),h->seek = ftell(h->fp),0);
                   16880:                        };
                   16881:                }
                   16882:        else {
                   16883:            if((status=PIC_fgets(hline+5,HL_MAX-5,fileno(h->fp)))<=0)
                   16884:                return(status);
                   16885:            strcpy(oline,hline);
                   16886:            hl=hline;  while(*hl==' ') hl++;  /* strip initial blanks */
                   16887:            while(strlen(hl)>1) {
                   16888:                if(PIC_debug) err("PIC_get_hdr:  hl \"%s\"",hl);
                   16889:                parm=strtok(hl,HTERM);
                   16890:                if(parm!=NULL&&strcmp(parm,"TYPE")==0) {
                   16891:                        if((parm=strtok(0,HTERM))!=NULL) {
                   16892:                                strcpy(h->type,parm);
                   16893:                                if( (strcmp(h->type,"dump")==0)
                   16894:                                    || (strcmp(h->type,"pico")==0)
                   16895:                                    || (strcmp(h->type,"rle")==0)
                   16896:                                    || (strcmp(h->type,"binary")==0)
                   16897:                                    || (strcmp(h->type,"bitmap")==0)
                   16898:                                    || (strcmp(h->type,"dim")==0)
                   16899:                                    || (strcmp(h->type,"document-image")==0)
                   16900:                                    || (strcmp(h->type,"ccitt-g31")==0)
                   16901:                                    || (strcmp(h->type,"ccitt-g32")==0)
                   16902:                                    || (strcmp(h->type,"ccitt-g4")==0)
                   16903:                                    || (strcmp(h->type,"cdf")==0)
                   16904:                                    || (strcmp(h->type,"tiff")==0)
                   16905:                                    ) /* these types are expected */ {
                   16906:                                        if(PIC_debug)
                   16907:                                                err("PIC_get_hdr:  good TYPE=\"%s\"",h->type);
                   16908:                                        }
                   16909:                                else {  if(PIC_debug)
                   16910:                                                err("PIC_get_hdr:  unexpected TYPE=\"%s\"",h->type);
                   16911:                                        return(-1);
                   16912:                                        };
                   16913:                                }
                   16914:                        else {  if(PIC_debug)
                   16915:                                        err("PIC_get_hdr:  1st line must be TYPE=...");
                   16916:                                        
                   16917:                                return(-1);
                   16918:                                };
                   16919:                        }
                   16920:                else if(parm!=NULL&&strcmp(parm,"WINDOW")==0) {
                   16921:                        if((parm=strtok(0,HTERM))!=NULL) h->bx.a.x=atoi(parm);
                   16922:                        else return(-1);
                   16923:                        if((parm=strtok(0,HTERM))!=NULL) h->bx.a.y=atoi(parm);
                   16924:                        else return(-1);
                   16925:                        if((parm=strtok(0,HTERM))!=NULL) h->bx.b.x=atoi(parm)-1;
                   16926:                        else return(-1);
                   16927:                        if((parm=strtok(0,HTERM))!=NULL) h->bx.b.y=atoi(parm)-1;
                   16928:                        else return(-1);
                   16929:                        }
                   16930:                else if(parm!=NULL&&strcmp(parm,"RES")==0) {
                   16931:                        if((parm=strtok(0,HTERM))!=NULL)
                   16932:                                h->res_x=(int)(atof(parm)+0.5);
                   16933:                        else return(-1);
                   16934:                        if((parm=strtok(0,HTERM))!=NULL)
                   16935:                                h->res_y=(int)(atof(parm)+0.5);
                   16936:                        else return(-1);
                   16937:                        }
                   16938:                else if(parm!=NULL&&strcmp(parm,"NCHAN")==0) {
                   16939:                    int nchan;
                   16940:                        if((parm=strtok(0,HTERM))!=NULL) nchan=atoi(parm);
                   16941:                        else return(-1);
                   16942:                        if(nchan!=1) {
                   16943:                                err("PIC_get_hdr: NCHAN=%d illegal: must be 1",nchan);
                   16944:                                return(-1);
                   16945:                                };
                   16946:                        }
                   16947:                else if(parm!=NULL&&strcmp(parm,"PARMS")==0) {
                   16948:                    int nchan;
                   16949:                        if((parm=strtok(0,"\n"))!=NULL) {
                   16950:                                h->parms = strdup(parm);
                   16951:                                }
                   16952:                        else return(-1);
                   16953:                        }
                   16954:                else if(parm!=NULL) {
                   16955:                    char *cat;
                   16956:                        /* save all header lines with unexpected keywords */
                   16957:                        if(h->misc==NULL) h->misc=(char *)malloc(strlen(oline)+2);
                   16958:                        else {  cat=(char *)malloc(strlen(h->misc)+strlen(oline)+2);
                   16959:                                strcpy(cat,h->misc);
                   16960:                                free(h->misc);
                   16961:                                h->misc=cat;
                   16962:                                };
                   16963:                        strcat(h->misc,oline);
                   16964:                        strcat(h->misc,"\n");
                   16965:                        }
                   16966:                else return(-1);
                   16967:                if((status=PIC_fgets(hline,HL_MAX,fileno(h->fp)))<=0)
                   16968:                        return(status);
                   16969:                strcpy(oline,hline);
                   16970:                hl=hline;  while(*hl==' ') hl++;  /* strip initial blanks */
                   16971:                };
                   16972:            };
                   16973: 
                   16974:        if(strcmp(h->type,"cdf")==0) {
                   16975:            int stat;
                   16976:                /* Compund Document Format has binary header */
                   16977:                /* synchronize FILE * ptr with file descr ptr */
                   16978:                fseek(h->fp,h->seek = lseek(fileno(h->fp),0L,1),0);
                   16979:                if((stat=CDF_get_hdr(h)) != 1) return(stat);
                   16980:                };
                   16981: 
                   16982:        if(strcmp(h->type,"tiff")==0) {
                   16983:            int stat;
                   16984:                /* Tagged Image File Format has abinary header */
                   16985:                /* synchronize FILE * ptr with file descr ptr */
                   16986:                fseek(h->fp,h->seek = lseek(fileno(h->fp),0L,1),0);
                   16987:                if((stat=TIFF_get_hdr(h)) != 1) return(stat);
                   16988:                };
                   16989: 
                   16990:        /* may want to allocate a line buffer here */
                   16991:        h->bpl = bbx_wid(&(h->bx));
                   16992:        if(strcmp(h->type,"binary")==0)
                   16993:                h->bpl = (h->bpl+7)/8;          /* round up to byte boundary */
                   16994:        else if(strcmp(h->type,"bitfile")==0)
                   16995:                h->bpl = 2*((h->bpl+15)/16);    /* round up to 2-byte boundary */
                   16996:        else if(strcmp(h->type,"bitmap")==0)
                   16997:                h->bpl = 2*((h->bpl+15)/16);    /* round up to 2-byte boundary */
                   16998:        else if( strcmp(h->type,"rle")==0
                   16999:                || strcmp(h->type,"dim")==0
                   17000:                || strcmp(h->type,"document-image")==0
                   17001:                || strcmp(h->type,"cdf")==0
                   17002:                || strcmp(h->type,"cdf-mrlc")==0
                   17003:                || strcmp(h->type,"cdf-g31")==0
                   17004:                || strcmp(h->type,"cdf-g32")==0
                   17005:                || strcmp(h->type,"cdf-g4")==0
                   17006:                || strcmp(h->type,"tiff")==0 )
                   17007:                h->bpl = 0;
                   17008:        if(h->bpl==0) h->line = NULL;
                   17009:        else {  /* allocate one extra byte in line buffer as a favor to RLE */
                   17010:                if((h->line = (unsigned char *) malloc(h->bpl+1))==NULL) {
                   17011:                        fprintf(stderr,
                   17012:                                "piclib: PIC_get_hdr: can't alloc h->line (%d bytes) - abort\n",
                   17013:                                h->bpl+1);
                   17014:                        return(-1);
                   17015:                        };
                   17016:                memset(h->line,'\0',h->bpl);
                   17017:                if(strcmp(h->type,"bitfile")==0) {
                   17018:                        if((h->pline = (unsigned char *) malloc(h->bpl+1))==NULL) {
                   17019:                                fprintf(stderr,
                   17020:                                        "piclib: PIC_get_hdr: can't alloc h->pline (%d bytes) - abort\n",
                   17021:                                        h->bpl+1);
                   17022:                                return(-1);
                   17023:                                };
                   17024:                        };
                   17025:                };
                   17026:        h->cy = h->bx.a.y-1;    /* just prior to 1st line */
                   17027:        /* synchronize FILE * ptr with file descr ptr */
                   17028:        fseek(h->fp,h->seek = lseek(fileno(h->fp),0L,1),0);
                   17029:        return(1);
                   17030:        }
                   17031: 
                   17032: /* Read next page from AT&T Image Director file header from file descr
                   17033:    fileno(h->fp), set up the rest of the header, and return status:
                   17034:    1 OK, 0 EOF, <0 error */
                   17035: int CDF_next_page( h )
                   17036:     PIC_hdr *h;
                   17037: {      return(-1);     /* unimplemented */
                   17038:        }
                   17039: 
                   17040: #define HASHEADER(h) ((strcmp((h)->type,"postscript")!=0&&strcmp((h)->type,"sunraster")!=0))
                   17041: 
                   17042: /* Read AT&T Image Director file header from file descr fileno(h->fp),
                   17043:    set up the rest of the header, and return status:  1 OK, 0 EOF, <0 error */
                   17044: int CDF_get_hdr( h )
                   17045:     PIC_hdr *h;
                   17046: {   char *cp,*parm,hline[HL_MAX];
                   17047:     int status,nrd,ch,mny;
                   17048: #define dbg_cdf (0)
                   17049: typedef struct CDF_file {
                   17050:        unsigned char raw[16];
                   17051:        unsigned char op,np,at;
                   17052:        unsigned int l1,l2,len;
                   17053:        } CDF_file;
                   17054: typedef struct CDF_page {
                   17055:        unsigned char raw[16];
                   17056:        unsigned char op,pn,at;
                   17057:        unsigned char f1,f2,f3,f4;
                   17058:         unsigned int ptr;
                   17059:        } CDF_page;
                   17060: typedef struct CDF_recd {
                   17061:        unsigned char raw[16];
                   17062:        unsigned char op,a1,a2,a3;
                   17063:         unsigned int len;
                   17064:        Bbx bx;
                   17065:        } CDF_recd;
                   17066:     CDF_file fh;
                   17067:     CDF_page ph;
                   17068:     CDF_recd rh;
                   17069:     
                   17070:        if(dbg_cdf) err("CDF_get_hdr: enter %s",PIC_hdr_toa(h));
                   17071:        /* synchronize FILE * ptr with file descr ptr */
                   17072:        fseek(h->fp,h->seek = lseek(fileno(h->fp),0L,1),0);
                   17073:        strcpy(h->type,"cdf");
                   17074: 
                   17075:        /* Read CDF File header */
                   17076:        if(fread(fh.raw,1,16,h->fp)!=16) return(0);
                   17077:        fh.op = fh.raw[0];
                   17078:        fh.np = fh.raw[1];
                   17079:        fh.at = fh.raw[2];
                   17080:        fh.l1 = fh.raw[4]+256*fh.raw[5];
                   17081:        fh.l2 = fh.raw[6]+256*fh.raw[7];
                   17082:        fh.len = fh.raw[12]+256*(fh.raw[13]+256*(fh.raw[14]+256*fh.raw[15]));
                   17083:        if(dbg_cdf) err("CDF_get_hdr: file hdr: op0x%x p%d at0x%x lim1:%u lim2:%u len%u",
                   17084:                fh.op,fh.np,fh.at,fh.l1,fh.l2,fh.len);
                   17085:        if(fh.op!=0xA0&&fh.op!=0xAF) abort("CDF_get_hdr: file must be CDF type");
                   17086:        if(fh.np!=1) err("CDF_get_hdr: file has %d pages - ignore all but 1st",fh.np);
                   17087:        switch(fh.at>>4) {
                   17088:            case 0:     h->res_x = h->res_y = 100;  break;
                   17089:            case 1:     h->res_x = h->res_y = 200;  break;
                   17090:            case 2:     h->res_x = h->res_y = 300;  break;
                   17091:            default:    err("CDF_get_hdr: file has unknown resolution nibble 0x%x -- assume 400 dpi",fh.at>>4);
                   17092:                        h->res_x = h->res_y = 400;
                   17093:                        break;
                   17094:            };
                   17095:        h->bx.a.x = h->bx.a.y = 0;
                   17096:        h->bx.b.x = fh.l1;
                   17097:        h->bx.b.y = fh.l2;
                   17098:        if(fh.op==0xAF) {
                   17099:                abort("CDF_get_hdr: file has continuation header");
                   17100:                };
                   17101: 
                   17102:        /* Read 1st page table entry */
                   17103:        if(fread(ph.raw,1,16,h->fp)!=16) return(0);
                   17104:        ph.op = ph.raw[0];
                   17105:        ph.pn = ph.raw[1];
                   17106:        ph.at = ph.raw[2];
                   17107:        ph.ptr = ph.raw[12]+256*(ph.raw[13]+256*(ph.raw[14]+256*ph.raw[15]));
                   17108:        if(dbg_cdf) err("CDF_get_hdr: page hdr: op0x%x p%d at0x%x ptr%u",
                   17109:                ph.op,ph.pn,ph.at,ph.ptr);
                   17110:        if(ph.op!=0x80&&ph.op!=0x8F)
                   17111:                abort("CDF_get_hdr: page opcode 0x%x is peculiar",ph.op);
                   17112:        if(ph.pn!=1) err("CDF_get_hdr: page %d out of order - read anyway",ph.pn);
                   17113:        switch(ph.at&0x0F) {    /* low nibble */
                   17114:            case 0:     /* portrait */  break;
                   17115:            case 1:     /* landscape */
                   17116:            default:    err("CDF_get_hdr: page has peculiar format nibble 0x%x -- assume 40portrait",ph.at&0x0F);
                   17117:                        break;
                   17118:            };
                   17119:        switch(ph.at>>4) {      /* high nibble */
                   17120:            case 0xF:   /* background is white */  break;
                   17121:            default:    err("CDF_get_hdr: page has peculiar color nibble 0x%x -- assume white",ph.at>>4);
                   17122:                        break;
                   17123:            };
                   17124:        /* seek top of Page */
                   17125:        fseek(h->fp,h->seek+=ph.ptr,0);
                   17126: 
                   17127:        /* Read CDF Record header */
                   17128:        if(fread(rh.raw,1,16,h->fp)!=16) return(0);
                   17129:        rh.op = rh.raw[0];
                   17130:        rh.a1 = rh.raw[1];
                   17131:        rh.a2 = rh.raw[2];
                   17132:        rh.a3 = rh.raw[3];
                   17133:        rh.len = rh.raw[4]+256*rh.raw[5];
                   17134:        rh.bx.a.x = rh.raw[8]+256*rh.raw[9];
                   17135:        rh.bx.a.y = rh.raw[10]+256*rh.raw[11];
                   17136:        rh.bx.b.x = rh.raw[12]+256*rh.raw[13];
                   17137:        rh.bx.b.y = rh.raw[14]+256*rh.raw[15];
                   17138:        if(dbg_cdf) err("CDF_get_hdr: record hdr: op0x%x a0x%x,0x%x,0x%x len%u bx%s",
                   17139:                rh.op,rh.a1,rh.a2,rh.a3,rh.len,bbx_toa(&rh.bx));
                   17140:        switch(rh.op) {
                   17141:            case 0x20: /* Image */ break;
                   17142:            case 0x01: /* End of Page */ 
                   17143:            case 0x10: /* Text */ 
                   17144:            case 0x1F: /* Text + cont. */ 
                   17145:            case 0x50: /* Text Document */ 
                   17146:            case 0x5F: /* Text Document + cont. */ 
                   17147:            case 0x40: case 0x41: case 0x42: case 0x43: case 0x44:
                   17148:            case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4A:
                   17149:            case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
                   17150:                        /* Graphics */ 
                   17151:            default:
                   17152:                abort("CDF_get_hdr: record not Image");
                   17153:            };
                   17154:        if(rh.a2!=0x01) err("CDF_get_hdr: record not opaque - assume opaque");
                   17155:        switch(rh.a3&0x0F) {    /* compression algorithm */
                   17156:            case 1:     /* modified run-length code */
                   17157:                strcat(h->type,"-mrlc");
                   17158:                break;
                   17159:            case 0:     /* raw */
                   17160:                abort("CDF_get_hdr: record compression 0x%x is legal but unsupported",rh.a3&0x0F);
                   17161:                break;
                   17162:            case 2:     /* ccitt_g31 */
                   17163:                strcat(h->type,"-g31");
                   17164:                abort("CDF_get_hdr: record compression 0x%x is legal but unsupported",rh.a3&0x0F);
                   17165:                break;
                   17166:            case 3:     /* ccitt_g32 or ccitt_g4 */
                   17167:                strcat(h->type,"-g32");
                   17168:                abort("CDF_get_hdr: record compression 0x%x is legal but unsupported",rh.a3&0x0F);
                   17169:                break;
                   17170:            default:
                   17171:                abort("CDF_get_hdr: record compression 0x%x is peculiar",rh.a3&0x0F);
                   17172:                break;
                   17173:            };
                   17174:        switch(rh.a3>>4) {      /* resolution */
                   17175:            case 0:
                   17176:                h->res_y = 100;
                   17177:                break;
                   17178:            case 1:
                   17179:                h->res_y = 200;
                   17180:                break;
                   17181:            case 2:
                   17182:                h->res_y = 300;
                   17183:                break;
                   17184:            default:
                   17185:                err("CDF_get_hdr: record vert resolution peculiar 0x%x - assume 200 dpi",
                   17186:                        rh.a3>>4);
                   17187:                h->res_y = 200;
                   17188:                break;
                   17189:            };
                   17190:        /* synchronize file descr ptr with FILE * ptr */
                   17191:        lseek(fileno(h->fp),h->seek = ftell(h->fp),0);
                   17192:        if(dbg_cdf) err("CDF_get_hdr: normal exit %s",PIC_hdr_toa(h));
                   17193:        return(1);
                   17194:        }
                   17195: 
                   17196: /* Read Tagged Image Format File (TIFF) header, from file descr fileno(h->fp),
                   17197:    set up the rest of the PIC header, and return status:  1 OK, 0 EOF, <0 error */
                   17198: int TIFF_get_hdr( h )
                   17199:     PIC_hdr *h;
                   17200: {      err("TIFF not yet supported");
                   17201:        return(-1);
                   17202:        }
                   17203: 
                   17204: /* Write header to picture file, to file descriptor fileno(h->fp), and initialize
                   17205:    line buffer and cy. */
                   17206: PIC_put_hdr( h )
                   17207:    PIC_hdr *h;
                   17208: {   char *cp,*parm,hline[HL_MAX];
                   17209:     int status,nrd;
                   17210:     unsigned short s;
                   17211: #define put_ushort(S) { s=(S); putc(s&0377,h->fp); putc(s>>8,h->fp); }
                   17212: 
                   17213:        /* write type header */
                   17214:        if( strcmp(h->type,"bitfile")==0 ) {    /* bitfile header */
                   17215:                put_ushort(0);
                   17216:                }
                   17217:        else if(HASHEADER(h)) {
                   17218:                sprintf(hline,"TYPE=%s\n",h->type);
                   17219:                  write(fileno(h->fp),hline,strlen(hline));
                   17220:                };
                   17221:        if(strcmp(h->type,"pico")==0
                   17222:            || strcmp(h->type,"dump")==0) {
                   17223:                sprintf(hline,"NCHAN=1\n");
                   17224:                  write(fileno(h->fp),hline,strlen(hline));
                   17225:                };
                   17226: 
                   17227:        /* write window */
                   17228:        h->bpl = bbx_wid(&(h->bx));
                   17229:        if(strcmp(h->type,"binary")!=0
                   17230:                && strcmp(h->type,"bitfile")!=0
                   17231:                && strcmp(h->type,"bitmap")!=0
                   17232:                && HASHEADER(h)) {
                   17233:                sprintf(hline,"WINDOW=%d %d %d %d\n",
                   17234:                                h->bx.a.x,h->bx.a.y,h->bx.b.x+1,h->bx.b.y+1);
                   17235:                  write(fileno(h->fp),hline,strlen(hline));
                   17236:                }
                   17237:        else if(strcmp(h->type,"binary")==0) {
                   17238:                h->bpl = (h->bpl+7)/8;  /* round up to byte boundary */
                   17239:                sprintf(hline,"WINDOW=%d %d %d %d\n",
                   17240:                                h->bx.a.x,h->bx.a.y,h->bx.b.x+1,h->bx.b.y+1);
                   17241:                  write(fileno(h->fp),hline,strlen(hline));
                   17242:                }
                   17243:        else if(strcmp(h->type,"bitmap")==0) {
                   17244:                h->bpl = 2*((h->bpl+15)/16);    /* round up to 2-byte boundary */
                   17245:                sprintf(hline,"WINDOW=%d %d %d %d\n",
                   17246:                                h->bx.a.x,h->bx.a.y,h->bx.b.x+1,h->bx.b.y+1);
                   17247:                  write(fileno(h->fp),hline,strlen(hline));
                   17248:                }
                   17249:        else if(strcmp(h->type,"sunraster")!=0 ) {      /* bitfile window */
                   17250:                h->bpl = 2*((h->bpl+15)/16);  /* round up to 2-byte boundary */
                   17251:                put_ushort(h->bx.a.x);  put_ushort(h->bx.a.y);
                   17252:                put_ushort(h->bx.b.x+1);  put_ushort(h->bx.b.y+1);
                   17253:                fflush(h->fp);
                   17254:                };
                   17255:        if( ((h->res_x!=0||h->res_y!=0)) && (HASHEADER(h))
                   17256:                && strcmp(h->type,"bitfile")!=0 ) {
                   17257:                sprintf(hline,"RES=%d %d\n",h->res_x,h->res_y);
                   17258:                  write(fileno(h->fp),hline,strlen(hline));
                   17259:                };
                   17260:        if(h->parms!=NULL && strlen(h->parms)>0 && strcmp(h->type,"bitfile")!=0 ) {
                   17261:                sprintf(hline,"PARMS=%s\n",h->parms);
                   17262:                  write(fileno(h->fp),hline,strlen(hline));
                   17263:                };
                   17264:        if(h->misc!=NULL && strlen(h->misc)>0 && strcmp(h->type,"bitfile")!=0 ) {
                   17265:                write(fileno(h->fp),h->misc,strlen(h->misc));
                   17266:                };
                   17267:        /* terminating blank line */
                   17268:        if( HASHEADER(h) && strcmp(h->type,"bitfile")!=0 ) {
                   17269:                hline[0] = '\n';
                   17270:                write(fileno(h->fp),hline,1);
                   17271:                };
                   17272: 
                   17273:        if(strcmp(h->type,"rle")==0) { h->bpl = 0;  h->line = NULL; }
                   17274:        else {  /* allocate one extra byte in line buffer as a favor to RLE */
                   17275:                if((h->line = (unsigned char *) malloc(h->bpl+1))==NULL) {
                   17276:                        fprintf(stderr,
                   17277:                                "piclib: PIC_put_hdr: can't alloc h->line (%d bytes) - abort\n",
                   17278:                                h->bpl+1);
                   17279:                        return(-1);
                   17280:                        };
                   17281:                if(strcmp(h->type,"bitfile")==0) {
                   17282:                        memset(h->line,'\0',h->bpl);
                   17283:                        if((h->pline = (unsigned char *) malloc(h->bpl+1))==NULL) {
                   17284:                                fprintf(stderr,
                   17285:                                        "piclib: PIC_put_hdr: can't alloc h->pline (%d bytes) - abort\n",
                   17286:                                        h->bpl+1);
                   17287:                                return(-1);
                   17288:                                };
                   17289:                        };
                   17290:                };
                   17291:        h->cy = h->bx.a.y-1;    /* just prior to 1st line */
                   17292:        /* synchronize FILE * ptr with file descr ptr */
                   17293:        fseek(h->fp,h->seek = lseek(fileno(h->fp),0L,1),0);
                   17294:        }
                   17295: 
                   17296: err_PIC_line(h,sl)
                   17297:        PIC_hdr *h;
                   17298:        char *sl;
                   17299: #define BPL 20 /* bytes to display per line */
                   17300: {   char *cp,*ep;
                   17301:     int bpl;           /* bytes per display line */
                   17302:        bpl=0;
                   17303:        for(cp=sl,ep=sl+h->bpl; cp!=ep; cp++) {
                   17304:                fprintf(stderr,"%o ",0377&(*cp));
                   17305:                if((++bpl)%BPL==0) fprintf(stderr,"\n   ");
                   17306:                };
                   17307:        if((bpl)%BPL!=0)fprintf(stderr,"\n");
                   17308:        }
                   17309: 
                   17310: /* Skip `y' lines of PIC file */
                   17311: PIC_skip(h,y)
                   17312:     PIC_hdr *h;
                   17313:     int y;
                   17314: {      lseek(fileno(h->fp),(long)(y*h->bpl),1);
                   17315:        h->seek += y*h->bpl;
                   17316:        h->cy += y;
                   17317:        }
                   17318: 
                   17319: /* Read next full line of picture data, and if OK update line & cy;
                   17320:    return status:  1 OK, 0 EOF, -1 ERR.
                   17321:    Free buffer in header on EOF. */
                   17322: int PIC_rline(h,lbpp)
                   17323:     PIC_hdr *h;
                   17324:     unsigned char **lbpp;
                   17325: {   int stat;
                   17326:        if( (stat=read(fileno(h->fp),h->line,h->bpl)) == h->bpl) {
                   17327:                *lbpp=h->line;
                   17328:                h->seek += h->bpl;
                   17329:                h->cy++;
                   17330:                if(PIC_debug) err("read %d bytes from fileno(h->fp) - OK",stat);
                   17331:                return(1);
                   17332:                }
                   17333:        else { /* EOF or ERR */
                   17334:                *lbpp=NULL;
                   17335:                free(h->line);  h->line = NULL;
                   17336:                if(PIC_debug) err("read from fileno(h->fp) stat%d",stat);
                   17337:                if((stat>=0)&&(stat<h->bpl)) return(0 /*EOF*/);
                   17338:                else return(-1);
                   17339:                };
                   17340:        }
                   17341: 
                   17342: /* write a full line of picture data, returning status:  1 OK, 0 EOF, -1 ERR */
                   17343: int PIC_wline(h,line)
                   17344:     PIC_hdr *h;
                   17345:     unsigned char *line;
                   17346: {   int stat;
                   17347:        if( (stat=write(fileno(h->fp),line,h->bpl)) == h->bpl) {
                   17348:                h->seek += h->bpl;
                   17349:                h->cy++;
                   17350:                if(PIC_debug) err("wrote %d bytes to fd%d - OK",stat,fileno(h->fp));
                   17351:                return(1);
                   17352:                }
                   17353:        else { /* ERR */
                   17354:                err("write to fd%d stat%d",fileno(h->fp),stat);
                   17355:                if((stat>=0)&&(stat<h->bpl)) return(0 /*EOF*/);
                   17356:                else return(-1);
                   17357:                };
                   17358:        }
                   17359: 
                   17360: char *PIC_hdr_toa(h)
                   17361:     PIC_hdr *h;
                   17362: {   static char s[120];
                   17363:        sprintf(s,"{type=%s bx%s res%d,%d bpl%d cy%d sk%d}",
                   17364:                h->type,
                   17365:                bbx_toa(&(h->bx)),
                   17366:                h->res_x,h->res_y,
                   17367:                h->bpl,
                   17368:                h->cy,
                   17369:                h->seek
                   17370:                );
                   17371:        return(s);
                   17372:        }
                   17373: 0707070035351135641006640007620000050000010264030476773367300001200000032256postlib.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   17374: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   17375: /* The copyright notice does not imply actual or intended publication. */
                   17376: /* AUTHORS:                                            */
                   17377: /*     T. Thompson - ATT-BL HO - first versions        */
                   17378: /* Routines for generating PostScript from RLE. */
                   17379: /* The routines at the bottom of this file, which */
                   17380: /* do the actual conversion to postscript, were */
                   17381: /* hacked out of 'sun2ps'.  The original header */
                   17382: /* giving credit to its authors is there. */
                   17383: 
                   17384: /* The 'binary' version of the output is collected in a */
                   17385: /* temporary file, which is then fed back to the routines */
                   17386: /* that generate postscript in a run-length-encoded form. */
                   17387: /* Ideally it should just convert the original run-length */
                   17388: /* encoding directly, but the REAL bottleneck is the */
                   17389: /* PostScript printer, of course.  Printing an 800 by 800 */
                   17390: /* pixel image takes 5 minutes. */
                   17391: 
                   17392: #include <stdio.h>
                   17393: #include <math.h>
                   17394: #include <string.h>
                   17395: #include "CPU.h"
                   17396: #include "boole.h"
                   17397: #include "limits.h"     /* numeric extreme values */
                   17398: #include "Units.h"
                   17399: #include "Coord.h"
                   17400: #include "pic.h"
                   17401: 
                   17402: FILE *Fp, *tmpfile();
                   17403: int Raswidth;
                   17404: int Raslength;
                   17405: int Rasbytes;  /* bytes per row */
                   17406: int Inv = 0;
                   17407: int Aspect = 1;                /* if non-zero, retain original aspect ratio */
                   17408: int Land = 0;          /* if non-zero, print in landscape mode */
                   17409: char Revbyte[256];
                   17410: /*  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */
                   17411: char Revnib[16] = {
                   17412:     0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
                   17413:     };
                   17414:  
                   17415: void
                   17416: POST_start(h)
                   17417: PIC_hdr *h;
                   17418: {
                   17419:        int n, v;
                   17420: 
                   17421:        /* build a table of reversed bytes */
                   17422:        for ( n=0; n<256; n++ )
                   17423:                Revbyte[n] = Revnib[(n>>4)&0xf] | Revnib[n&0xf]<<4;
                   17424: 
                   17425:        h->bpl = (h->bpl+7)/8;
                   17426:        Rasbytes = h->bpl;
                   17427:        Raslength = h->bpl * h->bx.b.y;
                   17428:        Raswidth = h->bx.b.x;
                   17429:        postmain(1,NULL,Raswidth,h->bx.b.y);
                   17430: #if CPU==SUN
                   17431:        Fp = tmpfile();
                   17432: #else
                   17433:        Fp = fopen("tmp.postlib.0","rw");
                   17434: #endif
                   17435: }
                   17436: 
                   17437: void
                   17438: POST_end()
                   17439: {
                   17440:        int c;
                   17441:        rewind(Fp);
                   17442:        (VOID) Encode(Raslength, Inv);
                   17443:        PrintPostScriptClosing();
                   17444:        fclose(Fp);
                   17445: }
                   17446: 
                   17447: /* write a full line of picture data, returning status:  1 OK, 0 EOF, -1 ERR */
                   17448: int POST_wline(h,line)
                   17449:     PIC_hdr *h;
                   17450:     unsigned char *line;
                   17451: {   int stat;
                   17452:         if( (stat=fwrite(line,1,h->bpl,Fp)) == h->bpl) {
                   17453:                 h->seek += h->bpl;
                   17454:                 h->cy++;
                   17455:                 return(1);
                   17456:                 }
                   17457:         else { /* ERR */
                   17458:                 err("write to fd%d stat%d",fileno(h->fp),stat);
                   17459:                 if((stat>=0)&&(stat<h->bpl)) return(0 /*EOF*/);
                   17460:                 else return(-1);
                   17461:                 };
                   17462:         }
                   17463: 
                   17464: /******************************************************************************
                   17465: *                                                                            *
                   17466: *      File:         sun2ps.c                                                *
                   17467: *      Author:       Glenn Boysko                                            *
                   17468: *      Organization: Case Western Reserve University                         *
                   17469: *      EMail:        {decvax, sun}!mandrill!boysko                           *
                   17470: *                    [email protected]                                *
                   17471: *      Created:      Wed Mar 23 9:25pm                                       *
                   17472: *      Contents:     Sun Rasterfile to PostScript image (using a run-length  *
                   17473: *                      encoding scheme.)                                     *
                   17474: *                                                                            *
                   17475: *      (Adapted from "postimage" filter by J. R. Bammi.)                     *
                   17476: *                                                                            *
                   17477: *      @(#)sun2ps.c    1.8
                   17478: ******************************************************************************/
                   17479: 
                   17480: /*
                   17481:  * Usage:
                   17482:  *  sun2ps [-s sizex sizey] [-t transx transy] [-r rot] [-l] [-i] [-a] file ...
                   17483:  *
                   17484:  *     -s sizex sizey   = size of postscript image - default 7.5 x 10 inches.
                   17485:  *     -t transx transy = translate image - default 0.5 0.5 inches
                   17486:  *     -r rotate        = rotate image     - default 0 degress
                   17487:  *      -l              = landscape (overrides *all* settings.) 
                   17488:  *     -i               = inverse image - default no inverse 
                   17489:  *                             (Inverse enabled implies white on black.)
                   17490:  *     -a               = maintain correct aspect ratio - default none.
                   17491:  *
                   17492:  */
                   17493: 
                   17494: /* Sun standard raster file format (as obtained by screendump(1)).
                   17495:  *
                   17496:  * Header      (8 16-bit quantities)
                   17497:  * Color Map
                   17498:  * Image
                   17499:  *
                   17500:  */
                   17501: 
                   17502: /* Header Format:
                   17503:  * 
                   17504:  * ras_magic           (int)   Raster Magic number 0x59a66a95
                   17505:  * ras_width           (int)   Width of image in pixels.
                   17506:  * ras_height          (int)   Height of image in pixels.
                   17507:  * ras_depth           (int)   Bits per pixel. Either 1 or 8 bits.
                   17508:  * ras_length          (int)   Length of image in bytes.
                   17509:  * ras_type            (int)   Type of file. Assumed to be RT_STANDARD (1) if
                   17510:  *                             produced by a screendump command.
                   17511:  * ras_maptype         (int)   Type of color map. 
                   17512:  * ras_maplength       (int)   Length of color map in bytes.
                   17513:  *
                   17514:  */
                   17515: 
                   17516: /* Ras_maplength bytes of Color map data. */
                   17517: 
                   17518: /* Ras_length bytes of Image data. */
                   17519: 
                   17520: /* Buffer and Input Modes... */
                   17521: #define LITERAL        0
                   17522: #define COPY   1
                   17523: #define IGNORE 2
                   17524: 
                   17525: /* Transmission Variables. */
                   17526: int BufCount;
                   17527: 
                   17528: unsigned char Buffer[128],
                   17529:              CurrByte,
                   17530:              NextByte,
                   17531:              *BufferP = Buffer;
                   17532: 
                   17533: /* Diagnostic Variables. */
                   17534: int    DiagNLongRuns = 0,
                   17535:        DiagMaxRunLength = 0,
                   17536:        DiagNumRuns = 0;
                   17537: double DiagSumRunLength = 0;
                   17538: 
                   17539: postmain(argc,argv,width,height)
                   17540: int argc;
                   17541: char **argv;
                   17542: int width, height;
                   17543: {
                   17544:      char      *filename;
                   17545:      double    sizex, sizey, transx, transy, rotate;
                   17546: 
                   17547:      extern double atof();
                   17548:      
                   17549:      filename = "STDIN";
                   17550:      sizex = 7.5;
                   17551:      sizey = 10.0;
                   17552:      transx = transy = 0.5;
                   17553:      rotate = 0.0;
                   17554:      
                   17555:      while(--argc > 0)
                   17556:      {
                   17557:          ++argv;
                   17558:          if((*argv)[0] == '-')
                   17559:          {
                   17560:               switch((*argv)[1])
                   17561:               {
                   17562:                 case 'l':
                   17563:                 case 'L':
                   17564:                    Land = 1;
                   17565:                    break;
                   17566:                    
                   17567:                 case 's':
                   17568:                 case 'S':
                   17569:                    sizex = atof(*++argv);
                   17570:                    sizey = atof(*++argv);
                   17571:                    argc -= 2;
                   17572:                    break;
                   17573:                    
                   17574:                 case 't':
                   17575:                 case 'T':
                   17576:                    transx = atof(*++argv);
                   17577:                    transy = atof(*++argv);
                   17578:                    argc -= 2;
                   17579:                    break;
                   17580:                    
                   17581:                 case 'r':
                   17582:                 case 'R':
                   17583:                    rotate = atof(*++argv);
                   17584:                    argc--;
                   17585:                    break;
                   17586:                    
                   17587:                 case 'I':
                   17588:                 case 'i':
                   17589:                    Inv = 1;
                   17590:                    break;
                   17591:                    
                   17592:                 case 'A':
                   17593:                 case 'a':
                   17594:                    Aspect = 1;
                   17595:                    break;
                   17596:                    
                   17597:                 default:
                   17598:                    fprintf(stderr,"Illegal switch %c - ignored\n",
                   17599:                            (*argv)[1]);
                   17600:               }
                   17601:          }
                   17602:      }
                   17603:      if (Land)
                   17604:      {
                   17605:          transx = 8.0;
                   17606:          transy = 0.5;
                   17607:          sizex  = 10.0;
                   17608:          sizey  = 7.5;
                   17609:          rotate = 90.0;
                   17610:      }
                   17611:        if (Aspect) {
                   17612:                if ((sizex / width) < (sizey / height)) {
                   17613:                        sizey = sizex * (height * 1.0 / width);
                   17614:                }
                   17615:                else {
                   17616:                        sizex = sizey * (width * 1.0 / height);
                   17617:                }
                   17618:        }
                   17619:        PrintPostScriptRoutines(height, width, 1 /*depth*/ ,
                   17620:                             transx, transy, sizex, sizey, rotate);
                   17621: }
                   17622: 
                   17623: /******************************************************************************
                   17624: *      I/O Routines.                                                         *
                   17625: ******************************************************************************/
                   17626: int
                   17627: gb()           /* Get a byte from Fp. */
                   17628: {
                   17629:      int byte;
                   17630:      
                   17631:      if (!feof(Fp))
                   17632:          byte = getc(Fp);
                   17633:      else
                   17634:          Error("Premature EOF.\n");
                   17635:      if (ferror(Fp))
                   17636:          Error("I/O Error.\n");
                   17637:      return(Revbyte[byte]);
                   17638: }
                   17639: 
                   17640: SendHex(Byte)          /* Send a Hex char to Stdout. */
                   17641: unsigned char Byte;
                   17642: {
                   17643:      static int LineCount = 0;
                   17644: 
                   17645:      printf("%02x",  0xff & Byte);
                   17646:      if (++LineCount == Rasbytes)
                   17647:      {
                   17648:          putchar('\n');
                   17649:          LineCount = 0;
                   17650:      }
                   17651: }
                   17652:      
                   17653: int
                   17654: SendBuffer(Inv)                /* Send a buffer to Stdout. Return BytesSent. */
                   17655: int Inv;
                   17656: {
                   17657:      int i, BytesSent;
                   17658:      
                   17659:      if (BufferMode() == LITERAL)
                   17660:      {
                   17661:          SendHex( (unsigned char) 0xff & BufCount );
                   17662:          for (i = 0; i < BufCount+1; i++)
                   17663:          {
                   17664:               SendHex( (Inv) ? Buffer[i] : ~Buffer[i]);
                   17665:          }
                   17666:          BytesSent = BufCount+2;
                   17667:      }
                   17668:      else if (BufferMode() == COPY)
                   17669:      {
                   17670:          SendHex( (unsigned char) 0xff & (0x100 + BufCount) );
                   17671:          SendHex( (Inv) ? Buffer[0] : ~Buffer[0]);
                   17672:          BytesSent = 2;
                   17673:          DiagRecLRun(mag(BufCount)+1);
                   17674:      }
                   17675:      return(BytesSent);
                   17676: }
                   17677: 
                   17678: /******************************************************************************
                   17679: *      Utility Routines.                                                     *
                   17680: ******************************************************************************/
                   17681: int
                   17682: mag(Byte)      /* Magitude of a signed char. */
                   17683: int Byte;
                   17684: {
                   17685:      if (Byte & 0x80)
                   17686:      {
                   17687:          /* Signed */
                   17688:          Byte = ~(--Byte);
                   17689:      }
                   17690:      return( 0xff & Byte );
                   17691: }
                   17692:          
                   17693: /******************************************************************************
                   17694: *      Buffer Management Routines.                                           *
                   17695: ******************************************************************************/
                   17696: int
                   17697: InputMode()
                   17698: {
                   17699:      if (CurrByte == NextByte)
                   17700:          return(COPY);
                   17701:      return(LITERAL);
                   17702: }
                   17703: 
                   17704: int
                   17705: BufferMode()
                   17706: {
                   17707:      if (BufCount >= 0 && BufCount <= 127)
                   17708:          return(LITERAL);
                   17709:      else if (BufCount >= -127 && BufCount <= -1)
                   17710:          return(COPY);
                   17711:      return(IGNORE);
                   17712: }
                   17713: 
                   17714: InitLitMode(NBytes, Inv)
                   17715: int *NBytes, Inv;
                   17716: {
                   17717:      BufferP    = Buffer;
                   17718:      BufCount   = -1;
                   17719:      ContLitMode(NBytes, Inv);
                   17720: }
                   17721: 
                   17722: ContLitMode(NBytes, Inv)
                   17723: int *NBytes, Inv;
                   17724: {
                   17725:      if (BufCount == 127)
                   17726:      {
                   17727:          SendBuffer(Inv);
                   17728:          BufferP  = Buffer;
                   17729:          BufCount = -1;
                   17730:      }
                   17731:      *BufferP++ = CurrByte;
                   17732:      BufCount++;
                   17733:      CurrByte   = NextByte;
                   17734:      NextByte   = (unsigned char) gb();
                   17735:      (*NBytes)--;
                   17736: }
                   17737:      
                   17738: InitCopyMode(NBytes, Inv)
                   17739: int *NBytes, Inv;
                   17740: {
                   17741:      BufferP    = Buffer;
                   17742:      *BufferP++ = CurrByte;
                   17743:      BufCount   = -1;
                   17744:      CurrByte   = (unsigned char) gb();
                   17745:      NextByte   = (unsigned char) gb();
                   17746:      *NBytes   -= 2;
                   17747: }
                   17748: 
                   17749: ContCopyMode(NBytes, Inv)
                   17750: int *NBytes, Inv;
                   17751: {
                   17752:      if (BufCount == -127)
                   17753:      {
                   17754:          SendBuffer(Inv);
                   17755:          InitCopyMode(NBytes, Inv);
                   17756:          DiagNLongRuns++;
                   17757:      }
                   17758:      BufCount--;
                   17759:      CurrByte   = NextByte;
                   17760:      NextByte   = gb();
                   17761:      (*NBytes)--;
                   17762: }
                   17763: 
                   17764: /******************************************************************************
                   17765: *      Encoding Algorithm.                                                   *
                   17766: ******************************************************************************/
                   17767: int
                   17768: Encode(NBytes, Inv)
                   17769: int NBytes, Inv;
                   17770: {
                   17771:      int BytesSent = 0;
                   17772:      
                   17773:      /* Initialize Buffer, BufCount, NextByte, CurrByte */
                   17774:      CurrByte = (unsigned char) gb();
                   17775:      NextByte = (unsigned char) gb();
                   17776:      if (InputMode() == LITERAL)
                   17777:      {
                   17778:          InitLitMode(&NBytes, Inv);
                   17779:      }
                   17780:      else
                   17781:      {
                   17782:          InitCopyMode(&NBytes, Inv);
                   17783:      }
                   17784:      while (NBytes > 3)
                   17785:      {
                   17786:          switch(BufferMode())
                   17787:          {
                   17788:            case LITERAL:
                   17789:               if (InputMode() == COPY)
                   17790:               {
                   17791:                    BytesSent += SendBuffer(Inv);
                   17792:                    InitCopyMode(&NBytes, Inv);
                   17793:               }
                   17794:               else
                   17795:               {
                   17796:                    ContLitMode(&NBytes, Inv);
                   17797:               }
                   17798:               break;
                   17799:            case COPY:
                   17800:               if (CurrByte == Buffer[0])
                   17801:               {
                   17802:                    ContCopyMode(&NBytes, Inv);
                   17803:               }
                   17804:               else
                   17805:               {
                   17806:                    BytesSent += SendBuffer(Inv);
                   17807:                    if (InputMode() == COPY)
                   17808:                    {
                   17809:                         InitCopyMode(&NBytes, Inv);
                   17810:                    }
                   17811:                    else
                   17812:                    {
                   17813:                         InitLitMode(&NBytes, Inv);
                   17814:                    }
                   17815:               }
                   17816:               break;
                   17817:            default:
                   17818:               Error("Bad Buffer Mode... Sorry\n");
                   17819:               break;
                   17820:          }
                   17821:      }
                   17822:      BytesSent += SendBuffer(Inv);
                   17823:      /* Send out rem'g 2-3 bytes in LITERAL mode. */
                   17824:      Buffer[0] = CurrByte;
                   17825:      Buffer[1] = NextByte;
                   17826:      if (NBytes == 3)
                   17827:          Buffer[2] = gb();
                   17828:      BufCount = NBytes-1;
                   17829:      BytesSent += SendBuffer(Inv);
                   17830:      return(BytesSent);
                   17831: }
                   17832: 
                   17833: /******************************************************************************
                   17834: *      Diagnostic Routines.                                                  *
                   17835: ******************************************************************************/
                   17836: DiagRecLRun(Rlength)
                   17837: int Rlength;
                   17838: {
                   17839: #ifdef DIAGS
                   17840:      if (Rlength > DiagMaxRunLength)
                   17841:          DiagMaxRunLength = Rlength;
                   17842:      DiagSumRunLength += Rlength;
                   17843:      DiagNumRuns++;
                   17844: #endif
                   17845: }
                   17846: 
                   17847: Diags()
                   17848: {
                   17849: #ifdef DIAGS
                   17850:      fprintf(stderr, "Longest Run (<= 128) = %d\n", DiagMaxRunLength);
                   17851:      fprintf(stderr, "Number of Runs over 128 = %d\n", DiagNLongRuns);
                   17852:      fprintf(stderr, "Average Run Length of %d. (%d Runs)\n",
                   17853:             (int) DiagSumRunLength / DiagNumRuns, DiagNumRuns);
                   17854: #endif
                   17855: }
                   17856: 
                   17857: /******************************************************************************
                   17858: *      PostScript Output Routines.                                           *
                   17859: ******************************************************************************/
                   17860: PrintPostScriptRoutines(ras_h, ras_w, ras_d, tx, ty, sx, sy, rot)
                   17861: int ras_h, ras_w, ras_d;
                   17862: double tx, ty, sx, sy, rot;
                   17863: {
                   17864:      printf("%%!\n/inch {72 mul} def\n");
                   17865:      printf("/bpp %d def\n", ras_d);
                   17866:      printf("/scanlines %d def\n", ras_h);
                   17867:      printf("/scansize %d def\n", ras_w);
                   17868:      printf("/bitmapx\n{");
                   17869:      printf(" %d %d %d [%d 0 0 %d 0 %d] ", ras_w, ras_h, ras_d, ras_w, 
                   17870:            -ras_h, ras_h);
                   17871:      printf("{currentfile readrlehexstring pop } image\n} def\n");
                   17872:      printf("gsave\n");
                   17873:      printf("%f inch %f inch translate\n",tx, ty);
                   17874:      printf("%f rotate\n", rot );
                   17875:      printf("%f inch %f inch scale\n", sx, sy);
                   17876:      printf("/readrlehexstring\t%% rle_file => decoded_string boolean\n");
                   17877:      printf("{\n\t/fileptr exch def\n\tfileptr 1 string readhexstring {");
                   17878:      printf("\n\t\t0 get dup 128 and 0 eq\n");
                   17879:      printf("\t\t{ 1 add /Buffer exch string def\n");
                   17880:      printf("\t\t\tfileptr Buffer readhexstring\n\t\t}\n\t\t{");
                   17881:      printf(" 256 exch sub /BufCount exch def\n");
                   17882:      printf("\t\t\t/Buffer BufCount 1 add string def\n");
                   17883:      printf("\t\t\t/RunInt fileptr 1 string readhexstring");
                   17884:      printf(" pop 0 get def\n");
                   17885:      printf("\t\t\t0 1 BufCount { RunInt Buffer 3 1 roll put } for\n");
                   17886:      printf("\t\t\tBuffer true\n\t\t} ifelse\n\t}\n\t{ false } ifelse\n");
                   17887:      printf("} def\n");
                   17888:      printf("/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f inch 0", sx);
                   17889:      printf(" lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n",
                   17890:            sx, sy, sy);
                   17891:      printf("\tclosepath\n} def\nclipathx clip\n");
                   17892:      printf("bitmapx\n");
                   17893: }
                   17894: 
                   17895: PrintPostScriptClosing()
                   17896: {     
                   17897:      printf("\ngrestore\n");
                   17898:      printf("showpage\n");
                   17899: }
                   17900: 
                   17901: /******************************************************************************
                   17902: *      Error Routine.                                                        *
                   17903: ******************************************************************************/
                   17904: Error(S1, S2, S3)
                   17905: char *S1, *S2, *S3;
                   17906: {
                   17907:      fprintf(stderr, S1, S2, S3);
                   17908:      exit(-1);
                   17909: }
                   17910: 0707070035351136011006640007620000050000010264130476773367300001200000005002rastlib.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   17911: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   17912: /* The copyright notice does not imply actual or intended publication. */
                   17913: /* AUTHORS:                                            */
                   17914: /*     T. Thompson - ATT-BL HO - first version         */
                   17915: /* Routines for generating PostScript from RLE. */
                   17916: /* The routines at the bottom of this file, which */
                   17917: /* do the actual conversion to postscript, were */
                   17918: /* take from 'sun2ps'.  The original header */
                   17919: /* giving credit to its authors is there. */
                   17920: 
                   17921: /* The 'binary' version of the output is collected in a */
                   17922: /* temporary file, which is then fed back to the routines */
                   17923: /* that generate postscript in a run-length-encoded form. */
                   17924: /* Ideally it should just convert the original run-length */
                   17925: /* encoding directly, but this is just a hack.  The REAL */
                   17926: /* bottleneck is the PostScript printer, of course.  */
                   17927: /* Printing an 800 by 800 pixel image takes 5 minutes. */
                   17928: 
                   17929: #include <stdio.h>
                   17930: #include <math.h>
                   17931: #include <string.h>
                   17932: #include "CPU.h"
                   17933: #include "boole.h"
                   17934: #include "limits.h"     /* numeric extreme values */
                   17935: #include "Units.h"
                   17936: #include "Coord.h"
                   17937: #include "pic.h"
                   17938: #include <sys/types.h>
                   17939: #include <suntool/sunview.h>
                   17940: #include <pixrect/pixrect.h>
                   17941: #include <pixrect/pr_io.h>
                   17942: 
                   17943: int Raswidth;
                   17944: int Raslength;
                   17945: extern char Revbyte[256];
                   17946: extern char Revnib[16];
                   17947: 
                   17948: static FILE *fout;
                   17949:  
                   17950: void
                   17951: RAST_start(h)
                   17952: PIC_hdr *h;
                   17953: {
                   17954:        int n, v;
                   17955:        struct rasterfile rh;
                   17956: 
                   17957:        /* build a table of reversed bytes */
                   17958:        for ( n=0; n<256; n++ )
                   17959:                Revbyte[n] = Revnib[(n>>4)&0xf] | Revnib[n&0xf]<<4;
                   17960: 
                   17961:        fout = h->fp;
                   17962:        h->bpl = (h->bpl+7)/8;
                   17963:        Raslength = h->bpl * h->bx.b.y;
                   17964:        Raswidth = h->bx.b.x;
                   17965: 
                   17966:        rh.ras_magic = RAS_MAGIC;
                   17967:        rh.ras_width = h->bx.b.x;
                   17968:        rh.ras_height = h->bx.b.y;
                   17969:        rh.ras_depth = 1;
                   17970:        rh.ras_length = Raslength;
                   17971:        rh.ras_type = RT_STANDARD;
                   17972:        rh.ras_maptype = RMT_NONE;
                   17973:        rh.ras_maplength = 0;
                   17974:        pr_dump_header(fout,&rh,(colormap_t*)0);
                   17975: }
                   17976: 
                   17977: void
                   17978: RAST_end()
                   17979: {
                   17980: }
                   17981: 
                   17982: /* write a full line of picture data, returning status:  1 OK, 0 EOF,
                   17983: -1 ERR */
                   17984: int RAST_wline(h,line)
                   17985:     PIC_hdr *h;
                   17986:     unsigned char *line;
                   17987: {   int stat;
                   17988:        int n;
                   17989: 
                   17990:        for ( n=h->bpl; n>0; n-- ) {
                   17991:                if ( putc(Revbyte[*line++],fout) == EOF )
                   17992:                        break;
                   17993:        }
                   17994:        if ( n == 0 ) {
                   17995:                 h->seek += h->bpl;
                   17996:                 h->cy++;
                   17997:                 return(1);
                   17998:                 }
                   17999:         else { /* ERR */
                   18000:                 err("write to fd%d stat%d",fileno(h->fp),stat);
                   18001:                 if((stat>=0)&&(stat<h->bpl)) return(0 /*EOF*/);
                   18002:                 else return(-1);
                   18003:                 };
                   18004:         }
                   18005: 0707070035351135651006640007620000050000010264150476773367300000600000003030ric.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   18006: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   18007: /* The copyright notice does not imply actual or intended publication. */
                   18008: /* AUTHORS:                                            */
                   18009: /*     H. S. Baird - ATT-BL MH - first versions        */
                   18010: /* ric.h -  Ricoh IS-30 scanner constants, typedefs, function declarations
                   18011:    The scanner program `rscan' creates a file (typically >1Mbyte).
                   18012:    It has an ascii header, terminated by \n\n -- see RIC_hdr for its data fields.
                   18013:    The rest is binary scanner data. Each `RIC_hdr.bpl' bytes holds one scan-line's
                   18014:    pixels, 1 bit/pixel.  A `1' bit means black.  The order of the bytes in a line
                   18015:    is left-to-right across the page.  The low-order bit in a byte is the left-most.
                   18016:    Conventionally, X-coordinates start at 0, at the left of the page, and
                   18017:    increase to the right.  Y-coordinates start at 0 at the top of the page,
                   18018:    and increase down.
                   18019: 
                   18020:    REQUIRES:  prior #include "Coord.h"
                   18021:    */
                   18022: 
                   18023: typedef struct {       /* Scanner file header */
                   18024:        short res_x,res_y;  /* resolution in pixels/inch (x,y may differ) */
                   18025:        short bpl;      /* bytes per scan line */
                   18026:        Bbx bx;         /* bounding box (pixel indices 0,1,...) */
                   18027:        } RIC_hdr;
                   18028: 
                   18029: /* these routines are found in /usr/hsb/ricoh/riclib.c */
                   18030: int RIC_get_hdr();     /* args: fd, (RIC_hdr *); returns: 1==OK, 0==EOF, -1=ERR */
                   18031: int RIC_line();                /* arg: (char **); returns: 1==OK, 0==EOF, -1==ERR */
                   18032: RIC_skip();            /* arg: int no. lines to skip */
                   18033: char *S_hdr_toa();     /* RIC_hdr in printable-string form */
                   18034: 
                   18035: 0707070035351135321006640007620000050000010264160476773367300001100000011466riclib.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   18036: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   18037: /* The copyright notice does not imply actual or intended publication. */
                   18038: /* AUTHORS:                                            */
                   18039: /*     H. S. Baird - ATT-BL MH - first versions        */
                   18040: /* riclib.c - Ricoh scanner-file public functions:
                   18041: 
                   18042: RIC_* functions use system I/O, for speed...
                   18043:    int RIC_get_hdr(fd,RIC_hdr *) - get scanner-file header
                   18044:    int RIC_line(char **)       - read one line of scanner data
                   18045:        err_RIC_Line(char *,RIC_hdr) - print on stderr
                   18046:    int RIC_oline(char **)      - write one line of scanner data
                   18047:    char *RIC_hdr_toa() - RIC_hdr to ascii printable string
                   18048:    */
                   18049: 
                   18050: #include <stdio.h>
                   18051: #include <math.h>
                   18052: #include <string.h>
                   18053: #include "CPU.h"
                   18054: #include "stdocr.h"
                   18055: 
                   18056: #define RIC_debug 0
                   18057: 
                   18058: /* treated as local static: */
                   18059: int RIC_fd;            /* file descr. */
                   18060: int RIC_bpl;           /* bytes per line */
                   18061: char *RIC_bf = NULL;   /* (malloc space *) holds one line of scanner data */
                   18062: 
                   18063: /* system I/O variation on fgets(3), except it replaces \n with \0,
                   18064:    and returns the number of chars read (including \0) */
                   18065: int RIC_fgets(bf,max,fd)
                   18066:        char *bf;
                   18067:        int max;
                   18068:        int fd;
                   18069: {   char *cp;
                   18070:     int stat,mny;
                   18071:        cp=bf; mny=0;
                   18072:        while(((stat=read(fd,cp,1))==1)&&(++mny<max)&&((*cp)!='\n')) cp++;
                   18073:        if(stat!=1) return(stat);
                   18074:        else if(mny>=max) return(-1);
                   18075:        *cp='\0';
                   18076:        return(mny);
                   18077:        }
                   18078: 
                   18079: /* read header from scanner file, return status:  1 OK, 0 EOF, -1 error */
                   18080: int RIC_get_hdr( fd, hp )
                   18081:        int fd;         /* should have been open'ed earlier */
                   18082:        RIC_hdr *hp;
                   18083: #define HL_MAX 80
                   18084: #define HTERM "=,      \n"     /* terminations for header words: "=,<sp><tab>" */
                   18085: {   char *cp,*parm,hline[HL_MAX];
                   18086:     int status,nrd;
                   18087:        RIC_fd = fd;
                   18088:        if((status=RIC_fgets(hline,HL_MAX,RIC_fd))<=0) return(status);
                   18089:        while(strlen(hline)>1) {
                   18090:                if(RIC_debug) err("hline \"%s\"",hline);
                   18091:                parm=strtok(hline,HTERM);
                   18092:                if(parm!=NULL&&strcmp(parm,"TYPE")==0) {
                   18093:                        if((parm=strtok(0,HTERM))!=NULL
                   18094:                                &&strcmp(parm,"binary")==0) ;
                   18095:                        else return(-1);
                   18096:                        }
                   18097:                else if(parm!=NULL&&strcmp(parm,"WINDOW")==0) {
                   18098:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.a.x=atoi(parm);
                   18099:                        else return(-1);
                   18100:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.a.y=atoi(parm);
                   18101:                        else return(-1);
                   18102:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.b.x=atoi(parm)-1;
                   18103:                        else return(-1);
                   18104:                        hp->bpl=(hp->bx.b.x-hp->bx.a.x+1+7)/8;
                   18105:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.b.y=atoi(parm)-1;
                   18106:                        else return(-1);
                   18107:                        }
                   18108:                else if(parm!=NULL&&strcmp(parm,"RES")==0) {
                   18109:                        if((parm=strtok(0,HTERM))!=NULL) hp->res_x=atoi(parm);
                   18110:                        else return(-1);
                   18111:                        if((parm=strtok(0,HTERM))!=NULL) hp->res_y=atoi(parm);
                   18112:                        else return(-1);
                   18113:                        }
                   18114:                else return(-1);
                   18115:                if((status=RIC_fgets(hline,HL_MAX,RIC_fd))<=0) return(status);
                   18116:                };
                   18117:        RIC_bpl=hp->bpl;
                   18118:        /* allocate one extra byte in scanner buffer as a favor to RLE */
                   18119:        if((RIC_bf = (char *) malloc(RIC_bpl+1))==NULL) {
                   18120:                fprintf(stderr,
                   18121:                        "riclib:  can't alloc RIC_bf (%d bytes) - abort\n",
                   18122:                        RIC_bpl+1);
                   18123:                return(-1);
                   18124:                };
                   18125:        return(1);
                   18126:        }
                   18127: 
                   18128: /* write header to scanner file */
                   18129: RIC_put_hdr( fd, hp )
                   18130:        int fd;         /* should have been open'ed earlier */
                   18131:        RIC_hdr *hp;
                   18132: {   char *cp,*parm,hline[HL_MAX];
                   18133:     int status,nrd;
                   18134:        sprintf(hline,"TYPE=binary\n");
                   18135:        write(fd,hline,strlen(hline));
                   18136:        sprintf(hline,"WINDOW=%d %d %d %d\n",
                   18137:                        hp->bx.a.x,hp->bx.a.y,hp->bpl,hp->bx.b.y+1);
                   18138:        write(fd,hline,strlen(hline));
                   18139:        sprintf(hline,"RES=%d %d\n\n",hp->res_x,hp->res_y);
                   18140:        write(fd,hline,strlen(hline));
                   18141:        }
                   18142: 
                   18143: err_RIC_line(sl,shdr)
                   18144:        char *sl;
                   18145:        RIC_hdr shdr;
                   18146: #define BPL 20 /* bytes to display per line */
                   18147: {   char *cp,*ep;
                   18148:     int bpl;           /* bytes per display line */
                   18149:        bpl=0;
                   18150:        for(cp=sl,ep=sl+shdr.bpl; cp!=ep; cp++) {
                   18151:                fprintf(stderr,"%o ",0377&(*cp));
                   18152:                if((++bpl)%BPL==0) fprintf(stderr,"\n   ");
                   18153:                };
                   18154:        if((bpl)%BPL!=0)fprintf(stderr,"\n");
                   18155:        }
                   18156: 
                   18157: /* skip `y' lines, starting from current read pointer */
                   18158: RIC_skip(y)
                   18159:        int y;
                   18160: {      lseek(RIC_fd,(long)(y*RIC_bpl),1);
                   18161:        }
                   18162: 
                   18163: /* read next full line of scanner data, return status:  1 OK, 0 EOF, -1 ERR */
                   18164: int RIC_line(lbpp)
                   18165:        char **lbpp;
                   18166: {   int stat;
                   18167:        if( (stat=read(RIC_fd,RIC_bf,RIC_bpl)) == RIC_bpl) {
                   18168:                *lbpp=RIC_bf;
                   18169:                if(RIC_debug) err("read %d bytes from RIC_fd - OK",stat);
                   18170:                return(1);
                   18171:                }
                   18172:        else { /* EOF or ERR */
                   18173:                *lbpp=NULL;
                   18174:                free(RIC_bf);
                   18175:                if(RIC_debug) err("read from RIC_fd stat%d",stat);
                   18176:                if((stat>=0)&&(stat<RIC_bpl)) return(0 /*EOF*/);
                   18177:                else return(-1);
                   18178:                };
                   18179:        }
                   18180: 
                   18181: /* write a full line of scanner data, returning status:  1 OK, 0 EOF, -1 ERR */
                   18182: int RIC_oline(fd,bf)
                   18183:        int fd;
                   18184:        char *bf;
                   18185: {   int stat;
                   18186:        if( (stat=write(fd,bf,RIC_bpl)) == RIC_bpl) {
                   18187:                if(RIC_debug) err("wrote %d bytes to fd%d - OK",stat,fd);
                   18188:                return(1);
                   18189:                }
                   18190:        else { /* ERR */
                   18191:                err("write to fd%d stat%d",fd,stat);
                   18192:                if((stat>=0)&&(stat<RIC_bpl)) return(0 /*EOF*/);
                   18193:                else return(-1);
                   18194:                };
                   18195:        }
                   18196: 
                   18197: char *RIC_hdr_toa(hp)
                   18198:        RIC_hdr *hp;
                   18199: {   static char s[40];
                   18200:        sprintf(s,"{res%d,%d bpl%d bx%s}\n",
                   18201:                hp->res_x,hp->res_y,
                   18202:                hp->bpl,
                   18203:                bbx_toa(&(hp->bx)));
                   18204:        return(s);
                   18205:        }
                   18206: 
                   18207: 0707070035351135311006640007620000050000010264170476773367400000600000007317rle.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   18208: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   18209: /* The copyright notice does not imply actual or intended publication. */
                   18210: /* AUTHORS:                                            */
                   18211: /*     H. S. Baird - ATT-BL MH - first versions        */
                   18212: /* A rle file consists of any number of:
                   18213:        `scan_line's, each of which has the form:
                   18214:                (short) bytes_mny, followed by bytes_mny bytes in the form:
                   18215:                        (packed short) runs_mny
                   18216:                                if >0, then followed by runs_mny runs
                   18217:                                else if ==0, then followed by:
                   18218:                                        (packed short) blank_lines_mny skipped, -1
                   18219:                                        (packed short) runs_mny (>0), then...
                   18220:                                                ...runs_mny runs
                   18221:    A `run' is two (packed short) oxs,oxe which are
                   18222:        both offset counts >=0 from the prior `?x?' (starts at 0 at left margin).
                   18223:        Suppose that xs, xe are the corresponding accumulated pixel indices,
                   18224:        then xs is the pixel index of the first black pixel of the run,
                   18225:        and xe the pixel index of the first white pixel following the run.
                   18226:    A `packed short' is a byte if its value is <128, else two bytes `HIGH' & `LOW'
                   18227:        with the 0200 bit of its HIGH byte set.
                   18228:    */
                   18229: 
                   18230: #define HIGH(A) ((A>>8)&0177)
                   18231: #define LOW(A) (A&0377)
                   18232: 
                   18233: /* run-length-encoding constants, typedefs */
                   18234: 
                   18235: /* The following assumes a worst case page width of 17 inches (Legal page, >ISO A2)
                   18236:    and worst case digitizing resolution of 400 pixels/inch (e.g. CCITT Group 4),
                   18237:    for a maximum of 6800 pixels/line */
                   18238: #define RLE_RUNS 3401  /* maximum no. runs in a line */
                   18239: #define RLE_BYTES 6800 /* maximum no. data bytes in a rle line (enough?) */
                   18240: 
                   18241: typedef struct RLE_Run {
                   18242:        short xs;       /* x-coord of first pixel in run */
                   18243:        short xe;       /* x-coord of last pixel in run (NOT first following) */
                   18244:        } RLE_Run;
                   18245: #define Init_RLE_Run {0,0}
                   18246: 
                   18247: typedef struct DRLE_Run {
                   18248:        short xs;       /* x-coord of first pixel in run */
                   18249:        short xe;       /* x-coord of last pixel in run (NOT first following) */
                   18250:        struct DRLE_Run *next;
                   18251:        } DRLE_Run;
                   18252: 
                   18253: typedef struct RLE_Yrun {
                   18254:        short y,xs,xe;
                   18255:        } RLE_Yrun;
                   18256: #define Init_RLE_Yrun {0,0,0}
                   18257: 
                   18258: typedef struct RLE_Line {
                   18259:        short y;        /* y-coord of line */
                   18260:        short len;      /* length of line in pixels (white+black) */
                   18261:        short runs;     /* no. of runs */
                   18262:        RLE_Run r[RLE_RUNS];
                   18263:        } RLE_Line;
                   18264: #define Init_RLE_Line {0,0,0,Init_RLE_Run}
                   18265: 
                   18266: 
                   18267: typedef struct DRLE_Line {     /* dynamically allocated version */
                   18268:        DRLE_Run *r;            /* first run */
                   18269:        DRLE_Run *lastr;        /* last run */
                   18270:        } DRLE_Line;
                   18271: #define Init_DRLE_Line {0,0}
                   18272: 
                   18273: typedef struct RLE_Lines {
                   18274:        int mny;
                   18275:        RLE_Line *rla;  /* array of RLE_Lines */
                   18276:        } RLE_Lines;
                   18277: #define Init_RLE_Lines {0,NULL}
                   18278: #if MAIN
                   18279: RLE_Lines empty_RLE_Lines = Init_RLE_Lines;
                   18280: #else
                   18281: extern RLE_Lines empty_RLE_Lines;
                   18282: #endif
                   18283: 
                   18284: typedef struct Transform_rlel_arg {
                   18285:        boolean ident;  /* if T, then no change (speed-optimization) */
                   18286:        Bbx tr;         /* trim:  select just this window of input */
                   18287:        Sp off;         /* offset:  translate by off.x,off.y */
                   18288:        Pp scl;         /* scale:  X & Y expansion factors (about 0,0) */
                   18289:        Sp wh;          /* truncate:  exact maximum output width,height */
                   18290:        Radians rot;    /* rotate:  angle (multiple of PI/4) */
                   18291:        boolean rev;    /* reverse:  swap black and white */
                   18292:        int sy;         /* next integer line no. to write */
                   18293:        double dy;      /* next real line no. to write */
                   18294:        } Transform_rlel_arg;
                   18295: #define Init_Transform_rlel_arg {T,Init_Bbx,Init_Zero_Sp,{1.0,1.0},Init_Zero_Sp,0.0,F,0,0.0}
                   18296: #if MAIN
                   18297: Transform_rlel_arg empty_Transform_rlel_arg = Init_Transform_rlel_arg;
                   18298: #else
                   18299: extern Transform_rlel_arg empty_Transform_rlel_arg;
                   18300: #endif
                   18301: 
                   18302: #ifdef MAIN
                   18303: /* these routines are found in rlelib.c */
                   18304: 
                   18305: boolean RLE_open();    /* arg: (FILE *) */
                   18306: RLE_Line *RLE_line();  /* args: l,r - left,right interval */
                   18307: RLE_Line *RLE_get_Line();  /*  args: l,r - left,right interval */
                   18308: int RLE_run();         /* arg: (RLE_Run *) */
                   18309: fwrb_rlines();         /* args: (FILE *), (RLE_Lines *) */
                   18310: insert_rlel();
                   18311: #endif
                   18312: 0707070035351135301006640007620000050000010264210476773367400001100000047356rlelib.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   18313: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   18314: /* The copyright notice does not imply actual or intended publication. */
                   18315: /* AUTHORS:                                            */
                   18316: /*     T. Pavlidis - ATT-BL MH - first versions        */
                   18317: /*     H. S. Baird - ATT-BL MH - first versions        */
                   18318: 
                   18319: /* rlelib.c - subroutines for writing/reading run-length-encoded format files.
                   18320:    BUG:  Uses system I/O for speed, but sacrifices machine-independence:
                   18321:    should use fioi.h macroes instead.
                   18322:    See rle.h for summary of rle file and format of public functions.
                   18323:    Writing a rle file:
                   18324:        fd=creat()
                   18325:        RLE_put_hdr(fd,hp)      - once: allocate buffers, write header
                   18326:        RLE_put_Line(fd,lp)     - repeatedly
                   18327:        RLE_close(fd)           - once: flush and deallocate buffers
                   18328:    Reading a rle file:
                   18329:        fd=open()
                   18330:        RLE_open(fd,hp)         - once: read header, 1st line into buffer
                   18331:        RLE_get_Line(l,r)       - repeatedly (on EOF, deallocates buffer)
                   18332:    The user can read line-at-a-time or run-at-a-time, but should not intermix them:
                   18333:         line-at-a-time:
                   18334:             (RLE_Line *) RLE_get_Line(l,r) - return ptr to next line with some run
                   18335:                        in the interval [l,r];
                   18336:                        read from opened file (NULL if EOF, abort on error)
                   18337:                        allocates large buffer and frees it when done
                   18338:         run-at-a-time:
                   18339:            int RLE_get_Run(&R) - read next run into (RLE_Run) R
                   18340:                        returns the line number (-1 for EOF, abort on ERROR)
                   18341:                        does not allocate large buffer;
                   18342:                        if only a few runs will be used, can be faster
                   18343:  */
                   18344: 
                   18345: #include <stdio.h>
                   18346: #define LIBC_INCL 1
                   18347: #include "CPU.h"
                   18348: #include "stdocr.h"
                   18349: #include "rle.h"
                   18350: 
                   18351: #define RLE_dbg F
                   18352: #define dbg_rd F
                   18353: #define dbg_wr F
                   18354: 
                   18355: /* Treated as local static: */
                   18356: typedef struct RLE_global {
                   18357:        int fd;                 /* rle file descriptor */
                   18358:        boolean eof;
                   18359:        int cy, cx;             /* current line no., x-coord */
                   18360:        short runs, nrun;       /* no. runs, next run in current line */
                   18361:        RLE_Line *lp;           /* pointer to line (malloc space) */
                   18362:        int bpl;                /* maximum no. bytes in packed rle line */
                   18363:        char *bf;               /* I/O buffer (malloc space) */
                   18364:        int bfsize;             /* size of buffer */
                   18365:        char *cp;               /* cur. ptr, into bf */
                   18366:        } RLE_global;
                   18367: #define Init_RLE_global {0,F,-1,-1,0,0,NULL,0,NULL,0,NULL}
                   18368: RLE_global _RLE = Init_RLE_global;
                   18369: 
                   18370: RLE_put_hdr( fd, rhp, bufn )
                   18371:     int fd;
                   18372:     RIC_hdr *rhp;
                   18373:     int bufn;  /* minimum number of lines to buffer locally */
                   18374: {   char hdr[100];
                   18375:     int stat;
                   18376:        sprintf(hdr,"TYPE=rle\nWINDOW=%d %d %d %d\nRES=%d %d\n\n",
                   18377:                /* use half-open WINDOW convention: l&t closed, r&b open*/
                   18378:                rhp->bx.a.x,rhp->bx.a.y,rhp->bx.b.x+1,rhp->bx.b.y+1,
                   18379:                rhp->res_x,rhp->res_y);
                   18380:        if((stat=write(fd,hdr,strlen(hdr)))!=strlen(hdr)) {
                   18381:                abort("rlelib: can't put hdr, stat %d",stat);
                   18382:                };
                   18383:        _RLE.fd = fd;
                   18384:        _RLE.cy = rhp->bx.a.y-1;
                   18385:        _RLE.bpl = rhp->bx.b.x-rhp->bx.a.x+9;   /* maximum bytes per line */
                   18386:        _RLE.bfsize = bufn*_RLE.bpl;
                   18387:        if((_RLE.bf=(char *)malloc(_RLE.bfsize))==NULL)
                   18388:                abort("can't alloc _RLE.bf[%d]",_RLE.bfsize);
                   18389:        _RLE.cp = _RLE.bf;
                   18390:        }
                   18391: 
                   18392: #define PUT(A,B) { if((A)<128) *(B)++ = (A); \
                   18393:                else { *(B)++ = HIGH(A) | 0200; *(B)++ = LOW(A); } \
                   18394:                }
                   18395: 
                   18396: /* write out a non-blank line of runs */
                   18397: RLE_put_Line(fd,rlp)
                   18398:        int fd;         /* file descr (already open) */
                   18399:        RLE_Line *rlp;
                   18400: {   register char *bp;
                   18401:     short blank_lines_mny;     /* the number of preceding blank lines, minus 1 */
                   18402:     register RLE_Run *rp,*ep;
                   18403:     Scoor xsofar;
                   18404:     short bytes_mny;
                   18405:     int stat;          /* I/O status */
                   18406:        if((_RLE.bfsize-(_RLE.cp-_RLE.bf)) < _RLE.bpl) {
                   18407:                /* not enough room left in buffer for worst-case line */
                   18408:                RLE_flush();
                   18409:                };
                   18410:        /* leave space for (short) bytes_mny count */
                   18411:        bp=_RLE.cp+sizeof(short);  
                   18412:        if((blank_lines_mny=(rlp->y-_RLE.cy-1))>0) /* blank lines were skipped */ {
                   18413:                PUT(0,bp);      /* ``0 runs'' signals blank lines */
                   18414:                PUT(blank_lines_mny,bp);
                   18415:                };
                   18416:        _RLE.cy=rlp->y;
                   18417:        PUT(rlp->runs,bp);
                   18418:        xsofar=0;
                   18419:        for(rp=rlp->r,ep=rp+rlp->runs; rp!=ep; rp++) {
                   18420:                PUT(rp->xs-xsofar,bp);  xsofar = rp->xs;
                   18421:                PUT(rp->xe-xsofar+1,bp);  xsofar = rp->xe+1;
                   18422:                };
                   18423:        /* go back & write no. bytes at top of line */
                   18424:        *((short *) _RLE.cp) = bp-_RLE.cp-sizeof(short);
                   18425:        _RLE.cp = bp;
                   18426:        if(dbg_wr) err("RLE_put_Line y%d nh%d",_RLE.cy,bytes_mny-2);
                   18427:        };
                   18428: 
                   18429: /* write out a set of runs */
                   18430: RLE_put_Lines(fd,rlsp)
                   18431:        int fd;         /* file descr (already open) */
                   18432:        RLE_Lines *rlsp;
                   18433: {   int i;
                   18434:     RLE_Line *rlp;
                   18435:        for(i=0,rlp=rlsp->rla; i<rlsp->mny; i++,rlp++)
                   18436:                RLE_put_Line(fd,rlp);
                   18437:        }
                   18438: 
                   18439: RLE_flush()
                   18440: {   int bytes;
                   18441:     int stat;
                   18442:        if((bytes=(_RLE.cp-_RLE.bf))>0)
                   18443:                if(stat=write(_RLE.fd,_RLE.bf,bytes)!=bytes)
                   18444:                        abort("can't write _RLE.bf[%d], status %d",bytes,stat);
                   18445:        _RLE.cp = _RLE.bf;
                   18446:        }
                   18447: 
                   18448: RLE_close(fd)
                   18449:    int fd;
                   18450: {      RLE_flush();
                   18451:        if(_RLE.bf!=NULL) free(_RLE.bf);
                   18452:        _RLE.bf = _RLE.cp = NULL;
                   18453:        _RLE.bfsize = 0;
                   18454:        }
                   18455: 
                   18456: /* ``open'' RLE_file for reading:
                   18457:    save filedes, read header, and read first line into buffer */
                   18458: boolean RLE_open( fd, hp )
                   18459:        int fd;
                   18460:        RIC_hdr *hp;
                   18461: {      _RLE.fd = fd;
                   18462:        /* read header */
                   18463:        RLE_get_hdr( fd, hp );
                   18464:        if(_RLE.bf!=NULL) free(_RLE.bf);
                   18465:        _RLE.bfsize = _RLE.bpl;
                   18466:        if((_RLE.bf=(char *)malloc(_RLE.bfsize))==NULL)
                   18467:                abort("can't alloc _RLE.bf[%d]",_RLE.bfsize);
                   18468:        /* read first non-blank line */
                   18469:        _RLE.cy = hp->bx.a.y-1;
                   18470:        if (!RLE_rdbf()) return(F);
                   18471:        _RLE.eof = F;
                   18472:        return(T);
                   18473:        }
                   18474: 
                   18475: /* read next short from rle-line buffer, updating arg ptr */
                   18476: short RLE_gshort(p)
                   18477:        char **p;
                   18478: {      register n;
                   18479:        register char *q;
                   18480:        q = *p;
                   18481:        if((*q)&0200) {
                   18482:                n = (((*q & 0177)<<8)&077400) | (*(q+1) & 0377);
                   18483:                (*p)++;
                   18484:                }
                   18485:        else n = *q;
                   18486:        (*p)++;
                   18487:        return(n);
                   18488:        }
                   18489: 
                   18490: /* system I/O variation on fgets(3), except it replaces \n with \0,
                   18491:    and returns the number of chars read (including \0) */
                   18492: int RLE_fgets(bf,max,fd)
                   18493:        char *bf;
                   18494:        int max;
                   18495:        int fd;
                   18496: {   char *cp;
                   18497:     int stat,mny;
                   18498:        cp=bf; mny=0;
                   18499:        while(((stat=read(fd,cp,1))==1)&&(++mny<max)&&((*cp)!='\n')) cp++;
                   18500:        if(stat!=1) return(stat);
                   18501:        else if(mny>=max) return(-1);
                   18502:        *cp='\0';
                   18503:        return(mny);
                   18504:        }
                   18505: 
                   18506: /* read ascii header from rle file, convert to RIC_hdr,
                   18507:    return status:  1 OK, 0 EOF, -1 error */
                   18508: int RLE_get_hdr( fd, hp )
                   18509:        int fd;         /* should have been open'ed earlier */
                   18510:        RIC_hdr *hp;
                   18511: #define HL_MAX 80
                   18512: #define HTERM "=,      \n"     /* terminations for header words: "=,<sp><tab>" */
                   18513: {   char *cp,*parm,hline[HL_MAX];
                   18514:     int status,nrd;
                   18515:        if((status=RLE_fgets(hline,HL_MAX,fd))<=0) return(status);
                   18516:        while(strlen(hline)>1) {
                   18517:                if(RLE_dbg) err("hline \"%s\"",hline);
                   18518:                parm=strtok(hline,HTERM);
                   18519:                if(parm!=NULL&&strcmp(parm,"TYPE")==0) {
                   18520:                        if((parm=strtok(0,HTERM))!=NULL
                   18521:                                &&strcmp(parm,"rle")==0) ;
                   18522:                        else return(-1);
                   18523:                        }
                   18524:                else if(parm!=NULL&&strcmp(parm,"WINDOW")==0) {
                   18525:                        /* assume half-open WINDOW: l&t closed, r&b open */
                   18526:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.a.x=atoi(parm);
                   18527:                        else return(-1);
                   18528:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.a.y=atoi(parm);
                   18529:                        else return(-1);
                   18530:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.b.x=atoi(parm)-1;
                   18531:                        else return(-1);
                   18532:                        if((parm=strtok(0,HTERM))!=NULL) hp->bx.b.y=atoi(parm)-1;
                   18533:                        else return(-1);
                   18534:                        }
                   18535:                else if(parm!=NULL&&strcmp(parm,"RES")==0) {
                   18536:                        if((parm=strtok(0,HTERM))!=NULL) hp->res_x=atoi(parm);
                   18537:                        else return(-1);
                   18538:                        if((parm=strtok(0,HTERM))!=NULL) hp->res_y=atoi(parm);
                   18539:                        else return(-1);
                   18540:                        }
                   18541:                else return(-1);
                   18542:                if((status=RLE_fgets(hline,HL_MAX,fd))<=0) return(status);
                   18543:                };
                   18544:        /* maximum possible no. bytes in a packed rle line */
                   18545:        _RLE.bpl = hp->bpl = hp->bx.b.x-hp->bx.a.x+9;
                   18546:        if(dbg_rd) fprintf(stderr,"rlelib: RLE_get_hdr: %s\n",RIC_hdr_toa(hp));
                   18547:        return(1);
                   18548:        }
                   18549: 
                   18550: /* read the next run into *Rp, and return line number
                   18551:    (-1 for EOF, abort on error) */
                   18552: int RLE_get_Run( Rp )
                   18553:        RLE_Run *Rp;
                   18554: {      if(_RLE.nrun >= _RLE.runs) {    /* no more, try to read next line */
                   18555:                if (!RLE_rdbf()) /* EOF */ return(-1); 
                   18556:                };
                   18557:        /* another run */
                   18558:        Rp->xs = (_RLE.cx += RLE_gshort(&_RLE.cp));
                   18559:        Rp->xe = (_RLE.cx += RLE_gshort(&_RLE.cp)) - 1;
                   18560:        _RLE.nrun++;
                   18561:        return(_RLE.cy);
                   18562:        }
                   18563: 
                   18564: /* Return ptr to the next line with at least one run overlapping the margins
                   18565:    [lm,rm]. The reported runs are not trimmed to fit exactly within margins.
                   18566:    If no more lines, return NULL.  On error, abort */
                   18567: RLE_Line *RLE_get_Line(lm,rm)
                   18568:        int lm, rm;             /* left, right margins */
                   18569: {      register int rr;        /* runs read */
                   18570:        register RLE_Run *rp;   /* write ptr */
                   18571: 
                   18572:        do {    if(_RLE.eof) {
                   18573:                        free(_RLE.lp);  _RLE.lp = NULL;
                   18574:                        free(_RLE.bf);  _RLE.bf = NULL;
                   18575:                        return(NULL);
                   18576:                        };
                   18577:                if(_RLE.lp==NULL) { /* allocate space for RLE_Line */
                   18578:                        _RLE.lp = (RLE_Line *) malloc(sizeof(RLE_Line));
                   18579:                        if(_RLE.lp==NULL) {
                   18580:                                abort("rlelib:  can't malloc RLE_Line (%d bytes)",
                   18581:                                        sizeof(RLE_Line));
                   18582:                                };
                   18583:                        };
                   18584:                _RLE.lp->y = _RLE.cy;
                   18585:                /* guaranteed to be at least one run in line */
                   18586:                rr=0;  rp=_RLE.lp->r;  _RLE.lp->runs=0;
                   18587:                /* skip runs that are outside left margin */
                   18588:                do      RLE_get_Run(rp);
                   18589:                while((rr++ < _RLE.runs) && (rp->xe < lm));
                   18590:                /* accept runs until cross right margin */
                   18591:                while(rp->xs <= rm) {
                   18592:                        _RLE.lp->runs++;        /* count accepted runs */
                   18593:                        if(rr++ >= _RLE.runs) break;
                   18594:                        RLE_get_Run(++rp);
                   18595:                        };
                   18596:                /* look ahead to next line */
                   18597:                if (!RLE_rdbf()) /* EOF */ _RLE.eof=T;
                   18598:                }
                   18599:        while(_RLE.lp->runs==0);        /* as result of margins, some lines may empty */
                   18600:        return(_RLE.lp);
                   18601:        }
                   18602: 
                   18603: /* read next line buffer - return F if EOF, abort on error
                   18604:    sideffects:  sets up _RLE.cp, _RLE.cy, _RLE.cx, _RLE.runs, _RLE.nrun */
                   18605: boolean RLE_rdbf()
                   18606: {   short nh;
                   18607:        if(dbg_rd) err("enter RLE_rdbf");
                   18608:        /* get number of bytes holding RLE of a scan line */
                   18609:        if( read(_RLE.fd,&nh,sizeof(short)) != sizeof(short)) {
                   18610:                return(F); /* normal EOF */
                   18611:                };
                   18612:        if( Readvax )
                   18613:                nh = swapshortin( nh );
                   18614:        if(dbg_rd) err("rlelib: RLE_rdbf: nh %d",nh);
                   18615:        if(nh > _RLE.bpl) {
                   18616:                abort("rlelib: too many bytes in line: %d > %d(_RLE.bpl)",
                   18617:                        nh,_RLE.bpl);
                   18618:                };
                   18619: 
                   18620:        /* get those bytes */
                   18621:        if( read(_RLE.fd,_RLE.bf,nh) != nh) {
                   18622:                abort("rlelib: rle line truncated");
                   18623:                };
                   18624:        if(dbg_rd) {
                   18625:                int bi;
                   18626:                err("rlelib: RLE_rdbf: _RLE.bf[0-%d] octal:",nh-1);
                   18627:                for(bi=0;bi<nh;bi++)
                   18628:                        fprintf(stderr," 0%o",0377&(_RLE.bf[bi]));
                   18629:                fprintf(stderr,"\n");
                   18630:                };
                   18631: 
                   18632:        /*      decode the bytes        */
                   18633:        _RLE.cp = _RLE.bf;
                   18634:        _RLE.runs = RLE_gshort(&_RLE.cp);
                   18635:        if(dbg_rd) err("rlelib: _RLE.runs %d",_RLE.runs);
                   18636:        if(_RLE.runs==0) {      /* blank lines seen */
                   18637:                _RLE.cy += RLE_gshort(&_RLE.cp);
                   18638:                _RLE.runs = RLE_gshort(&_RLE.cp);
                   18639:                if(dbg_rd)
                   18640:                        err("rlelib: _RLE.cy %d _RLE.runs %d",_RLE.cy,_RLE.runs);
                   18641:                };
                   18642:        if(_RLE.runs>RLE_RUNS || _RLE.runs<1) {
                   18643:                abort("rlelib: illegal no. runs %d in line",_RLE.runs);
                   18644:                };
                   18645:        _RLE.cy++;
                   18646:        if(dbg_rd) err("rlelib: RLE_rdbf: _RLE.runs %d _RLE.cy %d",_RLE.runs,_RLE.cy);
                   18647:        _RLE.cx = _RLE.nrun = 0;        /* next run will be first */
                   18648:        if(dbg_rd) err("rlelib: RLE_rdbf: T exit");
                   18649:        return(T);
                   18650:        }
                   18651: 
                   18652: /* brrl - compute a binary raster line from a run-length-encoded scanline.
                   18653:    runa[] is an array of shorts, grouped in pairs (xs,xe) to describe the starting
                   18654:    and ending index (inclusive) of each run of black pixels (1 bits).
                   18655:    xe >= xs > xe.  The runs are in strictly ascending order on xs.
                   18656:    lm & rm are the left and right margin indices of pixels, outside of which the
                   18657:    pixels are forced to be white.  rm >= lm.  The `lm'th pixel is written
                   18658:    into the `olm'th bit of the output raster (olm>=0).
                   18659:    rasp[] is a raser line of chars; on entry, it is assumed to have been zeroed
                   18660:    out.  rasp[0] holds the  leftmost byte in the line and the 001 bit of each
                   18661:    byte is the leftmost bit in that byte.
                   18662:    The user must ensure that rasp[] is at least (rm-lm+olm+9)/8 bytes long.
                   18663:    Returns the number of black pixels in the raster line.
                   18664:    NOTE:  this uses the ``little-endian'' convention, in which the leftmost pixel
                   18665:    in a byte is placed in the least-significant bit (0x01).  See `brrlb()' below
                   18666:    for the alternative ``big-endian'' version.
                   18667:    */
                   18668: int brrl(runs,runa,lm,rm,olm,rasp)
                   18669:     int runs;          /* number of run-segments in runa[] */
                   18670:     short runa[];      /* array of run-segments [xs,xe] (pairs of short) */
                   18671:     int lm,rm;         /* left,right margin bit indices within raster */
                   18672:     int olm;           /* `lm'th input pixel will be written to `olm'th bit */
                   18673:     char unsigned rasp[];      /* binary raster line (zeroed out on entry) */
                   18674: {   int pixels,bi;
                   18675:     RLE_Run r,*rp,*re;
                   18676:        pixels = 0;
                   18677:        re = (rp = (RLE_Run *) runa) + runs;
                   18678:        while(rp<re && rp->xe<lm) rp++;         /* skip runs to the left of 'lm' */
                   18679:        while(rp<re && rp->xs<=rm) {
                   18680:                /* truncate to margins */
                   18681:                if((r.xs = rp->xs)<lm) r.xs = lm;
                   18682:                if((r.xe = rp->xe)>rm) r.xe = rm;
                   18683:                /* shift to output indices */
                   18684:                r.xs += olm-lm;   r.xe += olm-lm;
                   18685:                /** SLOW **/
                   18686:                for(bi=r.xs; bi<=r.xe; bi++) rasp[bi/8] |= (01)<<(bi%8);
                   18687:                pixels += r.xe-r.xs+1;
                   18688:                rp++;
                   18689:                };
                   18690:        return(pixels);
                   18691:        }
                   18692: 
                   18693: /* ``big-endian'' version of brrl:  bits are packed so that the leftmost
                   18694:    pixel is placed in the high-order bit (0x80) of each byte.
                   18695:    */
                   18696: int brrlb(runs,runa,lm,rm,olm,rasp)
                   18697:     int runs;
                   18698:     short runa[];
                   18699:     int lm,rm,olm;
                   18700:     char unsigned rasp[];
                   18701: {   int pixels,bi;
                   18702:     RLE_Run r,*rp,*re;
                   18703:        pixels = 0;
                   18704:        re = (rp = (RLE_Run *) runa) + runs;
                   18705:        while(rp<re && rp->xe<lm) rp++; /* skip runs to the left of 'lm' */
                   18706:        while(rp<re && rp->xs<=rm) {
                   18707:                /* truncate to margins */
                   18708:                if((r.xs = rp->xs)<lm) r.xs = lm;
                   18709:                if((r.xe = rp->xe)>rm) r.xe = rm;
                   18710:                /* shift to output indices */
                   18711:                r.xs += olm-lm;   r.xe += olm-lm;
                   18712:                /** SLOW **/
                   18713:                for(bi=r.xs; bi<=r.xe; bi++) rasp[bi/8] |= (0200)>>(bi%8);
                   18714:                pixels += r.xe-r.xs+1;
                   18715:                rp++;
                   18716:                };
                   18717:        return(pixels);
                   18718:        }
                   18719: 
                   18720: /* crrl - compute a character raster line from a run-length-encoded scanline.
                   18721:    runa[] is an array of shorts, grouped in pairs (xs,xe) to describe the starting
                   18722:    and ending index (inclusive) of each run of black pixels (1 bits): xs<=xe.
                   18723:    The runs are in strictly ascending order on xs.  lm & rm are the left and
                   18724:    right margin indices, outside of which pixels are forced to be white.  rm >= lm.
                   18725:    rasp[] is a raster line, one unsigned char per pixel; rasp[0] holds the
                   18726:    leftmost pixel.  The user must ensure that rasp[] is at least (rm-lm+1)
                   18727:    bytes long.  Black pixels are encoded as 0, white as 255.  Returns the number
                   18728:    of black pixels in the raster line.
                   18729:    */
                   18730: #define WHITE_pel 0377
                   18731: #define BLACK_pel 0000
                   18732: int crrl(runs,runa,lm,rm,rasp)
                   18733:     int runs;          /* number of run-segments in runa[] */
                   18734:     short runa[];      /* array of run-segments [xs,xe] (pairs of short) */
                   18735:     int lm,rm;         /* left,right margin bit indices within raster */
                   18736:     unsigned char rasp[];      /* char raster line */
                   18737: {   int pixels,bi,wid;
                   18738:     RLE_Run r,*rp,*re;
                   18739:     unsigned char *cp,*ep;
                   18740:        wid=rm-lm+1;
                   18741:        memset(rasp,WHITE_pel,wid);
                   18742:        re = (rp = (RLE_Run *) runa) + runs;
                   18743:        while(rp<re&&rp->xe<lm) rp++;   /* skip runs to the left of 'lm' */
                   18744:        if(rp>=re) return(0);
                   18745: 
                   18746:        r = *rp;  r.xs -= lm;  r.xe -= lm;
                   18747:        pixels = 0;
                   18748:        do {    /* truncate left,right margin */
                   18749:                if(r.xs<0) r.xs = 0;
                   18750:                if(r.xe>(wid-1)) r.xe = wid-1;
                   18751:                /* write r into raster line */
                   18752:                pixels += (r.xe-r.xs+1);
                   18753:                for(cp=rasp+r.xs,ep=rasp+r.xe; cp<=ep; cp++) *cp = BLACK_pel;
                   18754:                /* step to next run */
                   18755:                r = *(++rp);  r.xs -= lm;  r.xe -= lm;
                   18756:                }
                   18757:        while(r.xs<=(wid-1)&&rp<re);
                   18758:        return(pixels);
                   18759:        }
                   18760: 
                   18761: /* trcr - threshold & run-length-encode a char raster line.  `rasp' is a raster
                   18762:    line, one unsigned char per pixel: rasp[0] is the leftmost pixel in the line.
                   18763:    Pixels with value < 'thresh' are translated to black, else white.  
                   18764:    Analyzes the line into a series of runs of `1's, placing them into array
                   18765:    `runs'.  Observes margins:  starts at `lm' bit and continues through `rm';
                   18766:    bits outside the margins are assumed 0.   A `run' is two shorts (the starting &
                   18767:    ending indices of the run of `1's, inclusive).  The indices are shifted
                   18768:    so that the `lm'th pixel goes to run index `olm'.  Returns the number of runs.
                   18769:    NOTE:  The user must ensure that: (1) margins fall within `rasp[]';
                   18770:    (2) `runp[]' is big enough to hold the worst-case no. of runs that can result
                   18771:    ((rm-lm+2)/2).  The contents of the raster-line are unmodified.
                   18772:    */
                   18773: int trcr(rasp,lm,rm,olm,thresh,runp)
                   18774:     char unsigned rasp[];      /* binary raster line (with 1 extra byte at end) */
                   18775:     int lm,rm; /* left,right margin indices within raster */
                   18776:     int olm;   /* `lm' pixel goes to `olm' run index */
                   18777:     int thresh;
                   18778:     short runp[];      /* array of run-segments [xs,xe] (pairs of short) */
                   18779: #define dbg_trcr (T)
                   18780: {   unsigned char *cp,*ep;
                   18781:     short x,*xp;
                   18782:     int cv,pv; /* current,prior binary pixel value */
                   18783:        ep=(cp=rasp+lm)+rm;  x=olm;  xp=runp;
                   18784:        pv=0;   /* assume pixels left of 'lm' are 0 */
                   18785:        while (cp<=ep) {
                   18786:                if((*cp)<thresh) {
                   18787:                        /* black pixel */
                   18788:                        cv=1;
                   18789:                        if(pv==0) { *xp = x; xp++; };
                   18790:                        }
                   18791:                else {  /* white pixel */
                   18792:                        cv=0;
                   18793:                        if(pv==1) { *xp = x-1; xp++; };
                   18794:                        };
                   18795:                pv=cv;  x++;
                   18796:                cp++;
                   18797:                };
                   18798:        if(pv==1) { *xp = x-1; xp++; }; /* assume pixels right of 'rm' is 0 */
                   18799:        return((xp-runp)/2);
                   18800:        }
                   18801: 
                   18802: /* Transform a sequence of rle-lines using trimming, offsetting, scaling,
                   18803:    truncation, and reverse-video.  Scaling may lead to interpolation or
                   18804:    decimation of lines, so an input line may be mapped into 0, 1, or more
                   18805:    output lines.
                   18806:    Input lines may be buffered, and there may be latency.  To flush buffers,
                   18807:    this must be called with NULL argument at end of the sequence.  Each output
                   18808:    line will be passed to function `sink()', which returns 1 if OK and 0 to quit.     Quits are passed back immediately with no latency.  Sink's 1st arg RLE_Line
                   18809:    *l is a line of runs in output coordinates, whose `len' is the maximum length
                   18810:    of the line.  l==NULL means end of sequence.
                   18811:    Return 1 if OK, 0 to quit.   A copy of *l is passed to sink().
                   18812:    a->sy is incremented for every line written to the sink, and is attached to
                   18813:    the output lines as *.y.
                   18814:    */
                   18815: int transform_rlel(l,a,sink,sa)
                   18816:     RLE_Line *l;       /* NULL if end of sequence */
                   18817:     Transform_rlel_arg *a;
                   18818:     int (*sink)();     /* takes args:  (RLE_Line *), and int */
                   18819:     VOID *sa;          /* passed to sink() as 2nd arg */
                   18820: {   RLE_Line m,r;
                   18821:     register RLE_Run *rp,*ep,*mp;
                   18822:     RLE_Run mr,mm,rr;
                   18823:     int rm;
                   18824:     int o_a_x,o_b_x;   /* maximum output index */
                   18825:        if(l==NULL) {
                   18826:                sink(NULL,sa);
                   18827:                return(1);
                   18828:                };
                   18829:        m.len = l->len;
                   18830:        m.runs = l->runs;
                   18831:        if(a->ident) {
                   18832:                if(m.runs>0) memcpy(m.r,l->r,2*m.runs*sizeof(short));
                   18833:                m.y = a->sy;
                   18834:                if(sink(&m,sa)==0) return(0);
                   18835:                else {  a->sy++;
                   18836:                        return(1);
                   18837:                        };
                   18838:                };
                   18839:        /* maximum permissable output bounds */
                   18840:        o_a_x = (int)((a->tr.a.x + a->off.x)*a->scl.x);
                   18841:        o_b_x = o_a_x + a->wh.x - 1;
                   18842:        if(a->sy<=((int)a->dy)) {
                   18843:                /* compute runs to be ouput: rp - input runs; mp - output runs*/
                   18844:                mp=(m.r - 1);
                   18845:                for(ep=(rp=l->r)+l->runs; rp<ep; rp++) {
                   18846:                        /* trim using a->tr */
                   18847:                        mr = *rp;
                   18848:                        if(mr.xe < a->tr.a.x) /* off left margin */ continue;
                   18849:                        if(mr.xs > a->tr.b.x) /* off right margin */ break;
                   18850:                        if(mr.xs < a->tr.a.x) /* extends left too far */
                   18851:                                mr.xs=a->tr.a.x;
                   18852:                        if(mr.xe > a->tr.b.x) /* extends right too far */
                   18853:                                mr.xe=a->tr.b.x;
                   18854: 
                   18855:                        /* offset using a->off */
                   18856:                        mr.xs += a->off.x;
                   18857:                        mr.xe += a->off.x;
                   18858: 
                   18859:                        /* expand using a->scl */
                   18860:                        mr.xs = (int)(mr.xs*a->scl.x);
                   18861:                        mr.xe = ((int)((mr.xe+1)*a->scl.x))-1;
                   18862:                        if(mr.xe<mr.xs) mr.xe=mr.xs;
                   18863: 
                   18864:                        /* truncate to maximum output width */
                   18865:                        if(mr.xe<o_a_x) /* off left margin */ continue;
                   18866:                        if(mr.xs>o_b_x) /* off right margin */ break;
                   18867:                        if(mr.xs<o_a_x) /* extends left too far */ mr.xs=o_a_x; 
                   18868:                        if(mr.xe>o_b_x) /* extends right too far */ mr.xe=o_b_x;
                   18869:                        /* store */
                   18870:                        if(mp < m.r) /* first */ *(++mp) = mr;
                   18871:                        else /* can merge with prior run? */ {
                   18872:                                if(mp->xe >= (mr.xs-1)) /* yes */ mp->xe = mr.xe;
                   18873:                                else /* no */ *(++mp) = mr;
                   18874:                                };
                   18875:                        };
                   18876:                m.runs = mp - m.r + 1;
                   18877:                m.len = a->wh.x;
                   18878:                do {    m.y = a->sy;
                   18879:                        if(a->rev) {
                   18880:                                /* r = reverse-video(m) */
                   18881:                                rp=r.r;  rr.xs=o_a_x;
                   18882:                                for(ep=(mp=m.r)+m.runs; mp<ep; mp++) {
                   18883:                                        if(rr.xs<mp->xs) {
                   18884:                                                rr.xe=mp->xs-1;
                   18885:                                                *(rp++)=rr;
                   18886:                                                };
                   18887:                                        rr.xs=mp->xe+1;
                   18888:                                        };
                   18889:                                if(rr.xs<=o_b_x) {
                   18890:                                        rr.xe=o_b_x;
                   18891:                                        *(rp++)=rr;
                   18892:                                        };
                   18893:                                r.runs = rp-r.r;
                   18894:                                r.len = m.len;
                   18895:                                r.y = m.y;
                   18896:                                if(sink(&r,sa)==0) return(0);
                   18897:                                }
                   18898:                        else {  if(sink(&m,sa)==0) return(0); };
                   18899:                        a->sy++;
                   18900:                        }
                   18901:                while(a->sy<=((int)a->dy));
                   18902:                };
                   18903:        a->dy += a->scl.y;
                   18904:        return(1);
                   18905:        }
                   18906: 
                   18907: /* Insert a (copy of) the given RLE_Line in the RLE_Lines */
                   18908: insert_rlel(rlp,rlsp)
                   18909:     RLE_Line *rlp;
                   18910:     RLE_Lines *rlsp;
                   18911: {      abort("insert_rlel:  unimplemented");
                   18912:        }
                   18913: 
                   18914: err_RLE_line(s,rl)
                   18915:     char *s;           /* name */
                   18916:     RLE_Line *rl;
                   18917: {   RLE_Run *r;
                   18918:     int ri;
                   18919:        if(rl==NULL) fprintf(stderr,"RLEL %10s NULL\n",s);
                   18920:        else {  fprintf(stderr,"RLEL %10s y%d r%d l%d: ",
                   18921:                                s,rl->y,rl->runs,rl->len);
                   18922:                for(ri=0,r=rl->r;ri<rl->runs;ri++,r++)
                   18923:                        fprintf(stderr,"[%d,%d] ",r->xs,r->xe);
                   18924:                fprintf(stderr,"\n");
                   18925:                };
                   18926:        }
                   18927: 
                   18928: 0707070035351135271006640007620000050000010264220476773367400001100000047346stdocr.h/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   18929: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   18930: /* The copyright notice does not imply actual or intended publication. */
                   18931: /* AUTHORS:                                            */
                   18932: /*     H. S. Baird - ATT-BL MH - first versions        */
                   18933: /* stdocr.h -- conventional OCGR constants, typedefs, and file formats
                   18934:  NOTE: sensitive to prior:
                   18935:        `#define MAIN 1'
                   18936:        `#define CPU ?'
                   18937:        `#define OS ?' */
                   18938: 
                   18939: extern int errno;      /* UNIX system call error number */
                   18940: 
                   18941: #ifndef MAIN
                   18942: #define MAIN 0
                   18943: #endif
                   18944: 
                   18945: #define FWRI (T)       /* use machine-independent format for dim-file writes */
                   18946: #define FRDI (T)       /* use machine-independent format for dim-file reads */
                   18947: 
                   18948: #ifndef PI
                   18949: #define PI 3.1415926535
                   18950: #endif
                   18951: 
                   18952: extern int Readvax;    /* T. Thompson flag:  see Coord.c */
                   18953: 
                   18954: #include "limits.h"    /* machine-dependent numeric extreme values */
                   18955: #include "fioi.h"      /* machine-independent types and binary I/O */
                   18956: #include "boole.h"     /* boolean type */
                   18957: #include "Units.h"     /* OCR-specific units */
                   18958: #include "Coord.h"     /* scanner coordinates & basic geometry */
                   18959: #include "ric.h"       /* ricoh scanner page & file formats */
                   18960: 
                   18961: /* 5620 dimensions, in dots */
                   18962: #define Width5620 800
                   18963: #define Height5620 1024
                   18964: 
                   18965: /* used (in clc.c) to compute absolute maximum value of natural 
                   18966:    log values used in Bayesian binary weights */
                   18967: #define LOG_ABS_MAX 3.0
                   18968: 
                   18969: #define Merit float            /* heuristic ``merit'' takes on values in [0,1] */
                   18970: /* machine-independent I/O:  range [0.0-1.0], precision .0000153 */
                   18971: #define fwri_Merit(F,V) fwri_uint2((F),((V)*USHRT_MAX))
                   18972: #define frdi_Merit(F) (frdi_uint2(F)/(Merit)USHRT_MAX)
                   18973: 
                   18974: #define Prob float             /* ``probability'' takes on values in [0,1] */
                   18975: /* machine-independent I/O:  range [0.0-1.0], precision .0000153 */
                   18976: #define fwri_Prob(F,V) fwri_uint2((F),((V)*USHRT_MAX))
                   18977: #define frdi_Prob(F) (frdi_uint2(F)/(Prob)USHRT_MAX)
                   18978: 
                   18979: #define Pts float              /* text-size units: ``points'' (1/72) inch */
                   18980: /* machine-independent I/O:  range [0,655.36], precision 0.01 ([0,9.1] inches) */
                   18981: #define fwri_Pts(F,V) fwri_uint2((F),((V)*100.0))
                   18982: #define frdi_Pts(F) (frdi_uint2(F)/100.0)
                   18983: 
                   18984: #define Ems float              /* em-space units */
                   18985: /* machine-independent I/O:  range [-32.768,32.767], precision 0.001 */
                   18986: #define fwri_Ems(F,V) fwri_int2((F),((V)*1000.0))
                   18987: #define frdi_Ems(F) (frdi_int2(F)/1000.0)
                   18988: 
                   18989: /* class name - long enough to be a unix file name */
                   18990: #define Cln_len (14)           /* maximum no. chars (DIRSIZ in some UNIX's) */
                   18991: #define Cln_lenp (Cln_len+1)   /* maximum size of array */
                   18992: typedef char Cln[Cln_lenp];
                   18993: #define fwri_Cln(F,S) fwri_str((F),(S))
                   18994: #define frdi_Cln(F,S) frdi_strn((F),(S),Cln_lenp)
                   18995: 
                   18996: /* font name */
                   18997: #define Fontn_len (Cln_len)            /* maximum no. chars */
                   18998: #define Fontn_lenp (Cln_lenp)          /* maximum size of array */
                   18999: typedef char Fontn[Fontn_lenp];
                   19000: #define fwri_Fontn(F,S) fwri_str((F),(S))
                   19001: #define frdi_Fontn(F,S) frdi_strn((F),(S),Fontn_lenp)
                   19002: 
                   19003: typedef struct ClassId {
                   19004:        Fontn f;        /* font name */
                   19005:        Pts s;          /* size in points */
                   19006:        Cln c;          /* printable symbol name (``class-name'') */
                   19007:        short v;        /* symbol variant no. 0,1,... */
                   19008:        } ClassId;
                   19009: 
                   19010: #define Init_ClassId {"",0.0,"",0}
                   19011: #if MAIN
                   19012: ClassId empty_ClassId = Init_ClassId;
                   19013: #else
                   19014: extern ClassId empty_ClassId;
                   19015: #endif
                   19016: char *classid_toa();   /* in chcln.c */
                   19017: #define eq_classid(a,b) ((!strcmp((a).f,(b).f))&&((a).s==(b).s)&&(!strcmp((a).c,(b).c))&&((a).v==(b).v))
                   19018: 
                   19019: #define fwri_ClassId(F,P) { \
                   19020:        fwri_Fontn((F),(P)->f); \
                   19021:        fwri_Pts((F),(P)->s); \
                   19022:        fwri_Cln((F),(P)->c); \
                   19023:        fwri_uint1((F),(P)->v); \
                   19024:        }
                   19025: #define frdi_ClassId(F,P) ( feof(F)? 0: ( \
                   19026:        frdi_Fontn((F),(P)->f), \
                   19027:        (P)->s=frdi_Pts(F), \
                   19028:        frdi_Cln((F),(P)->c), \
                   19029:        (P)->v=frdi_uint1(F), \
                   19030:        (ferror(F)? -errno: 1) ) )
                   19031: 
                   19032: /* Convert variant no. to ASCII character, and vice versa */
                   19033: #define vtoc(V) (((V)<=9)?('0'+(V)):(((V)<=35)?('a'+((V)-10)):('A'+((V)-36))))
                   19034: #define ctov(C) ((((C)>='0')&&((C)<='9'))?((C)-'0'):((((C)>='a')&&((C)<='z'))?(10+((C)-'a')):(36+((C)-'A'))))
                   19035: 
                   19036: /* parametric values: */
                   19037: #define Pval float
                   19038: /* machine-independent I/O:  precision 0.0001 & range [-838.8608,838.8607] */
                   19039: #define fwri_Pval(F,V) fwri_int4((F),(V)*1000.0)
                   19040: #define frdi_Pval(F) (frdi_int4(F)/1000.0)
                   19041: 
                   19042: typedef struct {       /* parametric point */
                   19043:        Pval x;
                   19044:        Pval y;
                   19045:        } Pp;
                   19046: 
                   19047: #define Init_Zero_Pp {0.0,0.0}
                   19048: #if MAIN
                   19049: Pp zero_Pp = Init_Zero_Pp;
                   19050: #else
                   19051: extern Pp zero_Pp;
                   19052: #endif
                   19053: 
                   19054: #define fwri_Pp(F,P) { fwri_Pval((F),(P)->x); fwri_Pval((F),(P)->y); }
                   19055: #define frdi_Pp(F,P) ( feof(F)? 0: ( \
                   19056:        (P)->x=frdi_Pval(F), \
                   19057:        (P)->y=frdi_Pval(F), \
                   19058:        (ferror(F)? -errno: 1) ) )
                   19059: 
                   19060: /* metrics:  ABSS, EUCL, MAXV */
                   19061: #define ABSS 'a'
                   19062: #define EUCL 'e'
                   19063: #define MAXV 'm'
                   19064: typedef short Metric;
                   19065: 
                   19066: #define fwri_Metric(F,V) fwri_ch((F),(V))
                   19067: #define frdi_Metric(F) (frdi_ch(F))
                   19068: 
                   19069: /* a vectorized blob file is a sequence of blob-descriptions.
                   19070:    a blob-description is a sequence of "vector" records; there are two
                   19071:    types of blob descriptions:
                   19072:        DOT:
                   19073:                'D'-vector (with bounding box)
                   19074:        CHAR:
                   19075:                'C'-vector, followed by:
                   19076:                        one 'B'-vector (bounding-box), and
                   19077:                        any number of: 'S' (stroke),
                   19078:                                       'G' (edge),
                   19079:                                       'O' (hole),
                   19080:                                       'A' (arc),
                   19081:                                       'C' (corner),
                   19082:                                       'P' (end-point), and
                   19083:                                       'V' & 'W' (boundary angles - 1 each),
                   19084:                        and terminated with one 'E' vector (giving classname)
                   19085:    */
                   19086: 
                   19087: #define Vrec_len 5
                   19088: typedef short Vrec[Vrec_len];
                   19089:    
                   19090: /* subshape values */
                   19091: /* #define U 0     uninitialized */
                   19092: #define NA (SHRT_MAX)  /* deliberately not-assigned (classifier failure) */
                   19093: 
                   19094: #define Dim short      /* specifies dimension 1,..,MaxDim */
                   19095: #define MaxDim 4
                   19096: 
                   19097: #define fwri_Dim(F,V) fwri_uint1((F),(V))
                   19098: #define frdi_Dim(F) (frdi_uint1(F))
                   19099: 
                   19100: #define Seq int                /* sequence nos;  indices into tables */
                   19101: #define FISeq 0                /* first value */
                   19102: #define NLSeq -1       /* conventional NULL value */
                   19103: #define S1Seq 0200000000  /* special bit 1 of Seq */
                   19104: #define S2Seq 0100000000  /* special bit 2 of Seq */
                   19105: #define NSSeq 0077777777  /* non-special bits */
                   19106: 
                   19107: #define fwri_Seq(F,V) fwri_int4((F),(V))
                   19108: #define frdi_Seq(F) (frdi_int4(F))
                   19109: 
                   19110: typedef short Liv;     /* limit value: scaled and truncated from floating-pt */
                   19111: #define Liv_MAX (SHRT_MAX)
                   19112: #define Liv_MIN (SHRT_MIN)
                   19113: 
                   19114: #define fwri_Liv(F,V) fwri_int2((F),(V))
                   19115: #define frdi_Liv(F) (frdi_int2(F))
                   19116: 
                   19117: typedef short Lit;     /* limit type, two flavors: */
                   19118: #define MN 0           /*      min:  MN < v */
                   19119: #define MX 1           /*      max:  v <= MX */
                   19120: 
                   19121: typedef Liv Ivl[2];    /* interval:  ( Ivl[MN], Ivl[MX] ] */
                   19122: 
                   19123: typedef Ivl Rec[MaxDim];   /* rectangular parallelopiped of limits in DIM-space */
                   19124: 
                   19125: /* a normalized blob file is a sequence of:
                   19126:        Nb_h    header, followed by Nb_h.ss of:
                   19127:                Nb_s    contour shapes */
                   19128: typedef struct {
                   19129:        ClassId ci;     /* class name */
                   19130:        Bbx bb;         /* bounding box */
                   19131:        Pval rsz;       /* raw character size (Ems) */
                   19132:        Pval bht;       /* height-above-baseline (Ems) */
                   19133:        Pval rwd;       /* width (Ems) */
                   19134:        Pval rar;       /* area (square-Ems) */
                   19135:        Pval rpe;       /* perimiter (Ems) */
                   19136:        Pval asp;       /* aspect ratio (h/w) */
                   19137:        Pval blk;       /* fraction of Bbx area that is black */
                   19138:        Pval per;       /* perimeter of blob as multiple of Bbx perim */
                   19139:        Pval gale;      /* Gale's feature:  incl. angle 'tween 2 longest sides */
                   19140:        short ss;       /* no. of shapes to follow */
                   19141:        } Nb_h;
                   19142: 
                   19143: #define MAX_SHAPES_EACH        1024    /* Max no. shapes per Blob/Char/item */
                   19144: 
                   19145: /* Shape is tiny (below threshold, may be pruned):  a flag ORed into shape type */
                   19146: #define Sh_tiny (0x80)
                   19147: 
                   19148: /* Shape types: */
                   19149: #define U 0    /* uninitialized */
                   19150: #define Sh_FI 1        /* first shape no. */
                   19151: #define Sh_B 1 /* blob (connected black region) */
                   19152: #define Sh_H 2 /* hole (connected white region) */
                   19153: #define Sh_S 3 /* stroke (undirected line-segment) */
                   19154: #define Sh_E 4 /* edge (directed line-segment along boundary) */
                   19155: #define Sh_C 5  /* concavity (intrusion from convex hull): its `cover' edge */
                   19156: #define Sh_D 6  /* direction and depth of concavity */
                   19157: #define Sh_A 7 /* locally-maximal convex arc (encloses black) */
                   19158: #define Sh_V 8  /* locally-maximal concave arc (encloses white) */
                   19159: #define Sh_P 9 /* endpoint (0-junction) */
                   19160: #define Sh_T 10        /* detail (left- and right-facing ticks) */
                   19161: #define Sh_X 11 /* crossing (X) */
                   19162: #define Sh_Y 12 /* global scalar variables, combined */
                   19163: #define Sh_Z 13 /* more global scalar variables, combined */
                   19164: #define Sh_LA 13 /* last of variable-no-of-occurences shape-types */
                   19165: #define Sh_MNY (Sh_LA+1)
                   19166: #define SHS_MNY (Sh_MNY)
                   19167: 
                   19168: #if (MAIN)
                   19169:        /* shape-names, given shape-type */
                   19170:        char Sh_nam[SHS_MNY] =
                   19171:        {'U', 'B', 'H', 'S', 'E', 'C', 'D', 'A', 'V', 'P', 'T', 'X', 'Y', 'Z'};
                   19172:        /* "dimension" -- no parameters in normalized form */
                   19173:        short Sh_dim[SHS_MNY] =
                   19174:        { 0,   3,   3,   4,   4,   4,   4,   4,   4,   4,   3,   2,   3,   1};
                   19175:        /* absolute minimum parametric values possible -- must be >= -1.0
                   19176:           (see norm.c & fiodict.c) */
                   19177:        Pval Sh_MN[SHS_MNY][MaxDim]
                   19178:                   = { { 0.0,  0.0,  0.0,  0.0},        /* U */
                   19179:                       {-0.5, -0.5, -0.5/*see mkd*/},   /* B */
                   19180:                       {-0.5, -0.5, -0.5/*see mkd*/},   /* H */
                   19181:                       {-0.5, -0.5, -0.5, -0.5},        /* S */
                   19182:                       {-0.5, -0.5, -0.5, -0.5},        /* E */
                   19183:                       {-0.5, -0.5, -0.5, -0.5},        /* C */
                   19184:                       {-0.5, -0.5, -0.5, -0.5},        /* D */
                   19185:                       {-0.5, -0.5, -0.5, -0.5},        /* A */
                   19186:                       {-0.5, -0.5, -0.5, -0.5},        /* V */
                   19187:                       {-0.5, -0.5, -0.5, -0.5},        /* P */
                   19188:                       {-0.5, -0.5, -0.5},              /* T */
                   19189:                       {-0.5, -0.5},                    /* X */
                   19190:                       {-0.5, -0.5, -0.5},              /* Y */
                   19191:                       {-0.5}                           /* Z */
                   19192:                         };
                   19193:        /* absolute maximum parametric value possible -- must be <= 1.0
                   19194:           (see norm.c & fiodict.c) */
                   19195:        Pval Sh_MX[SHS_MNY][MaxDim]
                   19196:                   = { { 0.0,  0.0,  0.0,  0.0},        /* U */
                   19197:                       {0.5, 0.5, 1.0/*see mkd*/},      /* B */
                   19198:                       {0.5, 0.5, 1.0/*see mkd*/},      /* H */
                   19199:                       {0.5, 0.5, 0.5, 0.5},            /* S */
                   19200:                       {0.5, 0.5, 0.5, 0.5},            /* E */
                   19201:                       {0.5, 0.5, 0.5, 0.5},            /* C */
                   19202:                       {0.5, 0.5, 0.5, 0.5},            /* D */
                   19203:                       {0.5, 0.5, 0.5, 0.5},            /* A */
                   19204:                       {0.5, 0.5, 0.5, 0.5},            /* V */
                   19205:                       {0.5, 0.5, 0.5, 0.5},            /* P */
                   19206:                       {0.5, 0.5, 0.5},                 /* T */
                   19207:                       {0.5, 0.5},                      /* X */
                   19208:                       {0.5, 0.5, 0.5},                 /* Y */
                   19209:                       {0.5}                            /* Z */
                   19210:                         };
                   19211:        /* minimum magnitude of (r,i) part of certain shapes */
                   19212:        Pval A_ri_minmag = 0.25;
                   19213:        Pval P_ri_minmag = 0.25;
                   19214: #else
                   19215:        extern char Sh_nam[];
                   19216:        extern short Sh_dim[];
                   19217:        extern Pval Sh_MN[][MaxDim];
                   19218:        extern Pval Sh_MX[][MaxDim];
                   19219:        extern Pval A_ri_minmag;
                   19220:        extern Pval P_ri_minmag;
                   19221: #endif
                   19222: 
                   19223: #define MIN_SD 0.001   /* minimum std-dev permitted */
                   19224: 
                   19225: typedef Pval Spar[MaxDim];     /* shape parameters */
                   19226: 
                   19227: typedef struct Nb_s {
                   19228:        short t;        /* shape type: one of U S O A C etc, perhaps |Sh_tiny */
                   19229:        Spar p;         /* parametric values */
                   19230:        } Nb_s;
                   19231: 
                   19232: /* indices into parametric values */
                   19233: /* blobs */
                   19234: #define B_x 0  /* (x,y) location of dot wrt bounding-box */
                   19235: #define B_y 1
                   19236: #define B_r 2  /* size of dot */
                   19237: /* holes */
                   19238: #define H_x 0  /* (x,y) location of center wrt bounding-box */
                   19239: #define H_y 1
                   19240: #define H_r 2  /* size of hole */
                   19241: /* strokes */
                   19242: #define S_x 0  /* (x,y) location of stroke center wrt bounding box */
                   19243: #define S_y 1
                   19244: #define S_r 2  /* (r,i) real-imag parts of rotation-length vector; */
                   19245: #define S_i 3   /*   rotation angle *2 since strokes have only [0,PI] range */
                   19246: /* edges */
                   19247: #define E_x 0  /* (x,y) location of edge center wrt bounding box */
                   19248: #define E_y 1
                   19249: #define E_r 2  /* (r,i) real-imag parts of direction-length vector */
                   19250: #define E_i 3 
                   19251: /* concavity hull edge */
                   19252: #define C_x 0  /* (x,y) location of center of hull-bdy edge wrt bounding-box */
                   19253: #define C_y 1
                   19254: #define C_r 2  /* (r,i) real-imag parts of hull-bdy edge */
                   19255: #define C_i 3
                   19256: /* concavity depth & direction */
                   19257: #define D_x 0  /* (x,y) location of center of depth & direction vector */
                   19258: #define D_y 1
                   19259: #define D_r 2  /* (r,i) real-imag parts of depth & direction vector */
                   19260: #define D_i 3
                   19261: /* locally-maximal convex arc */
                   19262: #define A_x 0  /* (x,y) location of center of enclosed area */
                   19263: #define A_y 1
                   19264: #define A_r 2  /* (r,i) real-imag parts of `incompleteness' vector */
                   19265: #define A_i 3
                   19266: /* locally-maximal concave arc */
                   19267: #define V_x 0  /* (x,y) location of center of enclosed area */
                   19268: #define V_y 1
                   19269: #define V_r 2  /* (r,i) real-imag parts of `incompleteness' vector */
                   19270: #define V_i 3
                   19271: /* endpoint */
                   19272: #define P_x 0  /* (x,y) location of center of hull-bdy wrt bounding-box */
                   19273: #define P_y 1
                   19274: #define P_r 2  /* (r,i) real-imag parts of direction-depth vector */
                   19275: #define P_i 3
                   19276: /* ticks:  left-, right-, top-, & bottom-facing extrema near ends */
                   19277: #define T_x 0  /* signed distance from centroid along principal axis */
                   19278: #define T_y 1  /* signed perpendicular distance from axis */
                   19279: #define T_a 2  /* angle of principal axis, within worst-case range */
                   19280: /* crossings */
                   19281: #define X_x 0  /* (x,y) location of crossing wrt bounding-box */
                   19282: #define X_y 1
                   19283: /* global scalars, combined */
                   19284: #define Y_a 0  /* log(aspect_ratio=hgt/wid) */
                   19285: #define Y_b 1  /* ratio of area to bbx_area */
                   19286: #define Y_p 2  /* ratio of perimeter to bbx_perimeter */
                   19287: /* global scalars, combined (more) */
                   19288: #define Z_g 0  /* Gale's feature: included angle between two longest bdy edges */
                   19289: 
                   19290: /* scalar features field indices */
                   19291: #define SF_RSZ 0       /* relative size (height in ems) */
                   19292: #define SF_BHT 1       /* height above baseline (ems) */
                   19293: #define SF_RWD 2       /* relative width (ems) */
                   19294: #define SF_RAR 3       /* relative area (square-ems) */
                   19295: #define SF_RPE 4       /* relative perimeter (ems) */
                   19296: #define SF_ASP 5       /* aspect-ratio */
                   19297: #define SF_BLK 6       /* fraction of Bbx that is black */
                   19298: #define SF_PER 7       /* ratio of perimeter to BBx per */
                   19299: #define SF_GALE 8      /* Gale's feature: incl. ang. between 2 longest edges */
                   19300: #define SF_N 8         /* index of last var that's not an occurrence-count */
                   19301: #define SF_MNY (SF_N+Sh_LA+1)
                   19302: 
                   19303: #if MAIN
                   19304:        /* ``Is this feature available early enough to be used in fast scalar-
                   19305:           feature preclassifier?'' (Must not depend on shape analysis.) */
                   19306:        boolean SFfeature[SF_MNY] = {
                   19307:                F, F, F, F, F, T, T, T, F,
                   19308:                T, T, T, T, T, T, T, T, T, T, T, F, F };
                   19309:        /* ``Is this feature discrete (integer-valued)?'' (Affects construction
                   19310:           of scalar-decision tree preclassifier.) */
                   19311:        boolean SFdiscrete[SF_MNY] = {
                   19312:                F, F, F, F, F, F, F, F, F,
                   19313:                T, T, T, T, T, T, T, T, T, T, T, T, T };
                   19314: #else
                   19315:        extern boolean SFfeature[];
                   19316:        extern boolean SFdiscrete[];
                   19317: #endif
                   19318: 
                   19319: typedef Pval SFv[SF_MNY];
                   19320: 
                   19321: /* blob tracer (boundary angles) features field indices */
                   19322: #define TR_MNY 8
                   19323: 
                   19324: typedef Pval TRv[TR_MNY];
                   19325: 
                   19326: /* tracer decision-tree header */
                   19327: typedef struct TRtr {
                   19328:        struct SFdnode *TRd;    /* array of decision-nodes */
                   19329:        struct Cl ***clist;     /* list of (class-ptr)-lists */
                   19330:        } TRtr;
                   19331: 
                   19332: /* Ss - sub-shape list-item */
                   19333: typedef struct Ss {
                   19334:        Seq seq;        /* globally unique sequence no */
                   19335:        Seq shs;        /* shape-hdr seq no */
                   19336:        Seq cls;        /* class sequence no */
                   19337:        short no;       /* sub-shape number (0,1,2..., NA) */
                   19338:        float focc;     /* fraction of training set w/ >=1 occurrence */
                   19339:        float fdup;     /* fraction of training set w/ >=2 occurrence */
                   19340:        Spar me;        /* mean parameters */
                   19341:        Spar sd;        /* std-dev parameters */
                   19342:        Spar min;       /* min limits (for fast checking) */
                   19343:        Spar max;       /* max limits (for fast checking) */
                   19344:        Rec r;          /* rectangular parallelopiped in Liv space */
                   19345:        Pval fr;        /* fraction of training set covered */
                   19346:        short nuse;     /* for current blob, no. uses */
                   19347:        float nocc;     /* occurrences: no. blobs with >=1 of these */
                   19348:        float ndup;     /* duplicates: no. blobs with >=2 of these */
                   19349:        float mind;     /* minimum scaled distance from cluster among uses */
                   19350:        float merit;    /* merit score resulting from 'nuse' matches to this */
                   19351:        struct Ss *ne;  /* ptr to next in list */
                   19352:        } Ss;
                   19353: 
                   19354: #define MAX_SS 8192    /* see 'kdt.h' for reasons */
                   19355: 
                   19356: /* BMask:  1-d, variable-length packed bitstring (N = no. bits).  The string
                   19357:    is stored in an array of (unsigned int).  It is often accessed via a fast
                   19358:    ascending sequence of 'short' pointers (unsigned short *) or (unsigned char *):
                   19359:    in these cases, enough are used to completely cover all the (unsigned int)s,
                   19360:    even though that may be more than enough, to ensure that the result is
                   19361:    insensitive to machine-dependent short-order-in-ints and char-order-in-shorts.
                   19362:       BMask_ni(N)    no. unsigned ints holding bit-data
                   19363:       BMask_si(N)    no. unsigned shorts covering bit-data (exactly 2x _ni)
                   19364:       BMask_ci(N)    no. unsigned chars covering bit-data (exactly 4x _ni)
                   19365:       BMask_size(N)  total no. bytes in, or pointed to by BMask:
                   19366:                        sizeof(n) + sizeof(mny) + sizeof(r) + sizeof(malloc space) 
                   19367:       */
                   19368: #define BMask_ni(N) (((N)+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))
                   19369: #define BMask_si(N) (2*BMask_ni(N))
                   19370: #define BMask_ci(N) (4*BMask_ni(N))
                   19371: #define BMask_size(N) (3*sizeof(unsigned int)+(BMask_ci((N))))
                   19372: 
                   19373: typedef struct BMask {
                   19374:        unsigned int n;                 /* no. of bits stored (==N above) */
                   19375:        unsigned int mny;               /* no. bits set to 1 */
                   19376:        unsigned int r;                 /* represents `r' BMasks altogether */
                   19377:        union { /* packed bits: 0th bit is 01 */
                   19378:                unsigned int *i;        /* malloc space: int [Bmask_ni] */
                   19379:                unsigned short *s;      /* malloc space: short [Bmask_si] */
                   19380:                int ii;                 /* index into (unsigned int)[] array */
                   19381:                int si;                 /* index into (unsigned short)[] array */
                   19382:                } u;
                   19383:        } BMask;
                   19384: 
                   19385: #define Init_BMask {0,0,0,}
                   19386: #if MAIN
                   19387:        BMask empty_BMask = Init_BMask;
                   19388: #else
                   19389:        extern BMask empty_BMask;
                   19390: #endif
                   19391: 
                   19392: 
                   19393: typedef struct BMasks {
                   19394:        unsigned short mny;     /* no. BMasks */
                   19395:        unsigned short r;       /* represents `r' BMasks altogether */
                   19396:        unsigned short shallow; /* 0 <= shallow <= mny */
                   19397:        unsigned short alloc;   /* no. items allocated in .a[] */
                   19398:        union { BMask *a;       /* array[mny] of BMasks */
                   19399:                int bi;         /* index into (BMask)[] array */
                   19400:                } u;
                   19401:        } BMasks;
                   19402: 
                   19403: #define Init_BMasks {0,0,0,0,}
                   19404: #if MAIN
                   19405:        BMasks empty_BMasks = Init_BMasks;
                   19406: #else
                   19407:        extern empty_BMasks;
                   19408: #endif
                   19409: 
                   19410: /* Sh - shape list-item */
                   19411: typedef struct Sh {
                   19412:        Seq seq;        /* unique sequence no. */
                   19413:        short t;        /* shape type: S, H, X, etc */
                   19414:        short nss;      /* no. sub-shapes in the list */
                   19415:        float mess;     /* mean no. sub-shapes in training set */
                   19416:        float sdss;     /* std-dev of sub-shapes in training set */
                   19417:        float NAocc;    /* prob at least one shape not-assigned */
                   19418:        float NAdup;    /* prob more than one not-assigned */
                   19419:        Ss NAss;        /* "not-assigned" data */
                   19420:        Ss *fi;         /* first sub-shape  */
                   19421:        Ss *la;         /* last sub-shape */
                   19422:        struct Sh *ne;  /* next shape */
                   19423:        } Sh;
                   19424: 
                   19425: /* Cl - class list-item */
                   19426: typedef struct Cl {
                   19427:        Seq seq;        /* unique sequence no. 0,1,... */
                   19428:        Cln c;          /* class name */
                   19429:        float shNA;     /* fraction of shapes unassigned */
                   19430:        float blDP;     /* fraction of blobs w/ >=1 duplicate shape-match*/
                   19431:        float blAL;     /* average extra alternate shape-matches / blob */
                   19432:        SFv sf_me;      /* scalar-features:  means, std-devs */
                   19433:        SFv sf_sd;
                   19434:        BMask bm;       /* canonical BMask */
                   19435:        BMasks bms;     /* additional representative BMask records */
                   19436:        Sh *sha[Sh_MNY];        /* table of pointers to shape-types */
                   19437:        Sh *fi;                 /* first owned shape */
                   19438:        Sh *la;                 /* last owned shape */
                   19439:        short unmat[Sh_MNY];    /* counts of unmatched shapes/shape-type */
                   19440:        struct Ssm *ssmfi;      /* first sub-shape match for this class */
                   19441:        TRtr *tr;               /* pointer to tracer decision tree (if any) */
                   19442:        TRv tr_me;              /* tracer-features:  means, std-devs */
                   19443:        TRv tr_sd;
                   19444:        float m_me;             /* mean, std-err of merit (in training set) */
                   19445:        float m_sd;
                   19446:        float bayes;    /* Bayesian merit: a posteriori log-probability */
                   19447:        Merit m01;      /* Haming, etc. merit in range [0,1] */
                   19448:        Merit merit;    /* sort and truncate based on this merit */
                   19449:        short pass;     /* the last classification method this class passed */
                   19450:        int ch_mny;     /* No. Chars of this class in a subset */
                   19451:        int ss_mny;     /* No. Chars with given feature */
                   19452:        boolean force_reseg;    /* forcibly resegment Chars of this Class */
                   19453:        struct Cl *ne;  /* next class */
                   19454:        } Cl;
                   19455: 
                   19456: /* MAX_CL (max no. of classes) is defined in CPU.h */
                   19457: #define MAX_SH (MAX_CL*SH_MNY)
                   19458: 
                   19459: typedef struct Classes {
                   19460:        int mny;        /* number of items in array */
                   19461:        Cl **clpa;      /* Cl *clpa[cl_mny+1]: NULL-term'd array of ptrs */
                   19462:        } Classes;
                   19463: #define Init_Classes {0,NULL}
                   19464: #if MAIN
                   19465: Classes empty_Classes = Init_Classes;
                   19466: #else
                   19467: extern Classes empty_Classes;
                   19468: #endif
                   19469: 
                   19470: typedef struct Ssm {   /* sub-shape match record */
                   19471:        Seq isn;        /* input shape sequence no (w/in blob) */
                   19472:        Cl *clp;        /* owning class, shape, sub-shape... */
                   19473:        Sh *shp;
                   19474:        Ss *ssp;
                   19475:        float mind;     /* distance to closest assigned sub-shape */
                   19476:        boolean alt;    /* T if this is an alternative (not the first) */
                   19477:        struct Ssm *ne; /* next, prior ptrs in list */
                   19478:        struct Ssm *pr;
                   19479:        } Ssm;
                   19480: 
                   19481: /* return pathname of OCR directory; if environment variable OCRDIR
                   19482:    is set, it is used; otherwise #defined variable OCRDIR is used. */
                   19483: #if MAIN
                   19484: char *getenv();
                   19485: char *ocrdir()
                   19486: {   char *ocrdir_ev;
                   19487:        if((ocrdir_ev=getenv("OCRDIR"))!=NULL) {
                   19488:                return(ocrdir_ev);
                   19489:                }
                   19490:        else return(OCRDIR);
                   19491:        }
                   19492: #else
                   19493: char *ocrdir();
                   19494: #endif
                   19495: 0707070035351135261006640007620000050000010264330476773367400001100000033171sunlib.c/* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                   19496: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                   19497: /* The copyright notice does not imply actual or intended publication. */
                   19498: /* AUTHORS:                                            */
                   19499: /*     T. Thompson - ATT-BL HO - first versions        */
                   19500: #include <stdio.h>
                   19501: #include <sys/types.h>
                   19502: #include <sys/stat.h>
                   19503: #include <sys/ioctl.h>
                   19504: #include <pixrect/pixrect.h>
                   19505: #include <pixrect/pixfont.h>
                   19506: #include <suntool/sunview.h>
                   19507: #include <suntool/canvas.h>
                   19508: #include "met.h"
                   19509: #include "boole.h"
                   19510: #include "Coord.h"
                   19511: 
                   19512: #define XYSCALE(x,y) (x=(x-obotx)*scx+botx),(y=(y-oboty)*scy+boty)
                   19513: 
                   19514: struct pixrect *source_pixrect;
                   19515: 
                   19516: Frame Mainframe;
                   19517: Canvas Win;
                   19518: int Winfd;
                   19519: Pixwin *Pw;
                   19520: int Key = -1;
                   19521: int Mousex;
                   19522: int Mousey;
                   19523: int Colorval;
                   19524: 
                   19525: /* CMAPSIZE MUST BE A POWER OF 2 (restriction in sun colormap stuff)*/
                   19526: #define CMAPSIZE 8
                   19527: 
                   19528: #define DEFAULTCOLOR (CMAPSIZE-1)
                   19529: 
                   19530: #define S_WHITE 0
                   19531: #define S_RED 1
                   19532: #define S_GREEN 2
                   19533: #define S_BLUE 3
                   19534: #define S_GREY 4
                   19535: #define S_AQUA 5
                   19536: #define S_YELLOW 6
                   19537: #define S_BLACK 7
                   19538: 
                   19539: int mycolors[CMAPSIZE][3] = {
                   19540:        255, 255, 255,  /* white */
                   19541:        230, 0, 75,     /* red */
                   19542:        0, 200, 0,      /* green */
                   19543:        0, 0, 200,      /* blue */
                   19544:        200, 200, 200,  /* grey */
                   19545:        0, 160, 170,    /* aqua */
                   19546:        250, 220, 0,    /* yellow */
                   19547:        0,0,0           /* foreground (black) */
                   19548: };
                   19549: 
                   19550: 
                   19551: void domouse();
                   19552: 
                   19553: extern int Debug;
                   19554: 
                   19555: extern event_proc();
                   19556: 
                   19557: static int
                   19558:        boty = 32767,           /* screen bottom y */
                   19559:        botx = 0,                       /* screen bottom x */
                   19560:        topx = 32767,           /* screen top x */
                   19561:        topy = 0,                       /* screen top y */
                   19562:        oboty = 0,                      /* user's bottom y */
                   19563:        obotx = 0,                      /* user's bottom x */
                   19564:        otopy = 32767,          /* user's top y */
                   19565:        otopx = 32767;          /* user's top x */
                   19566: 
                   19567: static double
                   19568:        scx = 1.0,                      /* scale factor x */
                   19569:        scy = 1.0                       /* scale factor y */
                   19570: ;
                   19571: static int lastx = 0;
                   19572: static int lasty = 0;
                   19573: static int lmode = 3;          /* drawing mode (default is xor)*/
                   19574: 
                   19575: int Prevlmode = 3;
                   19576: 
                   19577: #define signof(x) ((x)>=0.0?(1):(-1))
                   19578: #define absof(x) ((x)>=0.0?(x):(-x))
                   19579: 
                   19580: void flushout() { }
                   19581: 
                   19582: short bsy_pixrect_data[] = {
                   19583: /* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16
                   19584:  */
                   19585:        0x7FFE,0x4002,0x200C,0x1A38,0x0FF0,0x07E0,0x03C0,0x0180,
                   19586:        0x0180,0x0240,0x0520,0x0810,0x1108,0x23C4,0x47E2,0x7FFE
                   19587: };
                   19588: mpr_static(busy_pixrect, 16, 16, 1, bsy_pixrect_data);
                   19589: 
                   19590: int childpid;
                   19591: 
                   19592: Rect sweeparect();
                   19593: 
                   19594: om_open()
                   19595: {
                   19596:        Rect r;
                   19597: 
                   19598:        r = sweeparect();
                   19599: 
                   19600:        notify_errno = NOTIFY_OK;
                   19601: 
                   19602:        Mainframe = window_create((Window)NULL, FRAME,
                   19603:                FRAME_LABEL, "ocr",
                   19604:                0 );
                   19605:        Win = window_create(Mainframe, CANVAS, 0);
                   19606:         Pw = canvas_pixwin(Win);
                   19607: 
                   19608:        window_set(Mainframe, WIN_X, r.r_left,
                   19609:                        WIN_Y, r.r_top, 0);
                   19610:        window_set(Win, WIN_WIDTH, r.r_width,
                   19611:                        WIN_HEIGHT, r.r_height, 0);
                   19612: 
                   19613:        window_fit(Win);
                   19614:        window_fit(Mainframe);
                   19615: 
                   19616:        window_set(Mainframe, WIN_SHOW, TRUE, 0);
                   19617: 
                   19618:        Winfd = (int) window_get(Win, WIN_FD);
                   19619: 
                   19620:        if ( notify_errno != NOTIFY_OK ) {
                   19621:                notify_perror("ocr");
                   19622:                exit(1);
                   19623:        }
                   19624: 
                   19625:        setcolormap();
                   19626: 
                   19627:        set_color(DEFAULTCOLOR);
                   19628:        linemod("solid");
                   19629: 
                   19630:        window_set(Win,
                   19631:                WIN_CONSUME_PICK_EVENTS,
                   19632:                        WIN_NO_EVENTS,
                   19633:                        WIN_ASCII_EVENTS,
                   19634:                        WIN_MOUSE_BUTTONS,
                   19635:                        LOC_MOVE,
                   19636:                        /* LOC_DRAG, */
                   19637:                        LOC_WINEXIT, LOC_WINENTER,
                   19638:                        LOC_RGNEXIT, LOC_RGNENTER, 0,
                   19639:                0);
                   19640: 
                   19641:        window_set(Win, WIN_EVENT_PROC, event_proc, 0);
                   19642: 
                   19643:        space(0,0,M_WID,M_HGT);
                   19644:        interact();
                   19645: }
                   19646: 
                   19647: /***********************************************************/
                   19648: /* The code below was taken from the 'dumpregion' program. */
                   19649: /***********************************************************/
                   19650: 
                   19651: /*
                   19652:  * Copyright Richard Tobin 1987.  You may freely copy, modify and distribute
                   19653:  * this program in source form provided this comment remains intact.
                   19654:  *
                   19655:  * Richard Tobin,                    JANET: [email protected]             
                   19656:  * AI Applications Institute,        ARPA:  R.Tobin%[email protected]
                   19657:  * Edinburgh University.             UUCP:  ...!ukc!ed.ac.uk!R.Tobin
                   19658:  */
                   19659: 
                   19660: #include <sys/file.h>
                   19661: #include <suntool/fullscreen.h>
                   19662: 
                   19663: short nwdata[] = {
                   19664: #include </usr/include/images/stretchNW.cursor>
                   19665: };
                   19666: mpr_static(nwpixrect, 16, 16, 1, nwdata);
                   19667: 
                   19668: short sedata[] = {
                   19669: #include </usr/include/images/stretchSE.cursor>
                   19670: };
                   19671: mpr_static(sepixrect, 16, 16, 1, sedata);
                   19672: 
                   19673: Rect rect = {0,0,0,0};
                   19674: 
                   19675: Rect
                   19676: sweeparect()
                   19677: {
                   19678:     int wfd, n;
                   19679:     struct fullscreen *fs;
                   19680:     Event event;
                   19681:     Pixwin *pw;
                   19682:     int left, right, top, bottom, temp;
                   19683:     Window win;
                   19684:     double w;
                   19685:     Rect r;
                   19686: 
                   19687:     win = window_create(0, FRAME,
                   19688:                        FRAME_OPEN_RECT, &rect,
                   19689:                        WIN_CONSUME_PICK_EVENTS,
                   19690:                        WIN_ASCII_EVENTS,
                   19691:                         LOC_MOVE, WIN_MOUSE_BUTTONS, 0,
                   19692:                        0);
                   19693: 
                   19694:     wfd = (int)window_get(win, WIN_FD);
                   19695:     fs = fullscreen_init(wfd);
                   19696:     pw = fs->fs_pixwin;
                   19697: 
                   19698:     window_set(win,
                   19699:               WIN_CURSOR, cursor_create(CURSOR_IMAGE, &nwpixrect,
                   19700:                                         CURSOR_XHOT, 0, CURSOR_YHOT, 0,
                   19701:                                         0),
                   19702:               0);
                   19703: 
                   19704:     for ( ;; ) {
                   19705:        n = window_read_event(win, &event);
                   19706:        if ( n < 0 )
                   19707:                continue;
                   19708:        if ( event_is_ascii(&event) ) {
                   19709:                if ( event_id(&event) == 'F' ) {
                   19710:                        r.r_left = 10;
                   19711:                        r.r_top = 10;
                   19712:                        r.r_width = 900;
                   19713:                        r.r_height = 900;
                   19714:                }
                   19715:                else {
                   19716:                        r.r_left = 542;
                   19717:                        r.r_top = 0;
                   19718:                        r.r_width = 540;
                   19719:                        r.r_height = 512;
                   19720:                }
                   19721:                goto getout;
                   19722:        }
                   19723:        if ( event_is_down(&event) && event_is_button(&event) )
                   19724:                break;
                   19725:     }
                   19726: 
                   19727:     right = left = event_x(&event);
                   19728:     bottom = top = event_y(&event);
                   19729: 
                   19730:     window_set(win,
                   19731:               WIN_CURSOR, cursor_create(CURSOR_IMAGE, &sepixrect,
                   19732:                                         CURSOR_XHOT, 15, CURSOR_YHOT, 15,
                   19733:                                         0),
                   19734:               0);
                   19735: 
                   19736:     drawbox(pw, left, top, right, bottom);
                   19737: 
                   19738:     while(window_read_event(win, &event) == -1 ||
                   19739:          !event_is_up(&event) ||
                   19740:          !event_is_button(&event))
                   19741:     {
                   19742:        drawbox(pw, left, top, right, bottom);
                   19743:        right = event_x(&event);
                   19744:        bottom = event_y(&event);
                   19745:        drawbox(pw, left, top, right, bottom);
                   19746:     }
                   19747: 
                   19748:     drawbox(pw, left, top, right, bottom);
                   19749: 
                   19750:     if(right < left)
                   19751:     {
                   19752:        temp = right;
                   19753:        right = left;
                   19754:        left = temp;
                   19755:     }
                   19756:     if(bottom < top)
                   19757:     {
                   19758:        temp = bottom;
                   19759:        bottom = top;
                   19760:        top = temp;
                   19761:     }
                   19762:     r.r_left = left;
                   19763:     r.r_top = top;
                   19764:     r.r_width = (right-left);
                   19765:     r.r_height = (bottom-top);
                   19766: getout:
                   19767:     fullscreen_destroy(fs);
                   19768: 
                   19769:     window_set(win, FRAME_NO_CONFIRM, TRUE, 0);
                   19770:     window_destroy(win);
                   19771:     return r;
                   19772: }
                   19773: 
                   19774: drawbox(pw, left, top, right, bottom)
                   19775: Pixwin *pw;
                   19776: int left, top, right, bottom;
                   19777: {
                   19778:     fullscreen_pw_vector(pw, left, top, right, top, PIX_NOT(PIX_DST), 0);
                   19779:     fullscreen_pw_vector(pw, right, top, right, bottom, PIX_NOT(PIX_DST), 0);
                   19780:     fullscreen_pw_vector(pw, right, bottom, left, bottom, PIX_NOT(PIX_DST), 0);
                   19781:     fullscreen_pw_vector(pw, left, bottom, left, top, PIX_NOT(PIX_DST), 0);
                   19782: }
                   19783: 
                   19784: ttygets(buff,len)
                   19785: char *buff;
                   19786: {
                   19787:        int x, y, n, key;
                   19788:        char *p = buff;
                   19789: 
                   19790:        for ( n=0; n<(len-1); n++ ) {
                   19791:                while ( (key=mouseorkey(&x,&y)) < 0 )
                   19792:                        ;
                   19793:                if ( key == '\r' )      /* just in case */
                   19794:                        key = '\n';
                   19795:                *p++ = key;
                   19796:                if ( key == '\n' || key == '\0' )
                   19797:                        break;
                   19798:        }
                   19799:        *p++ = '\0';
                   19800: }
                   19801: 
                   19802: int mouseorkey(x,y)
                   19803: int* x;
                   19804: int* y;
                   19805: {
                   19806:        Event anevent;
                   19807:        char c;
                   19808:        int n;
                   19809: 
                   19810:        Key = -1;
                   19811: 
                   19812:        notify_do_dispatch();
                   19813:        n = read(0,&c,1);
                   19814:        notify_no_dispatch();
                   19815:        if ( n == 1 ) {
                   19816:                /* character was typed in text (original) window */
                   19817:                /* ie. stdin */
                   19818:                Key = c;
                   19819:                *x = Mousex;
                   19820:                *y = Mousey;
                   19821:                xyunscale(x,y);
                   19822:        }
                   19823:        else if ( Key >= 0 ) {
                   19824:                /* character was typed in graphics window */
                   19825:                /* so it must be echoed. */
                   19826:                putchar(Key);
                   19827:                if ( Key == '\r' )
                   19828:                        putchar('\n');
                   19829:                fflush(stdout);
                   19830:                *x = Mousex;
                   19831:                *y = Mousey;
                   19832:                xyunscale(x,y);
                   19833:        }
                   19834:        return(Key);
                   19835: }
                   19836: 
                   19837: interact()
                   19838: {
                   19839:        (void) notify_dispatch();
                   19840: }
                   19841: 
                   19842: setcolormap()
                   19843: {
                   19844:        u_char red[CMAPSIZE], green[CMAPSIZE], blue[CMAPSIZE];
                   19845:        int n;
                   19846: 
                   19847:        for(n=0;n<CMAPSIZE;n++) {
                   19848:                red[n] = mycolors[n][0];
                   19849:                green[n] = mycolors[n][1];
                   19850:                blue[n] = mycolors[n][2];
                   19851:        }
                   19852:         pw_setcmsname(Pw,"showcolor");
                   19853:         pw_putcolormap(Pw, 0, CMAPSIZE, red, green, blue);
                   19854: }
                   19855: 
                   19856: /*ARGSUSED*/
                   19857: wait_proc(window,event,arg)
                   19858: Window window;
                   19859: Event *event;
                   19860: caddr_t arg;
                   19861: {
                   19862:        int id = event_id(event);
                   19863: 
                   19864:        if ( event_is_ascii(event) && id == 'q' )
                   19865:                notify_stop(0);
                   19866: }
                   19867: 
                   19868: om_close()
                   19869: {
                   19870:        window_set(Win, WIN_EVENT_PROC, wait_proc, 0);
                   19871:        if ( fork() == 0 ) {
                   19872:                close(0);
                   19873:                close(1);
                   19874:                close(2);
                   19875:                /* This stuff doesn't seem to work.  I'm trying to */
                   19876:                /* get the window to be able to repaint itself when */
                   19877:                /* uncovered.  */
                   19878:                sleep(1);
                   19879:                window_main_loop(Mainframe);
                   19880:                exit(0);
                   19881:        }
                   19882: }
                   19883: 
                   19884: space(x0,y0,x1,y1)
                   19885: int x0, y0, x1, y1;
                   19886: {
                   19887:        int tx, ty;
                   19888: 
                   19889:        obotx = x0;
                   19890:        oboty = y0;
                   19891:        otopx = x1;
                   19892:        otopy = y1;
                   19893: 
                   19894:         boty = 0;
                   19895:         botx = 0;
                   19896:         tx = (int) window_get(Win,WIN_WIDTH);
                   19897:         ty = (int) window_get(Win,WIN_HEIGHT); 
                   19898:         topx = tx;
                   19899:         topy = ty;
                   19900:         scx = (double)(topx-botx)/(otopx-obotx);
                   19901:         scy = (double)(topy-boty)/(otopy-oboty);
                   19902: }
                   19903: 
                   19904: #ifdef OLDSTUFF
                   19905: xyscale(x, y)
                   19906: int *x, *y;
                   19907: {
                   19908:         *x = (*x-obotx)*scx+botx;
                   19909:         *y = (*y-oboty)*scy+boty;
                   19910: }
                   19911: #endif
                   19912: 
                   19913: xyunscale(x, y)
                   19914: int *x, *y;
                   19915: {
                   19916:        /* map from device coordinates to space() coordinates */
                   19917: 
                   19918:        *x = ( (*x - botx)/scx + obotx );
                   19919:        *y = ( (*y - boty)/scy + oboty );
                   19920: }
                   19921: 
                   19922: wline(x1,y1,x2,y2)
                   19923: int x1, y1, x2, y2;
                   19924: {
                   19925:        lastx = x2;
                   19926:        lasty = y2;
                   19927: 
                   19928:        XYSCALE(x1, y1);
                   19929:        XYSCALE(x2, y2);
                   19930: 
                   19931:        arawline(x1,y1,x2,y2);
                   19932: }
                   19933: 
                   19934: wrect(x1,y1,x2,y2)
                   19935: int x1, y1, x2, y2;
                   19936: {
                   19937:        lastx = x2;
                   19938:        lasty = y2;
                   19939: 
                   19940:        XYSCALE(x1, y1);
                   19941:        XYSCALE(x2, y2);
                   19942: 
                   19943:        arawbox(x1,y1,x2,y2);
                   19944: }
                   19945: 
                   19946: arawbox(x1,y1,x2,y2)
                   19947: int x1, y1, x2, y2;
                   19948: {
                   19949:        arawline(x1,y1,x2,y1);
                   19950:        arawline(x2,y1,x2,y2);
                   19951:        arawline(x2,y2,x1,y2);
                   19952:        arawline(x1,y2,x1,y1);
                   19953: }
                   19954: 
                   19955: arawline(x1,y1,x2,y2)
                   19956: int x1, y1, x2, y2;
                   19957: {
                   19958:        int op, col;
                   19959: 
                   19960:        currentopcol(&op,&col);
                   19961: /* fprintf(stderr,"calling pw_vector, %d,%d  %d,%d  currentop=%d  Colorval=%d  Pw=%ld\n",x1,y1,x2,y2,op,col,Pw); */
                   19962:        pw_vector(Pw, (int)x1,(int)y1, (int)x2,(int)y2, op, col);
                   19963:        interact();
                   19964: }
                   19965: 
                   19966: currentopcol(aop,acol)
                   19967: int *aop, *acol;
                   19968: {
                   19969:        if ( lmode == 1 && Colorval == S_WHITE ) {
                   19970:                *aop = (PIX_NOT(PIX_SRC) & PIX_DST);
                   19971:                *acol = S_BLACK;
                   19972:        }
                   19973:        else {
                   19974:                *acol = Colorval;
                   19975:                switch (lmode) {
                   19976:                case 0:
                   19977:                        *aop = (PIX_NOT(PIX_SRC) & PIX_DST);
                   19978:                        break;
                   19979:                case 1:
                   19980:                case 2:
                   19981:                        /* *aop = (PIX_SRC | PIX_DST); */
                   19982:                        *aop = PIX_SRC;
                   19983:                        break;
                   19984:                case 3:
                   19985:                        *aop = (PIX_SRC ^ PIX_DST);
                   19986:                        break;
                   19987:                default:
                   19988:                        *aop = (PIX_SRC | PIX_DST);
                   19989:                        break;
                   19990:                }
                   19991:        }
                   19992: }
                   19993: 
                   19994: wt(s,scl,left,top,right,bot)
                   19995: char *s;
                   19996: {
                   19997:        int op, col;
                   19998: /* fprintf(stderr,"wt() called, s=%s  lastxy=%d,%d  scl=%d  left-top=%d,%d\n",
                   19999: s,left,top,scl,left,top); */
                   20000:        currentopcol(&op,&col);
                   20001:        XYSCALE(left, top);
                   20002:        pw_ttext(Pw,(int)left,(int)top,op,NULL,s);
                   20003: }
                   20004: 
                   20005: Sp *
                   20006: set_font(n)
                   20007: {
                   20008:        static Sp chsz;
                   20009:        struct pr_size prs;
                   20010:        int x, y;
                   20011: 
                   20012:        prs = pf_textwidth(1,pf_default(),"x");
                   20013:        x = prs.x;
                   20014:        y = prs.y;
                   20015:        xyunscale(&x,&y);
                   20016:        chsz.x = ++x;
                   20017:        chsz.y = y;
                   20018:        return &chsz;
                   20019: }
                   20020: 
                   20021: #ifdef OLDSTUFF
                   20022: textwidth(s)
                   20023: {
                   20024:        struct pr_size prs;
                   20025: 
                   20026:        prs = pf_textwidth(bound,strlen(s),pf_default(),s);
                   20027: 
                   20028:        
                   20029:        prs = pf_textwidth(1,pf_default(),"x");
                   20030:        *ax = prs.x;
                   20031:        *ay = prs.y;
                   20032:        xyunscale(ax,ay);
                   20033: }
                   20034: #endif
                   20035: 
                   20036: amove(x,y)
                   20037: int x,y;
                   20038: {
                   20039:        lastx = x;
                   20040:        lasty = y;
                   20041: }
                   20042: 
                   20043: cont(x,y)
                   20044: int x,y;
                   20045: {
                   20046:        wline(lastx,lasty,x,y);
                   20047:        /* last[xy] are then updated by line */
                   20048: }
                   20049: 
                   20050: 
                   20051: set_color(n)
                   20052: int n;
                   20053: {
                   20054:        switch(n){
                   20055:        case M_WHITE:
                   20056:                n = S_WHITE; break;
                   20057:        case M_PALE_GREY:
                   20058:        case M_GREY_7:
                   20059:                n = S_GREY; break;
                   20060:        case M_BLACK:
                   20061:                n = S_BLACK; break;
                   20062:        case M_YELLOW_13:
                   20063:        case M_YELLOW_11:
                   20064:                n = S_YELLOW; break;
                   20065:        case M_MAGENTA:
                   20066:        case M_CYAN:
                   20067:        case M_CYAN_14:
                   20068:                n = S_AQUA; break;
                   20069:        case M_GREEN:
                   20070:        case M_GREEN_7:
                   20071:                n = S_GREEN; break;
                   20072:        case M_BLUE:
                   20073:                n = S_BLUE; break;
                   20074:        case M_RED:
                   20075:                n = S_RED; break;
                   20076:        default:
                   20077:                fprintf(stderr,"Unknown color in set_color (%d)\n",n);
                   20078:                n = S_WHITE;
                   20079:                break;
                   20080:        }
                   20081:        Colorval = n;
                   20082: /* fprintf(stderr,"set_color = (sun#) %d\n",n); */
                   20083: }
                   20084: 
                   20085: linemod(s)
                   20086: char *s;
                   20087: {
                   20088:        if ( strcmp(s,"erase")==0 )
                   20089:                lmode = 0;
                   20090:        else if ( strcmp(s,"dotted")==0 || strcmp(s,"hilight")==0 )
                   20091:                lmode = 2;
                   20092:        else if ( strcmp(s,"xor")==0 )
                   20093:                lmode = 3;
                   20094:        else { /* everything, including "solid" defaults to this */
                   20095:                lmode = 1;
                   20096:        }
                   20097: }
                   20098: 
                   20099: aerase()
                   20100: {
                   20101:        pw_writebackground(Pw,0,0,(int)topx,(int)topy,PIX_SRC);
                   20102: }
                   20103: 
                   20104: wfrect(x1,y1,x2,y2)
                   20105: int x1, y1, x2, y2;
                   20106: {
                   20107:        int op, col;
                   20108:        int t;
                   20109: 
                   20110:        XYSCALE(x1, y1);
                   20111:        XYSCALE(x2, y2);
                   20112: 
                   20113:        currentopcol(&op,&col);
                   20114: 
                   20115:        if ( x1 > x2 ) {
                   20116:                t = x1;
                   20117:                x1 = x2;
                   20118:                x2 = t;
                   20119:        }
                   20120:        if ( y1 > y2 ) {
                   20121:                t = y1;
                   20122:                y1 = y2;
                   20123:                y2 = t;
                   20124:        }
                   20125: /* fprintf(stderr,"wfrect(%d,%d to %d,%d  lmode=%d op=%d col=%d)\n",
                   20126: x1,y1,x2,y2,lmode,op,col); */
                   20127:        for ( t=y1; t<=y2; t++ ) {
                   20128:                pw_vector(Pw, x1,t, x2,t, op, col);
                   20129:        }
                   20130:        interact();
                   20131: }
                   20132: 
                   20133: /*ARGSUSED*/
                   20134: event_proc(window,event,arg)
                   20135: Window window;
                   20136: Event *event;
                   20137: caddr_t arg;
                   20138: {
                   20139:        int id = event_id(event);
                   20140: 
                   20141:        if ( event_is_ascii(event) ) {
                   20142:                Key = id;
                   20143:                notify_stop(0);
                   20144:                return;
                   20145:        }
                   20146: }
                   20147: 
                   20148: /* trim a Metheus X coordinate to fit on screen */
                   20149: int M_trimX(x)
                   20150:        int x;
                   20151: {      if(x<0) return(0);
                   20152:        else if(x>(topx-1)) return((topx-1));
                   20153:        return(x);
                   20154:        }
                   20155: 
                   20156: /* trim a Metheus Y coordinate to fit on screen */
                   20157: int M_trimY(y)
                   20158:        int y;
                   20159: {      if(y<0) return(0);
                   20160:        else if(y>(topy-1)) return((topy-1));
                   20161:        return(y);
                   20162:        }
                   20163: 
                   20164: /* show Sp (Metheus coordinates) on Metheus,
                   20165:    enlarged to a `dot'-sided square */
                   20166: sh_Mp(mpp,dot)
                   20167:        Sp *mpp;
                   20168:        int dot;
                   20169: {      int half_dot;
                   20170:        if(dot==1)
                   20171:           wfrect(mpp->x,mpp->y,mpp->x,mpp->y);
                   20172:        else {
                   20173:                half_dot=dot/2;
                   20174:                if((dot%2)==0)
                   20175:                        wfrect( M_trimX(mpp->x-half_dot+1),
                   20176:                                M_trimY(mpp->y-half_dot+1),
                   20177:                                M_trimX(mpp->x+half_dot),
                   20178:                                M_trimY(mpp->y+half_dot) );
                   20179:                else    wfrect( M_trimX(mpp->x-half_dot),
                   20180:                                M_trimY(mpp->y-half_dot),
                   20181:                                M_trimX(mpp->x+half_dot),
                   20182:                                M_trimY(mpp->y+half_dot) );
                   20183:                };
                   20184:        }
                   20185: 
                   20186: 
                   20187: om_force(){}
                   20188: 
                   20189: /* write "thick" line, two pixels wide */
                   20190: wtline(x1,y1,x2,y2)
                   20191: {   int absdx, absdy;
                   20192:        wline(x1,y1,x2,y2);
                   20193:        absdx = (x1-x2)>=0 ? x1-x2 : x2-x1;
                   20194:        absdy = (y1-y2)>=0 ? y1-y2 : y2-y1;
                   20195:        if(absdx>absdy)
                   20196:                /* more horizontal -- thicken vertically */
                   20197:                wline(x1,M_trimY(y1+1),x2,M_trimY(y2+1));
                   20198:        else
                   20199:                /* more vertical -- thicken horizontally */
                   20200:                wline(M_trimX(x1+1),y1,M_trimX(x2+1),y2);
                   20201: }
                   20202: 
                   20203: /* write "fat" line, three pixels wide */
                   20204: wfline(x1,y1,x2,y2)
                   20205: {      register int absdx, absdy;
                   20206: 
                   20207:        wline(x1,y1,x2,y2);
                   20208:        absdx = (x1-x2)>=0 ? x1-x2 : x2-x1;
                   20209:        absdy = (y1-y2)>=0 ? y1-y2 : y2-y1;
                   20210:        if(absdx>absdy) {
                   20211:                /* more horizontal -- thicken vertically */
                   20212:                wline(x1,M_trimY(y1+1),x2,M_trimY(y2+1));
                   20213:                wline(x1,M_trimY(y1-1),x2,M_trimY(y2-1));
                   20214:                }
                   20215:        else    {
                   20216:                /* more vertical -- thicken horizontally */
                   20217:                wline(M_trimX(x1+1),y1,M_trimX(x2+1),y2);
                   20218:                wline(M_trimX(x1-1),y1,M_trimX(x2-1),y2);
                   20219:                };
                   20220: }
                   20221: 
                   20222: 
                   20223: om_wrpix()
                   20224: {
                   20225:         printf("om_wrpix called\n");
                   20226: }
                   20227: 
                   20228: om_buffer(n) { }
                   20229: 
                   20230: rreset() { }
                   20231: 0707070035351136761006640007620000050000011476070476773366200001100000004314makefile# for all OS --
                   20232: OPT = -O
                   20233: PROF = -p
                   20234: PI = -g
                   20235: 
                   20236: PRODUCTION =  $(OPT)
                   20237: DEBUG = $(PROF) $(PI)
                   20238: 
                   20239: # -- for UNIX 9th Ed --
                   20240: CFLAGS = $(PRODUCTION)
                   20241: LIBS = -lY3610 -lY
                   20242: PORTLIB = -lport
                   20243: LDFLAGS = 
                   20244: F77LIBS = $(LIBS)
                   20245: MLIB =
                   20246: REGEX =
                   20247: FTW =
                   20248: METLIB = mlib.o
                   20249: RASTLIB =
                   20250: POSTLIB =
                   20251: GRAPHICLIBS = 
                   20252: 
                   20253: # -- For Sun OS 4.x --
                   20254: ##GRAPHICLIBS = -lsuntool -lsunwindow -lpixrect
                   20255: ##MLIB = -lm
                   20256: ##LIBS = $(GRAPHICLIBS) $(MLIB) 
                   20257: ##PORTLIB = /usr/lib/libport3.a
                   20258: ##F77LIBS = -lF77 -lI77 -lc $(MLIB) $(GRAPHICLIBS)
                   20259: ##REGEX = regexec.o regcomp.o regerror.o
                   20260: ##FTW = myftw.o
                   20261: ##LDFLAGS = $(PROF) -fswitch
                   20262: ##CFLAGS = $(PROF) -fswitch -Bstatic
                   20263: ##METLIB = sunlib.o
                   20264: ##RASTLIB = rastlib.o
                   20265: ##POSTLIB = postlib.o 
                   20266: 
                   20267: all:   bcp
                   20268:        touch bcp
                   20269: clean:
                   20270:        rm -rf *.[cho15] bcp bcp.cpio *.srcs makefile
                   20271: 
                   20272: # the next three targets are for use in 1127 software distribution on bowell
                   20273: 
                   20274: install: /usr/bin/bcp
                   20275:        cp bcp.1 /usr/man/man1
                   20276: 
                   20277: /usr/bin/bcp:  bcp
                   20278:        strip bcp
                   20279:        cp bcp /usr/bin
                   20280: 
                   20281: ship:  /usr/bin/bcp
                   20282:        ship /usr/bin/bcp
                   20283: 
                   20284: # If you want to use UNIX FILE_TREEs:
                   20285: Path.o:  Path.c CPU.h myftw.h Path.h
                   20286:        cc $(CFLAGS) -c Path.c
                   20287: FTREE=Path.o
                   20288: 
                   20289: # If you DON'T want to use FILE_TREEs:
                   20290: ##FTREE=
                   20291: 
                   20292: bcp:   bcp.o CCITT.o rlelib.o riclib.o Coord.o piclib.o jslr.o Text.o $(FTREE) $(POSTLIB) $(RASTLIB)
                   20293:        cc $(CFLAGS) bcp.o CCITT.o rlelib.o riclib.o Coord.o piclib.o jslr.o Text.o $(FTREE) $(POSTLIB) $(RASTLIB) $(MLIB) $(GRAPHICLIBS) -o bcp
                   20294: bcp.o: bcp.c CPU.h stdocr.h rle.h CCITT.h bitio.h pic.h Path.h Bitmap.h Text.h abort.h
                   20295:        cc $(CFLAGS) $(MLIB) $(GRAPHICLIBS) -c bcp.c
                   20296: 
                   20297: stdocr.h:  boole.h limits.h Units.h ric.h fioi.h
                   20298:        touch stdocr.h
                   20299: CCITT.o: CCITT.c CPU.h stdocr.h rle.h Bitmap.h CCITT.h bitio.h
                   20300:        cc $(CFLAGS) -c CCITT.c
                   20301: rlelib.o:  rlelib.c CPU.h stdocr.h rle.h ric.h
                   20302:        cc $(CFLAGS) -c rlelib.c
                   20303: riclib.o:  riclib.c CPU.h stdocr.h
                   20304:        cc $(CFLAGS) -c riclib.c
                   20305: Coord.o:  Coord.c CPU.h boole.h Units.h Coord.h
                   20306:        cc $(CFLAGS) -c Coord.c
                   20307: Text.o:  Text.c font.h Bfeats.h stdocr.h
                   20308:        cc $(CFLAGS) -c Text.c
                   20309: piclib.o:  piclib.c CPU.h boole.h limits.h Units.h Coord.h pic.h
                   20310:        cc $(CFLAGS) -c piclib.c
                   20311: jslr.o:        jslr.c
                   20312:        cc $(CFLAGS) -c jslr.c
                   20313: rastlib.o:  rastlib.c
                   20314:        cc $(CFLAGS) $(MLIB) $(GRAPHICLIBS) -c rastlib.c
                   20315: postlib.o:  postlib.c
                   20316:        cc $(CFLAGS) -c postlib.c
                   20317: sunlib.o: sunlib.c
                   20318:        cc $(CFLAGS) -c sunlib.c
                   20319: myftw.o: myftw.c myftw.h
                   20320:        cc $(CFLAGS) -c myftw.c
                   20321: 0707070035350335411006640007620000050000010556240457561704600000700000001365READMECopy bcp.cpio.z into an empty directory, cd there, and...
                   20322:        unpack bcp.cpio.z
                   20323:        cpio -ic <bcp.cpio
                   20324: If your cpu is not a VAX or your OS is not research UNIX:
                   20325:        edit CPU.h to specify SUN, CRAY, 3B, etc (and specify OS too)
                   20326:        edit makefile to enable SUN, CRAY, 3B, etc compilation options
                   20327: Next, defeat the UNIX file-tree code (later, you may decide you want this; but
                   20328: it seldom ports easily), by taking these steps:
                   20329:        1)  in CPU.h, change this line to:
                   20330:                #define FILE_TREE 0
                   20331:        2)  in makefile, remove all references to Path.c Path.o (this is
                   20332:            spelled out in the comments).
                   20333: Then say:
                   20334:        make
                   20335: and hope for the best, which is a working `bcp'.
                   20336: Bcp.1 and picfile.5 are man pages; print them using `troff -man'.
                   20337: More detailed documentation can be found in source bcp.c.
                   20338: 0707070035351136771006640007620000050000011476110476773366300000600000011432bcp.1.TH BCP 1 
                   20339: .CT 1 graphics
                   20340: .SH NAME
                   20341: bcp \(mi reformat black-and-white picture files
                   20342: .SH SYNOPSIS
                   20343: .B bcp
                   20344: [
                   20345: .I option ...
                   20346: ]
                   20347: [
                   20348: .I file1
                   20349: [
                   20350: .I file2
                   20351: ]
                   20352: ]
                   20353: .SH DESCRIPTION
                   20354: .I Bcp
                   20355: copies black-and-white (B&W) image
                   20356: .I file1
                   20357: to
                   20358: .I file2,
                   20359: optionally changing the file format and transforming the image.
                   20360: If
                   20361: .I file1
                   20362: is a directory name,
                   20363: then every leaf of its file tree is processed in turn; and, in this case,
                   20364: if
                   20365: .I file2
                   20366: also is specified, it is made the root directory
                   20367: of an isomorphic tree of output files.
                   20368: If
                   20369: .I file2
                   20370: is not specified, all output is catenated to stdout.
                   20371: .PP
                   20372: .I Bcp
                   20373: can copy among all the B&W
                   20374: .IR picfile (5)
                   20375: formats, and some others.
                   20376: The default output format is 
                   20377: .BR TYPE=ccitt-g4 .
                   20378: Image transformations include trimming, translation, scaling, and rotation,
                   20379: performed in that order (not in argument order).
                   20380: .PP
                   20381: Input files in
                   20382: .IR picfile (5)
                   20383: format must begin with an ASCII 
                   20384: .BI TYPE= type
                   20385: header line.
                   20386: .I Types
                   20387: supported both as input and output are:
                   20388: .nr xx \w'\fLccitt-g4\ '
                   20389: .TP \n(xxu
                   20390: .B dump
                   20391: One byte/pixel.
                   20392: .B NCHAN=1
                   20393: is required.
                   20394: On input, the grey pixel values are thresholded
                   20395: to B&W;
                   20396: see option
                   20397: .BR -T .
                   20398: On output, black becomes 0 and white 255.
                   20399: .TP
                   20400: .B bitmap
                   20401: One bit/pixel.
                   20402: Essentially Sun rasterfile format, with a
                   20403: .IR picfile (5)
                   20404: header replacing the Sun binary header.
                   20405: .TP
                   20406: .B ccitt-g4
                   20407: CCITT Group 4 FAX encoding, strongly compressive on printed text.
                   20408: Also,
                   20409: .B ccitt-g31
                   20410: (Group 3, 1-dim)
                   20411: and
                   20412: .B ccitt-g32
                   20413: (Group 3, 2-dim; see
                   20414: .BR -k ).
                   20415: .LP
                   20416: Other supported
                   20417: .I types
                   20418: are:
                   20419: .TP \n(xxu
                   20420: .B binary
                   20421: One bit/pixel encoding; obsolescent, but needed for old image archives.
                   20422: Both input and output.
                   20423: .TP
                   20424: .B rle
                   20425: Fast run-length encoding; obsolescent, but needed for old image archives.
                   20426: Input or output, but not both.
                   20427: .TP
                   20428: .B pico
                   20429: Same as
                   20430: .BR dump .
                   20431: Input only.
                   20432: .TP
                   20433: .B cdf
                   20434: `Compound document format', used in AT&T FAX Connection product.
                   20435: Input only.
                   20436: Only the first of multiple pages is read.
                   20437: .LP
                   20438: Other formats not using a 
                   20439: .BI TYPE= type
                   20440: header, are:
                   20441: .IR bitfile (9.5)
                   20442: format;
                   20443: PostScript bitmap format (output only); and
                   20444: Sun rasterfile format (with the Sun binary header; output only).
                   20445: .PP
                   20446: The options are:
                   20447: .TP \n(xxu
                   20448: .B -B[io]
                   20449: Read/write
                   20450: .IR bitfile (9.5)
                   20451: format (no 
                   20452: .BI TYPE= type
                   20453: header).
                   20454: .TP
                   20455: .B -M
                   20456: Write 
                   20457: .B TYPE=bitmap
                   20458: format.
                   20459: .TP
                   20460: .B -P
                   20461: Write Postscript bitmap format (Suns only).
                   20462: .TP
                   20463: .BI -R x , y
                   20464: Force output resolutions to 
                   20465: .I x,y
                   20466: (pixels/inch).
                   20467: If 
                   20468: .BI , y
                   20469: is missing, it is taken to be the same as
                   20470: .I x.
                   20471: Overrides
                   20472: .BI -x x , y .
                   20473: Requires a 
                   20474: .BI RES= "x y
                   20475: line in the header (but, see 
                   20476: .BR -Z ).
                   20477: .TP
                   20478: .B -R=
                   20479: Force the output resolution to be equal to the greater of
                   20480: the input resolutions.
                   20481: .TP
                   20482: .B -S
                   20483: Write Sun rasterfile format (no 
                   20484: .BI TYPE= type
                   20485: header; on Suns only).
                   20486: .TP
                   20487: .BI -T t
                   20488: Threshold.
                   20489: When reading 
                   20490: .BR TYPE=dump ,
                   20491: assign black to grey levels less than
                   20492: .I t,
                   20493: and white to others.
                   20494: Default:
                   20495: .BR -T128 .
                   20496: .TP
                   20497: .BI -Z x , y
                   20498: Force input 
                   20499: .BI RES= "x y.
                   20500: .TP
                   20501: .B -b
                   20502: Write 
                   20503: .B TYPE=binary
                   20504: format.
                   20505: .TP
                   20506: .B -g4
                   20507: .br
                   20508: .ns
                   20509: .TP
                   20510: .B -4
                   20511: Write 
                   20512: .B TYPE=ccitt-g4
                   20513: format.
                   20514: Similarly, 
                   20515: .B -g31
                   20516: or
                   20517: .B -31
                   20518: and 
                   20519: .B -g32
                   20520: or
                   20521: .BR -32 .
                   20522: .TP
                   20523: .BI -k n
                   20524: Set the `k' for 
                   20525: .B ccitt-g32
                   20526: encoding on output (default
                   20527: .BR -k4 ).
                   20528: .TP
                   20529: .BI -o x , y
                   20530: Offset (translate) the image by 
                   20531: .I x,y
                   20532: pixels.
                   20533: The width and height of the picture are not changed.
                   20534: .TP
                   20535: .B -p
                   20536: Write 
                   20537: .B TYPE=dump NCHAN=1
                   20538: format.
                   20539: Map black to 0, white to 255.
                   20540: .TP
                   20541: .B -r
                   20542: Write 
                   20543: .B TYPE=rle
                   20544: format.
                   20545: .TP
                   20546: .B -tl
                   20547: Rotate the image to bring the left edge of the page to the top.
                   20548: Set top-left corner of the rotated
                   20549: image at the top-left corner of the image.
                   20550: .TP
                   20551: .BI -t d
                   20552: Rotate the image 
                   20553: .I d
                   20554: degrees counterclockwise about its center.
                   20555: .I d
                   20556: is a real number.
                   20557: .TP
                   20558: .BI -w l,t,r,b
                   20559: Specify window (trim the image):
                   20560: .I l,t
                   20561: is the left-top corner and 
                   20562: .I r,b
                   20563: the right-bottom corner measured in pixels.
                   20564: If the new margins are outside the original picture,
                   20565: the new area is set to white.
                   20566: An argument given as
                   20567: .L %
                   20568: leaves the edge unchanged.
                   20569: .TP
                   20570: .BI -x x , y
                   20571: Expand/contract (scale) the image, by real factors 
                   20572: .I x
                   20573: and
                   20574: .I y.
                   20575: If
                   20576: .BI , y
                   20577: is missing,
                   20578: .I y
                   20579: is taken to be the same as
                   20580: .I x.
                   20581: May be overridden by 
                   20582: .BI -R x , y.
                   20583: Requires a 
                   20584: .BI RES= "x y
                   20585: line in the header (but, see 
                   20586: .BR -Z ).
                   20587: .SH SEE ALSO
                   20588: .IR cscan (1),
                   20589: .IR imscan (1),
                   20590: .IR ocr (1),
                   20591: .IR pico (1),
                   20592: .IR picfile (5)
                   20593: .br
                   20594: CCITT facsimile coding standards Rec. T.4(1988) and T.6(1988).
                   20595: .SH BUGS
                   20596: Concatenated pages are supported, but only if each new page has a complete
                   20597: header.
                   20598: .br
                   20599: Scaling is accomplished by naive replication/deletion of pixels.
                   20600: .br
                   20601: Rotation by small angles exhibits aliasing effects, and is slow.
                   20602: .br
                   20603: Rotations
                   20604: .B -tr
                   20605: and
                   20606: .B -tb
                   20607: are unfinished.
                   20608: .br
                   20609: CCITT FAX `uncompressed' (or, `transparent') mode is not implemented.
                   20610: .br
                   20611: Postscript output is useful only for small images.
                   20612: .br
                   20613: .BI WINDOW= "l t r b
                   20614: where
                   20615: .I l
                   20616: or
                   20617: .I t
                   20618: is non-zero
                   20619: may not be handled correctly for every combination of file types.
                   20620: .br
                   20621: .B TYPE=rle
                   20622: can't be both input and output.
                   20623: .br
                   20624: Should be merged with T. Duff's
                   20625: .I pcp.
                   20626: 0707070035351137001006640007620000050000010260120476773366300001200000006503picfile.5.TH PICFILE 5
                   20627: .CT 1 inst_info graphics
                   20628: .SH NAME
                   20629: picfile \- raster graphic image format
                   20630: .SH DESCRIPTION
                   20631: Files in this format store images represented as two-dimensional
                   20632: arrays of multiple-channel pixels.
                   20633: A
                   20634: .I picfile
                   20635: consists of an
                   20636: .SM ASCII
                   20637: header followed by binary data encoding the pixels
                   20638: in row-major order.
                   20639: The header is a list of attribute/value pairs
                   20640: separated by newlines, terminated by an
                   20641: empty line.
                   20642: Each header line has the form
                   20643: .IB name = value.
                   20644: The name may not contain an 
                   20645: .SM ASCII NUL,
                   20646: newline or
                   20647: .LR = ;
                   20648: the value may not contain null or newline.
                   20649: The last line of a header is empty.
                   20650: .PP
                   20651: The standard attributes are described below; all but
                   20652: .BR TYPE
                   20653: and
                   20654: .BR WINDOW
                   20655: are optional.
                   20656: .B TYPE
                   20657: must come first; otherwise order is irrelevant.
                   20658: As any unrecognised attribute is passed over uninterpreted by all standard software,
                   20659: applications are welcome to include arbitrary annotations, like
                   20660: .BR SHOESIZE=10 ,
                   20661: if they wish.
                   20662: .TP
                   20663: .BI TYPE= type
                   20664: How the pixels are encoded.
                   20665: Standard types are
                   20666: .PD 0
                   20667: .RS
                   20668: .TF runcode
                   20669: .TP
                   20670: .B runcode
                   20671: A run-length encoding.
                   20672: The data are a sequence of
                   20673: .RI ( nchan +1)-byte
                   20674: records each containing a count
                   20675: .I k
                   20676: and
                   20677: .I nchan
                   20678: bytes giving a pixel value to be repeated
                   20679: .IR k +1
                   20680: times.
                   20681: A run may not span scanlines.
                   20682: .TP
                   20683: .B dump
                   20684: A two-dimensional array of
                   20685: .IR nchan -byte
                   20686: records in row major order.
                   20687: .TP
                   20688: .B bitmap
                   20689: One-bit pixels, packed into bytes high bit leftmost.
                   20690: Zero bits are white, one bits are black.
                   20691: Rows are padded with zeros to a multiple of 16 bits.
                   20692: .TP
                   20693: .B ccitt-g4
                   20694: A black-and-white image under CCITT FAX Group 4 compression.
                   20695: This format is highly compressive on images of text and line art.
                   20696: Similarly,
                   20697: .L ccitt-g31
                   20698: and
                   20699: .L ccitt-g32
                   20700: for Group 3, 1-D and 2-D.
                   20701: .TP
                   20702: .B pico
                   20703: A sequence of
                   20704: .I nchan
                   20705: two-dimensional arrays of single bytes.
                   20706: .TP
                   20707: .B ccir601
                   20708: Pixels are in dump order, 2 bytes per pixel
                   20709: encoded according to the IEEE digital component video standard.
                   20710: .RE
                   20711: .TP
                   20712: .BI WINDOW= "x0 y0 x1 y1
                   20713: The 
                   20714: .I x,y
                   20715: coordinates of the upper left corner and
                   20716: the point just diagonally outside the lower right corner,
                   20717: .I x
                   20718: increasing to the right,
                   20719: .I y
                   20720: down.
                   20721: .TP
                   20722: .BI NCHAN= nchan
                   20723: The number of channels, default 1.
                   20724: .TP
                   20725: .BI CHAN= value
                   20726: The order of channels. 
                   20727: .TP
                   20728: .BI RES= "x y
                   20729: The digitizing resolution horizontally and vertically, in pixels/inch.
                   20730: .PD
                   20731: .TP
                   20732: .B CMAP=
                   20733: (The value is empty.)
                   20734: A color map, a 256\(mu3-byte translation table for
                   20735: color values, follows the header.
                   20736: In a full-color picture, each color-map row maps pixel
                   20737: values of the corresponding channel.
                   20738: In a monochrome picture, pixel values index
                   20739: the color map to yield red, green and blue, like this:
                   20740: .IP
                   20741: .EX
                   20742: unsigned char cmap[256][3];
                   20743: red=cmap[pixel][0];
                   20744: green=cmap[pixel][1];
                   20745: blue=cmap[pixel][2];
                   20746: .EE
                   20747: .SH EXAMPLES
                   20748: .TP
                   20749: .B sed '/^$/q' image
                   20750: Print a header.
                   20751: A sample header follows.
                   20752: .LP
                   20753: .EX
                   20754: TYPE=dump
                   20755: WINDOW=0 0 512 512
                   20756: NCHAN=1
                   20757: CHAN=m
                   20758: RES=300 300
                   20759: CMAP=
                   20760: COMMAND= antiquantize 'halftone CLASSIC' 512.halftone LIBERTY.anticlassic 
                   20761: COMMAND=  halftone CLASSIC 512.liberty 512.halftone 1.75 512.halftone 
                   20762: COMMAND=   transpose IN OUT 
                   20763: COMMAND=    resample 512 IN OUT 
                   20764: COMMAND=     transpose IN OUT 
                   20765: COMMAND=      resample 512 IN OUT 
                   20766: COMMAND=       clip 400 400 LIBERTY OUT
                   20767: .EE
                   20768: .SH "SEE ALSO"
                   20769: .IR bcp (1),
                   20770: .IR cscan (1),
                   20771: .IR imscan (1),
                   20772: .IR pico (1), 
                   20773: .IR flicks (9.1), 
                   20774: .IR mugs
                   20775: in
                   20776: .IR face (9.7), 
                   20777: .IR rebecca (9.1),
                   20778: .IR flickfile (9.5)
                   20779: .br
                   20780: T. Duff,
                   20781: `The 10th Edition Raster Graphics System',
                   20782: this manual, Volume\ 2
                   20783: 0707070035351137001006640007620000050000010260120476773366300001300000000000TRAILER!!!,
                   20784: .IR flickfile (9.5)
                   20785: .br
                   20786: T. Duff,
                   20787: `The 10th Edition Raster Graphics System',
                   20788: this manual, Volume\ 2
                   20789: 0707070035351137001006640007620000050000010260120476773366300001300000000000TRAILER!!!,
                   20790: .IR flickfile (9.5)
                   20791: .br
                   20792: T. Duff,
                   20793: `The 10th Edition Raster Graphics System',
                   20794: this manual, Volume\ 2
                   20795: 07070700353511370010066400076200000

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.