]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/rangecoder.c
Update licensing information: The FSF changed postal address.
[frescor/ffmpeg.git] / libavcodec / rangecoder.c
1 /*
2  * Range coder
3  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  */
20
21 /**
22  * @file rangecoder.c
23  * Range coder.
24  * based upon
25  *    "Range encoding: an algorithm for removing redundancy from a digitised
26  *                     message.
27  *     G. N. N. Martin                  Presented in March 1979 to the Video &
28  *                                      Data Recording Conference,
29  *     IBM UK Scientific Center         held in Southampton July 24-27 1979."
30  *
31  */
32
33 #include <string.h>
34
35 #include "avcodec.h"
36 #include "common.h"
37 #include "rangecoder.h"
38
39
40 void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size){
41     c->bytestream_start=
42     c->bytestream= buf;
43     c->bytestream_end= buf + buf_size;
44
45     c->low= 0;
46     c->range= 0xFF00;
47     c->outstanding_count= 0;
48     c->outstanding_byte= -1;
49 }
50
51 void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size){
52     /* cast to avoid compiler warning */
53     ff_init_range_encoder(c, (uint8_t *) buf, buf_size);
54
55     c->low =(*c->bytestream++)<<8;
56     c->low+= *c->bytestream++;
57 }
58
59 void ff_build_rac_states(RangeCoder *c, int factor, int max_p){
60     const int64_t one= 1LL<<32;
61     int64_t p;
62     int last_p8, p8, i;
63
64     memset(c->zero_state, 0, sizeof(c->zero_state));
65     memset(c-> one_state, 0, sizeof(c-> one_state));
66
67 #if 0
68     for(i=1; i<256; i++){
69         if(c->one_state[i])
70             continue;
71
72         p= (i*one + 128) >> 8;
73         last_p8= i;
74         for(;;){
75             p+= ((one-p)*factor + one/2) >> 32;
76             p8= (256*p + one/2) >> 32; //FIXME try without the one
77             if(p8 <= last_p8) p8= last_p8+1;
78             if(p8 > max_p) p8= max_p;
79             if(p8 < last_p8)
80                 break;
81             c->one_state[last_p8]=     p8;
82             if(p8 == last_p8)
83                 break;
84             last_p8= p8;
85         }
86     }
87 #endif
88 #if 1
89     last_p8= 0;
90     p= one/2;
91     for(i=0; i<128; i++){
92         p8= (256*p + one/2) >> 32; //FIXME try without the one
93         if(p8 <= last_p8) p8= last_p8+1;
94         if(last_p8 && last_p8<256 && p8<=max_p)
95             c->one_state[last_p8]= p8;
96
97         p+= ((one-p)*factor + one/2) >> 32;
98         last_p8= p8;
99     }
100 #endif
101     for(i=256-max_p; i<=max_p; i++){
102         if(c->one_state[i])
103             continue;
104
105         p= (i*one + 128) >> 8;
106         p+= ((one-p)*factor + one/2) >> 32;
107         p8= (256*p + one/2) >> 32; //FIXME try without the one
108         if(p8 <= i) p8= i+1;
109         if(p8 > max_p) p8= max_p;
110         c->one_state[    i]=     p8;
111     }
112
113     for(i=0; i<256; i++)
114         c->zero_state[i]= 256-c->one_state[256-i];
115 #if 0
116     for(i=0; i<256; i++)
117         av_log(NULL, AV_LOG_DEBUG, "%3d %3d\n", i, c->one_state[i]);
118 #endif
119 }
120
121 /**
122  *
123  * @return the number of bytes written
124  */
125 int ff_rac_terminate(RangeCoder *c){
126     c->range=0xFF;
127     c->low +=0xFF;
128     renorm_encoder(c);
129     c->range=0xFF;
130     renorm_encoder(c);
131
132     assert(c->low   == 0);
133     assert(c->range >= 0x100);
134
135     return c->bytestream - c->bytestream_start;
136 }
137
138 #if 0 //selftest
139 #define SIZE 10240
140 int main(){
141     RangeCoder c;
142     uint8_t b[9*SIZE];
143     uint8_t r[9*SIZE];
144     int i;
145     uint8_t state[10]= {0};
146
147     ff_init_range_encoder(&c, b, SIZE);
148     ff_build_rac_states(&c, 0.05*(1LL<<32), 128+64+32+16);
149
150     memset(state, 128, sizeof(state));
151
152     for(i=0; i<SIZE; i++){
153         r[i]= random()%7;
154     }
155
156
157     for(i=0; i<SIZE; i++){
158 START_TIMER
159         put_rac(&c, state, r[i]&1);
160 STOP_TIMER("put_rac")
161     }
162
163     ff_put_rac_terminate(&c);
164
165     ff_init_range_decoder(&c, b, SIZE);
166
167     memset(state, 128, sizeof(state));
168
169     for(i=0; i<SIZE; i++){
170 START_TIMER
171         if( (r[i]&1) != get_rac(&c, state) )
172             av_log(NULL, AV_LOG_DEBUG, "rac failure at %d\n", i);
173 STOP_TIMER("get_rac")
174     }
175
176     return 0;
177 }
178
179 #endif