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