Coverage Report

Created: 2022-10-31 07:00

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