Home | History | Annotate | Download | only in Tremolo
      1 /************************************************************************
      2  * Copyright (C) 2002-2009, Xiph.org Foundation
      3  * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  *     * Redistributions of source code must retain the above copyright
     11  * notice, this list of conditions and the following disclaimer.
     12  *     * Redistributions in binary form must reproduce the above
     13  * copyright notice, this list of conditions and the following disclaimer
     14  * in the documentation and/or other materials provided with the
     15  * distribution.
     16  *     * Neither the names of the Xiph.org Foundation nor Pinknoise
     17  * Productions Ltd nor the names of its contributors may be used to
     18  * endorse or promote products derived from this software without
     19  * specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  ************************************************************************
     33 
     34  function: maintain the info structure, info <-> header packets
     35 
     36  ************************************************************************/
     37 
     38 /* general handling of the header and the vorbis_info structure (and
     39    substructures) */
     40 
     41 #include <stdlib.h>
     42 #include <string.h>
     43 #include <ctype.h>
     44 #include "ogg.h"
     45 #include "ivorbiscodec.h"
     46 #include "codec_internal.h"
     47 #include "codebook.h"
     48 #include "misc.h"
     49 #include "os.h"
     50 
     51 /* helpers */
     52 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
     53   while(bytes--){
     54     *buf++=(char)oggpack_read(o,8);
     55   }
     56 }
     57 
     58 void vorbis_comment_init(vorbis_comment *vc){
     59   memset(vc,0,sizeof(*vc));
     60 }
     61 
     62 /* This is more or less the same as strncasecmp - but that doesn't exist
     63  * everywhere, and this is a fairly trivial function, so we include it */
     64 static int tagcompare(const char *s1, const char *s2, int n){
     65   int c=0;
     66   while(c < n){
     67     if(toupper(s1[c]) != toupper(s2[c]))
     68       return !0;
     69     c++;
     70   }
     71   return 0;
     72 }
     73 
     74 char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
     75   long i;
     76   int found = 0;
     77   int taglen = strlen(tag)+1; /* +1 for the = we append */
     78   char *fulltag = (char *)alloca(taglen+ 1);
     79 
     80   strcpy(fulltag, tag);
     81   strcat(fulltag, "=");
     82 
     83   for(i=0;i<vc->comments;i++){
     84     if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
     85       if(count == found)
     86 	/* We return a pointer to the data, not a copy */
     87       	return vc->user_comments[i] + taglen;
     88       else
     89 	found++;
     90     }
     91   }
     92   return NULL; /* didn't find anything */
     93 }
     94 
     95 int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
     96   int i,count=0;
     97   int taglen = strlen(tag)+1; /* +1 for the = we append */
     98   char *fulltag = (char *)alloca(taglen+1);
     99   strcpy(fulltag,tag);
    100   strcat(fulltag, "=");
    101 
    102   for(i=0;i<vc->comments;i++){
    103     if(!tagcompare(vc->user_comments[i], fulltag, taglen))
    104       count++;
    105   }
    106 
    107   return count;
    108 }
    109 
    110 void vorbis_comment_clear(vorbis_comment *vc){
    111   if(vc){
    112     long i;
    113     for(i=0;i<vc->comments;i++)
    114       if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
    115     if(vc->user_comments)_ogg_free(vc->user_comments);
    116 	if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
    117     if(vc->vendor)_ogg_free(vc->vendor);
    118   }
    119   memset(vc,0,sizeof(*vc));
    120 }
    121 
    122 /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long.
    123    They may be equal, but short will never ge greater than long */
    124 int vorbis_info_blocksize(vorbis_info *vi,int zo){
    125   codec_setup_info *ci = (codec_setup_info *)vi->codec_setup;
    126   return ci ? ci->blocksizes[zo] : -1;
    127 }
    128 
    129 /* used by synthesis, which has a full, alloced vi */
    130 void vorbis_info_init(vorbis_info *vi){
    131   memset(vi,0,sizeof(*vi));
    132   vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info));
    133 }
    134 
    135 void vorbis_info_clear(vorbis_info *vi){
    136   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
    137   int i;
    138 
    139   if(ci){
    140 
    141     if(ci->mode_param)_ogg_free(ci->mode_param);
    142 
    143     if(ci->map_param){
    144       for(i=0;i<ci->maps;i++) /* unpack does the range checking */
    145 	mapping_clear_info(ci->map_param+i);
    146       _ogg_free(ci->map_param);
    147     }
    148 
    149     if(ci->floor_param){
    150       for(i=0;i<ci->floors;i++) /* unpack does the range checking */
    151 	if(ci->floor_type[i])
    152 	  floor1_free_info(ci->floor_param[i]);
    153 	else
    154 	  floor0_free_info(ci->floor_param[i]);
    155       _ogg_free(ci->floor_param);
    156       _ogg_free(ci->floor_type);
    157     }
    158 
    159     if(ci->residue_param){
    160       for(i=0;i<ci->residues;i++) /* unpack does the range checking */
    161 	res_clear_info(ci->residue_param+i);
    162       _ogg_free(ci->residue_param);
    163     }
    164 
    165     if(ci->book_param){
    166       for(i=0;i<ci->books;i++)
    167 	vorbis_book_clear(ci->book_param+i);
    168       _ogg_free(ci->book_param);
    169     }
    170 
    171     _ogg_free(ci);
    172   }
    173 
    174   memset(vi,0,sizeof(*vi));
    175 }
    176 
    177 /* Header packing/unpacking ********************************************/
    178 
    179 int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
    180   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
    181   if(!ci)return(OV_EFAULT);
    182 
    183   vi->version=oggpack_read(opb,32);
    184   if(vi->version!=0)return(OV_EVERSION);
    185 
    186   vi->channels=oggpack_read(opb,8);
    187   vi->rate=oggpack_read(opb,32);
    188 
    189   vi->bitrate_upper=oggpack_read(opb,32);
    190   vi->bitrate_nominal=oggpack_read(opb,32);
    191   vi->bitrate_lower=oggpack_read(opb,32);
    192 
    193   ci->blocksizes[0]=1<<oggpack_read(opb,4);
    194   ci->blocksizes[1]=1<<oggpack_read(opb,4);
    195 
    196 #ifdef LIMIT_TO_64kHz
    197   if(vi->rate>=64000 || ci->blocksizes[1]>4096)goto err_out;
    198 #else
    199   if(vi->rate<64000 && ci->blocksizes[1]>4096)goto err_out;
    200 #endif
    201 
    202   if(vi->rate<1)goto err_out;
    203   if(vi->channels<1)goto err_out;
    204   if(ci->blocksizes[0]<64)goto err_out;
    205   if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
    206   if(ci->blocksizes[1]>8192)goto err_out;
    207 
    208   if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
    209 
    210   return(0);
    211  err_out:
    212   vorbis_info_clear(vi);
    213   return(OV_EBADHEADER);
    214 }
    215 
    216 int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
    217   int i;
    218   int vendorlen=oggpack_read(opb,32);
    219   if(vendorlen<0)goto err_out;
    220   vc->vendor=(char *)_ogg_calloc(vendorlen+1,1);
    221   if(!vc->vendor)goto err_out;
    222   _v_readstring(opb,vc->vendor,vendorlen);
    223   vc->comments=oggpack_read(opb,32);
    224   if(vc->comments<0)goto err_out;
    225   vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
    226   if (!vc->user_comments){
    227       vc->comments=0;
    228       goto err_out;
    229   }
    230   vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
    231   if (!vc->comment_lengths)goto err_out;
    232 
    233   for(i=0;i<vc->comments;i++){
    234     int len=oggpack_read(opb,32);
    235     if(len<0)goto err_out;
    236 	vc->comment_lengths[i]=len;
    237     vc->user_comments[i]=(char *)_ogg_calloc(len+1,1);
    238     if(!vc->user_comments[i])goto err_out;
    239     _v_readstring(opb,vc->user_comments[i],len);
    240   }
    241   if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
    242 
    243   return(0);
    244  err_out:
    245   vorbis_comment_clear(vc);
    246   return(OV_EBADHEADER);
    247 }
    248 
    249 /* all of the real encoding details are here.  The modes, books,
    250    everything */
    251 int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
    252   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
    253   int i;
    254   if(!ci)return(OV_EFAULT);
    255 
    256   /* codebooks */
    257   ci->books=oggpack_read(opb,8)+1;
    258   ci->book_param=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->book_param));
    259   if(!ci->book_param){
    260     ci->books=0;
    261     goto err_out;
    262   }
    263   for(i=0;i<ci->books;i++)
    264     if(vorbis_book_unpack(opb,ci->book_param+i))goto err_out;
    265 
    266   /* time backend settings, not actually used */
    267   i=oggpack_read(opb,6);
    268   for(;i>=0;i--)
    269     if(oggpack_read(opb,16)!=0)goto err_out;
    270 
    271   /* floor backend settings */
    272   ci->floors=oggpack_read(opb,6)+1;
    273   ci->floor_param=_ogg_calloc(ci->floors, sizeof(*ci->floor_param));
    274   ci->floor_type=_ogg_calloc(ci->floors, sizeof(*ci->floor_type));
    275   if(!ci->floor_param || !ci->floor_type){
    276     ci->floors=0;
    277     goto err_out;
    278   }
    279   for(i=0;i<ci->floors;i++){
    280     ci->floor_type[i]=(char)oggpack_read(opb,16);
    281     if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
    282     if(ci->floor_type[i])
    283       ci->floor_param[i]=floor1_info_unpack(vi,opb);
    284     else
    285       ci->floor_param[i]=floor0_info_unpack(vi,opb);
    286     if(!ci->floor_param[i])goto err_out;
    287   }
    288 
    289   /* residue backend settings */
    290   ci->residues=oggpack_read(opb,6)+1;
    291   ci->residue_param=_ogg_calloc(ci->residues, sizeof(*ci->residue_param));
    292   if (!ci->residue_param){
    293     ci->residues=0;
    294     goto err_out;
    295   }
    296   for(i=0;i<ci->residues;i++)
    297     if(res_unpack(ci->residue_param+i,vi,opb))goto err_out;
    298 
    299   /* map backend settings */
    300   ci->maps=oggpack_read(opb,6)+1;
    301   ci->map_param=_ogg_calloc(ci->maps, sizeof(*ci->map_param));
    302   if (!ci->map_param){
    303     ci->maps=0;
    304     goto err_out;
    305   }
    306   for(i=0;i<ci->maps;i++){
    307     if(oggpack_read(opb,16)!=0)goto err_out;
    308     if(mapping_info_unpack(ci->map_param+i,vi,opb))goto err_out;
    309   }
    310 
    311   /* mode settings */
    312   ci->modes=oggpack_read(opb,6)+1;
    313   ci->mode_param=
    314     (vorbis_info_mode *)_ogg_calloc(ci->modes, sizeof(*ci->mode_param));
    315   if (!ci->mode_param){
    316     ci->modes=0;
    317     goto err_out;
    318   }
    319   for(i=0;i<ci->modes;i++){
    320     ci->mode_param[i].blockflag=(unsigned char)oggpack_read(opb,1);
    321     if(oggpack_read(opb,16))goto err_out;
    322     if(oggpack_read(opb,16))goto err_out;
    323     ci->mode_param[i].mapping=(unsigned char)oggpack_read(opb,8);
    324     if(ci->mode_param[i].mapping>=ci->maps)goto err_out;
    325   }
    326 
    327   if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
    328 
    329   return(0);
    330  err_out:
    331   vorbis_info_clear(vi);
    332   return(OV_EBADHEADER);
    333 }
    334 
    335 /* The Vorbis header is in three packets; the initial small packet in
    336    the first page that identifies basic parameters, a second packet
    337    with bitstream comments and a third packet that holds the
    338    codebook. */
    339 
    340 int vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
    341   oggpack_buffer opb;
    342 
    343   if(op){
    344     oggpack_readinit(&opb,op->packet);
    345 
    346     /* Which of the three types of header is this? */
    347     /* Also verify header-ness, vorbis */
    348     {
    349       char buffer[6];
    350       int packtype=oggpack_read(&opb,8);
    351       memset(buffer,0,6);
    352       _v_readstring(&opb,buffer,6);
    353       if(memcmp(buffer,"vorbis",6)){
    354 	/* not a vorbis header */
    355 	return(OV_ENOTVORBIS);
    356       }
    357       switch(packtype){
    358       case 0x01: /* least significant *bit* is read first */
    359 	if(!op->b_o_s){
    360 	  /* Not the initial packet */
    361 	  return(OV_EBADHEADER);
    362 	}
    363 	if(vi->rate!=0){
    364 	  /* previously initialized info header */
    365 	  return(OV_EBADHEADER);
    366 	}
    367 
    368 	return(_vorbis_unpack_info(vi,&opb));
    369 
    370       case 0x03: /* least significant *bit* is read first */
    371 	if(vi->rate==0){
    372 	  /* um... we didn't get the initial header */
    373 	  return(OV_EBADHEADER);
    374 	}
    375 
    376 	return(_vorbis_unpack_comment(vc,&opb));
    377 
    378       case 0x05: /* least significant *bit* is read first */
    379 	if(vi->rate==0 || vc->vendor==NULL){
    380 	  /* um... we didn;t get the initial header or comments yet */
    381 	  return(OV_EBADHEADER);
    382 	}
    383 
    384 	return(_vorbis_unpack_books(vi,&opb));
    385 
    386       default:
    387 	/* Not a valid vorbis header type */
    388 	return(OV_EBADHEADER);
    389 	break;
    390       }
    391     }
    392   }
    393   return(OV_EBADHEADER);
    394 }
    395 
    396