codebook.c revision afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4a
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 2137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 2147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 2157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int _make_decode_table(codebook *s,char *lengthlist,long quantvals, 2177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *opb,int maptype){ 2187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 2197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_uint32_t *work; 2207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!lengthlist) return 1; 2227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->dec_nodeb==4){ 2237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Over-allocate by using s->entries instead of used_entries. 2247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang * This means that we can use s->entries to enforce size in 2257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang * _make_words without messing up length list looping. 2267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang * This probably wastes a bit of space, but it shouldn't 2277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang * impact behavior or size too much. 2287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang */ 2297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_table=_ogg_malloc((s->entries*2+1)*sizeof(*work)); 2307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!s->dec_table) return 1; 2317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* +1 (rather than -2) is to accommodate 0 and 1 sized books, 2327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang which are specialcased to nodeb==4 */ 2337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_make_words(lengthlist,s->entries, 2347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_table,quantvals,s,opb,maptype))return 1; 2357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 2377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->used_entries > INT_MAX/2 || 2407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->used_entries*2 > INT_MAX/((long) sizeof(*work)) - 1) return 1; 2417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Overallocate as above */ 2427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang work=alloca((s->entries*2+1)*sizeof(*work)); 2437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_make_words(lengthlist,s->entries,work,quantvals,s,opb,maptype))return 1; 2447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->used_entries > INT_MAX/(s->dec_leafw+1)) return 1; 2457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->dec_nodeb && s->used_entries * (s->dec_leafw+1) > INT_MAX/s->dec_nodeb) return 1; 2467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_table=_ogg_malloc((s->used_entries*(s->dec_leafw+1)-2)* 2477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_nodeb); 2487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!s->dec_table) return 1; 2497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->dec_leafw==1){ 2517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang switch(s->dec_nodeb){ 2527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 1: 2537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->used_entries*2-2;i++) 2547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ((unsigned char *)s->dec_table)[i]=(unsigned char) 2557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang (((work[i] & 0x80000000UL) >> 24) | work[i]); 2567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 2577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 2: 2587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->used_entries*2-2;i++) 2597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ((ogg_uint16_t *)s->dec_table)[i]=(ogg_uint16_t) 2607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang (((work[i] & 0x80000000UL) >> 16) | work[i]); 2617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 2627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 2657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* more complex; we have to do a two-pass repack that updates the 2667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang node indexing. */ 2677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long top=s->used_entries*3-2; 2687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->dec_nodeb==1){ 2697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang unsigned char *out=(unsigned char *)s->dec_table; 2707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=s->used_entries*2-4;i>=0;i-=2){ 2727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(work[i]&0x80000000UL){ 2737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(work[i+1]&0x80000000UL){ 2747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=4; 2757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=(work[i]>>8 & 0x7f)|0x80; 2767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=(work[i+1]>>8 & 0x7f)|0x80; 2777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+2]=work[i] & 0xff; 2787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+3]=work[i+1] & 0xff; 2797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 2807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=3; 2817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=(work[i]>>8 & 0x7f)|0x80; 2827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=work[work[i+1]*2]; 2837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+2]=work[i] & 0xff; 2847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 2867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(work[i+1]&0x80000000UL){ 2877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=3; 2887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=work[work[i]*2]; 2897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=(work[i+1]>>8 & 0x7f)|0x80; 2907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+2]=work[i+1] & 0xff; 2917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 2927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=2; 2937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=work[work[i]*2]; 2947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=work[work[i+1]*2]; 2957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang work[i]=top; 2987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 3007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_uint16_t *out=(ogg_uint16_t *)s->dec_table; 3017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=s->used_entries*2-4;i>=0;i-=2){ 3027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(work[i]&0x80000000UL){ 3037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(work[i+1]&0x80000000UL){ 3047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=4; 3057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=(work[i]>>16 & 0x7fff)|0x8000; 3067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000; 3077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+2]=work[i] & 0xffff; 3087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+3]=work[i+1] & 0xffff; 3097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 3107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=3; 3117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=(work[i]>>16 & 0x7fff)|0x8000; 3127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=work[work[i+1]*2]; 3137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+2]=work[i] & 0xffff; 3147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 3167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(work[i+1]&0x80000000UL){ 3177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=3; 3187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=work[work[i]*2]; 3197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000; 3207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+2]=work[i+1] & 0xffff; 3217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 3227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang top-=2; 3237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top]=work[work[i]*2]; 3247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang out[top+1]=work[work[i+1]*2]; 3257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang work[i]=top; 3287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 3337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 3347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* most of the time, entries%dimensions == 0, but we need to be 3367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang well defined. We define that the possible vales at each 3377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang scalar is values == entries/dim. If entries%dim != 0, we'll 3387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang have 'too few' values (values*dim<entries), which means that 3397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang we'll have 'left over' entries; left over entries use zeroed 3407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang values (and are wasted). So don't generate codebooks like 3417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang that */ 3427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* there might be a straightforward one-line way to do the below 3437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang that's portable and totally safe against roundoff, but I haven't 3447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang thought of it. Therefore, we opt on the side of caution */ 3457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong _book_maptype1_quantvals(codebook *b){ 3467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* get us a starting hint, we'll polish it below */ 3477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int bits=_ilog(b->entries); 3487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim); 3497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang while(1){ 3517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long acc=1; 3527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long acc1=1; 3537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 3547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<b->dim;i++){ 3557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang acc*=vals; 3567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang acc1*=vals+1; 3577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(acc<=b->entries && acc1>b->entries){ 3597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(vals); 3607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 3617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(acc>b->entries){ 3627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vals--; 3637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 3647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vals++; 3657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 3697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_book_clear(codebook *b){ 3717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* static book is not cleared; we're likely called on the lookup and 3727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang the static codebook belongs to the info struct */ 3737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(b->q_val)_ogg_free(b->q_val); 3747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(b->dec_table)_ogg_free(b->dec_table); 3757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(b->dec_buf)_ogg_free(b->dec_buf); 3767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang memset(b,0,sizeof(*b)); 3787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 3797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_book_unpack(oggpack_buffer *opb,codebook *s){ 3817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang char *lengthlist=NULL; 3827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int quantvals=0; 3837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long i,j; 3847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int maptype; 3857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang memset(s,0,sizeof(*s)); 3877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* make sure alignment is correct */ 3897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,24)!=0x564342)goto _eofout; 3907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* first the basic parameters */ 3927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dim=oggpack_read(opb,16); 3937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_buf=_ogg_malloc(sizeof(ogg_int32_t)*s->dim); 3947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->dec_buf == NULL) 3957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang goto _errout; 3967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->entries=oggpack_read(opb,24); 3977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->entries<=0)goto _eofout; 3987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->dim<=0)goto _eofout; 3997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout; 4007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->dim > INT_MAX/s->entries) goto _eofout; 4017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* codeword ordering.... length ordered or unordered? */ 4037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang switch((int)oggpack_read(opb,1)){ 4047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 0: 4057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* unordered */ 406afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen lengthlist=(char *)calloc(s->entries, sizeof(*lengthlist)); 4077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!lengthlist) goto _eofout; 4087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* allocated but unused entries? */ 4107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,1)){ 4117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* yes, unused entries */ 4127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->entries;i++){ 4147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,1)){ 4157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long num=oggpack_read(opb,5); 4167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(num==-1)goto _eofout; 4177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang lengthlist[i]=(char)(num+1); 4187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->used_entries++; 4197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; 4207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else 4217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang lengthlist[i]=0; 4227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 4237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 4247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* all entries used; no tagging */ 4257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->used_entries=s->entries; 4267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->entries;i++){ 4277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long num=oggpack_read(opb,5); 4287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(num==-1)goto _eofout; 4297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang lengthlist[i]=(char)(num+1); 4307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; 4317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 4327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 4337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 4357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 1: 4367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* ordered */ 4377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 4387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long length=oggpack_read(opb,5)+1; 4397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->used_entries=s->entries; 441afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen lengthlist=(char *)calloc(s->entries, sizeof(*lengthlist)); 4427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!lengthlist) goto _eofout; 4437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->entries;){ 4457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long num=oggpack_read(opb,_ilog(s->entries-i)); 4467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(num<0)goto _eofout; 4477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(j=0;j<num && i<s->entries;j++,i++) 4487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang lengthlist[i]=(char)length; 4497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_maxlength=length; 4507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang length++; 4517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 4527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 4537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 4547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang default: 4557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* EOF */ 4567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang goto _eofout; 4577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 4587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Do we have a mapping to unpack? */ 4617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if((maptype=oggpack_read(opb,4))>0){ 4637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_min=_float32_unpack(oggpack_read(opb,32),&s->q_minp); 4647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_del=_float32_unpack(oggpack_read(opb,32),&s->q_delp); 4657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_bits=oggpack_read(opb,4)+1; 4667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_seq=oggpack_read(opb,1); 4677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_del>>=s->q_bits; 4697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_delp+=s->q_bits; 4707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 4717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang switch(maptype){ 4737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 0: 4747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* no mapping; decode type 0 */ 4767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* how many bytes for the indexing? */ 4787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* this is the correct boundary here; we lose one bit to 4797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang node/leaf mark */ 4807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_nodeb=_determine_node_bytes(s->used_entries,_ilog(s->entries)/8+1); 4817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_leafw=_determine_leaf_words(s->dec_nodeb,_ilog(s->entries)/8+1); 4827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_type=0; 4837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)) goto _errout; 4857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 4867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 1: 4887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* mapping type 1; implicit values by lattice position */ 4907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang quantvals=_book_maptype1_quantvals(s); 4917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 4927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* dec_type choices here are 1,2; 3 doesn't make sense */ 4937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 4947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* packed values */ 4957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long total1=(s->q_bits*s->dim+8)/8; /* remember flag bit */ 4967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->dim > (INT_MAX-8)/s->q_bits) goto _eofout; 4977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* vector of column offsets; remember flag bit */ 4987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long total2=(_ilog(quantvals-1)*s->dim+8)/8+(s->q_bits+7)/8; 4997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(total1<=4 && total1<=total2){ 5027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* use dec_type 1: vector of packed values */ 5037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* need quantized values before */ 5057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_val=alloca(sizeof(ogg_uint16_t)*quantvals); 5067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!s->q_val) goto _eofout; 5077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<quantvals;i++) 5087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); 5097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_eop(opb)){ 5117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_val=0; /* cleanup must not free alloca memory */ 5127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang goto _eofout; 5137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_type=1; 5167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_nodeb=_determine_node_bytes(s->used_entries, 5177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang (s->q_bits*s->dim+8)/8); 5187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_leafw=_determine_leaf_words(s->dec_nodeb, 5197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang (s->q_bits*s->dim+8)/8); 5207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)){ 5217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_val=0; /* cleanup must not free alloca memory */ 5227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang goto _errout; 5237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_val=0; /* about to go out of scope; _make_decode_table 5267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang was using it */ 5277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 5297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* use dec_type 2: packed vector of column offsets */ 5307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* need quantized values before */ 5327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->q_bits<=8){ 5337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_val=_ogg_malloc(quantvals); 5347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!s->q_val) goto _eofout; 5357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<quantvals;i++) 5367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ((unsigned char *)s->q_val)[i]=(unsigned char)oggpack_read(opb,s->q_bits); 5377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 5387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_val=_ogg_malloc(quantvals*2); 5397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!s->q_val) goto _eofout; 5407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<quantvals;i++) 5417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ((ogg_uint16_t *)s->q_val)[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); 5427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_eop(opb))goto _eofout; 5457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_pack=_ilog(quantvals-1); 5477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_type=2; 5487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_nodeb=_determine_node_bytes(s->used_entries, 5497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang (_ilog(quantvals-1)*s->dim+8)/8); 5507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_leafw=_determine_leaf_words(s->dec_nodeb, 5517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang (_ilog(quantvals-1)*s->dim+8)/8); 5527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout; 5537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 5577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 2: 5587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* mapping type 2; explicit array of values */ 5607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang quantvals=s->entries*s->dim; 5617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* dec_type choices here are 1,3; 2 is not possible */ 5627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if( (s->q_bits*s->dim+8)/8 <=4){ /* remember flag bit */ 5647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* use dec_type 1: vector of packed values */ 5657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_type=1; 5677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_nodeb=_determine_node_bytes(s->used_entries,(s->q_bits*s->dim+8)/8); 5687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_leafw=_determine_leaf_words(s->dec_nodeb,(s->q_bits*s->dim+8)/8); 5697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout; 5707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 5727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* use dec_type 3: scalar offset into packed value array */ 5737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_type=3; 5757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_nodeb=_determine_node_bytes(s->used_entries,_ilog(s->used_entries-1)/8+1); 5767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_leafw=_determine_leaf_words(s->dec_nodeb,_ilog(s->used_entries-1)/8+1); 5777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout; 5787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* get the vals & pack them */ 5807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_pack=(s->q_bits+7)/8*s->dim; 5817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->q_val=_ogg_malloc(s->q_pack*s->used_entries); 5827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->q_bits<=8){ 5847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->used_entries*s->dim;i++) 5857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ((unsigned char *)(s->q_val))[i]=(unsigned char)oggpack_read(opb,s->q_bits); 5867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 5877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->used_entries*s->dim;i++) 5887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ((ogg_uint16_t *)(s->q_val))[i]=(ogg_uint16_t)oggpack_read(opb,s->q_bits); 5897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 5927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang default: 5937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang goto _errout; 5947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 5957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 5967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->dec_nodeb==1) 5977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->dec_leafw == 1) 5987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_method = 0; 5997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 6007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_method = 1; 6017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else if (s->dec_nodeb==2) 6027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (s->dec_leafw == 1) 6037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_method = 2; 6047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 6057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_method = 3; 6067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 6077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang s->dec_method = 4; 6087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 6097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_eop(opb))goto _eofout; 6107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 6117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 6127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _errout: 6137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _eofout: 6147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_book_clear(s); 615afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen free(lengthlist); 6167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return -1; 6177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 6187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 6197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef ONLY_C 6207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangogg_uint32_t decode_packed_entry_number(codebook *book, 6217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *b); 6227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else 6237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic inline ogg_uint32_t decode_packed_entry_number(codebook *book, 6247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *b){ 6257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_uint32_t chase=0; 6267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int read=book->dec_maxlength; 6277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long lok = oggpack_look(b,read),i; 6287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 6297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang while(lok<0 && read>1) 6307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang lok = oggpack_look(b, --read); 6317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 6327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(lok<0){ 6337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_adv(b,1); /* force eop */ 6347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return -1; 6357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 6377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* chase the tree with the bits we got */ 6387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang switch (book->dec_method) 6397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 6407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 0: 6417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 6427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* book->dec_nodeb==1, book->dec_leafw==1 */ 6437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* 8/8 - Used */ 6447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang unsigned char *t=(unsigned char *)book->dec_table; 6457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 6467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<read;i++){ 6477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase=t[chase*2+((lok>>i)&1)]; 6487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(chase&0x80UL)break; 6497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase&=0x7fUL; 6517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 6527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 1: 6547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 6557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* book->dec_nodeb==1, book->dec_leafw!=1 */ 6567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* 8/16 - Used by infile2 */ 6577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang unsigned char *t=(unsigned char *)book->dec_table; 6587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<read;i++){ 6597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int bit=(lok>>i)&1; 6607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int next=t[chase+bit]; 6617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(next&0x80){ 6627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase= (next<<8) | t[chase+bit+1+(!bit || t[chase]&0x80)]; 6637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 6647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase=next; 6667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang //chase&=0x7fffUL; 6687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase&=~0x8000UL; 6697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 6707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 2: 6727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 6737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* book->dec_nodeb==2, book->dec_leafw==1 */ 6747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* 16/16 - Used */ 6757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<read;i++){ 6767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase=((ogg_uint16_t *)(book->dec_table))[chase*2+((lok>>i)&1)]; 6777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(chase&0x8000UL)break; 6787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang //chase&=0x7fffUL; 6807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase&=~0x8000UL; 6817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 6827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 3: 6847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 6857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* book->dec_nodeb==2, book->dec_leafw!=1 */ 6867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* 16/32 - Used by infile2 */ 6877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_uint16_t *t=(ogg_uint16_t *)book->dec_table; 6887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<read;i++){ 6897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int bit=(lok>>i)&1; 6907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int next=t[chase+bit]; 6917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(next&0x8000){ 6927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase= (next<<16) | t[chase+bit+1+(!bit || t[chase]&0x8000)]; 6937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 6947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase=next; 6967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 6977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang //chase&=0x7fffffffUL; 6987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase&=~0x80000000UL; 6997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 7007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 4: 7027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 703d75baf2eee5ddd155009e7f0a79b175ae6026762Gloria Wang //Output("32/32"); 7047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<read;i++){ 7057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase=((ogg_uint32_t *)(book->dec_table))[chase*2+((lok>>i)&1)]; 7067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(chase&0x80000000UL)break; 7077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang //chase&=0x7fffffffUL; 7097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chase&=~0x80000000UL; 7107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 7117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(i<read){ 7157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_adv(b,i+1); 7167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return chase; 7177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_adv(b,read+1); 7197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(-1); 7207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 7217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif 7227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* returns the [original, not compacted] entry number or -1 on eof *********/ 7247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decode(codebook *book, oggpack_buffer *b){ 7257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(book->dec_type)return -1; 7267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return decode_packed_entry_number(book,b); 7277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 7287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef ONLY_C 7307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point); 7317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else 7327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point){ 7337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_uint32_t entry = decode_packed_entry_number(s,b); 7347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 7357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_eop(b))return(-1); 7367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* 1 used by test file 0 */ 7387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* according to decode type */ 7407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang switch(s->dec_type){ 7417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 1:{ 7427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* packed vector of values */ 7437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int mask=(1<<s->q_bits)-1; 7447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->dim;i++){ 7457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v[i]=entry&mask; 7467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang entry>>=s->q_bits; 7477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 7497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 2:{ 7517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* packed vector of column offsets */ 7527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int mask=(1<<s->q_pack)-1; 7537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->dim;i++){ 7547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->q_bits<=8) 7557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v[i]=((unsigned char *)(s->q_val))[entry&mask]; 7567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 7577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v[i]=((ogg_uint16_t *)(s->q_val))[entry&mask]; 7587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang entry>>=s->q_pack; 7597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 7617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 3:{ 7637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* offset into array */ 7647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang void *ptr=s->q_val+entry*s->q_pack; 7657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->q_bits<=8){ 7677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->dim;i++) 7687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v[i]=((unsigned char *)ptr)[i]; 7697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 7707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->dim;i++) 7717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v[i]=((ogg_uint16_t *)ptr)[i]; 7727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 7747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang default: 7767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return -1; 7777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* we have the unpacked multiplicands; compute final vals */ 7807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 7817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int shiftM = point-s->q_delp; 7827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_int32_t add = point-s->q_minp; 7837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int mul = s->q_del; 7847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(add>0) 7867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang add= s->q_min >> add; 7877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 7887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang add= s->q_min << -add; 7897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (shiftM<0) 7907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 7917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang mul <<= -shiftM; 7927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang shiftM = 0; 7937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 7947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang add <<= shiftM; 7957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<s->dim;i++) 7977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v[i]= ((add + v[i] * mul) >> shiftM); 7987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 7997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(s->q_seq) 8007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=1;i<s->dim;i++) 8017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang v[i]+=v[i-1]; 8027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 8057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 8067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif 8077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* returns 0 on OK or -1 on eof *************************************/ 8097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, 8107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *b,int n,int point){ 8117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(book->used_entries>0){ 8127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int step=n/book->dim; 8137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); 8147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i,j,o; 8157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!v) return -1; 8167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for (j=0;j<step;j++){ 8187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(decode_map(book,b,v,point))return -1; 8197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0,o=j;i<book->dim;i++,o+=step) 8207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang a[o]+=v[i]; 8217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 8247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 8257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, 8277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *b,int n,int point){ 8287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(book->used_entries>0){ 8297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); 8307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i,j; 8317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!v) return -1; 8337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<n;){ 8347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(decode_map(book,b,v,point))return -1; 8357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for (j=0;j<book->dim;j++) 8367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang a[i++]+=v[j]; 8377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 8407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 8417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, 8437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *b,int n,int point){ 8447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(book->used_entries>0){ 8457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); 8467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i,j; 8477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!v) return -1; 8497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<n;){ 8507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(decode_map(book,b,v,point))return -1; 8517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for (j=0;j<book->dim;j++) 8527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang a[i++]=v[j]; 8537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang }else{ 8557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i,j; 8567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<n;){ 8587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for (j=0;j<book->dim;j++) 8597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang a[i++]=0; 8607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 8647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 8657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifndef ONLY_C 8677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, 8687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long offset,int ch, 8697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *b,int n,int point); 8707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else 8717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglong vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, 8727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long offset,int ch, 8737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer *b,int n,int point){ 8747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(book->used_entries>0){ 8757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ogg_int32_t *v = book->dec_buf;//(ogg_int32_t *)alloca(sizeof(*v)*book->dim); 8777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long i,j; 8787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int chptr=0; 8797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if (!v) return -1; 8817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=offset;i<offset+n;){ 8827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(decode_map(book,b,v,point))return -1; 8837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for (j=0;j<book->dim;j++){ 8847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang a[chptr++][i]+=v[j]; 8857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(chptr==ch){ 8867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang chptr=0; 8877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang i++; 8887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 8927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 8937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 8947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 8957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif 896