info.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:11k
源码类别:

Windows CE

开发平台:

C/C++

  1. /********************************************************************  *                                                                  *  * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *  *                                                                  *  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *  *                                                                  *  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003    *  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *  *                                                                  *  ********************************************************************  function: maintain the info structure, info <-> header packets  ********************************************************************/ /* general handling of the header and the vorbis_info structure (and    substructures) */ #include <stdlib.h> #include <string.h>
  2. //#include <ctype.h> #include "ogg.h" #include "ivorbiscodec.h" #include "codec_internal.h" #include "codebook.h" #include "registry.h" #include "window.h" #include "misc.h" #include "os.h" /* helpers */ static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){   while(bytes--){     *buf++=oggpack_read(o,8);   } } void vorbis_comment_init(vorbis_comment *vc){   memset(vc,0,sizeof(*vc)); } /* This is more or less the same as strncasecmp - but that doesn't exist  * everywhere, and this is a fairly trivial function, so we include it */ static int tagcompare(const char *s1, const char *s2, int n){   int c=0;   while(c < n){     if(toupper(s1[c]) != toupper(s2[c]))       return !0;     c++;   }   return 0; }
  3. //unsafe string handling (Picard)
  4. #if 0
  5. char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){   long i;   int found = 0;   int taglen = strlen(tag)+1; /* +1 for the = we append */   char *fulltag = (char *)alloca(taglen+ 1);   strcpy(fulltag, tag);   strcat(fulltag, "=");      for(i=0;i<vc->comments;i++){     if(!tagcompare(vc->user_comments[i], fulltag, taglen)){       if(count == found) /* We return a pointer to the data, not a copy */        return vc->user_comments[i] + taglen;       else found++;     }   }   return NULL; /* didn't find anything */ } int vorbis_comment_query_count(vorbis_comment *vc, char *tag){   int i,count=0;   int taglen = strlen(tag)+1; /* +1 for the = we append */   char *fulltag = (char *)alloca(taglen+1);   strcpy(fulltag,tag);   strcat(fulltag, "=");   for(i=0;i<vc->comments;i++){     if(!tagcompare(vc->user_comments[i], fulltag, taglen))       count++;   }   return count; } #endif
  6. void vorbis_comment_clear(vorbis_comment *vc){   if(vc){     long i;     for(i=0;i<vc->comments;i++)       if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);     if(vc->user_comments)_ogg_free(vc->user_comments); if(vc->comment_lengths)_ogg_free(vc->comment_lengths);     if(vc->vendor)_ogg_free(vc->vendor);   }   memset(vc,0,sizeof(*vc)); } /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long.    They may be equal, but short will never ge greater than long */ int vorbis_info_blocksize(vorbis_info *vi,int zo){   codec_setup_info *ci = (codec_setup_info *)vi->codec_setup;   return ci ? ci->blocksizes[zo] : -1; } /* used by synthesis, which has a full, alloced vi */ void vorbis_info_init(vorbis_info *vi){   memset(vi,0,sizeof(*vi));   vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info)); } void vorbis_info_clear(vorbis_info *vi){   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;   int i;   if(ci){     for(i=0;i<ci->modes;i++)       if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);     for(i=0;i<ci->maps;i++) /* unpack does the range checking */       _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);     for(i=0;i<ci->floors;i++) /* unpack does the range checking */       _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);          for(i=0;i<ci->residues;i++) /* unpack does the range checking */       _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);     for(i=0;i<ci->books;i++){       if(ci->book_param[i]){ /* knows if the book was not alloced */ vorbis_staticbook_destroy(ci->book_param[i]);       }       if(ci->fullbooks) vorbis_book_clear(ci->fullbooks+i);     }     if(ci->fullbooks) _ogg_free(ci->fullbooks);          _ogg_free(ci);   }   memset(vi,0,sizeof(*vi)); } /* Header packing/unpacking ********************************************/ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;   if(!ci)return(OV_EFAULT);   vi->version=oggpack_read(opb,32);   if(vi->version!=0)return(OV_EVERSION);   vi->channels=oggpack_read(opb,8);   vi->rate=oggpack_read(opb,32);   vi->bitrate_upper=oggpack_read(opb,32);   vi->bitrate_nominal=oggpack_read(opb,32);   vi->bitrate_lower=oggpack_read(opb,32);   ci->blocksizes[0]=1<<oggpack_read(opb,4);   ci->blocksizes[1]=1<<oggpack_read(opb,4);      if(vi->rate<1)goto err_out;   if(vi->channels<1)goto err_out;   if(ci->blocksizes[0]<64)goto err_out;    if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;   if(ci->blocksizes[1]>8192)goto err_out;      if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */   return(0);  err_out:   vorbis_info_clear(vi);   return(OV_EBADHEADER); } int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb,int eop){   int i;   int vendorlen=oggpack_read(opb,32);   if(vendorlen<0)goto err_out;   vc->vendor=(char *)_ogg_calloc(vendorlen+1,1);   _v_readstring(opb,vc->vendor,vendorlen);   vc->comments=oggpack_read(opb,32);   if(vc->comments<0)goto err_out;   vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));   vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));        for(i=0;i<vc->comments;i++){     int len=oggpack_read(opb,32);     if(len<0)goto err_out; vc->comment_lengths[i]=len;     vc->user_comments[i]=(char *)_ogg_calloc(len+1,1);     _v_readstring(opb,vc->user_comments[i],len);   }      if(eop && oggpack_read(opb,1)!=1)goto err_out; /* EOP check */   return(0);  err_out:   vorbis_comment_clear(vc);   return(OV_EBADHEADER); } /* all of the real encoding details are here.  The modes, books,    everything */ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;   int i;   if(!ci)return(OV_EFAULT);   /* codebooks */   ci->books=oggpack_read(opb,8)+1;   /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/   for(i=0;i<ci->books;i++){     ci->book_param[i]=(static_codebook *)_ogg_calloc(1,sizeof(*ci->book_param[i]));     if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;   }   /* time backend settings */   ci->times=oggpack_read(opb,6)+1;   /*ci->time_type=_ogg_malloc(ci->times*sizeof(*ci->time_type));*/   /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/   for(i=0;i<ci->times;i++){     ci->time_type[i]=oggpack_read(opb,16);     if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out;     /* ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb);        Vorbis I has no time backend */     /*if(!ci->time_param[i])goto err_out;*/   }   /* floor backend settings */   ci->floors=oggpack_read(opb,6)+1;   /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/   /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/   for(i=0;i<ci->floors;i++){     ci->floor_type[i]=oggpack_read(opb,16);     if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;     ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);     if(!ci->floor_param[i])goto err_out;   }   /* residue backend settings */   ci->residues=oggpack_read(opb,6)+1;   /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/   /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/   for(i=0;i<ci->residues;i++){     ci->residue_type[i]=oggpack_read(opb,16);     if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;     ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);     if(!ci->residue_param[i])goto err_out;   }   /* map backend settings */   ci->maps=oggpack_read(opb,6)+1;   /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/   /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/   for(i=0;i<ci->maps;i++){     ci->map_type[i]=oggpack_read(opb,16);     if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;     ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);     if(!ci->map_param[i])goto err_out;   }      /* mode settings */   ci->modes=oggpack_read(opb,6)+1;   /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/   for(i=0;i<ci->modes;i++){     ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i]));     ci->mode_param[i]->blockflag=oggpack_read(opb,1);     ci->mode_param[i]->windowtype=oggpack_read(opb,16);     ci->mode_param[i]->transformtype=oggpack_read(opb,16);     ci->mode_param[i]->mapping=oggpack_read(opb,8);     if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;     if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;     if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;   }      if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */   return(0);  err_out:   vorbis_info_clear(vi);   return(OV_EBADHEADER); } /* The Vorbis header is in three packets; the initial small packet in    the first page that identifies basic parameters, a second packet    with bitstream comments and a third packet that holds the    codebook. */ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){   oggpack_buffer opb;      if(op){     oggpack_readinit(&opb,op->packet);     /* Which of the three types of header is this? */     /* Also verify header-ness, vorbis */     {       char buffer[6];       int packtype=oggpack_read(&opb,8);       memset(buffer,0,6);       _v_readstring(&opb,buffer,6);       if(memcmp(buffer,"vorbis",6)){ /* not a vorbis header */ return(OV_ENOTVORBIS);       }       switch(packtype){       case 0x01: /* least significant *bit* is read first */ if(!op->b_o_s){   /* Not the initial packet */   return(OV_EBADHEADER); } if(vi->rate!=0){   /* previously initialized info header */   return(OV_EBADHEADER); } return(_vorbis_unpack_info(vi,&opb));       case 0x03: /* least significant *bit* is read first */ if(vi->rate==0){   /* um... we didn't get the initial header */   return(OV_EBADHEADER); } return(_vorbis_unpack_comment(vc,&opb,1));       case 0x05: /* least significant *bit* is read first */ if(vi->rate==0 || vc->vendor==NULL){   /* um... we didn;t get the initial header or comments yet */   return(OV_EBADHEADER); } return(_vorbis_unpack_books(vi,&opb));       default: /* Not a valid vorbis header type */ return(OV_EBADHEADER); break;       }     }   }   return(OV_EBADHEADER); }