1 /* putbits.c, bit-level output */
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
6 * Disclaimer of Warranty
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
32 #include <sys/param.h>
35 static int ubuffer
[BUFFER_SIZE
];
37 /* initialize buffer, call once before first putbits or alignbits */
38 int init_putbits(bitstream
*bs
, char *bs_filename
)
40 if ((bs
->bitfile
= fopen(bs_filename
, "wb")) == NULL
)
42 fprintf(stderr
, "Unable to open file %s for writing.\n", bs_filename
);
45 bs
->bfr
= (unsigned char*)malloc(BUFFER_SIZE
);
49 fprintf(stderr
, "Unable to allocate memory for bitstream file %s.", bs_filename
);
56 bs
->fileOutError
= FALSE
;
60 void finish_putbits(bitstream
*bs
)
64 if ((bs
->byteidx
) && (!bs
->fileOutError
))
65 fwrite(bs
->bfr
, sizeof(unsigned char), bs
->byteidx
, bs
->bitfile
);
76 static void putbyte(bitstream
*bs
)
78 if (!bs
->fileOutError
)
80 bs
->bfr
[bs
->byteidx
++] = bs
->outbyte
;
81 if (bs
->byteidx
== BUFFER_SIZE
)
83 if (fwrite(bs
->bfr
, sizeof(unsigned char), BUFFER_SIZE
, bs
->bitfile
) != BUFFER_SIZE
)
84 bs
->fileOutError
= TRUE
;
91 /* write rightmost n (0<=n<=32) bits of val to outfile */
92 void putbits(bitstream
*bs
, int val
, int n
)
97 mask
= 1 << (n
- 1); /* selects first (leftmost) bit */
98 for (i
= 0; i
< n
; i
++)
104 mask
>>= 1; /* select next bit */
106 if (bs
->bitidx
== 0) /* 8 bit buffer full */
111 /* write rightmost bit of val to outfile */
112 void put1bit(bitstream
*bs
, int val
)
119 if (bs
->bitidx
== 0) /* 8 bit buffer full */
123 /* Prepare a upcoming undo at the beginning of a GOP */
124 void prepareundo(bitstream
*bs
, bitstream
*undo
)
126 memcpy(ubuffer
, bs
->bfr
, BUFFER_SIZE
);
127 fgetpos(bs
->bitfile
, &bs
->actpos
);
131 /* Reset old status, undo all changes made up to a point */
132 void undochanges(bitstream
*bs
, bitstream
*old
)
134 memcpy(bs
->bfr
, ubuffer
, BUFFER_SIZE
);
135 fsetpos(bs
->bitfile
, &bs
->actpos
);
139 /* zero bit stuffing to next byte boundary (5.2.3, 6.2.1) */
140 void alignbits(bitstream
*bs
)
143 putbits(bs
, 0, bs
->bitidx
);
146 /* return total number of generated bits */
147 bitcount_t
bitcount(bitstream
*bs
)
152 static int refill_buffer(bitstream
*bs
)
156 i
= fread(bs
->bfr
, sizeof(unsigned char), BUFFER_SIZE
, bs
->bitfile
);
166 /* open the device to read the bit stream from it */
167 int init_getbits(bitstream
*bs
, char *bs_filename
)
170 if ((bs
->bitfile
= fopen(bs_filename
, "rb")) == NULL
)
172 fprintf(stderr
, "Unable to open file %s for reading.\n", bs_filename
);
175 bs
->bfr
= (unsigned char*)malloc(BUFFER_SIZE
);
179 fprintf(stderr
, "Unable to allocate memory for bitstream file %s.\n", bs_filename
);
187 if (!refill_buffer(bs
))
191 fprintf(stderr
, "Unable to read from file %s.\n", bs_filename
);
198 /*close the device containing the bit stream after a read process*/
199 void finish_getbits(bitstream
*bs
)
206 int masks
[8]={0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
208 /*read 1 bit from the bit stream */
209 unsigned int get1bit(bitstream
*bs
)
216 bit
= (bs
->bfr
[bs
->byteidx
] & masks
[bs
->bitidx
- 1]) >> (bs
->bitidx
- 1);
223 if (bs
->byteidx
== bs
->bufcount
)
225 if (bs
->bufcount
== BUFFER_SIZE
)
236 /*read N bits from the bit stream */
237 unsigned int getbits(bitstream
*bs
, int N
)
239 unsigned int val
= 0;
243 // Optimize: we are on byte boundary and want to read multiple of bytes!
244 if ((bs
->bitidx
== 8) && ((N
& 7) == 0))
251 val
= (val
<< 8) | bs
->bfr
[bs
->byteidx
];
254 if (bs
->byteidx
== bs
->bufcount
)
256 if (bs
->bufcount
== BUFFER_SIZE
)
272 j
= (bs
->bfr
[bs
->byteidx
] & masks
[bs
->bitidx
- 1]) >> (bs
->bitidx
- 1);
279 if (bs
->byteidx
== bs
->bufcount
)
281 if (bs
->bufcount
== BUFFER_SIZE
)
288 val
= (val
<< 1) | j
;
295 /*return the status of the bit stream*/
296 /* returns 1 if end of bit stream was reached */
297 /* returns 0 if end of bit stream was not reached */
299 int end_bs(bitstream
*bs
)
304 /*this function seeks for a byte aligned sync word (max 32 bits) in the bit stream and
305 places the bit stream pointer right after the sync.
306 This function returns 1 if the sync was found otherwise it returns 0 */
308 int seek_sync(bitstream
*bs
, unsigned int sync
, int N
)
310 unsigned int val
, val1
;
311 unsigned int maxi
= ((1U<<N
)-1); /* pow(2.0, (double)N) - 1 */;
313 while (bs
->bitidx
!= 8)
318 val
= getbits(bs
, N
);
322 while ((val
& maxi
) != sync
)
325 val1
= getbits( bs
, 8 );