summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin@xiph.org>2010-05-15 16:17:50 +0000
committerRobin Watts <robin@xiph.org>2010-05-15 16:17:50 +0000
commit7726777045d50734e851570b448294226ec0580d (patch)
tree58741bb7cac4029342fb73161184d880508f7e6f
parent83fddbc0041ca1122f50147b3aa7a8442aa293b2 (diff)
downloadtremor-7726777045d50734e851570b448294226ec0580d.tar.gz
First commit of stuff from Tremolo. C-only changes to start with.
Mostly squashing of warnings with some explicit casts, and removing some variables that are never used. Optimisations to render_line. Various checks for (m)alloc failures and out of range inputs. Change to use explicit dec_buf rather than repeated calls to alloca. Change to use dec_method/switch rather than nested if. Reorder of contents of codebook struct in preparation for ARM code. git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremolo@17217 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--codebook.c180
-rw-r--r--codebook.h38
-rw-r--r--dsp.c6
-rw-r--r--floor0.c4
-rw-r--r--floor1.c89
-rw-r--r--mapping0.c12
-rw-r--r--misc.c8
-rw-r--r--res012.c7
-rw-r--r--vorbisfile.c14
9 files changed, 223 insertions, 135 deletions
diff --git a/codebook.c b/codebook.c
index 9157228..300b365 100644
--- a/codebook.c
+++ b/codebook.c
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <limits.h>
#include "ogg.h"
#include "ivorbiscodec.h"
#include "codebook.h"
@@ -126,6 +127,9 @@ static int _make_words(char *l,long n,ogg_uint32_t *r,long quantvals,
long top=0;
ogg_uint32_t marker[33];
+ if (n<1)
+ return 1;
+
if(n<2){
r[0]=0x80000000;
}else{
@@ -142,13 +146,16 @@ static int _make_words(char *l,long n,ogg_uint32_t *r,long quantvals,
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;
@@ -191,8 +198,16 @@ static int _make_decode_table(codebook *s,char *lengthlist,long quantvals,
int i;
ogg_uint32_t *work;
+ if (!lengthlist) return 1;
if(s->dec_nodeb==4){
- s->dec_table=_ogg_malloc((s->used_entries*2+1)*sizeof(*work));
+ /* Over-allocate by using s->entries instead of used_entries.
+ * This means that we can use s->entries to enforce size in
+ * _make_words without messing up length list looping.
+ * This probably wastes a bit of space, but it shouldn't
+ * impact behavior or size too much.
+ */
+ s->dec_table=_ogg_malloc((s->entries*2+1)*sizeof(*work));
+ if (!s->dec_table) return 1;
/* +1 (rather than -2) is to accommodate 0 and 1 sized books,
which are specialcased to nodeb==4 */
if(_make_words(lengthlist,s->entries,
@@ -201,22 +216,28 @@ static int _make_decode_table(codebook *s,char *lengthlist,long quantvals,
return 0;
}
- work=alloca((s->used_entries*2-2)*sizeof(*work));
+ if (s->used_entries > INT_MAX/2 ||
+ s->used_entries*2 > INT_MAX/((long) sizeof(*work)) - 1) return 1;
+ /* Overallocate as above */
+ work=alloca((s->entries*2+1)*sizeof(*work));
if(_make_words(lengthlist,s->entries,work,quantvals,s,opb,maptype))return 1;
+ if (s->used_entries > INT_MAX/(s->dec_leafw+1)) return 1;
+ if (s->dec_nodeb && s->used_entries * (s->dec_leafw+1) > INT_MAX/s->dec_nodeb) return 1;
s->dec_table=_ogg_malloc((s->used_entries*(s->dec_leafw+1)-2)*
s->dec_nodeb);
+ if (!s->dec_table) return 1;
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]=
- ((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]=
- ((work[i] & 0x80000000UL) >> 16) | work[i];
+ ((ogg_uint16_t *)s->dec_table)[i]=(ogg_uint16_t)
+ (((work[i] & 0x80000000UL) >> 16) | work[i]);
break;
}
@@ -331,6 +352,7 @@ void vorbis_book_clear(codebook *b){
the static codebook belongs to the info struct */
if(b->q_val)_ogg_free(b->q_val);
if(b->dec_table)_ogg_free(b->dec_table);
+ if(b->dec_buf)_ogg_free(b->dec_buf);
memset(b,0,sizeof(*b));
}
@@ -348,14 +370,21 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
/* first the basic parameters */
s->dim=oggpack_read(opb,16);
+ s->dec_buf=_ogg_malloc(sizeof(ogg_int32_t)*s->dim);
+ if (s->dec_buf == NULL)
+ goto _errout;
s->entries=oggpack_read(opb,24);
- if(s->entries==-1)goto _eofout;
+ if(s->entries<=0)goto _eofout;
+ if(s->dim<=0)goto _eofout;
+ if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
+ if (s->dim > INT_MAX/s->entries) goto _eofout;
/* codeword ordering.... length ordered or unordered? */
switch((int)oggpack_read(opb,1)){
case 0:
/* unordered */
lengthlist=(char *)alloca(sizeof(*lengthlist)*s->entries);
+ if(!lengthlist) goto _eofout;
/* allocated but unused entries? */
if(oggpack_read(opb,1)){
@@ -365,7 +394,7 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
if(oggpack_read(opb,1)){
long num=oggpack_read(opb,5);
if(num==-1)goto _eofout;
- lengthlist[i]=num+1;
+ lengthlist[i]=(char)(num+1);
s->used_entries++;
if(num+1>s->dec_maxlength)s->dec_maxlength=num+1;
}else
@@ -377,7 +406,7 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
for(i=0;i<s->entries;i++){
long num=oggpack_read(opb,5);
if(num==-1)goto _eofout;
- lengthlist[i]=num+1;
+ lengthlist[i]=(char)(num+1);
if(num+1>s->dec_maxlength)s->dec_maxlength=num+1;
}
}
@@ -390,12 +419,13 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
s->used_entries=s->entries;
lengthlist=(char *)alloca(sizeof(*lengthlist)*s->entries);
+ if (!lengthlist) goto _eofout;
for(i=0;i<s->entries;){
long num=oggpack_read(opb,_ilog(s->entries-i));
- if(num==-1)goto _eofout;
+ if(num<0)goto _eofout;
for(j=0;j<num && i<s->entries;j++,i++)
- lengthlist[i]=length;
+ lengthlist[i]=(char)length;
s->dec_maxlength=length;
length++;
}
@@ -443,6 +473,7 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
{
/* packed values */
long total1=(s->q_bits*s->dim+8)/8; /* remember flag bit */
+ if (s->dim > (INT_MAX-8)/s->q_bits) goto _eofout;
/* vector of column offsets; remember flag bit */
long total2=(_ilog(quantvals-1)*s->dim+8)/8+(s->q_bits+7)/8;
@@ -452,8 +483,9 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
/* need quantized values before */
s->q_val=alloca(sizeof(ogg_uint16_t)*quantvals);
+ if (!s->q_val) goto _eofout;
for(i=0;i<quantvals;i++)
- ((ogg_uint16_t *)s->q_val)[i]=oggpack_read(opb,s->q_bits);
+ ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits);
if(oggpack_eop(opb)){
s->q_val=0; /* cleanup must not free alloca memory */
@@ -479,12 +511,14 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
/* 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]=oggpack_read(opb,s->q_bits);
+ ((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]=oggpack_read(opb,s->q_bits);
+ ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits);
}
if(oggpack_eop(opb))goto _eofout;
@@ -528,10 +562,10 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
if(s->q_bits<=8){
for(i=0;i<s->used_entries*s->dim;i++)
- ((unsigned char *)(s->q_val))[i]=oggpack_read(opb,s->q_bits);
+ ((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]=oggpack_read(opb,s->q_bits);
+ ((ogg_uint16_t *)(s->q_val))[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits);
}
}
break;
@@ -539,6 +573,19 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
goto _errout;
}
+ if (s->dec_nodeb==1)
+ if (s->dec_leafw == 1)
+ s->dec_method = 0;
+ else
+ s->dec_method = 1;
+ else if (s->dec_nodeb==2)
+ if (s->dec_leafw == 1)
+ s->dec_method = 2;
+ else
+ s->dec_method = 3;
+ else
+ s->dec_method = 4;
+
if(oggpack_eop(opb))goto _eofout;
return 0;
@@ -563,19 +610,24 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book,
}
/* chase the tree with the bits we got */
- if(book->dec_nodeb==1){
- if(book->dec_leafw==1){
-
+ switch (book->dec_method)
+ {
+ case 0:
+ {
+ /* book->dec_nodeb==1, book->dec_leafw==1 */
/* 8/8 */
+
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&=0x7fUL;
-
- }else{
-
+ break;
+ }
+ case 1:
+ {
+ /* book->dec_nodeb==1, book->dec_leafw!=1 */
/* 8/16 */
unsigned char *t=(unsigned char *)book->dec_table;
for(i=0;i<read;i++){
@@ -587,44 +639,45 @@ static inline ogg_uint32_t decode_packed_entry_number(codebook *book,
}
chase=next;
}
- chase&=0x7fffUL;
+ chase&=~0x8000UL;
+ break;
}
-
- }else{
- if(book->dec_nodeb==2){
- if(book->dec_leafw==1){
-
- /* 16/16 */
- for(i=0;i<read;i++){
- chase=((ogg_uint16_t *)(book->dec_table))[chase*2+((lok>>i)&1)];
- if(chase&0x8000UL)break;
- }
- chase&=0x7fffUL;
-
- }else{
-
- /* 16/32 */
- 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;
+ case 2:
+ {
+ /* book->dec_nodeb==2, book->dec_leafw==1 */
+ /* 16/16 */
+ for(i=0;i<read;i++){
+ chase=((ogg_uint16_t *)(book->dec_table))[chase*2+((lok>>i)&1)];
+ if(chase&0x8000UL)break;
+ }
+ chase&=~0x8000UL;
+ break;
+ }
+ case 3:
+ {
+ /* book->dec_nodeb==2, book->dec_leafw!=1 */
+ /* 16/32 */
+ 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&=0x7fffffffUL;
+ chase=next;
}
-
- }else{
-
+ chase&=~0x80000000UL;
+ break;
+ }
+ case 4:
+ {
for(i=0;i<read;i++){
chase=((ogg_uint32_t *)(book->dec_table))[chase*2+((lok>>i)&1)];
if(chase&0x80000000UL)break;
}
- chase&=0x7fffffffUL;
-
+ chase&=~0x80000000UL;
+ break;
}
}
@@ -691,6 +744,7 @@ int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point){
{
int shiftM=point-s->q_delp;
ogg_int32_t add=point-s->q_minp;
+ int mul = s->q_del;
if(add>0)
add= s->q_min >> add;
else
@@ -698,10 +752,12 @@ int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point){
if(shiftM>0)
for(i=0;i<s->dim;i++)
- v[i]= add + ((v[i] * s->q_del) >> shiftM);
- else
+ v[i]= add + ((v[i] * mul) >> shiftM);
+ else {
+ mul <<= -shiftM;
for(i=0;i<s->dim;i++)
- v[i]= add + ((v[i] * s->q_del) << -shiftM);
+ v[i]= add + (v[i] * mul);
+ }
if(s->q_seq)
for(i=1;i<s->dim;i++)
@@ -716,8 +772,9 @@ long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
oggpack_buffer *b,int n,int point){
if(book->used_entries>0){
int step=n/book->dim;
- ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim);
+ ogg_int32_t *v = book->dec_buf;
int i,j,o;
+ if (!v) return -1;
for (j=0;j<step;j++){
if(decode_map(book,b,v,point))return -1;
@@ -731,9 +788,10 @@ long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
oggpack_buffer *b,int n,int point){
if(book->used_entries>0){
- ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim);
+ ogg_int32_t *v = book->dec_buf;
int i,j;
+ 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++)
@@ -746,9 +804,10 @@ long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
oggpack_buffer *b,int n,int point){
if(book->used_entries>0){
- ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim);
+ ogg_int32_t *v = book->dec_buf;
int i,j;
+ 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++)
@@ -771,10 +830,11 @@ long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
oggpack_buffer *b,int n,int point){
if(book->used_entries>0){
- ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim);
+ ogg_int32_t *v = book->dec_buf;
long i,j;
int chptr=0;
+ 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++){
diff --git a/codebook.h b/codebook.h
index 7519597..dc79997 100644
--- a/codebook.h
+++ b/codebook.h
@@ -21,27 +21,31 @@
#include "ogg.h"
typedef struct codebook{
- long dim; /* codebook dimensions (elements per vector) */
- long entries; /* codebook entries */
- long used_entries; /* populated codebook entries */
-
- int dec_maxlength;
- void *dec_table;
- int dec_nodeb;
- int dec_leafw;
- int dec_type; /* 0 = entry number
+ /* Top 15 used in ARM code */
+ int dec_maxlength;
+ void *dec_table;
+ int dec_method;
+ int dec_type; /* 0 = entry number
1 = packed vector of values
2 = packed vector of column offsets, maptype 1
3 = scalar offset into value array, maptype 2 */
+ int q_bits;
+ long dim; /* codebook dimensions (elements per vector) */
+ int q_delp;
+ int q_minp;
+ ogg_int32_t q_del;
+ ogg_int32_t q_min;
+ int q_seq;
+ int q_pack;
+ void *q_val;
+ long used_entries; /* populated codebook entries */
+ ogg_int32_t *dec_buf;
+
+ /* C only */
+ int dec_nodeb;
+ int dec_leafw;
- ogg_int32_t q_min;
- int q_minp;
- ogg_int32_t q_del;
- int q_delp;
- int q_seq;
- int q_bits;
- int q_pack;
- void *q_val;
+ long entries; /* codebook entries */
} codebook;
diff --git a/dsp.c b/dsp.c
index 882b685..eaa3649 100644
--- a/dsp.c
+++ b/dsp.c
@@ -263,10 +263,10 @@ int vorbis_dsp_synthesis(vorbis_dsp_state *vd,ogg_packet *op,int decodep){
/* granulepos could be -1 due to a seek, but that would result
in a long coun t, not short count */
- vd->out_end-=vd->sample_count-vd->granulepos;
+ vd->out_end-=(int)(vd->sample_count-vd->granulepos);
}else{
/* trim the beginning */
- vd->out_begin+=vd->sample_count-vd->granulepos;
+ vd->out_begin+=(int)(vd->sample_count-vd->granulepos);
if(vd->out_begin>vd->out_end)
vd->out_begin=vd->out_end;
}
@@ -280,7 +280,7 @@ int vorbis_dsp_synthesis(vorbis_dsp_state *vd,ogg_packet *op,int decodep){
if(op->granulepos!=-1 && vd->granulepos!=op->granulepos){
if(vd->granulepos>op->granulepos){
- long extra=vd->granulepos-op->granulepos;
+ long extra=(long)(vd->granulepos-op->granulepos);
if(extra)
if(op->e_o_s){
diff --git a/floor0.c b/floor0.c
index 864af70..d2e2087 100644
--- a/floor0.c
+++ b/floor0.c
@@ -136,7 +136,7 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
int ampi=amp;
ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
- ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq);
+ /* ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq); */
ogg_uint32_t imap= (1UL<<31) / ln;
ogg_uint32_t tBnyq1 = toBARK(nyq)<<1;
@@ -360,7 +360,7 @@ vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
if(info->barkmap<1)goto err_out;
for(j=0;j<info->numbooks;j++){
- info->books[j]=oggpack_read(opb,8);
+ info->books[j]=(char)(oggpack_read(opb,8));
if(info->books[j]>=ci->books)goto err_out;
}
diff --git a/floor1.c b/floor1.c
index 44091f5..5752968 100644
--- a/floor1.c
+++ b/floor1.c
@@ -64,7 +64,7 @@ static void mergesort(char *index,ogg_uint16_t *vals,ogg_uint16_t n){
int k2=mid;
int end=(j+i*2<n?j+i*2:n);
while(k1<mid && k2<end){
- if(vals[A[k1]]<vals[A[k2]])
+ if(vals[(int)A[k1]]<vals[(int)A[k2]])
B[j++]=A[k1++];
else
B[j++]=A[k2++];
@@ -94,7 +94,7 @@ vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
info->partitionclass=
(char *)_ogg_malloc(info->partitions*sizeof(*info->partitionclass));
for(j=0;j<info->partitions;j++){
- info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
+ info->partitionclass[j]=(char)oggpack_read(opb,4); /* only 0 to 15 legal */
if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
}
@@ -102,16 +102,16 @@ vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
info->class=
(floor1class *)_ogg_malloc((maxclass+1)*sizeof(*info->class));
for(j=0;j<maxclass+1;j++){
- info->class[j].class_dim=oggpack_read(opb,3)+1; /* 1 to 8 */
- info->class[j].class_subs=oggpack_read(opb,2); /* 0,1,2,3 bits */
+ info->class[j].class_dim=(char)oggpack_read(opb,3)+1; /* 1 to 8 */
+ info->class[j].class_subs=(char)oggpack_read(opb,2); /* 0,1,2,3 bits */
if(oggpack_eop(opb)<0) goto err_out;
if(info->class[j].class_subs)
- info->class[j].class_book=oggpack_read(opb,8);
+ info->class[j].class_book=(unsigned char)oggpack_read(opb,8);
else
info->class[j].class_book=0;
if(info->class[j].class_book>=ci->books)goto err_out;
for(k=0;k<(1<<info->class[j].class_subs);k++){
- info->class[j].class_subbook[k]=oggpack_read(opb,8)-1;
+ info->class[j].class_subbook[k]=(unsigned char)oggpack_read(opb,8)-1;
if(info->class[j].class_subbook[k]>=ci->books &&
info->class[j].class_subbook[k]!=0xff)goto err_out;
}
@@ -122,7 +122,7 @@ vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
rangebits=oggpack_read(opb,4);
for(j=0,k=0;j<info->partitions;j++)
- count+=info->class[info->partitionclass[j]].class_dim;
+ count+=info->class[(int)info->partitionclass[j]].class_dim;
info->postlist=
(ogg_uint16_t *)_ogg_malloc((count+2)*sizeof(*info->postlist));
info->forward_index=
@@ -134,9 +134,9 @@ vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
count=0;
for(j=0,k=0;j<info->partitions;j++){
- count+=info->class[info->partitionclass[j]].class_dim;
+ count+=info->class[(int)info->partitionclass[j]].class_dim;
for(;k<count;k++){
- int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
+ int t=info->postlist[k+2]=(ogg_uint16_t)oggpack_read(opb,rangebits);
if(t>=(1<<rangebits))goto err_out;
}
}
@@ -196,31 +196,52 @@ static int render_point(int x0,int x1,int y0,int y1,int x){
}
static void render_line(int n,int x0,int x1,int y0,int y1,ogg_int32_t *d){
- int dy=y1-y0;
- int adx=x1-x0;
- int ady=abs(dy);
- int base=dy/adx;
- int sy=(dy<0?base-1:base+1);
- int x=x0;
- int y=y0;
- int err=0;
+ int dy;
+ int adx;
+ int ady;
+ int base;
+ int err;
+ const ogg_int32_t *floor;
if(n>x1)n=x1;
+ n -= x0;
+ if (n <= 0)
+ return;
+ dy=y1-y0;
+ adx=x1-x0;
+ ady=abs(dy);
+ base=dy/adx;
+ err=adx-1;
+ floor=&FLOOR_fromdB_LOOKUP[y0];
+ d += x0;
ady-=abs(base*adx);
- if(x<n)
- d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]);
+ /* We should add base each time, and then:
+ * if dy >=0 we occasionally add 1
+ * else occasionally subtract 1.
+ * As an optimisation we say that if dy <0 we make base 1 smaller.
+ * Then we need to add 1 occassionally, rather than subtract 1 - but we
+ * need to add 1 in all the cases when we wouldn't have done so before.
+ * Previously we'd have added 1 (100*ady/adx)% of the time. Now we want
+ * to do so (100*(adx-ady)/adx)% of the time.
+ */
+ if (dy < 0){
+ base--;
+ ady = adx-ady;
+ err = 0;
+ }
- while(++x<n){
- err=err+ady;
- if(err>=adx){
- err-=adx;
- y+=sy;
- }else{
- y+=base;
+ do{
+ *d = MULT31_SHIFT15(*d,*floor);
+ d++;
+ floor+=base;
+ err-=ady;
+ if(err<0){
+ err+=adx;
+ floor+=1;
}
- d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]);
- }
+ n--;
+ } while(n>0);
}
int floor1_memosize(vorbis_info_floor *i){
@@ -275,10 +296,10 @@ ogg_int32_t *floor1_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *in,
/* unwrap positive values and reconsitute via linear interpolation */
for(i=2;i<info->posts;i++){
- int predicted=render_point(info->postlist[info->loneighbor[i-2]],
- info->postlist[info->hineighbor[i-2]],
- fit_value[info->loneighbor[i-2]],
- fit_value[info->hineighbor[i-2]],
+ int predicted=render_point(info->postlist[(int)info->loneighbor[i-2]],
+ info->postlist[(int)info->hineighbor[i-2]],
+ fit_value[(int)info->loneighbor[i-2]],
+ fit_value[(int)info->hineighbor[i-2]],
info->postlist[i]);
int hiroom=quant_q-predicted;
int loroom=predicted;
@@ -301,8 +322,8 @@ ogg_int32_t *floor1_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *in,
}
fit_value[i]=val+predicted;
- fit_value[info->loneighbor[i-2]]&=0x7fff;
- fit_value[info->hineighbor[i-2]]&=0x7fff;
+ fit_value[(int)info->loneighbor[i-2]]&=0x7fff;
+ fit_value[(int)info->hineighbor[i-2]]&=0x7fff;
}else{
fit_value[i]=predicted|0x8000;
diff --git a/mapping0.c b/mapping0.c
index 23e3b8e..de9f7db 100644
--- a/mapping0.c
+++ b/mapping0.c
@@ -64,8 +64,8 @@ int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi,
_ogg_malloc(info->coupling_steps*sizeof(*info->coupling));
for(i=0;i<info->coupling_steps;i++){
- int testM=info->coupling[i].mag=oggpack_read(opb,ilog(vi->channels));
- int testA=info->coupling[i].ang=oggpack_read(opb,ilog(vi->channels));
+ int testM=info->coupling[i].mag=(unsigned char)oggpack_read(opb,ilog(vi->channels));
+ int testA=info->coupling[i].ang=(unsigned char)oggpack_read(opb,ilog(vi->channels));
if(testM<0 ||
testA<0 ||
@@ -80,18 +80,20 @@ int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi,
if(info->submaps>1){
info->chmuxlist=_ogg_malloc(sizeof(*info->chmuxlist)*vi->channels);
+ if (!info->chmuxlist) goto err_out;
for(i=0;i<vi->channels;i++){
- info->chmuxlist[i]=oggpack_read(opb,4);
+ info->chmuxlist[i]=(unsigned char)oggpack_read(opb,4);
if(info->chmuxlist[i]>=info->submaps)goto err_out;
}
}
info->submaplist=_ogg_malloc(sizeof(*info->submaplist)*info->submaps);
+ if(!info->submaplist) goto err_out;
for(i=0;i<info->submaps;i++){
int temp=oggpack_read(opb,8);
- info->submaplist[i].floor=oggpack_read(opb,8);
+ info->submaplist[i].floor=(char)oggpack_read(opb,8);
if(info->submaplist[i].floor>=ci->floors)goto err_out;
- info->submaplist[i].residue=oggpack_read(opb,8);
+ info->submaplist[i].residue=(char)oggpack_read(opb,8);
if(info->submaplist[i].residue>=ci->residues)goto err_out;
}
diff --git a/misc.c b/misc.c
index 66bf523..0a6cdbf 100644
--- a/misc.c
+++ b/misc.c
@@ -22,9 +22,11 @@ static void **pointers=NULL;
static long *insertlist=NULL; /* We can't embed this in the pointer list;
a pointer can have any value... */
+#ifdef _VDBG_GRAPHFILE
static char **files=NULL;
static long *file_bytes=NULL;
static int filecount=0;
+#endif
static int ptop=0;
static int palloced=0;
@@ -115,7 +117,7 @@ static void *_insert(void *ptr,long bytes,char *file,long line){
global_bytes+=(bytes-HEAD_ALIGN);
- return(ptr+HEAD_ALIGN);
+ return(void*)(((char *)ptr)+HEAD_ALIGN);
}
static void _ripremove(void *ptr){
@@ -188,7 +190,7 @@ void _VDBG_dump(void){
extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line){
bytes+=HEAD_ALIGN;
if(ptr){
- ptr-=HEAD_ALIGN;
+ ptr=(void *)(((char *)ptr)-HEAD_ALIGN);
_ripremove(ptr);
ptr=realloc(ptr,bytes);
}else{
@@ -200,7 +202,7 @@ extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line){
extern void _VDBG_free(void *ptr,char *file,long line){
if(ptr){
- ptr-=HEAD_ALIGN;
+ ptr=(void *)(((char *)ptr)-HEAD_ALIGN);
_ripremove(ptr);
free(ptr);
}
diff --git a/res012.c b/res012.c
index fffda8e..fc64730 100644
--- a/res012.c
+++ b/res012.c
@@ -46,8 +46,8 @@ int res_unpack(vorbis_info_residue *info,
info->begin=oggpack_read(opb,24);
info->end=oggpack_read(opb,24);
info->grouping=oggpack_read(opb,24)+1;
- info->partitions=oggpack_read(opb,6)+1;
- info->groupbook=oggpack_read(opb,8);
+ info->partitions=(char)oggpack_read(opb,6)+1;
+ info->groupbook=(unsigned char)oggpack_read(opb,8);
if(info->groupbook>=ci->books)goto errout;
info->stagemasks=_ogg_malloc(info->partitions*sizeof(*info->stagemasks));
@@ -63,7 +63,7 @@ int res_unpack(vorbis_info_residue *info,
for(j=0;j<info->partitions;j++){
for(k=0;k<8;k++){
if((info->stagemasks[j]>>k)&1){
- unsigned char book=oggpack_read(opb,8);
+ unsigned char book=(unsigned char)oggpack_read(opb,8);
if(book>=ci->books)goto errout;
info->stagebooks[j*8+k]=book;
if(k+1>info->stages)info->stages=k+1;
@@ -217,7 +217,6 @@ int res_inverse(vorbis_dsp_state *vd,vorbis_info_residue *info,
}
}
}
- errout:
eopbreak:
return 0;
diff --git a/vorbisfile.c b/vorbisfile.c
index aafc308..ae143e3 100644
--- a/vorbisfile.c
+++ b/vorbisfile.c
@@ -493,7 +493,7 @@ static int _open_seekable2(OggVorbis_File *vf){
/* We get the offset for the last page of the physical bitstream.
Most OggVorbis files will contain a single logical bitstream */
end=_get_prev_page(vf,&og);
- if(end<0)return end;
+ if(end<0)return (int)end;
/* more than one logical bitstream? */
tempserialno=ogg_page_serialno(&og);
@@ -611,7 +611,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf,
ret=0;
goto cleanup;
}
- if((ret=_get_next_page(vf,&og,-1))<0){
+ if((ret=(int)_get_next_page(vf,&og,-1))<0){
ret=OV_EOF; /* eof. leave unitialized */
goto cleanup;
}
@@ -691,7 +691,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf,
fseek64 */
static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
if(f==NULL)return -1;
- return fseek(f,off,whence);
+ return fseek(f,(long)off,whence);
}
static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
@@ -861,11 +861,11 @@ long ov_bitrate(OggVorbis_File *vf,int i){
* gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
* so this is slightly transformed to make it work.
*/
- return bits*1000/ov_time_total(vf,-1);
+ return (long)(bits*1000/ov_time_total(vf,-1));
}else{
if(vf->seekable){
/* return the actual bitrate */
- return (vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i);
+ return (long)(vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i);
}else{
/* return nominal if set */
if(vf->vi.bitrate_nominal>0){
@@ -892,7 +892,7 @@ long ov_bitrate_instant(OggVorbis_File *vf){
long ret;
if(vf->ready_state<OPENED)return OV_EINVAL;
if(vf->samptrack==0)return OV_FALSE;
- ret=vf->bittrack/vf->samptrack*vf->vi.rate;
+ ret=(long)(vf->bittrack/vf->samptrack*vf->vi.rate);
vf->bittrack=0;
vf->samptrack=0;
return ret;
@@ -1387,7 +1387,7 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
ogg_int64_t target=pos-vf->pcm_offset;
long samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
- if(samples>target)samples=target;
+ if(samples>target)samples=(long)target;
vorbis_dsp_read(vf->vd,samples);
vf->pcm_offset+=samples;