media/libtremor/lib/tremor_res012.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libtremor/lib/tremor_res012.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,374 @@
     1.4 +/********************************************************************
     1.5 + *                                                                  *
     1.6 + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
     1.7 + *                                                                  *
     1.8 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
     1.9 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
    1.10 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
    1.11 + *                                                                  *
    1.12 + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
    1.13 + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
    1.14 + *                                                                  *
    1.15 + ********************************************************************
    1.16 +
    1.17 + function: residue backend 0, 1 and 2 implementation
    1.18 +
    1.19 + ********************************************************************/
    1.20 +
    1.21 +#include <stdlib.h>
    1.22 +#include <string.h>
    1.23 +#include <math.h>
    1.24 +#include <ogg/ogg.h>
    1.25 +#include "ivorbiscodec.h"
    1.26 +#include "codec_internal.h"
    1.27 +#include "registry.h"
    1.28 +#include "codebook.h"
    1.29 +#include "misc.h"
    1.30 +#include "os.h"
    1.31 +#include "block.h"
    1.32 +
    1.33 +typedef struct {
    1.34 +  vorbis_info_residue0 *info;
    1.35 +  int         map;
    1.36 +  
    1.37 +  int         parts;
    1.38 +  int         stages;
    1.39 +  codebook   *fullbooks;
    1.40 +  codebook   *phrasebook;
    1.41 +  codebook ***partbooks;
    1.42 +
    1.43 +  int         partvals;
    1.44 +  int       **decodemap;
    1.45 +
    1.46 +} vorbis_look_residue0;
    1.47 +
    1.48 +void res0_free_info(vorbis_info_residue *i){
    1.49 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
    1.50 +  if(info){
    1.51 +    memset(info,0,sizeof(*info));
    1.52 +    _ogg_free(info);
    1.53 +  }
    1.54 +}
    1.55 +
    1.56 +void res0_free_look(vorbis_look_residue *i){
    1.57 +  int j;
    1.58 +  if(i){
    1.59 +
    1.60 +    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
    1.61 +
    1.62 +    for(j=0;j<look->parts;j++)
    1.63 +      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
    1.64 +    _ogg_free(look->partbooks);
    1.65 +    for(j=0;j<look->partvals;j++)
    1.66 +      _ogg_free(look->decodemap[j]);
    1.67 +    _ogg_free(look->decodemap);
    1.68 +
    1.69 +    memset(look,0,sizeof(*look));
    1.70 +    _ogg_free(look);
    1.71 +  }
    1.72 +}
    1.73 +
    1.74 +static int ilog(unsigned int v){
    1.75 +  int ret=0;
    1.76 +  while(v){
    1.77 +    ret++;
    1.78 +    v>>=1;
    1.79 +  }
    1.80 +  return(ret);
    1.81 +}
    1.82 +
    1.83 +static int icount(unsigned int v){
    1.84 +  int ret=0;
    1.85 +  while(v){
    1.86 +    ret+=v&1;
    1.87 +    v>>=1;
    1.88 +  }
    1.89 +  return(ret);
    1.90 +}
    1.91 +
    1.92 +/* vorbis_info is for range checking */
    1.93 +vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
    1.94 +  int j,acc=0;
    1.95 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info));
    1.96 +  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
    1.97 +
    1.98 +  info->begin=oggpack_read(opb,24);
    1.99 +  info->end=oggpack_read(opb,24);
   1.100 +  info->grouping=oggpack_read(opb,24)+1;
   1.101 +  info->partitions=oggpack_read(opb,6)+1;
   1.102 +  info->groupbook=oggpack_read(opb,8);
   1.103 +
   1.104 +  /* check for premature EOP */
   1.105 +  if(info->groupbook<0)goto errout;
   1.106 +
   1.107 +  for(j=0;j<info->partitions;j++){
   1.108 +    int cascade=oggpack_read(opb,3);
   1.109 +    int cflag=oggpack_read(opb,1);
   1.110 +    if(cflag<0) goto errout;
   1.111 +    if(cflag){
   1.112 +      int c=oggpack_read(opb,5);
   1.113 +      if(c<0) goto errout;
   1.114 +      cascade|=(c<<3);
   1.115 +    }
   1.116 +    info->secondstages[j]=cascade;
   1.117 +
   1.118 +    acc+=icount(cascade);
   1.119 +  }
   1.120 +  for(j=0;j<acc;j++){
   1.121 +    int book=oggpack_read(opb,8);
   1.122 +    if(book<0) goto errout;
   1.123 +    info->booklist[j]=book;
   1.124 +  }
   1.125 +
   1.126 +  if(info->groupbook>=ci->books)goto errout;
   1.127 +  for(j=0;j<acc;j++){
   1.128 +    if(info->booklist[j]>=ci->books)goto errout;
   1.129 +    if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
   1.130 +  }
   1.131 +
   1.132 +  /* verify the phrasebook is not specifying an impossible or
   1.133 +     inconsistent partitioning scheme. */
   1.134 +  /* modify the phrasebook ranging check from r16327; an early beta
   1.135 +     encoder had a bug where it used an oversized phrasebook by
   1.136 +     accident.  These files should continue to be playable, but don't
   1.137 +     allow an exploit */
   1.138 +  {
   1.139 +    int entries = ci->book_param[info->groupbook]->entries;
   1.140 +    int dim = ci->book_param[info->groupbook]->dim;
   1.141 +    int partvals = 1;
   1.142 +    if (dim<1) goto errout;
   1.143 +    while(dim>0){
   1.144 +      partvals *= info->partitions;
   1.145 +      if(partvals > entries) goto errout;
   1.146 +      dim--;
   1.147 +    }
   1.148 +    info->partvals = partvals;
   1.149 +  }
   1.150 +
   1.151 +  return(info);
   1.152 + errout:
   1.153 +  res0_free_info(info);
   1.154 +  return(NULL);
   1.155 +}
   1.156 +
   1.157 +vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
   1.158 +			  vorbis_info_residue *vr){
   1.159 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
   1.160 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look));
   1.161 +  codec_setup_info     *ci=(codec_setup_info *)vd->vi->codec_setup;
   1.162 +
   1.163 +  int j,k,acc=0;
   1.164 +  int dim;
   1.165 +  int maxstage=0;
   1.166 +  look->info=info;
   1.167 +  look->map=vm->mapping;
   1.168 +
   1.169 +  look->parts=info->partitions;
   1.170 +  look->fullbooks=ci->fullbooks;
   1.171 +  look->phrasebook=ci->fullbooks+info->groupbook;
   1.172 +  dim=look->phrasebook->dim;
   1.173 +
   1.174 +  look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks));
   1.175 +
   1.176 +  for(j=0;j<look->parts;j++){
   1.177 +    int stages=ilog(info->secondstages[j]);
   1.178 +    if(stages){
   1.179 +      if(stages>maxstage)maxstage=stages;
   1.180 +      look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j]));
   1.181 +      for(k=0;k<stages;k++)
   1.182 +	if(info->secondstages[j]&(1<<k)){
   1.183 +	  look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
   1.184 +#ifdef TRAIN_RES
   1.185 +	  look->training_data[k][j]=calloc(look->partbooks[j][k]->entries,
   1.186 +					   sizeof(***look->training_data));
   1.187 +#endif
   1.188 +	}
   1.189 +    }
   1.190 +  }
   1.191 +
   1.192 +  look->partvals=look->parts;
   1.193 +  for(j=1;j<dim;j++)look->partvals*=look->parts;
   1.194 +  look->stages=maxstage;
   1.195 +  look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap));
   1.196 +  for(j=0;j<look->partvals;j++){
   1.197 +    long val=j;
   1.198 +    long mult=look->partvals/look->parts;
   1.199 +    look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j]));
   1.200 +    for(k=0;k<dim;k++){
   1.201 +      long deco=val/mult;
   1.202 +      val-=deco*mult;
   1.203 +      mult/=look->parts;
   1.204 +      look->decodemap[j][k]=deco;
   1.205 +    }
   1.206 +  }
   1.207 +
   1.208 +  return(look);
   1.209 +}
   1.210 +
   1.211 +
   1.212 +/* a truncated packet here just means 'stop working'; it's not an error */
   1.213 +static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.214 +		      ogg_int32_t **in,int ch,
   1.215 +		      long (*decodepart)(codebook *, ogg_int32_t *, 
   1.216 +					 oggpack_buffer *,int,int)){
   1.217 +
   1.218 +  long i,j,k,l,s;
   1.219 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   1.220 +  vorbis_info_residue0 *info=look->info;
   1.221 +
   1.222 +  /* move all this setup out later */
   1.223 +  int samples_per_partition=info->grouping;
   1.224 +  int partitions_per_word=look->phrasebook->dim;
   1.225 +  int max=vb->pcmend>>1;
   1.226 +  int end=(info->end<max?info->end:max);
   1.227 +  int n=end-info->begin;
   1.228 +
   1.229 +  if(n>0){
   1.230 +    int partvals=n/samples_per_partition;
   1.231 +    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
   1.232 +    int ***partword=(int ***)alloca(ch*sizeof(*partword));
   1.233 +    
   1.234 +    for(j=0;j<ch;j++)
   1.235 +      partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
   1.236 +    
   1.237 +    for(s=0;s<look->stages;s++){
   1.238 +      
   1.239 +      /* each loop decodes on partition codeword containing 
   1.240 +	 partitions_pre_word partitions */
   1.241 +      for(i=0,l=0;i<partvals;l++){
   1.242 +	if(s==0){
   1.243 +	  /* fetch the partition word for each channel */
   1.244 +	  for(j=0;j<ch;j++){
   1.245 +	    int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
   1.246 +	    if(temp==-1 || temp>=info->partvals)goto eopbreak;
   1.247 +	    partword[j][l]=look->decodemap[temp];
   1.248 +	    if(partword[j][l]==NULL)goto errout;
   1.249 +	  }
   1.250 +	}
   1.251 +	
   1.252 +	/* now we decode residual values for the partitions */
   1.253 +	for(k=0;k<partitions_per_word && i<partvals;k++,i++)
   1.254 +	  for(j=0;j<ch;j++){
   1.255 +	    long offset=info->begin+i*samples_per_partition;
   1.256 +	    if(info->secondstages[partword[j][l][k]]&(1<<s)){
   1.257 +	      codebook *stagebook=look->partbooks[partword[j][l][k]][s];
   1.258 +	      if(stagebook){
   1.259 +		if(decodepart(stagebook,in[j]+offset,&vb->opb,
   1.260 +			      samples_per_partition,-8)==-1)goto eopbreak;
   1.261 +	      }
   1.262 +	    }
   1.263 +	  }
   1.264 +      } 
   1.265 +    }
   1.266 +  }
   1.267 + errout:
   1.268 + eopbreak:
   1.269 +  return(0);
   1.270 +}
   1.271 +
   1.272 +int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.273 +		 ogg_int32_t **in,int *nonzero,int ch){
   1.274 +  int i,used=0;
   1.275 +  for(i=0;i<ch;i++)
   1.276 +    if(nonzero[i])
   1.277 +      in[used++]=in[i];
   1.278 +  if(used)
   1.279 +    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
   1.280 +  else
   1.281 +    return(0);
   1.282 +}
   1.283 +
   1.284 +int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.285 +		 ogg_int32_t **in,int *nonzero,int ch){
   1.286 +  int i,used=0;
   1.287 +  for(i=0;i<ch;i++)
   1.288 +    if(nonzero[i])
   1.289 +      in[used++]=in[i];
   1.290 +  if(used)
   1.291 +    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
   1.292 +  else
   1.293 +    return(0);
   1.294 +}
   1.295 +
   1.296 +/* duplicate code here as speed is somewhat more important */
   1.297 +int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.298 +		 ogg_int32_t **in,int *nonzero,int ch){
   1.299 +  long i,k,l,s;
   1.300 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   1.301 +  vorbis_info_residue0 *info=look->info;
   1.302 +
   1.303 +  /* move all this setup out later */
   1.304 +  int samples_per_partition=info->grouping;
   1.305 +  int partitions_per_word=look->phrasebook->dim;
   1.306 +  int max=(vb->pcmend*ch)>>1;
   1.307 +  int end=(info->end<max?info->end:max);
   1.308 +  int n=end-info->begin;
   1.309 +
   1.310 +  if(n>0){
   1.311 +    
   1.312 +    int partvals=n/samples_per_partition;
   1.313 +    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
   1.314 +    int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword));
   1.315 +    int beginoff=info->begin/ch;
   1.316 +    
   1.317 +    for(i=0;i<ch;i++)if(nonzero[i])break;
   1.318 +    if(i==ch)return(0); /* no nonzero vectors */
   1.319 +    
   1.320 +    samples_per_partition/=ch;
   1.321 +    
   1.322 +    for(s=0;s<look->stages;s++){
   1.323 +      for(i=0,l=0;i<partvals;l++){
   1.324 +	
   1.325 +	if(s==0){
   1.326 +	  /* fetch the partition word */
   1.327 +	  int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
   1.328 +	  if(temp==-1 || temp>=info->partvals)goto eopbreak;
   1.329 +	  partword[l]=look->decodemap[temp];
   1.330 +	  if(partword[l]==NULL)goto errout;
   1.331 +	}
   1.332 +
   1.333 +	/* now we decode residual values for the partitions */
   1.334 +	for(k=0;k<partitions_per_word && i<partvals;k++,i++)
   1.335 +	  if(info->secondstages[partword[l][k]]&(1<<s)){
   1.336 +	    codebook *stagebook=look->partbooks[partword[l][k]][s];
   1.337 +	    
   1.338 +	    if(stagebook){
   1.339 +	      if(vorbis_book_decodevv_add(stagebook,in,
   1.340 +					  i*samples_per_partition+beginoff,ch,
   1.341 +					  &vb->opb,
   1.342 +					  samples_per_partition,-8)==-1)
   1.343 +		goto eopbreak;
   1.344 +	    }
   1.345 +	  }
   1.346 +      } 
   1.347 +    }
   1.348 +  }
   1.349 + errout:
   1.350 + eopbreak:
   1.351 +  return(0);
   1.352 +}
   1.353 +
   1.354 +
   1.355 +vorbis_func_residue residue0_exportbundle={
   1.356 +  &res0_unpack,
   1.357 +  &res0_look,
   1.358 +  &res0_free_info,
   1.359 +  &res0_free_look,
   1.360 +  &res0_inverse
   1.361 +};
   1.362 +
   1.363 +vorbis_func_residue residue1_exportbundle={
   1.364 +  &res0_unpack,
   1.365 +  &res0_look,
   1.366 +  &res0_free_info,
   1.367 +  &res0_free_look,
   1.368 +  &res1_inverse
   1.369 +};
   1.370 +
   1.371 +vorbis_func_residue residue2_exportbundle={
   1.372 +  &res0_unpack,
   1.373 +  &res0_look,
   1.374 +  &res0_free_info,
   1.375 +  &res0_free_look,
   1.376 +  &res2_inverse
   1.377 +};

mercurial