annotate integer.c @ 2071:41d30bae5019 libavcodec

attempt to create some separation in the FLAC system with respect to demuxer and decoder layers by enabling the FLAC decoder to decode data without needing the entire file, from start to finish
author melanson
date Thu, 10 Jun 2004 04:13:43 +0000
parents 7523553ca85f
children 2c2f738772b7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2001
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
1 /*
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
2 * arbitrary precision integers
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
3 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
4 *
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
9 *
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
13 * Lesser General Public License for more details.
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
14 *
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
18 *
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
19 */
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
20
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
21 /**
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
22 * @file integer.c
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
23 * arbitrary precision integers.
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
24 * @author Michael Niedermayer <michaelni@gmx.at>
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
25 */
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
26
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
27 #include "common.h"
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
28 #include "integer.h"
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
29
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
30 AVInteger av_add_i(AVInteger a, AVInteger b){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
31 int i, carry=0;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
32
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
33 for(i=0; i<AV_INTEGER_SIZE; i++){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
34 carry= (carry>>16) + a.v[i] + b.v[i];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
35 a.v[i]= carry;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
36 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
37 return a;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
38 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
39
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
40 AVInteger av_sub_i(AVInteger a, AVInteger b){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
41 int i, carry=0;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
42
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
43 for(i=0; i<AV_INTEGER_SIZE; i++){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
44 carry= (carry>>16) + a.v[i] - b.v[i];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
45 a.v[i]= carry;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
46 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
47 return a;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
48 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
49
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
50 int av_log2_i(AVInteger a){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
51 int i;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
52
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
53 for(i=AV_INTEGER_SIZE-1; i>=0; i--){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
54 if(a.v[i])
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
55 return av_log2_16bit(a.v[i]) + 16*i;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
56 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
57 return -1;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
58 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
59
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
60 AVInteger av_mul_i(AVInteger a, AVInteger b){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
61 AVInteger out;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
62 int i, j;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
63 int na= (av_log2_i(a)+16) >> 4;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
64 int nb= (av_log2_i(b)+16) >> 4;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
65
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
66 memset(&out, 0, sizeof(out));
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
67
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
68 for(i=0; i<na; i++){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
69 unsigned int carry=0;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
70
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
71 if(a.v[i])
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
72 for(j=i; j<AV_INTEGER_SIZE && j-i<=nb; j++){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
73 carry= (carry>>16) + out.v[j] + a.v[i]*b.v[j-i];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
74 out.v[j]= carry;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
75 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
76 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
77
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
78 return out;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
79 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
80
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
81 int av_cmp_i(AVInteger a, AVInteger b){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
82 int i;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
83 int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
84 if(v) return (v>>16)|1;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
85
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
86 for(i=AV_INTEGER_SIZE-2; i>=0; i--){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
87 int v= a.v[i] - b.v[i];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
88 if(v) return (v>>16)|1;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
89 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
90 return 0;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
91 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
92
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
93 AVInteger av_shr_i(AVInteger a, int s){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
94 AVInteger out;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
95 int i;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
96
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
97 for(i=0; i<AV_INTEGER_SIZE; i++){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
98 int index= i + (s>>4);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
99 unsigned int v=0;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
100 if(index+1<AV_INTEGER_SIZE && index+1>=0) v = a.v[index+1]<<16;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
101 if(index <AV_INTEGER_SIZE && index >=0) v+= a.v[index ];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
102 out.v[i]= v >> (s&15);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
103 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
104 return out;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
105 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
106
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
107 AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
108 int i= av_log2_i(a) - av_log2_i(b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
109 AVInteger quot_temp;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
110 if(!quot) quot = &quot_temp;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
111
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
112 assert((int16_t)a[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b[AV_INTEGER_SIZE-1] >= 0);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
113 assert(av_log2(b)>=0);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
114
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
115 if(i > 0)
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
116 b= av_shr_i(b, -i);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
117
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
118 memset(quot, 0, sizeof(AVInteger));
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
119
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
120 while(i-- >= 0){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
121 *quot= av_shr_i(*quot, -1);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
122 if(av_cmp_i(a, b) >= 0){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
123 a= av_sub_i(a, b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
124 quot->v[0] += 1;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
125 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
126 b= av_shr_i(b, 1);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
127 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
128 return a;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
129 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
130
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
131 AVInteger av_div_i(AVInteger a, AVInteger b){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
132 AVInteger quot;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
133 av_mod_i(&quot, a, b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
134 return quot;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
135 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
136
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
137 AVInteger av_int2i(int64_t a){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
138 AVInteger out;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
139 int i;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
140
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
141 for(i=0; i<AV_INTEGER_SIZE; i++){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
142 out.v[i]= a;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
143 a>>=16;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
144 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
145 return out;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
146 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
147
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
148 int64_t av_i2int(AVInteger a){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
149 int i;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
150 int64_t out=(int8_t)a.v[AV_INTEGER_SIZE-1];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
151
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
152 for(i= AV_INTEGER_SIZE-2; i>=0; i--){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
153 out = (out<<16) + a.v[i];
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
154 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
155 return out;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
156 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
157
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
158 #if 0
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
159 #undef NDEBUG
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
160 #include <assert.h>
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
161
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
162 const uint8_t ff_log2_tab[256]={
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
163 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
164 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
165 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,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
166 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,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
167 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,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
168 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,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
169 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,
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
170 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
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
171 };
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
172
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
173 main(){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
174 int64_t a,b;
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
175
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
176 for(a=7; a<256*256*256; a+=13215){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
177 for(b=3; b<256*256*256; b+=27118){
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
178 AVInteger ai= av_int2i(a);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
179 AVInteger bi= av_int2i(b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
180
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
181 assert(av_i2int(ai) == a);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
182 assert(av_i2int(bi) == b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
183 assert(av_i2int(av_add_i(ai,bi)) == a+b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
184 assert(av_i2int(av_sub_i(ai,bi)) == a-b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
185 assert(av_i2int(av_mul_i(ai,bi)) == a*b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
186 assert(av_i2int(av_shr_i(ai, 9)) == a>>9);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
187 assert(av_i2int(av_shr_i(ai,-9)) == a<<9);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
188 assert(av_i2int(av_shr_i(ai, 17)) == a>>17);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
189 assert(av_i2int(av_shr_i(ai,-17)) == a<<17);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
190 assert(av_log2_i(ai) == av_log2(a));
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
191 assert(av_i2int(av_div_i(ai,bi)) == a/b);
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
192 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
193 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
194 }
7523553ca85f arbitrary precision integer support
michael
parents:
diff changeset
195 #endif