1/************************************************************************ 2 * Copyright (C) 2002-2009, Xiph.org Foundation 3 * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following disclaimer 14 * in the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the names of the Xiph.org Foundation nor Pinknoise 17 * Productions Ltd nor the names of its contributors may be used to 18 * endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 ************************************************************************ 33 34 function: residue backend 0, 1 and 2 implementation 35 36 ************************************************************************/ 37 38#include <stdlib.h> 39#include <string.h> 40#include <math.h> 41#include "ogg.h" 42#include "ivorbiscodec.h" 43#include "codec_internal.h" 44#include "codebook.h" 45#include "misc.h" 46#include "os.h" 47 48void res_clear_info(vorbis_info_residue *info){ 49 if(info){ 50 if(info->stagemasks)_ogg_free(info->stagemasks); 51 if(info->stagebooks)_ogg_free(info->stagebooks); 52 memset(info,0,sizeof(*info)); 53 } 54} 55 56 57/* vorbis_info is for range checking */ 58int res_unpack(vorbis_info_residue *info, 59 vorbis_info *vi,oggpack_buffer *opb){ 60 int j,k; 61 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 62 memset(info,0,sizeof(*info)); 63 64 info->type=oggpack_read(opb,16); 65 if(info->type>2 || info->type<0)goto errout; 66 info->begin=oggpack_read(opb,24); 67 info->end=oggpack_read(opb,24); 68 info->grouping=oggpack_read(opb,24)+1; 69 info->partitions=(char)(oggpack_read(opb,6)+1); 70 info->groupbook=(unsigned char)oggpack_read(opb,8); 71 if(info->groupbook>=ci->books)goto errout; 72 73 info->stagemasks=_ogg_malloc(info->partitions*sizeof(*info->stagemasks)); 74 info->stagebooks=_ogg_malloc(info->partitions*8*sizeof(*info->stagebooks)); 75 76 for(j=0;j<info->partitions;j++){ 77 int cascade=oggpack_read(opb,3); 78 if(oggpack_read(opb,1)) 79 cascade|=(oggpack_read(opb,5)<<3); 80 info->stagemasks[j]=cascade; 81 } 82 83 for(j=0;j<info->partitions;j++){ 84 for(k=0;k<8;k++){ 85 if((info->stagemasks[j]>>k)&1){ 86 unsigned char book=(unsigned char)oggpack_read(opb,8); 87 if(book>=ci->books)goto errout; 88 info->stagebooks[j*8+k]=book; 89 if(k+1>info->stages)info->stages=k+1; 90 }else 91 info->stagebooks[j*8+k]=0xff; 92 } 93 } 94 95 if(oggpack_eop(opb))goto errout; 96 97 return 0; 98 errout: 99 res_clear_info(info); 100 return 1; 101} 102 103int res_inverse(vorbis_dsp_state *vd,vorbis_info_residue *info, 104 ogg_int32_t **in,int *nonzero,int ch){ 105 106 int i,j,k,s,used=0; 107 codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; 108 codebook *phrasebook=ci->book_param+info->groupbook; 109 int samples_per_partition=info->grouping; 110 int partitions_per_word=phrasebook->dim; 111 int pcmend=ci->blocksizes[vd->W]; 112 113 if(info->type<2){ 114 int max=pcmend>>1; 115 int end=(info->end<max?info->end:max); 116 int n=end-info->begin; 117 118 if(n>0){ 119 int partvals=n/samples_per_partition; 120 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; 121 122 for(i=0;i<ch;i++) 123 if(nonzero[i]) 124 in[used++]=in[i]; 125 ch=used; 126 127 if(used){ 128 129 char **partword=(char **)alloca(ch*sizeof(*partword)); 130 for(j=0;j<ch;j++) 131 partword[j]=(char *)alloca(partwords*partitions_per_word* 132 sizeof(*partword[j])); 133 134 for(s=0;s<info->stages;s++){ 135 136 for(i=0;i<partvals;){ 137 if(s==0){ 138 /* fetch the partition word for each channel */ 139 140 partword[0][i+partitions_per_word-1]=1; 141 for(k=partitions_per_word-2;k>=0;k--) 142 partword[0][i+k]=partword[0][i+k+1]*info->partitions; 143 144 for(j=1;j<ch;j++) 145 for(k=partitions_per_word-1;k>=0;k--) 146 partword[j][i+k]=partword[j-1][i+k]; 147 148 for(j=0;j<ch;j++){ 149 int temp=vorbis_book_decode(phrasebook,&vd->opb); 150 if(temp==-1)goto eopbreak; 151 152 /* this can be done quickly in assembly due to the quotient 153 always being at most six bits */ 154 for(k=0;k<partitions_per_word;k++){ 155 ogg_uint32_t div=partword[j][i+k]; 156 partword[j][i+k]=temp/div; 157 temp-=partword[j][i+k]*div; 158 } 159 160 } 161 } 162 163 /* now we decode residual values for the partitions */ 164 for(k=0;k<partitions_per_word && i<partvals;k++,i++) 165 for(j=0;j<ch;j++){ 166 long offset=info->begin+i*samples_per_partition; 167 if(info->stagemasks[(int)partword[j][i]]&(1<<s)){ 168 codebook *stagebook=ci->book_param+ 169 info->stagebooks[(partword[j][i]<<3)+s]; 170 if(info->type){ 171 if(vorbis_book_decodev_add(stagebook,in[j]+offset,&vd->opb, 172 samples_per_partition,-8)==-1) 173 goto eopbreak; 174 }else{ 175 if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vd->opb, 176 samples_per_partition,-8)==-1) 177 goto eopbreak; 178 } 179 } 180 } 181 } 182 } 183 } 184 } 185 }else{ 186 int max=(pcmend*ch)>>1; 187 int end=(info->end<max?info->end:max); 188 int n=end-info->begin; 189 190 if(n>0){ 191 int partvals=n/samples_per_partition; 192 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; 193 194 char *partword= 195 (char *)alloca(partwords*partitions_per_word*sizeof(*partword)); 196 int beginoff=info->begin/ch; 197 198 for(i=0;i<ch;i++)if(nonzero[i])break; 199 if(i==ch)return(0); /* no nonzero vectors */ 200 201 samples_per_partition/=ch; 202 203 for(s=0;s<info->stages;s++){ 204 for(i=0;i<partvals;){ 205 206 if(s==0){ 207 int temp; 208 partword[i+partitions_per_word-1]=1; 209 for(k=partitions_per_word-2;k>=0;k--) 210 partword[i+k]=partword[i+k+1]*info->partitions; 211 212 /* fetch the partition word */ 213 temp=vorbis_book_decode(phrasebook,&vd->opb); 214 if(temp==-1)goto eopbreak; 215 216 /* this can be done quickly in assembly due to the quotient 217 always being at most six bits */ 218 for(k=0;k<partitions_per_word;k++){ 219 ogg_uint32_t div=partword[i+k]; 220 partword[i+k]=temp/div; 221 temp-=partword[i+k]*div; 222 } 223 } 224 225 /* now we decode residual values for the partitions */ 226 for(k=0;k<partitions_per_word && i<partvals;k++,i++) 227 if(info->stagemasks[(int)partword[i]]&(1<<s)){ 228 codebook *stagebook=ci->book_param+ 229 info->stagebooks[(partword[i]<<3)+s]; 230 if(vorbis_book_decodevv_add(stagebook,in, 231 i*samples_per_partition+beginoff,ch, 232 &vd->opb, 233 samples_per_partition,-8)==-1) 234 goto eopbreak; 235 } 236 } 237 } 238 } 239 } 240 eopbreak: 241 242 return 0; 243} 244 245