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]= (div == 0) ? 0 : (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 int idx = (int)partword[j][i]; 168 if(idx < info->partitions && info->stagemasks[idx]&(1<<s)){ 169 codebook *stagebook=ci->book_param+ 170 info->stagebooks[(partword[j][i]<<3)+s]; 171 if(info->type){ 172 if(vorbis_book_decodev_add(stagebook,in[j]+offset,&vd->opb, 173 samples_per_partition,-8)==-1) 174 goto eopbreak; 175 }else{ 176 if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vd->opb, 177 samples_per_partition,-8)==-1) 178 goto eopbreak; 179 } 180 } 181 } 182 } 183 } 184 } 185 } 186 }else{ 187 int max=(pcmend*ch)>>1; 188 int end=(info->end<max?info->end:max); 189 int n=end-info->begin; 190 191 if(n>0){ 192 int partvals=n/samples_per_partition; 193 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; 194 195 char *partword= 196 (char *)alloca(partwords*partitions_per_word*sizeof(*partword)); 197 int beginoff=info->begin/ch; 198 199 for(i=0;i<ch;i++)if(nonzero[i])break; 200 if(i==ch)return(0); /* no nonzero vectors */ 201 202 samples_per_partition/=ch; 203 204 for(s=0;s<info->stages;s++){ 205 for(i=0;i<partvals;){ 206 207 if(s==0){ 208 int temp; 209 partword[i+partitions_per_word-1]=1; 210 for(k=partitions_per_word-2;k>=0;k--) 211 partword[i+k]=partword[i+k+1]*info->partitions; 212 213 /* fetch the partition word */ 214 temp=vorbis_book_decode(phrasebook,&vd->opb); 215 if(temp==-1)goto eopbreak; 216 217 /* this can be done quickly in assembly due to the quotient 218 always being at most six bits */ 219 for(k=0;k<partitions_per_word;k++){ 220 ogg_uint32_t div=partword[i+k]; 221 partword[i+k]= (div == 0) ? 0 : (temp / div); 222 temp-=partword[i+k]*div; 223 } 224 } 225 226 /* now we decode residual values for the partitions */ 227 for(k=0;k<partitions_per_word && i<partvals;k++,i++){ 228 if(partword[i] >= 0 && partword[i] < info->partitions && 229 (info->stagemasks[(int)partword[i]] & (1 << s))){ 230 codebook *stagebook=ci->book_param+ 231 info->stagebooks[(partword[i]<<3)+s]; 232 if(vorbis_book_decodevv_add(stagebook,in, 233 i*samples_per_partition+beginoff,ch, 234 &vd->opb, 235 samples_per_partition,-8)==-1) 236 goto eopbreak; 237 } 238 } 239 } 240 } 241 } 242 } 243 eopbreak: 244 245 return 0; 246} 247 248