summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2003-04-11 09:16:35 +0000
committerMonty <xiphmont@xiph.org>2003-04-11 09:16:35 +0000
commite53ab577810533fdc0836bfb404f33fa26c603c4 (patch)
tree8fe49fb4085148c9ed775fa96be0f52019f1a4b0
parent36454e10b79797e68f02287f277b78a6225da413 (diff)
downloadtremor-e53ab577810533fdc0836bfb404f33fa26c603c4.tar.gz
Floor 1 memory reduction; no longer blindly allocate the maximum
possible amount of needed memory when typical case is much lower. git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremor@4605 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--backends.h31
-rw-r--r--floor1.c59
2 files changed, 56 insertions, 34 deletions
diff --git a/backends.h b/backends.h
index 6afe3ca..1ed4063 100644
--- a/backends.h
+++ b/backends.h
@@ -55,24 +55,25 @@ typedef struct{
#define VIF_POSIT 63
#define VIF_CLASS 16
#define VIF_PARTS 31
-typedef struct{
- int partitions; /* 0 to 31 */
- int partitionclass[VIF_PARTS]; /* 0 to 15 */
-
- int class_dim[VIF_CLASS]; /* 1 to 8 */
- int class_subs[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */
- int class_book[VIF_CLASS]; /* subs ^ dim entries */
- int class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
-
- int mult; /* 1 2 3 or 4 */
- ogg_uint16_t postlist[VIF_POSIT+2]; /* first two implicit */
+typedef struct{
+ char class_dim; /* 1 to 8 */
+ char class_subs; /* 0,1,2,3 (bits: 1<<n poss) */
+ unsigned char class_book; /* subs ^ dim entries */
+ unsigned char class_subbook[8]; /* [VIF_CLASS][subs] */
+} floor1class;
- /* useful, generated values */
- char forward_index[VIF_POSIT+2];
- char hineighbor[VIF_POSIT];
- char loneighbor[VIF_POSIT];
+typedef struct{
+ floor1class *class; /* [VIF_CLASS] */
+ char *partitionclass; /* [VIF_PARTS]; 0 to 15 */
+ ogg_uint16_t *postlist; /* [VIF_POSIT+2]; first two implicit */
+ char *forward_index; /* [VIF_POSIT+2]; */
+ char *hineighbor; /* [VIF_POSIT]; */
+ char *loneighbor; /* [VIF_POSIT]; */
+
+ int partitions; /* 0 to 31 */
int posts;
+ int mult; /* 1 2 3 or 4 */
} vorbis_info_floor1;
diff --git a/floor1.c b/floor1.c
index 46117f8..6ae1a66 100644
--- a/floor1.c
+++ b/floor1.c
@@ -32,6 +32,12 @@
static void floor1_free_info(vorbis_info_floor *i){
vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
if(info){
+ if(info->class)_ogg_free(info->class);
+ if(info->partitionclass)_ogg_free(info->partitionclass);
+ if(info->postlist)_ogg_free(info->postlist);
+ if(info->forward_index)_ogg_free(info->forward_index);
+ if(info->hineighbor)_ogg_free(info->hineighbor);
+ if(info->loneighbor)_ogg_free(info->loneighbor);
memset(info,0,sizeof(*info));
_ogg_free(info);
}
@@ -58,24 +64,27 @@ static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info));
/* read partitions */
info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
+ 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 */
if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
}
/* read partition classes */
+ info->class=
+ (floor1class *)_ogg_malloc((maxclass+1)*sizeof(*info->class));
for(j=0;j<maxclass+1;j++){
- info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
- info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
- if(info->class_subs[j]<0)
- goto err_out;
- if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
- if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
- goto err_out;
- for(k=0;k<(1<<info->class_subs[j]);k++){
- info->class_subbook[j][k]=oggpack_read(opb,8)-1;
- if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
- goto err_out;
+ 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 */
+ if(oggpack_eop(opb)<0) goto err_out;
+ if(info->class[j].class_subs)
+ info->class[j].class_book=oggpack_read(opb,8);
+ 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;
+ if(info->class[j].class_subbook[k]>=ci->books &&
+ info->class[j].class_subbook[k]!=0xff)goto err_out;
}
}
@@ -83,14 +92,26 @@ static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
rangebits=oggpack_read(opb,4);
+ for(j=0,k=0;j<info->partitions;j++)
+ count+=info->class[info->partitionclass[j]].class_dim;
+ info->postlist=
+ (ogg_uint16_t *)_ogg_malloc((count+2)*sizeof(*info->postlist));
+ info->forward_index=
+ (char *)_ogg_malloc((count+2)*sizeof(*info->forward_index));
+ info->loneighbor=
+ (char *)_ogg_malloc(count*sizeof(*info->loneighbor));
+ info->hineighbor=
+ (char *)_ogg_malloc(count*sizeof(*info->hineighbor));
+
+ count=0;
for(j=0,k=0;j<info->partitions;j++){
- count+=info->class_dim[info->partitionclass[j]];
+ count+=info->class[info->partitionclass[j]].class_dim;
for(;k<count;k++){
int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
- if(t<0 || t>=(1<<rangebits))
- goto err_out;
+ if(t>=(1<<rangebits))goto err_out;
}
}
+ if(oggpack_eop(opb))goto err_out;
info->postlist[0]=0;
info->postlist[1]=1<<rangebits;
info->posts=count+2;
@@ -270,22 +291,22 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_info_floor *in){
/* partition by partition */
for(i=0,j=2;i<info->partitions;i++){
int classv=info->partitionclass[i];
- int cdim=info->class_dim[classv];
- int csubbits=info->class_subs[classv];
+ int cdim=info->class[classv].class_dim;
+ int csubbits=info->class[classv].class_subs;
int csub=1<<csubbits;
int cval=0;
/* decode the partition's first stage cascade value */
if(csubbits){
- cval=vorbis_book_decode(books+info->class_book[classv],&vb->opb);
+ cval=vorbis_book_decode(books+info->class[classv].class_book,&vb->opb);
if(cval==-1)goto eop;
}
for(k=0;k<cdim;k++){
- int book=info->class_subbook[classv][cval&(csub-1)];
+ int book=info->class[classv].class_subbook[cval&(csub-1)];
cval>>=csubbits;
- if(book>=0){
+ if(book!=0xff){
if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
goto eop;
}else{