Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1995, 1996, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: zfilterx.c,v 1.4 2002/02/21 22:24:54 giles Exp $ */
18
/* Extended (non-standard) filter creation */
19
#include "memory_.h"
20
#include "ghost.h"
21
#include "oper.h"
22
#include "gsstruct.h"
23
#include "ialloc.h"
24
#include "idict.h"
25
#include "idparam.h"
26
#include "store.h"
27
#include "strimpl.h"
28
#include "sfilter.h"
29
#include "sbwbs.h"
30
#include "sbhc.h"
31
#include "sbtx.h"
32
#include "shcgen.h"
33
#include "smtf.h"
34
#include "ifilter.h"
35
 
36
/* ------ Bounded Huffman code filters ------ */
37
 
38
/* Common setup for encoding and decoding filters */
39
private int
40
bhc_setup(os_ptr op, stream_BHC_state * pbhcs)
41
{
42
    int code;
43
    int num_counts;
44
    int data[max_hc_length + 1 + 256 + max_zero_run + 1];
45
    uint dsize;
46
    int i;
47
    uint num_values, accum;
48
    ushort *counts;
49
    ushort *values;
50
 
51
    check_type(*op, t_dictionary);
52
    check_dict_read(*op);
53
    if ((code = dict_bool_param(op, "FirstBitLowOrder", false,
54
				&pbhcs->FirstBitLowOrder)) < 0 ||
55
	(code = dict_int_param(op, "MaxCodeLength", 1, max_hc_length,
56
			       max_hc_length, &num_counts)) < 0 ||
57
	(code = dict_bool_param(op, "EndOfData", true,
58
				&pbhcs->EndOfData)) < 0 ||
59
	(code = dict_uint_param(op, "EncodeZeroRuns", 2, 256,
60
				256, &pbhcs->EncodeZeroRuns)) < 0 ||
61
    /* Note: the code returned from the following call */
62
    /* is actually the number of elements in the array. */
63
	(code = dict_int_array_param(op, "Tables", countof(data),
64
				     data)) <= 0
65
	)
66
	return (code < 0 ? code : gs_note_error(e_rangecheck));
67
    dsize = code;
68
    if (dsize <= num_counts + 2)
69
	return_error(e_rangecheck);
70
    for (i = 0, num_values = 0, accum = 0; i <= num_counts;
71
	 i++, accum <<= 1
72
	) {
73
	int count = data[i];
74
 
75
	if (count < 0)
76
	    return_error(e_rangecheck);
77
	num_values += count;
78
	accum += count;
79
    }
80
    if (dsize != num_counts + 1 + num_values ||
81
	accum != 1 << (num_counts + 1) ||
82
	pbhcs->EncodeZeroRuns >
83
	(pbhcs->EndOfData ? num_values - 1 : num_values)
84
	)
85
	return_error(e_rangecheck);
86
    for (; i < num_counts + 1 + num_values; i++) {
87
	int value = data[i];
88
 
89
	if (value < 0 || value >= num_values)
90
	    return_error(e_rangecheck);
91
    }
92
    pbhcs->definition.counts = counts =
93
	(ushort *) ialloc_byte_array(num_counts + 1, sizeof(ushort),
94
				     "bhc_setup(counts)");
95
    pbhcs->definition.values = values =
96
	(ushort *) ialloc_byte_array(num_values, sizeof(ushort),
97
				     "bhc_setup(values)");
98
    if (counts == 0 || values == 0) {
99
	ifree_object(values, "bhc_setup(values)");
100
	ifree_object(counts, "bhc_setup(counts)");
101
	return_error(e_VMerror);
102
    }
103
    for (i = 0; i <= num_counts; i++)
104
	counts[i] = data[i];
105
    pbhcs->definition.counts = counts;
106
    pbhcs->definition.num_counts = num_counts;
107
    for (i = 0; i < num_values; i++)
108
	values[i] = data[i + num_counts + 1];
109
    pbhcs->definition.values = values;
110
    pbhcs->definition.num_values = num_values;
111
    return 0;
112
}
113
 
