1 /*
2  * Copyright (c) 1995 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation for any purpose, without fee, and without written agreement is
7  * hereby granted, provided that the above copyright notice and the following
8  * two paragraphs appear in all copies of this software.
9  *
10  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
11  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
12  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
13  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
18  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
19  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
20  */
21 
22 /*
23  * Portions of this software Copyright (c) 1995 Brown University.
24  * All rights reserved.
25  *
26  * Permission to use, copy, modify, and distribute this software and its
27  * documentation for any purpose, without fee, and without written agreement
28  * is hereby granted, provided that the above copyright notice and the
29  * following two paragraphs appear in all copies of this software.
30  *
31  * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
32  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
33  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
34  * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
37  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
38  * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
39  * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
40  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
41  */
42 
43 /*
44    Changes to make the code reentrant:
45      deglobalized: curBits, curVidStream
46      deglobalized: bitOffset, bitLength, bitBuffer in vid_stream, not used
47        here
48    Additional changes:
49    -lsh@cs.brown.edu (Loring Holden)
50  */
51 
52 /* Status codes for bit stream i/o operations. */
53 
54 #define NO_VID_STREAM (-1)
55 #define STREAM_UNDERFLOW (-2)
56 #define OK 1
57 
58 /* Size increment of extension data buffers. */
59 
60 #define EXT_BUF_SIZE 1024
61 
62 /* External declarations for bitstream i/o operations. */
63 extern unsigned int bitMask[];
64 extern unsigned int nBitMask[];
65 extern unsigned int rBitMask[];
66 extern unsigned int bitTest[];
67 
68 /* Macro for updating bit counter if analysis tool is on. */
69 #ifdef ANALYSIS
70 #define UPDATE_COUNT(numbits) bitCount += numbits
71 #else
72 #define UPDATE_COUNT(numbits)
73 #endif
74 
75 #ifdef NO_SANITY_CHECKS
76 #define get_bits1(result)                                                 \
77 {                                                                         \
78   UPDATE_COUNT(1);                                                        \
79   result = ((vid_stream->curBits & 0x80000000) != 0);                     \
80   vid_stream->curBits <<= 1;                                              \
81   vid_stream->bit_offset++;                                               \
82                                                                           \
83   if (vid_stream->bit_offset & 0x20) {                                    \
84     vid_stream->bit_offset = 0;                                           \
85     vid_stream->buffer++;                                                 \
86     vid_stream->curBits = *vid_stream->buffer;                            \
87     vid_stream->buf_length--;                                             \
88   }                                                                       \
89 }
90 
91 #define get_bits2(result)                                                 \
92 {                                                                         \
93   UPDATE_COUNT(2);                                                        \
94   vid_stream->bit_offset += 2;                                            \
95                                                                           \
96   if (vid_stream->bit_offset & 0x20) {                                    \
97     vid_stream->bit_offset -= 32;                                         \
98     vid_stream->buffer++;                                                 \
99     vid_stream->buf_length--;                                             \
100     if (vid_stream->bit_offset) {                                         \
101       vid_stream->curBits |=                                              \
102 	 (*vid_stream->buffer >> (2 - vid_stream->bit_offset));           \
103     }                                                                     \
104     result = ((vid_stream->curBits & 0xc0000000) >> 30);                  \
105     vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;  \
106   }                                                                       \
107                                                                           \
108   result = ((vid_stream->curBits & 0xc0000000) >> 30);                    \
109   vid_stream->curBits <<= 2;                                              \
110 }
111 
112 #define get_bitsX(num, mask, shift,  result)                              \
113 {                                                                         \
114   UPDATE_COUNT(num);                                                      \
115   vid_stream->bit_offset += num;                                          \
116                                                                           \
117   if (vid_stream->bit_offset & 0x20) {                                    \
118     vid_stream->bit_offset -= 32;                                         \
119     vid_stream->buffer++;                                                 \
120     vid_stream->buf_length--;                                             \
121     if (vid_stream->bit_offset) {                                         \
122       vid_stream->curBits |= (*vid_stream->buffer >>                      \
123       (num - vid_stream->bit_offset));                                    \
124     }                                                                     \
125     result = ((vid_stream->curBits & mask) >> shift);                     \
126     vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;  \
127   }                                                                       \
128   else {                                                                  \
129     result = ((vid_stream->curBits & mask) >> shift);                     \
130     vid_stream->curBits <<= num;                                          \
131   }                                                                       \
132 }
133 #else
134 
135 #define get_bits1(result)                                                 \
136 {                                                                         \
137   /* Check for underflow. */                                              \
138                                                                           \
139   if (vid_stream->buf_length < 2) {                                       \
140     correct_underflow(vid_stream);                                        \
141   }                                                                       \
142   UPDATE_COUNT(1);                                                        \
143   result = ((vid_stream->curBits & 0x80000000) != 0);                     \
144   vid_stream->curBits <<= 1;                                              \
145   vid_stream->bit_offset++;                                               \
146                                                                           \
147   if (vid_stream->bit_offset & 0x20) {                                    \
148     vid_stream->bit_offset = 0;                                           \
149     vid_stream->buffer++;                                                 \
150     vid_stream->curBits = *vid_stream->buffer;                            \
151     vid_stream->buf_length--;                                             \
152   }                                                                       \
153 }
154 
155 #define get_bits2(result)                                                 \
156 {                                                                         \
157   /* Check for underflow. */                                              \
158                                                                           \
159   if (vid_stream->buf_length < 2) {                                       \
160     correct_underflow(vid_stream);                                        \
161   }                                                                       \
162   UPDATE_COUNT(2);                                                        \
163   vid_stream->bit_offset += 2;                                            \
164                                                                           \
165   if (vid_stream->bit_offset & 0x20) {                                    \
166     vid_stream->bit_offset -= 32;                                         \
167     vid_stream->buffer++;                                                 \
168     vid_stream->buf_length--;                                             \
169     if (vid_stream->bit_offset) {                                         \
170       vid_stream->curBits |= (*vid_stream->buffer >>                      \
171       (2 - vid_stream->bit_offset));                                      \
172     }                                                                     \
173     result = ((vid_stream->curBits & 0xc0000000) >> 30);                  \
174     vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;  \
175   }                                                                       \
176                                                                           \
177   result = ((vid_stream->curBits & 0xc0000000) >> 30);                    \
178   vid_stream->curBits <<= 2;                                              \
179 }
180 
181 #define get_bitsX(num, mask, shift,  result)                              \
182 {                                                                         \
183   /* Check for underflow. */                                              \
184                                                                           \
185   if (vid_stream->buf_length < 2) {                                       \
186     correct_underflow(vid_stream);                                        \
187   }                                                                       \
188   UPDATE_COUNT(num);                                                      \
189   vid_stream->bit_offset += num;                                          \
190                                                                           \
191   if (vid_stream->bit_offset & 0x20) {                                    \
192     vid_stream->bit_offset -= 32;                                         \
193     vid_stream->buffer++;                                                 \
194     vid_stream->buf_length--;                                             \
195     if (vid_stream->bit_offset) {                                         \
196       vid_stream->curBits |= (*vid_stream->buffer >>                      \
197       (num - vid_stream->bit_offset));                                    \
198     }                                                                     \
199     result = ((vid_stream->curBits & mask) >> shift);                     \
200     vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;  \
201   }                                                                       \
202   else {                                                                  \
203    result = ((vid_stream->curBits & mask) >> shift);                      \
204    vid_stream->curBits <<= num;                                           \
205   }                                                                       \
206 }
207 #endif
208 
209 #define get_bits3(result) get_bitsX(3,   0xe0000000, 29, result)
210 #define get_bits4(result) get_bitsX(4,   0xf0000000, 28, result)
211 #define get_bits5(result) get_bitsX(5,   0xf8000000, 27, result)
212 #define get_bits6(result) get_bitsX(6,   0xfc000000, 26, result)
213 #define get_bits7(result) get_bitsX(7,   0xfe000000, 25, result)
214 #define get_bits8(result) get_bitsX(8,   0xff000000, 24, result)
215 #define get_bits9(result) get_bitsX(9,   0xff800000, 23, result)
216 #define get_bits10(result) get_bitsX(10, 0xffc00000, 22, result)
217 #define get_bits11(result) get_bitsX(11, 0xffe00000, 21, result)
218 #define get_bits12(result) get_bitsX(12, 0xfff00000, 20, result)
219 #define get_bits14(result) get_bitsX(14, 0xfffc0000, 18, result)
220 #define get_bits16(result) get_bitsX(16, 0xffff0000, 16, result)
221 #define get_bits18(result) get_bitsX(18, 0xffffc000, 14, result)
222 #define get_bits32(result) get_bitsX(32, 0xffffffff,  0, result)
223 
224 #define get_bitsn(num, result) get_bitsX((num), nBitMask[num], (32-(num)), result)
225 
226 #ifdef NO_SANITY_CHECKS
227 #define show_bits32(result)                              		\
228 {                                                                       \
229   if (vid_stream->bit_offset) {					        \
230     result = vid_stream->curBits | (*(vid_stream->buffer+1) >>          \
231 	 (32 - vid_stream->bit_offset));                                \
232   }                                                                     \
233   else {                                                                \
234     result = vid_stream->curBits;					\
235   }                                                                     \
236 }
237 
238 #define show_bitsX(num, mask, shift,  result)                           \
239 {                                                                       \
240   int bO;                                                               \
241   bO = vid_stream->bit_offset + num;                                    \
242   if (bO > 32) {                                                        \
243     bO -= 32;                                                           \
244     result = ((vid_stream->curBits & mask) >> shift) |                  \
245                 (*(vid_stream->buffer+1) >> (shift + (num - bO)));      \
246   }                                                                     \
247   else {                                                                \
248     result = ((vid_stream->curBits & mask) >> shift);                   \
249   }                                                                     \
250 }
251 
252 #else
253 #define show_bits32(result)                               		\
254 {                                                                       \
255   /* Check for underflow. */                                            \
256   if (vid_stream->buf_length < 2) {                                     \
257     correct_underflow(vid_stream);                                      \
258   }                                                                     \
259   if (vid_stream->bit_offset) {						\
260     result = vid_stream->curBits | (*(vid_stream->buffer+1) >>          \
261     (32 - vid_stream->bit_offset));		                        \
262   }                                                                     \
263   else {                                                                \
264     result = vid_stream->curBits;					\
265   }                                                                     \
266 }
267 
268 #define show_bitsX(num, mask, shift, result)                            \
269 {                                                                       \
270   int bO;                                                               \
271                                                                         \
272   /* Check for underflow. */                                            \
273   if (vid_stream->buf_length < 2) {                                     \
274     correct_underflow(vid_stream);                                      \
275   }                                                                     \
276   bO = vid_stream->bit_offset + num;                                    \
277   if (bO > 32) {                                                        \
278     bO -= 32;                                                           \
279     result = ((vid_stream->curBits & mask) >> shift) |                  \
280                 (*(vid_stream->buffer+1) >> (shift + (num - bO)));      \
281   }                                                                     \
282   else {                                                                \
283     result = ((vid_stream->curBits & mask) >> shift);                   \
284   }                                                                     \
285 }
286 #endif
287 
288 #define show_bits1(result)  show_bitsX(1,  0x80000000, 31, result)
289 #define show_bits2(result)  show_bitsX(2,  0xc0000000, 30, result)
290 #define show_bits3(result)  show_bitsX(3,  0xe0000000, 29, result)
291 #define show_bits4(result)  show_bitsX(4,  0xf0000000, 28, result)
292 #define show_bits5(result)  show_bitsX(5,  0xf8000000, 27, result)
293 #define show_bits6(result)  show_bitsX(6,  0xfc000000, 26, result)
294 #define show_bits7(result)  show_bitsX(7,  0xfe000000, 25, result)
295 #define show_bits8(result)  show_bitsX(8,  0xff000000, 24, result)
296 #define show_bits9(result)  show_bitsX(9,  0xff800000, 23, result)
297 #define show_bits10(result) show_bitsX(10, 0xffc00000, 22, result)
298 #define show_bits11(result) show_bitsX(11, 0xffe00000, 21, result)
299 #define show_bits12(result) show_bitsX(12, 0xfff00000, 20, result)
300 #define show_bits13(result) show_bitsX(13, 0xfff80000, 19, result)
301 #define show_bits14(result) show_bitsX(14, 0xfffc0000, 18, result)
302 #define show_bits15(result) show_bitsX(15, 0xfffe0000, 17, result)
303 #define show_bits16(result) show_bitsX(16, 0xffff0000, 16, result)
304 #define show_bits17(result) show_bitsX(17, 0xffff8000, 15, result)
305 #define show_bits18(result) show_bitsX(18, 0xffffc000, 14, result)
306 #define show_bits19(result) show_bitsX(19, 0xffffe000, 13, result)
307 #define show_bits20(result) show_bitsX(20, 0xfffff000, 12, result)
308 #define show_bits21(result) show_bitsX(21, 0xfffff800, 11, result)
309 #define show_bits22(result) show_bitsX(22, 0xfffffc00, 10, result)
310 #define show_bits23(result) show_bitsX(23, 0xfffffe00,  9, result)
311 #define show_bits24(result) show_bitsX(24, 0xffffff00,  8, result)
312 #define show_bits25(result) show_bitsX(25, 0xffffff80,  7, result)
313 #define show_bits26(result) show_bitsX(26, 0xffffffc0,  6, result)
314 #define show_bits27(result) show_bitsX(27, 0xffffffe0,  5, result)
315 #define show_bits28(result) show_bitsX(28, 0xfffffff0,  4, result)
316 #define show_bits29(result) show_bitsX(29, 0xfffffff8,  3, result)
317 #define show_bits30(result) show_bitsX(30, 0xfffffffc,  2, result)
318 #define show_bits31(result) show_bitsX(31, 0xfffffffe,  1, result)
319 
320 #define show_bitsn(num,result) show_bitsX((num), (0xffffffff << (32-(num))), (32-(num)), result)
321 
322 #ifdef NO_SANITY_CHECKS
323 #define flush_bits32                                                  \
324 {                                                                     \
325   UPDATE_COUNT(32);                                                   \
326                                                                       \
327   vid_stream->buffer++;                                               \
328   vid_stream->buf_length--;                                           \
329   vid_stream->curBits = *vid_stream->buffer  << vid_stream->bit_offset;\
330 }
331 
332 
333 #define flush_bits(num)                                               \
334 {                                                                     \
335   vid_stream->bit_offset += num;                                      \
336                                                                       \
337   UPDATE_COUNT(num);                                                  \
338                                                                       \
339   if (vid_stream->bit_offset & 0x20) {                                \
340     vid_stream->bit_offset -= 32;                                     \
341     vid_stream->buffer++;                                             \
342     vid_stream->buf_length--;                                         \
343     vid_stream->curBits = *vid_stream->buffer  << vid_stream->bit_offset;\
344   }                                                                   \
345   else {                                                              \
346     vid_stream->curBits <<= num;                                      \
347   }                                                                   \
348 }
349 #else
350 #define flush_bits32                                                  \
351 {                                                                     \
352   if (vid_stream  == NULL) {                                          \
353     /* Deal with no vid stream here. */                               \
354   }                                                                   \
355                                                                       \
356   if (vid_stream->buf_length < 2) {                                   \
357     correct_underflow(vid_stream);                                    \
358   }                                                                   \
359                                                                       \
360   UPDATE_COUNT(32);                                                   \
361                                                                       \
362   vid_stream->buffer++;                                               \
363   vid_stream->buf_length--;                                           \
364   vid_stream->curBits = *vid_stream->buffer  << vid_stream->bit_offset;\
365 }
366 
367 #define flush_bits(num)                                               \
368 {                                                                     \
369   if (vid_stream== NULL) {                                            \
370     /* Deal with no vid stream here. */                               \
371   }                                                                   \
372                                                                       \
373   if (vid_stream->buf_length < 2) {                                   \
374     correct_underflow(vid_stream);                                    \
375   }                                                                   \
376                                                                       \
377   UPDATE_COUNT(num);                                                  \
378                                                                       \
379   vid_stream->bit_offset += num;                                      \
380                                                                       \
381   if (vid_stream->bit_offset & 0x20) {                                \
382     vid_stream->buf_length--;                                         \
383     vid_stream->bit_offset -= 32;                                     \
384     vid_stream->buffer++;                                             \
385     vid_stream->curBits = *vid_stream->buffer << vid_stream->bit_offset;\
386   }                                                                   \
387   else {                                                              \
388     vid_stream->curBits <<= num;                                      \
389   }                                                                   \
390 }
391 #endif
392 
393 #define UTIL2
394