/* also responsible for range checking */ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ int i; vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info)); codec_setup_info *ci=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; for(i=0;i<info->coupling_steps;i++){ int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels)); int testA=info->coupling_ang[i]=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){ for(i=0;i<vi->channels;i++){ info->chmuxlist[i]=oggpack_read(opb,4); if(info->chmuxlist[i]>=info->submaps)goto err_out; } } for(i=0;i<info->submaps;i++){ oggpack_read(opb,8); /* time submap unused */ info->floorsubmap[i]=oggpack_read(opb,8); if(info->floorsubmap[i]>=ci->floors)goto err_out; info->residuesubmap[i]=oggpack_read(opb,8); if(info->residuesubmap[i]>=ci->residues)goto err_out; } return info; err_out: mapping0_free_info(info); return(NULL); }
static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb) { int i; vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info)); codec_setup_info *ci=vi->codec_setup; if(!info) goto err_out; _ogg_memset(info,0,sizeof(*info)); if(oggpack_read1(opb)) info->submaps=oggpack_read24(opb,4)+1; else info->submaps=1; if(oggpack_read1(opb)){ info->coupling_steps=oggpack_read24(opb,8)+1; info->coupling_mag=_ogg_malloc(sizeof(*info->coupling_mag)*info->coupling_steps); info->coupling_ang=_ogg_malloc(sizeof(*info->coupling_ang)*info->coupling_steps); if(!info->coupling_mag || !info->coupling_ang) goto err_out; for(i=0;i<info->coupling_steps;i++){ int testM=info->coupling_mag[i]=oggpack_read24(opb,ilog(vi->channels)); int testA=info->coupling_ang[i]=oggpack_read24(opb,ilog(vi->channels)); if(testM<0 || testA<0 || testM==testA || testM>=vi->channels || testA>=vi->channels) goto err_out; } } if(oggpack_read24(opb,2)!=0) goto err_out; info->chmuxlist=_ogg_calloc(vi->channels,sizeof(*info->chmuxlist)); if(!info->chmuxlist) goto err_out; if(info->submaps>1){ for(i=0;i<vi->channels;i++){ info->chmuxlist[i]=oggpack_read24(opb,4); if(info->chmuxlist[i]>=info->submaps) goto err_out; } } info->floorsubmap=_ogg_malloc(sizeof(*info->floorsubmap)*info->submaps); info->residuesubmap=_ogg_malloc(sizeof(*info->residuesubmap)*info->submaps); if(!info->floorsubmap || !info->residuesubmap) goto err_out; for(i=0;i<info->submaps;i++){ oggpack_adv(opb,8); info->floorsubmap[i]=oggpack_read24(opb,8); if(info->floorsubmap[i]>=ci->floors) goto err_out; info->residuesubmap[i]=oggpack_read24(opb,8); if(info->residuesubmap[i]>=ci->residues) goto err_out; } info->pcmbundle =_ogg_malloc(sizeof(*info->pcmbundle)*vi->channels); info->nonzero =_ogg_malloc(sizeof(*info->nonzero)*vi->channels); info->floormemo =_ogg_malloc(sizeof(*info->floormemo)*vi->channels); if(!info->pcmbundle || !info->nonzero || !info->floormemo) goto err_out; return info; err_out: mapping0_free_info(info); return(NULL); }