1 /* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 artofcode LLC.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /*$Id: scfd.c,v 1.3.4.1.2.1 2003/01/17 00:49:05 giles Exp $ */
20 /* CCITTFax decoding filter */
21 #include "stdio_.h"		/* includes std.h */
22 #include "memory_.h"
23 #include "gdebug.h"
24 #include "strimpl.h"
25 #include "scf.h"
26 #include "scfx.h"
27 
28 /* ------ CCITTFaxDecode ------ */
29 
30 private_st_CFD_state();
31 
32 /* Set default parameter values. */
33 private void
s_CFD_set_defaults(register stream_state * st)34 s_CFD_set_defaults(register stream_state * st)
35 {
36     stream_CFD_state *const ss = (stream_CFD_state *) st;
37 
38     s_CFD_set_defaults_inline(ss);
39 }
40 
41 /* Initialize CCITTFaxDecode filter */
42 private int
s_CFD_init(stream_state * st)43 s_CFD_init(stream_state * st)
44 {
45     stream_CFD_state *const ss = (stream_CFD_state *) st;
46     int raster = ss->raster =
47 	ROUND_UP((ss->Columns + 7) >> 3, ss->DecodedByteAlign);
48     byte white = (ss->BlackIs1 ? 0 : 0xff);
49 
50     s_hcd_init_inline(ss);
51     /* Because skip_white_pixels can look as many as 4 bytes ahead, */
52     /* we need to allow 4 extra bytes at the end of the row buffers. */
53     ss->lbuf = gs_alloc_bytes(st->memory, raster + 4, "CFD lbuf");
54     ss->lprev = 0;
55     if (ss->lbuf == 0)
56 	return ERRC;
57 /****** WRONG ******/
58     if (ss->K != 0) {
59 	ss->lprev = gs_alloc_bytes(st->memory, raster + 4, "CFD lprev");
60 	if (ss->lprev == 0)
61 	    return ERRC;
62 /****** WRONG ******/
63 	/* Clear the initial reference line for 2-D encoding. */
64 	memset(ss->lbuf, white, raster);
65 	/* Ensure that the scan of the reference line will stop. */
66 	ss->lbuf[raster] = 0xa0;
67     }
68     ss->k_left = min(ss->K, 0);
69     ss->run_color = 0;
70     ss->damaged_rows = 0;
71     ss->skipping_damage = false;
72     ss->cbit = 0;
73     ss->uncomp_run = 0;
74     ss->rows_left = (ss->Rows <= 0 || ss->EndOfBlock ? -1 : ss->Rows + 1);
75     ss->rpos = ss->wpos = raster - 1;
76     ss->eol_count = 0;
77     ss->invert = white;
78     ss->min_left = 1;
79     return 0;
80 }
81 
82 /* Release the filter. */
83 private void
s_CFD_release(stream_state * st)84 s_CFD_release(stream_state * st)
85 {
86     stream_CFD_state *const ss = (stream_CFD_state *) st;
87 
88     gs_free_object(st->memory, ss->lprev, "CFD lprev(close)");
89     gs_free_object(st->memory, ss->lbuf, "CFD lbuf(close)");
90 }
91 
92 /* Declare the variables that hold the state. */
93 #define cfd_declare_state\
94 	hcd_declare_state;\
95 	register byte *q;\
96 	int qbit
97 /* Load the state from the stream. */
98 #define cfd_load_state()\
99 	hcd_load_state(),\
100 	q = ss->lbuf + ss->wpos, qbit = ss->cbit
101 /* Store the state back in the stream. */
102 #define cfd_store_state()\
103 	hcd_store_state(),\
104 	ss->wpos = q - ss->lbuf, ss->cbit = qbit
105 
106 /* Macros to get blocks of bits from the input stream. */
107 /* Invariants: 0 <= bits_left <= bits_size; */
108 /* bits [bits_left-1..0] contain valid data. */
109 
110 #define avail_bits(n) hcd_bits_available(n)
111 #define ensure_bits(n, outl) hcd_ensure_bits(n, outl)
112 #define peek_bits(n) hcd_peek_bits(n)
113 #define peek_var_bits(n) hcd_peek_var_bits(n)
114 #define skip_bits(n) hcd_skip_bits(n)
115 
116 /* Get a run from the stream. */
117 #ifdef DEBUG
118 #  define IF_DEBUG(expr) expr
119 #else
120 #  define IF_DEBUG(expr) DO_NOTHING
121 #endif
122 #define get_run(decode, initial_bits, min_bits, runlen, str, locl, outl)\
123     BEGIN\
124 	const cfd_node *np;\
125 	int clen;\
126 \
127 	HCD_ENSURE_BITS_ELSE(initial_bits) {\
128 	    /* We might still have enough bits for the specific code. */\
129 	    if (bits_left < min_bits) goto outl;\
130 	    np = &decode[hcd_peek_bits_left() << (initial_bits - bits_left)];\
131 	    if ((clen = np->code_length) > bits_left) goto outl;\
132 	    goto locl;\
133 	}\
134 	np = &decode[peek_bits(initial_bits)];\
135 	if ((clen = np->code_length) > initial_bits) {\
136 		IF_DEBUG(uint init_bits = peek_bits(initial_bits));\
137 		if (!avail_bits(clen)) goto outl;\
138 		clen -= initial_bits;\
139 		skip_bits(initial_bits);\
140 		ensure_bits(clen, outl);		/* can't goto outl */\
141 		np = &decode[np->run_length + peek_var_bits(clen)];\
142 		if_debug4('W', "%s xcode=0x%x,%d rlen=%d\n", str,\
143 			  (init_bits << np->code_length) +\
144 			    peek_var_bits(np->code_length),\
145 			  initial_bits + np->code_length,\
146 			  np->run_length);\
147 		skip_bits(np->code_length);\
148 	} else {\
149     locl:	if_debug4('W', "%s code=0x%x,%d rlen=%d\n", str,\
150 			  peek_var_bits(clen), clen, np->run_length);\
151 		skip_bits(clen);\
152 	}\
153 	runlen = np->run_length;\
154     END
155 
156 /* Skip data bits for a white run. */
157 /* rlen is either less than 64, or a multiple of 64. */
158 #define skip_data(rlen, makeup_label)\
159 	if ( (qbit -= rlen) < 0 )\
160 	{	q -= qbit >> 3, qbit &= 7;\
161 		if ( rlen >= 64 ) goto makeup_label;\
162 	}
163 
164 /* Invert data bits for a black run. */
165 /* If rlen >= 64, execute makeup_action: this is to handle */
166 /* makeup codes efficiently, since these are always a multiple of 64. */
167 #define invert_data(rlen, black_byte, makeup_action, d)\
168 	if ( rlen > qbit )\
169 	{	*q++ ^= (1 << qbit) - 1;\
170 		rlen -= qbit;\
171 		switch ( rlen >> 3 )\
172 		{\
173 		case 7:		/* original rlen possibly >= 64 */\
174 			if ( rlen + qbit >= 64 ) goto d;\
175 			*q++ = black_byte;\
176 		case 6: *q++ = black_byte;\
177 		case 5: *q++ = black_byte;\
178 		case 4: *q++ = black_byte;\
179 		case 3: *q++ = black_byte;\
180 		case 2: *q++ = black_byte;\
181 		case 1: *q = black_byte;\
182 			rlen &= 7;\
183 			if ( !rlen ) { qbit = 0; break; }\
184 			q++;\
185 		case 0:			/* know rlen != 0 */\
186 			qbit = 8 - rlen;\
187 			*q ^= 0xff << qbit;\
188 			break;\
189 		default:	/* original rlen >= 64 */\
190 d:			memset(q, black_byte, rlen >> 3);\
191 			q += rlen >> 3;\
192 			rlen &= 7;\
193 			if ( !rlen ) qbit = 0, q--;\
194 			else qbit = 8 - rlen, *q ^= 0xff << qbit;\
195 			makeup_action;\
196 		}\
197 	}\
198 	else\
199 		qbit -= rlen,\
200 		*q ^= ((1 << rlen) - 1) << qbit
201 
202 /* Buffer refill for CCITTFaxDecode filter */
203 private int cf_decode_eol(P2(stream_CFD_state *, stream_cursor_read *));
204 private int cf_decode_1d(P2(stream_CFD_state *, stream_cursor_read *));
205 private int cf_decode_2d(P2(stream_CFD_state *, stream_cursor_read *));
206 private int cf_decode_uncompressed(P2(stream_CFD_state *, stream_cursor_read *));
207 private int
s_CFD_process(stream_state * st,stream_cursor_read * pr,stream_cursor_write * pw,bool last)208 s_CFD_process(stream_state * st, stream_cursor_read * pr,
209 	      stream_cursor_write * pw, bool last)
210 {
211     stream_CFD_state *const ss = (stream_CFD_state *) st;
212     int wstop = ss->raster - 1;
213     int eol_count = ss->eol_count;
214     int k_left = ss->k_left;
215     int rows_left = ss->rows_left;
216     int status = 0;
217 
218 #ifdef DEBUG
219     const byte *rstart = pr->ptr;
220     const byte *wstart = pw->ptr;
221 
222 #endif
223 
224   top:
225 #ifdef DEBUG
226     {
227 	hcd_declare_state;
228 	hcd_load_state();
229 	if_debug8('w', "\
230 [w]CFD_process top: eol_count=%d, k_left=%d, rows_left=%d\n\
231     bits=0x%lx, bits_left=%d, read %u, wrote %u%s\n",
232 		  eol_count, k_left, rows_left,
233 		  (ulong) bits, bits_left,
234 		  (uint) (p - rstart), (uint) (pw->ptr - wstart),
235 		  (ss->skipping_damage ? ", skipping damage" : ""));
236     }
237 #endif
238     if (ss->skipping_damage) {	/* Skip until we reach an EOL. */
239 	hcd_declare_state;
240 	int skip;
241 
242 	status = 0;
243 	do {
244 	    switch ((skip = cf_decode_eol(ss, pr))) {
245 		default:	/* not EOL */
246 		    hcd_load_state();
247 		    skip_bits(-skip);
248 		    hcd_store_state();
249 		    continue;
250 		case 0:	/* need more input */
251 		    goto out;
252 		case 1:	/* EOL */
253 		    {		/* Back up over the EOL. */
254 			hcd_load_state();
255 			bits_left += run_eol_code_length;
256 			hcd_store_state();
257 		    }
258 		    ss->skipping_damage = false;
259 	    }
260 	}
261 	while (ss->skipping_damage);
262 	ss->damaged_rows++;
263     }
264     /*
265      * Check for a completed input scan line.  This isn't quite as
266      * simple as it seems, because we could have run out of input data
267      * between a makeup code and a 0-length termination code, or in a
268      * 2-D line before a final horizontal code with a 0-length second
269      * run.  There's probably a way to think about this situation that
270      * doesn't require a special check, but I haven't found it yet.
271      */
272     if (ss->wpos == wstop && ss->cbit <= (-ss->Columns & 7) &&
273 	(k_left == 0 ? !(ss->run_color & ~1) : ss->run_color == 0)
274 	) {			/* Check for completed data to be copied to the client. */
275 	/* (We could avoid the extra copy step for 1-D, but */
276 	/* it's simpler not to, and it doesn't cost much.) */
277 	if (ss->rpos < ss->wpos) {
278 	    stream_cursor_read cr;
279 
280 	    cr.ptr = ss->lbuf + ss->rpos;
281 	    cr.limit = ss->lbuf + ss->wpos;
282 	    status = stream_move(&cr, pw);
283 	    ss->rpos = cr.ptr - ss->lbuf;
284 	    if (status)
285 		goto out;
286 	}
287 	if (rows_left > 0 && --rows_left == 0) {
288 	    status = EOFC;
289 	    goto out;
290 	}
291 	if (ss->K != 0) {
292 	    byte *prev_bits = ss->lprev;
293 
294 	    ss->lprev = ss->lbuf;
295 	    ss->lbuf = prev_bits;
296 	    if (ss->K > 0)
297 		k_left = (k_left == 0 ? ss->K : k_left) - 1;
298 	}
299 	ss->rpos = ss->wpos = -1;
300 	ss->eol_count = eol_count = 0;
301 	ss->cbit = 0;
302 	ss->invert = (ss->BlackIs1 ? 0 : 0xff);
303 	memset(ss->lbuf, ss->invert, wstop + 1);
304 	ss->run_color = 0;
305 	/*
306 	 * If EndOfLine is true, we want to include the byte padding
307 	 * in the string of initial zeros in the EOL.  If EndOfLine
308 	 * is false, we aren't sure what we should do....
309 	 */
310 	if (ss->EncodedByteAlign & !ss->EndOfLine)
311 	    ss->bits_left &= ~7;
312     }
313     /* If we're between scan lines, scan for EOLs. */
314     if (ss->wpos < 0) {
315 	while ((status = cf_decode_eol(ss, pr)) > 0) {
316 	    if_debug0('w', "[w]EOL\n");
317 	    /* If we are in a Group 3 mixed regime, */
318 	    /* check the next bit for 1- vs. 2-D. */
319 	    if (ss->K > 0) {
320 		hcd_declare_state;
321 		hcd_load_state();
322 		ensure_bits(1, out);	/* can't fail */
323 		k_left = (peek_bits(1) ? 0 : 1);
324 		skip_bits(1);
325 		hcd_store_state();
326 	    }
327 	    ++eol_count;
328 	    /*
329 	     * According to Adobe, the decoder should always check for
330 	     * the EOD sequence, regardless of EndOfBlock: the Red Book's
331 	     * documentation of EndOfBlock is wrong.
332 	     */
333 	    if (eol_count == (ss->K < 0 ? 2 : 6)) {
334 		status = EOFC;
335 		goto out;
336 	    }
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, %d left\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 private 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 private 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 private 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     return status;
713     /*
714      * We handle horizontal decoding here, so that we can
715      * branch back into it if we run out of input data.
716      */
717     /* White, then black. */
718   hww:get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
719 	      rlen, " white", wwl, outww);
720     if ((count -= rlen) < end_count) {
721 	status = ERRC;
722 	goto out;
723     }
724     skip_data(rlen, hww);
725     /* Handle the second half of a white-black horizontal code. */
726   hwb:get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
727 	      rlen, " black", wbl, outwb);
728     if ((count -= rlen) < end_count) {
729 	status = ERRC;
730 	goto out;
731     }
732     invert_data(rlen, black_byte, goto hwb, ihwb);
733     goto top;
734   outww:ss->run_color = -2;
735     goto out0;
736   outwb:ss->run_color = 1;
737     goto out0;
738     /* Black, then white. */
739   hbb:get_run(cf_black_decode, cfd_black_initial_bits, cfd_black_min_bits,
740 	      rlen, " black", bbl, outbb);
741     if ((count -= rlen) < end_count) {
742 	status = ERRC;
743 	goto out;
744     }
745     invert_data(rlen, black_byte, goto hbb, ihbb);
746     /* Handle the second half of a black-white horizontal code. */
747   hbw:get_run(cf_white_decode, cfd_white_initial_bits, cfd_white_min_bits,
748 	      rlen, " white", bwl, outbw);
749     if ((count -= rlen) < end_count) {
750 	status = ERRC;
751 	goto out;
752     }
753     skip_data(rlen, hbw);
754     goto top;
755   outbb:ss->run_color = 2;
756     goto out0;
757   outbw:ss->run_color = -1;
758     goto out0;
759 }
760 
761 #if 1				/*************** */
762 private int
cf_decode_uncompressed(stream_CFD_state * ss,stream_cursor_read * pr)763 cf_decode_uncompressed(stream_CFD_state * ss, stream_cursor_read * pr)
764 {
765     return ERRC;
766 }
767 #else /*************** */
768 
769 /* Decode uncompressed data. */
770 /* (Not tested: no sample data available!) */
771 /****** DOESN'T CHECK FOR OVERFLOWING SCAN LINE ******/
772 private int
cf_decode_uncompressed(stream * s)773 cf_decode_uncompressed(stream * s)
774 {
775     cfd_declare_state;
776     const cfd_node *np;
777     int clen, rlen;
778 
779     cfd_load_state();
780     while (1) {
781 	ensure_bits(cfd_uncompressed_initial_bits, NOOUT);
782 	np = &cf_uncompressed_decode[peek_bits(cfd_uncompressed_initial_bits)];
783 	clen = np->code_length;
784 	rlen = np->run_length;
785 	if (clen > cfd_uncompressed_initial_bits) {	/* Must be an exit code. */
786 	    break;
787 	}
788 	if (rlen == cfd_uncompressed_initial_bits) {	/* Longest representable white run */
789 	    if_debug1('W', "[wu]%d\n", rlen);
790 	    if ((qbit -= cfd_uncompressed_initial_bits) < 0)
791 		qbit += 8, q++;
792 	} else {
793 	    if_debug1('W', "[wu]%d+1\n", rlen);
794 	    if (qbit -= rlen < 0)
795 		qbit += 8, q++;
796 	    *q ^= 1 << qbit;
797 	}
798 	skip_bits(clen);
799     }
800     clen -= cfd_uncompressed_initial_bits;
801     skip_bits(cfd_uncompressed_initial_bits);
802     ensure_bits(clen, NOOUT);
803     np = &cf_uncompressed_decode[rlen + peek_var_bits(clen)];
804     rlen = np->run_length;
805     skip_bits(np->code_length);
806     if_debug1('w', "[wu]exit %d\n", rlen);
807     if (rlen >= 0) {		/* Valid exit code, rlen = 2 * run length + next polarity */
808 	if ((qbit -= rlen >> 1) < 0)
809 	    qbit += 8, q++;
810 	rlen &= 1;
811     }
812   out:
813 /******* WRONG ******/
814     cfd_store_state();
815     return rlen;
816 }
817 
818 #endif /*************** */
819 
820 /* Stream template */
821 const stream_template s_CFD_template =
822 {&st_CFD_state, s_CFD_init, s_CFD_process, 1, 1, s_CFD_release,
823  s_CFD_set_defaults
824 };
825