LCOV - code coverage report
Current view: top level - media/libvorbis/lib - vorbis_info.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 383 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13