1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* CCITTFax decoding filter */
18 #include "stdio_.h"		/* includes std.h */
19 #include "memory_.h"
20 #include "gdebug.h"
21 #include "strimpl.h"
22 #include "scf.h"
23 #include "scfx.h"
24 
25 /* ------ CCITTFaxDecode ------ */
26 
27 private_st_CFD_state();
28 
29 #define CFD_BUFFER_SLOP 4
30 
31 static inline int
32 get_run(stream_CFD_state *ss, stream_cursor_read *pr, const cfd_node decode[],
33     int initial_bits, int min_bits, int *runlen, const char *str);
34 
35 static inline int
36 invert_data(stream_CFD_state *ss, stream_cursor_read *pr, int *rlen, byte black_byte);
37 
38 static inline int
39 skip_data(stream_CFD_state *ss, stream_cursor_read *pr, int rlen);
40 
41 /* Set default parameter values. */
42 static void
s_CFD_set_defaults(register stream_state * st)43 s_CFD_set_defaults(register stream_state * st)
44 {
45     stream_CFD_state *const ss = (stream_CFD_state *) st;
46 
47     s_CFD_set_defaults_inline(ss);
48 }
49 
50 /* Initialize CCITTFaxDecode filter */
51 static int
s_CFD_init(stream_state * st)52 s_CFD_init(stream_state * st)
53 {
54     stream_CFD_state *const ss = (stream_CFD_state *) st;
55     int raster = ss->raster =
56         ROUND_UP((ss->Columns + 7) >> 3, ss->DecodedByteAlign);
57     byte white = (ss->BlackIs1 ? 0 : 0xff);
58 
59     s_hcd_init_inline(ss);
60     /* Because skip_white_pixels can look as many as 4 bytes ahead, */
61     /* we need to allow 4 extra bytes at the end of the row buffers. */
62     ss->lbuf = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP, "CFD lbuf");
63     ss->lprev = 0;
64     if (ss->lbuf == 0)
65         return ERRC;		/****** WRONG ******/
66     memset(ss->lbuf, white, raster);
67     memset(ss->lbuf + raster, 0xaa, CFD_BUFFER_SLOP);  /* for Valgrind */
68     if (ss->K != 0) {
69         ss->lprev = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP, "CFD lprev");
70         if (ss->lprev == 0)
71             return ERRC;	/****** WRONG ******/
72         /* Clear the initial reference line for 2-D encoding. */
73         memset(ss->lprev, white, raster);
74         /* Ensure that the scan of the reference line will stop. */
75         memset(ss->lprev + raster, 0xaa, CFD_BUFFER_SLOP);
76     }
77     ss->k_left = min(ss->K, 0);
78     ss->run_color = 0;
79     ss->damaged_rows = 0;
80     ss->skipping_damage = false;
81     ss->cbit = 0;
82     ss->uncomp_run = 0;
83     ss->rows_left = (ss->Rows <= 0 || ss->EndOfBlock ? -1 : ss->Rows);
84     ss->row = 0;
85     ss->rpos = ss->wpos = -1;
86     ss->eol_count = 0;
87     ss->invert = white;
88     ss->min_left = 1;
89     return 0;
90 }
91 
92 /* Release the filter. */
93 static void
s_CFD_release(stream_state * st)94 s_CFD_release(stream_state * st)
95 {
96     stream_CFD_state *const ss = (stream_CFD_state *) st;
97 
98     gs_free_object(st->memory, ss->lprev, "CFD lprev(close)");
99     gs_free_object(st->memory, ss->lbuf, "CFD lbuf(close)");
100 }
101 
102 /* Declare the variables that hold the state. */
103 #define cfd_declare_state\
104         hcd_declare_state;\
105         register byte *q;\
106         int qbit
107 /* Load the state from the stream. */
108 #define cfd_load_state()\
109         hcd_load_state(),\
110         q = ss->lbuf + ss->wpos, qbit = ss->cbit
111 /* Store the state back in the stream. */
112 #define cfd_store_state()\
113         hcd_store_state(),\
114         ss->wpos = q - ss->lbuf, ss->cbit = qbit
115 
116 /* Macros to get blocks of bits from the input stream. */
117 /* Invariants: 0 <= bits_left <= bits_size; */
118 /* bits [bits_left-1..0] contain valid data. */
119 
120 #define avail_bits(n) hcd_bits_available(n)
121 #define ensure_bits(n, outl) hcd_ensure_bits(n, outl)
122 #define peek_bits(n) hcd_peek_bits(n)
123 #define peek_var_bits(n) hcd_peek_var_bits(n)
124 #define skip_bits(n) hcd_skip_bits(n)
125 
126 /* Get a run from the stream. */
127 #ifdef DEBUG
128 #  define IF_DEBUG(expr) expr
129 #else
130 #  define IF_DEBUG(expr) DO_NOTHING
131 #endif
132 
get_run(stream_CFD_state * ss,stream_cursor_read * pr,const cfd_node decode[],int initial_bits,int min_bits,int * runlen,const char * str)133 static inline int get_run(stream_CFD_state *ss, stream_cursor_read *pr, const cfd_node decode[],
134            int initial_bits, int min_bits, int *runlen, const char *str)
135 {
136     cfd_declare_state;
137     const cfd_node *np;
138     int clen;
139     cfd_load_state();
140 
141     HCD_ENSURE_BITS_ELSE(initial_bits) {
142         /* We might still have enough bits for the specific code. */
143         if (bits_left < min_bits)
144             goto outl;
145         np = &decode[hcd_peek_bits_left() << (initial_bits - bits_left)];
146         if ((clen = np->code_length) > bits_left)
147             goto outl;
148         goto locl;
149     }
150     np = &decode[peek_bits(initial_bits)];
151     if ((clen = np->code_length) > initial_bits) {
152             IF_DEBUG(uint init_bits = peek_bits(initial_bits));
153             if (!avail_bits(clen)) goto outl;
154             clen -= initial_bits;
155             skip_bits(initial_bits);
156             ensure_bits(clen, outl);                /* can't goto outl */
157             np = &decode[np->run_length + peek_var_bits(clen)];
158             if_debug4('W', "%s xcode=0x%x,%d rlen=%d\n", str,
159                       (init_bits << np->code_length) +
160                         peek_var_bits(np->code_length),
161                       initial_bits + np->code_length,
162                       np->run_length);
163             skip_bits(np->code_length);
164     } else {
165 locl:
166        if_debug4('W', "%s code=0x%x,%d rlen=%d\n", str,
167                       peek_var_bits(clen), clen, np->run_length);
168        skip_bits(clen);
169     }
170     *runlen = np->run_length;
171 
172     cfd_store_state();
173     return(0);
174 outl:
175     cfd_store_state();
176     return(-1);
177 }
178 
179 
180 /* Skip data bits for a white run. */
181 /* rlen is either less than 64, or a multiple of 64. */
skip_data(stream_CFD_state * ss,stream_cursor_read * pr,int rlen)182 static inline int skip_data(stream_CFD_state *ss, stream_cursor_read *pr, int rlen)
183 {
184     cfd_declare_state;
185     cfd_load_state();
186     (void)rlimit;
187 
188     if ( (qbit -= rlen) < 0 )
189     {
190         q -= qbit >> 3, qbit &= 7;
191         if ( rlen >= 64 ) {
192             cfd_store_state();
193             return(-1);
194         }
195     }
196     cfd_store_state();
197     return(0);
198 }
199 
200 
201 /* Invert data bits for a black run. */
202 /* If rlen >= 64, execute makeup_action: this is to handle */
203 /* makeup codes efficiently, since these are always a multiple of 64. */
204 
invert_data(stream_CFD_state * ss,stream_cursor_read * pr,int * rlen,byte black_byte)205 static inline int invert_data(stream_CFD_state *ss, stream_cursor_read *pr, int *rlen, byte black_byte)
206 {
207     cfd_declare_state;
208     cfd_load_state();
209     (void)rlimit;
210 
211     if (q >= ss->lbuf + ss->raster + CFD_BUFFER_SLOP) {
212         return(-1);
213     }
214 
215     if ( (*rlen) > qbit )
216     {
217         if (q + ((*rlen - qbit) >> 3) > ss->lbuf + ss->raster + CFD_BUFFER_SLOP) {
218             return(-1);
219         }
220 
221         if (q >= ss->lbuf) {
222           *q++ ^= (1 << qbit) - 1;
223         }
224         else {
225             q++;
226         }
227         (*rlen) -= qbit;
228 
229         switch ( (*rlen) >> 3 )
230         {
231           case 7:         /* original rlen possibly >= 64 */
232                   if ( (*rlen) + qbit >= 64 ) {
233                     goto d;
234                   }
235                   *q++ = black_byte;
236           case 6: *q++ = black_byte;
237           case 5: *q++ = black_byte;
238           case 4: *q++ = black_byte;
239           case 3: *q++ = black_byte;
240           case 2: *q++ = black_byte;
241           case 1: *q = black_byte;
242               (*rlen) &= 7;
243               if ( !(*rlen) ) {
244                   qbit = 0;
245                   break;
246               }
247               q++;
248           case 0:                 /* know rlen != 0 */
249               qbit = 8 - (*rlen);
250               *q ^= 0xff << qbit;
251               break;
252           default:        /* original rlen >= 64 */
253 d:            memset(q, black_byte, (*rlen) >> 3);
254               q += (*rlen) >> 3;
255               (*rlen) &= 7;
256               if ( !(*rlen) ) {
257                 qbit = 0;
258                 q--;
259               }
260               else {
261                 qbit = 8 - (*rlen);
262                 *q ^= 0xff << qbit;
263               }
264               cfd_store_state();
265               return(-1);
266           }
267     }
268     else {
269             qbit -= (*rlen),
270             *q ^= ((1 << (*rlen)) - 1) << qbit;
271 
272     }
273     cfd_store_state();
274     return(0);
275 }
276 
277 
278 /* Buffer refill for CCITTFaxDecode filter */
279 static int cf_decode_eol(stream_CFD_state *, stream_cursor_read *);
280 static int cf_decode_1d(stream_CFD_state *, stream_cursor_read *);
281 static int cf_decode_2d(stream_CFD_state *, stream_cursor_read *);
282 static int cf_decode_uncompressed(stream_CFD_state *, stream_cursor_read *);
283 static int
s_CFD_process(stream_state * st,stream_cursor_read * pr,stream_cursor_write * pw,bool last)284 s_CFD_process(stream_state * st, stream_cursor_read * pr,
285               stream_cursor_write * pw, bool last)
286 {
287     stream_CFD_state *const ss = (stream_CFD_state *) st;
288     int wstop = ss->raster - 1;
289     int eol_count = ss->eol_count;
290     int k_left = ss->k_left;
291     int rows_left = ss->rows_left;
292     int status = 0;
293 
294 #ifdef DEBUG
295     const byte *rstart = pr->ptr;
296     const byte *wstart = pw->ptr;
297 
298 #endif
299 
300   top:
301 #ifdef DEBUG
302     {
303         hcd_declare_state;
304         hcd_load_state();
305         (void)rlimit;
306         if_debug8m('w', ss->memory,
307                    "[w]CFD_process top: eol_count=%d, k_left=%d, rows_left=%d\n"
308                    "    bits=0x%lx, bits_left=%d, read %u, wrote %u%s\n",
309                    eol_count, k_left, rows_left,
310                    (ulong) bits, bits_left,
311                    (uint) (p - rstart), (uint) (pw->ptr - wstart),
312                    (ss->skipping_damage ? ", skipping damage" : ""));
313     }
314 #endif
315     if (ss->skipping_damage) {	/* Skip until we reach an EOL. */
316         hcd_declare_state;
317         int skip;
318         (void)rlimit;
319 
320         status = 0;
321         do {
322             switch ((skip = cf_decode_eol(ss, pr))) {
323                 default:	/* not EOL */
324                     hcd_load_state();
325                     skip_bits(-skip);
326                     hcd_store_state();
327                     continue;
328                 case 0:	/* need more input */
329                     goto out;
330                 case 1:	/* EOL */
331                     {		/* Back up over the EOL. */
332                         hcd_load_state();
333                         bits_left += run_eol_code_length;
334                         hcd_store_state();
335                     }
336                     ss->skipping_damage = false;
337             }
338         }
339         while (ss->skipping_damage);
340         ss->damaged_rows++;
341     }
342     /*
343      * Check for a completed input scan line.  This isn't quite as
344      * simple as it seems, because we could have run out of input data
345      * between a makeup code and a 0-length termination code, or in a
346      * 2-D line before a final horizontal code with a 0-length second
347      * run.  There's probably a way to think about this situation that
348      * doesn't require a special check, but I haven't found it yet.
349      */
350     if (ss->wpos == wstop && ss->cbit <= (-ss->Columns & 7) &&
351         (k_left == 0 ? !(ss->run_color & ~1) : ss->run_color == 0)
352         ) {			/* Check for completed data to be copied to the client. */
353         /* (We could avoid the extra copy step for 1-D, but */
354         /* it's simpler not to, and it doesn't cost much.) */
355         if (ss->rpos < ss->wpos) {
356             stream_cursor_read cr;
357 
358             cr.ptr = ss->lbuf + ss->rpos;
359             cr.limit = ss->lbuf + ss->wpos;
360             status = stream_move(&cr, pw);
361             ss->rpos = cr.ptr - ss->lbuf;
362             if (status)
363                 goto out;
364         }
365         ss->row++;
366         if (rows_left > 0 && --rows_left == 0)
367             goto ck_eol;	/* handle EOD if it is present */
368         if (ss->K != 0) {
369             byte *prev_bits = ss->lprev;
370 
371             ss->lprev = ss->lbuf;
372             ss->lbuf = prev_bits;
373             if (ss->K > 0)
374                 k_left = (k_left == 0 ? ss->K : k_left) - 1;
375         }
376         ss->rpos = ss->wpos = -1;
377         ss->eol_count = eol_count = 0;
378         ss->cbit = 0;
379         ss->invert = (ss->BlackIs1 ? 0 : 0xff);
380         memset(ss->lbuf, ss->invert, wstop + 1);
381         ss->run_color = 0;
382         /*
383          * If EndOfLine is true, we want to include the byte padding
384          * in the string of initial zeros in the EOL.  If EndOfLine
385          * is false, we aren't sure what we should do....
386          */
387         if (ss->EncodedByteAlign && !ss->EndOfLine)
388             ss->bits_left &= ~7;
389     }
390     /* If we're between scan lines, scan for EOLs. */
391     if (ss->wpos < 0) {
392             /*
393              * According to Adobe, the decoder should always check for
394              * the EOD sequence, regardless of EndOfBlock: the Red Book's
395              * documentation of EndOfBlock is wrong.
396              */
397 ck_eol:
398         while ((status = cf_decode_eol(ss, pr)) > 0) {
399             if_debug0m('w', ss->memory, "[w]EOL\n");
400             /* If we are in a Group 3 mixed regime, */
401             /* check the next bit for 1- vs. 2-D. */
402             if (ss->K > 0) {
403                 hcd_declare_state;
404                 hcd_load_state();
405                 ensure_bits(1, out);	/* can't fail */
406                 k_left = (peek_bits(1) ? 0 : 1);
407                 skip_bits(1);
408                 hcd_store_state();
409             }
410             ++eol_count;
411             if (eol_count == (ss->K < 0 ? 2 : 6)) {
412                 status = EOFC;
413                 goto out;
414             }
415         }
416         if (rows_left == 0) {
417             status = EOFC;
418             goto out;
419         }
420         if (status == 0)	/* input empty while scanning EOLs */
421             goto out;
422         switch (eol_count) {
423             case 0:
424                 if (ss->EndOfLine) {	/* EOL is required, but none is present. */
425                     status = ERRC;
426                     goto check;
427                 }
428             case 1:
429                 break;
430             default:
431                 status = ERRC;
432                 goto check;
433         }
434     }
435     /* Now decode actual data. */
436     if (k_left < 0) {
437         if_debug0m('w', ss->memory, "[w2]new row\n");
438         status = cf_decode_2d(ss, pr);
439     } else if (k_left == 0) {
440         if_debug0m('w', ss->memory, "[w1]new row\n");
441         status = cf_decode_1d(ss, pr);
442     } else {
443         if_debug1m('w', ss->memory, "[w1]new 2-D row, k_left=%d\n", k_left);
444         status = cf_decode_2d(ss, pr);
445     }
446     if_debug3m('w', ss->memory, "[w]CFD status = %d, wpos = %d, cbit = %d\n",
447                status, ss->wpos, ss->cbit);
448   check:switch (status) {
449         case 1:		/* output full */
450             goto top;
451         case ERRC:
452             /* Check for special handling of damaged rows. */
453             if (ss->damaged_rows >= ss->DamagedRowsBeforeError ||
454                 !(ss->EndOfLine && ss->K >= 0)
455                 )
456                 break;
457             /* Substitute undamaged data if appropriate. */
458             /****** NOT IMPLEMENTED YET ******/
459             {
460                 ss->wpos = wstop;
461                 ss->cbit = -ss->Columns & 7;
462                 ss->run_color = 0;
463             }
464             ss->skipping_damage = true;
465             goto top;
466         default:
467             ss->damaged_rows = 0;	/* finished a good row */
468     }
469   out:ss->k_left = k_left;
470     ss->rows_left = rows_left;
471     ss->eol_count = eol_count;
472     if (ss->ErrsAsEOD && status < 0)
473         return EOFC;
474     return status;
475 }
476 
477 /*
478  * Decode a leading EOL, if any.
479  * If an EOL is present, skip over it and return 1;
480  * if no EOL is present, read no input and return -N, where N is the
481  * number of initial bits that can be skipped in the search for an EOL;
482  * if more input is needed, return 0.
483  * Note that if we detected an EOL, we know that we can back up over it;
484  * if we detected an N-bit non-EOL, we know that at least N bits of data
485  * are available in the buffer.
486  */
487 static int
cf_decode_eol(stream_CFD_state * ss,stream_cursor_read * pr)488 cf_decode_eol(stream_CFD_state * ss, stream_cursor_read * pr)
489 {
490     hcd_declare_state;
491     int zeros;
492     int look_ahead;
493 
494     hcd_load_state();
495     for (zeros = 0; zeros < run_eol_code_length - 1; zeros++) {
496         ensure_bits(1, out);
497         if (peek_bits(1))
498             return -(zeros + 1);
499         skip_bits(1);
500     }
501     /* We definitely have an EOL.  Skip further zero bits. */
502     look_ahead = (ss->K > 0 ? 2 : 1);
503     for (;;) {
504         ensure_bits(look_ahead, back);
505         if (peek_bits(1))
506             break;
507         skip_bits(1);
508     }
509     skip_bits(1);
510     hcd_store_state();
511     return 1;
512   back:			/*
513                                  * We ran out of data while skipping zeros.
514                                  * We know we are at a byte boundary, and have just skipped
515                                  * at least run_eol_code_length - 1 zeros.  However,
516                                  * bits_left may be 1 if look_ahead == 2.
517                                  */
518     bits &= (1 << bits_left) - 1;
519     bits_left += run_eol_code_length - 1;
520     hcd_store_state();
521   out:return 0;
522 }
523 
524 /* Decode a 1-D scan line. */
525 static int
cf_decode_1d(stream_CFD_state * ss,stream_cursor_read * pr)526 cf_decode_1d(stream_CFD_state * ss, stream_cursor_read * pr)
527 {
528     cfd_declare_state;
529     byte black_byte = (ss->BlackIs1 ? 0xff : 0);
530     int end_bit = -ss->Columns & 7;
531     byte *stop = ss->lbuf - 1 + ss->raster;
532     int run_color = ss->run_color;
533     int status;
534     int bcnt;
535     (void)rlimit;
536 
537     cfd_load_state();
538     if_debug1m('w', ss->memory, "[w1]entry run_color = %d\n", ss->run_color);
539     if (ss->run_color > 0)
540         goto db;
541     else
542         goto dw;
543 #define q_at_stop() (q >= stop && (qbit <= end_bit || q > stop))
544   top:run_color = 0;
545     if (q_at_stop())
546         goto done;
547   dw:				/* Decode a white run. */
548 
549     cfd_store_state();
550     status = get_run(ss, pr, cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
551             &bcnt, "[w1]white");
552     cfd_load_state();
553     if (status < 0) {
554         goto out0;
555     }
556 
557     if (bcnt < 0) {		/* exceptional situation */
558         switch (bcnt) {
559             case run_uncompressed:	/* Uncompressed data. */
560                 cfd_store_state();
561                 bcnt = cf_decode_uncompressed(ss, pr);
562                 if (bcnt < 0)
563                     return bcnt;
564                 cfd_load_state();
565                 if (bcnt)
566                     goto db;
567                 else
568                     goto dw;
569                 /*case run_error: */
570                 /*case run_zeros: *//* Premature end-of-line. */
571             default:
572                 status = ERRC;
573                 goto out;
574         }
575     }
576 
577     cfd_store_state();
578     status = skip_data(ss, pr, bcnt);
579     cfd_load_state();
580     if (status < 0) {
581         goto dwx;
582     }
583 
584     if (q_at_stop()) {
585         run_color = 0;		/* not inside a run */
586         goto done;
587     }
588     run_color = 1;
589   db:			/* Decode a black run. */
590 
591     cfd_store_state();
592     status = get_run(ss, pr, cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
593             &bcnt, "[w1]black");
594     cfd_load_state();
595     if (status < 0) {
596         goto out1;
597     }
598 
599     if (bcnt < 0) {		/* All exceptional codes are invalid here. */
600         /****** WRONG, uncompressed IS ALLOWED ******/
601         status = ERRC;
602         goto out;
603     }
604 
605     /* Invert bits designated by black run. */
606     cfd_store_state();
607     status = invert_data(ss, pr, &bcnt, black_byte);
608     cfd_load_state();
609     if (status < 0) {
610         goto dbx;
611     }
612 
613     goto top;
614   dwx:				/* If we run out of data after a makeup code, */
615     /* note that we are still processing a white run. */
616     run_color = -1;
617     goto dw;
618   dbx:				/* If we run out of data after a makeup code, */
619     /* note that we are still processing a black run. */
620     run_color = 2;
621     goto db;
622   done:if (q > stop || qbit < end_bit)
623         status = ERRC;
624     else
625         status = 1;
626   out:cfd_store_state();
627     ss->run_color = run_color;
628     if_debug1m('w', ss->memory, "[w1]exit run_color = %d\n", run_color);
629     return status;
630   out0:			/* We already set run_color to 0 or -1. */
631     status = 0;
632     goto out;
633   out1:			/* We already set run_color to 1 or 2. */
634     status = 0;
635     goto out;
636 }
637 
638 /* Decode a 2-D scan line. */
639 static int
cf_decode_2d(stream_CFD_state * ss,stream_cursor_read * pr)640 cf_decode_2d(stream_CFD_state * ss, stream_cursor_read * pr)
641 {
642     cfd_declare_state;
643     byte invert_white = (ss->BlackIs1 ? 0 : 0xff);
644     byte black_byte = ~invert_white;
645     byte invert = ss->invert;
646     int end_count = -ss->Columns & 7;
647     uint raster = ss->raster;
648     byte *q0 = ss->lbuf;
649     byte *prev_q01 = ss->lprev + 1;
650     byte *endptr = q0 - 1 + raster;
651     int init_count = raster << 3;
652     register int count;
653     int rlen;
654     int status;
655 
656     cfd_load_state();
657     count = ((endptr - q) << 3) + qbit;
658     endptr[1] = 0xa0;		/* a byte with some 0s and some 1s, */
659     /* to ensure run scan will stop */
660     if_debug1m('W', ss->memory, "[w2]raster=%d\n", raster);
661     switch (ss->run_color) {
662         case -2:
663             ss->run_color = 0;
664             goto hww;
665         case -1:
666             ss->run_color = 0;
667             goto hbw;
668         case 1:
669             ss->run_color = 0;
670             goto hwb;
671         case 2:
672             ss->run_color = 0;
673             goto hbb;
674             /*case 0: */
675     }
676   top:if (count <= end_count) {
677         status = (count < end_count ? ERRC : 1);
678         goto out;
679     }
680     /* If invert == invert_white, white and black have their */
681     /* correct meanings; if invert == ~invert_white, */
682     /* black and white are interchanged. */
683     if_debug1m('W', ss->memory, "[w2]%4d:\n", count);
684 #ifdef DEBUG
685     /* Check the invariant between q, qbit, and count. */
686     {
687         int pcount = (endptr - q) * 8 + qbit;
688 
689         if (pcount != count)
690             dmlprintf2(ss->memory, "[w2]Error: count=%d pcount=%d\n",
691                        count, pcount);
692     }
693 #endif
694     /*
695      * We could just use get_run here, but we can do better.  However,
696      * we must be careful to handle the case where the very last codes
697      * in the input stream are 1-bit "vertical 0" codes: we can't just
698      * use ensure_bits(3, ...) and go to get more data if it fails.
699      */
700     ensure_bits(3, out3);
701 #define vertical_0 (countof(cf2_run_vertical) / 2)
702     switch (peek_bits(3)) {
703         default /*4..7*/ :	/* vertical(0) */
704 v0:	    skip_bits(1);
705             rlen = vertical_0;
706             break;
707         case 2:		/* vertical(+1) */
708             skip_bits(3);
709             rlen = vertical_0 + 1;
710             break;
711         case 3:		/* vertical(-1) */
712             skip_bits(3);
713             rlen = vertical_0 - 1;
714             break;
715         case 1:		/* horizontal */
716             skip_bits(3);
717             if (invert == invert_white)
718                 goto hww;
719             else
720                 goto hbb;
721         case 0:		/* everything else */
722             cfd_store_state();
723             status = get_run(ss, pr, cf_2d_decode, cfd_2d_initial_bits, cfd_2d_min_bits,
724                     &rlen, "[w2]");
725             cfd_load_state();
726             if (status < 0) {
727                 goto out0;
728             }
729 
730             /* rlen may be run2_pass, run_uncompressed, or */
731             /* 0..countof(cf2_run_vertical)-1. */
732 rlen_lt_zero:
733             if (rlen < 0)
734                 switch (rlen) {
735                     case run2_pass:
736                         break;
737                     case run_uncompressed:
738                         {
739                             int which;
740 
741                             cfd_store_state();
742                             which = cf_decode_uncompressed(ss, pr);
743                             if (which < 0) {
744                                 status = which;
745                                 goto out;
746                             }
747                             cfd_load_state();
748 /****** ADJUST count ******/
749                             invert = (which ? ~invert_white : invert_white);
750                         }
751                         goto top;
752                     default:	/* run_error, run_zeros */
753                         status = ERRC;
754                         goto out;
755                 }
756     }
757     /* Interpreting the run requires scanning the */
758     /* previous ('reference') line. */
759     {
760         int prev_count = count;
761         byte prev_data;
762         int dlen;
763         static const byte count_bit[8] =
764         {0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40};
765         byte *prev_q = prev_q01 + (q - q0);
766         int plen;
767 
768         if (!(count & 7))
769             prev_q++;		/* because of skip macros */
770         prev_data = prev_q[-1] ^ invert;
771         /* Find the b1 transition. */
772         if ((prev_data & count_bit[prev_count & 7]) &&
773             (prev_count < init_count || invert != invert_white)
774             ) {			/* Look for changing white first. */
775             if_debug1m('W', ss->memory, " data=0x%x", prev_data);
776             skip_black_pixels(prev_data, prev_q,
777                               prev_count, invert, plen);
778             if (prev_count < end_count)		/* overshot */
779                 prev_count = end_count;
780             if_debug1m('W', ss->memory, " b1 other=%d", prev_count);
781         }
782         if (prev_count != end_count) {
783             if_debug1m('W', ss->memory, " data=0x%x", prev_data);
784             skip_white_pixels(prev_data, prev_q,
785                               prev_count, invert, plen);
786             if (prev_count < end_count)		/* overshot */
787                 prev_count = end_count;
788             if_debug1m('W', ss->memory, " b1 same=%d", prev_count);
789         }
790         /* b1 = prev_count; */
791         if (rlen == run2_pass) {	/* Pass mode.  Find b2. */
792             if (prev_count != end_count) {
793                 if_debug1m('W', ss->memory, " data=0x%x", prev_data);
794                 skip_black_pixels(prev_data, prev_q,
795                                   prev_count, invert, plen);
796                 if (prev_count < end_count)	/* overshot */
797                     prev_count = end_count;
798             }
799             /* b2 = prev_count; */
800             if_debug2m('W', ss->memory, " b2=%d, pass %d\n",
801                       prev_count, count - prev_count);
802         } else {		/* Vertical coding. */
803             /* Remember that count counts *down*. */
804             prev_count += rlen - vertical_0;	/* a1 */
805             if_debug2m('W', ss->memory, " vertical %d -> %d\n",
806                        (int)(rlen - vertical_0), prev_count);
807         }
808         /* Now either invert or skip from count */
809         /* to prev_count, and reset count. */
810         if (invert == invert_white) {	/* Skip data bits. */
811             q = endptr - (prev_count >> 3);
812             qbit = prev_count & 7;
813         } else {		/* Invert data bits. */
814             dlen = count - prev_count;
815 
816             cfd_store_state();
817             (void)invert_data(ss, pr, &dlen, black_byte);
818             cfd_load_state();
819         }
820         count = prev_count;
821         if (rlen >= 0)		/* vertical mode */
822             invert = ~invert;	/* polarity changes */
823     }
824     goto top;
825  out3:
826     if (bits_left > 0 && peek_bits(1)) {
827         /* This is a 1-bit "vertical 0" code, which we can still process. */
828         goto v0;
829     }
830     /* falls through */
831   out0:status = 0;
832     /* falls through */
833   out:cfd_store_state();
834     ss->invert = invert;
835     /* Ignore an error (missing EOFB/RTC when EndOfBlock == true) */
836     /* if we have finished all rows. */
837     if (status == ERRC && ss->Rows > 0 && ss->row > ss->Rows)
838         status = EOFC;
839     return status;
840     /*
841      * We handle horizontal decoding here, so that we can
842      * branch back into it if we run out of input data.
843      */
844     /* White, then black. */
845   hww:
846 
847     cfd_store_state();
848     status = get_run(ss, pr, cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
849               &rlen, " white");
850     cfd_load_state();
851     if (status < 0) {
852         goto outww;
853     }
854 
855     if ((count -= rlen) < end_count) {
856         status = ERRC;
857         goto out;
858     }
859     if (rlen < 0) goto rlen_lt_zero;
860 
861     cfd_store_state();
862     status = skip_data(ss, pr, rlen);
863     cfd_load_state();
864     if (status < 0) {
865         goto hww;
866     }
867 
868     /* Handle the second half of a white-black horizontal code. */
869   hwb:
870 
871     cfd_store_state();
872     status = get_run(ss, pr, cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
873               &rlen, " black");
874     cfd_load_state();
875     if (status < 0){
876         goto outwb;
877     }
878 
879     if ((count -= rlen) < end_count) {
880         status = ERRC;
881         goto out;
882     }
883     if (rlen < 0) goto rlen_lt_zero;
884 
885     cfd_store_state();
886     status = invert_data(ss, pr, &rlen, black_byte);
887     cfd_load_state();
888     if (status < 0) {
889         goto hwb;
890     }
891 
892     goto top;
893   outww:ss->run_color = -2;
894     goto out0;
895   outwb:ss->run_color = 1;
896     goto out0;
897     /* Black, then white. */
898   hbb:
899 
900     cfd_store_state();
901     status = get_run(ss, pr, cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
902               &rlen, " black");
903     cfd_load_state();
904     if (status < 0) {
905         goto outbb;
906     }
907 
908     if ((count -= rlen) < end_count) {
909         status = ERRC;
910         goto out;
911     }
912     if (rlen < 0) goto rlen_lt_zero;
913 
914     cfd_store_state();
915     status = invert_data(ss, pr, &rlen, black_byte);
916     cfd_load_state();
917     if (status < 0) {
918         goto hbb;
919     }
920 
921     /* Handle the second half of a black-white horizontal code. */
922   hbw:
923 
924     cfd_store_state();
925     status = get_run(ss, pr, cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
926               &rlen, " white");
927     cfd_load_state();
928     if (status < 0) {
929         goto outbw;
930     }
931 
932     if ((count -= rlen) < end_count) {
933         status = ERRC;
934         goto out;
935     }
936     if (rlen < 0) goto rlen_lt_zero;
937 
938     cfd_store_state();
939     status = skip_data(ss, pr, rlen);
940     cfd_load_state();
941     if (status < 0) {
942         goto hbw;
943     }
944 
945     goto top;
946   outbb:ss->run_color = 2;
947     goto out0;
948   outbw:ss->run_color = -1;
949     goto out0;
950 }
951 
952 #if 1				/*************** */
953 static int
cf_decode_uncompressed(stream_CFD_state * ss,stream_cursor_read * pr)954 cf_decode_uncompressed(stream_CFD_state * ss, stream_cursor_read * pr)
955 {
956     return ERRC;
957 }
958 #else /*************** */
959 
960 /* Decode uncompressed data. */
961 /* (Not tested: no sample data available!) */
962 /****** DOESN'T CHECK FOR OVERFLOWING SCAN LINE ******/
963 static int
cf_decode_uncompressed(stream * s)964 cf_decode_uncompressed(stream * s)
965 {
966     cfd_declare_state;
967     const cfd_node *np;
968     int clen, rlen;
969 
970     cfd_load_state();
971     while (1) {
972         ensure_bits(cfd_uncompressed_initial_bits, NOOUT);
973         np = &cf_uncompressed_decode[peek_bits(cfd_uncompressed_initial_bits)];
974         clen = np->code_length;
975         rlen = np->run_length;
976         if (clen > cfd_uncompressed_initial_bits) {	/* Must be an exit code. */
977             break;
978         }
979         if (rlen == cfd_uncompressed_initial_bits) {	/* Longest representable white run */
980             if_debug1m('W', s->memory, "[wu]%d\n", rlen);
981             if ((qbit -= cfd_uncompressed_initial_bits) < 0)
982                 qbit += 8, q++;
983         } else {
984             if_debug1m('W', s->memory, "[wu]%d+1\n", rlen);
985             if (qbit -= rlen < 0)
986                 qbit += 8, q++;
987             *q ^= 1 << qbit;
988         }
989         skip_bits(clen);
990     }
991     clen -= cfd_uncompressed_initial_bits;
992     skip_bits(cfd_uncompressed_initial_bits);
993     ensure_bits(clen, NOOUT);
994     np = &cf_uncompressed_decode[rlen + peek_var_bits(clen)];
995     rlen = np->run_length;
996     skip_bits(np->code_length);
997     if_debug1m('w', s->memory, "[wu]exit %d\n", rlen);
998     if (rlen >= 0) {		/* Valid exit code, rlen = 2 * run length + next polarity */
999         if ((qbit -= rlen >> 1) < 0)
1000             qbit += 8, q++;
1001         rlen &= 1;
1002     }
1003   out:				/******* WRONG ******/
1004     cfd_store_state();
1005     return rlen;
1006 }
1007 
1008 #endif /*************** */
1009 
1010 /* Stream template */
1011 const stream_template s_CFD_template =
1012 {&st_CFD_state, s_CFD_init, s_CFD_process, 1, 1, s_CFD_release,
1013  s_CFD_set_defaults
1014 };
1015