Import the current wip animation datatype and subclasses. further development will...
[AROS.git] / workbench / classes / datatypes / mpegvideo / mpegutil.c
blob5a7b6fb6270a9e58afae4f7765518cd03b022d27
2 /*
3 **
4 ** $VER: mpegutil.c 1.11 (1.11.97)
5 ** mpegvideo.datatype 1.11
6 **
7 ** mpeg utility functions
8 **
9 ** Written 1996/1997 by Roland 'Gizzy' Mainz
13 #ifndef DEBUG
14 # define DEBUG 0
15 #endif
16 #include <aros/debug.h>
18 /* ansi includes */
19 #include <stdlib.h>
20 #include <string.h>
21 #include <limits.h>
23 /* project includes */
24 #include "mpegvideo.h"
25 #include "mpegproto.h"
26 #include "mpegutil.h"
28 /* Bit masks used by bit i/o operations. */
29 const
30 ULONG nBitMask[] =
32 0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
33 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
34 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
35 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
36 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
37 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
38 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
39 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe,
40 0xffffffff
44 const
45 ULONG bitMask[] =
47 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
48 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
49 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
50 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
51 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
52 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
53 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
54 0x0000000f, 0x00000007, 0x00000003, 0x00000001,
55 0x00000000
59 const
60 ULONG rBitMask[] =
62 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
63 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
64 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
65 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
66 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
67 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
68 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
69 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
70 0x00000000
74 const
75 ULONG bitTest[] =
77 0x80000000, 0x40000000, 0x20000000, 0x10000000,
78 0x08000000, 0x04000000, 0x02000000, 0x01000000,
79 0x00800000, 0x00400000, 0x00200000, 0x00100000,
80 0x00080000, 0x00040000, 0x00020000, 0x00010000,
81 0x00008000, 0x00004000, 0x00002000, 0x00001000,
82 0x00000800, 0x00000400, 0x00000200, 0x00000100,
83 0x00000080, 0x00000040, 0x00000020, 0x00000010,
84 0x00000008, 0x00000004, 0x00000002, 0x00000001,
85 0x00000000
90 *--------------------------------------------------------------
92 * correct_underflow --
94 * Called when buffer does not have sufficient data to
95 * satisfy request for bits.
96 * Calls get_more_data, an application specific routine
97 * required to fill the buffer with more data.
99 * Results:
100 * None really.
102 * Side effects:
103 * buf_length and buffer fields in curVidStream structure
104 * may be changed.
106 *--------------------------------------------------------------
110 void correct_underflow( struct MPEGVideoInstData *mvid )
112 int status;
114 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__));
116 status = get_more_data( mvid, (curVidStream -> buf_start), (curVidStream -> max_buf_length), (int *)(&bufLength), (unsigned int **)(&bitBuffer) );
118 if( status < 0 )
120 error_printf( mvid, "Unexpected read error (status = %x).\n", status);
122 myexit( mvid, RETURN_ERROR, ERROR_SEEK_ERROR );
124 else
126 if( (status == 0) && (bufLength < 1) )
128 error_printf( mvid, "\nImproper or missing sequence end code. Done ! (status=%x, bufLength = %d)\n", status, bufLength );
130 myexit( mvid, RETURN_WARN, ERROR_SEEK_ERROR );
134 curBits = *bitBuffer << bitOffset;
139 *--------------------------------------------------------------
141 * next_bits --
143 * Compares next num bits to low order position in mask.
144 * Buffer pointer is NOT advanced.
146 * Results:
147 * TRUE, FALSE, or error code.
149 * Side effects:
150 * None.
152 *--------------------------------------------------------------
156 int next_bits( struct MPEGVideoInstData *mvid, int num, unsigned int mask )
158 unsigned int stream;
160 /* Get next num bits, no buffer pointer advance. */
161 show_bitsn( num, stream );
163 /* Compare bit stream and mask. Set return value to TRUE if equal, FALSE if differs. */
164 return( (int)(mask == stream) );
169 *--------------------------------------------------------------
171 * get_ext_data --
173 * Assumes that bit stream is at begining of extension
174 * data. Parses off extension data into dynamically
175 * allocated space until start code is hit.
177 * Results:
178 * Pointer to dynamically allocated memory containing
179 * extension data.
181 * Side effects:
182 * Bit stream irreversibly parsed.
184 *--------------------------------------------------------------
188 char *get_ext_data( struct MPEGVideoInstData *mvid )
190 int size,
191 marker;
192 char *dataPtr;
193 unsigned int data;
195 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__));
197 /* Set initial ext data buffer size. */
198 size = EXT_BUF_SIZE;
200 /* Allocate ext data buffer. */
201 dataPtr = (char *)mymalloc( mvid, size );
203 /* Initialize marker to keep place in ext data buffer. */
204 marker = 0;
206 /* While next data is not start code... */
207 while( !next_bits( mvid, 24, 0x000001 ) )
209 /* Get next byte of ext data. */
210 get_bits8( data );
212 /* Put ext data into ext data buffer. Advance marker. */
213 dataPtr[ marker ] = (char)data;
214 marker++;
216 /* If end of ext data buffer reached, resize data buffer. */
217 if( marker == size )
219 size += EXT_BUF_SIZE;
220 dataPtr = (char *)myrealloc( mvid, dataPtr, size );
224 /* Realloc data buffer to free any extra space. */
225 dataPtr = (char *)myrealloc( mvid, dataPtr, marker );
227 /* Return pointer to ext data buffer. */
228 return( dataPtr );
233 *--------------------------------------------------------------
235 * next_start_code --
237 * Parses off bitstream until start code reached. When done
238 * next 4 bytes of bitstream will be start code. Bit offset
239 * reset to 0.
241 * Results:
242 * Status code.
244 * Side effects:
245 * Bit stream irreversibly parsed.
247 *--------------------------------------------------------------
251 int next_start_code( struct MPEGVideoInstData *mvid )
253 int byteoff;
254 unsigned int data;
255 UWORD state;
257 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__));
259 /* If insufficient buffer length, correct underflow. */
260 if( bufLength < SSP )
262 correct_underflow( mvid );
265 /* If bit offset not zero, reset and advance buffer pointer. */
266 byteoff = bitOffset % CHAR_BIT;
268 if( byteoff != 0 )
270 /* Align to byte boundary */
271 flush_bits( (CHAR_BIT - byteoff) );
274 /* Set state = 0U. */
275 state = 0U;
277 /* While buffer has data ... */
278 while( bufLength > 0 )
280 /* If insufficient data exists, correct underflow. */
281 if( bufLength < SSP )
283 correct_underflow( mvid );
286 /* If next byte is zero... */
287 get_bits8( data );
289 if( data == 0 )
291 /* If state < 2U, advance state. */
292 if( state < 2U )
294 state++;
297 /* If next byte is one... */
298 else
300 if( data == 1 )
302 /* If (state == 2U), advance state (state = 3U) (i.e. start code found),
303 * otherwise, reset state to zero.
305 state = (state == 2U)?(3U):(0U);
307 else
309 /* Otherwise byte is neither 1 or 0, reset state to 0U. */
310 state = 0U;
314 /* If state == 3U (i.e. start code found)... */
315 if( state == 3U )
317 /* Set buffer pointer back and reset length & bit offsets so next bytes will be beginning of start code. */
318 bitOffset = bitOffset - 24;
320 if( bitOffset < 0 )
322 bitOffset = 32 + bitOffset;
323 bufLength++;
324 bitBuffer--;
327 curBits = *bitBuffer << bitOffset;
329 D(bug("[mpegvideo.datatype] %s: ok\n", __PRETTY_FUNCTION__));
330 /* Return success. */
331 return( OK );
335 D(bug("[mpegvideo.datatype] %s: underflow\n", __PRETTY_FUNCTION__));
336 /* Return underflow error. */
337 return( UNDERFLOW );
342 *--------------------------------------------------------------
344 * get_extra_bit_info --
346 * Parses off extra bit info stream into dynamically
347 * allocated memory. Extra bit info is indicated by
348 * a flag bit set to 1, followed by 8 bits of data.
349 * This continues until the flag bit is zero. Assumes
350 * that bit stream set to first flag bit in extra
351 * bit info stream.
353 * Results:
354 * Pointer to dynamically allocated memory with extra
355 * bit info in it. Flag bits are NOT included.
357 * Side effects:
358 * Bit stream irreversibly parsed.
360 *--------------------------------------------------------------
364 char *get_extra_bit_info( struct MPEGVideoInstData *mvid )
366 int size,
367 marker;
368 char *dataPtr;
369 unsigned int data;
371 D(bug("[mpegvideo.datatype] %s()\n", __PRETTY_FUNCTION__));
373 /* Get first flag bit. */
374 get_bits1( data );
376 /* If flag is false, return NULL pointer (i.e. no extra bit info). */
377 if( !data )
379 return( NULL );
382 /* Initialize size of extra bit info buffer and allocate. */
383 size = EXT_BUF_SIZE;
384 dataPtr = (char *)mymalloc( mvid, size );
386 /* Reset marker to hold place in buffer. */
387 marker = 0;
389 /* While flag bit is true. */
390 while( data )
392 /* Get next 8 bits of data. */
393 get_bits8( data );
395 /* Place in extra bit info buffer. */
396 dataPtr[ marker ] = (char)data;
397 marker++;
399 /* If buffer is full, reallocate. */
400 if( marker == size )
402 size += EXT_BUF_SIZE;
403 dataPtr = (char *)myrealloc( mvid, dataPtr, size );
406 /* Get next flag bit. */
407 get_bits1( data );
410 /* Reallocate buffer to free extra space. */
411 dataPtr = (char *)myrealloc( mvid, dataPtr, marker );
413 /* Return pointer to extra bit info buffer. */
414 return( dataPtr );
418 long stream_pos( struct MPEGVideoInstData *mvid )
420 return( (long)(((mvid -> mvid_ReadMarkPos) + ((UBYTE *)bitBuffer - (mvid -> mvid_ReadMark))) + (bitOffset / CHAR_BIT)) );