]> git.sesse.net Git - x264/blob - common/bs.h
fix rounding of intra dequant when qp<=3
[x264] / common / bs.h
1 /*****************************************************************************
2  * bs.h :
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: bs.h,v 1.1 2004/06/03 19:27:06 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #ifdef _BS_H
25 #warning FIXME Multiple inclusion of bs.h
26 #else
27 #define _BS_H
28
29 typedef struct bs_s
30 {
31     uint8_t *p_start;
32     uint8_t *p;
33     uint8_t *p_end;
34
35     int     i_left;    /* i_count number of available bits */
36 } bs_t;
37
38 static inline void bs_init( bs_t *s, void *p_data, int i_data )
39 {
40     s->p_start = p_data;
41     s->p       = p_data;
42     s->p_end   = s->p + i_data;
43     s->i_left  = 8;
44 }
45 static inline int bs_pos( bs_t *s )
46 {
47     return( 8 * ( s->p - s->p_start ) + 8 - s->i_left );
48 }
49 static inline int bs_eof( bs_t *s )
50 {
51     return( s->p >= s->p_end ? 1: 0 );
52 }
53 static inline uint32_t bs_read( bs_t *s, int i_count )
54 {
55      static uint32_t i_mask[33] ={0x00,
56                                   0x01,      0x03,      0x07,      0x0f,
57                                   0x1f,      0x3f,      0x7f,      0xff,
58                                   0x1ff,     0x3ff,     0x7ff,     0xfff,
59                                   0x1fff,    0x3fff,    0x7fff,    0xffff,
60                                   0x1ffff,   0x3ffff,   0x7ffff,   0xfffff,
61                                   0x1fffff,  0x3fffff,  0x7fffff,  0xffffff,
62                                   0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
63                                   0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
64     int      i_shr;
65     uint32_t i_result = 0;
66
67     while( i_count > 0 )
68     {
69         if( s->p >= s->p_end )
70         {
71             break;
72         }
73
74         if( ( i_shr = s->i_left - i_count ) >= 0 )
75         {
76             /* more in the buffer than requested */
77             i_result |= ( *s->p >> i_shr )&i_mask[i_count];
78             s->i_left -= i_count;
79             if( s->i_left == 0 )
80             {
81                 s->p++;
82                 s->i_left = 8;
83             }
84             return( i_result );
85         }
86         else
87         {
88             /* less in the buffer than requested */
89            i_result |= (*s->p&i_mask[s->i_left]) << -i_shr;
90            i_count  -= s->i_left;
91            s->p++;
92            s->i_left = 8;
93         }
94     }
95
96     return( i_result );
97 }
98
99 #if 0
100 /* Only > i386 */
101 static uint32_t bswap32( uint32_t x )
102 {
103     asm( "bswap   %0": "=r" (x):"0" (x));
104     return x;
105 }
106 /* work only for i_count <= 32 - 7 */
107 static inline uint32_t bs_read( bs_t *s, int i_count )
108 {
109     if( s->p < s->p_end && i_count > 0 )
110     {
111 #if 0
112         uint32_t i_cache = ((s->p[0] << 24)+(s->p[1] << 16)+(s->p[2] << 8)+s->p[3]) << (8-s->i_left);
113 #else
114         uint32_t i_cache = bswap32( *((uint32_t*)s->p) ) << (8-s->i_left);
115 #endif
116         uint32_t i_ret = i_cache >> ( 32 - i_count);
117
118         s->i_left -= i_count;
119 #if 0
120         if( s->i_left <= 0 )
121         {
122             int i_skip = (8-s->i_left) >> 3;
123
124             s->p += i_skip;
125
126             s->i_left += i_skip << 3;
127         }
128 #else
129         while( s->i_left <= 0 )
130         {
131             s->p++;
132             s->i_left += 8;
133         }
134 #endif
135         return i_ret;
136     }
137     return 0;
138 }
139
140 #endif
141 static inline uint32_t bs_read1( bs_t *s )
142 {
143
144     if( s->p < s->p_end )
145     {
146         unsigned int i_result;
147
148         s->i_left--;
149         i_result = ( *s->p >> s->i_left )&0x01;
150         if( s->i_left == 0 )
151         {
152             s->p++;
153             s->i_left = 8;
154         }
155         return i_result;
156     }
157
158     return 0;
159 }
160 static inline uint32_t bs_show( bs_t *s, int i_count )
161 {
162 #if 0
163     bs_t     s_tmp = *s;
164     return bs_read( &s_tmp, i_count );
165 #else
166     if( s->p < s->p_end && i_count > 0 )
167     {
168         uint32_t i_cache = ((s->p[0] << 24)+(s->p[1] << 16)+(s->p[2] << 8)+s->p[3]) << (8-s->i_left);
169         return( i_cache >> ( 32 - i_count) );
170     }
171     return 0;
172 #endif
173 }
174
175 /* TODO optimize */
176 static inline void bs_skip( bs_t *s, int i_count )
177 {
178     s->i_left -= i_count;
179
180     while( s->i_left <= 0 )
181     {
182         s->p++;
183         s->i_left += 8;
184     }
185 }
186
187
188 static inline int bs_read_ue( bs_t *s )
189 {
190     int i = 0;
191
192     while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 )
193     {
194         i++;
195     }
196     return( ( 1 << i) - 1 + bs_read( s, i ) );
197 }
198 static inline int bs_read_se( bs_t *s )
199 {
200     int val = bs_read_ue( s );
201
202     return val&0x01 ? (val+1)/2 : -(val/2);
203 }
204
205 static inline int bs_read_te( bs_t *s, int x )
206 {
207     if( x == 1 )
208     {
209         return 1 - bs_read1( s );
210     }
211     else if( x > 1 )
212     {
213         return bs_read_ue( s );
214     }
215     return 0;
216 }
217
218 /* TODO optimize (write x bits at once) */
219 static inline void bs_write( bs_t *s, int i_count, uint32_t i_bits )
220 {
221     while( i_count > 0 )
222     {
223         if( s->p >= s->p_end )
224         {
225             break;
226         }
227
228         i_count--;
229
230         if( ( i_bits >> i_count )&0x01 )
231         {
232             *s->p |= 1 << ( s->i_left - 1 );
233         }
234         else
235         {
236             *s->p &= ~( 1 << ( s->i_left - 1 ) );
237         }
238         s->i_left--;
239         if( s->i_left == 0 )
240         {
241             s->p++;
242             s->i_left = 8;
243         }
244     }
245 }
246
247 static inline void bs_write1( bs_t *s, uint32_t i_bits )
248 {
249     if( s->p < s->p_end )
250     {
251         s->i_left--;
252
253         if( i_bits&0x01 )
254         {
255             *s->p |= 1 << s->i_left;
256         }
257         else
258         {
259             *s->p &= ~( 1 << s->i_left );
260         }
261         if( s->i_left == 0 )
262         {
263             s->p++;
264             s->i_left = 8;
265         }
266     }
267 }
268
269 static inline void bs_align( bs_t *s )
270 {
271     if( s->i_left != 8 )
272     {
273         s->i_left = 8;
274         s->p++;
275     }
276 }
277 static inline void bs_align_0( bs_t *s )
278 {
279     if( s->i_left != 8 )
280     {
281         bs_write( s, s->i_left, 0 );
282     }
283 }
284 static inline void bs_align_1( bs_t *s )
285 {
286     if( s->i_left != 8 )
287     {
288         bs_write( s, s->i_left, ~0 );
289     }
290 }
291
292
293
294 /* golomb functions */
295
296 static inline void bs_write_ue( bs_t *s, unsigned int val )
297 {
298     int i_size = 0;
299     static const int i_size0_255[256] =
300     {
301         1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
302         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
303         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
304         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
305         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
306         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
307         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
308         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
309     };
310
311     if( val == 0 )
312     {
313         bs_write( s, 1, 1 );
314     }
315     else
316     {
317         unsigned int tmp = ++val;
318
319         if( tmp >= 0x00010000 )
320         {
321             i_size += 16;
322             tmp >>= 16;
323         }
324         if( tmp >= 0x100 )
325         {
326             i_size += 8;
327             tmp >>= 8;
328         }
329         i_size += i_size0_255[tmp];
330
331         bs_write( s, 2 * i_size - 1, val );
332     }
333 }
334
335 static inline void bs_write_se( bs_t *s, int val )
336 {
337     bs_write_ue( s, val <= 0 ? -val * 2 : val * 2 - 1);
338 }
339
340 static inline void bs_write_te( bs_t *s, int x, int val )
341 {
342     if( x == 1 )
343     {
344         bs_write( s, 1, ~val );
345     }
346     else if( x > 1 )
347     {
348         bs_write_ue( s, val );
349     }
350 }
351
352 static inline void bs_rbsp_trailing( bs_t *s )
353 {
354     bs_write( s, 1, 1 );
355     if( s->i_left != 8 )
356     {
357         bs_write( s, s->i_left, 0x00 );
358     }
359 }
360
361 static inline int bs_size_ue( unsigned int val )
362 {
363     static const int i_size0_254[255] =
364     {
365         1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
366         9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
367         11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
368         11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
369         13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
370         13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
371         13,13,13,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
372         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
373         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
374         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
375         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
376         15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
377     };
378
379     if( val < 255 )
380     {
381         return i_size0_254[val];
382     }
383     else
384     {
385         int i_size = 0;
386
387         val++;
388
389         if( val >= 0x10000 )
390         {
391             i_size += 32;
392             val = (val >> 16) - 1;
393         }
394         if( val >= 0x100 )
395         {
396             i_size += 16;
397             val = (val >> 8) - 1;
398         }
399         return i_size0_254[val] + i_size;
400     }
401 }
402
403 static inline int bs_size_se( int val )
404 {
405     return bs_size_ue( val <= 0 ? -val * 2 : val * 2 - 1);
406 }
407
408 static inline int bs_size_te( int x, int val )
409 {
410     if( x == 1 )
411     {
412         return 1;
413     }
414     else if( x > 1 )
415     {
416         return bs_size_ue( val );
417     }
418     return 0;
419 }
420
421
422
423 #endif