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