Annotation of researchv10no/cmd/bcp/bcp.cpio, revision 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.