예제 #1
0
/* also responsible for range checking */
int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi,
			oggpack_buffer *opb){
  int i;
  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
  memset(info,0,sizeof(*info));

  if(oggpack_read(opb,1))
    info->submaps=oggpack_read(opb,4)+1;
  else
    info->submaps=1;

  if(oggpack_read(opb,1)){
    info->coupling_steps=oggpack_read(opb,8)+1;
    info->coupling=
      _ogg_malloc(info->coupling_steps*sizeof(*info->coupling));
    
    for(i=0;i<info->coupling_steps;i++){
      int testM=info->coupling[i].mag=oggpack_read(opb,ilog(vi->channels));
      int testA=info->coupling[i].ang=oggpack_read(opb,ilog(vi->channels));

      if(testM<0 || 
	 testA<0 || 
	 testM==testA || 
	 testM>=vi->channels ||
	 testA>=vi->channels) goto err_out;
    }

  }

  if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
    
  if(info->submaps>1){
    info->chmuxlist=_ogg_malloc(sizeof(*info->chmuxlist)*vi->channels);
    for(i=0;i<vi->channels;i++){
      info->chmuxlist[i]=oggpack_read(opb,4);
      if(info->chmuxlist[i]>=info->submaps)goto err_out;
    }
  }

  info->submaplist=_ogg_malloc(sizeof(*info->submaplist)*info->submaps);
  for(i=0;i<info->submaps;i++){
    int temp=oggpack_read(opb,8);
    info->submaplist[i].floor=oggpack_read(opb,8);
    if(info->submaplist[i].floor>=ci->floors)goto err_out;
    info->submaplist[i].residue=oggpack_read(opb,8);
    if(info->submaplist[i].residue>=ci->residues)goto err_out;
  }

  return 0;

 err_out:
  mapping_clear_info(info);
  return -1;
}
예제 #2
0
void vorbis_info_clear(vorbis_info *vi){
  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
  int i;

  if(ci){

    if(ci->mode_param)_ogg_free(ci->mode_param);

    if(ci->map_param){
      for(i=0;i<ci->maps;i++) /* unpack does the range checking */
	mapping_clear_info(ci->map_param+i);
      _ogg_free(ci->map_param);
    }

    if(ci->floor_param){
      for(i=0;i<ci->floors;i++) /* unpack does the range checking */
	if(ci->floor_type[i])
	  floor1_free_info(ci->floor_param[i]);
	else
	  floor0_free_info(ci->floor_param[i]);
      _ogg_free(ci->floor_param);
      _ogg_free(ci->floor_type);
    }

    if(ci->residue_param){
      for(i=0;i<ci->residues;i++) /* unpack does the range checking */
	res_clear_info(ci->residue_param+i);
      _ogg_free(ci->residue_param);
    }

    if(ci->book_param){
      for(i=0;i<ci->books;i++)
	vorbis_book_clear(ci->book_param+i);
      _ogg_free(ci->book_param);
    }
    
    _ogg_free(ci);
  }

  memset(vi,0,sizeof(*vi));
}