diff options
author | Henry Stiles <henry.stiles@artifex.com> | 1998-07-28 06:22:20 +0000 |
---|---|---|
committer | Henry Stiles <henry.stiles@artifex.com> | 1998-07-28 06:22:20 +0000 |
commit | 5fbdbaab7335a147a3a7890b5c6fc123926815db (patch) | |
tree | 154edc89b06c38333fd6d4b9abaf0ee8740ddf6a /gs/src/scfe.c | |
parent | 14cf10e3738f95f7864978c5a4778b50fb39524b (diff) |
This commit was generated by cvs2svn to compensate for changes in r257,
which included commits to RCS files with non-trunk default branches.
git-svn-id: http://svn.ghostscript.com/ghostpcl/trunk/ghostpcl@258 06663e23-700e-0410-b217-a244a6096597
Diffstat (limited to 'gs/src/scfe.c')
-rw-r--r-- | gs/src/scfe.c | 773 |
1 files changed, 393 insertions, 380 deletions
diff --git a/gs/src/scfe.c b/gs/src/scfe.c index c15306f95..14728558f 100644 --- a/gs/src/scfe.c +++ b/gs/src/scfe.c @@ -1,24 +1,24 @@ /* Copyright (C) 1992, 1995, 1997 Aladdin Enterprises. All rights reserved. - - This file is part of Aladdin Ghostscript. - - Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author - or distributor accepts any responsibility for the consequences of using it, - or for whether it serves any particular purpose or works at all, unless he - or she says so in writing. Refer to the Aladdin Ghostscript Free Public - License (the "License") for full details. - - Every copy of Aladdin Ghostscript must include a copy of the License, - normally in a plain ASCII text file named PUBLIC. The License grants you - the right to copy, modify and redistribute Aladdin Ghostscript, but only - under certain conditions described in the License. Among other things, the - License requires that the copyright notice and this notice be preserved on - all copies. -*/ + + This file is part of Aladdin Ghostscript. + + Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author + or distributor accepts any responsibility for the consequences of using it, + or for whether it serves any particular purpose or works at all, unless he + or she says so in writing. Refer to the Aladdin Ghostscript Free Public + License (the "License") for full details. + + Every copy of Aladdin Ghostscript must include a copy of the License, + normally in a plain ASCII text file named PUBLIC. The License grants you + the right to copy, modify and redistribute Aladdin Ghostscript, but only + under certain conditions described in the License. Among other things, the + License requires that the copyright notice and this notice be preserved on + all copies. + */ /* scfe.c */ /* CCITTFax encoding filter */ -#include "stdio_.h" /* includes std.h */ +#include "stdio_.h" /* includes std.h */ #include "memory_.h" #include "gdebug.h" #include "strimpl.h" @@ -30,7 +30,10 @@ /* Statistics */ #ifdef DEBUG -private struct _r1d { ulong termination[64], make_up[41]; } runs_1d[2]; +private struct _r1d { + ulong termination[64], make_up[41]; +} runs_1d[2]; + # define count_run(tab, i) ((tab)[i]++) #else # define count_run(cnt, n) DO_NOTHING @@ -73,7 +76,7 @@ private struct _r1d { ulong termination[64], make_up[41]; } runs_1d[2]; /* ------ CCITTFaxEncode ------ */ private_st_CFE_state(); - + #define ss ((stream_CFE_state *)st) private void s_CFE_release(P1(stream_state *)); @@ -85,249 +88,258 @@ private void s_CFE_release(P1(stream_state *)); /* Set default parameter values. */ private void -s_CFE_set_defaults(register stream_state *st) -{ s_CFE_set_defaults_inline(ss); +s_CFE_set_defaults(register stream_state * st) +{ + s_CFE_set_defaults_inline(ss); } /* Initialize CCITTFaxEncode filter */ private int -s_CFE_init(register stream_state *st) -{ int columns = ss->Columns; - int raster = ss->raster = - round_up((columns + 7) >> 3, ss->DecodedByteAlign); - - s_hce_init_inline(ss); - ss->count = raster << 3; /* starting a scan line */ - ss->lbuf = ss->lprev = 0; - if ( columns > cfe_max_width ) - return ERRC; /****** WRONG ******/ - /* Because skip_white_pixels can look as many as 4 bytes ahead, */ - /* we need to allow 4 extra bytes at the end of the row buffers. */ - ss->lbuf = gs_alloc_bytes(st->memory, raster + 4, - "CFE lbuf"); - if ( ss->lbuf == 0 ) - { s_CFE_release(st); - return ERRC; /****** WRONG ******/ - } - if ( ss->K != 0 ) - { ss->lprev = gs_alloc_bytes(st->memory, raster + 4, - "CFE lprev"); - if ( ss->lprev == 0 ) - { s_CFE_release(st); - return ERRC; /****** WRONG ******/ - } - /* Clear the initial reference line for 2-D encoding. */ - /* Make sure it is terminated properly. */ - memset(ss->lprev, (ss->BlackIs1 ? 0 : 0xff), raster); - if ( columns & 7 ) - ss->lprev[raster - 1] ^= 0x80 >> (columns & 7); - else - ss->lprev[raster] = ~ss->lprev[0]; - } - ss->copy_count = raster; - ss->new_line = true; - ss->k_left = (ss->K > 0 ? 1 : ss->K); - /* Initialize values for buffer space checking. */ - { int max_bytes = cfe_max_code_bytes(columns); - - /* - * For a single-run line, we need room for byte alignment, - * an aligned EOL, run_horizontal, and 2 runs. - */ - ss->max_line_bytes = max_bytes * 2 + 4; - ss->max_run2_bytes = max_bytes * 2; - ss->max_run3_bytes = max_bytes * 3; +s_CFE_init(register stream_state * st) +{ + int columns = ss->Columns; + int raster = ss->raster = + round_up((columns + 7) >> 3, ss->DecodedByteAlign); + + s_hce_init_inline(ss); + ss->count = raster << 3; /* starting a scan line */ + ss->lbuf = ss->lprev = 0; + if (columns > cfe_max_width) + return ERRC; +/****** WRONG ******/ + /* Because skip_white_pixels can look as many as 4 bytes ahead, */ + /* we need to allow 4 extra bytes at the end of the row buffers. */ + ss->lbuf = gs_alloc_bytes(st->memory, raster + 4, + "CFE lbuf"); + if (ss->lbuf == 0) { + s_CFE_release(st); + return ERRC; +/****** WRONG ******/ + } + if (ss->K != 0) { + ss->lprev = gs_alloc_bytes(st->memory, raster + 4, + "CFE lprev"); + if (ss->lprev == 0) { + s_CFE_release(st); + return ERRC; +/****** WRONG ******/ } - return 0; + /* Clear the initial reference line for 2-D encoding. */ + /* Make sure it is terminated properly. */ + memset(ss->lprev, (ss->BlackIs1 ? 0 : 0xff), raster); + if (columns & 7) + ss->lprev[raster - 1] ^= 0x80 >> (columns & 7); + else + ss->lprev[raster] = ~ss->lprev[0]; + } + ss->copy_count = raster; + ss->new_line = true; + ss->k_left = (ss->K > 0 ? 1 : ss->K); + /* Initialize values for buffer space checking. */ + { + int max_bytes = cfe_max_code_bytes(columns); + + /* + * For a single-run line, we need room for byte alignment, + * an aligned EOL, run_horizontal, and 2 runs. + */ + ss->max_line_bytes = max_bytes * 2 + 4; + ss->max_run2_bytes = max_bytes * 2; + ss->max_run3_bytes = max_bytes * 3; + } + return 0; } /* Release the filter. */ private void -s_CFE_release(stream_state *st) -{ gs_free_object(st->memory, ss->lprev, "CFE lprev(close)"); - gs_free_object(st->memory, ss->lbuf, "CFE lbuf(close)"); +s_CFE_release(stream_state * st) +{ + gs_free_object(st->memory, ss->lprev, "CFE lprev(close)"); + gs_free_object(st->memory, ss->lbuf, "CFE lbuf(close)"); } /* Flush the buffer */ private int cf_encode_1d(P4(stream_CFE_state *, const byte *, - stream_cursor_write *, uint)); + stream_cursor_write *, uint)); private int cf_encode_2d(P5(stream_CFE_state *, const byte *, - stream_cursor_write *, uint, const byte *)); + stream_cursor_write *, uint, const byte *)); private int -s_CFE_process(stream_state *st, stream_cursor_read *pr, - stream_cursor_write *pw, bool last) -{ const byte *rlimit = pr->limit; - byte *wlimit = pw->limit; - int raster = ss->raster; - int initial_count = raster << 3; - int end_count = -ss->Columns & 7; - byte end_mask = 1 << (-ss->Columns & 7); - int status = 0; - hce_declare_state; +s_CFE_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + const byte *rlimit = pr->limit; + byte *wlimit = pw->limit; + int raster = ss->raster; + int initial_count = raster << 3; + int end_count = -ss->Columns & 7; + byte end_mask = 1 << (-ss->Columns & 7); + int status = 0; - hce_load_state(); - while ( pr->ptr < rlimit || ss->count != initial_count ) - { byte *end = ss->lbuf + raster - 1; - if_debug7('w', "[w]CFE: copy_count = %d, pr = 0x%lx(%d)0x%lx, pw = 0x%lx(%d)0x%lx\n", - ss->copy_count, (ulong)pr->ptr, - (int)(rlimit - pr->ptr), (ulong)rlimit, - (ulong)pw->ptr, (int)(wlimit - pw->ptr), - (ulong)wlimit); - /* Check whether we are still accumulating a scan line. */ - if ( ss->copy_count != 0 ) - { int rcount = rlimit - pr->ptr; - int ccount = min(rcount, ss->copy_count); - memcpy(ss->lbuf + raster - ss->copy_count, - pr->ptr + 1, ccount); - pr->ptr += ccount; - if ( (ss->copy_count -= ccount) != 0 ) - goto out; - /* - * Ensure that the scan line ends with two - * polarity changes. - */ - { byte end_bit = *end & end_mask; - byte not_bit = end_bit ^ end_mask; - *end &= -end_mask; - if ( end_mask == 1 ) - end[1] = (end_bit ? 0x40 : 0x80); - else if ( end_mask == 2 ) - *end |= not_bit >> 1, end[1] = end_bit << 7; - else - *end |= (not_bit >> 1) | (end_bit >> 2); - } - } - if ( ss->new_line ) - { /* Start a new scan line. */ - byte *q = pw->ptr; - if ( wlimit - q < ss->max_line_bytes ) - { status = 1; - break; - } + hce_declare_state; + + hce_load_state(); + while (pr->ptr < rlimit || ss->count != initial_count) { + byte *end = ss->lbuf + raster - 1; + + if_debug7('w', "[w]CFE: copy_count = %d, pr = 0x%lx(%d)0x%lx, pw = 0x%lx(%d)0x%lx\n", + ss->copy_count, (ulong) pr->ptr, + (int)(rlimit - pr->ptr), (ulong) rlimit, + (ulong) pw->ptr, (int)(wlimit - pw->ptr), + (ulong) wlimit); + /* Check whether we are still accumulating a scan line. */ + if (ss->copy_count != 0) { + int rcount = rlimit - pr->ptr; + int ccount = min(rcount, ss->copy_count); + + memcpy(ss->lbuf + raster - ss->copy_count, + pr->ptr + 1, ccount); + pr->ptr += ccount; + if ((ss->copy_count -= ccount) != 0) + goto out; + /* + * Ensure that the scan line ends with two + * polarity changes. + */ + { + byte end_bit = *end & end_mask; + byte not_bit = end_bit ^ end_mask; + + *end &= -end_mask; + if (end_mask == 1) + end[1] = (end_bit ? 0x40 : 0x80); + else if (end_mask == 2) + *end |= not_bit >> 1, end[1] = end_bit << 7; + else + *end |= (not_bit >> 1) | (end_bit >> 2); + } + } + if (ss->new_line) { /* Start a new scan line. */ + byte *q = pw->ptr; + + if (wlimit - q < ss->max_line_bytes) { + status = 1; + break; + } #ifdef DEBUG - if ( ss->K > 0 ) - { if_debug1('w', "[w]new row, k_left=%d\n", - ss->k_left); - } - else - { if_debug0('w', "[w]new row\n"); - } + if (ss->K > 0) { + if_debug1('w', "[w]new row, k_left=%d\n", + ss->k_left); + } else { + if_debug0('w', "[w]new row\n"); + } #endif - if ( ss->EndOfLine ) - { const cfe_run *rp = - (ss->K <= 0 ? &cf_run_eol : - ss->k_left > 1 ? &cf2_run_eol_2d : - &cf2_run_eol_1d); - cfe_run run; - if ( ss->EncodedByteAlign ) - { run = *rp; - /* Pad the run on the left */ - /* so it winds up byte-aligned. */ - run.code_length += - (bits_left - run_eol_code_length) & 7; - if ( run.code_length > 16 ) /* <= 23 */ - bits_left -= run.code_length & 7, - run.code_length = 16; - rp = &run; - } - hc_put_code(ss, q, rp); - pw->ptr = q; - } - else if ( ss->EncodedByteAlign ) - bits_left &= ~7; - ss->run_color = 0; - ss->new_line = false; - } - hce_store_state(); - if ( ss->K > 0 ) - { /* Group 3, mixed encoding */ - if ( --(ss->k_left) ) /* Use 2-D encoding */ - { status = cf_encode_2d(ss, ss->lbuf, pw, end_count, ss->lprev); - if ( status ) - { /* We didn't finish encoding */ - /* the line, so back out. */ - ss->k_left++; - } - } - else /* Use 1-D encoding */ - { status = cf_encode_1d(ss, ss->lbuf, pw, end_count); - if ( status ) - { /* Didn't finish encoding the line, */ - /* back out. */ - ss->k_left++; - } - else - ss->k_left = ss->K; - } - } - else /* Uniform encoding */ - { status = (ss->K == 0 ? - cf_encode_1d(ss, ss->lbuf, pw, end_count) : - cf_encode_2d(ss, ss->lbuf, pw, end_count, ss->lprev)); - } - hce_load_state(); - if ( status ) - break; - if ( ss->count == end_count ) - { /* Finished a scan line, start a new one. */ - ss->count = initial_count; - ss->new_line = true; - if ( ss->K != 0 ) - { byte *temp = ss->lbuf; - ss->lbuf = ss->lprev; - ss->lprev = temp; - } - ss->copy_count = raster; + if (ss->EndOfLine) { + const cfe_run *rp = + (ss->K <= 0 ? &cf_run_eol : + ss->k_left > 1 ? &cf2_run_eol_2d : + &cf2_run_eol_1d); + cfe_run run; + + if (ss->EncodedByteAlign) { + run = *rp; + /* Pad the run on the left */ + /* so it winds up byte-aligned. */ + run.code_length += + (bits_left - run_eol_code_length) & 7; + if (run.code_length > 16) /* <= 23 */ + bits_left -= run.code_length & 7, + run.code_length = 16; + rp = &run; } + hc_put_code(ss, q, rp); + pw->ptr = q; + } else if (ss->EncodedByteAlign) + bits_left &= ~7; + ss->run_color = 0; + ss->new_line = false; } - /* Check for end of data. */ - if ( last && status == 0 ) - { const cfe_run *rp = - (ss->K > 0 ? &cf2_run_eol_1d : &cf_run_eol); - int i = (!ss->EndOfBlock ? 0 : ss->K < 0 ? 2 : 6); - uint bits_to_write = - hc_bits_size - bits_left + i * rp->code_length; - byte *q = pw->ptr; - if ( wlimit - q < (bits_to_write + 7) >> 3 ) - { status = 1; - goto out; + hce_store_state(); + if (ss->K > 0) { /* Group 3, mixed encoding */ + if (--(ss->k_left)) { /* Use 2-D encoding */ + status = cf_encode_2d(ss, ss->lbuf, pw, end_count, ss->lprev); + if (status) { /* We didn't finish encoding */ + /* the line, so back out. */ + ss->k_left++; } - if ( ss->EncodedByteAlign ) - bits_left &= ~7; - while ( --i >= 0 ) - hc_put_code(ss, q, rp); - /* Force out the last byte or bytes. */ - pw->ptr = q = hc_put_last_bits((stream_hc_state *)ss, q); - goto ns; + } else { /* Use 1-D encoding */ + status = cf_encode_1d(ss, ss->lbuf, pw, end_count); + if (status) { /* Didn't finish encoding the line, */ + /* back out. */ + ss->k_left++; + } else + ss->k_left = ss->K; + } + } else { /* Uniform encoding */ + status = (ss->K == 0 ? + cf_encode_1d(ss, ss->lbuf, pw, end_count) : + cf_encode_2d(ss, ss->lbuf, pw, end_count, ss->lprev)); + } + hce_load_state(); + if (status) + break; + if (ss->count == end_count) { /* Finished a scan line, start a new one. */ + ss->count = initial_count; + ss->new_line = true; + if (ss->K != 0) { + byte *temp = ss->lbuf; + + ss->lbuf = ss->lprev; + ss->lprev = temp; + } + ss->copy_count = raster; + } + } + /* Check for end of data. */ + if (last && status == 0) { + const cfe_run *rp = + (ss->K > 0 ? &cf2_run_eol_1d : &cf_run_eol); + int i = (!ss->EndOfBlock ? 0 : ss->K < 0 ? 2 : 6); + uint bits_to_write = + hc_bits_size - bits_left + i * rp->code_length; + byte *q = pw->ptr; + + if (wlimit - q < (bits_to_write + 7) >> 3) { + status = 1; + goto out; } -out: hce_store_state(); -ns: if_debug9('w', "[w]CFE exit %d: count = %d, run_color = %d,\n pr = 0x%lx(%d)0x%lx; pw = 0x%lx(%d)0x%lx\n", - status, ss->count, ss->run_color, - (ulong)pr->ptr, (int)(rlimit - pr->ptr), (ulong)rlimit, - (ulong)pw->ptr, (int)(wlimit - pw->ptr), (ulong)wlimit); + if (ss->EncodedByteAlign) + bits_left &= ~7; + while (--i >= 0) + hc_put_code(ss, q, rp); + /* Force out the last byte or bytes. */ + pw->ptr = q = hc_put_last_bits((stream_hc_state *) ss, q); + goto ns; + } + out:hce_store_state(); + ns:if_debug9('w', "[w]CFE exit %d: count = %d, run_color = %d,\n pr = 0x%lx(%d)0x%lx; pw = 0x%lx(%d)0x%lx\n", + status, ss->count, ss->run_color, + (ulong) pr->ptr, (int)(rlimit - pr->ptr), (ulong) rlimit, + (ulong) pw->ptr, (int)(wlimit - pw->ptr), (ulong) wlimit); #ifdef DEBUG - if ( pr->ptr > rlimit || pw->ptr > wlimit ) - { lprintf("Pointer overrun!\n"); - status = ERRC; + if (pr->ptr > rlimit || pw->ptr > wlimit) { + lprintf("Pointer overrun!\n"); + status = ERRC; + } + if (gs_debug_c('w') && status == 1) { + int ti; + + for (ti = 0; ti < 2; ti++) { + int i; + ulong total; + + dprintf1("[w]runs[%d]", ti); + for (i = 0, total = 0; i < 41; i++) + dprintf1(" %lu", runs_1d[ti].make_up[i]), + total += runs_1d[ti].make_up[i]; + dprintf1(" total=%lu\n\t", total); + for (i = 0, total = 0; i < 64; i++) + dprintf1(" %lu", runs_1d[ti].termination[i]), + total += runs_1d[ti].termination[i]; + dprintf1(" total=%lu\n", total); } - if ( gs_debug_c('w') && status == 1 ) - { int ti; - for ( ti = 0; ti < 2; ti++ ) - { int i; - ulong total; - dprintf1("[w]runs[%d]", ti); - for ( i = 0, total = 0; i < 41; i++ ) - dprintf1(" %lu", runs_1d[ti].make_up[i]), - total += runs_1d[ti].make_up[i]; - dprintf1(" total=%lu\n\t", total); - for ( i = 0, total = 0; i < 64; i++ ) - dprintf1(" %lu", runs_1d[ti].termination[i]), - total += runs_1d[ti].termination[i]; - dprintf1(" total=%lu\n", total); - } - } + } #endif - return status; + return status; } #undef ss @@ -340,161 +352,162 @@ ns: if_debug9('w', "[w]CFE exit %d: count = %d, run_color = %d,\n pr = 0x%lx /* Encode a 1-D scan line. */ private int -cf_encode_1d(stream_CFE_state *ss, const byte *lbuf, - stream_cursor_write *pw, uint end_count) -{ uint count = ss->count; - byte *q = pw->ptr; - byte *wlimit = pw->limit; - int rlen; - int status = 0; - hce_declare_state; - - { register const byte *p = lbuf + ss->raster - ((count + 7) >> 3); - byte invert = (ss->BlackIs1 ? 0 : 0xff); - /* Invariant: data = p[-1] ^ invert. */ - register uint data = *p++ ^ invert; - - hce_load_state(); - while ( count != end_count ) - { /* Parse a white run. */ - cf_ensure_put_runs(max_run2_bytes, 0, out); - skip_white_pixels(data, p, count, invert, rlen); - cf_put_white_run(ss, rlen); - if ( count == end_count ) - break; - /* Parse a black run. */ - skip_black_pixels(data, p, count, invert, rlen); - cf_put_black_run(ss, rlen); - } +cf_encode_1d(stream_CFE_state * ss, const byte * lbuf, + stream_cursor_write * pw, uint end_count) +{ + uint count = ss->count; + byte *q = pw->ptr; + byte *wlimit = pw->limit; + int rlen; + int status = 0; + + hce_declare_state; + + { + register const byte *p = lbuf + ss->raster - ((count + 7) >> 3); + byte invert = (ss->BlackIs1 ? 0 : 0xff); + + /* Invariant: data = p[-1] ^ invert. */ + register uint data = *p++ ^ invert; + + hce_load_state(); + while (count != end_count) { /* Parse a white run. */ + cf_ensure_put_runs(max_run2_bytes, 0, out); + skip_white_pixels(data, p, count, invert, rlen); + cf_put_white_run(ss, rlen); + if (count == end_count) + break; + /* Parse a black run. */ + skip_black_pixels(data, p, count, invert, rlen); + cf_put_black_run(ss, rlen); } + } -out: hce_store_state(); - pw->ptr = q; - ss->count = count; - return status; + out:hce_store_state(); + pw->ptr = q; + ss->count = count; + return status; } /* Encode a 2-D scan line. */ private int -cf_encode_2d(stream_CFE_state *ss, const byte *lbuf, - stream_cursor_write *pw, uint end_count, const byte *lprev) -{ byte invert_white = (ss->BlackIs1 ? 0 : 0xff); - byte invert = (ss->run_color ? ~invert_white : invert_white); - register uint count = ss->count; - const byte *p = lbuf + ss->raster - ((count + 7) >> 3); - byte *q = pw->ptr; - byte *wlimit = pw->limit; - register uint data = *p++ ^ invert; - int status = 0; - hce_declare_state; - /* In order to handle the nominal 'changing white' at the */ - /* beginning of each scan line, we need to suppress the test for */ - /* an initial black bit in the reference line when we are at */ - /* the very beginning of the scan line. To avoid an extra test, */ - /* we use two different mask tables. */ - static const byte initial_count_bit[8] = - { 0, 1, 2, 4, 8, 0x10, 0x20, 0x40 }; - static const byte further_count_bit[8] = - { 0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40 }; - const byte _ds *count_bit = - (count == ss->raster << 3 ? initial_count_bit : further_count_bit); +cf_encode_2d(stream_CFE_state * ss, const byte * lbuf, + stream_cursor_write * pw, uint end_count, const byte * lprev) +{ + byte invert_white = (ss->BlackIs1 ? 0 : 0xff); + byte invert = (ss->run_color ? ~invert_white : invert_white); + register uint count = ss->count; + const byte *p = lbuf + ss->raster - ((count + 7) >> 3); + byte *q = pw->ptr; + byte *wlimit = pw->limit; + register uint data = *p++ ^ invert; + int status = 0; + + hce_declare_state; + /* In order to handle the nominal 'changing white' at the */ + /* beginning of each scan line, we need to suppress the test for */ + /* an initial black bit in the reference line when we are at */ + /* the very beginning of the scan line. To avoid an extra test, */ + /* we use two different mask tables. */ + static const byte initial_count_bit[8] = + {0, 1, 2, 4, 8, 0x10, 0x20, 0x40}; + static const byte further_count_bit[8] = + {0x80, 1, 2, 4, 8, 0x10, 0x20, 0x40}; + const byte _ds *count_bit = + (count == ss->raster << 3 ? initial_count_bit : further_count_bit); + + hce_load_state(); + while (count != end_count) { /* If invert == invert_white, white and black have their */ + /* correct meanings; if invert == ~invert_white, */ + /* black and white are interchanged. */ + uint a0 = count; + uint a1; - hce_load_state(); - while ( count != end_count ) - { /* If invert == invert_white, white and black have their */ - /* correct meanings; if invert == ~invert_white, */ - /* black and white are interchanged. */ - uint a0 = count; - uint a1; #define b1 (a1 - diff) /* only for printing */ - int diff; - uint prev_count = count; - const byte *prev_p = p - lbuf + lprev; - byte prev_data = prev_p[-1] ^ invert; - int rlen; - - /* Make sure we have room for a run_horizontal plus */ - /* two data runs. */ - cf_ensure_put_runs(max_run3_bytes, invert != invert_white, out); - /* Find the a1 and b1 transitions. */ - skip_white_pixels(data, p, count, invert, rlen); - a1 = count; - if ( (prev_data & count_bit[prev_count & 7]) ) - { /* Look for changing white first. */ - skip_black_pixels(prev_data, prev_p, prev_count, invert, rlen); - } - count_bit = further_count_bit; /* no longer at beginning */ -pass: if ( prev_count != end_count ) - { skip_white_pixels(prev_data, prev_p, prev_count, invert, rlen); - } - diff = a1 - prev_count; /* i.e., logical b1 - a1 */ - /* In all the comparisons below, remember that count */ - /* runs downward, not upward, so the comparisons are */ - /* reversed. */ - if ( diff <= -2 ) - { /* Could be a pass mode. Find b2. */ - if ( prev_count != end_count ) - { skip_black_pixels(prev_data, prev_p, - prev_count, invert, rlen); - } - if ( prev_count > a1 ) - { /* Use pass mode. */ - if_debug4('W', "[W]pass: count = %d, a1 = %d, b1 = %d, new count = %d\n", - a0, a1, b1, prev_count); - hc_put_value(ss, q, cf2_run_pass_value, - cf2_run_pass_length); - cf_ensure_put_runs(max_run3_bytes, - invert != invert_white, - pass_out); - a0 = prev_count; - goto pass; -pass_out: count = prev_count; - break; - } - } - /* Check for vertical coding. */ - if ( diff <= 3 && diff >= -3 ) - { /* Use vertical coding. */ - const cfe_run *cp; - if_debug5('W', "[W]vertical %d: count = %d, a1 = %d, b1 = %d, new count = %d\n", - diff, a0, a1, b1, count); - cp = &cf2_run_vertical[diff + 3]; - hc_put_code(ss, q, cp); - invert = ~invert; /* a1 polarity changes */ - data ^= 0xff; - continue; - } - /* No luck, use horizontal coding. */ - if ( count != end_count ) - { skip_black_pixels(data, p, count, invert, rlen); /* find a2 */ - } - hc_put_value(ss, q, cf2_run_horizontal_value, - cf2_run_horizontal_length); - a0 -= a1; - a1 -= count; - if ( invert == invert_white ) - { if_debug3('W', "[W]horizontal: white = %d, black = %d, new count = %d\n", - a0, a1, count); - cf_put_white_run(ss, a0); - cf_put_black_run(ss, a1); - } - else - { if_debug3('W', "[W]horizontal: black = %d, white = %d, new count = %d\n", - a0, a1, count); - cf_put_black_run(ss, a0); - cf_put_white_run(ss, a1); + int diff; + uint prev_count = count; + const byte *prev_p = p - lbuf + lprev; + byte prev_data = prev_p[-1] ^ invert; + int rlen; + + /* Make sure we have room for a run_horizontal plus */ + /* two data runs. */ + cf_ensure_put_runs(max_run3_bytes, invert != invert_white, out); + /* Find the a1 and b1 transitions. */ + skip_white_pixels(data, p, count, invert, rlen); + a1 = count; + if ((prev_data & count_bit[prev_count & 7])) { /* Look for changing white first. */ + skip_black_pixels(prev_data, prev_p, prev_count, invert, rlen); + } + count_bit = further_count_bit; /* no longer at beginning */ + pass:if (prev_count != end_count) { + skip_white_pixels(prev_data, prev_p, prev_count, invert, rlen); + } + diff = a1 - prev_count; /* i.e., logical b1 - a1 */ + /* In all the comparisons below, remember that count */ + /* runs downward, not upward, so the comparisons are */ + /* reversed. */ + if (diff <= -2) { /* Could be a pass mode. Find b2. */ + if (prev_count != end_count) { + skip_black_pixels(prev_data, prev_p, + prev_count, invert, rlen); + } + if (prev_count > a1) { /* Use pass mode. */ + if_debug4('W', "[W]pass: count = %d, a1 = %d, b1 = %d, new count = %d\n", + a0, a1, b1, prev_count); + hc_put_value(ss, q, cf2_run_pass_value, + cf2_run_pass_length); + cf_ensure_put_runs(max_run3_bytes, + invert != invert_white, + pass_out); + a0 = prev_count; + goto pass; + pass_out:count = prev_count; + break; + } + } + /* Check for vertical coding. */ + if (diff <= 3 && diff >= -3) { /* Use vertical coding. */ + const cfe_run *cp; + + if_debug5('W', "[W]vertical %d: count = %d, a1 = %d, b1 = %d, new count = %d\n", + diff, a0, a1, b1, count); + cp = &cf2_run_vertical[diff + 3]; + hc_put_code(ss, q, cp); + invert = ~invert; /* a1 polarity changes */ + data ^= 0xff; + continue; + } + /* No luck, use horizontal coding. */ + if (count != end_count) { + skip_black_pixels(data, p, count, invert, rlen); /* find a2 */ + } + hc_put_value(ss, q, cf2_run_horizontal_value, + cf2_run_horizontal_length); + a0 -= a1; + a1 -= count; + if (invert == invert_white) { + if_debug3('W', "[W]horizontal: white = %d, black = %d, new count = %d\n", + a0, a1, count); + cf_put_white_run(ss, a0); + cf_put_black_run(ss, a1); + } else { + if_debug3('W', "[W]horizontal: black = %d, white = %d, new count = %d\n", + a0, a1, count); + cf_put_black_run(ss, a0); + cf_put_white_run(ss, a1); #undef b1 - } } -out: hce_store_state(); - pw->ptr = q; - ss->count = count; - return status; + } + out:hce_store_state(); + pw->ptr = q; + ss->count = count; + return status; } /* Stream template */ const stream_template s_CFE_template = -{ &st_CFE_state, s_CFE_init, s_CFE_process, - 2, 15, /* 31 left-over bits + 7 bits of padding + 6 13-bit EOLs */ - s_CFE_release, s_CFE_set_defaults +{&st_CFE_state, s_CFE_init, s_CFE_process, + 2, 15, /* 31 left-over bits + 7 bits of padding + 6 13-bit EOLs */ + s_CFE_release, s_CFE_set_defaults }; |