Initial revision
[libav.git] / libav / common.c
1 /*
2 * Common bit/dsp utils
3 * Copyright (c) 2000 Gerard Lantau.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <netinet/in.h>
23 #include <math.h>
24 #include "common.h"
25
26 #define NDEBUG
27 #include <assert.h>
28
29 void init_put_bits(PutBitContext *s,
30 UINT8 *buffer, int buffer_size,
31 void *opaque,
32 void (*write_data)(void *, UINT8 *, int))
33 {
34 s->buf = buffer;
35 s->buf_ptr = s->buf;
36 s->buf_end = s->buf + buffer_size;
37 s->bit_cnt=0;
38 s->bit_buf=0;
39 s->data_out_size = 0;
40 s->write_data = write_data;
41 s->opaque = opaque;
42 }
43
44 static void flush_buffer(PutBitContext *s)
45 {
46 int size;
47 if (s->write_data) {
48 size = s->buf_ptr - s->buf;
49 if (size > 0)
50 s->write_data(s->opaque, s->buf, size);
51 s->buf_ptr = s->buf;
52 s->data_out_size += size;
53 }
54 }
55
56 void put_bits(PutBitContext *s, int n, unsigned int value)
57 {
58 unsigned int bit_buf;
59 int bit_cnt;
60
61 assert(n == 32 || value < (1U << n));
62
63 bit_buf = s->bit_buf;
64 bit_cnt = s->bit_cnt;
65
66 // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
67 /* XXX: optimize */
68 if (n < (32-bit_cnt)) {
69 bit_buf |= value << (32 - n - bit_cnt);
70 bit_cnt+=n;
71 } else {
72 bit_buf |= value >> (n + bit_cnt - 32);
73 *(UINT32 *)s->buf_ptr = htonl(bit_buf);
74 //printf("bitbuf = %08x\n", bit_buf);
75 s->buf_ptr+=4;
76 if (s->buf_ptr >= s->buf_end)
77 flush_buffer(s);
78 bit_cnt=bit_cnt + n - 32;
79 if (bit_cnt == 0) {
80 bit_buf = 0;
81 } else {
82 bit_buf = value << (32 - bit_cnt);
83 }
84 }
85
86 s->bit_buf = bit_buf;
87 s->bit_cnt = bit_cnt;
88 }
89
90 /* return the number of bits output */
91 long long get_bit_count(PutBitContext *s)
92 {
93 return (s->buf_ptr - s->buf + s->data_out_size) * 8 + (long long)s->bit_cnt;
94 }
95
96 void align_put_bits(PutBitContext *s)
97 {
98 put_bits(s,(8 - s->bit_cnt) & 7,0);
99 }
100
101 /* pad the end of the output stream with zeros */
102 void flush_put_bits(PutBitContext *s)
103 {
104 while (s->bit_cnt > 0) {
105 /* XXX: should test end of buffer */
106 *s->buf_ptr++=s->bit_buf >> 24;
107 s->bit_buf<<=8;
108 s->bit_cnt-=8;
109 }
110 flush_buffer(s);
111 s->bit_cnt=0;
112 s->bit_buf=0;
113 }
114
115 /* for jpeg : espace 0xff with 0x00 after it */
116 void jput_bits(PutBitContext *s, int n, unsigned int value)
117 {
118 unsigned int bit_buf, b;
119 int bit_cnt, i;
120
121 assert(n == 32 || value < (1U << n));
122
123 bit_buf = s->bit_buf;
124 bit_cnt = s->bit_cnt;
125
126 //printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
127 /* XXX: optimize */
128 if (n < (32-bit_cnt)) {
129 bit_buf |= value << (32 - n - bit_cnt);
130 bit_cnt+=n;
131 } else {
132 bit_buf |= value >> (n + bit_cnt - 32);
133 /* handle escape */
134 for(i=0;i<4;i++) {
135 b = (bit_buf >> 24);
136 *(s->buf_ptr++) = b;
137 if (b == 0xff)
138 *(s->buf_ptr++) = 0;
139 bit_buf <<= 8;
140 }
141 /* we flush the buffer sooner to handle worst case */
142 if (s->buf_ptr >= (s->buf_end - 8))
143 flush_buffer(s);
144
145 bit_cnt=bit_cnt + n - 32;
146 if (bit_cnt == 0) {
147 bit_buf = 0;
148 } else {
149 bit_buf = value << (32 - bit_cnt);
150 }
151 }
152
153 s->bit_buf = bit_buf;
154 s->bit_cnt = bit_cnt;
155 }
156
157 /* pad the end of the output stream with zeros */
158 void jflush_put_bits(PutBitContext *s)
159 {
160 unsigned int b;
161
162 while (s->bit_cnt > 0) {
163 b = s->bit_buf >> 24;
164 *s->buf_ptr++ = b;
165 if (b == 0xff)
166 *s->buf_ptr++ = 0;
167 s->bit_buf<<=8;
168 s->bit_cnt-=8;
169 }
170 flush_buffer(s);
171 s->bit_cnt=0;
172 s->bit_buf=0;
173 }
174