137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang/************************************************************************
22da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Copyright (C) 2002-2009, Xiph.org Foundation
32da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * All rights reserved.
537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *
637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * Redistribution and use in source and binary forms, with or without
72da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * modification, are permitted provided that the following conditions
82da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * are met:
937fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *
1037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *     * Redistributions of source code must retain the above copyright
1137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * notice, this list of conditions and the following disclaimer.
1237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *     * Redistributions in binary form must reproduce the above
1337fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * copyright notice, this list of conditions and the following disclaimer
1437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * in the documentation and/or other materials provided with the
1537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * distribution.
162da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang *     * Neither the names of the Xiph.org Foundation nor Pinknoise
172da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * Productions Ltd nor the names of its contributors may be used to
182da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * endorse or promote products derived from this software without
192da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang * specific prior written permission.
2037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang *
2137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2337fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2437fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2537fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2737fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2837fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2937fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3037fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3137fe158a8611dd11ec0253ab1552399b780988dcGloria Wang * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3237fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************
337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang function: residue backend 0, 1 and 2 implementation
357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************/
377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <stdlib.h>
397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <string.h>
407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <math.h>
417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ogg.h"
427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ivorbiscodec.h"
437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codec_internal.h"
447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codebook.h"
457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "misc.h"
467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "os.h"
477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid res_clear_info(vorbis_info_residue *info){
497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info){
507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(info->stagemasks)_ogg_free(info->stagemasks);
517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(info->stagebooks)_ogg_free(info->stagebooks);
527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    memset(info,0,sizeof(*info));
537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* vorbis_info is for range checking */
587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint res_unpack(vorbis_info_residue *info,
597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		vorbis_info *vi,oggpack_buffer *opb){
607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int j,k;
617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  memset(info,0,sizeof(*info));
637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->type=oggpack_read(opb,16);
657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info->type>2 || info->type<0)goto errout;
667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->begin=oggpack_read(opb,24);
677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->end=oggpack_read(opb,24);
687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->grouping=oggpack_read(opb,24)+1;
697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->partitions=(char)(oggpack_read(opb,6)+1);
707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->groupbook=(unsigned char)oggpack_read(opb,8);
717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info->groupbook>=ci->books)goto errout;
727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->stagemasks=_ogg_malloc(info->partitions*sizeof(*info->stagemasks));
747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  info->stagebooks=_ogg_malloc(info->partitions*8*sizeof(*info->stagebooks));
757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  for(j=0;j<info->partitions;j++){
777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int cascade=oggpack_read(opb,3);
787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(oggpack_read(opb,1))
797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      cascade|=(oggpack_read(opb,5)<<3);
807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    info->stagemasks[j]=cascade;
817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  for(j=0;j<info->partitions;j++){
847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(k=0;k<8;k++){
857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if((info->stagemasks[j]>>k)&1){
867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	unsigned char book=(unsigned char)oggpack_read(opb,8);
877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(book>=ci->books)goto errout;
887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	info->stagebooks[j*8+k]=book;
897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(k+1>info->stages)info->stages=k+1;
907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }else
917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	info->stagebooks[j*8+k]=0xff;
927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(oggpack_eop(opb))goto errout;
967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang errout:
997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  res_clear_info(info);
1007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 1;
1017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
1027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint res_inverse(vorbis_dsp_state *vd,vorbis_info_residue *info,
1047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		ogg_int32_t **in,int *nonzero,int ch){
1057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int i,j,k,s,used=0;
1077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  codec_setup_info     *ci=(codec_setup_info *)vd->vi->codec_setup;
1087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  codebook *phrasebook=ci->book_param+info->groupbook;
1097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int samples_per_partition=info->grouping;
1107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int partitions_per_word=phrasebook->dim;
1117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int pcmend=ci->blocksizes[vd->W];
1127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(info->type<2){
1147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int max=pcmend>>1;
1157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int end=(info->end<max?info->end:max);
1167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int n=end-info->begin;
1177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(n>0){
1197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      int partvals=n/samples_per_partition;
1207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
1217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<ch;i++)
1237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(nonzero[i])
1247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  in[used++]=in[i];
1257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      ch=used;
1267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(used){
1287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	char **partword=(char **)alloca(ch*sizeof(*partword));
1307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(j=0;j<ch;j++)
1317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  partword[j]=(char *)alloca(partwords*partitions_per_word*
1327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang				     sizeof(*partword[j]));
1337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(s=0;s<info->stages;s++){
1357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  for(i=0;i<partvals;){
1377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    if(s==0){
1387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      /* fetch the partition word for each channel */
1397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      partword[0][i+partitions_per_word-1]=1;
1417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      for(k=partitions_per_word-2;k>=0;k--)
1427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		partword[0][i+k]=partword[0][i+k+1]*info->partitions;
1437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      for(j=1;j<ch;j++)
1457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		for(k=partitions_per_word-1;k>=0;k--)
1467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  partword[j][i+k]=partword[j-1][i+k];
1477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      for(j=0;j<ch;j++){
1497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		int temp=vorbis_book_decode(phrasebook,&vd->opb);
1507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		if(temp==-1)goto eopbreak;
1517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		/* this can be done quickly in assembly due to the quotient
1537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		   always being at most six bits */
1547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		for(k=0;k<partitions_per_word;k++){
1557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  ogg_uint32_t div=partword[j][i+k];
1567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  partword[j][i+k]=temp/div;
1577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  temp-=partword[j][i+k]*div;
1587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		}
1597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      }
1617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    }
1627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    /* now we decode residual values for the partitions */
1647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    for(k=0;k<partitions_per_word && i<partvals;k++,i++)
1657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      for(j=0;j<ch;j++){
1667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		long offset=info->begin+i*samples_per_partition;
1677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		if(info->stagemasks[(int)partword[j][i]]&(1<<s)){
1687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  codebook *stagebook=ci->book_param+
1697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		    info->stagebooks[(partword[j][i]<<3)+s];
1707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  if(info->type){
1717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		    if(vorbis_book_decodev_add(stagebook,in[j]+offset,&vd->opb,
1727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					       samples_per_partition,-8)==-1)
1737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		      goto eopbreak;
1747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  }else{
1757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		    if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vd->opb,
1767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang						samples_per_partition,-8)==-1)
1777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		      goto eopbreak;
1787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		  }
1797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		}
1807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      }
1817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
1827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
1837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
1847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
1857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }else{
1867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int max=(pcmend*ch)>>1;
1877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int end=(info->end<max?info->end:max);
1887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int n=end-info->begin;
1897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(n>0){
1917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      int partvals=n/samples_per_partition;
1927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
1937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      char *partword=
1957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	(char *)alloca(partwords*partitions_per_word*sizeof(*partword));
1967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      int beginoff=info->begin/ch;
1977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<ch;i++)if(nonzero[i])break;
1997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(i==ch)return(0); /* no nonzero vectors */
2007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      samples_per_partition/=ch;
2027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(s=0;s<info->stages;s++){
2047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(i=0;i<partvals;){
2057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(s==0){
2077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    int temp;
2087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    partword[i+partitions_per_word-1]=1;
2097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    for(k=partitions_per_word-2;k>=0;k--)
2107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      partword[i+k]=partword[i+k+1]*info->partitions;
2117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    /* fetch the partition word */
2137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    temp=vorbis_book_decode(phrasebook,&vd->opb);
2147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    if(temp==-1)goto eopbreak;
2157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    /* this can be done quickly in assembly due to the quotient
2177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	       always being at most six bits */
2187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    for(k=0;k<partitions_per_word;k++){
2197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      ogg_uint32_t div=partword[i+k];
2207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      partword[i+k]=temp/div;
2217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      temp-=partword[i+k]*div;
2227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    }
2237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
2247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  /* now we decode residual values for the partitions */
2267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  for(k=0;k<partitions_per_word && i<partvals;k++,i++)
2277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    if(info->stagemasks[(int)partword[i]]&(1<<s)){
2287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      codebook *stagebook=ci->book_param+
2297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		info->stagebooks[(partword[i]<<3)+s];
2307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      if(vorbis_book_decodevv_add(stagebook,in,
2317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					  i*samples_per_partition+beginoff,ch,
2327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					  &vd->opb,
2337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					  samples_per_partition,-8)==-1)
2347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		goto eopbreak;
2357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    }
2367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
2377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
2387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
2397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
2407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang eopbreak:
2417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
2437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
2447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
245