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: maintain the info structure, info <-> header packets 357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3637fe158a8611dd11ec0253ab1552399b780988dcGloria Wang ************************************************************************/ 377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* general handling of the header and the vorbis_info structure (and 397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang substructures) */ 407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <stdlib.h> 427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <string.h> 437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include <ctype.h> 447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ogg.h" 457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "ivorbiscodec.h" 467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codec_internal.h" 477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "codebook.h" 487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "misc.h" 497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#include "os.h" 507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* helpers */ 527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ 537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang while(bytes--){ 547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang *buf++=(char)oggpack_read(o,8); 557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_comment_init(vorbis_comment *vc){ 597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang memset(vc,0,sizeof(*vc)); 607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* This is more or less the same as strncasecmp - but that doesn't exist 637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang * everywhere, and this is a fairly trivial function, so we include it */ 647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangstatic int tagcompare(const char *s1, const char *s2, int n){ 657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int c=0; 667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang while(c < n){ 677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(toupper(s1[c]) != toupper(s2[c])) 687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return !0; 697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang c++; 707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return 0; 727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangchar *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ 757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long i; 767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int found = 0; 777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int taglen = strlen(tag)+1; /* +1 for the = we append */ 787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang char *fulltag = (char *)alloca(taglen+ 1); 797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang strcpy(fulltag, tag); 817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang strcat(fulltag, "="); 827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vc->comments;i++){ 847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ 857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(count == found) 867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* We return a pointer to the data, not a copy */ 877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return vc->user_comments[i] + taglen; 887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang found++; 907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return NULL; /* didn't find anything */ 937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_comment_query_count(vorbis_comment *vc, char *tag){ 967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i,count=0; 977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int taglen = strlen(tag)+1; /* +1 for the = we append */ 987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang char *fulltag = (char *)alloca(taglen+1); 997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang strcpy(fulltag,tag); 1007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang strcat(fulltag, "="); 1017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vc->comments;i++){ 1037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!tagcompare(vc->user_comments[i], fulltag, taglen)) 1047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang count++; 1057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return count; 1087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_comment_clear(vorbis_comment *vc){ 1117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vc){ 1127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang long i; 1137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vc->comments;i++) 1147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); 1157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vc->user_comments)_ogg_free(vc->user_comments); 1167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vc->comment_lengths)_ogg_free(vc->comment_lengths); 1177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vc->vendor)_ogg_free(vc->vendor); 1187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang memset(vc,0,sizeof(*vc)); 1207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. 1237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang They may be equal, but short will never ge greater than long */ 1247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_info_blocksize(vorbis_info *vi,int zo){ 1257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci = (codec_setup_info *)vi->codec_setup; 1267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return ci ? ci->blocksizes[zo] : -1; 1277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* used by synthesis, which has a full, alloced vi */ 1307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_info_init(vorbis_info *vi){ 1317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang memset(vi,0,sizeof(*vi)); 1327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info)); 1337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangvoid vorbis_info_clear(vorbis_info *vi){ 1367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 1377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 1387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci){ 1407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->mode_param)_ogg_free(ci->mode_param); 1427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->map_param){ 1447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->maps;i++) /* unpack does the range checking */ 1457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang mapping_clear_info(ci->map_param+i); 1467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(ci->map_param); 1477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->floor_param){ 1507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->floors;i++) /* unpack does the range checking */ 1517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->floor_type[i]) 1527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang floor1_free_info(ci->floor_param[i]); 1537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 1547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang floor0_free_info(ci->floor_param[i]); 1557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(ci->floor_param); 1567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(ci->floor_type); 1577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->residue_param){ 1607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->residues;i++) /* unpack does the range checking */ 1617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang res_clear_info(ci->residue_param+i); 1627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(ci->residue_param); 1637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->book_param){ 1667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->books;i++) 1677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_book_clear(ci->book_param+i); 1687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(ci->book_param); 1697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _ogg_free(ci); 1727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 1737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang memset(vi,0,sizeof(*vi)); 1757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 1767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* Header packing/unpacking ********************************************/ 1787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1791a7ca64dd19ab9a5af3c4c3c58c815f764877bf7Andreas Huberint _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ 1807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 1817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!ci)return(OV_EFAULT); 1827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vi->version=oggpack_read(opb,32); 1847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->version!=0)return(OV_EVERSION); 1857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vi->channels=oggpack_read(opb,8); 1877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vi->rate=oggpack_read(opb,32); 1887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vi->bitrate_upper=oggpack_read(opb,32); 1907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vi->bitrate_nominal=oggpack_read(opb,32); 1917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vi->bitrate_lower=oggpack_read(opb,32); 1927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->blocksizes[0]=1<<oggpack_read(opb,4); 1947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->blocksizes[1]=1<<oggpack_read(opb,4); 1957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#ifdef LIMIT_TO_64kHz 1977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->rate>=64000 || ci->blocksizes[1]>4096)goto err_out; 1987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#else 1997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->rate<64000 && ci->blocksizes[1]>4096)goto err_out; 2007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang#endif 2017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->rate<1)goto err_out; 2037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->channels<1)goto err_out; 2047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->blocksizes[0]<64)goto err_out; 2057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out; 2067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->blocksizes[1]>8192)goto err_out; 2077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ 2097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(0); 2117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang err_out: 2127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_info_clear(vi); 2137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 2147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 2157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2161a7ca64dd19ab9a5af3c4c3c58c815f764877bf7Andreas Huberint _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ 2177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 2187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int vendorlen=oggpack_read(opb,32); 2197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vendorlen<0)goto err_out; 2207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vc->vendor=(char *)_ogg_calloc(vendorlen+1,1); 221afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if(!vc->vendor)goto err_out; 2227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _v_readstring(opb,vc->vendor,vendorlen); 2237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vc->comments=oggpack_read(opb,32); 2247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vc->comments<0)goto err_out; 2257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); 226afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if (!vc->user_comments){ 227afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen vc->comments=0; 228afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen goto err_out; 229afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen } 2307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); 231afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if (!vc->comment_lengths)goto err_out; 2327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<vc->comments;i++){ 2347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int len=oggpack_read(opb,32); 2357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(len<0)goto err_out; 2367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vc->comment_lengths[i]=len; 2377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vc->user_comments[i]=(char *)_ogg_calloc(len+1,1); 238afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if(!vc->user_comments[i])goto err_out; 2397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _v_readstring(opb,vc->user_comments[i],len); 2407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ 2427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(0); 2447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang err_out: 2457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_comment_clear(vc); 2467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 2477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 2487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* all of the real encoding details are here. The modes, books, 2507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang everything */ 2511a7ca64dd19ab9a5af3c4c3c58c815f764877bf7Andreas Huberint _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ 2527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 2537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int i; 2547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!ci)return(OV_EFAULT); 2557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* codebooks */ 2577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->books=oggpack_read(opb,8)+1; 2587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->book_param=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->book_param)); 259afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if(!ci->book_param){ 260afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->books=0; 261afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen goto err_out; 262afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen } 2637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->books;i++) 2647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vorbis_book_unpack(opb,ci->book_param+i))goto err_out; 2657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* time backend settings, not actually used */ 2677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang i=oggpack_read(opb,6); 2687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(;i>=0;i--) 2697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,16)!=0)goto err_out; 2707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* floor backend settings */ 2727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->floors=oggpack_read(opb,6)+1; 273afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->floor_param=_ogg_calloc(ci->floors, sizeof(*ci->floor_param)); 274afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->floor_type=_ogg_calloc(ci->floors, sizeof(*ci->floor_type)); 275afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if(!ci->floor_param || !ci->floor_type){ 276afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->floors=0; 277afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen goto err_out; 278afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen } 2797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->floors;i++){ 2807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->floor_type[i]=(char)oggpack_read(opb,16); 2817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; 2827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->floor_type[i]) 2837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->floor_param[i]=floor1_info_unpack(vi,opb); 2847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang else 2857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->floor_param[i]=floor0_info_unpack(vi,opb); 2867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!ci->floor_param[i])goto err_out; 2877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 2887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* residue backend settings */ 2907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->residues=oggpack_read(opb,6)+1; 291afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->residue_param=_ogg_calloc(ci->residues, sizeof(*ci->residue_param)); 292afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if (!ci->residue_param){ 293afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->residues=0; 294afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen goto err_out; 295afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen } 2967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->residues;i++) 2977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(res_unpack(ci->residue_param+i,vi,opb))goto err_out; 2987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* map backend settings */ 3007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->maps=oggpack_read(opb,6)+1; 301afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->map_param=_ogg_calloc(ci->maps, sizeof(*ci->map_param)); 302afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if (!ci->map_param){ 303afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->maps=0; 304afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen goto err_out; 305afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen } 3067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->maps;i++){ 3077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,16)!=0)goto err_out; 3087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(mapping_info_unpack(ci->map_param+i,vi,opb))goto err_out; 3097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* mode settings */ 3127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->modes=oggpack_read(opb,6)+1; 3137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->mode_param= 314afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen (vorbis_info_mode *)_ogg_calloc(ci->modes, sizeof(*ci->mode_param)); 315afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen if (!ci->mode_param){ 316afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen ci->modes=0; 317afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen goto err_out; 318afa1f6bad4e2a387c6d3889132fcd1c8dc80ae4aMarco Nelissen } 3197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang for(i=0;i<ci->modes;i++){ 3207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->mode_param[i].blockflag=(unsigned char)oggpack_read(opb,1); 3217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,16))goto err_out; 3227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,16))goto err_out; 3237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ci->mode_param[i].mapping=(unsigned char)oggpack_read(opb,8); 3247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(ci->mode_param[i].mapping>=ci->maps)goto err_out; 3257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ 3287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(0); 3307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang err_out: 3317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang vorbis_info_clear(vi); 3327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 3337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 3347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang/* The Vorbis header is in three packets; the initial small packet in 3367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang the first page that identifies basic parameters, a second packet 3377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang with bitstream comments and a third packet that holds the 3387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang codebook. */ 3397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangint vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ 3417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_buffer opb; 3427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(op){ 3447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang oggpack_readinit(&opb,op->packet); 3457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Which of the three types of header is this? */ 3477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Also verify header-ness, vorbis */ 3487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang { 3497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang char buffer[6]; 3507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang int packtype=oggpack_read(&opb,8); 3517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang memset(buffer,0,6); 3527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang _v_readstring(&opb,buffer,6); 3537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(memcmp(buffer,"vorbis",6)){ 3547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* not a vorbis header */ 3557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_ENOTVORBIS); 3567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang switch(packtype){ 3587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 0x01: /* least significant *bit* is read first */ 3597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(!op->b_o_s){ 3607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Not the initial packet */ 3617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 3627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->rate!=0){ 3647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* previously initialized info header */ 3657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 3667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(_vorbis_unpack_info(vi,&opb)); 3697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 0x03: /* least significant *bit* is read first */ 3717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->rate==0){ 3727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* um... we didn't get the initial header */ 3737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 3747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(_vorbis_unpack_comment(vc,&opb)); 3777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang case 0x05: /* least significant *bit* is read first */ 3797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang if(vi->rate==0 || vc->vendor==NULL){ 3807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* um... we didn;t get the initial header or comments yet */ 3817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 3827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(_vorbis_unpack_books(vi,&opb)); 3857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang default: 3877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang /* Not a valid vorbis header type */ 3887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 3897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang break; 3907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang } 3937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang return(OV_EBADHEADER); 3947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang} 3957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 396