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: basic codebook pack/unpack/code/decode operations
357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************/
377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <stdlib.h>
397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <string.h>
407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <math.h>
417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <limits.h>
427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ogg.h"
437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ivorbiscodec.h"
447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codebook.h"
457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "misc.h"
467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "os.h"
477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/**** pack/unpack helpers ******************************************/
507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint _ilog(unsigned int v){
517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int ret=0;
527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  while(v){
537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ret++;
547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    v>>=1;
557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return(ret);
577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic ogg_uint32_t decpack(long entry,long used_entry,long quantvals,
607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			    codebook *b,oggpack_buffer *opb,int maptype){
617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t ret=0;
627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int j;
637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  switch(b->dec_type){
657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 0:
677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return (ogg_uint32_t)entry;
687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 1:
707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(maptype==1){
717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* vals are already read into temporary column vector here */
727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(j=0;j<b->dim;j++){
737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	ogg_uint32_t off=entry%quantvals;
747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	entry/=quantvals;
757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	ret|=((ogg_uint16_t *)(b->q_val))[off]<<(b->q_bits*j);
767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(j=0;j<b->dim;j++)
797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	ret|=oggpack_read(opb,b->q_bits)<<(b->q_bits*j);
807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return ret;
827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 2:
847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(j=0;j<b->dim;j++){
857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      ogg_uint32_t off=entry%quantvals;
867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      entry/=quantvals;
877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      ret|=off<<(b->q_pack*j);
887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return ret;
907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 3:
927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return (ogg_uint32_t)used_entry;
937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0; /* silence compiler */
967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* 32 bit float (not IEEE; nonnormalized mantissa +
997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
1007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   Why not IEEE?  It's just not that important here. */
1017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic ogg_int32_t _float32_unpack(long val,int *point){
1037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long   mant=val&0x1fffff;
1047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int    sign=val&0x80000000;
1057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  *point=((val&0x7fe00000L)>>21)-788;
1077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(mant){
1097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    while(!(mant&0x40000000)){
1107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      mant<<=1;
1117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      *point-=1;
1127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
1137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(sign)mant= -mant;
1147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }else{
1157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    *point=-9999;
1167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
1177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return mant;
1187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
1197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* choose the smallest supported node size that fits our decode table.
1217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   Legal bytewidths are 1/1 1/2 2/2 2/4 4/4 */
1227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int _determine_node_bytes(long used, int leafwidth){
1237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* special case small books to size 4 to avoid multiple special
1257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang     cases in repack */
1267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(used<2)
1277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return 4;
1287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(leafwidth==3)leafwidth=4;
1307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(_ilog(3*used-6)+1 <= leafwidth*4)
1317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return leafwidth/2?leafwidth/2:1;
1327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return leafwidth;
1337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
1347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* convenience/clarity; leaves are specified as multiple of node word
1367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   size (1 or 2) */
1377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int _determine_leaf_words(int nodeb, int leafwidth){
1387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(leafwidth>nodeb)return 2;
1397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 1;
1407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
1417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* given a list of word lengths, number of used entries, and byte
1437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   width of a leaf, generate the decode table */
1447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int _make_words(char *l,long n,ogg_uint32_t *r,long quantvals,
1457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		       codebook *b, oggpack_buffer *opb,int maptype){
1467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long i,j,count=0;
1477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long top=0;
1487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t marker[33];
1497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if (n<1)
1517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return 1;
1527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(n<2){
1547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    r[0]=0x80000000;
1557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }else{
1567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    memset(marker,0,sizeof(marker));
1577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<n;i++){
1597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      long length=l[i];
1607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(length){
1617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	ogg_uint32_t entry=marker[length];
1627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	long chase=0;
1637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(count && !entry)return -1; /* overpopulated tree! */
1647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	/* chase the tree as far as it's already populated, fill in past */
1667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(j=0;j<length-1;j++){
1677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  int bit=(entry>>(length-j-1))&1;
1687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(chase>=top){
1697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    if (chase < 0 || chase >= n) return 1;
1707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top++;
1717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    r[chase*2]=top;
1727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    r[chase*2+1]=0;
1737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }else
1747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    if (chase < 0 || chase >= n || chase*2+bit > n*2+1) return 1;
1757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    if(!r[chase*2+bit])
1767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	      r[chase*2+bit]=top;
1777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  chase=r[chase*2+bit];
1787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if (chase < 0 || chase >= n) return 1;
1797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
1807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	{
1817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  int bit=(entry>>(length-j-1))&1;
1827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(chase>=top){
1837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top++;
1847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    r[chase*2+1]=0;
1857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
1867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  r[chase*2+bit]= decpack(i,count++,quantvals,b,opb,maptype) |
1877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    0x80000000;
1887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
1897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
1907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	/* Look to see if the next shorter marker points to the node
1917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	   above. if so, update it and repeat.  */
1927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(j=length;j>0;j--){
1937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(marker[j]&1){
1947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    marker[j]=marker[j-1]<<1;
1957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    break;
1967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
1977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  marker[j]++;
1987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
1997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	/* prune the tree; the implicit invariant says all the longer
2017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	   markers were dangling from our just-taken node.  Dangle them
2027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	   from our *new* node. */
2037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(j=length+1;j<33;j++)
2047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if((marker[j]>>1) == entry){
2057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    entry=marker[j];
2067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    marker[j]=marker[j-1]<<1;
2077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }else
2087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    break;
2097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
2107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
2117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
2127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
21352193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen  // following sanity check copied from libvorbis
21452193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen  /* sanity check the huffman tree; an underpopulated tree must be
21552193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen     rejected. The only exception is the one-node pseudo-nil tree,
21652193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen     which appears to be underpopulated because the tree doesn't
21752193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen     really exist; there's only one possible 'codeword' or zero bits,
21852193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen     but the above tree-gen code doesn't mark that. */
21952193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen  if(b->used_entries != 1){
22052193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen    for(i=1;i<33;i++)
22152193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen      if(marker[i] & (0xffffffffUL>>(32-i))){
22252193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen          return 1;
22352193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen      }
22452193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen  }
22552193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen
22652193fa3472b79873e73044ce02e1c0a67c85043Marco Nelissen
2277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
2287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
2297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int _make_decode_table(codebook *s,char *lengthlist,long quantvals,
2317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			      oggpack_buffer *opb,int maptype){
2327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int i;
2337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t *work;
2347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if (!lengthlist) return 1;
2367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(s->dec_nodeb==4){
2377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* Over-allocate by using s->entries instead of used_entries.
2387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang     * This means that we can use s->entries to enforce size in
2397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang     * _make_words without messing up length list looping.
2407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang     * This probably wastes a bit of space, but it shouldn't
2417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang     * impact behavior or size too much.
2427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang     */
2437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->dec_table=_ogg_malloc((s->entries*2+1)*sizeof(*work));
2447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (!s->dec_table) return 1;
2457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* +1 (rather than -2) is to accommodate 0 and 1 sized books,
2467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang       which are specialcased to nodeb==4 */
2477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(_make_words(lengthlist,s->entries,
2487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang		   s->dec_table,quantvals,s,opb,maptype))return 1;
2497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return 0;
2517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
2527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if (s->used_entries > INT_MAX/2 ||
2547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->used_entries*2 > INT_MAX/((long) sizeof(*work)) - 1) return 1;
2557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* Overallocate as above */
256ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  work=calloc((s->entries*2+1),sizeof(*work));
257ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  if (!work) return 1;
258ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  if(_make_words(lengthlist,s->entries,work,quantvals,s,opb,maptype)) goto error_out;
259ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  if (s->used_entries > INT_MAX/(s->dec_leafw+1)) goto error_out;
260ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  if (s->dec_nodeb && s->used_entries * (s->dec_leafw+1) > INT_MAX/s->dec_nodeb) goto error_out;
2617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  s->dec_table=_ogg_malloc((s->used_entries*(s->dec_leafw+1)-2)*
2627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			   s->dec_nodeb);
263ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  if (!s->dec_table) goto error_out;
2647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(s->dec_leafw==1){
2667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    switch(s->dec_nodeb){
2677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    case 1:
2687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<s->used_entries*2-2;i++)
2697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  ((unsigned char *)s->dec_table)[i]=(unsigned char)
2707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    (((work[i] & 0x80000000UL) >> 24) | work[i]);
2717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      break;
2727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    case 2:
2737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<s->used_entries*2-2;i++)
2747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  ((ogg_uint16_t *)s->dec_table)[i]=(ogg_uint16_t)
2757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    (((work[i] & 0x80000000UL) >> 16) | work[i]);
2767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      break;
2777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
2787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }else{
2807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* more complex; we have to do a two-pass repack that updates the
2817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang       node indexing. */
2827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    long top=s->used_entries*3-2;
2837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(s->dec_nodeb==1){
2847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      unsigned char *out=(unsigned char *)s->dec_table;
2857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
2867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=s->used_entries*2-4;i>=0;i-=2){
2877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(work[i]&0x80000000UL){
2887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(work[i+1]&0x80000000UL){
2897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=4;
2907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=(work[i]>>8 & 0x7f)|0x80;
2917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=(work[i+1]>>8 & 0x7f)|0x80;
2927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+2]=work[i] & 0xff;
2937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+3]=work[i+1] & 0xff;
2947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }else{
2957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=3;
2967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=(work[i]>>8 & 0x7f)|0x80;
2977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=work[work[i+1]*2];
2987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+2]=work[i] & 0xff;
2997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
3007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}else{
3017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(work[i+1]&0x80000000UL){
3027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=3;
3037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=work[work[i]*2];
3047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=(work[i+1]>>8 & 0x7f)|0x80;
3057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+2]=work[i+1] & 0xff;
3067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }else{
3077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=2;
3087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=work[work[i]*2];
3097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=work[work[i+1]*2];
3107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
3117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
3127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	work[i]=top;
3137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
3147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
3157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      ogg_uint16_t *out=(ogg_uint16_t *)s->dec_table;
3167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=s->used_entries*2-4;i>=0;i-=2){
3177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(work[i]&0x80000000UL){
3187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(work[i+1]&0x80000000UL){
3197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=4;
3207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=(work[i]>>16 & 0x7fff)|0x8000;
3217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000;
3227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+2]=work[i] & 0xffff;
3237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+3]=work[i+1] & 0xffff;
3247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }else{
3257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=3;
3267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=(work[i]>>16 & 0x7fff)|0x8000;
3277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=work[work[i+1]*2];
3287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+2]=work[i] & 0xffff;
3297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
3307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}else{
3317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(work[i+1]&0x80000000UL){
3327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=3;
3337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=work[work[i]*2];
3347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000;
3357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+2]=work[i+1] & 0xffff;
3367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }else{
3377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    top-=2;
3387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top]=work[work[i]*2];
3397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    out[top+1]=work[work[i+1]*2];
3407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  }
3417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
3427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	work[i]=top;
3437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
3447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
3457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
3467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
347ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  free(work);
3487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
349ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissenerror_out:
350ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  free(work);
351ff9b5b2d260b100be4430fb6cd73deabdc732f02Marco Nelissen  return 1;
3527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
3537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* most of the time, entries%dimensions == 0, but we need to be
3557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   well defined.  We define that the possible vales at each
3567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   scalar is values == entries/dim.  If entries%dim != 0, we'll
3577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   have 'too few' values (values*dim<entries), which means that
3587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   we'll have 'left over' entries; left over entries use zeroed
3597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   values (and are wasted).  So don't generate codebooks like
3607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   that */
3617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* there might be a straightforward one-line way to do the below
3627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   that's portable and totally safe against roundoff, but I haven't
3637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang   thought of it.  Therefore, we opt on the side of caution */
3647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong _book_maptype1_quantvals(codebook *b){
3657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* get us a starting hint, we'll polish it below */
3667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int bits=_ilog(b->entries);
3677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim);
3687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  while(1){
3707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    long acc=1;
3717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    long acc1=1;
3727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int i;
3737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<b->dim;i++){
3747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      acc*=vals;
3757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      acc1*=vals+1;
3767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
3777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(acc<=b->entries && acc1>b->entries){
3787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      return(vals);
3797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
3807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(acc>b->entries){
3817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang        vals--;
3827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }else{
3837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang        vals++;
3847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
3857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
3867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
3877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
3887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_book_clear(codebook *b){
3907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* static book is not cleared; we're likely called on the lookup and
3917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang     the static codebook belongs to the info struct */
3927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(b->q_val)_ogg_free(b->q_val);
3937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(b->dec_table)_ogg_free(b->dec_table);
3947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(b->dec_buf)_ogg_free(b->dec_buf);
3957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  memset(b,0,sizeof(*b));
3977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
3987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
3997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_book_unpack(oggpack_buffer *opb,codebook *s){
4007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  char         *lengthlist=NULL;
4017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int           quantvals=0;
4027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long          i,j;
4037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int           maptype;
4047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  memset(s,0,sizeof(*s));
4067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* make sure alignment is correct */
4087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(oggpack_read(opb,24)!=0x564342)goto _eofout;
4097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* first the basic parameters */
4117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  s->dim=oggpack_read(opb,16);
4127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  s->dec_buf=_ogg_malloc(sizeof(ogg_int32_t)*s->dim);
4137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if (s->dec_buf == NULL)
4147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      goto _errout;
4157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  s->entries=oggpack_read(opb,24);
4167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(s->entries<=0)goto _eofout;
4177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(s->dim<=0)goto _eofout;
4187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
4197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if (s->dim > INT_MAX/s->entries) goto _eofout;
4207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* codeword ordering.... length ordered or unordered? */
4227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  switch((int)oggpack_read(opb,1)){
4237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 0:
4247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* unordered */
425afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen    lengthlist=(char *)calloc(s->entries, sizeof(*lengthlist));
4267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(!lengthlist) goto _eofout;
4277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* allocated but unused entries? */
4297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(oggpack_read(opb,1)){
4307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* yes, unused entries */
4317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<s->entries;i++){
4337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(oggpack_read(opb,1)){
4347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  long num=oggpack_read(opb,5);
4357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(num==-1)goto _eofout;
4367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  lengthlist[i]=(char)(num+1);
4377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  s->used_entries++;
4387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if(num+1>s->dec_maxlength)s->dec_maxlength=num+1;
4397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}else
4407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  lengthlist[i]=0;
4417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
4427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
4437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* all entries used; no tagging */
4447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->used_entries=s->entries;
4457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<s->entries;i++){
4467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	long num=oggpack_read(opb,5);
4477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(num==-1)goto _eofout;
4487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	lengthlist[i]=(char)(num+1);
4497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(num+1>s->dec_maxlength)s->dec_maxlength=num+1;
4507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
4517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
4527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
4547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 1:
4557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* ordered */
4567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
4577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      long length=oggpack_read(opb,5)+1;
4587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->used_entries=s->entries;
460afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen      lengthlist=(char *)calloc(s->entries, sizeof(*lengthlist));
4617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if (!lengthlist) goto _eofout;
4627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<s->entries;){
4647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	long num=oggpack_read(opb,_ilog(s->entries-i));
4657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(num<0)goto _eofout;
4667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(j=0;j<num && i<s->entries;j++,i++)
4677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  lengthlist[i]=(char)length;
4687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->dec_maxlength=length;
4697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	length++;
4707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
4717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
4727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
4737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  default:
4747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* EOF */
4757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    goto _eofout;
4767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
4777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* Do we have a mapping to unpack? */
4807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if((maptype=oggpack_read(opb,4))>0){
4827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->q_min=_float32_unpack(oggpack_read(opb,32),&s->q_minp);
4837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->q_del=_float32_unpack(oggpack_read(opb,32),&s->q_delp);
4847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->q_bits=oggpack_read(opb,4)+1;
4857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->q_seq=oggpack_read(opb,1);
4867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->q_del>>=s->q_bits;
4887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->q_delp+=s->q_bits;
4897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
4907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  switch(maptype){
4927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 0:
4937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* no mapping; decode type 0 */
4957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
4967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* how many bytes for the indexing? */
4977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* this is the correct boundary here; we lose one bit to
4987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang       node/leaf mark */
4997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->dec_nodeb=_determine_node_bytes(s->used_entries,_ilog(s->entries)/8+1);
5007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->dec_leafw=_determine_leaf_words(s->dec_nodeb,_ilog(s->entries)/8+1);
5017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->dec_type=0;
5027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)) goto _errout;
5047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
5057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 1:
5077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* mapping type 1; implicit values by lattice  position */
5097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    quantvals=_book_maptype1_quantvals(s);
5107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* dec_type choices here are 1,2; 3 doesn't make sense */
5127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
5137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* packed values */
5147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      long total1=(s->q_bits*s->dim+8)/8; /* remember flag bit */
5157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if (s->dim > (INT_MAX-8)/s->q_bits) goto _eofout;
5167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* vector of column offsets; remember flag bit */
5177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      long total2=(_ilog(quantvals-1)*s->dim+8)/8+(s->q_bits+7)/8;
5187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(total1<=4 && total1<=total2){
5217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	/* use dec_type 1: vector of packed values */
5227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	/* need quantized values before  */
5242e941e40ce76eb13b273479a4ee8fb6e40d33795Marco Nelissen	s->q_val=calloc(sizeof(ogg_uint16_t), quantvals);
5257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if (!s->q_val) goto _eofout;
5267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(i=0;i<quantvals;i++)
5277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits);
5287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(oggpack_eop(opb)){
5307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  goto _eofout;
5317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
5327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->dec_type=1;
5347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->dec_nodeb=_determine_node_bytes(s->used_entries,
5357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					   (s->q_bits*s->dim+8)/8);
5367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->dec_leafw=_determine_leaf_words(s->dec_nodeb,
5377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					   (s->q_bits*s->dim+8)/8);
5387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)){
5397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  goto _errout;
5407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
5417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5422e941e40ce76eb13b273479a4ee8fb6e40d33795Marco Nelissen	free(s->q_val);
5432e941e40ce76eb13b273479a4ee8fb6e40d33795Marco Nelissen	s->q_val=0;
5447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }else{
5467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	/* use dec_type 2: packed vector of column offsets */
5477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	/* need quantized values before */
5497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(s->q_bits<=8){
5507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  s->q_val=_ogg_malloc(quantvals);
5517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if (!s->q_val) goto _eofout;
5527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  for(i=0;i<quantvals;i++)
5537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    ((unsigned char *)s->q_val)[i]=(unsigned char)oggpack_read(opb,s->q_bits);
5547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}else{
5557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  s->q_val=_ogg_malloc(quantvals*2);
5567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  if (!s->q_val) goto _eofout;
5577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  for(i=0;i<quantvals;i++)
5587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	    ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits);
5597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
5607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(oggpack_eop(opb))goto _eofout;
5627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->q_pack=_ilog(quantvals-1);
5647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->dec_type=2;
5657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->dec_nodeb=_determine_node_bytes(s->used_entries,
5667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					   (_ilog(quantvals-1)*s->dim+8)/8);
5677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	s->dec_leafw=_determine_leaf_words(s->dec_nodeb,
5687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang					   (_ilog(quantvals-1)*s->dim+8)/8);
5697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout;
5707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
5727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
5737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
5747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 2:
5757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* mapping type 2; explicit array of values */
5777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    quantvals=s->entries*s->dim;
5787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* dec_type choices here are 1,3; 2 is not possible */
5797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if( (s->q_bits*s->dim+8)/8 <=4){ /* remember flag bit */
5817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* use dec_type 1: vector of packed values */
5827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_type=1;
5847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_nodeb=_determine_node_bytes(s->used_entries,(s->q_bits*s->dim+8)/8);
5857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_leafw=_determine_leaf_words(s->dec_nodeb,(s->q_bits*s->dim+8)/8);
5867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout;
5877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
5897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* use dec_type 3: scalar offset into packed value array */
5907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_type=3;
5927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_nodeb=_determine_node_bytes(s->used_entries,_ilog(s->used_entries-1)/8+1);
5937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_leafw=_determine_leaf_words(s->dec_nodeb,_ilog(s->used_entries-1)/8+1);
5947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout;
5957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
5967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* get the vals & pack them */
5977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->q_pack=(s->q_bits+7)/8*s->dim;
5987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->q_val=_ogg_malloc(s->q_pack*s->used_entries);
5997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(s->q_bits<=8){
6017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(i=0;i<s->used_entries*s->dim;i++)
6027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  ((unsigned char *)(s->q_val))[i]=(unsigned char)oggpack_read(opb,s->q_bits);
6037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }else{
6047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	for(i=0;i<s->used_entries*s->dim;i++)
6057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  ((ogg_uint16_t *)(s->q_val))[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits);
6067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
6077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
6087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
6097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  default:
6107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    goto _errout;
6117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
6127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if (s->dec_nodeb==1)
6147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (s->dec_leafw == 1)
6157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_method = 0;
6167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    else
6177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_method = 1;
6187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  else if (s->dec_nodeb==2)
6197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (s->dec_leafw == 1)
6207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_method = 2;
6217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    else
6227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      s->dec_method = 3;
6237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  else
6247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    s->dec_method = 4;
6257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(oggpack_eop(opb))goto _eofout;
6277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
62897fe197df913aea1a1f436d6e44100ff75a54c82Marco Nelissen  free(lengthlist);
6297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
6307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _errout:
6317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _eofout:
6327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  vorbis_book_clear(s);
633afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen  free(lengthlist);
6342e941e40ce76eb13b273479a4ee8fb6e40d33795Marco Nelissen  free(s->q_val);
6357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return -1;
6367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
6377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef ONLY_C
6397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangogg_uint32_t decode_packed_entry_number(codebook *book,
6407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang                                        oggpack_buffer *b);
6417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
6427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_uint32_t decode_packed_entry_number(codebook *book,
6437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang						      oggpack_buffer *b){
6447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t chase=0;
6457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int  read=book->dec_maxlength;
6467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  long lok = oggpack_look(b,read),i;
6477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  while(lok<0 && read>1)
6497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    lok = oggpack_look(b, --read);
6507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(lok<0){
6527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    oggpack_adv(b,1); /* force eop */
6537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return -1;
6547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
6557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* chase the tree with the bits we got */
6577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  switch (book->dec_method)
6587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  {
6597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    case 0:
6607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
6617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* book->dec_nodeb==1, book->dec_leafw==1 */
6627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* 8/8 - Used */
6637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      unsigned char *t=(unsigned char *)book->dec_table;
6647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
6657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<read;i++){
6667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	chase=t[chase*2+((lok>>i)&1)];
6677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(chase&0x80UL)break;
6687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
6697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      chase&=0x7fUL;
6707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      break;
6717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
6727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    case 1:
6737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
6747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* book->dec_nodeb==1, book->dec_leafw!=1 */
6757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* 8/16 - Used by infile2 */
6767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      unsigned char *t=(unsigned char *)book->dec_table;
6777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<read;i++){
6787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	int bit=(lok>>i)&1;
6797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	int next=t[chase+bit];
6807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(next&0x80){
6817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  chase= (next<<8) | t[chase+bit+1+(!bit || t[chase]&0x80)];
6827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  break;
6837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
6847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	chase=next;
6857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
6867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      //chase&=0x7fffUL;
6877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      chase&=~0x8000UL;
6887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      break;
6897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
6907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    case 2:
6917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
6927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* book->dec_nodeb==2, book->dec_leafw==1 */
6937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* 16/16 - Used */
6947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<read;i++){
6957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	chase=((ogg_uint16_t *)(book->dec_table))[chase*2+((lok>>i)&1)];
6967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(chase&0x8000UL)break;
6977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
6987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      //chase&=0x7fffUL;
6997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      chase&=~0x8000UL;
7007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      break;
7017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
7027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    case 3:
7037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
7047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* book->dec_nodeb==2, book->dec_leafw!=1 */
7057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      /* 16/32 - Used by infile2 */
7067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      ogg_uint16_t *t=(ogg_uint16_t *)book->dec_table;
7077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<read;i++){
7087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	int bit=(lok>>i)&1;
7097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	int next=t[chase+bit];
7107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(next&0x8000){
7117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  chase= (next<<16) | t[chase+bit+1+(!bit || t[chase]&0x8000)];
7127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  break;
7137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
7147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	chase=next;
7157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
7167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      //chase&=0x7fffffffUL;
7177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      chase&=~0x80000000UL;
7187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      break;
7197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
7207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    case 4:
7217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
722d75baf2eee5ddd155009e7f0a79b175ae6026762Gloria Wang      //Output("32/32");
7237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<read;i++){
7247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	chase=((ogg_uint32_t *)(book->dec_table))[chase*2+((lok>>i)&1)];
7257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(chase&0x80000000UL)break;
7267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
7277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      //chase&=0x7fffffffUL;
7287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      chase&=~0x80000000UL;
7297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      break;
7307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
7317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
7327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
7337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(i<read){
7347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    oggpack_adv(b,i+1);
7357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return chase;
7367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
7377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  oggpack_adv(b,read+1);
7387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return(-1);
7397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
7407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
7417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
7427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* returns the [original, not compacted] entry number or -1 on eof *********/
7437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decode(codebook *book, oggpack_buffer *b){
7447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(book->dec_type)return -1;
7457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return decode_packed_entry_number(book,b);
7467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
7477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
7487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef ONLY_C
7497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point);
7507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
7517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point){
7527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  ogg_uint32_t entry = decode_packed_entry_number(s,b);
7537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  int i;
7547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(oggpack_eop(b))return(-1);
7557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
7567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* 1 used by test file 0 */
7577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
7587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* according to decode type */
7597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  switch(s->dec_type){
7607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 1:{
7617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* packed vector of values */
7627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int mask=(1<<s->q_bits)-1;
7637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<s->dim;i++){
7647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      v[i]=entry&mask;
7657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      entry>>=s->q_bits;
7667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
7677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
7687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
7697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 2:{
7707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* packed vector of column offsets */
7717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int mask=(1<<s->q_pack)-1;
7727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<s->dim;i++){
7737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(s->q_bits<=8)
7747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	v[i]=((unsigned char *)(s->q_val))[entry&mask];
7757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      else
7767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	v[i]=((ogg_uint16_t *)(s->q_val))[entry&mask];
7777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      entry>>=s->q_pack;
7787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
7797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
7807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
7817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  case 3:{
7827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    /* offset into array */
7837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    void *ptr=s->q_val+entry*s->q_pack;
7847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
7857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(s->q_bits<=8){
7867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<s->dim;i++)
7877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	v[i]=((unsigned char *)ptr)[i];
7887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }else{
7897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0;i<s->dim;i++)
7907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	v[i]=((ogg_uint16_t *)ptr)[i];
7917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
7927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    break;
7937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
7947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  default:
7957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    return -1;
7967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
7977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
7987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  /* we have the unpacked multiplicands; compute final vals */
7997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  {
8007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int         shiftM = point-s->q_delp;
8017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t add    = point-s->q_minp;
8027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int         mul    = s->q_del;
8037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(add>0)
8057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      add= s->q_min >> add;
8067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    else
8077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      add= s->q_min << -add;
8087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (shiftM<0)
8097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    {
8107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      mul <<= -shiftM;
8117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      shiftM = 0;
8127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
8137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    add <<= shiftM;
8147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<s->dim;i++)
8167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      v[i]= ((add + v[i] * mul) >> shiftM);
8177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if(s->q_seq)
8197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=1;i<s->dim;i++)
8207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	v[i]+=v[i-1];
8217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
8227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
8247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
8257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
8267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* returns 0 on OK or -1 on eof *************************************/
8287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
8297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			      oggpack_buffer *b,int n,int point){
8307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(book->used_entries>0){
8317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int step=n/book->dim;
8327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim);
8337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int i,j,o;
8347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (!v) return -1;
8357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for (j=0;j<step;j++){
8377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(decode_map(book,b,v,point))return -1;
8387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for(i=0,o=j;i<book->dim;i++,o+=step)
8397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	a[o]+=v[i];
8407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
8417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
8427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
8437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
8447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
8467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			     oggpack_buffer *b,int n,int point){
8477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(book->used_entries>0){
8487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim);
8497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int i,j;
8507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (!v) return -1;
8527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<n;){
8537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(decode_map(book,b,v,point))return -1;
8547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for (j=0;j<book->dim;j++)
8557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	a[i++]+=v[j];
8567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
8577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
8587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
8597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
8607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
8627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			     oggpack_buffer *b,int n,int point){
8637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(book->used_entries>0){
8647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim);
8657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int i,j;
8667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (!v) return -1;
8687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<n;){
8697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(decode_map(book,b,v,point))return -1;
8707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for (j=0;j<book->dim;j++)
8717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	a[i++]=v[j];
8727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
8737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }else{
8747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int i,j;
8757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=0;i<n;){
8777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for (j=0;j<book->dim;j++)
8787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	a[i++]=0;
8797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
8807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
8817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
8837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
8847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef ONLY_C
8867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
8877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			      long offset,int ch,
8887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			      oggpack_buffer *b,int n,int point);
8897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else
8907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
8917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			      long offset,int ch,
8927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang			      oggpack_buffer *b,int n,int point){
8937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  if(book->used_entries>0){
8947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim);
8967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    long i,j;
8977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    int chptr=0;
8987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
8997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    if (!v) return -1;
9007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    for(i=offset;i<offset+n;){
9017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      if(decode_map(book,b,v,point))return -1;
9027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      for (j=0;j<book->dim;j++){
9037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	a[chptr++][i]+=v[j];
9047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	if(chptr==ch){
9057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  chptr=0;
9067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	  i++;
9077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang	}
9087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang      }
9097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang    }
9107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  }
9117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang
9127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang  return 0;
9137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang}
9147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif
915