annotate cabac.c @ 3295:8c9825dbea20 libavcodec

add outcommented chunk of code to handle stuffing MBs at the end of slices (IMHO the standard doesnt allow this and there are no real world files which need it)
author michael
date Mon, 08 May 2006 13:44:54 +0000
parents 0b546eab515d
children c8c591fe26f8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1287
michaelni
parents:
diff changeset
1 /*
michaelni
parents:
diff changeset
2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
michaelni
parents:
diff changeset
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
michaelni
parents:
diff changeset
4 *
michaelni
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
michaelni
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
michaelni
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
michaelni
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
michaelni
parents:
diff changeset
9 *
michaelni
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
michaelni
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
michaelni
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michaelni
parents:
diff changeset
13 * Lesser General Public License for more details.
michaelni
parents:
diff changeset
14 *
michaelni
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
michaelni
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2967
diff changeset
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1287
michaelni
parents:
diff changeset
18 *
michaelni
parents:
diff changeset
19 */
michaelni
parents:
diff changeset
20
michaelni
parents:
diff changeset
21 /**
michaelni
parents:
diff changeset
22 * @file cabac.c
michaelni
parents:
diff changeset
23 * Context Adaptive Binary Arithmetic Coder.
michaelni
parents:
diff changeset
24 */
michaelni
parents:
diff changeset
25
michaelni
parents:
diff changeset
26 #include <string.h>
michaelni
parents:
diff changeset
27
michaelni
parents:
diff changeset
28 #include "common.h"
2398
582e635cfa08 common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents: 2323
diff changeset
29 #include "bitstream.h"
1287
michaelni
parents:
diff changeset
30 #include "cabac.h"
michaelni
parents:
diff changeset
31
michaelni
parents:
diff changeset
32 const uint8_t ff_h264_lps_range[64][4]= {
michaelni
parents:
diff changeset
33 {128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205},
michaelni
parents:
diff changeset
34 {116,142,169,195}, {111,135,160,185}, {105,128,152,175}, {100,122,144,166},
michaelni
parents:
diff changeset
35 { 95,116,137,158}, { 90,110,130,150}, { 85,104,123,142}, { 81, 99,117,135},
michaelni
parents:
diff changeset
36 { 77, 94,111,128}, { 73, 89,105,122}, { 69, 85,100,116}, { 66, 80, 95,110},
michaelni
parents:
diff changeset
37 { 62, 76, 90,104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89},
michaelni
parents:
diff changeset
38 { 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72},
michaelni
parents:
diff changeset
39 { 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59},
michaelni
parents:
diff changeset
40 { 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48},
michaelni
parents:
diff changeset
41 { 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39},
michaelni
parents:
diff changeset
42 { 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31},
michaelni
parents:
diff changeset
43 { 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25},
michaelni
parents:
diff changeset
44 { 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21},
michaelni
parents:
diff changeset
45 { 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17},
michaelni
parents:
diff changeset
46 { 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14},
michaelni
parents:
diff changeset
47 { 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11},
michaelni
parents:
diff changeset
48 { 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2},
michaelni
parents:
diff changeset
49 };
michaelni
parents:
diff changeset
50
michaelni
parents:
diff changeset
51 const uint8_t ff_h264_mps_state[64]= {
michaelni
parents:
diff changeset
52 1, 2, 3, 4, 5, 6, 7, 8,
michaelni
parents:
diff changeset
53 9,10,11,12,13,14,15,16,
michaelni
parents:
diff changeset
54 17,18,19,20,21,22,23,24,
michaelni
parents:
diff changeset
55 25,26,27,28,29,30,31,32,
michaelni
parents:
diff changeset
56 33,34,35,36,37,38,39,40,
michaelni
parents:
diff changeset
57 41,42,43,44,45,46,47,48,
michaelni
parents:
diff changeset
58 49,50,51,52,53,54,55,56,
michaelni
parents:
diff changeset
59 57,58,59,60,61,62,62,63,
michaelni
parents:
diff changeset
60 };
michaelni
parents:
diff changeset
61
michaelni
parents:
diff changeset
62 const uint8_t ff_h264_lps_state[64]= {
michaelni
parents:
diff changeset
63 0, 0, 1, 2, 2, 4, 4, 5,
michaelni
parents:
diff changeset
64 6, 7, 8, 9, 9,11,11,12,
michaelni
parents:
diff changeset
65 13,13,15,15,16,16,18,18,
michaelni
parents:
diff changeset
66 19,19,21,21,22,22,23,24,
michaelni
parents:
diff changeset
67 24,25,26,26,27,27,28,29,
michaelni
parents:
diff changeset
68 29,30,30,30,31,32,32,33,
michaelni
parents:
diff changeset
69 33,33,34,34,35,35,35,36,
michaelni
parents:
diff changeset
70 36,36,37,37,37,38,38,63,
michaelni
parents:
diff changeset
71 };
michaelni
parents:
diff changeset
72
2323
1c39d9786efd optimization
michael
parents: 2116
diff changeset
73 const uint8_t ff_h264_norm_shift[256]= {
1c39d9786efd optimization
michael
parents: 2116
diff changeset
74 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,
1c39d9786efd optimization
michael
parents: 2116
diff changeset
75 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
1c39d9786efd optimization
michael
parents: 2116
diff changeset
76 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1c39d9786efd optimization
michael
parents: 2116
diff changeset
77 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1c39d9786efd optimization
michael
parents: 2116
diff changeset
78 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1c39d9786efd optimization
michael
parents: 2116
diff changeset
79 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1c39d9786efd optimization
michael
parents: 2116
diff changeset
80 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1c39d9786efd optimization
michael
parents: 2116
diff changeset
81 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
82 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
83 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
84 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
85 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
86 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
87 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
88 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
89 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2323
1c39d9786efd optimization
michael
parents: 2116
diff changeset
90 };
1c39d9786efd optimization
michael
parents: 2116
diff changeset
91
1287
michaelni
parents:
diff changeset
92 /**
michaelni
parents:
diff changeset
93 *
michaelni
parents:
diff changeset
94 * @param buf_size size of buf in bits
michaelni
parents:
diff changeset
95 */
michaelni
parents:
diff changeset
96 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
1522
79dddc5cd990 removed the obsolete and unused parameters of init_put_bits
alex
parents: 1300
diff changeset
97 init_put_bits(&c->pb, buf, buf_size);
1287
michaelni
parents:
diff changeset
98
michaelni
parents:
diff changeset
99 c->low= 0;
michaelni
parents:
diff changeset
100 c->range= 0x1FE;
michaelni
parents:
diff changeset
101 c->outstanding_count= 0;
michaelni
parents:
diff changeset
102 #ifdef STRICT_LIMITS
michaelni
parents:
diff changeset
103 c->sym_count =0;
michaelni
parents:
diff changeset
104 #endif
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
105
1287
michaelni
parents:
diff changeset
106 c->pb.bit_left++; //avoids firstBitFlag
michaelni
parents:
diff changeset
107 }
michaelni
parents:
diff changeset
108
michaelni
parents:
diff changeset
109 /**
michaelni
parents:
diff changeset
110 *
michaelni
parents:
diff changeset
111 * @param buf_size size of buf in bits
michaelni
parents:
diff changeset
112 */
2024
f65d87bfdd5a some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents: 1908
diff changeset
113 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
114 c->bytestream_start=
1287
michaelni
parents:
diff changeset
115 c->bytestream= buf;
2116
48d9f86fb047 overread fix
michael
parents: 2024
diff changeset
116 c->bytestream_end= buf + buf_size;
1287
michaelni
parents:
diff changeset
117
2323
1c39d9786efd optimization
michael
parents: 2116
diff changeset
118 #if CABAC_BITS == 16
1c39d9786efd optimization
michael
parents: 2116
diff changeset
119 c->low = (*c->bytestream++)<<18;
1c39d9786efd optimization
michael
parents: 2116
diff changeset
120 c->low+= (*c->bytestream++)<<10;
1c39d9786efd optimization
michael
parents: 2116
diff changeset
121 #else
1c39d9786efd optimization
michael
parents: 2116
diff changeset
122 c->low = (*c->bytestream++)<<10;
1c39d9786efd optimization
michael
parents: 2116
diff changeset
123 #endif
1c39d9786efd optimization
michael
parents: 2116
diff changeset
124 c->low+= ((*c->bytestream++)<<2) + 2;
1c39d9786efd optimization
michael
parents: 2116
diff changeset
125 c->range= 0x1FE<<(CABAC_BITS + 1);
1287
michaelni
parents:
diff changeset
126 }
michaelni
parents:
diff changeset
127
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
128 void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4],
1287
michaelni
parents:
diff changeset
129 uint8_t const *mps_state, uint8_t const *lps_state, int state_count){
michaelni
parents:
diff changeset
130 int i, j;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
131
1287
michaelni
parents:
diff changeset
132 for(i=0; i<state_count; i++){
michaelni
parents:
diff changeset
133 for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save
2323
1c39d9786efd optimization
michael
parents: 2116
diff changeset
134 c->lps_range[2*i+0][j+4]=
1c39d9786efd optimization
michael
parents: 2116
diff changeset
135 c->lps_range[2*i+1][j+4]= lps_range[i][j];
1287
michaelni
parents:
diff changeset
136 }
michaelni
parents:
diff changeset
137
michaelni
parents:
diff changeset
138 c->mps_state[2*i+0]= 2*mps_state[i];
michaelni
parents:
diff changeset
139 c->mps_state[2*i+1]= 2*mps_state[i]+1;
michaelni
parents:
diff changeset
140
1908
e20fd60b215c h264 - progressive I frame CABAC support patch by (Laurent Aimar <fenrir at via dot ecp dot fr>)
michael
parents: 1522
diff changeset
141 if( i ){
1287
michaelni
parents:
diff changeset
142 c->lps_state[2*i+0]= 2*lps_state[i];
michaelni
parents:
diff changeset
143 c->lps_state[2*i+1]= 2*lps_state[i]+1;
michaelni
parents:
diff changeset
144 }else{
michaelni
parents:
diff changeset
145 c->lps_state[2*i+0]= 1;
michaelni
parents:
diff changeset
146 c->lps_state[2*i+1]= 0;
michaelni
parents:
diff changeset
147 }
michaelni
parents:
diff changeset
148 }
michaelni
parents:
diff changeset
149 }
michaelni
parents:
diff changeset
150
michaelni
parents:
diff changeset
151 #if 0 //selftest
michaelni
parents:
diff changeset
152 #define SIZE 10240
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
153
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
154 #include "avcodec.h"
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
155
1287
michaelni
parents:
diff changeset
156 int main(){
michaelni
parents:
diff changeset
157 CABACContext c;
michaelni
parents:
diff changeset
158 uint8_t b[9*SIZE];
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
159 uint8_t r[9*SIZE];
1287
michaelni
parents:
diff changeset
160 int i;
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
161 uint8_t state[10]= {0};
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
162
1287
michaelni
parents:
diff changeset
163 ff_init_cabac_encoder(&c, b, SIZE);
michaelni
parents:
diff changeset
164 ff_init_cabac_states(&c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
165
1287
michaelni
parents:
diff changeset
166 for(i=0; i<SIZE; i++){
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
167 r[i]= random()%7;
1287
michaelni
parents:
diff changeset
168 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
169
1287
michaelni
parents:
diff changeset
170 for(i=0; i<SIZE; i++){
michaelni
parents:
diff changeset
171 START_TIMER
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
172 put_cabac_bypass(&c, r[i]&1);
1287
michaelni
parents:
diff changeset
173 STOP_TIMER("put_cabac_bypass")
michaelni
parents:
diff changeset
174 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
175
1287
michaelni
parents:
diff changeset
176 for(i=0; i<SIZE; i++){
michaelni
parents:
diff changeset
177 START_TIMER
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
178 put_cabac(&c, state, r[i]&1);
1287
michaelni
parents:
diff changeset
179 STOP_TIMER("put_cabac")
michaelni
parents:
diff changeset
180 }
michaelni
parents:
diff changeset
181
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
182 for(i=0; i<SIZE; i++){
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
183 START_TIMER
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
184 put_cabac_u(&c, state, r[i], 6, 3, i&1);
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
185 STOP_TIMER("put_cabac_u")
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
186 }
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
187
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
188 for(i=0; i<SIZE; i++){
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
189 START_TIMER
1298
5bc3184810dc cleanup
michaelni
parents: 1290
diff changeset
190 put_cabac_ueg(&c, state, r[i], 3, 0, 1, 2);
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
191 STOP_TIMER("put_cabac_ueg")
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
192 }
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
193
1287
michaelni
parents:
diff changeset
194 put_cabac_terminate(&c, 1);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
195
1287
michaelni
parents:
diff changeset
196 ff_init_cabac_decoder(&c, b, SIZE);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
197
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
198 memset(state, 0, sizeof(state));
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
199
1287
michaelni
parents:
diff changeset
200 for(i=0; i<SIZE; i++){
michaelni
parents:
diff changeset
201 START_TIMER
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
202 if( (r[i]&1) != get_cabac_bypass(&c) )
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
203 av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
1287
michaelni
parents:
diff changeset
204 STOP_TIMER("get_cabac_bypass")
michaelni
parents:
diff changeset
205 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
206
1287
michaelni
parents:
diff changeset
207 for(i=0; i<SIZE; i++){
michaelni
parents:
diff changeset
208 START_TIMER
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
209 if( (r[i]&1) != get_cabac(&c, state) )
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
210 av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
1287
michaelni
parents:
diff changeset
211 STOP_TIMER("get_cabac")
michaelni
parents:
diff changeset
212 }
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
213 #if 0
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
214 for(i=0; i<SIZE; i++){
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
215 START_TIMER
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
216 if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) )
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
217 av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
218 STOP_TIMER("get_cabac_u")
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
219 }
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
220
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
221 for(i=0; i<SIZE; i++){
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
222 START_TIMER
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
223 if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2))
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
224 av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
1290
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
225 STOP_TIMER("get_cabac_ueg")
dae280b939ca (truncated) unary binerization
michaelni
parents: 1287
diff changeset
226 }
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
227 #endif
1287
michaelni
parents:
diff changeset
228 if(!get_cabac_terminate(&c))
2420
842e5e7f3b7a fixing selftest
michael
parents: 2398
diff changeset
229 av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2420
diff changeset
230
1287
michaelni
parents:
diff changeset
231 return 0;
michaelni
parents:
diff changeset
232 }
michaelni
parents:
diff changeset
233
michaelni
parents:
diff changeset
234 #endif