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