annotate ffmpeg/libavutil/integer.c @ 13:844d341cf643 tip

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