e60b0dd85b6270884db5caa38dfb4bf1eee08079
[ffmpeg.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