Subversion Repositories tendra.SVN

Rev

Rev 5 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5 Rev 6
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 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
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
29
 
59
 
30
 
60
 
31
#include "config.h"
61
#include "config.h"
32
#include "types.h"
62
#include "types.h"
33
#include "enc_types.h"
63
#include "enc_types.h"
-
 
64
#include "bitstream.h"
34
#include "file.h"
65
#include "file.h"
35
#include "utility.h"
66
#include "utility.h"
36
 
67
 
37
 
68
 
38
/*
69
/*
Line 40... Line 71...
40
 
71
 
41
    The nth value in this array can be used to extract the bottom n
72
    The nth value in this array can be used to extract the bottom n
42
    bits of a value.
73
    bits of a value.
43
*/
74
*/
44
 
75
 
45
static unsigned long mask [] = {
76
static unsigned long mask[] = {
46
    0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
77
    0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
47
} ;
78
};
48
 
79
 
49
 
80
 
50
/*
81
/*
51
    SIZE OF A STANDARD BITSTREAM
82
    SIZE OF A STANDARD BITSTREAM
52
 
83
 
Line 62... Line 93...
62
    LIST OF FREE BITSTREAMS
93
    LIST OF FREE BITSTREAMS
63
 
94
 
64
    Bitstreams are allocated from this list.
95
    Bitstreams are allocated from this list.
65
*/
96
*/
66
 
97
 
67
static bitstream *free_bitstreams = null ;
98
static bitstream *free_bitstreams = null;
68
 
99
 
69
 
100
 
70
/*
101
/*
71
    CREATE A NEW BITSTREAM
102
    CREATE A NEW BITSTREAM
72
 
103
 
73
    A new bitstream is allocated and initialized.
104
    A new bitstream is allocated and initialized.
74
*/
105
*/
75
 
106
 
76
bitstream *new_bitstream
107
bitstream *
77
    PROTO_Z ()
108
new_bitstream(void)
78
{
109
{
79
    unsigned i ;
110
    unsigned i;
80
    bitstream *p ;
111
    bitstream *p;
81
    if ( free_bitstreams == null ) {
112
    if (free_bitstreams == null) {
82
	p = alloc_nof ( bitstream, 1 ) ;
113
	p = alloc_nof(bitstream, 1);
83
	p->length = BITSTREAM_SIZE ;
114
	p->length = BITSTREAM_SIZE;
84
	p->source = alloc_nof ( byte, BITSTREAM_SIZE + 10 ) ;
115
	p->source = alloc_nof(byte, BITSTREAM_SIZE + 10);
85
    } else {
116
    } else {
86
	p = free_bitstreams ;
117
	p = free_bitstreams;
87
	free_bitstreams = p->next ;
118
	free_bitstreams = p->next;
88
    }
119
    }
89
    for ( i = 0 ; i < p->length ; i++ ) p->source [i] = 0 ;
120
    for (i = 0; i < p->length; i++)p->source[i] = 0;
90
    p->bytes = 0 ;
121
    p->bytes = 0;
91
    p->bits = 0 ;
122
    p->bits = 0;
92
    p->next = null ;
123
    p->next = null;
93
    p->end = p ;
124
    p->end = p;
94
    return ( p ) ;
125
    return(p);
95
}
126
}
96
 
127
 
97
 
128
 
98
#if 0
129
#if 0
99
 
130
 
Line 103... Line 134...
103
    The bitstream p is closed off and any free space is garbage collected.
134
    The bitstream p is closed off and any free space is garbage collected.
104
    (Not currently used.)
135
    (Not currently used.)
105
*/
136
*/
106
 
137
 
107
static void close_bitstream
138
static void close_bitstream
108
    PROTO_N ( ( p ) )
-
 
109
    PROTO_T ( bitstream *p )
139
(bitstream *p)
110
{
140
{
111
    bitstream *q ;
141
    bitstream *q;
112
    int used = p->end->bytes + 4 ;
142
    int used = p->end->bytes + 4;
113
    int left = p->end->length - used ;
143
    int left = p->end->length - used;
114
    if ( left < CRITICAL_SIZE ) return ;
144
    if (left < CRITICAL_SIZE) return;
115
    q = alloc_nof ( bitstream, 1 ) ;
145
    q = alloc_nof(bitstream, 1);
116
    q->length = left ;
146
    q->length = left;
117
    q->source = p->end->source + used ;
147
    q->source = p->end->source + used;
118
    q->next = free_bitstreams ;
148
    q->next = free_bitstreams;
119
    free_bitstreams = q ;
149
    free_bitstreams = q;
120
    p->end->length = used ;
150
    p->end->length = used;
121
    return ;
151
    return;
122
}
152
}
123
 
