Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavcodec / put_bits.h
CommitLineData
2ba45a60
DM
1/*
2 * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file
23 * bitstream writer API
24 */
25
26#ifndef AVCODEC_PUT_BITS_H
27#define AVCODEC_PUT_BITS_H
28
29#include <stdint.h>
30#include <stddef.h>
31#include <assert.h>
32
33#include "libavutil/intreadwrite.h"
34#include "libavutil/avassert.h"
35
36typedef struct PutBitContext {
37 uint32_t bit_buf;
38 int bit_left;
39 uint8_t *buf, *buf_ptr, *buf_end;
40 int size_in_bits;
41} PutBitContext;
42
43/**
44 * Initialize the PutBitContext s.
45 *
46 * @param buffer the buffer where to put bits
47 * @param buffer_size the size in bytes of buffer
48 */
49static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
50 int buffer_size)
51{
52 if (buffer_size < 0) {
53 buffer_size = 0;
54 buffer = NULL;
55 }
56
57 s->size_in_bits = 8 * buffer_size;
58 s->buf = buffer;
59 s->buf_end = s->buf + buffer_size;
60 s->buf_ptr = s->buf;
61 s->bit_left = 32;
62 s->bit_buf = 0;
63}
64
65/**
66 * @return the total number of bits written to the bitstream.
67 */
68static inline int put_bits_count(PutBitContext *s)
69{
70 return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
71}
72
73/**
74 * @return the number of bits available in the bitstream.
75 */
76static inline int put_bits_left(PutBitContext* s)
77{
78 return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
79}
80
81/**
82 * Pad the end of the output stream with zeros.
83 */
84static inline void flush_put_bits(PutBitContext *s)
85{
86#ifndef BITSTREAM_WRITER_LE
87 if (s->bit_left < 32)
88 s->bit_buf <<= s->bit_left;
89#endif
90 while (s->bit_left < 32) {
91 /* XXX: should test end of buffer */
92#ifdef BITSTREAM_WRITER_LE
93 *s->buf_ptr++ = s->bit_buf;
94 s->bit_buf >>= 8;
95#else
96 *s->buf_ptr++ = s->bit_buf >> 24;
97 s->bit_buf <<= 8;
98#endif
99 s->bit_left += 8;
100 }
101 s->bit_left = 32;
102 s->bit_buf = 0;
103}
104
105#ifdef BITSTREAM_WRITER_LE
106#define avpriv_align_put_bits align_put_bits_unsupported_here
107#define avpriv_put_string ff_put_string_unsupported_here
108#define avpriv_copy_bits avpriv_copy_bits_unsupported_here
109#else
110/**
111 * Pad the bitstream with zeros up to the next byte boundary.
112 */
113void avpriv_align_put_bits(PutBitContext *s);
114
115/**
116 * Put the string string in the bitstream.
117 *
118 * @param terminate_string 0-terminates the written string if value is 1
119 */
120void avpriv_put_string(PutBitContext *pb, const char *string,
121 int terminate_string);
122
123/**
124 * Copy the content of src to the bitstream.
125 *
126 * @param length the number of bits of src to copy
127 */
128void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
129#endif
130
131/**
132 * Write up to 31 bits into a bitstream.
133 * Use put_bits32 to write 32 bits.
134 */
135static inline void put_bits(PutBitContext *s, int n, unsigned int value)
136{
137 unsigned int bit_buf;
138 int bit_left;
139
140 av_assert2(n <= 31 && value < (1U << n));
141
142 bit_buf = s->bit_buf;
143 bit_left = s->bit_left;
144
145 /* XXX: optimize */
146#ifdef BITSTREAM_WRITER_LE
147 bit_buf |= value << (32 - bit_left);
148 if (n >= bit_left) {
149 av_assert2(s->buf_ptr+3<s->buf_end);
150 AV_WL32(s->buf_ptr, bit_buf);
151 s->buf_ptr += 4;
152 bit_buf = (bit_left == 32) ? 0 : value >> bit_left;
153 bit_left += 32;
154 }
155 bit_left -= n;
156#else
157 if (n < bit_left) {
158 bit_buf = (bit_buf << n) | value;
159 bit_left -= n;
160 } else {
161 bit_buf <<= bit_left;
162 bit_buf |= value >> (n - bit_left);
163 av_assert2(s->buf_ptr+3<s->buf_end);
164 AV_WB32(s->buf_ptr, bit_buf);
165 s->buf_ptr += 4;
166 bit_left += 32 - n;
167 bit_buf = value;
168 }
169#endif
170
171 s->bit_buf = bit_buf;
172 s->bit_left = bit_left;
173}
174
175static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
176{
177 av_assert2(n >= 0 && n <= 31);
178
179 put_bits(pb, n, value & ((1 << n) - 1));
180}
181
182/**
183 * Write exactly 32 bits into a bitstream.
184 */
185static void av_unused put_bits32(PutBitContext *s, uint32_t value)
186{
187 int lo = value & 0xffff;
188 int hi = value >> 16;
189#ifdef BITSTREAM_WRITER_LE
190 put_bits(s, 16, lo);
191 put_bits(s, 16, hi);
192#else
193 put_bits(s, 16, hi);
194 put_bits(s, 16, lo);
195#endif
196}
197
198/**
199 * Return the pointer to the byte where the bitstream writer will put
200 * the next bit.
201 */
202static inline uint8_t *put_bits_ptr(PutBitContext *s)
203{
204 return s->buf_ptr;
205}
206
207/**
208 * Skip the given number of bytes.
209 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
210 */
211static inline void skip_put_bytes(PutBitContext *s, int n)
212{
213 av_assert2((put_bits_count(s) & 7) == 0);
214 av_assert2(s->bit_left == 32);
215 s->buf_ptr += n;
216}
217
218/**
219 * Skip the given number of bits.
220 * Must only be used if the actual values in the bitstream do not matter.
221 * If n is 0 the behavior is undefined.
222 */
223static inline void skip_put_bits(PutBitContext *s, int n)
224{
225 s->bit_left -= n;
226 s->buf_ptr -= 4 * (s->bit_left >> 5);
227 s->bit_left &= 31;
228}
229
230/**
231 * Change the end of the buffer.
232 *
233 * @param size the new size in bytes of the buffer where to put bits
234 */
235static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
236{
237 s->buf_end = s->buf + size;
238}
239
240#endif /* AVCODEC_PUT_BITS_H */