diff options
-rw-r--r-- | pcl/pcl.mak | 6 | ||||
-rw-r--r-- | pcl/rtgmode.c | 5 | ||||
-rw-r--r-- | pcl/rtraster.c | 130 | ||||
-rw-r--r-- | pcl/rtrstcmp.c | 2 | ||||
-rw-r--r-- | pcl/rtrstcmp.h | 24 |
5 files changed, 152 insertions, 15 deletions
diff --git a/pcl/pcl.mak b/pcl/pcl.mak index 9490c83c4..caa0dd8ad 100644 --- a/pcl/pcl.mak +++ b/pcl/pcl.mak @@ -351,6 +351,9 @@ $(PCLOBJ)rtmisc.$(OBJ): $(PCLSRC)rtmisc.c \ # Chapter 15 $(PCLOBJ)rtraster.$(OBJ): $(PCLSRC)rtraster.c \ $(memory__h) \ + $(strimpl_h) \ + $(scfx_h) \ + $(stream_h) \ $(gx_h) \ $(gsmatrix_h) \ $(gscoord_h) \ @@ -367,6 +370,7 @@ $(PCLOBJ)rtraster.$(OBJ): $(PCLSRC)rtraster.c \ $(pcindxed_h) \ $(pcwhtidx_h) \ $(pcdraw_h) \ + $(plvalue_h) \ $(rtgmode_h) \ $(rtrstcmp_h) \ $(rtraster_h) @@ -582,7 +586,7 @@ $(PCLOBJ)rtgmode.$(OBJ): $(PCLSRC)rtgmode.c \ $(PCLCCC) $(PCLSRC)rtgmode.c $(PCLO_)rtgmode.$(OBJ) $(PCLOBJ)rtrstcmp.$(OBJ): $(PCLSRC)rtrstcmp.c \ - $(string__h) \ + $(string__h) \ $(pcstate_h) \ $(rtrstcmp_h) $(PCLCCC) $(PCLSRC)rtrstcmp.c $(PCLO_)rtrstcmp.$(OBJ) diff --git a/pcl/rtgmode.c b/pcl/rtgmode.c index a9b2a40e3..d0f7a165b 100644 --- a/pcl/rtgmode.c +++ b/pcl/rtgmode.c @@ -506,9 +506,10 @@ set_compression_method( { uint mode = uint_arg(pargs); - if ( (mode < count_of(pcl_decomp_proc)) && - ((pcl_decomp_proc[mode] != 0) || (mode == (uint)ADAPTIVE_COMPRESS)) ) + if (mode < count_of(pcl_decomp_proc)) pcs->raster_state.compression_mode = mode; + else + return gs_throw1(e_Range, "unsupported mode %d\n", mode); return 0; } diff --git a/pcl/rtraster.c b/pcl/rtraster.c index 840c2ac76..73af06754 100644 --- a/pcl/rtraster.c +++ b/pcl/rtraster.c @@ -14,6 +14,9 @@ /* rtraster.c - raster transfer commands */ #include "memory_.h" +#include "strimpl.h" +#include "scfx.h" +#include "stream.h" #include "gx.h" #include "gsmatrix.h" #include "gscoord.h" @@ -30,6 +33,7 @@ #include "pcindxed.h" #include "pcwhtidx.h" #include "pcdraw.h" +#include "plvalue.h" #include "rtgmode.h" #include "rtrstcmp.h" #include "rtraster.h" @@ -253,7 +257,7 @@ gen_mask_1byte( * pixel. The only possible such case in PCL is 8-bits per primary 3 color, * so this routine handles only that case. */ - void + static void gen_mask_multibyte( pcl_raster_t * prast ) @@ -914,6 +918,118 @@ process_row( } /* + * Process an input data buffer using no compression with blocks (multiple rows) + */ + + static int +process_block_nocompress( + gs_state * pgs, + pcl_raster_t * prast, + const byte * pin, + uint insize +) +{ + uint32 row_bytes, nrows; + pcl_seed_row_t *pseed_row = prast->pseed_rows; + byte *p; + + /* the size of the rows are stored in the first 4 bytes */ + if (insize < 4) { + return gs_throw(e_Range, "Size of raster cannot be determined\n"); + } + + row_bytes = (pl_get_uint32(pin) * prast->bits_per_plane + 7) / 8; + + /* the remaining data after the row size should be divisible by + the row length to have equal sized rows */ + if ((insize - 4) % row_bytes) + return gs_throw(e_Range, "Non integral number of rows in raster\n"); + + nrows = insize / row_bytes; + + for (p = (byte *)pin + 4; nrows > 0; p += row_bytes, nrows--) { + int code; + pcl_decomp_proc[0](pseed_row, p, row_bytes); + prast->plane_index = 1; + code = process_row(prast, 0); + if (code < 0) + return gs_rethrow(code, "Raster row processing failed\n"); + } + return 0; +} + +static int +pcl_ccitt_error(stream_state * st, const char *str) +{ + (void) gs_throw1(-1, "%s", str); + return 0; +} + + +static int +process_ccitt_compress( + gs_state * pgs, + pcl_raster_t * prast, + const byte * pin, + uint insize, + pcl_rast_buff_type_t comp + +) +{ + stream_CFD_state state; + stream_cursor_read scr; + stream_cursor_write scw; + pcl_seed_row_t *pout = prast->pseed_rows; + + if (insize < 4) + return gs_throw(e_Range, "raster row size not specified"); + s_init_state((stream_state*)&state, &s_CFD_template, prast->pmem); + state.report_error = pcl_ccitt_error; + s_CFD_template.set_defaults((stream_state*)&state); + state.EndOfLine = false; + state.EndOfBlock = false; + state.Columns = pl_get_uint32(pin); + state.Rows = 0; /* undetermined */ + if (comp == CCITT_GR3_1D_COMPRESS) + state.K = 0; + else if (comp == CCITT_GR3_2D_COMPRESS) + state.K = 1; + else + state.K = -1; + s_CFD_template.init((stream_state*)&state); + scr.ptr = pin + 4 - 1; + scr.limit = scr.ptr + insize; + scw.ptr = pout->pdata - 1; + scw.limit = scw.ptr + (state.Columns + 7) / 8; + + while (1) { + int code = s_CFD_template.process((stream_state*)&state, &scr, &scw, true); + switch (code) { + + case 1: /* need output, process the scanline and continue. */ + scw.ptr = pout->pdata - 1; + scw.limit = scw.ptr + (state.Columns + 7) / 8; + process_row(prast, 0); + break; + case EOFC: /* all done */ + s_CFD_template.release((stream_state*)&state); + return 0; + case 0: /* need input is an error - we've given it all the data */ + case ERRC: /* error */ + s_CFD_template.release((stream_state*)&state); + return gs_rethrow(e_Range, "CCITT decompression failed\n"); + default: + return gs_throw(e_Range, "unknown code CCITT decompression\n"); + } + } + /* not reached */ + return -1; +} + + + + +/* * Process an input data buffer using adpative compression. */ static int @@ -1050,12 +1166,16 @@ add_raster_plane( pcl_seed_row_t * pseed = prast->pseed_rows + plane_index; prast->plane_index++; - if (comp_mode == ADAPTIVE_COMPRESS) + if (!PCL_BLOCK_COMP(comp_mode)) + (void)pcl_decomp_proc[comp_mode](pseed, pdata, nbytes); + else if (comp_mode == NO_COMPRESS_BLOCK) + return process_block_nocompress(pcs->pgs, prast, pdata, nbytes); + else if (comp_mode == ADAPTIVE_COMPRESS) return process_adaptive_compress(pcs->pgs, prast, pdata, nbytes); else - (void)pcl_decomp_proc[comp_mode](pseed, pdata, nbytes); + return process_ccitt_compress(pcs->pgs, prast, pdata, nbytes, comp_mode); + } - return 0; } @@ -1339,7 +1459,7 @@ transfer_raster_row( code = add_raster_plane(pdata, arg_data_size(pargs), true, pcs); /* complete the row (execpt for adaptive compression) */ - if (comp_mode != ADAPTIVE_COMPRESS && code == 0) + if (!PCL_BLOCK_COMP(comp_mode) && code == 0) code = process_row((pcl_raster_t *)pcs->raster_state.pcur_raster, comp_mode); return code; diff --git a/pcl/rtrstcmp.c b/pcl/rtrstcmp.c index fcddedd5c..d4998743f 100644 --- a/pcl/rtrstcmp.c +++ b/pcl/rtrstcmp.c @@ -255,6 +255,6 @@ void (*const pcl_decomp_proc[9 + 1])( pcl_seed_row_t * pout, uncompress_1, uncompress_2, uncompress_3, - 0, 0, 0, 0, 0, /* modes 4 and 6 - 8 unused; mode 5 handled separately */ + 0, 0, 0, 0, 0, /* modes 4 - 8 handled separately */ uncompress_9 }; diff --git a/pcl/rtrstcmp.h b/pcl/rtrstcmp.h index e9b34c378..ab8ad2fb1 100644 --- a/pcl/rtrstcmp.h +++ b/pcl/rtrstcmp.h @@ -26,8 +26,11 @@ * 1 - compression mode 1 (run length compression), param is size in bytes * 2 - compression mode 2 ("Packbits" compression), param is size in bytes * 3 - compression mode 3 (delta row compression), param is size in bytes - * 4 - not used + * 4 - compression mode 4 (no compression blocks), param is size in bytes * 5 - compression mode 5 (adaptive), param is size in bytes + * 6 - compression mode 5 (ccitt group 3 1d), param is size in bytes + * 7 - compression mode 5 (ccitt group 3 2d), param is size in bytes + * 8 - compression mode 5 (ccitt group 4 2d), param is size in bytes * 9 - compression mode 9 (modified delta row), param is size in bytes * * There is no separate format for repeated rows. The desired effect can be @@ -38,13 +41,22 @@ typedef enum { RUN_LEN_COMPRESS = 1, PACKBITS_COMPRESS = 2, DELTA_ROW_COMPRESS = 3, - /* 4 is not used, and indicated as reserved by HP */ + NO_COMPRESS_BLOCK = 4, ADAPTIVE_COMPRESS = 5, - /* 6 - 8 unused */ + CCITT_GR3_1D_COMPRESS = 6, + CCITT_GR3_2D_COMPRESS = 7, + CCITT_GR4_COMPRESS = 8, MOD_DELTA_ROW_COMPRESS = 9 } pcl_rast_buff_type_t; /* + * Identify the compression schemes that are block (not scan line + * oriented) + */ + +#define PCL_BLOCK_COMP(comp) ((comp) >= NO_COMPRESS_BLOCK && (comp) <= CCITT_GR4_COMPRESS) + +/* * A seed-row structure. These buffers are used both to pass data to the * graphic library image routines, and to retain information on the last row * sent to support "delta-row" compression. @@ -82,8 +94,8 @@ typedef struct pcl_seed_row_s { * The array of decompression functions. */ extern void (*const pcl_decomp_proc[9 + 1])(pcl_seed_row_t *pout, - const byte *pin, - int in_size - ); + const byte *pin, + int in_size + ); #endif /* rtrstcmp_INCLUDED */ |