114
/* <target> <dict> BoundedHuffmanEncode/filter <file> */
115
private int
116
zBHCE(i_ctx_t *i_ctx_p)
117
{
118
    os_ptr op = osp;
119
    stream_BHCE_state bhcs;
120
    int code = bhc_setup(op, (stream_BHC_state *)&bhcs);
121
 
122
    if (code < 0)
123
	return code;
124
    return filter_write(op, 0, &s_BHCE_template, (stream_state *)&bhcs, 0);
125
}
126
 
127
/* <source> <dict> BoundedHuffmanDecode/filter <file> */
128
private int
129
zBHCD(i_ctx_t *i_ctx_p)
130
{
131
    os_ptr op = osp;
132
    stream_BHCD_state bhcs;
133
    int code = bhc_setup(op, (stream_BHC_state *)&bhcs);
134
 
135
    if (code < 0)
136
	return code;
137
    return filter_read(i_ctx_p, 0, &s_BHCD_template, (stream_state *)&bhcs, 0);
138
}
139
 
140
/* <array> <max_length> .computecodes <array> */
141
/* The first max_length+1 elements of the array will be filled in with */
142
/* the code counts; the remaining elements will be replaced with */
143
/* the code values.  This is the form needed for the Tables element of */
144
/* the dictionary parameter for the BoundedHuffman filters. */
145
private int
146
zcomputecodes(i_ctx_t *i_ctx_p)
147
{
148
    os_ptr op = osp;
149
    os_ptr op1 = op - 1;
150
    uint asize;
151
    hc_definition def;
152
    ushort *data;
153
    long *freqs;
154
    int code = 0;
155
 
156
    check_type(*op, t_integer);
157
    check_write_type(*op1, t_array);
158
    asize = r_size(op1);
159
    if (op->value.intval < 1 || op->value.intval > max_hc_length)
160
	return_error(e_rangecheck);
161
    def.num_counts = op->value.intval;
162
    if (asize < def.num_counts + 2)
163
	return_error(e_rangecheck);
164
    def.num_values = asize - (def.num_counts + 1);
165
    data = (ushort *) gs_alloc_byte_array(imemory, asize, sizeof(ushort),
166
					  "zcomputecodes");
167
    freqs = (long *)gs_alloc_byte_array(imemory, def.num_values,
168
					sizeof(long),
169
					"zcomputecodes(freqs)");
170
 
171
    if (data == 0 || freqs == 0)
172
	code = gs_note_error(e_VMerror);
173
    else {
174
	uint i;
175
 
176
	def.counts = data;
177
	def.values = data + (def.num_counts + 1);
178
	for (i = 0; i < def.num_values; i++) {
179
	    const ref *pf = op1->value.const_refs + i + def.num_counts + 1;
180
 
181
	    if (!r_has_type(pf, t_integer)) {
182
		code = gs_note_error(e_typecheck);
183
		break;
184
	    }
185
	    freqs[i] = pf->value.intval;
186
	}
187
	if (!code) {
188
	    code = hc_compute(&def, freqs, imemory);
189
	    if (code >= 0) {
190
		/* Copy back results. */
191
		for (i = 0; i < asize; i++)
192
		    make_int(op1->value.refs + i, data[i]);
193
	    }
194
	}
195
    }
196
    gs_free_object(imemory, freqs, "zcomputecodes(freqs)");
197
    gs_free_object(imemory, data, "zcomputecodes");
198
    if (code < 0)
199
	return code;
200
    pop(1);
201
    return code;
202
}
203
 
204
/* ------ Burrows/Wheeler block sorting filters ------ */
205
 
206
/* Common setup for encoding and decoding filters */
207
private int
208
bwbs_setup(os_ptr op, stream_BWBS_state * pbwbss)
209
{
210
    int code =
211
	dict_int_param(op, "BlockSize", 1, max_int / sizeof(int) - 10, 16384,
212
		       &pbwbss->BlockSize);
213
 
214
    if (code < 0)
215
	return code;
216
    return 0;
217
}
218
 