153
 
124
#endif
154
#endif
125
 
155
 
126
 
156
 
Line 128... Line 158...
128
    PRINT A BITSTREAM
158
    PRINT A BITSTREAM
129
 
159
 
130
    The bitstream p is dumped to the output file.
160
    The bitstream p is dumped to the output file.
131
*/
161
*/
132
 
162
 
133
void print_bitstream
163
void
134
    PROTO_N ( ( p ) )
-
 
135
    PROTO_T ( bitstream *p )
164
print_bitstream(bitstream *p)
136
{
165
{
137
    unsigned r = 0 ;
166
    unsigned r = 0;
138
    unsigned long buff = 0 ;
167
    unsigned long buff = 0;
139
    for ( ; p ; p = p->next ) {
168
    for (; p; p = p->next) {
140
	unsigned i ;
169
	unsigned i;
141
	for ( i = 0 ; i < p->bytes ; i++ ) {
170
	for (i = 0; i < p->bytes; i++) {
142
	    byte b = p->source [i] ;
171
	    byte b = p->source[i];
143
	    if ( r == 0 ) {
172
	    if (r == 0) {
144
		IGNORE fputc ( ( int ) b, output ) ;
173
		IGNORE fputc((int)b, output);
145
	    } else {
174
	    } else {
146
		buff = ( buff << BYTESIZE ) | ( ( unsigned long ) b ) ;
175
		buff = (buff << BYTESIZE) | ((unsigned long)b);
147
		IGNORE fputc ( ( int ) ( ( buff >> r ) & 0xff ), output ) ;
176
		IGNORE fputc((int)((buff >> r) & 0xff), output);
148
		buff &= mask [r] ;
177
		buff &= mask[r];
149
	    }
178
	    }
150
	}
179
	}
151
	if ( p->bits ) {
180
	if (p->bits) {
152
	    byte b = p->source [ p->bytes ] ;
181
	    byte b = p->source[p->bytes];
153
	    b = ( byte ) ( ( unsigned ) b >> ( BYTESIZE - p->bits ) ) ;
182
	    b = (byte)((unsigned)b >> (BYTESIZE - p->bits));
154
	    buff = ( buff << p->bits ) | ( ( unsigned long ) b ) ;
183
	    buff = (buff << p->bits) | ((unsigned long)b);
155
	    r += p->bits ;
184
	    r += p->bits;
156
	    if ( r >= BYTESIZE ) {
185
	    if (r >= BYTESIZE) {
157
		r -= BYTESIZE ;
186
		r -= BYTESIZE;
158
		IGNORE fputc ( ( int ) ( ( buff >> r ) & 0xff ), output ) ;
187
		IGNORE fputc((int)((buff >> r) & 0xff), output);
159
		buff &= mask [r] ;
188
		buff &= mask[r];
160
	    }
189
	    }
161
	}
190
	}
162
    }
191
    }
163
    if ( r ) {
192
    if (r) {
164
	buff <<= ( BYTESIZE - r ) ;
193
	buff <<= (BYTESIZE - r);
165
	IGNORE fputc ( ( int ) buff, output ) ;
194
	IGNORE fputc((int)buff, output);
166
    }
195
    }
167
    return ;
196
    return;
168
}
197
}
169
 
198
 
170
 
199
 
171
/*
200
/*
172
    FIND THE LENGTH OF A BITSTREAM
201
    FIND THE LENGTH OF A BITSTREAM
173
 
202
 
174
    The length of the bitstream p (in bits) is returned.
203
    The length of the bitstream p (in bits) is returned.
175
*/
204
*/
176
 
205
 
177
long bitstream_length
206
long
178
    PROTO_N ( ( p ) )
-
 
179
    PROTO_T ( bitstream *p )
207
bitstream_length(bitstream *p)
180
{
208
{
181
    unsigned n = 0 ;
209
    unsigned n = 0;
182
    for ( ; p ; p = p->next ) n += ( BYTESIZE * p->bytes ) + p->bits ;
210
    for (; p; p = p->next)n += (BYTESIZE * p->bytes) + p->bits;
183
    return ( ( long ) n ) ;
211
    return((long)n);
184
}
212
}
185
 
213
 
186
 
214
 
