examples/sfexamples/oggvorbiscodec/src/libvorbis/lib/info.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: maintain the info structure, info <-> header packets
00014  last mod: $Id: info.c 9513 2005-06-26 18:36:49Z giles $
00015 
00016  ********************************************************************/
00017 
00018 /* general handling of the header and the vorbis_info structure (and
00019    substructures) */
00020 
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <ctype.h>
00024 #include "ogg/ogg.h"
00025 #include "vorbis/codec.h"
00026 #include "codec_internal.h"
00027 #include "codebook.h"
00028 #include "registry.h"
00029 #include "window.h"
00030 #include "psy.h"
00031 #include "misc.h"
00032 #include "os.h"
00033 
00034 /* helpers */
00035 static int ilog2(unsigned int v){
00036   int ret=0;
00037   if(v)--v;
00038   while(v){
00039     ret++;
00040     v>>=1;
00041   }
00042   return(ret);
00043 }
00044 
00045 static void _v_writestring(oggpack_buffer *o,char *s, int bytes){
00046 
00047   while(bytes--){
00048     oggpack_write(o,*s++,8);
00049   }
00050 }
00051 
00052 static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
00053   while(bytes--){
00054     *buf++=oggpack_read(o,8);
00055   }
00056 }
00057 
00058 void vorbis_comment_init(vorbis_comment *vc){
00059   memset(vc,0,sizeof(*vc));
00060 }
00061 
00062 void vorbis_comment_add(vorbis_comment *vc,char *comment){
00063   vc->user_comments=(char**)_ogg_realloc(vc->user_comments,
00064                             (vc->comments+2)*sizeof(*vc->user_comments));
00065   vc->comment_lengths=(int*)_ogg_realloc(vc->comment_lengths,
00066                             (vc->comments+2)*sizeof(*vc->comment_lengths));
00067   vc->comment_lengths[vc->comments]=strlen(comment);
00068   vc->user_comments[vc->comments]=(char*)_ogg_malloc(vc->comment_lengths[vc->comments]+1);
00069   strcpy(vc->user_comments[vc->comments], comment);
00070   vc->comments++;
00071   vc->user_comments[vc->comments]=NULL;
00072 }
00073 
00074 void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){
00075   //char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
00076   char *comment=(char*)_ogg_malloc(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
00077   strcpy(comment, tag);
00078   strcat(comment, "=");
00079   strcat(comment, contents);
00080   vorbis_comment_add(vc, comment);
00081   free(comment); //patch; caution:check for address change
00082 }
00083 
00084 /* This is more or less the same as strncasecmp - but that doesn't exist
00085  * everywhere, and this is a fairly trivial function, so we include it */
00086 static int tagcompare(const char *s1, const char *s2, int n){
00087   int c=0;
00088   while(c < n){
00089     if(toupper(s1[c]) != toupper(s2[c]))
00090       return !0;
00091     c++;
00092   }
00093   return 0;
00094 }
00095 
00096 char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
00097   long i;
00098   int found = 0;
00099   int taglen = strlen(tag)+1; /* +1 for the = we append */
00100   //char *fulltag = alloca(taglen+ 1); //patch
00101   char *fulltag = (char*)_ogg_malloc(taglen+ 1); //patch
00102 
00103   strcpy(fulltag, tag);
00104   strcat(fulltag, "=");
00105   
00106   for(i=0;i<vc->comments;i++){
00107     if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
00108       if(count == found){
00109         free(fulltag); //patch
00110         /* We return a pointer to the data, not a copy */
00111         return vc->user_comments[i] + taglen;
00112       }
00113       else
00114         found++;
00115     }
00116   }
00117   free(fulltag); //patch //caution:check for address change 
00118   return NULL; /* didn't find anything */
00119 }
00120 
00121 int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
00122   int i,count=0;
00123   int taglen = strlen(tag)+1; /* +1 for the = we append */
00124   char *fulltag = (char*)_ogg_malloc(taglen+1);//alloca(taglen+1);//patch
00125   strcpy(fulltag,tag);
00126   strcat(fulltag, "=");
00127 
00128   for(i=0;i<vc->comments;i++){
00129     if(!tagcompare(vc->user_comments[i], fulltag, taglen))
00130       count++;
00131   }
00132   free(fulltag); //patch;caution:check for address change       
00133   return count;
00134 }
00135 
00136 void vorbis_comment_clear(vorbis_comment *vc){
00137   if(vc){
00138     long i;
00139     for(i=0;i<vc->comments;i++)
00140       if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
00141     if(vc->user_comments)_ogg_free(vc->user_comments);
00142         if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
00143     if(vc->vendor)_ogg_free(vc->vendor);
00144   }
00145   memset(vc,0,sizeof(*vc));
00146 }
00147 
00148 /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long.
00149    They may be equal, but short will never ge greater than long */
00150 int vorbis_info_blocksize(vorbis_info *vi,int zo){
00151   codec_setup_info *ci = (codec_setup_info*)vi->codec_setup;
00152   return ci ? ci->blocksizes[zo] : -1;
00153 }
00154 
00155 /* used by synthesis, which has a full, alloced vi */
00156 void vorbis_info_init(vorbis_info *vi){
00157   memset(vi,0,sizeof(*vi));
00158   vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
00159 }
00160 
00161 void vorbis_info_clear(vorbis_info *vi){
00162   codec_setup_info     *ci=(codec_setup_info*)vi->codec_setup;
00163   int i;
00164 
00165   if(ci){
00166 
00167     for(i=0;i<ci->modes;i++)
00168       if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
00169 
00170     for(i=0;i<ci->maps;i++) /* unpack does the range checking */
00171       _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
00172 
00173     for(i=0;i<ci->floors;i++) /* unpack does the range checking */
00174       _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
00175     
00176     for(i=0;i<ci->residues;i++) /* unpack does the range checking */
00177       _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
00178 
00179     for(i=0;i<ci->books;i++){
00180       if(ci->book_param[i]){
00181         /* knows if the book was not alloced */
00182         vorbis_staticbook_destroy(ci->book_param[i]);
00183       }
00184       if(ci->fullbooks)
00185         vorbis_book_clear(ci->fullbooks+i);
00186     }
00187     if(ci->fullbooks)
00188         _ogg_free(ci->fullbooks);
00189     
00190     for(i=0;i<ci->psys;i++)
00191       _vi_psy_free(ci->psy_param[i]);
00192 
00193     _ogg_free(ci);
00194   }
00195 
00196   memset(vi,0,sizeof(*vi));
00197 }
00198 
00199 /* Header packing/unpacking ********************************************/
00200 
00201 static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
00202   codec_setup_info     *ci=(codec_setup_info*)vi->codec_setup;
00203   if(!ci)return(OV_EFAULT);
00204 
00205   vi->version=oggpack_read(opb,32);
00206   if(vi->version!=0)return(OV_EVERSION);
00207 
00208   vi->channels=oggpack_read(opb,8);
00209   vi->rate=oggpack_read(opb,32);
00210 
00211   vi->bitrate_upper=oggpack_read(opb,32);
00212   vi->bitrate_nominal=oggpack_read(opb,32);
00213   vi->bitrate_lower=oggpack_read(opb,32);
00214 
00215   ci->blocksizes[0]=1<<oggpack_read(opb,4);
00216   ci->blocksizes[1]=1<<oggpack_read(opb,4);
00217   
00218   if(vi->rate<1)goto err_out;
00219   if(vi->channels<1)goto err_out;
00220   if(ci->blocksizes[0]<8)goto err_out; 
00221   if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
00222   
00223   if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
00224 
00225   return(0);
00226  err_out:
00227   vorbis_info_clear(vi);
00228   return(OV_EBADHEADER);
00229 }
00230 
00231 static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
00232   int i;
00233   int vendorlen=oggpack_read(opb,32);
00234   if(vendorlen<0)goto err_out;
00235   vc->vendor=(char*)_ogg_calloc(vendorlen+1,1);
00236   _v_readstring(opb,vc->vendor,vendorlen);
00237   vc->comments=oggpack_read(opb,32);
00238   if(vc->comments<0)goto err_out;
00239   vc->user_comments=(char**)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
00240   vc->comment_lengths=(int*)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
00241             
00242   for(i=0;i<vc->comments;i++){
00243     int len=oggpack_read(opb,32);
00244     if(len<0)goto err_out;
00245         vc->comment_lengths[i]=len;
00246     vc->user_comments[i]=(char*)_ogg_calloc(len+1,1);
00247     _v_readstring(opb,vc->user_comments[i],len);
00248   }       
00249   if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
00250 
00251   return(0);
00252  err_out:
00253   vorbis_comment_clear(vc);
00254   return(OV_EBADHEADER);
00255 }
00256 
00257 /* all of the real encoding details are here.  The modes, books,
00258    everything */
00259 static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
00260   codec_setup_info     *ci=(codec_setup_info*)vi->codec_setup;
00261   int i;
00262   if(!ci)return(OV_EFAULT);
00263 
00264   /* codebooks */
00265   ci->books=oggpack_read(opb,8)+1;
00266   /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/
00267   for(i=0;i<ci->books;i++){
00268     ci->book_param[i]=(static_codebook*)_ogg_calloc(1,sizeof(*ci->book_param[i]));
00269     if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
00270   }
00271 
00272   /* time backend settings; hooks are unused */
00273   {
00274     int times=oggpack_read(opb,6)+1;
00275     for(i=0;i<times;i++){
00276       int test=oggpack_read(opb,16);
00277       if(test<0 || test>=VI_TIMEB)goto err_out;
00278     }
00279   }
00280 
00281   /* floor backend settings */
00282   ci->floors=oggpack_read(opb,6)+1;
00283   /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/
00284   /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
00285   for(i=0;i<ci->floors;i++){
00286     ci->floor_type[i]=oggpack_read(opb,16);
00287     if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
00288     ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
00289     if(!ci->floor_param[i])goto err_out;
00290   }
00291 
00292   /* residue backend settings */
00293   ci->residues=oggpack_read(opb,6)+1;
00294   /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/
00295   /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
00296   for(i=0;i<ci->residues;i++){
00297     ci->residue_type[i]=oggpack_read(opb,16);
00298     if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
00299     ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
00300     if(!ci->residue_param[i])goto err_out;
00301   }
00302 
00303   /* map backend settings */
00304   ci->maps=oggpack_read(opb,6)+1;
00305   /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/
00306   /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
00307   for(i=0;i<ci->maps;i++){
00308     ci->map_type[i]=oggpack_read(opb,16);
00309     if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
00310     ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
00311     if(!ci->map_param[i])goto err_out;
00312   }
00313   
00314   /* mode settings */
00315   ci->modes=oggpack_read(opb,6)+1;
00316   /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
00317   for(i=0;i<ci->modes;i++){
00318     ci->mode_param[i]=(vorbis_info_mode*)_ogg_calloc(1,sizeof(*ci->mode_param[i]));
00319     ci->mode_param[i]->blockflag=oggpack_read(opb,1);
00320     ci->mode_param[i]->windowtype=oggpack_read(opb,16);
00321     ci->mode_param[i]->transformtype=oggpack_read(opb,16);
00322     ci->mode_param[i]->mapping=oggpack_read(opb,8);
00323 
00324     if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
00325     if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
00326     if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
00327   }
00328   
00329   if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
00330 
00331   return(0);
00332  err_out:
00333   vorbis_info_clear(vi);
00334   return(OV_EBADHEADER);
00335 }
00336 
00337 /* The Vorbis header is in three packets; the initial small packet in
00338    the first page that identifies basic parameters, a second packet
00339    with bitstream comments and a third packet that holds the
00340    codebook. */
00341 
00342 int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
00343   oggpack_buffer opb;
00344   
00345   if(op){
00346     oggpack_readinit(&opb,op->packet,op->bytes);
00347 
00348     /* Which of the three types of header is this? */
00349     /* Also verify header-ness, vorbis */
00350     {
00351       char buffer[6];
00352       int packtype=oggpack_read(&opb,8);
00353       memset(buffer,0,6);
00354       _v_readstring(&opb,buffer,6);
00355       if(memcmp(buffer,"vorbis",6)){
00356         /* not a vorbis header */
00357         return(OV_ENOTVORBIS);
00358       }
00359       switch(packtype){
00360       case 0x01: /* least significant *bit* is read first */
00361         if(!op->b_o_s){
00362           /* Not the initial packet */
00363           return(OV_EBADHEADER);
00364         }
00365         if(vi->rate!=0){
00366           /* previously initialized info header */
00367           return(OV_EBADHEADER);
00368         }
00369 
00370         return(_vorbis_unpack_info(vi,&opb));
00371 
00372       case 0x03: /* least significant *bit* is read first */
00373         if(vi->rate==0){
00374           /* um... we didn't get the initial header */
00375           return(OV_EBADHEADER);
00376         }
00377 
00378         return(_vorbis_unpack_comment(vc,&opb));
00379 
00380       case 0x05: /* least significant *bit* is read first */
00381         if(vi->rate==0 || vc->vendor==NULL){
00382           /* um... we didn;t get the initial header or comments yet */
00383           return(OV_EBADHEADER);
00384         }
00385 
00386         return(_vorbis_unpack_books(vi,&opb));
00387 
00388       default:
00389         /* Not a valid vorbis header type */
00390         return(OV_EBADHEADER);
00391         //break; //warning
00392       }
00393     }
00394   }
00395   return(OV_EBADHEADER);
00396 }
00397 
00398 /* pack side **********************************************************/
00399 
00400 static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
00401   codec_setup_info     *ci=(codec_setup_info*)vi->codec_setup;
00402   if(!ci)return(OV_EFAULT);
00403 
00404   /* preamble */  
00405   oggpack_write(opb,0x01,8);
00406   _v_writestring(opb,"vorbis", 6);
00407 
00408   /* basic information about the stream */
00409   oggpack_write(opb,0x00,32);
00410   oggpack_write(opb,vi->channels,8);
00411   oggpack_write(opb,vi->rate,32);
00412 
00413   oggpack_write(opb,vi->bitrate_upper,32);
00414   oggpack_write(opb,vi->bitrate_nominal,32);
00415   oggpack_write(opb,vi->bitrate_lower,32);
00416 
00417   oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
00418   oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
00419   oggpack_write(opb,1,1);
00420 
00421   return(0);
00422 }
00423 
00424 static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
00425   char temp[]="Xiph.Org libVorbis I 20050304";
00426   int bytes = strlen(temp);
00427 
00428   /* preamble */  
00429   oggpack_write(opb,0x03,8);
00430   _v_writestring(opb,"vorbis", 6);
00431 
00432   /* vendor */
00433   oggpack_write(opb,bytes,32);
00434   _v_writestring(opb,temp, bytes);
00435   
00436   /* comments */
00437 
00438   oggpack_write(opb,vc->comments,32);
00439   if(vc->comments){
00440     int i;
00441     for(i=0;i<vc->comments;i++){
00442       if(vc->user_comments[i]){
00443         oggpack_write(opb,vc->comment_lengths[i],32);
00444         _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]);
00445       }else{
00446         oggpack_write(opb,0,32);
00447       }
00448     }
00449   }
00450   oggpack_write(opb,1,1);
00451 
00452   return(0);
00453 }
00454  
00455 static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
00456   codec_setup_info     *ci=(codec_setup_info*)vi->codec_setup;
00457   int i;
00458   if(!ci)return(OV_EFAULT);
00459 
00460   oggpack_write(opb,0x05,8);
00461   _v_writestring(opb,"vorbis", 6);
00462 
00463   /* books */
00464   oggpack_write(opb,ci->books-1,8);
00465   for(i=0;i<ci->books;i++)
00466     if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
00467 
00468   /* times; hook placeholders */
00469   oggpack_write(opb,0,6);
00470   oggpack_write(opb,0,16);
00471 
00472   /* floors */
00473   oggpack_write(opb,ci->floors-1,6);
00474   for(i=0;i<ci->floors;i++){
00475     oggpack_write(opb,ci->floor_type[i],16);
00476     if(_floor_P[ci->floor_type[i]]->pack)
00477       _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
00478     else
00479       goto err_out;
00480   }
00481 
00482   /* residues */
00483   oggpack_write(opb,ci->residues-1,6);
00484   for(i=0;i<ci->residues;i++){
00485     oggpack_write(opb,ci->residue_type[i],16);
00486     _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
00487   }
00488 
00489   /* maps */
00490   oggpack_write(opb,ci->maps-1,6);
00491   for(i=0;i<ci->maps;i++){
00492     oggpack_write(opb,ci->map_type[i],16);
00493     _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
00494   }
00495 
00496   /* modes */
00497   oggpack_write(opb,ci->modes-1,6);
00498   for(i=0;i<ci->modes;i++){
00499     oggpack_write(opb,ci->mode_param[i]->blockflag,1);
00500     oggpack_write(opb,ci->mode_param[i]->windowtype,16);
00501     oggpack_write(opb,ci->mode_param[i]->transformtype,16);
00502     oggpack_write(opb,ci->mode_param[i]->mapping,8);
00503   }
00504   oggpack_write(opb,1,1);
00505 
00506   return(0);
00507 err_out:
00508   return(-1);
00509 } 
00510 
00511 int vorbis_commentheader_out(vorbis_comment *vc,
00512                                       ogg_packet *op){
00513 
00514   oggpack_buffer opb;
00515 
00516   oggpack_writeinit(&opb);
00517   if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL;
00518 
00519   op->packet = (unsigned char*)_ogg_malloc(oggpack_bytes(&opb));
00520   memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
00521 
00522   op->bytes=oggpack_bytes(&opb);
00523   op->b_o_s=0;
00524   op->e_o_s=0;
00525   op->granulepos=0;
00526   op->packetno=1;
00527 
00528   return 0;
00529 }
00530 
00531 int vorbis_analysis_headerout(vorbis_dsp_state *v,
00532                               vorbis_comment *vc,
00533                               ogg_packet *op,
00534                               ogg_packet *op_comm,
00535                               ogg_packet *op_code){
00536   int ret=OV_EIMPL;
00537   vorbis_info *vi=v->vi;
00538   oggpack_buffer opb;
00539   private_state *b=(private_state*)v->backend_state;
00540 
00541   if(!b){
00542     ret=OV_EFAULT;
00543     goto err_out;
00544   }
00545 
00546   /* first header packet **********************************************/
00547 
00548   oggpack_writeinit(&opb);
00549   if(_vorbis_pack_info(&opb,vi))goto err_out;
00550 
00551   /* build the packet */
00552   if(b->header)_ogg_free(b->header);
00553   b->header=(unsigned char*)_ogg_malloc(oggpack_bytes(&opb));
00554   memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
00555   op->packet=b->header;
00556   op->bytes=oggpack_bytes(&opb);
00557   op->b_o_s=1;
00558   op->e_o_s=0;
00559   op->granulepos=0;
00560   op->packetno=0;
00561 
00562   /* second header packet (comments) **********************************/
00563 
00564   oggpack_reset(&opb);
00565   if(_vorbis_pack_comment(&opb,vc))goto err_out;
00566 
00567   if(b->header1)_ogg_free(b->header1);
00568   b->header1=(unsigned char*)_ogg_malloc(oggpack_bytes(&opb));
00569   memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
00570   op_comm->packet=b->header1;
00571   op_comm->bytes=oggpack_bytes(&opb);
00572   op_comm->b_o_s=0;
00573   op_comm->e_o_s=0;
00574   op_comm->granulepos=0;
00575   op_comm->packetno=1;
00576 
00577   /* third header packet (modes/codebooks) ****************************/
00578 
00579   oggpack_reset(&opb);
00580   if(_vorbis_pack_books(&opb,vi))goto err_out;
00581 
00582   if(b->header2)_ogg_free(b->header2);
00583   b->header2=(unsigned char*)_ogg_malloc(oggpack_bytes(&opb));
00584   memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
00585   op_code->packet=b->header2;
00586   op_code->bytes=oggpack_bytes(&opb);
00587   op_code->b_o_s=0;
00588   op_code->e_o_s=0;
00589   op_code->granulepos=0;
00590   op_code->packetno=2;
00591 
00592   oggpack_writeclear(&opb);
00593   return(0);
00594  err_out:
00595   oggpack_writeclear(&opb);
00596   memset(op,0,sizeof(*op));
00597   memset(op_comm,0,sizeof(*op_comm));
00598   memset(op_code,0,sizeof(*op_code));
00599 
00600   if(b->header)_ogg_free(b->header);
00601   if(b->header1)_ogg_free(b->header1);
00602   if(b->header2)_ogg_free(b->header2);
00603   b->header=NULL;
00604   b->header1=NULL;
00605   b->header2=NULL;
00606   return(ret);
00607 }
00608 
00609 double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){
00610   if(granulepos>=0)
00611     return((double)granulepos/v->vi->rate);
00612   return(-1);
00613 }

Generated by  doxygen 1.6.2