diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-10 07:32:02 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-10 07:32:02 +0000 |
commit | bf16b0c3d73d729e6375eb6f161df0d3057126b9 (patch) | |
tree | c7f143a497427fe4cac557c62390591a68407e07 | |
parent | b61cdbdc4aa88280b6368afc5225236a056b270d (diff) | |
parent | e901b52af3a949e9ea3d356f4bc791611b53a3b6 (diff) | |
download | tremolo-android-8.1.0_r33.tar.gz |
release-request-7f84484c-eec6-4577-8d5a-55079be4f3c5-for-git_oc-mr1-release-4262309 snap-temp-L02100000091441105android-wear-8.1.0_r1android-vts-8.1_r9android-vts-8.1_r8android-vts-8.1_r7android-vts-8.1_r6android-vts-8.1_r5android-vts-8.1_r4android-vts-8.1_r3android-vts-8.1_r14android-vts-8.1_r13android-vts-8.1_r12android-vts-8.1_r11android-vts-8.1_r10android-cts-8.1_r9android-cts-8.1_r8android-cts-8.1_r7android-cts-8.1_r6android-cts-8.1_r5android-cts-8.1_r4android-cts-8.1_r3android-cts-8.1_r25android-cts-8.1_r24android-cts-8.1_r23android-cts-8.1_r22android-cts-8.1_r21android-cts-8.1_r20android-cts-8.1_r2android-cts-8.1_r19android-cts-8.1_r18android-cts-8.1_r17android-cts-8.1_r16android-cts-8.1_r15android-cts-8.1_r14android-cts-8.1_r13android-cts-8.1_r12android-cts-8.1_r11android-cts-8.1_r10android-cts-8.1_r1android-8.1.0_r9android-8.1.0_r8android-8.1.0_r7android-8.1.0_r6android-8.1.0_r5android-8.1.0_r48android-8.1.0_r47android-8.1.0_r46android-8.1.0_r45android-8.1.0_r43android-8.1.0_r42android-8.1.0_r41android-8.1.0_r40android-8.1.0_r4android-8.1.0_r39android-8.1.0_r38android-8.1.0_r37android-8.1.0_r36android-8.1.0_r35android-8.1.0_r33android-8.1.0_r32android-8.1.0_r31android-8.1.0_r30android-8.1.0_r3android-8.1.0_r29android-8.1.0_r28android-8.1.0_r27android-8.1.0_r26android-8.1.0_r25android-8.1.0_r23android-8.1.0_r22android-8.1.0_r21android-8.1.0_r20android-8.1.0_r2android-8.1.0_r19android-8.1.0_r18android-8.1.0_r17android-8.1.0_r16android-8.1.0_r15android-8.1.0_r14android-8.1.0_r13android-8.1.0_r12android-8.1.0_r11android-8.1.0_r10android-8.1.0_r1oreo-mr1-wear-releaseoreo-mr1-vts-releaseoreo-mr1-s1-releaseoreo-mr1-releaseoreo-mr1-cuttlefish-testingoreo-mr1-cts-releaseoreo-m6-s4-releaseoreo-m6-s3-releaseoreo-m6-s2-releaseoreo-m5-releaseoreo-m4-s9-releaseoreo-m4-s8-releaseoreo-m4-s7-releaseoreo-m4-s6-releaseoreo-m4-s5-releaseoreo-m4-s4-releaseoreo-m4-s3-releaseoreo-m4-s2-releaseoreo-m4-s12-releaseoreo-m4-s11-releaseoreo-m4-s10-releaseoreo-m4-s1-releaseoreo-m3-releaseoreo-m2-s5-releaseoreo-m2-s4-releaseoreo-m2-s3-releaseoreo-m2-s2-releaseoreo-m2-s1-releaseoreo-m2-release
Change-Id: Iefa190dd9d5070797039d4a291a27af401d3dc34
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | Tremolo/codebook.c | 456 | ||||
-rw-r--r-- | Tremolo/dpen.s | 2 | ||||
-rw-r--r-- | Tremolo/res012.c | 15 |
4 files changed, 246 insertions, 231 deletions
@@ -1,5 +1,9 @@ cc_library_shared { name: "libvorbisidec", + vendor_available: true, + vndk: { + enabled: true, + }, srcs: [ "Tremolo/bitwise.c", diff --git a/Tremolo/codebook.c b/Tremolo/codebook.c index 4d0dd91..467640d 100644 --- a/Tremolo/codebook.c +++ b/Tremolo/codebook.c @@ -59,7 +59,7 @@ int _ilog(unsigned int v){ } static ogg_uint32_t decpack(long entry,long used_entry,long quantvals, - codebook *b,oggpack_buffer *opb,int maptype){ + codebook *b,oggpack_buffer *opb,int maptype){ ogg_uint32_t ret=0; int j; @@ -72,13 +72,13 @@ static ogg_uint32_t decpack(long entry,long used_entry,long quantvals, if(maptype==1){ /* vals are already read into temporary column vector here */ for(j=0;j<b->dim;j++){ - ogg_uint32_t off=entry%quantvals; - entry/=quantvals; - ret|=((ogg_uint16_t *)(b->q_val))[off]<<(b->q_bits*j); + ogg_uint32_t off=entry%quantvals; + entry/=quantvals; + ret|=((ogg_uint16_t *)(b->q_val))[off]<<(b->q_bits*j); } }else{ for(j=0;j<b->dim;j++) - ret|=oggpack_read(opb,b->q_bits)<<(b->q_bits*j); + ret|=oggpack_read(opb,b->q_bits)<<(b->q_bits*j); } return ret; @@ -144,7 +144,7 @@ static int _determine_leaf_words(int nodeb, int leafwidth){ /* given a list of word lengths, number of used entries, and byte width of a leaf, generate the decode table */ static int _make_words(char *l,long n,ogg_uint32_t *r,long quantvals, - codebook *b, oggpack_buffer *opb,int maptype){ + codebook *b, oggpack_buffer *opb,int maptype){ long i,j,count=0; long top=0; ogg_uint32_t marker[MARKER_SIZE]; @@ -164,54 +164,54 @@ static int _make_words(char *l,long n,ogg_uint32_t *r,long quantvals, ALOGE("b/23881715"); return 1; } - ogg_uint32_t entry=marker[length]; - long chase=0; - if(count && !entry)return -1; /* overpopulated tree! */ - - /* chase the tree as far as it's already populated, fill in past */ - for(j=0;j<length-1;j++){ - int bit=(entry>>(length-j-1))&1; - if(chase>=top){ - if (chase < 0 || chase >= n) return 1; - top++; - r[chase*2]=top; - r[chase*2+1]=0; - }else - if (chase < 0 || chase >= n || chase*2+bit > n*2+1) return 1; - if(!r[chase*2+bit]) - r[chase*2+bit]=top; - chase=r[chase*2+bit]; - if (chase < 0 || chase >= n) return 1; - } - { - int bit=(entry>>(length-j-1))&1; - if(chase>=top){ - top++; - r[chase*2+1]=0; - } - r[chase*2+bit]= decpack(i,count++,quantvals,b,opb,maptype) | - 0x80000000; - } - - /* Look to see if the next shorter marker points to the node - above. if so, update it and repeat. */ - for(j=length;j>0;j--){ - if(marker[j]&1){ - marker[j]=marker[j-1]<<1; - break; - } - marker[j]++; - } - - /* prune the tree; the implicit invariant says all the longer - markers were dangling from our just-taken node. Dangle them - from our *new* node. */ - for(j=length+1;j<MARKER_SIZE;j++) - if((marker[j]>>1) == entry){ - entry=marker[j]; - marker[j]=marker[j-1]<<1; - }else - break; + ogg_uint32_t entry=marker[length]; + long chase=0; + if(count && !entry)return -1; /* overpopulated tree! */ + + /* chase the tree as far as it's already populated, fill in past */ + for(j=0;j<length-1;j++){ + int bit=(entry>>(length-j-1))&1; + if(chase>=top){ + if (chase < 0 || chase >= n) return 1; + top++; + r[chase*2]=top; + r[chase*2+1]=0; + }else + if (chase < 0 || chase >= n || chase*2+bit > n*2+1) return 1; + if(!r[chase*2+bit]) + r[chase*2+bit]=top; + chase=r[chase*2+bit]; + if (chase < 0 || chase >= n) return 1; + } + { + int bit=(entry>>(length-j-1))&1; + if(chase>=top){ + top++; + r[chase*2+1]=0; + } + r[chase*2+bit]= decpack(i,count++,quantvals,b,opb,maptype) | + 0x80000000; + } + + /* Look to see if the next shorter marker points to the node + above. if so, update it and repeat. */ + for(j=length;j>0;j--){ + if(marker[j]&1){ + marker[j]=marker[j-1]<<1; + break; + } + marker[j]++; + } + + /* prune the tree; the implicit invariant says all the longer + markers were dangling from our just-taken node. Dangle them + from our *new* node. */ + for(j=length+1;j<MARKER_SIZE;j++) + if((marker[j]>>1) == entry){ + entry=marker[j]; + marker[j]=marker[j-1]<<1; + }else + break; } } } @@ -234,7 +234,7 @@ static int _make_words(char *l,long n,ogg_uint32_t *r,long quantvals, } static int _make_decode_table(codebook *s,char *lengthlist,long quantvals, - oggpack_buffer *opb,int maptype){ + oggpack_buffer *opb,int maptype){ int i; ogg_uint32_t *work; @@ -251,7 +251,7 @@ static int _make_decode_table(codebook *s,char *lengthlist,long quantvals, /* +1 (rather than -2) is to accommodate 0 and 1 sized books, which are specialcased to nodeb==4 */ if(_make_words(lengthlist,s->entries, - s->dec_table,quantvals,s,opb,maptype))return 1; + s->dec_table,quantvals,s,opb,maptype))return 1; return 0; } @@ -265,20 +265,20 @@ static int _make_decode_table(codebook *s,char *lengthlist,long quantvals, if (s->used_entries > INT_MAX/(s->dec_leafw+1)) goto error_out; if (s->dec_nodeb && s->used_entries * (s->dec_leafw+1) > INT_MAX/s->dec_nodeb) goto error_out; s->dec_table=_ogg_malloc((s->used_entries*(s->dec_leafw+1)-2)* - s->dec_nodeb); + s->dec_nodeb); if (!s->dec_table) goto error_out; if(s->dec_leafw==1){ switch(s->dec_nodeb){ case 1: for(i=0;i<s->used_entries*2-2;i++) - ((unsigned char *)s->dec_table)[i]=(unsigned char) - (((work[i] & 0x80000000UL) >> 24) | work[i]); + ((unsigned char *)s->dec_table)[i]=(unsigned char) + (((work[i] & 0x80000000UL) >> 24) | work[i]); break; case 2: for(i=0;i<s->used_entries*2-2;i++) - ((ogg_uint16_t *)s->dec_table)[i]=(ogg_uint16_t) - (((work[i] & 0x80000000UL) >> 16) | work[i]); + ((ogg_uint16_t *)s->dec_table)[i]=(ogg_uint16_t) + (((work[i] & 0x80000000UL) >> 16) | work[i]); break; } @@ -290,62 +290,62 @@ static int _make_decode_table(codebook *s,char *lengthlist,long quantvals, unsigned char *out=(unsigned char *)s->dec_table; for(i=s->used_entries*2-4;i>=0;i-=2){ - if(work[i]&0x80000000UL){ - if(work[i+1]&0x80000000UL){ - top-=4; - out[top]=(work[i]>>8 & 0x7f)|0x80; - out[top+1]=(work[i+1]>>8 & 0x7f)|0x80; - out[top+2]=work[i] & 0xff; - out[top+3]=work[i+1] & 0xff; - }else{ - top-=3; - out[top]=(work[i]>>8 & 0x7f)|0x80; - out[top+1]=work[work[i+1]*2]; - out[top+2]=work[i] & 0xff; - } - }else{ - if(work[i+1]&0x80000000UL){ - top-=3; - out[top]=work[work[i]*2]; - out[top+1]=(work[i+1]>>8 & 0x7f)|0x80; - out[top+2]=work[i+1] & 0xff; - }else{ - top-=2; - out[top]=work[work[i]*2]; - out[top+1]=work[work[i+1]*2]; - } - } - work[i]=top; + if(work[i]&0x80000000UL){ + if(work[i+1]&0x80000000UL){ + top-=4; + out[top]=(work[i]>>8 & 0x7f)|0x80; + out[top+1]=(work[i+1]>>8 & 0x7f)|0x80; + out[top+2]=work[i] & 0xff; + out[top+3]=work[i+1] & 0xff; + }else{ + top-=3; + out[top]=(work[i]>>8 & 0x7f)|0x80; + out[top+1]=work[work[i+1]*2]; + out[top+2]=work[i] & 0xff; + } + }else{ + if(work[i+1]&0x80000000UL){ + top-=3; + out[top]=work[work[i]*2]; + out[top+1]=(work[i+1]>>8 & 0x7f)|0x80; + out[top+2]=work[i+1] & 0xff; + }else{ + top-=2; + out[top]=work[work[i]*2]; + out[top+1]=work[work[i+1]*2]; + } + } + work[i]=top; } }else{ ogg_uint16_t *out=(ogg_uint16_t *)s->dec_table; for(i=s->used_entries*2-4;i>=0;i-=2){ - if(work[i]&0x80000000UL){ - if(work[i+1]&0x80000000UL){ - top-=4; - out[top]=(work[i]>>16 & 0x7fff)|0x8000; - out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000; - out[top+2]=work[i] & 0xffff; - out[top+3]=work[i+1] & 0xffff; - }else{ - top-=3; - out[top]=(work[i]>>16 & 0x7fff)|0x8000; - out[top+1]=work[work[i+1]*2]; - out[top+2]=work[i] & 0xffff; - } - }else{ - if(work[i+1]&0x80000000UL){ - top-=3; - out[top]=work[work[i]*2]; - out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000; - out[top+2]=work[i+1] & 0xffff; - }else{ - top-=2; - out[top]=work[work[i]*2]; - out[top+1]=work[work[i+1]*2]; - } - } - work[i]=top; + if(work[i]&0x80000000UL){ + if(work[i+1]&0x80000000UL){ + top-=4; + out[top]=(work[i]>>16 & 0x7fff)|0x8000; + out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000; + out[top+2]=work[i] & 0xffff; + out[top+3]=work[i+1] & 0xffff; + }else{ + top-=3; + out[top]=(work[i]>>16 & 0x7fff)|0x8000; + out[top+1]=work[work[i+1]*2]; + out[top+2]=work[i] & 0xffff; + } + }else{ + if(work[i+1]&0x80000000UL){ + top-=3; + out[top]=work[work[i]*2]; + out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000; + out[top+2]=work[i+1] & 0xffff; + }else{ + top-=2; + out[top]=work[work[i]*2]; + out[top+1]=work[work[i+1]*2]; + } + } + work[i]=top; } } } @@ -436,23 +436,23 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){ /* yes, unused entries */ for(i=0;i<s->entries;i++){ - if(oggpack_read(opb,1)){ - long num=oggpack_read(opb,5); - if(num==-1)goto _eofout; - lengthlist[i]=(char)(num+1); - s->used_entries++; - if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; - }else - lengthlist[i]=0; + if(oggpack_read(opb,1)){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + lengthlist[i]=(char)(num+1); + s->used_entries++; + if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; + }else + lengthlist[i]=0; } }else{ /* all entries used; no tagging */ s->used_entries=s->entries; for(i=0;i<s->entries;i++){ - long num=oggpack_read(opb,5); - if(num==-1)goto _eofout; - lengthlist[i]=(char)(num+1); - if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + lengthlist[i]=(char)(num+1); + if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; } } @@ -467,12 +467,12 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){ if (!lengthlist) goto _eofout; for(i=0;i<s->entries;){ - long num=oggpack_read(opb,_ilog(s->entries-i)); - if(num<0)goto _eofout; - for(j=0;j<num && i<s->entries;j++,i++) - lengthlist[i]=(char)length; - s->dec_maxlength=length; - length++; + long num=oggpack_read(opb,_ilog(s->entries-i)); + if(num<0)goto _eofout; + for(j=0;j<num && i<s->entries;j++,i++) + lengthlist[i]=(char)length; + s->dec_maxlength=length; + length++; } } break; @@ -524,55 +524,55 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){ if(total1<=4 && total1<=total2){ - /* use dec_type 1: vector of packed values */ - - /* need quantized values before */ - s->q_val=calloc(sizeof(ogg_uint16_t), quantvals); - if (!s->q_val) goto _eofout; - for(i=0;i<quantvals;i++) - ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); - - if(oggpack_eop(opb)){ - goto _eofout; - } - - s->dec_type=1; - s->dec_nodeb=_determine_node_bytes(s->used_entries, - (s->q_bits*s->dim+8)/8); - s->dec_leafw=_determine_leaf_words(s->dec_nodeb, - (s->q_bits*s->dim+8)/8); - if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)){ - goto _errout; - } - - free(s->q_val); - s->q_val=0; + /* use dec_type 1: vector of packed values */ + + /* need quantized values before */ + s->q_val=calloc(sizeof(ogg_uint16_t), quantvals); + if (!s->q_val) goto _eofout; + for(i=0;i<quantvals;i++) + ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); + + if(oggpack_eop(opb)){ + goto _eofout; + } + + s->dec_type=1; + s->dec_nodeb=_determine_node_bytes(s->used_entries, + (s->q_bits*s->dim+8)/8); + s->dec_leafw=_determine_leaf_words(s->dec_nodeb, + (s->q_bits*s->dim+8)/8); + if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)){ + goto _errout; + } + + free(s->q_val); + s->q_val=0; }else{ - /* use dec_type 2: packed vector of column offsets */ - - /* need quantized values before */ - if(s->q_bits<=8){ - s->q_val=_ogg_malloc(quantvals); - if (!s->q_val) goto _eofout; - for(i=0;i<quantvals;i++) - ((unsigned char *)s->q_val)[i]=(unsigned char)oggpack_read(opb,s->q_bits); - }else{ - s->q_val=_ogg_malloc(quantvals*2); - if (!s->q_val) goto _eofout; - for(i=0;i<quantvals;i++) - ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); - } - - if(oggpack_eop(opb))goto _eofout; - - s->q_pack=_ilog(quantvals-1); - s->dec_type=2; - s->dec_nodeb=_determine_node_bytes(s->used_entries, - (_ilog(quantvals-1)*s->dim+8)/8); - s->dec_leafw=_determine_leaf_words(s->dec_nodeb, - (_ilog(quantvals-1)*s->dim+8)/8); - if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout; + /* use dec_type 2: packed vector of column offsets */ + + /* need quantized values before */ + if(s->q_bits<=8){ + s->q_val=_ogg_malloc(quantvals); + if (!s->q_val) goto _eofout; + for(i=0;i<quantvals;i++) + ((unsigned char *)s->q_val)[i]=(unsigned char)oggpack_read(opb,s->q_bits); + }else{ + s->q_val=_ogg_malloc(quantvals*2); + if (!s->q_val) goto _eofout; + for(i=0;i<quantvals;i++) + ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); + } + + if(oggpack_eop(opb))goto _eofout; + + s->q_pack=_ilog(quantvals-1); + s->dec_type=2; + s->dec_nodeb=_determine_node_bytes(s->used_entries, + (_ilog(quantvals-1)*s->dim+8)/8); + s->dec_leafw=_determine_leaf_words(s->dec_nodeb, + (_ilog(quantvals-1)*s->dim+8)/8); + if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout; } } @@ -604,11 +604,11 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){ s->q_val=_ogg_malloc(s->q_pack*s->used_entries); if(s->q_bits<=8){ - for(i=0;i<s->used_entries*s->dim;i++) - ((unsigned char *)(s->q_val))[i]=(unsigned char)oggpack_read(opb,s->q_bits); + for(i=0;i<s->used_entries*s->dim;i++) + ((unsigned char *)(s->q_val))[i]=(unsigned char)oggpack_read(opb,s->q_bits); }else{ - for(i=0;i<s->used_entries*s->dim;i++) - ((ogg_uint16_t *)(s->q_val))[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); + for(i=0;i<s->used_entries*s->dim;i++) + ((ogg_uint16_t *)(s->q_val))[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); } } break; @@ -646,7 +646,7 @@ ogg_uint32_t decode_packed_entry_number(codebook *book, oggpack_buffer *b); #else static inline ogg_uint32_t decode_packed_entry_number(codebook *book, - oggpack_buffer *b){ + oggpack_buffer *b){ ogg_uint32_t chase=0; int read=book->dec_maxlength; long lok = oggpack_look(b,read),i; @@ -669,8 +669,8 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book, unsigned char *t=(unsigned char *)book->dec_table; for(i=0;i<read;i++){ - chase=t[chase*2+((lok>>i)&1)]; - if(chase&0x80UL)break; + chase=t[chase*2+((lok>>i)&1)]; + if(chase&0x80UL)break; } chase&=0x7fUL; break; @@ -681,13 +681,13 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book, /* 8/16 - Used by infile2 */ unsigned char *t=(unsigned char *)book->dec_table; for(i=0;i<read;i++){ - int bit=(lok>>i)&1; - int next=t[chase+bit]; - if(next&0x80){ - chase= (next<<8) | t[chase+bit+1+(!bit || t[chase]&0x80)]; - break; - } - chase=next; + int bit=(lok>>i)&1; + int next=t[chase+bit]; + if(next&0x80){ + chase= (next<<8) | t[chase+bit+1+(!bit || t[chase]&0x80)]; + break; + } + chase=next; } //chase&=0x7fffUL; chase&=~0x8000UL; @@ -698,8 +698,8 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book, /* book->dec_nodeb==2, book->dec_leafw==1 */ /* 16/16 - Used */ for(i=0;i<read;i++){ - chase=((ogg_uint16_t *)(book->dec_table))[chase*2+((lok>>i)&1)]; - if(chase&0x8000UL)break; + chase=((ogg_uint16_t *)(book->dec_table))[chase*2+((lok>>i)&1)]; + if(chase&0x8000UL)break; } //chase&=0x7fffUL; chase&=~0x8000UL; @@ -711,13 +711,13 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book, /* 16/32 - Used by infile2 */ ogg_uint16_t *t=(ogg_uint16_t *)book->dec_table; for(i=0;i<read;i++){ - int bit=(lok>>i)&1; - int next=t[chase+bit]; - if(next&0x8000){ - chase= (next<<16) | t[chase+bit+1+(!bit || t[chase]&0x8000)]; - break; - } - chase=next; + int bit=(lok>>i)&1; + int next=t[chase+bit]; + if(next&0x8000){ + chase= (next<<16) | t[chase+bit+1+(!bit || t[chase]&0x8000)]; + break; + } + chase=next; } //chase&=0x7fffffffUL; chase&=~0x80000000UL; @@ -727,8 +727,8 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book, { //Output("32/32"); for(i=0;i<read;i++){ - chase=((ogg_uint32_t *)(book->dec_table))[chase*2+((lok>>i)&1)]; - if(chase&0x80000000UL)break; + chase=((ogg_uint32_t *)(book->dec_table))[chase*2+((lok>>i)&1)]; + if(chase&0x80000000UL)break; } //chase&=0x7fffffffUL; chase&=~0x80000000UL; @@ -777,9 +777,9 @@ static int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point) int mask=(1<<s->q_pack)-1; for(i=0;i<s->dim;i++){ if(s->q_bits<=8) - v[i]=((unsigned char *)(s->q_val))[entry&mask]; + v[i]=((unsigned char *)(s->q_val))[entry&mask]; else - v[i]=((ogg_uint16_t *)(s->q_val))[entry&mask]; + v[i]=((ogg_uint16_t *)(s->q_val))[entry&mask]; entry>>=s->q_pack; } break; @@ -790,10 +790,10 @@ static int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point) if(s->q_bits<=8){ for(i=0;i<s->dim;i++) - v[i]=((unsigned char *)ptr)[i]; + v[i]=((unsigned char *)ptr)[i]; }else{ for(i=0;i<s->dim;i++) - v[i]=((ogg_uint16_t *)ptr)[i]; + v[i]=((ogg_uint16_t *)ptr)[i]; } break; } @@ -823,7 +823,7 @@ static int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point) if(s->q_seq) for(i=1;i<s->dim;i++) - v[i]+=v[i-1]; + v[i]+=v[i-1]; } return 0; @@ -832,7 +832,7 @@ static int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point) /* returns 0 on OK or -1 on eof *************************************/ long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, - oggpack_buffer *b,int n,int point){ + oggpack_buffer *b,int n,int point){ if(book->used_entries>0){ int step=n/book->dim; ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); @@ -842,14 +842,14 @@ long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, for (j=0;j<step;j++){ if(decode_map(book,b,v,point))return -1; for(i=0,o=j;i<book->dim;i++,o+=step) - a[o]+=v[i]; + a[o]+=v[i]; } } return 0; } long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, - oggpack_buffer *b,int n,int point){ + oggpack_buffer *b,int n,int point){ if(book->used_entries>0){ ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); int i,j; @@ -857,15 +857,15 @@ long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, if (!v) return -1; for(i=0;i<n;){ if(decode_map(book,b,v,point))return -1; - for (j=0;j<book->dim;j++) - a[i++]+=v[j]; + for (j=0;j<book->dim && i < n;j++) + a[i++]+=v[j]; } } return 0; } long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, - oggpack_buffer *b,int n,int point){ + oggpack_buffer *b,int n,int point){ if(book->used_entries>0){ ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); int i,j; @@ -873,15 +873,15 @@ long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, if (!v) return -1; for(i=0;i<n;){ if(decode_map(book,b,v,point))return -1; - for (j=0;j<book->dim;j++) - a[i++]=v[j]; + for (j=0;j<book->dim && i < n;j++) + a[i++]=v[j]; } }else{ int i,j; for(i=0;i<n;){ - for (j=0;j<book->dim;j++) - a[i++]=0; + for (j=0;j<book->dim && i < n;j++) + a[i++]=0; } } @@ -890,12 +890,12 @@ long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, #ifndef ONLY_C long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, - long offset,int ch, - oggpack_buffer *b,int n,int point); + long offset,int ch, + oggpack_buffer *b,int n,int point); #else long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, - long offset,int ch, - oggpack_buffer *b,int n,int point){ + long offset,int ch, + oggpack_buffer *b,int n,int point){ if(book->used_entries>0){ ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); @@ -905,12 +905,12 @@ long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, if (!v) return -1; for(i=offset;i<offset+n;){ if(decode_map(book,b,v,point))return -1; - for (j=0;j<book->dim;j++){ - a[chptr++][i]+=v[j]; - if(chptr==ch){ - chptr=0; - i++; - } + for (j=0;j<book->dim && i < offset + n;j++){ + a[chptr++][i]+=v[j]; + if(chptr==ch){ + chptr=0; + i++; + } } } } diff --git a/Tremolo/dpen.s b/Tremolo/dpen.s index 7e4f1ed..344e41b 100644 --- a/Tremolo/dpen.s +++ b/Tremolo/dpen.s @@ -430,6 +430,8 @@ vbdvva_loop1: LDR r0, [r9, # 5*4] @ r0 = book->dim LDR r1, [r9, #14*4] @ r1 = v = dec_buf vbdvva_loop2: + CMP r5,#0 + BLE vbdvva_exit LDR r2, [r10],#4 @ r2 = a[chptr++] LDR r12,[r1], #4 @ r1 = v[j++] CMP r10,r8 @ if (chptr == ch) diff --git a/Tremolo/res012.c b/Tremolo/res012.c index d6495fb..ac09671 100644 --- a/Tremolo/res012.c +++ b/Tremolo/res012.c @@ -65,9 +65,9 @@ int res_unpack(vorbis_info_residue *info, if(info->type>2 || info->type<0)goto errout; info->begin=oggpack_read(opb,24); info->end=oggpack_read(opb,24); - info->grouping=oggpack_read(opb,24)+1; - info->partitions=(char)(oggpack_read(opb,6)+1); - info->groupbook=(unsigned char)oggpack_read(opb,8); + info->grouping=oggpack_read(opb,24)+1; // "partition size" in spec + info->partitions=(char)(oggpack_read(opb,6)+1); // "classification" in spec + info->groupbook=(unsigned char)oggpack_read(opb,8); // "classbook" in spec if(info->groupbook>=ci->books)goto errout; info->stagemasks=_ogg_malloc(info->partitions*sizeof(*info->stagemasks)); @@ -94,6 +94,15 @@ int res_unpack(vorbis_info_residue *info, if(oggpack_eop(opb))goto errout; + // According to the Vorbis spec (paragraph 8.6.2 "packet decode"), residue + // begin and end should be limited to the maximum possible vector size in + // case they exceed it. However doing that makes the decoder crash further + // down, so we return an error instead. + int limit = (info->type == 2 ? vi->channels : 1) * ci->blocksizes[1] / 2; + if (info->begin > info->end || + info->end > limit) { + goto errout; + } return 0; errout: res_clear_info(info); |