Annotation of researchv10no/cmd/bcp/CCITT.c, revision 1.1.1.1

1.1       root        1: /* 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: /* CCITT.c - functions for CCITT compression/decompression of binary images.
                      8:    The following discussion is a summary of CCITT Recommendations T.4 and T.6
                      9: on facsimile coding schemes and coding control functions for Group 3 and Group
                     10: 4 facsimile apparatus (drafted at Malaga-Torremolinos, 1984).  They describe
                     11: algorithms for invertible (lossless) compression and decompression of bilevel
                     12: (black-and-white, not grey) 2D rectangular images of arbitrary height and
                     13: width.  By convention the images are processed top-down, one horizontal scan
                     14: line at a time.  It is not strictly necessary to know the height of an image
                     15: before starting compression or decompression.  Width, however, must be known
                     16: in advance in some cases (discussed below), and must remain constant for the
                     17: whole image in all cases.  There are three distinct but intimately related
                     18: standards:  Group 3 1-dimensional, Group 3 2-dimensional, and Group 4.
                     19: VLSI hardware implementations always include all three.  The Group 3 encodings
                     20: are used in the vast installed base of FAX machines.  Group 4 is not used
                     21: in today's FAX machines, but seems to be the default standard in document image
                     22: archiving applications.
                     23:        The CCITT Group 3 FAX standard permits either 1-D or 2-D encoding.
                     24: It is not easy to tell from an encoding which was used.  Both 1-D and 2-D
                     25: assume fixed scanline length (in pixels), which must be known at encoding time.
                     26:        Group 3 1-D (g31) code uses fixed ``modified Huffman'' codes for
                     27: run-lengths, with two different code tables for black and white runs.  Each
                     28: line is assumed to begin with a (possibly 0-length) white run.  Of course,
                     29: the colors strictly alternate.  An empty (all-white) line is supposed to be
                     30: spelled out with a full pixel count, although some decoders won't complain
                     31: if just a 0-length count is used.  There are provisions for fill bits at the
                     32: end of lines to allow slow receiving equipment to keep up.  Each line ends with
                     33: an EOL code on which it may be possible to synchronize after transmission error.
                     34:        Group 3 2-D (g32) encoding tries to exploit the slowly-changing nature
                     35: of artwork from line to line.  It is a mixture of 1-D-coded lines and
                     36: ``2-D''-coded lines describing small local changes relative to the immediately
                     37: prior ``reference'' line.  1-D coding recurs every few (`k') lines, so that
                     38: resynchronization is frequently possible.  K is usually 2 or 4, but the
                     39: standard permits any number, even infinity, since the coding method used on
                     40: a line is specified by which of two special EOLx codes is used to end the
                     41: prior line.
                     42:        CCITT Group 4 (g4) is like Group 3 2-D, but optimized to take advantage
                     43: of a lossless communications channel or reliable storage medium (such as computer
                     44: memory), where resynchronization is unnecessary.  Thus the first line is 2-D
                     45: encoded referenced to an imaginary initial blank line, k is always infinity,
                     46: and EOL's are not used at all.  It essential that the line-length be known in
                     47: advance of both encoding and decoding, so that line-breaks can be triggered when
                     48: that length is exceeded.  End of FAX buffer (end of page) is signaled by a
                     49: special EOFB code.
                     50:    On images of printed text and sparse line-graphics, g4-compressed files
                     51: are often 15-40X smaller than bitmap (packed bits), 5X than bitfile(9.5),
                     52: 2X than g31, and 2X than rle | pack.
                     53: PERFORMANCE
                     54:    On 10 printed A4 pages (business letters, technical reports, etc),
                     55: at a resolution of 400 dpi:
                     56:        binary:         2020 Kbytes     CPU secs (to compress binary)
                     57:         pack:           200 - 380      17
                     58:        bitfile(9.5):    150 - 360       ?
                     59:        rle:             100 - 230       7.5
                     60:         compress:        90 - 155      14
                     61:        g31:              85 - 190      13
                     62:        g32:              55 - 110      13
                     63:        g4:               30 -  70      13
                     64:    G4-compressed files are 15-40X smaller than binary, 5X than bitfile(9.5),
                     65: 3.5X than rle, 2X than g31, and 2X than rle | pack.
                     66: */
                     67: 
                     68: #include <stdio.h>
                     69: #include <string.h>
                     70: #include <ctype.h>
                     71: #include "CPU.h"
                     72: #include "stdocr.h"
                     73: #include "rle.h"
                     74: #include "bitio.h"
                     75: #include "CCITT.h"
                     76: 
                     77: #define DEBUG 0                /* 0 disables compilation of all debugging code;
                     78:                           1 compiles, but must enable particular parts below */
                     79: #define NEW_TRAIL 1    /* enable new trailing-0 counts (has passed early tests) */
                     80: #define dbg_trail 0
                     81: 
                     82: DST_table *ccitt_table()
                     83: {   DST_context cx;
                     84:        if((cx.t = (DST_table *)malloc(sizeof(DST_table)))==NULL)
                     85:                abort("CCITT.c: build_tbl: can't alloc cx.t");
                     86:        /* All tables have e[DST_white], e[DST_black], & e[DST_2d] entries */
                     87:        cx.t->mny=3;
                     88:        if((cx.t->e=(DST_entry *)malloc(cx.t->mny*sizeof(DST_entry)))==NULL)
                     89:                abort("CCITT.c: build_tbl: can't alloc cx.t->e[%d]",cx.t->mny);
                     90: 
                     91:        cx.s = cx.c = DST_white;
                     92:        cx.l = 0;
                     93:        cx.t->e[cx.s].p[0] = '\0';
                     94:        cx.t->e[cx.s].l = 0;
                     95:        cx.t->e[cx.s].z = 0;
                     96:        build_transits(cx);
                     97: 
                     98:        cx.s = cx.c = DST_black;
                     99:        cx.l = 0;
                    100:        cx.t->e[cx.s].p[0] = '\0';
                    101:        cx.t->e[cx.s].l = 0;
                    102:        cx.t->e[cx.s].z = 0;
                    103:        build_transits(cx);
                    104: 
                    105:        cx.s = cx.c = DST_2d;
                    106:        cx.l = 0;
                    107:        cx.t->e[cx.s].p[0] = '\0';
                    108:        cx.t->e[cx.s].l = 0;
                    109:        cx.t->e[cx.s].z = 0;
                    110:        build_transits(cx);
                    111: 
                    112: #if DEBUG
                    113:        if(F) ccitt_err_tbl(cx.t);
                    114: #endif
                    115:        return(cx.t);
                    116:        }
                    117: 
                    118: DST_state new_state(t)
                    119:    DST_table *t;
                    120: {      t->mny++;
                    121:        if((t->e=(DST_entry *)realloc(t->e,t->mny*sizeof(DST_entry)))==NULL)
                    122:                abort("can't realloc t->[%d]",t->mny);
                    123:        return(t->mny-1);
                    124:        }
                    125: 
                    126: /* The entry described by `cx' exists in the table, and its prefix `p' is
                    127:    setup; create its transitions, and their next entries, recursively.  */
                    128: build_transits(cx)
                    129:     DST_context cx;
                    130: #define entry cx.t->e[cx.s]
                    131: #define transit entry.t[col]
                    132: {   DST_color col;
                    133:     DST_entry ne;      /* next entry */
                    134:     DST_context ncx;   /* next Context */
                    135:     char **s,**ss;     /* for searching code */
                    136:     short *c,*cs;
                    137:     int si,matching,longer;
                    138:     char svch,col_str[2];
                    139:        switch(cx.c) {
                    140:            case DST_white:
                    141:                ss=codewht;
                    142:                cs=bitcwht;
                    143:                break;
                    144:            case DST_black:
                    145:                ss=codeblk;
                    146:                cs=bitcblk;
                    147:                break;
                    148:            case DST_2d:
                    149:                ss=code2d;
                    150:                cs=bitc2d;
                    151:                break;
                    152:            };
                    153:        for(col=0;col<=1;col++) {
                    154:                sprintf(col_str,"%1d",col);
                    155:                ncx = cx;  ncx.l++; 
                    156:                /* build a transition */
                    157:                strcpy(ne.p,entry.p); strcat(ne.p,col_str);
                    158:                ne.l = ncx.l;
                    159:                if(col==0) ne.z = entry.z+1; else ne.z = 0;
                    160:                /* count those that match new prefix */
                    161:                longer=matching=0;
                    162:                for(s=ss,c=cs,si=0; (*s)!=NULL; s++,c++,si++) {
                    163:                        if(*c==ncx.l) {
                    164:                                if(strcmp(*s,ne.p)==0) {
                    165:                                        matching++;
                    166:                                        switch(cx.c) {
                    167:                                            case DST_white:
                    168:                                            case DST_black:
                    169:                                                transit.a = itor(si);
                    170:                                                break;
                    171:                                            case DST_2d:
                    172:                                                transit.a = si;
                    173:                                                break;
                    174:                                            };
                    175:                                        };
                    176:                                }
                    177:                        else if(*c>ncx.l) {
                    178:                                svch=(*s)[ncx.l]; (*s)[ncx.l] = '\0';
                    179:                                if(strcmp(*s,ne.p)==0) {
                    180:                                        longer++;
                    181:                                        };
                    182:                                (*s)[ncx.l]=svch;
                    183:                                };
                    184:                        };
                    185:                /* analyze results */
                    186:                if(matching==0&&longer>0) {
                    187:                        /* no match yet; go deeper */
                    188:                        transit.a = DST_action_NULL;
                    189:                        ncx.s = transit.s = new_state(cx.t);
                    190:                        strcpy(cx.t->e[ncx.s].p,ne.p);
                    191:                        cx.t->e[ncx.s].l = ne.l;
                    192:                        cx.t->e[ncx.s].z = ne.z;
                    193:                        build_transits(ncx);
                    194:                        }
                    195:                else if(matching==1&&longer==0) {
                    196:                        /* unique leaf: good */
                    197:                        /* picked up action earlier */
                    198:                        switch(cx.c) {
                    199:                            case DST_white:
                    200:                            case DST_black:
                    201:                                if(transit.a<=63) /* termination code */
                    202:                                        transit.s = flip_color(cx.c); 
                    203:                                else /* makeup code */
                    204:                                        transit.s = cx.c;
                    205:                                break;
                    206:                            case DST_2d:
                    207:                                /* legal end of code */
                    208:                                transit.s = DST_state_NULL;
                    209:                                break;
                    210:                            };
                    211:                        }
                    212:                else {  /* illegal transition */
                    213:                        transit.a = DST_action_ERROR;
                    214:                        transit.s = DST_state_NULL;
                    215:                        };
                    216:                };
                    217:        }
                    218: 
                    219: ccitt_err_tbl(t)
                    220:     DST_table *t;
                    221: {   int d;
                    222:        ccitt_err_state(DST_white,t);
                    223:        ccitt_err_state(DST_black,t);
                    224:        ccitt_err_state(DST_2d,t);
                    225:        }
                    226: 
                    227: ccitt_err_state(s,t)
                    228:     DST_state s;
                    229:     DST_table *t;
                    230: {      err("%03d %s %2d %2d%*s %d %03d,%-4d  %d %03d,%-4d",
                    231:                        s,t->e[s].p,t->e[s].l,t->e[s].z,14-strlen(t->e[s].p)," ",
                    232:                        0,t->e[s].t[0].s,t->e[s].t[0].a,
                    233:                        1,t->e[s].t[1].s,t->e[s].t[1].a
                    234:                        );
                    235:        if(t->e[s].t[0].s>1) ccitt_err_state(t->e[s].t[0].s,t);
                    236:        if(t->e[s].t[1].s>1) ccitt_err_state(t->e[s].t[1].s,t);
                    237:        }
                    238: 
                    239: /* Translate a stream of bits in CCITT FAX Group 3 (1-D) compression format
                    240:    into a sequence of RLE_Lines.  Returns one (RLE_Line *) on each call (or NULL
                    241:    if EOF or error).  The first pixel (black or white) in each g31 line is
                    242:    assigned run index 0. */
                    243: RLE_Line *g31_to_rlel(t,f,bof)
                    244:     DST_table *t;
                    245:     BITFILE *f;
                    246:     boolean bof;       /* beginning of file */
                    247: #define dbg_g31r_r (0) /* trace each run/EOL/ERR_SYN */
                    248: #define dbg_g31r_c (0) /* trace each Huffman code (or, fill+EOL)*/
                    249: #define dbg_g31r_t (0) /* trace each state-transition */
                    250: {   static DST_context cx;
                    251:     static RLE_Line rl;
                    252:     static RLE_Run *r; /* prior, current runs */
                    253:     int run,biti,sync,si,bitv;
                    254:     boolean fill;
                    255: /* color of 1st run in each line */
                    256: #define g31_first_color DST_white
                    257: /* reverse Black/White in output image */
                    258: #define g31_negative 0
                    259:        if(bof){if(T) { /* sync by skipping initial FILL & EOL code */
                    260:                        sync=0;  while((bitv=getb(f))==0) sync++;
                    261:                        if(bitv!=1||sync<11) {
                    262: #if DEBUG
                    263:                                if(dbg_g31r_c) {
                    264:                                        fprintf(stderr,"BOF_ERR ");
                    265:                                        for(si=0;si<sync;si++) fprintf(stderr,"0");
                    266:                                        if(bitv==1) fprintf(stderr,"1\n");
                    267:                                        else fprintf(stderr,"?\n");
                    268:                                        };
                    269: #endif
                    270:                                return(NULL);
                    271:                                }
                    272: #if DEBUG
                    273:                        else if(dbg_g31r_c){
                    274:                                fprintf(stderr,"BOF_EOL ");
                    275:                                for(si=0;si<sync;si++) fprintf(stderr,"0");
                    276:                                fprintf(stderr,"1\n");
                    277:                                };
                    278: #endif
                    279:                        };
                    280:                /* start file expecting a run-code of a fixed color */
                    281:                cx.s = cx.c = g31_first_color;
                    282:                rl.y = -1;      /* assume first line is y==0 */
                    283:                };
                    284:        rl.y++;  rl.runs=0;  r = rl.r;  biti=run=0;
                    285:        while(T) switch(getb(f)) {
                    286:            case 0 :  /* next bit is 0 */
                    287:                switch(t->e[cx.s].t[0].a) {
                    288:                    case DST_action_ERROR:
                    289:                        /* bad code: try to resynchronize */
                    290: #if DEBUG
                    291:                        if(dbg_g31r_t){
                    292:                                fprintf(stderr,"%s %04d  %s0?...\n",
                    293:                                        (cx.c==DST_white)? "W": "B",
                    294:                                        t->e[cx.s].t[0].s,
                    295:                                        t->e[cx.s].p);
                    296:                                };
                    297: #endif
                    298:                        /* count trailing 0's so far (should be in table) */
                    299: #if !NEW_TRAIL
                    300:                        sync=1;
                    301:                        si=strlen(t->e[cx.s].p)-1;
                    302:                        while(si>=0&&t->e[cx.s].p[si]=='0') {sync++; si--;};
                    303:                        fill = (si<0);  /* all 0's:  may be fill bits */
                    304: #else
                    305:                        sync=t->e[cx.s].z+1;
                    306:                        fill = (sync>t->e[cx.s].l); /* all 0's:  maybe fill bits */
                    307: #endif
                    308: #if DEBUG
                    309:                        if(dbg_trail) err("sync %d fill %d",sync,fill);
                    310:                        if(dbg_g31r_c)fprintf(stderr,"ERR_SYN %s0?",t->e[cx.s].p);
                    311: #endif
                    312:                        while(sync<11) {
                    313:                                switch(bitv=getb(f)) {
                    314:                                        case 0:  sync++;
                    315: #if DEBUG
                    316:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                    317: #endif
                    318:                                                break;
                    319:                                        case 1:  sync=0;  fill=F;
                    320: #if DEBUG
                    321:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                    322: #endif
                    323:                                                break;
                    324:                                        case EOF:
                    325: #if DEBUG
                    326:                                                if(dbg_g31r_c) fprintf(stderr,"<EOF>\n");
                    327: #endif
                    328:                                                return(NULL);  break;
                    329:                                        };
                    330:                                };
                    331:                        /* next `1' will synchronize */
                    332:                        do {    switch(bitv=getb(f)) {
                    333:                                        case 0:
                    334: #if DEBUG
                    335:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                    336: #endif
                    337:                                                break;
                    338:                                        case 1:
                    339: #if DEBUG
                    340:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                    341: #endif
                    342:                                                break;
                    343:                                        case EOF:
                    344: #if DEBUG
                    345:                                                if(dbg_g31r_c) fprintf(stderr,"<EOF>\n");
                    346: #endif
                    347:                                                return(NULL);  break;
                    348:                                        };
                    349:                                }
                    350:                        while(bitv!=1);
                    351: #if DEBUG
                    352:                        if(dbg_g31r_c) fprintf(stderr,"\n");
                    353:                        if(dbg_g31r_r) {
                    354:                                if(fill) fprintf(stderr,"FILL_EOL\n");
                    355:                                else fprintf(stderr,"ERR_SYN_EOL\n");
                    356:                                };
                    357: #endif
                    358:                        /* start next line expecting a run-code of a fixed color */
                    359:                        cx.s = cx.c = g31_first_color;
                    360:                        return(&rl);
                    361:                        break;
                    362:                    case DST_action_NULL:
                    363: #if DEBUG
                    364:                        if(dbg_g31r_t)fprintf(stderr,"%s %04d  %s0\n",
                    365:                                (cx.c==DST_white)? "W": "B",
                    366:                                t->e[cx.s].t[0].s,
                    367:                                t->e[cx.s].p);
                    368: #endif
                    369:                        cx.s = t->e[cx.s].t[0].s;
                    370:                        break;
                    371:                    case DST_EOL:
                    372: #if DEBUG
                    373:                        if(dbg_g31r_c)fprintf(stderr,"EOL     %s0\n",
                    374:                                t->e[cx.s].p);
                    375:                        if(dbg_g31r_r)fprintf(stderr,"EOL\n");
                    376: #endif
                    377:                        /* start next line expecting a run-code of a fixed color */
                    378:                        cx.s = cx.c = g31_first_color;
                    379:                        return(&rl);
                    380:                        break;
                    381:                    default:
                    382: #if DEBUG
                    383:                        if(dbg_g31r_c)fprintf(stderr,"%s%6d %s0\n",
                    384:                                (cx.c==DST_white)? "W": "B",
                    385:                                t->e[cx.s].t[0].a,
                    386:                                t->e[cx.s].p);
                    387: #endif
                    388:                        if(t->e[cx.s].t[0].a<=63) {
                    389:                                run += t->e[cx.s].t[0].a;
                    390: #if DEBUG
                    391:                                if(dbg_g31r_r)fprintf(stderr,"%s%6d\n",
                    392:                                        (cx.c==DST_white)? "W": "B",
                    393:                                        run);
                    394: #endif
                    395:                                biti += run;
                    396:                                if(cx.c==DST_black^g31_negative) {
                    397:                                        /* end of black run */
                    398:                                        r->xe = biti-1;
                    399:                                        r++; rl.runs++;
                    400:                                        }
                    401:                                else {  /* end of white run */
                    402:                                        r->xs = biti;
                    403:                                        };
                    404:                                cx.c = flip_color(cx.c);
                    405:                                run = 0;
                    406:                                }
                    407:                        else run += t->e[cx.s].t[0].a;
                    408:                        cx.s = t->e[cx.s].t[0].s;
                    409:                        break;
                    410:                    };
                    411:                break;
                    412:            case 1:  /* next bit is 1 */
                    413:                switch(t->e[cx.s].t[1].a) {
                    414:                    case DST_action_ERROR:
                    415:                        /* bad code: try to resynchronize */
                    416: #if DEBUG
                    417:                        if(dbg_g31r_t){
                    418:                                fprintf(stderr,"%s %04d  %s1?...\n",
                    419:                                        (cx.c==DST_white)? "W": "B",
                    420:                                        t->e[cx.s].t[1].s,
                    421:                                        t->e[cx.s].p);
                    422:                                };
                    423:                        if(dbg_g31r_c)fprintf(stderr,"ERR_SYN %s1?",t->e[cx.s].p);
                    424: #endif
                    425:                        /* no trailing 0's; can't be fill bits */
                    426:                        sync=0;
                    427:                        while(sync<11) {
                    428:                                switch(bitv=getb(f)) {
                    429:                                        case 0:  sync++;
                    430: #if DEBUG
                    431:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                    432: #endif
                    433:                                                break;
                    434:                                        case 1:  sync=0;
                    435: #if DEBUG
                    436:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                    437: #endif
                    438:                                                break;
                    439:                                        case EOF:
                    440: #if DEBUG
                    441:                                                if(dbg_g31r_c)
                    442:                                                        fprintf(stderr,"<EOF>\n");
                    443: #endif
                    444:                                                return(NULL);  break;
                    445:                                        };
                    446:                                };
                    447:                        /* next `1' will synchronize */
                    448:                        do {    switch(bitv=getb(f)) {
                    449:                                        case 0:
                    450: #if DEBUG
                    451:                                                if(dbg_g31r_c) fprintf(stderr,"0");
                    452: #endif
                    453:                                                break;
                    454:                                        case 1:
                    455: #if DEBUG
                    456:                                                if(dbg_g31r_c) fprintf(stderr,"1");
                    457: #endif
                    458:                                                break;
                    459:                                        case EOF:
                    460: #if DEBUG
                    461:                                                if(dbg_g31r_c)
                    462:                                                        fprintf(stderr,"<EOF>\n");
                    463: #endif
                    464:                                                return(NULL);  break;
                    465:                                        };
                    466:                                }
                    467:                        while(bitv!=1);
                    468: #if DEBUG
                    469:                        if(dbg_g31r_c) fprintf(stderr,"\n");
                    470:                        if(dbg_g31r_r) fprintf(stderr,"ERR_SYN_EOL\n");
                    471: #endif
                    472:                        /* start next line expecting a run-code of a fixed color */
                    473:                        cx.s = cx.c = g31_first_color;
                    474:                        return(&rl);
                    475:                        break;
                    476:                    case DST_action_NULL:
                    477: #if DEBUG
                    478:                        if(dbg_g31r_t)fprintf(stderr,"%s %04d  %s1\n",
                    479:                                (cx.c==DST_white)? "W": "B",
                    480:                                t->e[cx.s].t[1].s,
                    481:                                t->e[cx.s].p);
                    482: #endif
                    483:                        cx.s = t->e[cx.s].t[1].s;
                    484:                        break;
                    485:                    case DST_EOL:
                    486: #if DEBUG
                    487:                        if(dbg_g31r_c)fprintf(stderr,"EOL     %s1\n",
                    488:                                t->e[cx.s].p);
                    489:                        if(dbg_g31r_r)fprintf(stderr,"EOL\n");
                    490: #endif
                    491:                        /* start next line expecting a run-code of a fixed color */
                    492:                        cx.s = cx.c = g31_first_color;
                    493:                        return(&rl);
                    494:                        break;
                    495:                    default:
                    496: #if DEBUG
                    497:                        if(dbg_g31r_c)fprintf(stderr,"%s%6d %s1\n",
                    498:                                (cx.c==DST_white)? "W": "B",
                    499:                                t->e[cx.s].t[1].a,
                    500:                                t->e[cx.s].p);
                    501: #endif
                    502:                        if(t->e[cx.s].t[1].a<=63) {
                    503:                                run += t->e[cx.s].t[1].a;
                    504: #if DEBUG
                    505:                                if(dbg_g31r_r)fprintf(stderr,"%s%6d\n",
                    506:                                        (cx.c==DST_white)? "W": "B",
                    507:                                        run);
                    508: #endif
                    509:                                biti += run;
                    510:                                if(cx.c==DST_black^g31_negative) {
                    511:                                        /* end of black run */
                    512:                                        r->xe = biti-1;
                    513:                                        r++; rl.runs++;
                    514:                                        }
                    515:                                else {  /* end of white run */
                    516:                                        r->xs = biti;
                    517:                                        };
                    518:                                cx.c = flip_color(cx.c);
                    519:                                run = 0;
                    520:                                }
                    521:                        else run += t->e[cx.s].t[1].a;
                    522:                        cx.s = t->e[cx.s].t[1].s;
                    523:                        break;
                    524:                    };
                    525:                break;
                    526:            case EOF:
                    527:                return(NULL);
                    528:                break;
                    529:            default:
                    530:                return(NULL);
                    531:                break;
                    532:            };
                    533:        /* never come here:  return() variously from cases above */
                    534:        }
                    535: 
                    536: /* Translate a sequence of RLE_Line's (describing a binary image)
                    537:    into a file (a stream of bits) in CCITT FAX Group 3 (1-D) compression format.
                    538:    BOF_to_g31() must be called first; then call rlel_to_g31() for each line
                    539:    (including blank lines); finally, EOF_to_g31() must be called.  Each line's
                    540:    EOL and the RTC's first EOL are padded so they end on a byte boundary.
                    541:    */
                    542: /* debugging flags:  trace to stderr */
                    543: #define dbg_rg31_e (0) /* entry */
                    544: #define dbg_rg31_r (0) /* runs */
                    545: #define dbg_rg31_s (0) /* bitstrings */
                    546: 
                    547: #if DEBUG
                    548: #define bits_g31(bits) { \
                    549:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                    550:        if(dbg_rg31_s) fprintf(stderr,"%s",(bits)); \
                    551:        if(dbg_rg31_r) fprintf(stderr," "); \
                    552:        }
                    553: #define EOL_g31 { \
                    554:        if(dbg_rg31_r) fprintf(stderr,"EOL     "); \
                    555:        bits_g31(EOLSTRING); \
                    556:        if(dbg_rg31_r) fprintf(stderr,"\n"); \
                    557:        }
                    558: #else
                    559: #define bits_g31(bits) { \
                    560:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                    561:        }
                    562: #define EOL_g31 { \
                    563:        bits_g31(EOLSTRING); \
                    564:        }
                    565: #endif
                    566: 
                    567: BOF_to_g31(f)
                    568:     BITFILE *f;        /* state of output bitfile */
                    569: {   char *cs;
                    570:        EOL_g31;
                    571:        }
                    572: 
                    573: rlel_to_g31(rl,wid,f)
                    574:     RLE_Line *rl;      /* line of runs:  if NULL, then blank */
                    575:     int wid;           /* width of an output line in pixels */
                    576:     BITFILE *f;                /* state of output bitfile */
                    577: {   int pi;            /* input pixel index on line */
                    578:     RLE_Run *rp,*pp,*sp;
                    579:     int runl,codi;
                    580:     char *cs,*p01;
                    581: #if DEBUG
                    582: #define Wrun_g31(rn) { \
                    583:        runl=(rn); \
                    584:        if(dbg_rg31_r) fprintf(stderr,"W %5d ",runl); \
                    585:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                    586:        p01=codewht[codi=rtoi(runl)]; bits_g31(p01); \
                    587:        if(codi>=64) {p01=codewht[runl%64]; bits_g31(p01);}; \
                    588:        if(dbg_rg31_r) fprintf(stderr,"\n"); \
                    589:        }
                    590: #else
                    591: #define Wrun_g31(rn) { \
                    592:        runl=(rn); \
                    593:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                    594:        p01=codewht[codi=rtoi(runl)]; bits_g31(p01); \
                    595:        if(codi>=64) {p01=codewht[runl%64]; bits_g31(p01);}; \
                    596:        }
                    597: #endif
                    598: #if DEBUG
                    599: #define Brun_g31(rn) { \
                    600:        runl=(rn); \
                    601:        if(dbg_rg31_r) fprintf(stderr,"B %5d ",runl); \
                    602:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                    603:        p01=codeblk[codi=rtoi(runl)]; bits_g31(p01); \
                    604:        if(codi>=64) {p01=codeblk[runl%64]; bits_g31(p01);}; \
                    605:        if(dbg_rg31_r) fprintf(stderr,"\n"); \
                    606:        }
                    607: 
                    608: #else
                    609: #define Brun_g31(rn) { \
                    610:        runl=(rn); \
                    611:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g31(p01); runl-=2560;}; \
                    612:        p01=codeblk[codi=rtoi(runl)]; bits_g31(p01); \
                    613:        if(codi>=64) {p01=codeblk[runl%64]; bits_g31(p01);}; \
                    614:        }
                    615: #endif
                    616: #if DEBUG
                    617:        if(dbg_rg31_e) err("rlel_to_g31(rl[y%d,r%d])",rl->y,rl->runs);
                    618: #endif
                    619:        if(rl!=NULL&&rl->runs>0) {
                    620:                pi=0;   /* bit to write next */
                    621: #if DEBUG
                    622:                if(dbg_rg31_e) err("rlel_to_g31(rl[y%d,r%d])",rl->y,rl->runs);
                    623: #endif
                    624:                for(sp=(rp=rl->r)+rl->runs; rp<sp; rp++) {
                    625:                        Wrun_g31(rp->xs-pi);  pi=rp->xs;
                    626:                        Brun_g31(rp->xe-pi+1);  pi=rp->xe+1;
                    627:                        };
                    628:                if((--rp)->xe+1<wid) Wrun_g31(wid-rp->xe-1);
                    629:                }
                    630:        else {  
                    631: #if DEBUG
                    632:                if(dbg_rg31_e) err("rlel_to_g31(rl[y?,r0])");
                    633: #endif
                    634:                Wrun_g31(wid);  /* blank (all-white) scanline */
                    635:                };
                    636:        /* fill so that EOL ends on byte boundary */
                    637:        padb(f,0,8,EOLLENGTH);
                    638: #if DEBUG
                    639:        if(dbg_rg31_s) fprintf(stderr,"+0?");
                    640: #endif
                    641:        EOL_g31;
                    642:        }
                    643: 
                    644: EOF_to_g31(f)
                    645:     BITFILE *f;
                    646: {   char *cs;
                    647:        /* fill so that EOL ends on byte boundary */
                    648:        padb(f,0,8,EOLLENGTH);
                    649: #if DEBUG
                    650:        if(dbg_rg31_s) fprintf(stderr,"+0?");
                    651: #endif
                    652:        /* write RTC */
                    653:        EOL_g31;
                    654:        EOL_g31;
                    655:        EOL_g31;
                    656:        EOL_g31;
                    657:        EOL_g31;
                    658:        EOL_g31;
                    659:        }
                    660: 
                    661: /* Macro for use within g32_to_rlel, to read one 1-D Modified Huffman coded
                    662:    run-length of a given color, placing the result in a given variable.
                    663:    Exceptionally, goto trap_eol, trap_eof, or trap_code_err.
                    664:   */
                    665: #if DEBUG
                    666: #define g32_1d_run(C,V) { \
                    667:        run = 0; \
                    668:        do {    cx.tr.s = (C); \
                    669:                do {    px = cx; \
                    670:                        switch(bitv=getb(f)) { \
                    671:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                    672:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                    673:                            case EOF :  goto trap_eof;  break; \
                    674:                            }; \
                    675:                        } \
                    676:                while(cx.tr.a==DST_action_NULL); \
                    677:                switch(cx.tr.a) { \
                    678:                    case DST_EOL : \
                    679:                        if(dbg_g32r_c)fprintf(stderr,"EOL     %s\n",EOLSTRING); \
                    680:                        goto trap_eol; \
                    681:                        break; \
                    682:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                    683:                    default : \
                    684:                        if(dbg_g32r_c)fprintf(stderr,"%s%6d %s%d\n", \
                    685:                                ((C)==DST_white)? "W": "B", \
                    686:                                cx.tr.a, \
                    687:                                t->e[px.tr.s].p, \
                    688:                                bitv); \
                    689:                        run += cx.tr.a; \
                    690:                        break; \
                    691:                    }; \
                    692:                } \
                    693:        while(cx.tr.a>63); \
                    694:        (V) = run; \
                    695:        }
                    696: #else
                    697: #define g32_1d_run(C,V) { \
                    698:        run = 0; \
                    699:        do {    cx.tr.s = (C); \
                    700:                do {    px = cx; \
                    701:                        switch(bitv=getb(f)) { \
                    702:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                    703:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                    704:                            case EOF :  goto trap_eof;  break; \
                    705:                            }; \
                    706:                        } \
                    707:                while(cx.tr.a==DST_action_NULL); \
                    708:                switch(cx.tr.a) { \
                    709:                    case DST_EOL : \
                    710:                        goto trap_eol; \
                    711:                        break; \
                    712:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                    713:                    default : \
                    714:                        run += cx.tr.a; \
                    715:                        break; \
                    716:                    }; \
                    717:                } \
                    718:        while(cx.tr.a>63); \
                    719:        (V) = run; \
                    720:        }
                    721: #endif
                    722: 
                    723: /* Translate a stream of bits in CCITT FAX Group 3 (2-D) compression format
                    724:    into a sequence of RLE_Lines.  Returns one (RLE_Line *) on each call (or NULL
                    725:    if EOF or error).  The first pixel (black or white) in each g32 line is
                    726:    assigned run index 0. */
                    727: RLE_Line *g32_to_rlel(t,f,bof)
                    728:     DST_table *t;
                    729:     BITFILE *f;
                    730:     boolean bof;       /* beginning of file */
                    731: #define dbg_g32r_e (0) /* entry/exit */
                    732: #define dbg_g32r_r (0) /* trace each run/EOL/ERR_SYN */
                    733: #define dbg_g32r_c (0) /* trace each Huffman code (or, fill+EOL)*/
                    734: #define dbg_g32r_t (0) /* trace each state-transition */
                    735: #define g32r_strict (1)        /* 1 is CORRECT: explicitly code the last black pel */
                    736: {   static RLE_Line rl0,rl1,*prl,*crl; /* prior, current run-lines */
                    737:     RLE_Line *swrl;
                    738:     int bitv;          /* the last-read bit value */
                    739:     DST_context cx,px; /* the current/prior decoding context */
                    740:     RLE_Run *cr,*pr,*pre;      /* into current/prior rle lines */      
                    741:     RLE_Run *pra0;     /* rightmost in prior line with xe<=a0 (if none: prl->r) */
                    742:     int run,sync,si,rtc_eols;
                    743:     boolean fill;
                    744:     /* pixel indices (0,1,...):  current-line a*; prior-line b*.
                    745:        a0 is the index of the most recently completely encoded bit */
                    746:     int a0,a1,a2,b1,b2;        
                    747:     DST_color a0_color;  /* a0's color:  same as a2 & b2, opposite of a1 & b1 */
                    748:     int a01,a12;        /* lengths of runs a0-a1 & a1-a2 */
                    749: #define g32_first_color DST_white      /* color of 1st run in each line */
                    750: #define g32_negative (0)       /* if 1, invert Black/White on output */
                    751: #define swap_rl(f,b) {swrl=(f); (f)=(b); (b)=swrl;}
                    752: /* detect b1 & b2:  sensitive to a0, a0_color, and prior runs *pr *(pr+1) */
                    753: #define g32r_find_Bb1Wb2 { \
                    754:        /* find 1st black changing pel>a0 */ \
                    755:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                    756:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                    757:        /* look beyond pra0 */ \
                    758:        pr=pra0;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                    759:        /* move b2 to 1st changing white pel > b1 */ \
                    760:        if(pr<pre) b2=pr->xe+1; \
                    761:        else b1=b2=prl->len; \
                    762:        }
                    763: #define g32r_find_Wb1Bb2 { \
                    764:        /* find 1st white changing pel>a0 */ \
                    765:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                    766:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                    767:        /* look beyond pra0 */ \
                    768:        pr=pra0;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                    769:        /* move b2 to 1st changing black pel > b1 */ \
                    770:        if(pr<pre) { \
                    771:                if((pr+1)<pre) b2=(pr+1)->xs; \
                    772:                else b2=prl->len; \
                    773:                } \
                    774:        else b1=b2=prl->len; \
                    775:        }
                    776: #define g32r_find_b1b2 {if(a0_color==DST_white) g32r_find_Bb1Wb2 else g32r_find_Wb1Bb2;}
                    777: 
                    778: #if DEBUG
                    779: if(dbg_g32r_e) fprintf(stderr,"g32_to_rlel(t,bf,bof%d)\n",bof);
                    780: #endif
                    781: if(bof){crl= &rl0;  crl->y= -1;  crl->len=0;  crl->runs=0;
                    782:        prl= &rl1;  prl->y= -1;  prl->len=0;  prl->runs=0;
                    783:        /* sync by skipping initial FILL & EOL code */
                    784:        sync=0;  while((bitv=getb(f))==0) sync++;
                    785:        if(bitv!=1||sync<11) {
                    786: #if DEBUG
                    787:                if(dbg_g32r_c) {
                    788:                        fprintf(stderr,"BOF_ERR ");
                    789:                        for(si=0;si<sync;si++) fprintf(stderr,"0");
                    790:                        if(bitv==1) fprintf(stderr,"1\n");
                    791:                        else fprintf(stderr,"?\n");
                    792:                        };
                    793: #endif
                    794:                return(NULL);
                    795:                }
                    796: #if DEBUG
                    797:        else if(dbg_g32r_c){
                    798:                fprintf(stderr,"BOF_EOL ");
                    799:                for(si=0;si<sync;si++) fprintf(stderr,"0");
                    800:                fprintf(stderr,"1\n");
                    801:                };
                    802: #else
                    803:                ;
                    804: #endif
                    805:        prl->y = -1;  crl->y = 0;
                    806:        }
                    807: else crl->y = prl->y + 1;
                    808: 
                    809: pre = (pra0=pr=prl->r) + prl->runs;    /* prior line */
                    810: crl->runs=0;  cr=crl->r-1;             /* current line */
                    811: /* start on an imaginary white pixel just to left of margin */
                    812: a0= -1;  a0_color = DST_white; 
                    813: 
                    814: /* check 1-D / 2-D bit immediately after prior EOL */
                    815: switch(bitv=getb(f)) {
                    816:     case 0 :  /* 2-dimensionally encoded line */
                    817: #if DEBUG
                    818:        if(dbg_g32r_c) fprintf(stderr,"2D_LINE 0\n");
                    819: #endif
                    820:        /* start b1/b2 on prior line's first black pixel, etc;
                    821:           if none, then place off end of line */
                    822:        if(pr<pre) {b1=pr->xs; b2=pr->xe+1;} else b1=b2=prl->len;
                    823:        /* parse a sequence of 2D codes... */
                    824:        while(T/* exited only via goto trap_* and return */) {
                    825:                cx.tr.s = DST_2d;  cx.tr.a = DST_action_NULL;
                    826: #if DEBUG
                    827:                if(dbg_g32r_t)fprintf(stderr,"(%d,%d)\n",cx.tr.s,cx.tr.a);
                    828: #endif
                    829:                do {    switch(bitv=getb(f)) {
                    830:                            case 0 :
                    831:                            case 1 :
                    832:                                cx.tr=t->e[cx.tr.s].t[bitv];
                    833:                                break;
                    834:                            case EOF:  goto trap_eof;  break;
                    835:                            };
                    836: #if DEBUG
                    837:                        if(dbg_g32r_t)fprintf(stderr,"%d->(%d,%d)\n",
                    838:                                        bitv,cx.tr.s,cx.tr.a);
                    839: #endif
                    840:                        }
                    841:                while(cx.tr.a==DST_action_NULL);
                    842: #if DEBUG
                    843:                if(dbg_g32r_t)fprintf(stderr,"%s %04d  %s0\n",
                    844:                        (cx.c==DST_white)? "W": "B",
                    845:                        cx.tr.s,
                    846:                        t->e[cx.tr.s].p);
                    847: #endif
                    848:                switch(cx.tr.a) {
                    849:                    case i2D_V0:
                    850: #if DEBUG
                    851:                        if(dbg_g32r_c)
                    852:                                fprintf(stderr,"V0      %s\n",code2d[cx.tr.a]);
                    853: #endif
                    854:                        a1=b1;
                    855:                        /* encode a0 to a1-1 */
                    856:                        if(a0_color==DST_black) cr->xe=a1-1;
                    857:                        /* move a0 to a1 */
                    858:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                    859:                        a0_color = flip_color(a0_color);
                    860:                        /* encode a0 */
                    861:                        if(a0_color==DST_black)
                    862:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                    863: #if g32r_strict
                    864:                        if(a0==prl->len-1)
                    865:                                { a0++;  goto trap_expecting_eol; };
                    866: #endif
                    867:                        g32r_find_b1b2;
                    868:                        break;
                    869:                    case i2D_VR1:
                    870: #if DEBUG
                    871:                        if(dbg_g32r_c)
                    872:                                fprintf(stderr,"VR1     %s\n",code2d[cx.tr.a]);
                    873: #endif
                    874:                        a1=b1+1;
                    875:                        /* encode a0 to a1-1 */
                    876:                        if(a0_color==DST_black) cr->xe=a1-1;
                    877:                        /* move a0 to a1 */
                    878:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                    879:                        a0_color = flip_color(a0_color);
                    880:                        /* encode a0 */
                    881:                        if(a0_color==DST_black)
                    882:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                    883: #if !g32r_strict
                    884:                        if(a0==prl->len-1)
                    885:                                { a0++;  goto trap_expecting_eol; };
                    886: #endif
                    887:                        g32r_find_b1b2;
                    888:                        break;
                    889:                    case i2D_VR2:
                    890: #if DEBUG
                    891:                        if(dbg_g32r_c)
                    892:                                fprintf(stderr,"VR2     %s\n",code2d[cx.tr.a]);
                    893: #endif
                    894:                        a1=b1+2;
                    895:                        /* encode a0 to a1-1 */
                    896:                        if(a0_color==DST_black) cr->xe=a1-1;
                    897:                        /* move a0 to a1 */
                    898:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                    899:                        a0_color = flip_color(a0_color);
                    900:                        /* encode a0 */
                    901:                        if(a0_color==DST_black)
                    902:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                    903: #if !g32r_strict
                    904:                        if(a0==prl->len-1)
                    905:                                { a0++;  goto trap_expecting_eol; };
                    906: #endif
                    907:                        g32r_find_b1b2;
                    908:                        break;
                    909:                    case i2D_VR3:
                    910: #if DEBUG
                    911:                        if(dbg_g32r_c)
                    912:                                fprintf(stderr,"VR3     %s\n",code2d[cx.tr.a]);
                    913: #endif
                    914:                        a1=b1+3;
                    915:                        /* encode a0 to a1-1 */
                    916:                        if(a0_color==DST_black) cr->xe=a1-1;
                    917:                        /* move a0 to a1 */
                    918:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                    919:                        a0_color = flip_color(a0_color);
                    920:                        /* encode a0 */
                    921:                        if(a0_color==DST_black)
                    922:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                    923: #if !g32r_strict
                    924:                        if(a0==prl->len-1)
                    925:                                { a0++;  goto trap_expecting_eol; };
                    926: #endif
                    927:                        g32r_find_b1b2;
                    928:                        break;
                    929:                    case i2D_VL1:
                    930: #if DEBUG
                    931:                        if(dbg_g32r_c)
                    932:                                fprintf(stderr,"VL1     %s\n",code2d[cx.tr.a]);
                    933: #endif
                    934:                        if((a1=b1-1)<0) err("g32_to_rlel: VL1 backs up to %d",a1);
                    935:                        /* encode a0 to a1-1 */
                    936:                        if(a0_color==DST_black) cr->xe=a1-1;
                    937:                        /* move a0 to a1 */
                    938:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                    939:                        a0_color = flip_color(a0_color);
                    940:                        /* encode a0 */
                    941:                        if(a0_color==DST_black)
                    942:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                    943: #if !g32_strict
                    944:                        if(a0==prl->len-1)
                    945:                                { a0++;  goto trap_expecting_eol; };
                    946: #endif
                    947:                        g32r_find_b1b2;
                    948:                        break;
                    949:                    case i2D_VL2:
                    950: #if DEBUG
                    951:                        if(dbg_g32r_c)
                    952:                                fprintf(stderr,"VL2     %s\n",code2d[cx.tr.a]);
                    953: #endif
                    954:                        if((a1=b1-2)<0) err("g32_to_rlel: VL2 backs up to %d",a1);
                    955:                        /* encode a0 to a1-1 */
                    956:                        if(a0_color==DST_black) cr->xe=a1-1;
                    957:                        /* move a0 to a1 */
                    958:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                    959:                        a0_color = flip_color(a0_color);
                    960:                        /* encode a0 */
                    961:                        if(a0_color==DST_black)
                    962:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                    963: #if !g32r_strict
                    964:                        if(a0==prl->len-1)
                    965:                                { a0++;  goto trap_expecting_eol; };
                    966: #endif
                    967:                        g32r_find_b1b2;
                    968:                        break;
                    969:                    case i2D_VL3:
                    970: #if DEBUG
                    971:                        if(dbg_g32r_c)
                    972:                                fprintf(stderr,"VL3     %s\n",code2d[cx.tr.a]);
                    973: #endif
                    974:                        if((a1=b1-3)<0) err("g32_to_rlel: VL3 backs up to %d",a1);
                    975:                        /* encode a0 to a1-1 */
                    976:                        if(a0_color==DST_black) cr->xe=a1-1;
                    977:                        /* move a0 to a1 */
                    978:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                    979:                        a0_color = flip_color(a0_color);
                    980:                        /* encode a0 */
                    981:                        if(a0_color==DST_black)
                    982:                                { crl->runs++;  (++cr)->xs = a0;  cr->xe = a0; };
                    983: #if !g32r_strict
                    984:                        if(a0==prl->len-1)
                    985:                                { a0++;  goto trap_expecting_eol; };
                    986: #endif
                    987:                        g32r_find_b1b2;
                    988:                        break;
                    989:                    case i2D_PASS:
                    990: #if DEBUG
                    991:                        if(dbg_g32r_c)
                    992:                                fprintf(stderr,"PASS    %s\n",code2d[cx.tr.a]);
                    993: #endif
                    994:                        /* move a0 to b2; no change of color */
                    995:                        a0=b2;  if(a0>=prl->len) goto trap_expecting_eol;
                    996:                        if(a0_color==DST_black) cr->xe = a0;
                    997: #if !g32r_strict
                    998:                        if(a0==prl->len-1)
                    999:                                { a0++;  goto trap_expecting_eol; };
                   1000: #endif
                   1001:                        g32r_find_b1b2;
                   1002:                        break;
                   1003:                    case i2D_HORIZ:
                   1004: #if DEBUG
                   1005:                        if(dbg_g32r_c)
                   1006:                                fprintf(stderr,"HORIZ   %s\n",code2d[cx.tr.a]);
                   1007: #endif
                   1008:                        if(a0_color==DST_white) {
                   1009:                                if(a0<0) a0=0;  /* first run in line starts at 0 */
                   1010:                                g32_1d_run(DST_white,a01);  a1 = a0 + a01;
                   1011:                                g32_1d_run(DST_black,a12);  a2 = a1 + a12;
                   1012:                                if(a12>0) /* Black run of >0 length */ {
                   1013:                                        crl->runs++;
                   1014:                                        (++cr)->xs = a1;
                   1015:                                        cr->xe = a2-1;
                   1016:                                        };
                   1017:                                a0 = a2;        /* still white */
                   1018:                                if(a0>=prl->len) goto trap_expecting_eol;
                   1019:                                /* encode a0 */
                   1020: #if !g32r_strict
                   1021:                                if(a0==prl->len-1)
                   1022:                                        { a0++;  goto trap_expecting_eol; };
                   1023: #endif
                   1024:                                g32r_find_Bb1Wb2;
                   1025:                                }
                   1026:                        else {  g32_1d_run(DST_black,a01);  a1 = a0 + a01;
                   1027:                                g32_1d_run(DST_white,a12);  a2 = a1 + a12;
                   1028:                                if(a01>0) /* Black run of >0 length */ {
                   1029:                                        cr->xe = a1 - 1;
                   1030:                                        }
                   1031:                                else {  /* 0-length: very peculiar: ignore */
                   1032:                                        fprintf(stderr,
                   1033:                                           "g32_to_rlel: HORIZ B%d! W%d - ignore\n",
                   1034:                                           a01,a12);
                   1035:                                        cr--; crl->runs--;
                   1036:                                        };
                   1037:                                a0 = a2;        /* still black */
                   1038:                                if(a0>=prl->len) goto trap_expecting_eol;
                   1039:                                /* encode a0 */
                   1040:                                crl->runs++;  (++cr)->xs = a0;
                   1041: #if !g32r_strict
                   1042:                                if(a0==prl->len-1) {
                   1043:                                        cr->xe = a0;
                   1044:                                        a0++;
                   1045:                                        goto trap_expecting_eol;
                   1046:                                        };
                   1047: #endif
                   1048:                                g32r_find_Wb1Bb2;
                   1049:                                };
                   1050:                        break;
                   1051:                    case i2D_EOL:
                   1052: #if DEBUG
                   1053:                        if(dbg_g32r_c)
                   1054:                                fprintf(stderr,"EOL     %s\n",code2d[cx.tr.a]);
                   1055: #endif
                   1056:                        goto trap_eol;
                   1057:                        break;
                   1058:                    case DST_action_ERROR:  goto trap_code_err;  break;
                   1059:                    };
                   1060:                };
                   1061:        break;
                   1062:     case 1 :  /* 1-dimensionally encoded line */
                   1063: #if DEBUG
                   1064:        if(dbg_g32r_c) fprintf(stderr,"1D_LINE 1\n");
                   1065: #endif
                   1066:        /* read a sequence of 1-D runcodes... */
                   1067:        while(T/* exit only via goto trap_X */) {
                   1068:                g32_1d_run(a0_color,a01);
                   1069:                a1 = ((a0>=0)? a0 : 0) + a01;
                   1070:                if(a01>0) {
                   1071:                        /* encode a0 through a1-1 */
                   1072:                        if(a0_color==DST_black^g32_negative) {
                   1073:                                /* output-black run */
                   1074:                                crl->runs++;
                   1075:                                (++cr)->xs=((a0>=0)? a0 : 0);
                   1076:                                cr->xe=a1-1;
                   1077:                                };
                   1078:                        };
                   1079:                a0=a1;
                   1080:                a0_color=flip_color(a0_color);
                   1081:                if(prl->len>0 && a0>=prl->len) goto trap_expecting_eol;
                   1082:                };
                   1083:        break;
                   1084:     case EOF :  goto trap_eof;  break;
                   1085:     };
                   1086: 
                   1087: /* come here via goto's: all these traps return() */
                   1088: 
                   1089: trap_expecting_eol:    /* come here expecting to see EOL or FILL+EOL */
                   1090:        sync=0;  while((bitv=getb(f))==0) sync++;
                   1091:        switch(bitv) {
                   1092:            case 1:
                   1093:                if(sync==11) {
                   1094: #if DEBUG
                   1095:                        if(dbg_g32r_c){
                   1096:                                fprintf(stderr,"EOL     %s\n",EOLSTRING);
                   1097:                                };
                   1098: #endif
                   1099:                        goto trap_eol;
                   1100:                        }
                   1101:                else if(sync>11) {
                   1102: #if DEBUG
                   1103:                        if(dbg_g32r_c){
                   1104:                                fprintf(stderr,"FILLEOL ");
                   1105:                                for(si=0;si<sync-11;si++) fprintf(stderr,"0");
                   1106:                                fprintf(stderr,"+");
                   1107:                                fprintf(stderr,"%s\n",EOLSTRING);
                   1108:                                };
                   1109: #endif
                   1110:                        goto trap_eol;
                   1111:                        }
                   1112:                else {  
                   1113: #if DEBUG
                   1114:                        if(dbg_g32r_c){
                   1115:                                fprintf(stderr,"NOT EOL ");
                   1116:                                for(si=0;si<sync;si++) fprintf(stderr,"0");
                   1117:                                fprintf(stderr,"1?");
                   1118:                                };
                   1119: #endif
                   1120:                        sync=0;
                   1121:                        goto trap_eol_err;
                   1122:                        };
                   1123:                break;
                   1124:            case EOF:  goto trap_eof;  break;
                   1125:            };
                   1126:        goto trap_eol;
                   1127: 
                   1128: trap_code_err:
                   1129:        /* unexpected coding sequence:
                   1130:           'px' holds last decoding context & 'bitv' latest bit value;
                   1131:           will attempt to resynchronize on next EOL */
                   1132: #if DEBUG
                   1133:        if(dbg_g32r_c)fprintf(stderr,"CODERR  %s%d?",
                   1134:                                t->e[px.tr.s].p,bitv);
                   1135: #endif
                   1136:        /* count trailing 0's so far (should be in table) */
                   1137: #if !NEW_TRAIL
                   1138:        if(bitv==0) sync=1; else sync=0;
                   1139:        si=strlen(t->e[px.tr.s].p)-1;
                   1140:        while(si>=0&&t->e[px.tr.s].p[si]=='0') {sync++; si--;};
                   1141:        fill = (si<0);  /* all 0's:  may be fill bits */
                   1142: #else
                   1143:        if(bitv==0) sync=t->e[px.tr.s].z+1; else sync=t->e[px.tr.s].z;
                   1144:        fill = (sync>t->e[px.tr.s].l); /* all 0's:  maybe fill bits */
                   1145: #endif 
                   1146: #if DEBUG
                   1147:        if(dbg_trail)err("sync %d fill %d",sync,fill);
                   1148: #endif
                   1149: trap_eol_err:
                   1150:        while(sync<11) {
                   1151:                switch(bitv=getb(f)) {
                   1152:                        case 0:  sync++;
                   1153: #if DEBUG
                   1154:                                if(dbg_g32r_c) fprintf(stderr,"0");
                   1155: #endif
                   1156:                                break;
                   1157:                        case 1:  sync=0;
                   1158: #if DEBUG
                   1159:                                if(dbg_g32r_c) fprintf(stderr,"1");
                   1160: #endif
                   1161:                                break;
                   1162:                        case EOF:  goto trap_eof;  break;
                   1163:                        };
                   1164:                };
                   1165:        /* next `1' will synchronize */
                   1166:        do {    switch(bitv=getb(f)) {
                   1167:                        case 0:
                   1168: #if DEBUG
                   1169:                                if(dbg_g32r_c) fprintf(stderr,"0");
                   1170: #endif
                   1171:                                break;
                   1172:                        case 1:
                   1173: #if DEBUG
                   1174:                                if(dbg_g32r_c) fprintf(stderr,"1");
                   1175: #endif
                   1176:                                break;
                   1177:                        case EOF:  goto trap_eof;  break;
                   1178:                        };
                   1179:                }
                   1180:        while(bitv!=1);
                   1181: #if DEBUG
                   1182:        if(dbg_g32r_c) fprintf(stderr," EOL\n");
                   1183: #endif
                   1184:        goto trap_eol;
                   1185: 
                   1186: trap_eol:      /* come here having seen (and reported) EOL */
                   1187:        /* learn/check line-length */
                   1188:        if(a0>=0) crl->len=a0; else crl->len=0;
                   1189:        if(crl->len==0) {
                   1190:                /* no pixels coded -- may be the 1st of 6 RTC EOLs */
                   1191:                /* check suffix 1 bit */
                   1192:                if((bitv=getb(f))!=1) goto trap_eol_err;
                   1193:                rtc_eols=1;
                   1194: #if DEBUG
                   1195:                if(dbg_g32r_c)fprintf(stderr,"RTC_EOL +1 (%d)\n",rtc_eols);
                   1196: #endif
                   1197:                do {    sync=0;  while((bitv=getb(f))==0) sync++;
                   1198:                        switch(bitv) {
                   1199:                            case 1:
                   1200:                                if(sync<11) {
                   1201: #if DEBUG
                   1202:                                        if(dbg_g32r_c){
                   1203:                                                fprintf(stderr,"NOT RTC ");
                   1204:                                                for(si=0;si<sync;si++)
                   1205:                                                        fprintf(stderr,"0");
                   1206:                                                fprintf(stderr,"1?\n");
                   1207:                                                };
                   1208: #endif
                   1209:                                        sync=0;
                   1210:                                        goto trap_eol_err;
                   1211:                                        };
                   1212:                                break;
                   1213:                            case EOF:  goto trap_eof;  break;
                   1214:                            };
                   1215:                        /* check suffix 1 bit */
                   1216:                        if((bitv=getb(f))!=1) goto trap_eol_err;
                   1217:                        rtc_eols++;
                   1218: #if DEBUG
                   1219:                        if(dbg_g32r_c) {
                   1220:                                fprintf(stderr,"RTC_EOL ");
                   1221:                                for(si=0;si<sync;si++) fprintf(stderr,"0");
                   1222:                                fprintf(stderr,"1+1  (%d)\n",rtc_eols);
                   1223:                                };
                   1224: #endif
                   1225:                        }
                   1226:                while(rtc_eols<6);
                   1227:                /* normal RTC */
                   1228: #if DEBUG
                   1229:                if(dbg_g32r_c)fprintf(stderr,"RTC\n");
                   1230: #endif
                   1231:                return(NULL);
                   1232:                }
                   1233:        else if(prl->len==0) {
                   1234: #if DEBUG
                   1235:                if(dbg_g32r_c)fprintf(stderr,"LINELEN %d\n",crl->len);
                   1236: #endif
                   1237:                }
                   1238:        else if(crl->len!=prl->len) {
                   1239:                err("g32_to_rlel: y%d: LINELEN changes c%d != p%d ? (force to %d)",
                   1240:                        crl->y,crl->len,prl->len,prl->len);
                   1241:                crl->len = prl->len;
                   1242:                };
                   1243:        swap_rl(crl,prl);
                   1244:        return(prl);
                   1245: 
                   1246: trap_eof:
                   1247: #if DEBUG
                   1248:        if(dbg_g32r_c) fprintf(stderr,"<EOF>\n");
                   1249: #endif
                   1250:        return(NULL);
                   1251: 
                   1252:     }
                   1253: 
                   1254: /* Translate a sequence of RLE_Line's (describing a binary image)
                   1255:    into a file (a stream of bits) in CCITT FAX Group 3 (2-D) compression format.
                   1256:    BOF_to_g32() must be called first;  then call rlel_to_g32() for each line
                   1257:    (including blank lines); finally, EOF_to_g32() must be called.  Each line's
                   1258:    EOL and the RTC's first EOL will be padded so they end on a byte boundary.
                   1259:    */
                   1260: /* debugging flags:  trace to stderr */
                   1261: #define dbg_rg32_e (0) /* entry */
                   1262: #define dbg_rg32_r (0) /* runs */
                   1263: #define dbg_rg32_s (0) /* bitstrings */
                   1264: #define rg32_strict (1)        /* 1 is CORRECT: explicitly code the last black pel */
                   1265: 
                   1266: #if DEBUG
                   1267: #define bits_g32(bits) { \
                   1268:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   1269:        if(dbg_rg32_s) fprintf(stderr,"%s",(bits)); \
                   1270:        if(dbg_rg32_r) fprintf(stderr," "); \
                   1271:        }
                   1272: #else
                   1273: #define bits_g32(bits) { \
                   1274:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   1275:        }
                   1276: #endif
                   1277: #if DEBUG
                   1278: #define EOL_g32 { \
                   1279:        if(dbg_rg32_r) fprintf(stderr,"EOL     "); \
                   1280:        bits_g32(EOLSTRING); \
                   1281:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1282:        }
                   1283: #else
                   1284: #define EOL_g32 { \
                   1285:        bits_g32(EOLSTRING); \
                   1286:        }
                   1287: #endif
                   1288: 
                   1289: BOF_to_g32(f)
                   1290:     BITFILE *f;
                   1291: {   char *cs;
                   1292:        /* a NOP: no header for Group 3 (2-D) */
                   1293: #if DEBUG
                   1294:        if(dbg_rg32_e) fprintf(stderr,"BOF\n");
                   1295: #endif
                   1296:        };
                   1297: 
                   1298: rlel_to_g32(pl,cl,wid,f)
                   1299:     RLE_Line *pl;      /* prior "reference" line: if NULL, use 1-D coding on cl */
                   1300:     RLE_Line *cl;      /* current "coding" line: if NULL, is blank (all white) */
                   1301:     int wid;           /* width of an output line in pixels */
                   1302:     BITFILE *f;
                   1303: {   int runl,codi;
                   1304:     char *cs,*p01;
                   1305: #if DEBUG
                   1306: #define Wrun_g32(rn) { \
                   1307:        runl=(rn); \
                   1308:        if(dbg_rg32_r) fprintf(stderr,"W %5d ",runl); \
                   1309:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   1310:        p01=codewht[codi=rtoi(runl)]; bits_g32(p01); \
                   1311:        if(codi>=64) {p01=codewht[runl%64]; bits_g32(p01);}; \
                   1312:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1313:        }
                   1314: #else
                   1315: #define Wrun_g32(rn) { \
                   1316:        runl=(rn); \
                   1317:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   1318:        p01=codewht[codi=rtoi(runl)]; bits_g32(p01); \
                   1319:        if(codi>=64) {p01=codewht[runl%64]; bits_g32(p01);}; \
                   1320:        }
                   1321: #endif
                   1322: #if DEBUG
                   1323: #define Brun_g32(rn) { \
                   1324:        runl=(rn); \
                   1325:        if(dbg_rg32_r) fprintf(stderr,"B %5d ",runl); \
                   1326:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   1327:        p01=codeblk[codi=rtoi(runl)]; bits_g32(p01); \
                   1328:        if(codi>=64) {p01=codeblk[runl%64]; bits_g32(p01);}; \
                   1329:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1330:        }
                   1331: #else
                   1332: #define Brun_g32(rn) { \
                   1333:        runl=(rn); \
                   1334:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g32(p01); runl-=2560;}; \
                   1335:        p01=codeblk[codi=rtoi(runl)]; bits_g32(p01); \
                   1336:        if(codi>=64) {p01=codeblk[runl%64]; bits_g32(p01);}; \
                   1337:        }
                   1338: #endif
                   1339: #if DEBUG
                   1340: #define V0_g32 { \
                   1341:        if(dbg_rg32_r) fprintf(stderr,"V0      "); \
                   1342:        bits_g32(code2d[i2D_V0]); \
                   1343:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1344:        }
                   1345: #else
                   1346: #define V0_g32 { \
                   1347:        bits_g32(code2d[i2D_V0]); \
                   1348:        }
                   1349: #endif
                   1350: #if DEBUG
                   1351: #define VR1_g32 { \
                   1352:        if(dbg_rg32_r) fprintf(stderr,"VR1     "); \
                   1353:        bits_g32(code2d[i2D_VR1]); \
                   1354:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1355:        }
                   1356: #else
                   1357: #define VR1_g32 { \
                   1358:        bits_g32(code2d[i2D_VR1]); \
                   1359:        }
                   1360: #endif
                   1361: #if DEBUG
                   1362: #define VR2_g32 { \
                   1363:        if(dbg_rg32_r) fprintf(stderr,"VR2     "); \
                   1364:        bits_g32(code2d[i2D_VR2]); \
                   1365:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1366:        }
                   1367: #else
                   1368: #define VR2_g32 { \
                   1369:        bits_g32(code2d[i2D_VR2]); \
                   1370:        }
                   1371: #endif
                   1372: #if DEBUG
                   1373: #define VR3_g32 { \
                   1374:        if(dbg_rg32_r) fprintf(stderr,"VR3     "); \
                   1375:        bits_g32(code2d[i2D_VR3]); \
                   1376:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1377:        }
                   1378: #else
                   1379: #define VR3_g32 { \
                   1380:        bits_g32(code2d[i2D_VR3]); \
                   1381:        }
                   1382: #endif
                   1383: #if DEBUG
                   1384: #define VL1_g32 { \
                   1385:        if(dbg_rg32_r) fprintf(stderr,"VL1     "); \
                   1386:        bits_g32(code2d[i2D_VL1]); \
                   1387:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1388:        }
                   1389: #else
                   1390: #define VL1_g32 { \
                   1391:        bits_g32(code2d[i2D_VL1]); \
                   1392:        }
                   1393: #endif
                   1394: #if DEBUG
                   1395: #define VL2_g32 { \
                   1396:        if(dbg_rg32_r) fprintf(stderr,"VL2     "); \
                   1397:        bits_g32(code2d[i2D_VL2]); \
                   1398:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1399:        }
                   1400: #else
                   1401: #define VL2_g32 { \
                   1402:        bits_g32(code2d[i2D_VL2]); \
                   1403:        }
                   1404: #endif
                   1405: #if DEBUG
                   1406: #define VL3_g32 { \
                   1407:        if(dbg_rg32_r) fprintf(stderr,"VL3     "); \
                   1408:        bits_g32(code2d[i2D_VL3]); \
                   1409:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1410:        }
                   1411: #else
                   1412: #define VL3_g32 { \
                   1413:        bits_g32(code2d[i2D_VL3]); \
                   1414:        }
                   1415: #endif
                   1416: #if DEBUG
                   1417: #define PASS_g32 { \
                   1418:        if(dbg_rg32_r) fprintf(stderr,"PASS    "); \
                   1419:        bits_g32(code2d[i2D_PASS]); \
                   1420:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1421:        }
                   1422: #else
                   1423: #define PASS_g32 { \
                   1424:        bits_g32(code2d[i2D_PASS]); \
                   1425:        }
                   1426: #endif
                   1427: #if DEBUG
                   1428: #define HORIZ_g32 { \
                   1429:        if(dbg_rg32_r) fprintf(stderr,"HORIZ   "); \
                   1430:        bits_g32(code2d[i2D_HORIZ]); \
                   1431:        if(dbg_rg32_r) fprintf(stderr,"\n"); \
                   1432:        }
                   1433: #else
                   1434: #define HORIZ_g32 { \
                   1435:        bits_g32(code2d[i2D_HORIZ]); \
                   1436:        }
                   1437: #endif
                   1438: #define detect_a1a2_BW { \
                   1439:        /* find leftmost black changing pel > a0 */ \
                   1440:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   1441:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   1442:        /* look beyond cra, until cr->xs>a0 */ \
                   1443:        cr=cra; while(cr<cre && (a1=cr->xs)<=a0) cr++; \
                   1444:        if(cr<cre) a2=cr->xe+1; \
                   1445:        else a1=a2=wid; \
                   1446:        }
                   1447: #define detect_a1a2_WB { \
                   1448:        /* find leftmost white changing pel > a0 */ \
                   1449:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   1450:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   1451:        /* look beyond cra, until cr->xe+1>a0 */ \
                   1452:        cr=cra;  while(cr<cre && (a1=cr->xe+1)<=a0) cr++; \
                   1453:        if(cr<cre) { \
                   1454:                if((cr+1)<cre) a2=(cr+1)->xs; \
                   1455:                else a2=wid; \
                   1456:                } \
                   1457:        else a1=a2=wid; \
                   1458:        }
                   1459: #define detect_a1a2 {if(a0_color==DST_white) detect_a1a2_BW else detect_a1a2_WB;}
                   1460: #define detect_b1b2_BW {\
                   1461:        /* find leftmost black changing pel > a0 */ \
                   1462:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   1463:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   1464:        /* look beyond pra */ \
                   1465:        pr=pra;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                   1466:        /* move b2 to 1st changing white pel > b1 */ \
                   1467:        if(pr<pre) b2=pr->xe+1; \
                   1468:        else b1=b2=wid; \
                   1469:        }
                   1470: #define detect_b1b2_WB {\
                   1471:        /* find leftmost white changing pel > a0 */ \
                   1472:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   1473:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   1474:        /* look beyond pra */ \
                   1475:        pr=pra;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                   1476:        /* move b2 to 1st changing black pel > b1 */ \
                   1477:        if(pr<pre) { \
                   1478:                if((pr+1)<pre) b2=(pr+1)->xs; \
                   1479:                else b2=wid; \
                   1480:                } \
                   1481:        else b1=b2=wid; \
                   1482:        }
                   1483: #define detect_b1b2 {if(a0_color==DST_white) detect_b1b2_BW else detect_b1b2_WB;}
                   1484: 
                   1485: #if DEBUG
                   1486:        if(dbg_rg32_e) err("rlel_to_g32(pl[%d],cl[%d],w%d)",
                   1487:                                (pl==NULL)? -1: pl->runs,
                   1488:                                (cl==NULL)? -1: cl->runs,
                   1489:                                wid);
                   1490: #endif
                   1491:        /* fill so that EOL ends on byte boundary */
                   1492:        padb(f,0,8,EOLLENGTH);
                   1493: #if DEBUG
                   1494:        if(dbg_rg32_s) fprintf(stderr,"FILL  +0?");
                   1495: #endif
                   1496:        EOL_g32;        /* begin with EOL (sic) */
                   1497:        if(pl==NULL) /* use 1-D coding for *cl */ {
                   1498:            int pi;             /* input pixel index on line */
                   1499:            RLE_Run *rp,*pp,*sp;
                   1500:                putb(1,f);
                   1501: #if DEBUG
                   1502:                if(dbg_rg32_r) fprintf(stderr,"1D_LINE 1\n");
                   1503: #endif
                   1504:                if(cl!=NULL&&cl->runs>0) {
                   1505:                        pi=0;   /* bit to write next */
                   1506:                        for(sp=(rp=cl->r)+cl->runs; rp<sp; rp++) {
                   1507:                                Wrun_g32(rp->xs-pi);  pi=rp->xs;
                   1508:                                Brun_g32(rp->xe-pi+1);  pi=rp->xe+1;
                   1509:                                };
                   1510:                        if((--rp)->xe+1<wid) Wrun_g32(wid-rp->xe-1);
                   1511:                        }
                   1512:                else Wrun_g32(wid);  /* blank scanline */
                   1513:                }
                   1514:        else /* use 2-D coding for *cl */ {
                   1515:            RLE_Run *cr,*cre,*pr,*pre;  /* into current/prior rle lines */      
                   1516:            int a0,a1,a2,b1,b2;  /* indices {0,1,...} of pixels */
                   1517:            DST_color a0_color;  /* a0's color:  same as a2 & b2, opp of a1 & b1 */
                   1518:            RLE_Run *cra;   /* rightmost in current st xe<=a0 (none: ==cl->r)  */
                   1519:            RLE_Run *pra;   /* rightmost in prior st xe<=a0 (none: ==pl->r) */
                   1520:            int a01,a12,a1b1;   /* lengths of runs a0-a1 a1-a2 a1-b1 */
                   1521:                putb(0,f);
                   1522: #if DEBUG
                   1523:                if(dbg_rg32_r) fprintf(stderr,"2D_LINE 0\n");
                   1524: #endif
                   1525:                /* start on an imaginary white pixel just to left of margin */
                   1526:                a0= -1;  a0_color = DST_white;  
                   1527:                pre = (pra=pl->r) + pl->runs;   /* prior line's runs */
                   1528:                /* start b1/b2 on prior line's first black pixel, etc;
                   1529:                   if none, then place off end of line */
                   1530:                if(pra<pre) {b1=pra->xs; b2=pra->xe+1;} else b1=b2=wid;
                   1531:                if(cl!=NULL&&cl->runs>0) {
                   1532:                        cre = (cra=cl->r) + cl->runs;
                   1533:                        a1=cra->xs;  a2=cra->xe+1;
                   1534: #if rg32_strict
                   1535:                        while(a0 < wid) {
                   1536: #else
                   1537:                        while(a0 < wid-1) {
                   1538: #endif
                   1539:                                /* a0, a1, a2, b1, b2 are as in CCITT Rec T.4 */
                   1540: #if DEBUG
                   1541:                                if(dbg_rg32_r)
                   1542:                                    fprintf(stderr,"f%d(%d,%d,%d) b%d(%d,%d)\n",
                   1543:                                        cra-(cl->r),a0,a1,a2,pra-(pl->r),b1,b2);
                   1544: #endif
                   1545:                                if(b2<a1) /* PASS mode */ {
                   1546:                                        PASS_g32;
                   1547:                                        a0=b2;
                   1548:                                        /* a0-color, a1, & a2 are unchanged */
                   1549:                                        detect_b1b2;
                   1550:                                        }
                   1551:                                else if((a1b1=(a1-b1))<=3 && a1b1>= -3) {
                   1552:                                        /* VERTICAL mode */
                   1553:                                        switch(a1b1) {
                   1554:                                            case -3:  VL3_g32;  break;
                   1555:                                            case -2:  VL2_g32;  break;
                   1556:                                            case -1:  VL1_g32;  break;
                   1557:                                            case 0:  V0_g32;  break;
                   1558:                                            case 1:  VR1_g32;  break;
                   1559:                                            case 2:  VR2_g32;  break;
                   1560:                                            case 3:  VR3_g32;  break;
                   1561:                                            };
                   1562:                                        a0=a1;  a0_color=flip_color(a0_color);
                   1563:                                        detect_a1a2;
                   1564:                                        detect_b1b2;
                   1565:                                        }
                   1566:                                else {  /* HORIZONTAL mode */
                   1567:                                        HORIZ_g32;
                   1568:                                        a01=a1-a0; if(a0== -1) a01--;
                   1569:                                        a12=a2-a1;
                   1570:                                        if(a0_color==DST_white) {
                   1571:                                                Wrun_g32(a01);
                   1572:                                                Brun_g32(a12);
                   1573:                                                }
                   1574:                                        else {  Brun_g32(a01);
                   1575:                                                Wrun_g32(a12);
                   1576:                                                };
                   1577:                                        a0=a2;
                   1578:                                        /* a0_color is unchanged */
                   1579:                                        detect_a1a2;
                   1580:                                        detect_b1b2;
                   1581:                                        };
                   1582:                                };
                   1583:                        }
                   1584:                else /* current line is blank */ {
                   1585:                        a1=a2=wid;
                   1586: #if rg32_strict
                   1587:                        while(a0 < wid) {
                   1588: #else
                   1589:                        while(a0 < wid-1) {
                   1590: #endif
                   1591:                                /* a0, a1, a2, b1, b2 are as in CCITT Rec. T.4 */
                   1592: #if DEBUG
                   1593:                                if(dbg_rg32_r)
                   1594:                                    fprintf(stderr,"f(%d,%d,%d) b%d(%d,%d)\n",
                   1595:                                        a0,a1,a2,pra-(pl->r),b1,b2);
                   1596: #endif
                   1597:                                if(b2<a1) /* PASS mode */ {
                   1598:                                        PASS_g32;
                   1599:                                        a0=b2;
                   1600:                                        /* a0-color, a1, & a2 are unchanged */
                   1601:                                        detect_b1b2;
                   1602:                                        }
                   1603:                                else if((a1b1=a1-b1)<=3 && a1b1>= -3) {
                   1604:                                        /* VERTICAL mode */
                   1605:                                        switch(a1b1) {
                   1606:                                            case -3:  VL3_g32;  break;
                   1607:                                            case -2:  VL2_g32;  break;
                   1608:                                            case -1:  VL1_g32;  break;
                   1609:                                            case 0:  V0_g32;  break;
                   1610:                                            case 1:  VR1_g32;  break;
                   1611:                                            case 2:  VR2_g32;  break;
                   1612:                                            case 3:  VR3_g32;  break;
                   1613:                                            };
                   1614:                                        a0=a1;  a0_color=flip_color(a0_color);
                   1615:                                        /* a1, & a2 are unchanged */
                   1616:                                        detect_b1b2;
                   1617:                                        }
                   1618:                                else {  /* HORIZONTAL mode */
                   1619:                                        HORIZ_g32;
                   1620:                                        a01=a1-a0; if(a0== -1) a01--;
                   1621:                                        a12=a2-a1;
                   1622:                                        if(a0_color==DST_white) {
                   1623:                                                Wrun_g32(a01);
                   1624:                                                Brun_g32(a12);
                   1625:                                                }
                   1626:                                        else {  Brun_g32(a01);
                   1627:                                                Wrun_g32(a12);
                   1628:                                                };
                   1629:                                        a0=a2;
                   1630:                                        /* a0_color, a1, & a2 are unchanged */
                   1631:                                        detect_b1b2;
                   1632:                                        };
                   1633:                                };
                   1634:                        };
                   1635:                };
                   1636:        }
                   1637: 
                   1638: EOF_to_g32(f)
                   1639:     BITFILE *f;
                   1640: {   char *cs;
                   1641:        padb(f,0,8,EOLLENGTH);  /* fill so that EOL ends on byte boundary */
                   1642: #if DEBUG
                   1643:        if(dbg_rg32_s) fprintf(stderr,"FILL  +0?");
                   1644: #endif
                   1645:        /* write RTC */
                   1646:        EOL_g32;
                   1647:        EOL_g32;
                   1648:        EOL_g32;
                   1649:        EOL_g32;
                   1650:        EOL_g32;
                   1651:        EOL_g32;
                   1652: #if DEBUG
                   1653:        if(dbg_rg32_e) fprintf(stderr,"EOF\n");
                   1654: #endif
                   1655:        }
                   1656: 
                   1657: /* Macro for use within g4_to_rlel, to read one 1-D Modified Huffman coded
                   1658:    run-length of color C, placing the result in variable V.
                   1659:    Exceptionally, goto trap_eol, trap_eof, or trap_code_err.
                   1660:   */
                   1661: #if DEBUG
                   1662: #define g4_1d_run(C,V) { \
                   1663:        run = 0; \
                   1664:        do {    cx.tr.s = (C); \
                   1665:                do {    px = cx; \
                   1666:                        switch(bitv=getb(f)) { \
                   1667:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                   1668:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                   1669:                            case EOF :  goto trap_eof;  break; \
                   1670:                            }; \
                   1671:                        } \
                   1672:                while(cx.tr.a==DST_action_NULL); \
                   1673:                switch(cx.tr.a) { \
                   1674:                    case DST_EOL : \
                   1675:                        if(dbg_g4r_c)fprintf(stderr,"EOL     %s\n",EOLSTRING); \
                   1676:                        goto trap_eol; \
                   1677:                        break; \
                   1678:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                   1679:                    default : \
                   1680:                        if(dbg_g4r_c)fprintf(stderr,"%s%6d %s%d\n", \
                   1681:                                ((C)==DST_white)? "W": "B", \
                   1682:                                cx.tr.a, \
                   1683:                                t->e[px.tr.s].p, \
                   1684:                                bitv); \
                   1685:                        run += cx.tr.a; \
                   1686:                        break; \
                   1687:                    }; \
                   1688:                } \
                   1689:        while(cx.tr.a>63); \
                   1690:        (V) = run; \
                   1691:        }
                   1692: #else
                   1693: #define g4_1d_run(C,V) { \
                   1694:        run = 0; \
                   1695:        do {    cx.tr.s = (C); \
                   1696:                do {    px = cx; \
                   1697:                        switch(bitv=getb(f)) { \
                   1698:                            case 0 :  cx.tr=t->e[cx.tr.s].t[0];  break; \
                   1699:                            case 1 :  cx.tr=t->e[cx.tr.s].t[1];  break; \
                   1700:                            case EOF :  goto trap_eof;  break; \
                   1701:                            }; \
                   1702:                        } \
                   1703:                while(cx.tr.a==DST_action_NULL); \
                   1704:                switch(cx.tr.a) { \
                   1705:                    case DST_EOL : \
                   1706:                        goto trap_eol; \
                   1707:                        break; \
                   1708:                    case DST_action_ERROR :  goto trap_code_err;  break; \
                   1709:                    default : \
                   1710:                        run += cx.tr.a; \
                   1711:                        break; \
                   1712:                    }; \
                   1713:                } \
                   1714:        while(cx.tr.a>63); \
                   1715:        (V) = run; \
                   1716:        }
                   1717: #endif
                   1718: 
                   1719: /* Translate a stream of bits in CCITT FAX Group 4 compression format, of known
                   1720:    fixed line-length, into a sequence of RLE_Lines.  Returns one (RLE_Line *)
                   1721:    on each call (or NULL if EOF or error).  The first pixel (black or white)
                   1722:    in each g4 line is assigned run index 0.
                   1723:    WARNING:  the RLE_Line returned must NOT be modified by the caller, since
                   1724:    it is used to decode the next line. */
                   1725: RLE_Line *g4_to_rlel(t,f,bof,len)
                   1726:     DST_table *t;
                   1727:     BITFILE *f;
                   1728:     boolean bof;       /* beginning of file */
                   1729:     int len;           /* line-length in pixels (used only on bof) */
                   1730: #define dbg_g4r_e (0)  /* trace entry-to / exit-from function */
                   1731: #define dbg_g4r_r (0)  /* trace each run/EOL/ERR_SYN */
                   1732: #define dbg_g4r_c (0)  /* trace each Huffman code (or, fill+EOL)*/
                   1733: #define dbg_g4r_t (0)  /* trace each state-transition */
                   1734: #define g4r_strict (1) /* 1 is CORRECT: explicitly code the last black pel */
                   1735: {   static RLE_Line rl0,rl1,*prl,*crl; /* prior, current run-lines */
                   1736:     RLE_Line *swrl;
                   1737:     int bitv;                  /* the last-read bit value */
                   1738:     DST_context cx,px;         /* the current/prior decoding context */
                   1739:     RLE_Run *cr,*pr,*pre;      /* into current/prior rle lines */      
                   1740:     RLE_Run *pra0;             /* rightmost in prior line with xe<=a0
                   1741:                                   (if none: prl->r) */
                   1742:     int run,sync,si,rtc_eols;
                   1743:     /* pixel indices (0,1,...):  current-line a*; prior-line b*.
                   1744:        a0 is the index of the most recently completely encoded bit */
                   1745:     int a0,a1,a2,b1,b2;        
                   1746:     DST_color a0_color;  /* a0's color:  same as a2 & b2, opposite of a1 & b1 */
                   1747:     int a01,a12;       /* lengths of runs a0-a1 & a1-a2 */
                   1748: #define g4_first_color (DST_white)     /* color of 1st run in each line */
                   1749: #define g4_negative (0)                /* if 1, invert Black/White on output */
                   1750: #define swap_rl(f,b) {swrl=(f); (f)=(b); (b)=swrl;}
                   1751: /* detect b1 & b2:  sensitive to a0, a0_color, and prior runs *pr *(pr+1) */
                   1752: #define g4r_find_Bb1Wb2 { \
                   1753:        /* find 1st black changing pel>a0 */ \
                   1754:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                   1755:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                   1756:        /* look beyond pra0 */ \
                   1757:        pr=pra0;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                   1758:        /* move b2 to 1st changing white pel > b1 */ \
                   1759:        if(pr<pre) b2=pr->xe+1; \
                   1760:        else b1=b2=prl->len; \
                   1761:        }
                   1762: #define g4r_find_Wb1Bb2 { \
                   1763:        /* find 1st white changing pel>a0 */ \
                   1764:        /* advance pra0 as far as possible s.t. pra0->xe<=a0 */ \
                   1765:        while((pra0+1)<pre && (pra0+1)->xe<=a0) pra0++; \
                   1766:        /* look beyond pra0 */ \
                   1767:        pr=pra0;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                   1768:        /* move b2 to 1st changing black pel > b1 */ \
                   1769:        if(pr<pre) { \
                   1770:                if((pr+1)<pre) b2=(pr+1)->xs; \
                   1771:                else b2=prl->len; \
                   1772:                } \
                   1773:        else b1=b2=prl->len; \
                   1774:        }
                   1775: #define g4r_find_b1b2 { \
                   1776:        if(a0_color==DST_white) g4r_find_Bb1Wb2 else g4r_find_Wb1Bb2; \
                   1777:        if(b1<=a0) err("g4_to_rlel: y%d: b1 %d <= a0 %d ?",crl->y,a0,b1); \
                   1778:        }
                   1779: 
                   1780:        if(bof){/* initial reference line is all white, of known length */
                   1781:                prl= &rl0;  prl->y= -1;  prl->len=len;  prl->runs=0;
                   1782:                /* initial coding line has y-coordinate 0 */
                   1783:                crl= &rl1;  crl->y=0;  crl->len=0;  crl->runs=0;
                   1784:                }
                   1785:        else crl->y = prl->y + 1;
                   1786: #if DEBUG
                   1787:        if(dbg_g4r_e)
                   1788:                fprintf(stderr,
                   1789:                        "g4_to_rlel(t,f,bof%d,len%d) y%d,l%d\n",
                   1790:                        bof,len,prl->y,prl->len);
                   1791: #endif
                   1792:        
                   1793:        pre = (pra0=pr=prl->r) + prl->runs;     /* prior line */
                   1794:        crl->runs=0;  cr=crl->r-1;              /* current line */
                   1795:        /* start on an imaginary white pixel just to left of margin */
                   1796:        a0= -1;  a0_color = DST_white;
                   1797: #if DEBUG
                   1798:        a1=a2=b1=b2=0;  /* immaterial; looks better when debugging */
                   1799: #endif
                   1800: 
                   1801:        /* start b1/b2 on prior line's first black pixel, etc;
                   1802:           if none, then place off end of line */
                   1803:        if(pr<pre) {b1=pr->xs; b2=pr->xe+1;} else b1=b2=prl->len;
                   1804:        /* parse a sequence of 2D codes... */
                   1805:        while(T/* exit only via 'goto trap_X' */) {
                   1806:                /* a0, a1, a2, b1, b2 are as defined in CCITT Rec. T.6 */
                   1807: #if DEBUG
                   1808:                if(dbg_g4r_r)
                   1809:                        fprintf(stderr,"a(%d,%d,%d) b(%d,%d)\n",a0,a1,a2,b1,b2);
                   1810: #endif
                   1811:                cx.tr.s = DST_2d;  cx.tr.a = DST_action_NULL;
                   1812: #if DEBUG
                   1813:                if(dbg_g4r_t)fprintf(stderr,"(%d,%d)\n",cx.tr.s,cx.tr.a);
                   1814: #endif
                   1815:                do {    switch(bitv=getb(f)) {
                   1816:                            case 0 :
                   1817:                            case 1 :
                   1818:                                cx.tr=t->e[cx.tr.s].t[bitv];
                   1819:                                break;
                   1820:                            case EOF:  goto trap_eof;  break;
                   1821:                            };
                   1822: #if DEBUG
                   1823:                        if(dbg_g4r_t)fprintf(stderr,"%d->(%d,%d)\n",
                   1824:                                        bitv,cx.tr.s,cx.tr.a);
                   1825: #endif
                   1826:                        }
                   1827:                while(cx.tr.a==DST_action_NULL);
                   1828: #if DEBUG
                   1829:                if(dbg_g4r_t)fprintf(stderr,"%s %04d  %s0\n",
                   1830:                        (cx.c==DST_white)? "W": "B",
                   1831:                        cx.tr.s,
                   1832:                        t->e[cx.tr.s].p);
                   1833: #endif
                   1834:                switch(cx.tr.a) {
                   1835:                    case i2D_V0:
                   1836: #if DEBUG
                   1837:                        if(dbg_g4r_c)
                   1838:                                fprintf(stderr,"V0      %s\n",code2d[cx.tr.a]);
                   1839: #endif
                   1840:                        a1=b1;
                   1841:                        /* interpret (a0,a1-1] */
                   1842:                        if(a0_color==DST_black) cr->xe=a1-1;
                   1843:                        /* move a0 to a1 */
                   1844:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   1845:                        a0_color = flip_color(a0_color);
                   1846:                        /* interpret a0 */
                   1847:                        if(a0_color==DST_black) {
                   1848:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   1849:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   1850:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   1851:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   1852:                                };
                   1853: #if !g4r_strict
                   1854:                        if(a0==prl->len-1)
                   1855:                                { a0++;  goto trap_expecting_eol; };
                   1856: #endif
                   1857:                        g4r_find_b1b2;
                   1858:                        break;
                   1859:                    case i2D_VR1:
                   1860: #if DEBUG
                   1861:                        if(dbg_g4r_c)
                   1862:                                fprintf(stderr,"VR1     %s\n",code2d[cx.tr.a]);
                   1863: #endif
                   1864:                        a1=b1+1;
                   1865:                        /* encode a0 to a1-1 */
                   1866:                        if(a0_color==DST_black) cr->xe=a1-1;
                   1867:                        /* move a0 to a1 */
                   1868:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   1869:                        a0_color = flip_color(a0_color);
                   1870:                        /* encode a0 */
                   1871:                        if(a0_color==DST_black) {
                   1872:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   1873:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   1874:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   1875:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   1876:                                };
                   1877: #if !g4r_strict
                   1878:                        if(a0==prl->len-1)
                   1879:                                { a0++;  goto trap_expecting_eol; };
                   1880: #endif
                   1881:                        g4r_find_b1b2;
                   1882:                        break;
                   1883:                    case i2D_VR2:
                   1884: #if DEBUG
                   1885:                        if(dbg_g4r_c)
                   1886:                                fprintf(stderr,"VR2     %s\n",code2d[cx.tr.a]);
                   1887: #endif
                   1888:                        a1=b1+2;
                   1889:                        /* encode a0 to a1-1 */
                   1890:                        if(a0_color==DST_black) cr->xe=a1-1;
                   1891:                        /* move a0 to a1 */
                   1892:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   1893:                        a0_color = flip_color(a0_color);
                   1894:                        /* encode a0 */
                   1895:                        if(a0_color==DST_black) {
                   1896:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   1897:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   1898:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   1899:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   1900:                                };
                   1901: #if !g4r_strict
                   1902:                        if(a0==prl->len-1)
                   1903:                                { a0++;  goto trap_expecting_eol; };
                   1904: #endif
                   1905:                        g4r_find_b1b2;
                   1906:                        break;
                   1907:                    case i2D_VR3:
                   1908: #if DEBUG
                   1909:                        if(dbg_g4r_c)
                   1910:                                fprintf(stderr,"VR3     %s\n",code2d[cx.tr.a]);
                   1911: #endif
                   1912:                        a1=b1+3;
                   1913:                        /* encode a0 to a1-1 */
                   1914:                        if(a0_color==DST_black) cr->xe=a1-1;
                   1915:                        /* move a0 to a1 */
                   1916:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   1917:                        a0_color = flip_color(a0_color);
                   1918:                        /* encode a0 */
                   1919:                        if(a0_color==DST_black) {
                   1920:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   1921:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   1922:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   1923:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   1924:                                };
                   1925: #if !g4r_strict
                   1926:                        if(a0==prl->len-1)
                   1927:                                { a0++;  goto trap_expecting_eol; };
                   1928: #endif
                   1929:                        g4r_find_b1b2;
                   1930:                        break;
                   1931:                    case i2D_VL1:
                   1932: #if DEBUG
                   1933:                        if(dbg_g4r_c)
                   1934:                                fprintf(stderr,"VL1     %s\n",code2d[cx.tr.a]);
                   1935: #endif
                   1936:                        if((a1=b1-1)<=a0)
                   1937:                                err("g4_to_rlel: y%d: VL1 a1 %d <= a0 %d ?",
                   1938:                                        crl->y,a1,a0);
                   1939:                        /* encode a0 to a1-1 */
                   1940:                        if(a0_color==DST_black) cr->xe=a1-1;
                   1941:                        /* move a0 to a1 */
                   1942:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   1943:                        a0_color = flip_color(a0_color);
                   1944:                        /* encode a0 */
                   1945:                        if(a0_color==DST_black) {
                   1946:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   1947:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   1948:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   1949:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   1950:                                };
                   1951: #if !g4r_strict
                   1952:                        if(a0==prl->len-1)
                   1953:                                { a0++;  goto trap_expecting_eol; };
                   1954: #endif
                   1955:                        g4r_find_b1b2;
                   1956:                        break;
                   1957:                    case i2D_VL2:
                   1958: #if DEBUG
                   1959:                        if(dbg_g4r_c)
                   1960:                                fprintf(stderr,"VL2     %s\n",code2d[cx.tr.a]);
                   1961: #endif
                   1962:                        if((a1=b1-2)<=a0)
                   1963:                                err("g4_to_rlel: y%d: VL2 a1 %d <= a0 %d ?",
                   1964:                                        crl->y,a1,a0);
                   1965:                        /* encode a0 to a1-1 */
                   1966:                        if(a0_color==DST_black) cr->xe=a1-1;
                   1967:                        /* move a0 to a1 */
                   1968:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   1969:                        a0_color = flip_color(a0_color);
                   1970:                        /* encode a0 */
                   1971:                        if(a0_color==DST_black) { 
                   1972:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   1973:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   1974:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   1975:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   1976:                                };
                   1977: #if !g4r_strict
                   1978:                        if(a0==prl->len-1)
                   1979:                                { a0++;  goto trap_expecting_eol; };
                   1980: #endif
                   1981:                        g4r_find_b1b2;
                   1982:                        break;
                   1983:                    case i2D_VL3:
                   1984: #if DEBUG
                   1985:                        if(dbg_g4r_c)
                   1986:                                fprintf(stderr,"VL3     %s\n",code2d[cx.tr.a]);
                   1987: #endif
                   1988:                        if((a1=b1-3)<=a0)
                   1989:                                err("g4_to_rlel: y%d: VL3 a1 %d <= a0 %d ?",
                   1990:                                        crl->y,a1,a0);
                   1991:                        /* encode a0 to a1-1 */
                   1992:                        if(a0_color==DST_black) cr->xe=a1-1;
                   1993:                        /* move a0 to a1 */
                   1994:                        a0=a1;  if(a0>=prl->len) goto trap_expecting_eol;
                   1995:                        a0_color = flip_color(a0_color);
                   1996:                        /* encode a0 */
                   1997:                        if(a0_color==DST_black) {
                   1998:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   1999:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   2000:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   2001:                                crl->runs++;  (++cr)->xs = a0;  cr->xe = a0;
                   2002:                                };
                   2003: #if !g4r_strict
                   2004:                        if(a0==prl->len-1)
                   2005:                                { a0++;  goto trap_expecting_eol; };
                   2006: #endif
                   2007:                        g4r_find_b1b2;
                   2008:                        break;
                   2009:                    case i2D_PASS:
                   2010: #if DEBUG
                   2011:                        if(dbg_g4r_c)
                   2012:                                fprintf(stderr,"PASS    %s\n",code2d[cx.tr.a]);
                   2013: #endif
                   2014:                        /* move a0 to b2; no change of color */
                   2015:                        a0=b2;  if(a0>=prl->len) goto trap_expecting_eol;
                   2016:                        if(a0_color==DST_black) cr->xe = a0;
                   2017: #if !g4r_strict
                   2018:                        if(a0==prl->len-1)
                   2019:                                { a0++;  goto trap_expecting_eol; };
                   2020: #endif
                   2021:                        g4r_find_b1b2;
                   2022:                        break;
                   2023:                    case i2D_HORIZ:
                   2024: #if DEBUG
                   2025:                        if(dbg_g4r_c)
                   2026:                                fprintf(stderr,"HORIZ   %s\n",code2d[cx.tr.a]);
                   2027: #endif
                   2028:                        if(a0_color==DST_white) {
                   2029:                                if(a0<0) a0=0;  /* first run in line starts at 0 */
                   2030:                                g4_1d_run(DST_white,a01);  a1 = a0 + a01;
                   2031:                                g4_1d_run(DST_black,a12);  a2 = a1 + a12;
                   2032:                                if(a12>0) /* Black run of >0 length */ {
                   2033:                                if(cr->xs>cr->xe&&cr->xs<prl->len&&cr->xe>0)
                   2034:                                        err("g4_to_rlel: y%d: r%d[%d,%d] not monotone ?",
                   2035:                                                crl->y,crl->runs,cr->xs,cr->xe);
                   2036:                                        crl->runs++; (++cr)->xs = a1; cr->xe = a2-1;
                   2037:                                        };
                   2038:                                a0 = a2;        /* still white */
                   2039:                                if(a0>=prl->len) goto trap_expecting_eol;
                   2040:                                /* encode a0 */
                   2041: #if !g4r_strict
                   2042:                                if(a0==prl->len-1)
                   2043:                                        { a0++;  goto trap_expecting_eol; };
                   2044: #endif
                   2045:                                g4r_find_Bb1Wb2;
                   2046:                                }
                   2047:                        else {  g4_1d_run(DST_black,a01);  a1 = a0 + a01;
                   2048:                                g4_1d_run(DST_white,a12);  a2 = a1 + a12;
                   2049:                                if(a01>0) /* Black run of >0 length */ {
                   2050:                                        cr->xe = a1 - 1;
                   2051:                                        }
                   2052:                                else {  /* 0-length: very peculiar: ignore */
                   2053:                                        fprintf(stderr,
                   2054:                                           "g4_to_rlel: HORIZ B%d! W%d - ignore\n",
                   2055:                                           a01,a12);
                   2056:                                        cr--; crl->runs--;
                   2057:                                        };
                   2058:                                a0 = a2;        /* still black */
                   2059:                                if(a0>=prl->len) goto trap_expecting_eol;
                   2060:                                /* encode a0 */
                   2061:                                crl->runs++;  (++cr)->xs = a0;
                   2062: #if !g4r_strict
                   2063:                                if(a0==prl->len-1) {
                   2064:                                        cr->xe = a0;
                   2065:                                        a0++;
                   2066:                                        goto trap_expecting_eol;
                   2067:                                        };
                   2068: #endif
                   2069:                                g4r_find_Wb1Bb2;
                   2070:                                };
                   2071:                        break;
                   2072:                    case i2D_EOL:
                   2073: #if DEBUG
                   2074:                        if(dbg_g4r_c)
                   2075:                                fprintf(stderr,"EOL     %s\n",code2d[cx.tr.a]);
                   2076: #endif
                   2077:                        goto trap_eol;
                   2078:                        break;
                   2079:                    case DST_action_ERROR:  goto trap_code_err;  break;
                   2080:                    };
                   2081:                };
                   2082: 
                   2083: /* come here via goto's: all these traps return() */
                   2084: 
                   2085: trap_expecting_eol:    /* come here having detected (computed) end-of-line */
                   2086:        /* learn/check/correct line-length */
                   2087:        crl->len = (a0>0)? a0 : 0;
                   2088:        if(crl->len!=prl->len) {
                   2089:                err("g4_to_rlel: y%d: LINELEN changes c%d != p%d ? (force to %d)",
                   2090:                        crl->y,crl->len,prl->len,prl->len);
                   2091:                crl->len = prl->len;
                   2092:                };
                   2093:        swap_rl(crl,prl);
                   2094: #if DEBUG
                   2095:        if(dbg_g4r_e)
                   2096:                fprintf(stderr,
                   2097:                        "exit g4_to_rlel: expg_eol y%d,l%d\n",
                   2098:                        prl->y,prl->len);
                   2099: #endif
                   2100:        return(prl);
                   2101: 
                   2102: trap_eol:  /* come here having seen an EOL code (rare in Group 4) */
                   2103:        /* It must be the first of two EOL codes making up the EOB signal */
                   2104:        /* look for 2nd EOL */
                   2105:        sync=0;  while((bitv=getb(f))==0) sync++;
                   2106:        switch(bitv) {
                   2107:            case 1:
                   2108:                if(sync==11) {
                   2109: #if DEBUG
                   2110:                        if(dbg_g4r_c) {
                   2111:                                fprintf(stderr,"EOB_EOL %s\n",EOLSTRING);
                   2112:                                fprintf(stderr,"EOB\n");
                   2113:                                };
                   2114: #endif
                   2115:                        }
                   2116:                else {  
                   2117: #if DEBUG
                   2118:                        if(dbg_g4r_c){
                   2119:                                fprintf(stderr,"NOT EOB ");
                   2120:                                for(si=0;si<sync;si++)
                   2121:                                        fprintf(stderr,"0");
                   2122:                                fprintf(stderr,"1?\n");
                   2123:                                fprintf(stderr,"ABORT\n");
                   2124:                                };
                   2125: #endif
                   2126:                        };
                   2127:                break;
                   2128:            case EOF:  goto trap_eof;  break;
                   2129:            };
                   2130: #if DEBUG
                   2131:        if(dbg_g4r_e) fprintf(stderr,"exit g4_to_rlel: eol\n");
                   2132: #endif
                   2133:        return(NULL);
                   2134: 
                   2135: trap_code_err:
                   2136:        /* unexpected coding sequence:
                   2137:           'px' holds last decoding context & 'bitv' latest bit value;
                   2138:           will attempt to resynchronize on next EOL */
                   2139: #if DEBUG
                   2140:        if(dbg_g4r_c)fprintf(stderr,"CODERR  %s%d? (px.tr.s=%d)\n",
                   2141:                                t->e[px.tr.s].p,bitv,px.tr.s);
                   2142: #endif
                   2143:        err("g4_to_rlel: code error");
                   2144: #if DEBUG
                   2145:        if(dbg_g4r_e) fprintf(stderr,"exit g4_to_rlel: code_err\n");
                   2146: #endif
                   2147:        return(NULL);
                   2148: 
                   2149: trap_eof:
                   2150: #if DEBUG
                   2151:        if(dbg_g4r_c) fprintf(stderr,"<EOF>\n");
                   2152:        if(dbg_g4r_e) fprintf(stderr,"exit g4_to_rlel: eof\n");
                   2153: #endif
                   2154:        return(NULL);
                   2155: 
                   2156:     }
                   2157: 
                   2158: /* Translate a sequence of RLE_Line's (describing a binary image)
                   2159:    into a file (a stream of bits) in CCITT FAX Group 4 compression format.
                   2160:    BOF_to_g4() must be called first; then call rlel_to_g4() for each line
                   2161:    (including blank lines); finally, EOF_to_g4() must be called.  The EOFB
                   2162:    is padded (suffixed) with 0's to a byte boundary if necessary; no other
                   2163:    filling or padding is performed.
                   2164:    */
                   2165: /* debugging flags:  trace to stderr */
                   2166: #define dbg_rg4_e (0)  /* entry */
                   2167: #define dbg_rg4_r (0)  /* runs */
                   2168: #define dbg_rg4_c (0)  /* codes (bitstrings) */
                   2169: #define rg4_strict (1) /* 1 is CORRECT: explicitly code the last black pel */
                   2170: 
                   2171: #if DEBUG
                   2172: #define bits_g4(bits) { \
                   2173:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   2174:        if(dbg_rg4_c) fprintf(stderr,"%s",(bits)); \
                   2175:        if(dbg_rg4_r) fprintf(stderr," "); \
                   2176:        }
                   2177: #else
                   2178: #define bits_g4(bits) { \
                   2179:        cs=(bits); while(*cs!='\0') {putb(*cs-'0',f); cs++;};  \
                   2180:        }
                   2181: #endif
                   2182: #if DEBUG
                   2183: #define EOFB_g4 { \
                   2184:        if(dbg_rg4_r) fprintf(stderr,"EOFB    "); \
                   2185:        bits_g4(EOFB); \
                   2186:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2187:        }
                   2188: #else
                   2189: #define EOFB_g4 { \
                   2190:        bits_g4(EOFB); \
                   2191:        }
                   2192: #endif
                   2193: 
                   2194: BOF_to_g4(f)
                   2195:     BITFILE *f;
                   2196: {   char *cs;
                   2197:        /* a NOP: no header for Group 4 */
                   2198: #if DEBUG
                   2199:        if(dbg_rg4_e) fprintf(stderr,"BOF\n");
                   2200: #endif
                   2201:        };
                   2202: 
                   2203: rlel_to_g4(pl,cl,wid,f)
                   2204:     RLE_Line *pl;      /* prior "reference" line */
                   2205:     RLE_Line *cl;      /* current "coding" line: if NULL, is blank (all white) */
                   2206:     int wid;           /* width of an output line in pixels */
                   2207:     BITFILE *f;
                   2208: {   int runl,codi;
                   2209:     char *cs,*p01;
                   2210: #if DEBUG
                   2211: #define Wrun_g4(rn) { \
                   2212:        runl=(rn); \
                   2213:        if(dbg_rg4_r) fprintf(stderr,"W %5d ",runl); \
                   2214:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   2215:        p01=codewht[codi=rtoi(runl)]; bits_g4(p01); \
                   2216:        if(codi>=64) {p01=codewht[runl%64]; bits_g4(p01);}; \
                   2217:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2218:        }
                   2219: #else
                   2220: #define Wrun_g4(rn) { \
                   2221:        runl=(rn); \
                   2222:        while(runl>2560) {p01=codewht[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   2223:        p01=codewht[codi=rtoi(runl)]; bits_g4(p01); \
                   2224:        if(codi>=64) {p01=codewht[runl%64]; bits_g4(p01);}; \
                   2225:        }
                   2226: #endif
                   2227: #if DEBUG
                   2228: #define Brun_g4(rn) { \
                   2229:        runl=(rn); \
                   2230:        if(dbg_rg4_r) fprintf(stderr,"B %5d ",runl); \
                   2231:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   2232:        p01=codeblk[codi=rtoi(runl)]; bits_g4(p01); \
                   2233:        if(codi>=64) {p01=codeblk[runl%64]; bits_g4(p01);}; \
                   2234:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2235:        }
                   2236: #else
                   2237: #define Brun_g4(rn) { \
                   2238:        runl=(rn); \
                   2239:        while(runl>2560) {p01=codeblk[rtoi(2560)]; bits_g4(p01); runl-=2560;}; \
                   2240:        p01=codeblk[codi=rtoi(runl)]; bits_g4(p01); \
                   2241:        if(codi>=64) {p01=codeblk[runl%64]; bits_g4(p01);}; \
                   2242:        }
                   2243: #endif
                   2244: #if DEBUG
                   2245: #define V0_g4 { \
                   2246:        if(dbg_rg4_r) fprintf(stderr,"V0      "); \
                   2247:        bits_g4(code2d[i2D_V0]); \
                   2248:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2249:        }
                   2250: #else
                   2251: #define V0_g4 { \
                   2252:        bits_g4(code2d[i2D_V0]); \
                   2253:        }
                   2254: #endif
                   2255: #if DEBUG
                   2256: #define VR1_g4 { \
                   2257:        if(dbg_rg4_r) fprintf(stderr,"VR1     "); \
                   2258:        bits_g4(code2d[i2D_VR1]); \
                   2259:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2260:        }
                   2261: #else
                   2262: #define VR1_g4 { \
                   2263:        bits_g4(code2d[i2D_VR1]); \
                   2264:        }
                   2265: #endif
                   2266: #if DEBUG
                   2267: #define VR2_g4 { \
                   2268:        if(dbg_rg4_r) fprintf(stderr,"VR2     "); \
                   2269:        bits_g4(code2d[i2D_VR2]); \
                   2270:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2271:        }
                   2272: #else
                   2273: #define VR2_g4 { \
                   2274:        bits_g4(code2d[i2D_VR2]); \
                   2275:        }
                   2276: #endif
                   2277: #if DEBUG
                   2278: #define VR3_g4 { \
                   2279:        if(dbg_rg4_r) fprintf(stderr,"VR3     "); \
                   2280:        bits_g4(code2d[i2D_VR3]); \
                   2281:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2282:        }
                   2283: #else
                   2284: #define VR3_g4 { \
                   2285:        bits_g4(code2d[i2D_VR3]); \
                   2286:        }
                   2287: #endif
                   2288: #if DEBUG
                   2289: #define VL1_g4 { \
                   2290:        if(dbg_rg4_r) fprintf(stderr,"VL1     "); \
                   2291:        bits_g4(code2d[i2D_VL1]); \
                   2292:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2293:        }
                   2294: #else
                   2295: #define VL1_g4 { \
                   2296:        bits_g4(code2d[i2D_VL1]); \
                   2297:        }
                   2298: #endif
                   2299: #if DEBUG
                   2300: #define VL2_g4 { \
                   2301:        if(dbg_rg4_r) fprintf(stderr,"VL2     "); \
                   2302:        bits_g4(code2d[i2D_VL2]); \
                   2303:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2304:        }
                   2305: #else
                   2306: #define VL2_g4 { \
                   2307:        bits_g4(code2d[i2D_VL2]); \
                   2308:        }
                   2309: #endif
                   2310: #if DEBUG
                   2311: #define VL3_g4 { \
                   2312:        if(dbg_rg4_r) fprintf(stderr,"VL3     "); \
                   2313:        bits_g4(code2d[i2D_VL3]); \
                   2314:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2315:        }
                   2316: #else
                   2317: #define VL3_g4 { \
                   2318:        bits_g4(code2d[i2D_VL3]); \
                   2319:        }
                   2320: #endif
                   2321: #if DEBUG
                   2322: #define PASS_g4 { \
                   2323:        if(dbg_rg4_r) fprintf(stderr,"PASS    "); \
                   2324:        bits_g4(code2d[i2D_PASS]); \
                   2325:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2326:        }
                   2327: #else
                   2328: #define PASS_g4 { \
                   2329:        bits_g4(code2d[i2D_PASS]); \
                   2330:        }
                   2331: #endif
                   2332: #if DEBUG
                   2333: #define HORIZ_g4 { \
                   2334:        if(dbg_rg4_r) fprintf(stderr,"HORIZ   "); \
                   2335:        bits_g4(code2d[i2D_HORIZ]); \
                   2336:        if(dbg_rg4_r) fprintf(stderr,"\n"); \
                   2337:        }
                   2338: #else
                   2339: #define HORIZ_g4 { \
                   2340:        bits_g4(code2d[i2D_HORIZ]); \
                   2341:        }
                   2342: #endif
                   2343: #define detect_a1a2_BW { \
                   2344:        /* find leftmost black changing pel > a0 */ \
                   2345:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   2346:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   2347:        /* look beyond cra, until cr->xs>a0 */ \
                   2348:        cr=cra; while(cr<cre && (a1=cr->xs)<=a0) cr++; \
                   2349:        if(cr<cre) a2=cr->xe+1; \
                   2350:        else a1=a2=wid; \
                   2351:        }
                   2352: #define detect_a1a2_WB { \
                   2353:        /* find leftmost white changing pel > a0 */ \
                   2354:        /* advance cra as far as possible s.t. cra->xe<=a0 */ \
                   2355:        while((cra+1)<cre && (cra+1)->xe<=a0) cra++; \
                   2356:        /* look beyond cra, until cr->xe+1>a0 */ \
                   2357:        cr=cra;  while(cr<cre && (a1=cr->xe+1)<=a0) cr++; \
                   2358:        if(cr<cre) { \
                   2359:                if((cr+1)<cre) a2=(cr+1)->xs; \
                   2360:                else a2=wid; \
                   2361:                } \
                   2362:        else a1=a2=wid; \
                   2363:        }
                   2364: #define detect_a1a2 {if(a0_color==DST_white) detect_a1a2_BW else detect_a1a2_WB;}
                   2365: #define detect_b1b2_BW {\
                   2366:        /* find leftmost black changing pel > a0 */ \
                   2367:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   2368:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   2369:        /* look beyond pra */ \
                   2370:        pr=pra;  while(pr<pre && (b1=pr->xs)<=a0) pr++; \
                   2371:        /* move b2 to 1st changing white pel > b1 */ \
                   2372:        if(pr<pre) b2=pr->xe+1; \
                   2373:        else b1=b2=wid; \
                   2374:        }
                   2375: #define detect_b1b2_WB {\
                   2376:        /* find leftmost white changing pel > a0 */ \
                   2377:        /* advance pra as far as possible s.t. pra->xe<=a0 */ \
                   2378:        while((pra+1)<pre && (pra+1)->xe<=a0) pra++; \
                   2379:        /* look beyond pra */ \
                   2380:        pr=pra;  while(pr<pre && (b1=pr->xe+1)<=a0) pr++; \
                   2381:        /* move b2 to 1st changing black pel > b1 */ \
                   2382:        if(pr<pre) { \
                   2383:                if((pr+1)<pre) b2=(pr+1)->xs; \
                   2384:                else b2=wid; \
                   2385:                } \
                   2386:        else b1=b2=wid; \
                   2387:        }
                   2388: #define detect_b1b2 {if(a0_color==DST_white) detect_b1b2_BW else detect_b1b2_WB;}
                   2389: 
                   2390:     RLE_Run *cr,*cre,*pr,*pre; /* into current/prior rle lines */      
                   2391:     int a0,a1,a2,b1,b2;         /* indices {0,1,...} of pixels */
                   2392:     DST_color a0_color;  /* a0's color:  same as a2 & b2, opp of a1 & b1 */
                   2393:     RLE_Run *cra;   /* rightmost in current st xe<=a0 (none: ==cl->r)  */
                   2394:     RLE_Run *pra;   /* rightmost in prior st xe<=a0 (none: ==pl->r) */
                   2395:     int a01,a12,a1b1;  /* lengths of runs a0-a1 a1-a2 a1-b1 */
                   2396: #if DEBUG
                   2397:        if(dbg_rg4_e) err("rlel_to_g4(pl[%d],cl[%d],w%d)",
                   2398:                                (pl==NULL)? -1: pl->runs,
                   2399:                                (cl==NULL)? -1: cl->runs,
                   2400:                                wid);
                   2401: #endif
                   2402:        /* start on an imaginary white pixel just to left of margin */
                   2403:        a0= -1;  a0_color = DST_white;  
                   2404:        pre = (pra=pl->r) + pl->runs;   /* prior line's runs */
                   2405:        /* start b1/b2 on prior line's first black pixel, etc;
                   2406:           if none, then place off end of line */
                   2407:        if(pra<pre) {b1=pra->xs; b2=pra->xe+1;} else b1=b2=wid;
                   2408:        if(cl!=NULL&&cl->runs>0) {
                   2409:                cre = (cra=cl->r) + cl->runs;
                   2410:                a1=cra->xs;  a2=cra->xe+1;
                   2411: #if rg4_strict
                   2412:                while( a0 < wid ) {
                   2413: #else
                   2414:                while( a0 < wid-1 ) {
                   2415: #endif
                   2416:                        /* a0, a1, a2, b1, b2 are as defined in CCITT Rec. T.6 */
                   2417: #if DEBUG
                   2418:                        if(dbg_rg4_r)
                   2419:                            fprintf(stderr,"f%d(%d,%d,%d) b%d(%d,%d)\n",
                   2420:                                cra-(cl->r),a0,a1,a2,pra-(pl->r),b1,b2);
                   2421: #endif
                   2422:                        if(b2<a1) /* PASS mode */ {
                   2423:                                PASS_g4;
                   2424:                                a0=b2;
                   2425:                                /* a0-color, a1, & a2 are unchanged */
                   2426:                                detect_b1b2;
                   2427:                                }
                   2428:                        else if((a1b1=(a1-b1))<=3 && a1b1>= -3) {
                   2429:                                /* VERTICAL mode */
                   2430:                                switch(a1b1) {
                   2431:                                    case -3:  VL3_g4;  break;
                   2432:                                    case -2:  VL2_g4;  break;
                   2433:                                    case -1:  VL1_g4;  break;
                   2434:                                    case 0:  V0_g4;  break;
                   2435:                                    case 1:  VR1_g4;  break;
                   2436:                                    case 2:  VR2_g4;  break;
                   2437:                                    case 3:  VR3_g4;  break;
                   2438:                                    };
                   2439:                                a0=a1;  a0_color=flip_color(a0_color);
                   2440:                                detect_a1a2;
                   2441:                                detect_b1b2;
                   2442:                                }
                   2443:                        else {  /* HORIZONTAL mode */
                   2444:                                HORIZ_g4;
                   2445:                                a01=a1-a0; if(a0== -1) a01--;
                   2446:                                a12=a2-a1;
                   2447:                                if(a0_color==DST_white) {
                   2448:                                        Wrun_g4(a01);
                   2449:                                        Brun_g4(a12);
                   2450:                                        }
                   2451:                                else {  Brun_g4(a01);
                   2452:                                        Wrun_g4(a12);
                   2453:                                        };
                   2454:                                a0=a2;
                   2455:                                /* a0_color is unchanged */
                   2456:                                detect_a1a2;
                   2457:                                detect_b1b2;
                   2458:                                };
                   2459:                        };
                   2460:                }
                   2461:        else /* current line is blank */ {
                   2462:                a1=a2=wid;
                   2463: #if rg4_strict
                   2464:                while( a0 < wid ) {
                   2465: #else
                   2466:                while( a0 < wid-1 ) {
                   2467: #endif
                   2468:                        /* a0, a1, a2, b1, b2 are as defined in CCITT Rec. T.6 */
                   2469: #if DEBUG
                   2470:                        if(dbg_rg4_r)
                   2471:                            fprintf(stderr,"f(%d,%d,%d) b%d(%d,%d)\n",
                   2472:                                a0,a1,a2,pra-(pl->r),b1,b2);
                   2473: #endif
                   2474:                        if(b2<a1) /* PASS mode */ {
                   2475:                                PASS_g4;
                   2476:                                a0=b2;
                   2477:                                /* a0-color, a1, & a2 are unchanged */
                   2478:                                detect_b1b2;
                   2479:                                }
                   2480:                        else if((a1b1=a1-b1)<=3 && a1b1>= -3) {
                   2481:                                /* VERTICAL mode */
                   2482:                                switch(a1b1) {
                   2483:                                    case -3:  VL3_g4;  break;
                   2484:                                    case -2:  VL2_g4;  break;
                   2485:                                    case -1:  VL1_g4;  break;
                   2486:                                    case 0:  V0_g4;  break;
                   2487:                                    case 1:  VR1_g4;  break;
                   2488:                                    case 2:  VR2_g4;  break;
                   2489:                                    case 3:  VR3_g4;  break;
                   2490:                                    };
                   2491:                                a0=a1;  a0_color=flip_color(a0_color);
                   2492:                                /* a1, & a2 are unchanged */
                   2493:                                detect_b1b2;
                   2494:                                }
                   2495:                        else {  /* HORIZONTAL mode */
                   2496:                                HORIZ_g4;
                   2497:                                a01=a1-a0; if(a0== -1) a01--;
                   2498:                                a12=a2-a1;
                   2499:                                if(a0_color==DST_white) {
                   2500:                                        Wrun_g4(a01);
                   2501:                                        Brun_g4(a12);
                   2502:                                        }
                   2503:                                else {  Brun_g4(a01);
                   2504:                                        Wrun_g4(a12);
                   2505:                                        };
                   2506:                                a0=a2;
                   2507:                                /* a0_color, a1, & a2 are unchanged */
                   2508:                                detect_b1b2;
                   2509:                                };
                   2510:                        };
                   2511:                };
                   2512:        }
                   2513: 
                   2514: EOF_to_g4(f)
                   2515:     BITFILE *f;
                   2516: {   char *cs;
                   2517:        /* write EOFB */
                   2518:        EOFB_g4;
                   2519: #if DEBUG
                   2520:        if(dbg_rg4_e) fprintf(stderr,"EOF\n");
                   2521: #endif
                   2522:        }
                   2523: 

unix.superglobalmegacorp.com

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