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