1 /* Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved. 2 3 This file is part of AFPL Ghostscript. 4 5 AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or 6 distributor accepts any responsibility for the consequences of using it, or 7 for whether it serves any particular purpose or works at all, unless he or 8 she says so in writing. Refer to the Aladdin Free Public License (the 9 "License") for full details. 10 11 Every copy of AFPL Ghostscript must include a copy of the License, normally 12 in a plain ASCII text file named PUBLIC. The License grants you the right 13 to copy, modify and redistribute AFPL Ghostscript, but only under certain 14 conditions described in the License. Among other things, the License 15 requires that the copyright notice and this notice be preserved on all 16 copies. 17 */ 18 19 /*$Id: zfdecode.c,v 1.3 2000/09/19 19:00:53 lpd Exp $ */ 20 /* Additional decoding filter creation */ 21 #include "memory_.h" 22 #include "ghost.h" 23 #include "oper.h" 24 #include "gsparam.h" 25 #include "gsstruct.h" 26 #include "ialloc.h" 27 #include "idict.h" 28 #include "idparam.h" 29 #include "ilevel.h" /* for LL3 test */ 30 #include "iparam.h" 31 #include "store.h" 32 #include "stream.h" /* for setting is_temp */ 33 #include "strimpl.h" 34 #include "sfilter.h" 35 #include "sa85x.h" 36 #include "scfx.h" 37 #include "scf.h" 38 #include "slzwx.h" 39 #include "spdiffx.h" 40 #include "spngpx.h" 41 #include "ifilter.h" 42 #include "ifilter2.h" 43 #include "ifrpred.h" 44 45 /* ------ ASCII85 filters ------ */ 46 47 /* We include both encoding and decoding filters here, */ 48 /* because it would be a nuisance to separate them. */ 49 50 /* <target> ASCII85Encode/filter <file> */ 51 /* <target> <dict> ASCII85Encode/filter <file> */ 52 private int 53 zA85E(i_ctx_t *i_ctx_p) 54 { 55 return filter_write_simple(i_ctx_p, &s_A85E_template); 56 } 57 58 /* <source> ASCII85Decode/filter <file> */ 59 /* <source> <dict> ASCII85Decode/filter <file> */ 60 private int 61 zA85D(i_ctx_t *i_ctx_p) 62 { 63 return filter_read_simple(i_ctx_p, &s_A85D_template); 64 } 65 66 /* ------ CCITTFaxDecode filter ------ */ 67 68 /* Common setup for encoding and decoding filters. */ 69 extern stream_state_proc_put_params(s_CF_put_params, stream_CF_state); 70 int 71 zcf_setup(os_ptr op, stream_CF_state *pcfs, gs_ref_memory_t *imem) 72 { 73 dict_param_list list; 74 int code = dict_param_list_read(&list, op, NULL, false, imem); 75 76 if (code < 0) 77 return code; 78 s_CF_set_defaults_inline(pcfs); 79 code = s_CF_put_params((gs_param_list *)&list, pcfs); 80 iparam_list_release(&list); 81 return code; 82 } 83 84 /* <source> <dict> CCITTFaxDecode/filter <file> */ 85 /* <source> CCITTFaxDecode/filter <file> */ 86 private int 87 zCFD(i_ctx_t *i_ctx_p) 88 { 89 os_ptr op = osp; 90 os_ptr dop; 91 stream_CFD_state cfs; 92 int code; 93 94 if (r_has_type(op, t_dictionary)) { 95 check_dict_read(*op); 96 dop = op; 97 } else 98 dop = 0; 99 code = zcf_setup(dop, (stream_CF_state *)&cfs, iimemory); 100 if (code < 0) 101 return code; 102 return filter_read(i_ctx_p, 0, &s_CFD_template, (stream_state *)&cfs, 0); 103 } 104 105 /* ------ Common setup for possibly pixel-oriented decoding filters ------ */ 106 107 int 108 filter_read_predictor(i_ctx_t *i_ctx_p, int npop, 109 const stream_template * template, stream_state * st) 110 { 111 os_ptr op = osp; 112 int predictor, code; 113 stream_PDiff_state pds; 114 stream_PNGP_state pps; 115 116 if (r_has_type(op, t_dictionary)) { 117 if ((code = dict_int_param(op, "Predictor", 0, 15, 1, &predictor)) < 0) 118 return code; 119 switch (predictor) { 120 case 0: /* identity */ 121 predictor = 1; 122 case 1: /* identity */ 123 break; 124 case 2: /* componentwise horizontal differencing */ 125 code = zpd_setup(op, &pds); 126 break; 127 case 10: 128 case 11: 129 case 12: 130 case 13: 131 case 14: 132 case 15: 133 /* PNG prediction */ 134 code = zpp_setup(op, &pps); 135 break; 136 default: 137 return_error(e_rangecheck); 138 } 139 if (code < 0) 140 return code; 141 } else 142 predictor = 1; 143 if (predictor == 1) 144 return filter_read(i_ctx_p, npop, template, st, 0); 145 { 146 /* We need to cascade filters. */ 147 ref rsource, rdict; 148 int code; 149 150 /* Save the operands, just in case. */ 151 ref_assign(&rsource, op - 1); 152 ref_assign(&rdict, op); 153 code = filter_read(i_ctx_p, 1, template, st, 0); 154 if (code < 0) 155 return code; 156 /* filter_read changed osp.... */ 157 op = osp; 158 code = 159 (predictor == 2 ? 160 filter_read(i_ctx_p, 0, &s_PDiffD_template, (stream_state *) & pds, 0) : 161 filter_read(i_ctx_p, 0, &s_PNGPD_template, (stream_state *) & pps, 0)); 162 if (code < 0) { 163 /* Restore the operands. Don't bother trying to clean up */ 164 /* the first stream. */ 165 osp = ++op; 166 ref_assign(op - 1, &rsource); 167 ref_assign(op, &rdict); 168 return code; 169 } 170 /* 171 * Mark the compression stream as temporary, and propagate 172 * CloseSource from it to the predictor stream. 173 */ 174 filter_mark_strm_temp(op, 2); 175 return code; 176 } 177 } 178 179 /* ------ Generalized LZW/GIF decoding filter ------ */ 180 181 /* Common setup for encoding and decoding filters. */ 182 int 183 zlz_setup(os_ptr op, stream_LZW_state * plzs) 184 { 185 int code; 186 const ref *dop; 187 188 if (r_has_type(op, t_dictionary)) { 189 check_dict_read(*op); 190 dop = op; 191 } else 192 dop = 0; 193 if ( (code = dict_int_param(dop, "EarlyChange", 0, 1, 1, 194 &plzs->EarlyChange)) < 0 || 195 /* 196 * The following are not PostScript standard, although 197 * LanguageLevel 3 provides the first two under different 198 * names. 199 */ 200 (code = dict_int_param(dop, "InitialCodeLength", 2, 11, 8, 201 &plzs->InitialCodeLength)) < 0 || 202 (code = dict_bool_param(dop, "FirstBitLowOrder", false, 203 &plzs->FirstBitLowOrder)) < 0 || 204 (code = dict_bool_param(dop, "BlockData", false, 205 &plzs->BlockData)) < 0 206 ) 207 return code; 208 return 0; 209 } 210 211 /* <source> LZWDecode/filter <file> */ 212 /* <source> <dict> LZWDecode/filter <file> */ 213 private int 214 zLZWD(i_ctx_t *i_ctx_p) 215 { 216 os_ptr op = osp; 217 stream_LZW_state lzs; 218 int code = zlz_setup(op, &lzs); 219 220 if (code < 0) 221 return code; 222 if (LL3_ENABLED && r_has_type(op, t_dictionary)) { 223 int unit_size; 224 225 if ((code = dict_bool_param(op, "LowBitFirst", lzs.FirstBitLowOrder, 226 &lzs.FirstBitLowOrder)) < 0 || 227 (code = dict_int_param(op, "UnitSize", 3, 8, 8, 228 &unit_size)) < 0 229 ) 230 return code; 231 if (code == 0 /* UnitSize specified */ ) 232 lzs.InitialCodeLength = unit_size + 1; 233 } 234 return filter_read_predictor(i_ctx_p, 0, &s_LZWD_template, 235 (stream_state *) & lzs); 236 } 237 238 /* ------ Color differencing filters ------ */ 239 240 /* We include both encoding and decoding filters here, */ 241 /* because it would be a nuisance to separate them. */ 242 243 /* Common setup for encoding and decoding filters. */ 244 int 245 zpd_setup(os_ptr op, stream_PDiff_state * ppds) 246 { 247 int code, bpc; 248 249 check_type(*op, t_dictionary); 250 check_dict_read(*op); 251 if ((code = dict_int_param(op, "Colors", 1, s_PDiff_max_Colors, 1, 252 &ppds->Colors)) < 0 || 253 (code = dict_int_param(op, "BitsPerComponent", 1, 8, 8, 254 &bpc)) < 0 || 255 (bpc & (bpc - 1)) != 0 || 256 (code = dict_int_param(op, "Columns", 1, max_int, 1, 257 &ppds->Columns)) < 0 258 ) 259 return (code < 0 ? code : gs_note_error(e_rangecheck)); 260 ppds->BitsPerComponent = bpc; 261 return 0; 262 } 263 264 /* <target> <dict> PixelDifferenceEncode/filter <file> */ 265 private int 266 zPDiffE(i_ctx_t *i_ctx_p) 267 { 268 os_ptr op = osp; 269 stream_PDiff_state pds; 270 int code = zpd_setup(op, &pds); 271 272 if (code < 0) 273 return code; 274 return filter_write(i_ctx_p, 0, &s_PDiffE_template, (stream_state *) & pds, 0); 275 } 276 277 /* <source> <dict> PixelDifferenceDecode/filter <file> */ 278 private int 279 zPDiffD(i_ctx_t *i_ctx_p) 280 { 281 os_ptr op = osp; 282 stream_PDiff_state pds; 283 int code = zpd_setup(op, &pds); 284 285 if (code < 0) 286 return code; 287 return filter_read(i_ctx_p, 0, &s_PDiffD_template, (stream_state *) & pds, 0); 288 } 289 290 /* ------ PNG pixel predictor filters ------ */ 291 292 /* Common setup for encoding and decoding filters. */ 293 int 294 zpp_setup(os_ptr op, stream_PNGP_state * ppps) 295 { 296 int code, bpc; 297 298 check_type(*op, t_dictionary); 299 check_dict_read(*op); 300 if ((code = dict_int_param(op, "Colors", 1, 16, 1, 301 &ppps->Colors)) < 0 || 302 (code = dict_int_param(op, "BitsPerComponent", 1, 16, 8, 303 &bpc)) < 0 || 304 (bpc & (bpc - 1)) != 0 || 305 (code = dict_uint_param(op, "Columns", 1, max_uint, 1, 306 &ppps->Columns)) < 0 || 307 (code = dict_int_param(op, "Predictor", 10, 15, 15, 308 &ppps->Predictor)) < 0 309 ) 310 return (code < 0 ? code : gs_note_error(e_rangecheck)); 311 ppps->BitsPerComponent = bpc; 312 return 0; 313 } 314 315 /* <target> <dict> PNGPredictorEncode/filter <file> */ 316 private int 317 zPNGPE(i_ctx_t *i_ctx_p) 318 { 319 os_ptr op = osp; 320 stream_PNGP_state pps; 321 int code = zpp_setup(op, &pps); 322 323 if (code < 0) 324 return code; 325 return filter_write(i_ctx_p, 0, &s_PNGPE_template, (stream_state *) & pps, 0); 326 } 327 328 /* <source> <dict> PNGPredictorDecode/filter <file> */ 329 private int 330 zPNGPD(i_ctx_t *i_ctx_p) 331 { 332 os_ptr op = osp; 333 stream_PNGP_state pps; 334 int code = zpp_setup(op, &pps); 335 336 if (code < 0) 337 return code; 338 return filter_read(i_ctx_p, 0, &s_PNGPD_template, (stream_state *) & pps, 0); 339 } 340 341 /* ---------------- Initialization procedure ---------------- */ 342 343 const op_def zfdecode_op_defs[] = { 344 op_def_begin_filter(), 345 {"1ASCII85Encode", zA85E}, 346 {"1ASCII85Decode", zA85D}, 347 {"2CCITTFaxDecode", zCFD}, 348 {"1LZWDecode", zLZWD}, 349 {"2PixelDifferenceDecode", zPDiffD}, 350 {"2PixelDifferenceEncode", zPDiffE}, 351 {"2PNGPredictorDecode", zPNGPD}, 352 {"2PNGPredictorEncode", zPNGPE}, 353 op_def_end(0) 354 }; 355