summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2010-12-08 16:34:25 +0000
committerNils Wallménius <nils@rockbox.org>2010-12-08 16:34:25 +0000
commit199b2a84e2b29bd7da582ab1588ebcb6f158928c (patch)
tree7ec85c2adee22d480c5aa4cfb63449b09dc94cf3
parentc0e3e1628575647ec9083fd23c26de85ea8f86c0 (diff)
downloadrockbox-199b2a84e2b29bd7da582ab1588ebcb6f158928c.tar.gz
rockbox-199b2a84e2b29bd7da582ab1588ebcb6f158928c.zip
libtremor: merge upstream revision 17534 and 17536, fixing a possible 64 bit math overflow and correct types for some comparisons.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28769 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libtremor/vorbisfile.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/apps/codecs/libtremor/vorbisfile.c b/apps/codecs/libtremor/vorbisfile.c
index 9365ba344b..f0a83364ec 100644
--- a/apps/codecs/libtremor/vorbisfile.c
+++ b/apps/codecs/libtremor/vorbisfile.c
@@ -193,7 +193,7 @@ static void _add_serialno(ogg_page *og,ogg_uint32_t **serialno_list, int *n){
193} 193}
194 194
195/* returns nonzero if found */ 195/* returns nonzero if found */
196static int _lookup_serialno(long s, ogg_uint32_t *serialno_list, int n){ 196static int _lookup_serialno(ogg_uint32_t s, ogg_uint32_t *serialno_list, int n){
197 if(serialno_list){ 197 if(serialno_list){
198 while(n--){ 198 while(n--){
199 if(*serialno_list == (ogg_uint32_t) s) return 1; 199 if(*serialno_list == (ogg_uint32_t) s) return 1;
@@ -204,7 +204,7 @@ static int _lookup_serialno(long s, ogg_uint32_t *serialno_list, int n){
204} 204}
205 205
206static int _lookup_page_serialno(ogg_page *og, ogg_uint32_t *serialno_list, int n){ 206static int _lookup_page_serialno(ogg_page *og, ogg_uint32_t *serialno_list, int n){
207 long s = ogg_page_serialno(og); 207 ogg_uint32_t s = ogg_page_serialno(og);
208 return _lookup_serialno(s,serialno_list,n); 208 return _lookup_serialno(s,serialno_list,n);
209} 209}
210 210
@@ -245,12 +245,12 @@ static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
245 ret_gran=ogg_page_granulepos(&og); 245 ret_gran=ogg_page_granulepos(&og);
246 offset=ret; 246 offset=ret;
247 247
248 if(ret_serialno == (ogg_uint32_t) *serialno){ 248 if((ogg_uint32_t)ret_serialno == (ogg_uint32_t)*serialno){
249 prefoffset=ret; 249 prefoffset=ret;
250 *granpos=ret_gran; 250 *granpos=ret_gran;
251 } 251 }
252 252
253 if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){ 253 if(!_lookup_serialno((ogg_uint32_t)ret_serialno,serial_list,serial_n)){
254 /* we fell off the end of the link, which means we seeked 254 /* we fell off the end of the link, which means we seeked
255 back too far and shouldn't have been looking in that link 255 back too far and shouldn't have been looking in that link
256 to begin with. If we found the preferred serial number, 256 to begin with. If we found the preferred serial number,
@@ -1201,6 +1201,36 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1201 return OV_EBADLINK; 1201 return OV_EBADLINK;
1202} 1202}
1203 1203
1204/* rescales the number x from the range of [0,from] to [0,to]
1205 x is in the range [0,from]
1206 from, to are in the range [1, 1<<62-1] */
1207ogg_int64_t rescale64(ogg_int64_t x, ogg_int64_t from, ogg_int64_t to){
1208 ogg_int64_t frac=0;
1209 ogg_int64_t ret=0;
1210 int i;
1211 if(x >= from) return to;
1212 if(x <= 0) return 0;
1213
1214 for(i=0;i<64;i++){
1215 if(x>=from){
1216 frac|=1;
1217 x-=from;
1218 }
1219 x<<=1;
1220 frac<<=1;
1221 }
1222
1223 for(i=0;i<64;i++){
1224 if(frac & 1){
1225 ret+=to;
1226 }
1227 frac>>=1;
1228 ret>>=1;
1229 }
1230
1231 return ret;
1232}
1233
1204/* Page granularity seek (faster than sample granularity because we 1234/* Page granularity seek (faster than sample granularity because we
1205 don't do the last bit of decode to find a specific sample). 1235 don't do the last bit of decode to find a specific sample).
1206 1236
@@ -1246,8 +1276,9 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1246 bisect=begin; 1276 bisect=begin;
1247 }else{ 1277 }else{
1248 /* take a (pretty decent) guess. */ 1278 /* take a (pretty decent) guess. */
1249 bisect=begin + 1279 bisect=begin + rescale64(target-begintime,
1250 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE; 1280 endtime-begintime,
1281 end-begin) - CHUNKSIZE;
1251 if(bisect<begin+CHUNKSIZE) 1282 if(bisect<begin+CHUNKSIZE)
1252 bisect=begin; 1283 bisect=begin;
1253 } 1284 }