diff options
author | Henry Stiles <henry.stiles@artifex.com> | 1998-07-26 07:36:41 +0000 |
---|---|---|
committer | Henry Stiles <henry.stiles@artifex.com> | 1998-07-26 07:36:41 +0000 |
commit | eec0ef527f18c5978c4476c9490f4de4c4249628 (patch) | |
tree | 5588d5e1300a245186594893c930949a19bcbbce /gs/src/zfdecode.c | |
parent | d4bdba93ef34f68d27148e1b31088d1d3e786e8c (diff) |
Initial revision
git-svn-id: http://svn.ghostscript.com/ghostpcl/trunk/ghostpcl@246 06663e23-700e-0410-b217-a244a6096597
Diffstat (limited to 'gs/src/zfdecode.c')
-rw-r--r-- | gs/src/zfdecode.c | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/gs/src/zfdecode.c b/gs/src/zfdecode.c new file mode 100644 index 000000000..3679123f3 --- /dev/null +++ b/gs/src/zfdecode.c @@ -0,0 +1,345 @@ +/* Copyright (C) 1994, 1996 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. +*/ + +/* zfdecode.c */ +/* Additional decoding filter creation */ +#include "memory_.h" +#include "ghost.h" +#include "errors.h" +#include "oper.h" +#include "gsstruct.h" +#include "ialloc.h" +#include "idict.h" +#include "idparam.h" +#include "store.h" +#include "stream.h" /* for setting is_temp */ +#include "strimpl.h" +#include "sfilter.h" +#include "sa85x.h" +#include "scfx.h" +#include "scf.h" +#include "slzwx.h" +#include "spdiffx.h" +#include "spngpx.h" +#include "ifilter.h" + +/* Import the Level 2 scanner extensions. */ +extern const stream_template _ds *scan_ascii85_template; + +/* Initialize the Level 2 scanner for ASCII85 strings. */ +private void +zfdecode_init(void) +{ scan_ascii85_template = &s_A85D_template; +} + +/* ------ ASCII85 filters ------ */ + +/* We include both encoding and decoding filters here, */ +/* because it would be a nuisance to separate them. */ + +/* <target> ASCII85Encode/filter <file> */ +/* <target> <dict_ignored> ASCII85Encode/filter <file> */ +private int +zA85E(os_ptr op) +{ return filter_write_simple(op, &s_A85E_template); +} + +/* <source> ASCII85Decode/filter <file> */ +/* <source> <dict_ignored> ASCII85Decode/filter <file> */ +private int +zA85D(os_ptr op) +{ return filter_read_simple(op, &s_A85D_template); +} + +/* ------ CCITTFaxDecode filter ------ */ + +/* Define a limit on the Rows parameter, close to max_int. */ +#define cf_max_height 32000 + +/* Common setup for encoding and decoding filters. */ +int +zcf_setup(os_ptr op, stream_CF_state *pcfs) +{ int code; + if ( (code = dict_bool_param(op, "Uncompressed", false, + &pcfs->Uncompressed)) < 0 || + (code = dict_int_param(op, "K", -cf_max_height, cf_max_height, 0, + &pcfs->K)) < 0 || + (code = dict_bool_param(op, "EndOfLine", false, + &pcfs->EndOfLine)) < 0 || + (code = dict_bool_param(op, "EncodedByteAlign", false, + &pcfs->EncodedByteAlign)) < 0 || + (code = dict_int_param(op, "Columns", 0, cfe_max_width, 1728, + &pcfs->Columns)) < 0 || + (code = dict_int_param(op, "Rows", 0, cf_max_height, 0, + &pcfs->Rows)) < 0 || + (code = dict_bool_param(op, "EndOfBlock", true, + &pcfs->EndOfBlock)) < 0 || + (code = dict_bool_param(op, "BlackIs1", false, + &pcfs->BlackIs1)) < 0 || + (code = dict_int_param(op, "DamagedRowsBeforeError", 0, + cf_max_height, 0, + &pcfs->DamagedRowsBeforeError)) < 0 || + (code = dict_bool_param(op, "FirstBitLowOrder", false, + &pcfs->FirstBitLowOrder)) < 0 || + (code = dict_int_param(op, "DecodedByteAlign", 1, 16, 1, + &pcfs->DecodedByteAlign)) < 0 + ) + return code; + if ( pcfs->DecodedByteAlign & (pcfs->DecodedByteAlign - 1) ) + return_error(e_rangecheck); /* not a power of 2 */ + return 0; +} + +/* <source> <dict> CCITTFaxDecode/filter <file> */ +/* <source> CCITTFaxDecode/filter <file> */ +private int +zCFD(os_ptr op) +{ os_ptr dop; + int npop; + stream_CFD_state cfs; + int code; + + if ( r_has_type(op, t_dictionary) ) + { check_dict_read(*op); + dop = op, npop = 1; + } + else + dop = 0, npop = 0; + code = zcf_setup(dop, (stream_CF_state *)&cfs); + if ( code < 0 ) + return code; + return filter_read(op, npop, &s_CFD_template, (stream_state *)&cfs, 0); +} + +/* ------ Common setup for possibly pixel-oriented decoding filters ------ */ + +/* Forward declarations */ +int zpd_setup(P2(os_ptr op, stream_PDiff_state *ppds)); +int zpp_setup(P2(os_ptr op, stream_PNGP_state *ppps)); + +int +filter_read_predictor(os_ptr op, int npop, const stream_template *template, + stream_state *st) +{ int predictor, code; + stream_PDiff_state pds; + stream_PNGP_state pps; + + if ( r_has_type(op, t_dictionary) ) + { if ( (code = dict_int_param(op, "Predictor", 0, 15, 1, &predictor)) < 0 ) + return code; + switch ( predictor ) + { + case 0: /* identity */ + predictor = 1; + case 1: /* identity */ + break; + case 2: /* componentwise horizontal differencing */ + code = zpd_setup(op, &pds); + break; + case 10: case 11: case 12: case 13: case 14: case 15: + /* PNG prediction */ + code = zpp_setup(op, &pps); + break; + default: + return_error(e_rangecheck); + } + if ( code < 0 ) + return code; + } + else + predictor = 1; + if ( predictor == 1 ) + return filter_read(op, npop, template, st, 0); + { /* We need to cascade filters. */ + ref rsource, rdict, rfd; + int code; + + /* Save the operands, just in case. */ + ref_assign(&rsource, op - 1); + ref_assign(&rdict, op); + code = filter_read(op, 1, template, st, 0); + if ( code < 0 ) + return code; + /* filter_read changed osp.... */ + op = osp; + ref_assign(&rfd, op); + code = + (predictor == 2 ? + filter_read(op, 0, &s_PDiffD_template, (stream_state *)&pds, 0) : + filter_read(op, 0, &s_PNGPD_template, (stream_state *)&pps, 0)); + if ( code < 0 ) + { /* Restore the operands. Don't bother trying to clean up */ + /* the first stream. */ + osp = ++op; + ref_assign(op - 1, &rsource); + ref_assign(op, &rdict); + return code; + } + filter_mark_temp(&rfd, 2); /* Mark the decompression stream as temporary. */ + return code; + } +} + +/* ------ Generalized LZW/GIF decoding filter ------ */ + +/* Common setup for encoding and decoding filters. */ +int +zlz_setup(os_ptr op, stream_LZW_state *plzs) +{ int code; + const ref *dop; + int npop; + + if ( r_has_type(op, t_dictionary) ) + { check_dict_read(*op); + dop = op, npop = 1; + } + else + dop = 0, npop = 0; + if ( /* Following are not PostScript standard */ + (code = dict_int_param(dop, "EarlyChange", 0, 1, 1, + &plzs->EarlyChange)) < 0 || + (code = dict_int_param(dop, "InitialCodeLength", 2, 11, 8, + &plzs->InitialCodeLength)) < 0 || + (code = dict_bool_param(dop, "FirstBitLowOrder", false, + &plzs->FirstBitLowOrder)) < 0 || + (code = dict_bool_param(dop, "BlockData", false, + &plzs->BlockData)) < 0 + ) + return code; + return npop; +} + +/* <source> LZWDecode/filter <file> */ +/* <source> <dict> LZWDecode/filter <file> */ +private int +zLZWD(os_ptr op) +{ stream_LZW_state lzs; + int code = zlz_setup(op, &lzs); + + if ( code < 0 ) + return code; + return filter_read_predictor(op, code, &s_LZWD_template, + (stream_state *)&lzs); +} + +/* ------ Color differencing filters ------ */ + +/* We include both encoding and decoding filters here, */ +/* because it would be a nuisance to separate them. */ + +/* Common setup for encoding and decoding filters. */ +int +zpd_setup(os_ptr op, stream_PDiff_state *ppds) +{ int code, bpc; + + check_type(*op, t_dictionary); + check_dict_read(*op); + if ( (code = dict_int_param(op, "Colors", 1, 4, 1, + &ppds->Colors)) < 0 || + (code = dict_int_param(op, "BitsPerComponent", 1, 8, 8, + &bpc)) < 0 || + (bpc & (bpc - 1)) != 0 || + (code = dict_int_param(op, "Columns", 1, max_int, 1, + &ppds->Columns)) < 0 + ) + return (code < 0 ? code : gs_note_error(e_rangecheck)); + ppds->BitsPerComponent = bpc; + return 0; +} + +/* <target> <dict> PixelDifferenceEncode/filter <file> */ +private int +zPDiffE(os_ptr op) +{ stream_PDiff_state pds; + int code = zpd_setup(op, &pds); + + if ( code < 0 ) + return code; + return filter_write(op, 1, &s_PDiffE_template, (stream_state *)&pds, 0); +} + +/* <source> <dict> PixelDifferenceDecode/filter <file> */ +private int +zPDiffD(os_ptr op) +{ stream_PDiff_state pds; + int code = zpd_setup(op, &pds); + + if ( code < 0 ) + return code; + return filter_read(op, 1, &s_PDiffD_template, (stream_state *)&pds, 0); +} + +/* ------ PNG pixel predictor filters ------ */ + +/* Common setup for encoding and decoding filters. */ +int +zpp_setup(os_ptr op, stream_PNGP_state *ppps) +{ int code, bpc; + + check_type(*op, t_dictionary); + check_dict_read(*op); + if ( (code = dict_int_param(op, "Colors", 1, 16, 1, + &ppps->Colors)) < 0 || + (code = dict_int_param(op, "BitsPerComponent", 1, 16, 8, + &bpc)) < 0 || + (bpc & (bpc - 1)) != 0 || + (code = dict_uint_param(op, "Columns", 1, max_uint, 1, + &ppps->Columns)) < 0 || + (code = dict_int_param(op, "Predictor", 10, 15, 15, + &ppps->Predictor)) < 0 + ) + return (code < 0 ? code : gs_note_error(e_rangecheck)); + ppps->BitsPerComponent = bpc; + return 0; +} + +/* <target> <dict> PNGPredictorEncode/filter <file> */ +private int +zPNGPE(os_ptr op) +{ stream_PNGP_state pps; + int code = zpp_setup(op, &pps); + + if ( code < 0 ) + return code; + return filter_write(op, 1, &s_PNGPE_template, (stream_state *)&pps, 0); +} + +/* <source> <dict> PNGPredictorDecode/filter <file> */ +private int +zPNGPD(os_ptr op) +{ stream_PNGP_state pps; + int code = zpp_setup(op, &pps); + + if ( code < 0 ) + return code; + return filter_read(op, 1, &s_PNGPD_template, (stream_state *)&pps, 0); +} + +/* ---------------- Initialization procedure ---------------- */ + +BEGIN_OP_DEFS(zfdecode_op_defs) { + op_def_begin_filter(), + {"1ASCII85Encode", zA85E}, + {"1ASCII85Decode", zA85D}, + {"2CCITTFaxDecode", zCFD}, + {"1LZWDecode", zLZWD}, + {"2PixelDifferenceDecode", zPDiffD}, + {"2PixelDifferenceEncode", zPDiffE}, + {"2PNGPredictorDecode", zPNGPD}, + {"2PNGPredictorEncode", zPNGPE}, +END_OP_DEFS(zfdecode_init) } |