219
/* <target> <dict> BWBlockSortEncode/filter <file> */
220
private int
221
zBWBSE(i_ctx_t *i_ctx_p)
222
{
223
    os_ptr op = osp;
224
    stream_BWBSE_state bwbss;
225
    int code;
226
 
227
    check_type(*op, t_dictionary);
228
    check_dict_read(*op);
229
    code = bwbs_setup(op, (stream_BWBS_state *)&bwbss);
230
    if (code < 0)
231
	return code;
232
    return filter_write(op, 0, &s_BWBSE_template, (stream_state *)&bwbss, 0);
233
}
234
 
235
/* <source> <dict> BWBlockSortDecode/filter <file> */
236
private int
237
zBWBSD(i_ctx_t *i_ctx_p)
238
{
239
    os_ptr op = osp;
240
    stream_BWBSD_state bwbss;
241
    int code = bwbs_setup(op, (stream_BWBS_state *)&bwbss);
242
 
243
    if (code < 0)
244
	return code;
245
    return filter_read(i_ctx_p, 0, &s_BWBSD_template, (stream_state *)&bwbss, 0);
246
}
247
 
248
/* ------ Byte translation filters ------ */
249
 
250
/* Common setup */
251
private int
252
bt_setup(os_ptr op, stream_BT_state * pbts)
253
{
254
    check_read_type(*op, t_string);
255
    if (r_size(op) != 256)
256
	return_error(e_rangecheck);
257
    memcpy(pbts->table, op->value.const_bytes, 256);
258
    return 0;
259
}
260
 
261
/* <target> <table> ByteTranslateEncode/filter <file> */
262
/* <target> <table> <dict> ByteTranslateEncode/filter <file> */
263
private int
264
zBTE(i_ctx_t *i_ctx_p)
265
{
266
    os_ptr op = osp;
267
    stream_BT_state bts;
268
    int code = bt_setup(op, &bts);
269
 
270
    if (code < 0)
271
	return code;
272
    return filter_write(op, 0, &s_BTE_template, (stream_state *)&bts, 0);
273
}
274
 
275
/* <target> <table> ByteTranslateDecode/filter <file> */
276
/* <target> <table> <dict> ByteTranslateDecode/filter <file> */
277
private int
278
zBTD(i_ctx_t *i_ctx_p)
279
{
280
    os_ptr op = osp;
281
    stream_BT_state bts;
282
    int code = bt_setup(op, &bts);
283
 
284
    if (code < 0)
285
	return code;
286
    return filter_read(i_ctx_p, 0, &s_BTD_template, (stream_state *)&bts, 0);
287
}
288
 
289
/* ------ Move-to-front filters ------ */
290
 
291
/* <target> MoveToFrontEncode/filter <file> */
292
/* <target> <dict> MoveToFrontEncode/filter <file> */
293
private int
294
zMTFE(i_ctx_t *i_ctx_p)
295
{
296
    os_ptr op = osp;
297
 
298
    return filter_write_simple(op, &s_MTFE_template);
299
}
300
 
301
/* <source> MoveToFrontDecode/filter <file> */
302
/* <source> <dict> MoveToFrontDecode/filter <file> */
303
private int
304
zMTFD(i_ctx_t *i_ctx_p)
305
{
306
    os_ptr op = osp;
307
 
308
    return filter_read_simple(op, &s_MTFD_template);
309
}
310
 
311
/* ================ Initialization procedure ================ */
312
 
313
const op_def zfilterx_op_defs[] =
314
{
315
    {"2.computecodes", zcomputecodes},	/* not a filter */
316
    op_def_begin_filter(),
317
		/* Non-standard filters */
318
    {"2BoundedHuffmanEncode", zBHCE},
319
    {"2BoundedHuffmanDecode", zBHCD},
320
    {"2BWBlockSortEncode", zBWBSE},
321
    {"2BWBlockSortDecode", zBWBSD},
322
    {"2ByteTranslateEncode", zBTE},
323
    {"2ByteTranslateDecode", zBTD},
324
    {"1MoveToFrontEncode", zMTFE},
325
    {"1MoveToFrontDecode", zMTFD},
326
    op_def_end(0)
327
};