LCOV - app.info - media/libvorbis/lib/vorbis_info.c

LCOV - code coverage report
| Current view: | directory - media/libvorbis/lib - vorbis_info.c (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 375 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 25 | 0 | 0.0 %

           1                 : /********************************************************************
           2                 :  *                                                                  *
           3                 :  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
           4                 :  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
           5                 :  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
           6                 :  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
           7                 :  *                                                                  *
           8                 :  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
           9                 :  * by the Xiph.Org Foundation http://www.xiph.org/                  *
          10                 :  *                                                                  *
          11                 :  ********************************************************************
          12                 :
          13                 :  function: maintain the info structure, info <-> header packets
          14                 :  last mod: $Id: info.c 17584 2010-11-01 19:26:16Z xiphmont $
          15                 :
          16                 :  ********************************************************************/
          17                 :
          18                 : /* general handling of the header and the vorbis_info structure (and
          19                 :    substructures) */
          20                 :
          21                 : #include <stdlib.h>
          22                 : #include <string.h>
          23                 : #include <ctype.h>
          24                 : #include <ogg/ogg.h>
          25                 : #include "vorbis/codec.h"
          26                 : #include "codec_internal.h"
          27                 : #include "codebook.h"
          28                 : #include "registry.h"
          29                 : #include "window.h"
          30                 : #include "psy.h"
          31                 : #include "misc.h"
          32                 : #include "os.h"
          33                 :
          34                 : #define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.2"
          35                 : #define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20101101 (Schaufenugget)"
          36                 :
          37                 : /* helpers */
          38               0 : static int ilog2(unsigned int v){
          39               0 :   int ret=0;
          40               0 :   if(v)--v;
          41               0 :   while(v){
          42               0 :     ret++;
          43               0 :     v>>=1;
          44                 :   }
          45               0 :   return(ret);
          46                 : }
          47                 :
          48               0 : static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){
          49                 :
          50               0 :   while(bytes--){
          51               0 :     oggpack_write(o,*s++,8);
          52                 :   }
          53               0 : }
          54                 :
          55               0 : static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
          56               0 :   while(bytes--){
          57               0 :     *buf++=oggpack_read(o,8);
          58                 :   }
          59               0 : }
          60                 :
          61               0 : void vorbis_comment_init(vorbis_comment *vc){
          62               0 :   memset(vc,0,sizeof(*vc));
          63               0 : }
          64                 :
          65               0 : void vorbis_comment_add(vorbis_comment *vc,const char *comment){
          66               0 :   vc->user_comments=_ogg_realloc(vc->user_comments,
          67               0 :                             (vc->comments+2)*sizeof(*vc->user_comments));
          68               0 :   vc->comment_lengths=_ogg_realloc(vc->comment_lengths,
          69               0 :                                   (vc->comments+2)*sizeof(*vc->comment_lengths));
          70               0 :   vc->comment_lengths[vc->comments]=strlen(comment);
          71               0 :   vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1);
          72               0 :   strcpy(vc->user_comments[vc->comments], comment);
          73               0 :   vc->comments++;
          74               0 :   vc->user_comments[vc->comments]=NULL;
          75               0 : }
          76                 :
          77               0 : void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents){
          78               0 :   char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
          79               0 :   strcpy(comment, tag);
          80               0 :   strcat(comment, "=");
          81               0 :   strcat(comment, contents);
          82               0 :   vorbis_comment_add(vc, comment);
          83               0 : }
          84                 :
          85                 : /* This is more or less the same as strncasecmp - but that doesn't exist
          86                 :  * everywhere, and this is a fairly trivial function, so we include it */
          87               0 : static int tagcompare(const char *s1, const char *s2, int n){
          88               0 :   int c=0;
          89               0 :   while(c < n){
          90               0 :     if(toupper(s1[c]) != toupper(s2[c]))
          91               0 :       return !0;
          92               0 :     c++;
          93                 :   }
          94               0 :   return 0;
          95                 : }
          96                 :
          97               0 : char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count){
          98                 :   long i;
          99               0 :   int found = 0;
         100               0 :   int taglen = strlen(tag)+1; /* +1 for the = we append */
         101               0 :   char *fulltag = alloca(taglen+ 1);
         102                 :
         103               0 :   strcpy(fulltag, tag);
         104               0 :   strcat(fulltag, "=");
         105                 :
         106               0 :   for(i=0;i<vc->comments;i++){
         107               0 :     if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
         108               0 :       if(count == found)
         109                 :         /* We return a pointer to the data, not a copy */
         110               0 :               return vc->user_comments[i] + taglen;
         111                 :       else
         112               0 :         found++;
         113                 :     }
         114                 :   }
         115               0 :   return NULL; /* didn't find anything */
         116                 : }
         117                 :
         118               0 : int vorbis_comment_query_count(vorbis_comment *vc, const char *tag){
         119               0 :   int i,count=0;
         120               0 :   int taglen = strlen(tag)+1; /* +1 for the = we append */
         121               0 :   char *fulltag = alloca(taglen+1);
         122               0 :   strcpy(fulltag,tag);
         123               0 :   strcat(fulltag, "=");
         124                 :
         125               0 :   for(i=0;i<vc->comments;i++){
         126               0 :     if(!tagcompare(vc->user_comments[i], fulltag, taglen))
         127               0 :       count++;
         128                 :   }
         129                 :
         130               0 :   return count;
         131                 : }
         132                 :
         133               0 : void vorbis_comment_clear(vorbis_comment *vc){
         134               0 :   if(vc){
         135                 :     long i;
         136               0 :     if(vc->user_comments){
         137               0 :       for(i=0;i<vc->comments;i++)
         138               0 :         if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
         139               0 :       _ogg_free(vc->user_comments);
         140                 :     }
         141               0 :     if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
         142               0 :     if(vc->vendor)_ogg_free(vc->vendor);
         143               0 :     memset(vc,0,sizeof(*vc));
         144                 :   }
         145               0 : }
         146                 :
         147                 : /* blocksize 0 is guaranteed to be short, 1 is guaranteed to be long.
         148                 :    They may be equal, but short will never ge greater than long */
         149               0 : int vorbis_info_blocksize(vorbis_info *vi,int zo){
         150               0 :   codec_setup_info *ci = vi->codec_setup;
         151               0 :   return ci ? ci->blocksizes[zo] : -1;
         152                 : }
         153                 :
         154                 : /* used by synthesis, which has a full, alloced vi */
         155               0 : void vorbis_info_init(vorbis_info *vi){
         156               0 :   memset(vi,0,sizeof(*vi));
         157               0 :   vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
         158               0 : }
         159                 :
         160               0 : void vorbis_info_clear(vorbis_info *vi){
         161               0 :   codec_setup_info     *ci=vi->codec_setup;
         162                 :   int i;
         163                 :
         164               0 :   if(ci){
         165                 :
         166               0 :     for(i=0;i<ci->modes;i++)
         167               0 :       if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
         168                 :
         169               0 :     for(i=0;i<ci->maps;i++) /* unpack does the range checking */
         170               0 :       if(ci->map_param[i]) /* this may be cleaning up an aborted
         171                 :                               unpack, in which case the below type
         172                 :                               cannot be trusted */
         173               0 :         _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
         174                 :
         175               0 :     for(i=0;i<ci->floors;i++) /* unpack does the range checking */
         176               0 :       if(ci->floor_param[i]) /* this may be cleaning up an aborted
         177                 :                                 unpack, in which case the below type
         178                 :                                 cannot be trusted */
         179               0 :         _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
         180                 :
         181               0 :     for(i=0;i<ci->residues;i++) /* unpack does the range checking */
         182               0 :       if(ci->residue_param[i]) /* this may be cleaning up an aborted
         183                 :                                   unpack, in which case the below type
         184                 :                                   cannot be trusted */
         185               0 :         _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
         186                 :
         187               0 :     for(i=0;i<ci->books;i++){
         188               0 :       if(ci->book_param[i]){
         189                 :         /* knows if the book was not alloced */
         190               0 :         vorbis_staticbook_destroy(ci->book_param[i]);
         191                 :       }
         192               0 :       if(ci->fullbooks)
         193               0 :         vorbis_book_clear(ci->fullbooks+i);
         194                 :     }
         195               0 :     if(ci->fullbooks)
         196               0 :         _ogg_free(ci->fullbooks);
         197                 :
         198               0 :     for(i=0;i<ci->psys;i++)
         199               0 :       _vi_psy_free(ci->psy_param[i]);
         200                 :
         201               0 :     _ogg_free(ci);
         202                 :   }
         203                 :
         204               0 :   memset(vi,0,sizeof(*vi));
         205               0 : }
         206                 :
         207                 : /* Header packing/unpacking ********************************************/
         208                 :
         209               0 : static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
         210               0 :   codec_setup_info     *ci=vi->codec_setup;
         211               0 :   if(!ci)return(OV_EFAULT);
         212                 :
         213               0 :   vi->version=oggpack_read(opb,32);
         214               0 :   if(vi->version!=0)return(OV_EVERSION);
         215                 :
         216               0 :   vi->channels=oggpack_read(opb,8);
         217               0 :   vi->rate=oggpack_read(opb,32);
         218                 :
         219               0 :   vi->bitrate_upper=oggpack_read(opb,32);
         220               0 :   vi->bitrate_nominal=oggpack_read(opb,32);
         221               0 :   vi->bitrate_lower=oggpack_read(opb,32);
         222                 :
         223               0 :   ci->blocksizes[0]=1<<oggpack_read(opb,4);
         224               0 :   ci->blocksizes[1]=1<<oggpack_read(opb,4);
         225                 :
         226               0 :   if(vi->rate<1)goto err_out;
         227               0 :   if(vi->channels<1)goto err_out;
         228               0 :   if(ci->blocksizes[0]<64)goto err_out;
         229               0 :   if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
         230               0 :   if(ci->blocksizes[1]>8192)goto err_out;
         231                 :
         232               0 :   if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
         233                 :
         234               0 :   return(0);
         235                 :  err_out:
         236               0 :   vorbis_info_clear(vi);
         237               0 :   return(OV_EBADHEADER);
         238                 : }
         239                 :
         240               0 : static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
         241                 :   int i;
         242               0 :   int vendorlen=oggpack_read(opb,32);
         243               0 :   if(vendorlen<0)goto err_out;
         244               0 :   if(vendorlen>opb->storage-8)goto err_out;
         245               0 :   vc->vendor=_ogg_calloc(vendorlen+1,1);
         246               0 :   _v_readstring(opb,vc->vendor,vendorlen);
         247               0 :   i=oggpack_read(opb,32);
         248               0 :   if(i<0)goto err_out;
         249               0 :   if(i>((opb->storage-oggpack_bytes(opb))>>2))goto err_out;
         250               0 :   vc->comments=i;
         251               0 :   vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
         252               0 :   vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
         253                 :
         254               0 :   for(i=0;i<vc->comments;i++){
         255               0 :     int len=oggpack_read(opb,32);
         256               0 :     if(len<0)goto err_out;
         257               0 :     if(len>opb->storage-oggpack_bytes(opb))goto err_out;
         258               0 :     vc->comment_lengths[i]=len;
         259               0 :     vc->user_comments[i]=_ogg_calloc(len+1,1);
         260               0 :     _v_readstring(opb,vc->user_comments[i],len);
         261                 :   }
         262               0 :   if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
         263                 :
         264               0 :   return(0);
         265                 :  err_out:
         266               0 :   vorbis_comment_clear(vc);
         267               0 :   return(OV_EBADHEADER);
         268                 : }
         269                 :
         270                 : /* all of the real encoding details are here.  The modes, books,
         271                 :    everything */
         272               0 : static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
         273               0 :   codec_setup_info     *ci=vi->codec_setup;
         274                 :   int i;
         275               0 :   if(!ci)return(OV_EFAULT);
         276                 :
         277                 :   /* codebooks */
         278               0 :   ci->books=oggpack_read(opb,8)+1;
         279               0 :   if(ci->books<=0)goto err_out;
         280               0 :   for(i=0;i<ci->books;i++){
         281               0 :     ci->book_param[i]=vorbis_staticbook_unpack(opb);
         282               0 :     if(!ci->book_param[i])goto err_out;
         283                 :   }
         284                 :
         285                 :   /* time backend settings; hooks are unused */
         286                 :   {
         287               0 :     int times=oggpack_read(opb,6)+1;
         288               0 :     if(times<=0)goto err_out;
         289               0 :     for(i=0;i<times;i++){
         290               0 :       int test=oggpack_read(opb,16);
         291               0 :       if(test<0 || test>=VI_TIMEB)goto err_out;
         292                 :     }
         293                 :   }
         294                 :
         295                 :   /* floor backend settings */
         296               0 :   ci->floors=oggpack_read(opb,6)+1;
         297               0 :   if(ci->floors<=0)goto err_out;
         298               0 :   for(i=0;i<ci->floors;i++){
         299               0 :     ci->floor_type[i]=oggpack_read(opb,16);
         300               0 :     if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
         301               0 :     ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
         302               0 :     if(!ci->floor_param[i])goto err_out;
         303                 :   }
         304                 :
         305                 :   /* residue backend settings */
         306               0 :   ci->residues=oggpack_read(opb,6)+1;
         307               0 :   if(ci->residues<=0)goto err_out;
         308               0 :   for(i=0;i<ci->residues;i++){
         309               0 :     ci->residue_type[i]=oggpack_read(opb,16);
         310               0 :     if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
         311               0 :     ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
         312               0 :     if(!ci->residue_param[i])goto err_out;
         313                 :   }
         314                 :
         315                 :   /* map backend settings */
         316               0 :   ci->maps=oggpack_read(opb,6)+1;
         317               0 :   if(ci->maps<=0)goto err_out;
         318               0 :   for(i=0;i<ci->maps;i++){
         319               0 :     ci->map_type[i]=oggpack_read(opb,16);
         320               0 :     if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
         321               0 :     ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
         322               0 :     if(!ci->map_param[i])goto err_out;
         323                 :   }
         324                 :
         325                 :   /* mode settings */
         326               0 :   ci->modes=oggpack_read(opb,6)+1;
         327               0 :   if(ci->modes<=0)goto err_out;
         328               0 :   for(i=0;i<ci->modes;i++){
         329               0 :     ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i]));
         330               0 :     ci->mode_param[i]->blockflag=oggpack_read(opb,1);
         331               0 :     ci->mode_param[i]->windowtype=oggpack_read(opb,16);
         332               0 :     ci->mode_param[i]->transformtype=oggpack_read(opb,16);
         333               0 :     ci->mode_param[i]->mapping=oggpack_read(opb,8);
         334                 :
         335               0 :     if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
         336               0 :     if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
         337               0 :     if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
         338               0 :     if(ci->mode_param[i]->mapping<0)goto err_out;
         339                 :   }
         340                 :
         341               0 :   if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
         342                 :
         343               0 :   return(0);
         344                 :  err_out:
         345               0 :   vorbis_info_clear(vi);
         346               0 :   return(OV_EBADHEADER);
         347                 : }
         348                 :
         349                 : /* Is this packet a vorbis ID header? */
         350               0 : int vorbis_synthesis_idheader(ogg_packet *op){
         351                 :   oggpack_buffer opb;
         352                 :   char buffer[6];
         353                 :
         354               0 :   if(op){
         355               0 :     oggpack_readinit(&opb,op->packet,op->bytes);
         356                 :
         357               0 :     if(!op->b_o_s)
         358               0 :       return(0); /* Not the initial packet */
         359                 :
         360               0 :     if(oggpack_read(&opb,8) != 1)
         361               0 :       return 0; /* not an ID header */
         362                 :
         363               0 :     memset(buffer,0,6);
         364               0 :     _v_readstring(&opb,buffer,6);
         365               0 :     if(memcmp(buffer,"vorbis",6))
         366               0 :       return 0; /* not vorbis */
         367                 :
         368               0 :     return 1;
         369                 :   }
         370                 :
         371               0 :   return 0;
         372                 : }
         373                 :
         374                 : /* The Vorbis header is in three packets; the initial small packet in
         375                 :    the first page that identifies basic parameters, a second packet
         376                 :    with bitstream comments and a third packet that holds the
         377                 :    codebook. */
         378                 :
         379               0 : int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
         380                 :   oggpack_buffer opb;
         381                 :
         382               0 :   if(op){
         383               0 :     oggpack_readinit(&opb,op->packet,op->bytes);
         384                 :
         385                 :     /* Which of the three types of header is this? */
         386                 :     /* Also verify header-ness, vorbis */
         387                 :     {
         388                 :       char buffer[6];
         389               0 :       int packtype=oggpack_read(&opb,8);
         390               0 :       memset(buffer,0,6);
         391               0 :       _v_readstring(&opb,buffer,6);
         392               0 :       if(memcmp(buffer,"vorbis",6)){
         393                 :         /* not a vorbis header */
         394               0 :         return(OV_ENOTVORBIS);
         395                 :       }
         396               0 :       switch(packtype){
         397                 :       case 0x01: /* least significant *bit* is read first */
         398               0 :         if(!op->b_o_s){
         399                 :           /* Not the initial packet */
         400               0 :           return(OV_EBADHEADER);
         401                 :         }
         402               0 :         if(vi->rate!=0){
         403                 :           /* previously initialized info header */
         404               0 :           return(OV_EBADHEADER);
         405                 :         }
         406                 :
         407               0 :         return(_vorbis_unpack_info(vi,&opb));
         408                 :
         409                 :       case 0x03: /* least significant *bit* is read first */
         410               0 :         if(vi->rate==0){
         411                 :           /* um... we didn't get the initial header */
         412               0 :           return(OV_EBADHEADER);
         413                 :         }
         414                 :
         415               0 :         return(_vorbis_unpack_comment(vc,&opb));
         416                 :
         417                 :       case 0x05: /* least significant *bit* is read first */
         418               0 :         if(vi->rate==0 || vc->vendor==NULL){
         419                 :           /* um... we didn;t get the initial header or comments yet */
         420               0 :           return(OV_EBADHEADER);
         421                 :         }
         422                 :
         423               0 :         return(_vorbis_unpack_books(vi,&opb));
         424                 :
         425                 :       default:
         426                 :         /* Not a valid vorbis header type */
         427               0 :         return(OV_EBADHEADER);
         428                 :         break;
         429                 :       }
         430                 :     }
         431                 :   }
         432               0 :   return(OV_EBADHEADER);
         433                 : }
         434                 :
         435                 : /* pack side **********************************************************/
         436                 :
         437               0 : static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
         438               0 :   codec_setup_info     *ci=vi->codec_setup;
         439               0 :   if(!ci)return(OV_EFAULT);
         440                 :
         441                 :   /* preamble */
         442               0 :   oggpack_write(opb,0x01,8);
         443               0 :   _v_writestring(opb,"vorbis", 6);
         444                 :
         445                 :   /* basic information about the stream */
         446               0 :   oggpack_write(opb,0x00,32);
         447               0 :   oggpack_write(opb,vi->channels,8);
         448               0 :   oggpack_write(opb,vi->rate,32);
         449                 :
         450               0 :   oggpack_write(opb,vi->bitrate_upper,32);
         451               0 :   oggpack_write(opb,vi->bitrate_nominal,32);
         452               0 :   oggpack_write(opb,vi->bitrate_lower,32);
         453                 :
         454               0 :   oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
         455               0 :   oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
         456               0 :   oggpack_write(opb,1,1);
         457                 :
         458               0 :   return(0);
         459                 : }
         460                 :
         461               0 : static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
         462               0 :   int bytes = strlen(ENCODE_VENDOR_STRING);
         463                 :
         464                 :   /* preamble */
         465               0 :   oggpack_write(opb,0x03,8);
         466               0 :   _v_writestring(opb,"vorbis", 6);
         467                 :
         468                 :   /* vendor */
         469               0 :   oggpack_write(opb,bytes,32);
         470               0 :   _v_writestring(opb,ENCODE_VENDOR_STRING, bytes);
         471                 :
         472                 :   /* comments */
         473                 :
         474               0 :   oggpack_write(opb,vc->comments,32);
         475               0 :   if(vc->comments){
         476                 :     int i;
         477               0 :     for(i=0;i<vc->comments;i++){
         478               0 :       if(vc->user_comments[i]){
         479               0 :         oggpack_write(opb,vc->comment_lengths[i],32);
         480               0 :         _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]);
         481                 :       }else{
         482               0 :         oggpack_write(opb,0,32);
         483                 :       }
         484                 :     }
         485                 :   }
         486               0 :   oggpack_write(opb,1,1);
         487                 :
         488               0 :   return(0);
         489                 : }
         490                 :
         491               0 : static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
         492               0 :   codec_setup_info     *ci=vi->codec_setup;
         493                 :   int i;
         494               0 :   if(!ci)return(OV_EFAULT);
         495                 :
         496               0 :   oggpack_write(opb,0x05,8);
         497               0 :   _v_writestring(opb,"vorbis", 6);
         498                 :
         499                 :   /* books */
         500               0 :   oggpack_write(opb,ci->books-1,8);
         501               0 :   for(i=0;i<ci->books;i++)
         502               0 :     if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
         503                 :
         504                 :   /* times; hook placeholders */
         505               0 :   oggpack_write(opb,0,6);
         506               0 :   oggpack_write(opb,0,16);
         507                 :
         508                 :   /* floors */
         509               0 :   oggpack_write(opb,ci->floors-1,6);
         510               0 :   for(i=0;i<ci->floors;i++){
         511               0 :     oggpack_write(opb,ci->floor_type[i],16);
         512               0 :     if(_floor_P[ci->floor_type[i]]->pack)
         513               0 :       _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
         514                 :     else
         515               0 :       goto err_out;
         516                 :   }
         517                 :
         518                 :   /* residues */
         519               0 :   oggpack_write(opb,ci->residues-1,6);
         520               0 :   for(i=0;i<ci->residues;i++){
         521               0 :     oggpack_write(opb,ci->residue_type[i],16);
         522               0 :     _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
         523                 :   }
         524                 :
         525                 :   /* maps */
         526               0 :   oggpack_write(opb,ci->maps-1,6);
         527               0 :   for(i=0;i<ci->maps;i++){
         528               0 :     oggpack_write(opb,ci->map_type[i],16);
         529               0 :     _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
         530                 :   }
         531                 :
         532                 :   /* modes */
         533               0 :   oggpack_write(opb,ci->modes-1,6);
         534               0 :   for(i=0;i<ci->modes;i++){
         535               0 :     oggpack_write(opb,ci->mode_param[i]->blockflag,1);
         536               0 :     oggpack_write(opb,ci->mode_param[i]->windowtype,16);
         537               0 :     oggpack_write(opb,ci->mode_param[i]->transformtype,16);
         538               0 :     oggpack_write(opb,ci->mode_param[i]->mapping,8);
         539                 :   }
         540               0 :   oggpack_write(opb,1,1);
         541                 :
         542               0 :   return(0);
         543                 : err_out:
         544               0 :   return(-1);
         545                 : }
         546                 :
         547               0 : int vorbis_commentheader_out(vorbis_comment *vc,
         548                 :                                           ogg_packet *op){
         549                 :
         550                 :   oggpack_buffer opb;
         551                 :
         552               0 :   oggpack_writeinit(&opb);
         553               0 :   if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL;
         554                 :
         555               0 :   op->packet = _ogg_malloc(oggpack_bytes(&opb));
         556               0 :   memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
         557                 :
         558               0 :   op->bytes=oggpack_bytes(&opb);
         559               0 :   op->b_o_s=0;
         560               0 :   op->e_o_s=0;
         561               0 :   op->granulepos=0;
         562               0 :   op->packetno=1;
         563                 :
         564               0 :   return 0;
         565                 : }
         566                 :
         567               0 : int vorbis_analysis_headerout(vorbis_dsp_state *v,
         568                 :                               vorbis_comment *vc,
         569                 :                               ogg_packet *op,
         570                 :                               ogg_packet *op_comm,
         571                 :                               ogg_packet *op_code){
         572               0 :   int ret=OV_EIMPL;
         573               0 :   vorbis_info *vi=v->vi;
         574                 :   oggpack_buffer opb;
         575               0 :   private_state *b=v->backend_state;
         576                 :
         577               0 :   if(!b){
         578               0 :     ret=OV_EFAULT;
         579               0 :     goto err_out;
         580                 :   }
         581                 :
         582                 :   /* first header packet **********************************************/
         583                 :
         584               0 :   oggpack_writeinit(&opb);
         585               0 :   if(_vorbis_pack_info(&opb,vi))goto err_out;
         586                 :
         587                 :   /* build the packet */
         588               0 :   if(b->header)_ogg_free(b->header);
         589               0 :   b->header=_ogg_malloc(oggpack_bytes(&opb));
         590               0 :   memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
         591               0 :   op->packet=b->header;
         592               0 :   op->bytes=oggpack_bytes(&opb);
         593               0 :   op->b_o_s=1;
         594               0 :   op->e_o_s=0;
         595               0 :   op->granulepos=0;
         596               0 :   op->packetno=0;
         597                 :
         598                 :   /* second header packet (comments) **********************************/
         599                 :
         600               0 :   oggpack_reset(&opb);
         601               0 :   if(_vorbis_pack_comment(&opb,vc))goto err_out;
         602                 :
         603               0 :   if(b->header1)_ogg_free(b->header1);
         604               0 :   b->header1=_ogg_malloc(oggpack_bytes(&opb));
         605               0 :   memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
         606               0 :   op_comm->packet=b->header1;
         607               0 :   op_comm->bytes=oggpack_bytes(&opb);
         608               0 :   op_comm->b_o_s=0;
         609               0 :   op_comm->e_o_s=0;
         610               0 :   op_comm->granulepos=0;
         611               0 :   op_comm->packetno=1;
         612                 :
         613                 :   /* third header packet (modes/codebooks) ****************************/
         614                 :
         615               0 :   oggpack_reset(&opb);
         616               0 :   if(_vorbis_pack_books(&opb,vi))goto err_out;
         617                 :
         618               0 :   if(b->header2)_ogg_free(b->header2);
         619               0 :   b->header2=_ogg_malloc(oggpack_bytes(&opb));
         620               0 :   memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
         621               0 :   op_code->packet=b->header2;
         622               0 :   op_code->bytes=oggpack_bytes(&opb);
         623               0 :   op_code->b_o_s=0;
         624               0 :   op_code->e_o_s=0;
         625               0 :   op_code->granulepos=0;
         626               0 :   op_code->packetno=2;
         627                 :
         628               0 :   oggpack_writeclear(&opb);
         629               0 :   return(0);
         630                 :  err_out:
         631               0 :   memset(op,0,sizeof(*op));
         632               0 :   memset(op_comm,0,sizeof(*op_comm));
         633               0 :   memset(op_code,0,sizeof(*op_code));
         634                 :
         635               0 :   if(b){
         636               0 :     oggpack_writeclear(&opb);
         637               0 :     if(b->header)_ogg_free(b->header);
         638               0 :     if(b->header1)_ogg_free(b->header1);
         639               0 :     if(b->header2)_ogg_free(b->header2);
         640               0 :     b->header=NULL;
         641               0 :     b->header1=NULL;
         642               0 :     b->header2=NULL;
         643                 :   }
         644               0 :   return(ret);
         645                 : }
         646                 :
         647               0 : double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){
         648               0 :   if(granulepos == -1) return -1;
         649                 :
         650                 :   /* We're not guaranteed a 64 bit unsigned type everywhere, so we
         651                 :      have to put the unsigned granpo in a signed type. */
         652               0 :   if(granulepos>=0){
         653               0 :     return((double)granulepos/v->vi->rate);
         654                 :   }else{
         655               0 :     ogg_int64_t granuleoff=0xffffffff;
         656               0 :     granuleoff<<=31;
         657               0 :     granuleoff|=0x7ffffffff;
         658               0 :     return(((double)granulepos+2+granuleoff+granuleoff)/v->vi->rate);
         659                 :   }
         660                 : }
         661                 :
         662               0 : const char *vorbis_version_string(void){
         663               0 :   return GENERAL_VENDOR_STRING;
         664                 : }

Generated by: LCOV version 1.7