Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "c_types.h"
63
#include "error.h"
64
#include "buffer.h"
65
#include "char.h"
66
#include "decode.h"
67
#include "encode.h"
68
#include "file.h"
69
#include "literal.h"
70
 
71
 
72
/*
73
    FILL A BITSTREAM
74
 
75
    This routine fills the bitstream bs from its associated file.  It
76
    returns the number of bytes read.
77
*/
78
 
7 7u83 79
static unsigned
80
fill_bitstream(BITSTREAM *bs)
2 7u83 81
{
7 7u83 82
	unsigned sz;
83
	FILE *f = bs->file;
84
	string text = bs->text;
85
	sz = (unsigned)fread((gen_ptr)text, sizeof(character),
86
			     (size_t)CHUNK_SIZE, f);
87
	if (sz == 0) {
88
		/* No more characters in file */
89
		bs->link = (gen_ptr)text;
90
		while (sz < CHUNK_SIZE) {
91
			/* Fill buffer with all ones */
92
			text[sz] = (character)BYTE_MASK;
93
			sz++;
94
		}
2 7u83 95
	}
7 7u83 96
	bs->size = sz;
97
	return (sz);
2 7u83 98
}
99
 
100
 
101
/*
102
    CHECK FOR END OF FILE
103
 
104
    This routine checks whether the end of the file associated with the
105
    bitstream bs has been precisely reached.  Note that the link field
106
    is set to a non-null value by fill_bitstream if the end of file is
107
    encountered.
108
*/
109
 
7 7u83 110
int
111
de_eof(BITSTREAM *bs)
2 7u83 112
{
7 7u83 113
	if (bs->link) {
114
		return (0);
115
	}
116
	if (bs->bytes >= bs->size) {
117
		IGNORE fill_bitstream(bs);
118
		if (bs->link) {
119
			return (1);
120
		}
121
	}
122
	return (0);
2 7u83 123
}
124
 
125
 
126
/*
127
    TABLE OF BIT MASKS
128
 
129
    This array gives the bit masks for values up to 16 bits.
130
*/
131
 
7 7u83 132
static unsigned long bit_mask[17] = {
133
	0x0000,
2 7u83 134
#if FS_NUMBER_SUFFIX
7 7u83 135
	0x0001UL, 0x0003UL, 0x0007UL, 0x000fUL,
136
	0x001fUL, 0x003fUL, 0x007fUL, 0x00ffUL,
137
	0x01ffUL, 0x03ffUL, 0x07ffUL, 0x0fffUL,
138
	0x1fffUL, 0x3fffUL, 0x7fffUL, 0xffffUL
2 7u83 139
#else
7 7u83 140
	0x0001, 0x0003, 0x0007, 0x000f,
141
	0x001f, 0x003f, 0x007f, 0x00ff,
142
	0x01ff, 0x03ff, 0x07ff, 0x0fff,
143
	0x1fff, 0x3fff, 0x7fff, 0xffff
2 7u83 144
#endif
7 7u83 145
};
2 7u83 146
 
147
 
148
/*
149
    READ A NUMBER OF BITS FROM A BITSTREAM
150
 
151
    This routine reads the next n bits from the bitstream bs.  n will be
152
    at most 16.
153
*/
154
 
7 7u83 155
unsigned
156
de_bits(BITSTREAM *bs, unsigned n)
2 7u83 157
{
7 7u83 158
	unsigned long d = 0;
159
	string text = bs->text;
160
	unsigned sz = bs->size;
161
	unsigned bytes = bs->bytes;
162
	unsigned bits = 0;
2 7u83 163
 
7 7u83 164
	/* Build up result */
165
	unsigned m = n + bs->bits;
166
	while (m) {
167
		unsigned b;
168
		unsigned long c;
2 7u83 169
 
7 7u83 170
		/* Refill buffer from file if necessary */
171
		if (bytes >= sz) {
172
			sz = fill_bitstream(bs);
173
			bytes = 0;
174
			bits = 0;
175
		}
2 7u83 176
 
7 7u83 177
		/* Get next character */
178
		c = (unsigned long)text[bytes];
179
		d = ((d << BYTE_SIZE) | c);
180
		b = BYTE_SIZE - bits;
181
		if (m < b) {
182
			d >>= (b - m);
183
			bits += m;
184
			m = 0;
185
		} else {
186
			bits += b;
187
			m -= b;
188
		}
189
		if (bits == BYTE_SIZE) {
190
			bits = 0;
191
			bytes++;
192
		}
2 7u83 193
	}
7 7u83 194
	bs->bytes = bytes;
195
	bs->bits = bits;
196
	d &= bit_mask[n];
197
	return ((unsigned)d);
2 7u83 198
}
199
 
200
 
201
/*
202
    READ A LARGE NUMBER OF BITS FROM A BITSTREAM
203
 
204
    This routine is identical to de_bits except that it works for up to
205
    32 bits.
206
*/
207
 
7 7u83 208
unsigned long
209
de_long_bits(BITSTREAM *bs, unsigned n)
2 7u83 210
{
7 7u83 211
	unsigned long a, b;
212
	if (n > 16) {
213
		a = (unsigned long)de_bits(bs, n - 16);
214
		n = 16;
215
	} else {
216
		a = 0;
217
	}
218
	b = (unsigned long)de_bits(bs, n);
219
	return ((a << 16) | b);
2 7u83 220
}
221
 
222
 
223
/*
224
    READ AN INTEGER FROM A BITSTREAM
225
 
226
    This routine reads an integer as a series of octal digits from the
227
    bitstream bs.
228
*/
229
 
7 7u83 230
unsigned long
231
de_int(BITSTREAM *bs)
2 7u83 232
{
7 7u83 233
	unsigned long d, n = 0;
234
	for (;;) {
235
		d = (unsigned long)de_bits(bs,(unsigned)4);
236
		if (d & 0x8) {
237
			break;
238
		}
239
		n = ((n << 3) | d);
240
	}
241
	n = ((n << 3) | (d & 0x7));
242
	return (n);
2 7u83 243
}
244
 
245
 
246
/*
247
    ALIGN A BITSTREAM TO A BYTE BOUNDARY
248
 
249
    This routine reads enough bits from the bitstream bs to align it to
250
    the next byte boundary.
251
*/
252
 
7 7u83 253
void
254
de_boundary(BITSTREAM *bs)
2 7u83 255
{
7 7u83 256
	unsigned bits = bs->bits;
257
	if (bits) {
258
		IGNORE de_bits(bs, BYTE_SIZE - bits);
259
	}
260
	return;
2 7u83 261
}
262
 
263
 
264
/*
265
    READ A STRING FROM A BITSTREAM
266
 
267
    This routine reads a string from the bitstream bs into the buffer bf.
268
*/
269
 
7 7u83 270
void
271
de_tdfstring(BITSTREAM *bs, BUFFER *bf)
2 7u83 272
{
7 7u83 273
	unsigned m = (unsigned)de_int(bs);
274
	unsigned long n = de_int(bs);
275
	string p = stretch_buffer(bf, bf->posn,(gen_size)n);
276
	bf->posn = p + n;
277
	while (n) {
278
		int ch = CHAR_SIMPLE;
279
		unsigned long c = (unsigned long)de_bits(bs, m);
280
		c = from_ascii(c, &ch);
281
		*(p++) = (character)c;
282
		n--;
283
	}
284
	*p = 0;
285
	return;
2 7u83 286
}