187
/*
215
/*
188
    JOIN TWO BITSTREAMS
216
    JOIN TWO BITSTREAMS
189
 
217
 
190
    The bitstream q is appended to p.
218
    The bitstream q is appended to p.
191
*/
219
*/
192
 
220
 
193
void join_bitstreams
221
void
194
    PROTO_N ( ( p, q ) )
-
 
195
    PROTO_T ( bitstream *p X bitstream *q )
222
join_bitstreams(bitstream *p, bitstream *q)
196
{
223
{
197
#if 0
224
#if 0
198
    close_bitstream ( p ) ;
225
    close_bitstream(p);
199
#endif
226
#endif
200
    p->end->next = q ;
227
    p->end->next = q;
201
    p->end = q->end ;
228
    p->end = q->end;
202
    return ;
229
    return;
203
}
230
}
204
 
231
 
205
 
232
 
206
/*
233
/*
207
    ADD A NUMBER OF BITS TO THE END OF A BITSTREAM
234
    ADD A NUMBER OF BITS TO THE END OF A BITSTREAM
208
 
235
 
209
    n bits of value v are added to the end of the bitstream p.
236
    n bits of value v are added to the end of the bitstream p.
210
*/
237
*/
211
 
238
 
212
void enc_bits
239
void
213
    PROTO_N ( ( p, n, v ) )
-
 
214
    PROTO_T ( bitstream *p X int n X long v )
240
enc_bits(bitstream *p, int n, long v)
215
{
241
{
216
    byte *t ;
242
    byte *t;
217
    bitstream *q = p->end ;
243
    bitstream *q = p->end;
218
    unsigned m = ( unsigned ) n ;
244
    unsigned m = (unsigned)n;
219
    unsigned left = BYTESIZE - q->bits ;
245
    unsigned left = BYTESIZE - q->bits;
220
    unsigned long w = ( unsigned long ) v ;
246
    unsigned long w = (unsigned long)v;
221
    if ( left == 0 ) {
247
    if (left == 0) {
222
	left = BYTESIZE ;
248
	left = BYTESIZE;
223
	q->bits = 0 ;
249
	q->bits = 0;
224
	q->bytes++ ;
250
	q->bytes++;
225
	if ( q->bytes >= q->length ) {
251
	if (q->bytes >= q->length) {
226
	    q->next = new_bitstream () ;
252
	    q->next = new_bitstream();
227
	    q = q->next ;
253
	    q = q->next;
228
	    p->end = q ;
254
	    p->end = q;
229
	}
255
	}
230
	q->source [ q->bytes ] = 0 ;
256
	q->source[q->bytes] = 0;
231
    }
257
    }
232
    if ( m > left ) {
258
    if (m > left) {
233
	enc_bits ( p, ( int ) ( m - left ), ( long ) ( w >> left ) ) ;
259
	enc_bits(p,(int)(m - left), (long)(w >> left));
234
	enc_bits ( p, ( int ) left, ( long ) ( w & mask [ left ] ) ) ;
260
	enc_bits(p,(int)left,(long)(w & mask[left]));
235
	return ;
261
	return;
236
    }
262
    }
237
    w <<= ( left - m ) ;
263
    w <<= (left - m);
238
    t = q->source + q->bytes ;
264
    t = q->source + q->bytes;
239
    *t = ( byte ) ( *t | ( byte ) w ) ;
265
    *t = (byte)(*t | (byte)w);
240
    q->bits += m ;
266
    q->bits += m;
241
    return ;
267
    return;
242
}
268
}
243
 
269
 
244
 
270
 
245
/*
271
/*
246
    ALIGN A BITSTREAM TO A BYTE BOUNDARY
272
    ALIGN A BITSTREAM TO A BYTE BOUNDARY
247
 
273
 
248
    The bitstream p is aligned to a byte boundary.
274
    The bitstream p is aligned to a byte boundary.
249
*/
275
*/
250
 
276
 
251
void align_bitstream
277
void
252
    PROTO_N ( ( p ) )
-
 
253
    PROTO_T ( bitstream *p )
278
align_bitstream(bitstream *p)
254
{
279
{
255
    int bit = ( int ) ( bitstream_length ( p ) % BYTESIZE ) ;
280
    int bit = (int)(bitstream_length(p)% BYTESIZE);
256
    if ( bit ) enc_bits ( p, BYTESIZE - bit, ( long ) 0 ) ;
281
    if (bit)enc_bits(p, BYTESIZE - bit,(long)0);
257
    return ;
282
    return;
258
}
283
}