static void floor1_free_look(vorbis_look_floor *i) { vorbis_look_floor1 *look=(vorbis_look_floor1 *)i; if(look) { /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n", (float)look->phrasebits/look->frames, (float)look->postbits/look->frames, (float)(look->postbits+look->phrasebits)/look->frames);*/ memset(look,0,sizeof(*look)); _ogg_free(look); } }
/* reap the chain, pull the ripcord */ void _vorbis_block_ripcord(vorbis_block *vb){ /* reap the chain */ struct alloc_chain *reap=vb->reap; while(reap){ struct alloc_chain *next=reap->next; _ogg_free(reap->ptr); memset(reap,0,sizeof(*reap)); _ogg_free(reap); reap=next; } /* consolidate storage */ if(vb->totaluse){ vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); vb->localalloc+=vb->totaluse; vb->totaluse=0; } /* pull the ripcord */ vb->localtop=0; vb->reap=NULL; }
/* clear out the OggVorbis_File struct */ int ov_clear(OggVorbis_File *vf){ if(vf){ vorbis_block_clear(&vf->vb); vorbis_dsp_clear(&vf->vd); ogg_stream_clear(&vf->os); if(vf->vi && vf->links){ int i; for(i=0;i<vf->links;i++){ vorbis_info_clear(vf->vi+i); vorbis_comment_clear(vf->vc+i); } _ogg_free(vf->vi); _ogg_free(vf->vc); } if(vf->dataoffsets)_ogg_free(vf->dataoffsets); if(vf->pcmlengths)_ogg_free(vf->pcmlengths); if(vf->serialnos)_ogg_free(vf->serialnos); if(vf->offsets)_ogg_free(vf->offsets); ogg_sync_clear(&vf->oy); if(vf->datasource)(vf->callbacks.close_func)(vf->datasource); memset(vf,0,sizeof(*vf)); } #ifdef DEBUG_LEAKS _VDBG_dump(); #endif return(0); }
/* given a list of word lengths, generate a list of codewords. Works for length ordered or unordered, always assigns the lowest valued codewords first. Extended to handle unused entries (length 0) */ static ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ long i,j,count=0; ogg_uint32_t marker[33]; ogg_uint32_t *r=_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); memset(marker,0,sizeof(marker)); for(i=0;i<n;i++){ long length=l[i]; if(length>0){ ogg_uint32_t entry=marker[length]; /* when we claim a node for an entry, we also claim the nodes below it (pruning off the imagined tree that may have dangled from it) as well as blocking the use of any nodes directly above for leaves */ /* update ourself */ if(length<32 && (entry>>length)){ /* error condition; the lengths must specify an overpopulated tree */ _ogg_free(r); return(NULL); } r[count++]=entry; /* Look to see if the next shorter marker points to the node above. if so, update it and repeat. */ { for(j=length;j>0;j--){ if(marker[j]&1){ /* have to jump branches */ if(j==1) marker[1]++; else marker[j]=marker[j-1]<<1; break; /* invariant says next upper marker would already have been moved if it was on the same path */ } marker[j]++; } } /* prune the tree; the implicit invariant says all the longer markers were dangling from our just-taken node. Dangle them from our *new* node. */ for(j=length+1;j<33;j++) if((marker[j]>>1) == entry){ entry=marker[j]; marker[j]=marker[j-1]<<1; }else break; }else
int vorbis_analysis_headerout(vorbis_dsp_state *v, ogg_packet *op_code) { int ret=OV_EIMPL; vorbis_info *vi=v->vi; oggpack_buffer opb; private_state *b=v->backend_state; if(!b){ ret=OV_EFAULT; goto err_out; } oggpack_writeinit(&opb); /* third header packet (modes/codebooks) ****************************/ oggpack_reset(&opb); if(_vorbis_pack_books(&opb,vi))goto err_out; if(b->header2)_ogg_free(b->header2); b->header2=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); op_code->packet=b->header2; op_code->bytes=oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; op_code->granulepos=0; oggpack_writeclear(&opb); return(0); err_out: oggpack_writeclear(&opb); memset(op_code,0,sizeof(*op_code)); if(b->header2)_ogg_free(b->header2); b->header2=NULL; return(ret); }
int vorbis_block_clear( vorbis_block *vb ) { int i; vorbis_block_internal *vbi = vb->internal; _vorbis_block_ripcord( vb ); if ( vb->localstore ) _ogg_free( vb->localstore ); if ( vbi ) { for ( i = 0;i < PACKETBLOBS;i++ ) { oggpack_writeclear( vbi->packetblob[i] ); if ( i != PACKETBLOBS / 2 ) _ogg_free( vbi->packetblob[i] ); } _ogg_free( vbi ); } memset( vb, 0, sizeof( *vb ) ); return( 0 ); }
char *theora_comment_query(theora_comment *tc, char *tag, int count){ long i; int found = 0; int taglen = strlen(tag)+1; /* +1 for the = we append */ char *fulltag = _ogg_malloc(taglen+ 1); strcpy(fulltag, tag); strcat(fulltag, "="); for(i=0;i<tc->comments;i++){ if(!tagcompare(tc->user_comments[i], fulltag, taglen)){ if(count == found){ _ogg_free(fulltag); /* We return a pointer to the data, not a copy */ return tc->user_comments[i] + taglen; } else found++; } } _ogg_free(fulltag); return NULL; /* didn't find anything */ }
void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){ char *comment; int tag_len; int val_len; tag_len=strlen(_tag); val_len=strlen(_val); /*+2 for '=' and '\0'.*/ comment=_ogg_malloc(tag_len+val_len+2); memcpy(comment,_tag,tag_len); comment[tag_len]='='; memcpy(comment+tag_len+1,_val,val_len+1); th_comment_add(_tc,comment); _ogg_free(comment); }
int theora_comment_query_count(theora_comment *tc, char *tag){ int i,count=0; int taglen = strlen(tag)+1; /* +1 for the = we append */ char *fulltag = _ogg_malloc(taglen+1); strcpy(fulltag,tag); strcat(fulltag, "="); for(i=0;i<tc->comments;i++){ if(!tagcompare(tc->user_comments[i], fulltag, taglen)) count++; } _ogg_free(fulltag); return count; }
void oc_quant_params_clear(th_quant_info *_qinfo){ int i; for(i=6;i-->0;){ int qti; int pli; qti=i/3; pli=i%3; /*Clear any duplicate pointer references.*/ if(i>0){ int qtj; int plj; qtj=(i-1)/3; plj=(i-1)%3; if(_qinfo->qi_ranges[qti][pli].sizes== _qinfo->qi_ranges[qtj][plj].sizes){ _qinfo->qi_ranges[qti][pli].sizes=NULL; } if(_qinfo->qi_ranges[qti][pli].base_matrices== _qinfo->qi_ranges[qtj][plj].base_matrices){ _qinfo->qi_ranges[qti][pli].base_matrices=NULL; } } if(qti>0){ if(_qinfo->qi_ranges[1][pli].sizes== _qinfo->qi_ranges[0][pli].sizes){ _qinfo->qi_ranges[1][pli].sizes=NULL; } if(_qinfo->qi_ranges[1][pli].base_matrices== _qinfo->qi_ranges[0][pli].base_matrices){ _qinfo->qi_ranges[1][pli].base_matrices=NULL; } } /*Now free all the non-duplicate storage.*/ _ogg_free((void *)_qinfo->qi_ranges[qti][pli].sizes); _ogg_free((void *)_qinfo->qi_ranges[qti][pli].base_matrices); } }
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 */ if(ci->map_param[i]) _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); for(i=0;i<ci->floors;i++) /* unpack does the range checking */ if(ci->floor_param[i]) _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); for(i=0;i<ci->residues;i++) /* unpack does the range checking */ if(ci->residue_param[i]) _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)); }
/*Makes a copy of the given set of Huffman trees. _dst: The array to store the copy in. _src: The array of trees to copy.*/ int oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES], const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]){ int i; for(i=0;i<TH_NHUFFMAN_TABLES;i++){ size_t size; char *storage; size=oc_huff_tree_size(_src[i]); storage=(char *)_ogg_calloc(1,size); if(storage==NULL){ while(i-->0)_ogg_free(_dst[i]); return TH_EFAULT; } _dst[i]=oc_huff_tree_copy(_src[i],&storage); } return 0; }
void vorbis_dsp_clear(vorbis_dsp_state *v) { int i; if(v){ vorbis_info *vi=v->vi; codec_setup_info *ci=(vi?vi->codec_setup:NULL); backend_lookup_state *b=v->backend_state; if(b){ if(b->window[0]) _ogg_free(b->window[0]); if(b->window[1]) _ogg_free(b->window[1]); oggdec_mdct_clear(b->transform[0]); oggdec_mdct_clear(b->transform[1]); if(b->flr && ci){ for(i=0;i<ci->floors;i++) _floor_P[ci->floor_type[i]]->free_look(b->flr[i]); _ogg_free(b->flr); } if(b->residue && ci){ for(i=0;i<ci->residues;i++) _residue_P[ci->residue_type[i]]->free_look(b->residue[i]); _ogg_free(b->residue); } _ogg_free(b); } if(v->pcm && vi){ for(i=0;i<vi->channels;i++) if(v->pcm[i]) _ogg_free(v->pcm[i]); _ogg_free(v->pcm); } if(v->pcmret) _ogg_free(v->pcmret); _ogg_memset(v,0,sizeof(*v)); } }
/* build the comment header packet from the passed metadata */ int theora_encode_comment(theora_comment *tc, ogg_packet *op) { const char *vendor = theora_version_string(); const int vendor_length = strlen(vendor); oggpack_buffer *opb; opb = _ogg_malloc(sizeof(oggpack_buffer)); oggpackB_writeinit(opb); oggpackB_write(opb, 0x81, 8); _tp_writebuffer(opb, "theora", 6); _tp_writelsbint(opb, vendor_length); _tp_writebuffer(opb, vendor, vendor_length); _tp_writelsbint(opb, tc->comments); if(tc->comments){ int i; for(i=0;i<tc->comments;i++){ if(tc->user_comments[i]){ _tp_writelsbint(opb,tc->comment_lengths[i]); _tp_writebuffer(opb,tc->user_comments[i],tc->comment_lengths[i]); }else{ oggpackB_write(opb,0,32); } } } op->bytes=oggpack_bytes(opb); /* So we're expecting the application will free this? */ op->packet=_ogg_malloc(oggpack_bytes(opb)); memcpy(op->packet, oggpack_get_buffer(opb), oggpack_bytes(opb)); oggpack_writeclear(opb); _ogg_free(opb); op->b_o_s=0; op->e_o_s=0; op->packetno=0; op->granulepos=0; return (0); }
void _vp_psy_clear(vorbis_look_psy *p){ int i,j; if(p){ if(p->ath)_ogg_free(p->ath); if(p->octave)_ogg_free(p->octave); if(p->bark)_ogg_free(p->bark); if(p->tonecurves){ for(i=0;i<P_BANDS;i++){ for(j=0;j<P_LEVELS;j++){ _ogg_free(p->tonecurves[i][j]); } _ogg_free(p->tonecurves[i]); } _ogg_free(p->tonecurves); _ogg_free(p->noiseoffset); } memset(p,0,sizeof(vorbis_look_psy)); } }
float *_vorbis_window(int type, int window,int left,int right){ float *ret=_ogg_calloc(window,sizeof(float)); switch(type){ case 0: /* The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi) */ { int leftbegin=window/4-left/2; int rightbegin=window-window/4-right/2; int i; for(i=0;i<left;i++){ float x=(i+.5f)/left*M_PI/2.; x=sin(x); x*=x; x*=M_PI/2.f; x=sin(x); ret[i+leftbegin]=x; } for(i=leftbegin+left;i<rightbegin;i++) ret[i]=1.f; for(i=0;i<right;i++){ float x=(right-i-.5f)/right*M_PI/2.; x=sin(x); x*=x; x*=M_PI/2.f; x=sin(x); ret[i+rightbegin]=x; } } break; default: _ogg_free(ret); return(NULL); } return(ret); }
void theora_clear(theora_state *t){ if(t){ CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode); PB_INSTANCE *pbi=(PB_INSTANCE *)(t->internal_decode); if (cpi) theora_encoder_clear (cpi); if(pbi){ theora_info_clear(&pbi->info); ClearHuffmanSet(pbi); ClearFragmentInfo(pbi); ClearFrameInfo(pbi); ClearPBInstance(pbi); _ogg_free(t->internal_decode); } t->internal_encode=NULL; t->internal_decode=NULL; } }
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)); }
static ogg_buffer *_fetch_buffer(ogg_buffer_state *bs,long bytes){ ogg_buffer *ob; bs->outstanding++; /* do we have an unused buffer sitting in the pool? */ if(bs->unused_buffers){ ob=bs->unused_buffers; bs->unused_buffers=ob->ptr.next; /* if the unused buffer is too small, grow it */ if(ob->size<bytes){ ob->data=_ogg_realloc((void*)ob->data,bytes); ob->size=bytes; } if (bytes<0){ if (ob->data) _ogg_free((void*)ob->data); ob->data=NULL; ob->size=0; } }else{ /* allocate a new buffer */ ob=_ogg_malloc(sizeof(*ob)); ob->ext = NULL; ob->extdata = NULL; if (bytes>=0){ ob->data=_ogg_malloc(bytes<16?16:bytes); ob->size=bytes; } else{ ob->data=NULL; ob->size=0; } } ob->refcount=1; ob->ptr.owner=bs; return ob; }
int theora_decode_init(theora_state *_td,theora_info *_ci){ th_api_info *apiinfo; th_api_wrapper *api; th_info info; api=(th_api_wrapper *)_ci->codec_setup; /*Allocate our own combined API wrapper/theora_info struct. We put them both in one malloc'd block so that when the API wrapper is freed, the info struct goes with it. This avoids having to figure out whether or not we need to free the info struct in either theora_info_clear() or theora_clear().*/ apiinfo=(th_api_info *)_ogg_calloc(1,sizeof(*apiinfo)); /*Make our own copy of the info struct, since its lifetime should be independent of the one we were passed in.*/ *&apiinfo->info=*_ci; /*Convert the info struct now instead of saving the the one we decoded with theora_decode_header(), since the user might have modified values (i.e., color space, aspect ratio, etc. can be specified from a higher level). The user also might be doing something "clever" with the header packets if they are not using an Ogg encapsulation.*/ oc_theora_info2th_info(&info,_ci); /*Don't bother to copy the setup info; th_decode_alloc() makes its own copy of the stuff it needs.*/ apiinfo->api.decode=th_decode_alloc(&info,api->setup); if(apiinfo->api.decode==NULL){ _ogg_free(apiinfo); return OC_EINVAL; } apiinfo->api.clear=(oc_setup_clear_func)th_dec_api_clear; _td->internal_encode=NULL; /*Provide entry points for ABI compatibility with old decoder shared libs.*/ _td->internal_decode=(void *)&OC_DEC_DISPATCH_VTBL; _td->granulepos=0; _td->i=&apiinfo->info; _td->i->codec_setup=&apiinfo->api; return 0; }
int theora_encode_init(theora_state *_te,theora_info *_ci){ th_api_info *apiinfo; th_info info; ogg_uint32_t keyframe_frequency_force; /*Allocate our own combined API wrapper/theora_info struct. We put them both in one malloc'd block so that when the API wrapper is freed, the info struct goes with it. This avoids having to figure out whether or not we need to free the info struct in either theora_info_clear() or theora_clear().*/ apiinfo=(th_api_info *)_ogg_malloc(sizeof(*apiinfo)); if(apiinfo==NULL)return TH_EFAULT; /*Make our own copy of the info struct, since its lifetime should be independent of the one we were passed in.*/ *&apiinfo->info=*_ci; oc_theora_info2th_info(&info,_ci); apiinfo->api.encode=th_encode_alloc(&info); if(apiinfo->api.encode==NULL){ _ogg_free(apiinfo); return OC_EINVAL; } apiinfo->api.clear=(oc_setup_clear_func)th_enc_api_clear; /*Provide entry points for ABI compatibility with old decoder shared libs.*/ _te->internal_encode=(void *)&OC_ENC_DISPATCH_VTBL; _te->internal_decode=NULL; _te->granulepos=0; _te->i=&apiinfo->info; _te->i->codec_setup=&apiinfo->api; /*Set the precise requested keyframe frequency.*/ keyframe_frequency_force=_ci->keyframe_auto_p? _ci->keyframe_frequency_force:_ci->keyframe_frequency; th_encode_ctl(apiinfo->api.encode, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, &keyframe_frequency_force,sizeof(keyframe_frequency_force)); /*TODO: Additional codec setup using the extra fields in theora_info.*/ return 0; }
static void floor0_free_look(vorbis_look_floor *vlf) { vorbis_look_floor0 *look=(vorbis_look_floor0 *)vlf; unsigned int i; if(look){ vorbis_info_floor0 *info=look->vif0; if(look->linearcosmap){ if(look->linearcosmap[0]) _ogg_free(look->linearcosmap[0]); if(look->linearcosmap[1]) _ogg_free(look->linearcosmap[1]); _ogg_free(look->linearcosmap); } if(look->lsp_data && info && info->vi){ vorbis_info *vi=info->vi; for(i=0;i<vi->channels;i++) _ogg_free(look->lsp_data[i]); _ogg_free(look->lsp_data); } _ogg_free(look); } }
static void res012_free_info(vorbis_info_residue *i) { vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; int j; if(info){ if(info->partwordp) _ogg_free(info->partwordp); if(info->partbooks){ for(j=0;j<info->stages;j++) if(info->partbooks[j]) _ogg_free(info->partbooks[j]); _ogg_free(info->partbooks); } if(info->decodemap){ for(j=0;j<info->look_partvals;j++) _ogg_free(info->decodemap[j]); _ogg_free(info->decodemap); } _ogg_free(info); } }
void ogg_packet_clear(ogg_packet *op) { _ogg_free(op->packet); memset(op, 0, sizeof(*op)); }
int main(void){ ogg_stream_init(&os_en,0x04030201); ogg_stream_init(&os_de,0x04030201); ogg_sync_init(&oy); /* Exercise each code path in the framing code. Also verify that the checksums are working. */ { /* 17 only */ const int packets[]={17, -1}; const int *headret[]={head1_0,NULL}; fprintf(stderr,"testing single page encoding... "); test_pack(packets,headret); } { /* 17, 254, 255, 256, 500, 510, 600 byte, pad */ const int packets[]={17, 254, 255, 256, 500, 510, 600, -1}; const int *headret[]={head1_1,head2_1,NULL}; fprintf(stderr,"testing basic page encoding... "); test_pack(packets,headret); } { /* nil packets; beginning,middle,end */ const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1}; const int *headret[]={head1_2,head2_2,NULL}; fprintf(stderr,"testing basic nil packets... "); test_pack(packets,headret); } { /* large initial packet */ const int packets[]={4345,259,255,-1}; const int *headret[]={head1_3,head2_3,NULL}; fprintf(stderr,"testing initial-packet lacing > 4k... "); test_pack(packets,headret); } { /* continuing packet test */ const int packets[]={0,4345,259,255,-1}; const int *headret[]={head1_4,head2_4,head3_4,NULL}; fprintf(stderr,"testing single packet page span... "); test_pack(packets,headret); } /* page with the 255 segment limit */ { const int packets[]={0,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,50,-1}; const int *headret[]={head1_5,head2_5,head3_5,NULL}; fprintf(stderr,"testing max packet segments... "); test_pack(packets,headret); } { /* packet that overspans over an entire page */ const int packets[]={0,100,9000,259,255,-1}; const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; fprintf(stderr,"testing very large packets... "); test_pack(packets,headret); } { /* term only page. why not? */ const int packets[]={0,100,4080,-1}; const int *headret[]={head1_7,head2_7,head3_7,NULL}; fprintf(stderr,"testing zero data page (1 nil packet)... "); test_pack(packets,headret); } { /* build a bunch of pages for testing */ unsigned char *data=_ogg_malloc(1024*1024); int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1}; int inptr=0,i,j; ogg_page og[5]; ogg_stream_reset(&os_en); for(i=0;pl[i]!=-1;i++){ ogg_packet op; int len=pl[i]; op.packet=data+inptr; op.bytes=len; op.e_o_s=(pl[i+1]<0?1:0); op.granulepos=(i+1)*1000; for(j=0;j<len;j++)data[inptr++]=i+j; ogg_stream_packetin(&os_en,&op); } _ogg_free(data); /* retrieve finished pages */ for(i=0;i<5;i++){ if(ogg_stream_pageout(&os_en,&og[i])==0){ fprintf(stderr,"Too few pages output building sync tests!\n"); exit(1); } copy_page(&og[i]); } /* Test lost pages on pagein/packetout: no rollback */ { ogg_page temp; ogg_packet test; fprintf(stderr,"Testing loss of pages... "); ogg_sync_reset(&oy); ogg_stream_reset(&os_de); for(i=0;i<5;i++){ memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header, og[i].header_len); ogg_sync_wrote(&oy,og[i].header_len); memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len); ogg_sync_wrote(&oy,og[i].body_len); } ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); ogg_sync_pageout(&oy,&temp); /* skip */ ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); /* do we get the expected results/packets? */ if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,0,0,0); if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,100,1,-1); if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,4079,2,3000); if(ogg_stream_packetout(&os_de,&test)!=-1){ fprintf(stderr,"Error: loss of page did not return error\n"); exit(1); } if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,76,5,-1); if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,34,6,-1); fprintf(stderr,"ok.\n"); } /* Test lost pages on pagein/packetout: rollback with continuation */ { ogg_page temp; ogg_packet test; fprintf(stderr,"Testing loss of pages (rollback required)... "); ogg_sync_reset(&oy); ogg_stream_reset(&os_de); for(i=0;i<5;i++){ memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header, og[i].header_len); ogg_sync_wrote(&oy,og[i].header_len); memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len); ogg_sync_wrote(&oy,og[i].body_len); } ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); ogg_sync_pageout(&oy,&temp); /* skip */ ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); /* do we get the expected results/packets? */ if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,0,0,0); if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,100,1,-1); if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,4079,2,3000); if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,2956,3,4000); if(ogg_stream_packetout(&os_de,&test)!=-1){ fprintf(stderr,"Error: loss of page did not return error\n"); exit(1); } if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,300,13,14000); fprintf(stderr,"ok.\n"); } /* the rest only test sync */ { ogg_page og_de; /* Test fractional page inputs: incomplete capture */ fprintf(stderr,"Testing sync on partial inputs... "); ogg_sync_reset(&oy); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, 3); ogg_sync_wrote(&oy,3); if(ogg_sync_pageout(&oy,&og_de)>0)error(); /* Test fractional page inputs: incomplete fixed header */ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3, 20); ogg_sync_wrote(&oy,20); if(ogg_sync_pageout(&oy,&og_de)>0)error(); /* Test fractional page inputs: incomplete header */ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23, 5); ogg_sync_wrote(&oy,5); if(ogg_sync_pageout(&oy,&og_de)>0)error(); /* Test fractional page inputs: incomplete body */ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28, og[1].header_len-28); ogg_sync_wrote(&oy,og[1].header_len-28); if(ogg_sync_pageout(&oy,&og_de)>0)error(); memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000); ogg_sync_wrote(&oy,1000); if(ogg_sync_pageout(&oy,&og_de)>0)error(); memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000, og[1].body_len-1000); ogg_sync_wrote(&oy,og[1].body_len-1000); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); fprintf(stderr,"ok.\n"); } /* Test fractional page inputs: page + incomplete capture */ { ogg_page og_de; fprintf(stderr,"Testing sync on 1+partial inputs... "); ogg_sync_reset(&oy); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, og[1].header_len); ogg_sync_wrote(&oy,og[1].header_len); memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, og[1].body_len); ogg_sync_wrote(&oy,og[1].body_len); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, 20); ogg_sync_wrote(&oy,20); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); if(ogg_sync_pageout(&oy,&og_de)>0)error(); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20, og[1].header_len-20); ogg_sync_wrote(&oy,og[1].header_len-20); memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, og[1].body_len); ogg_sync_wrote(&oy,og[1].body_len); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); fprintf(stderr,"ok.\n"); } /* Test recapture: garbage + page */ { ogg_page og_de; fprintf(stderr,"Testing search for capture... "); ogg_sync_reset(&oy); /* 'garbage' */ memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, og[1].body_len); ogg_sync_wrote(&oy,og[1].body_len); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, og[1].header_len); ogg_sync_wrote(&oy,og[1].header_len); memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, og[1].body_len); ogg_sync_wrote(&oy,og[1].body_len); memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, 20); ogg_sync_wrote(&oy,20); if(ogg_sync_pageout(&oy,&og_de)>0)error(); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); if(ogg_sync_pageout(&oy,&og_de)>0)error(); memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20, og[2].header_len-20); ogg_sync_wrote(&oy,og[2].header_len-20); memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, og[2].body_len); ogg_sync_wrote(&oy,og[2].body_len); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); fprintf(stderr,"ok.\n"); } /* Test recapture: page + garbage + page */ { ogg_page og_de; fprintf(stderr,"Testing recapture... "); ogg_sync_reset(&oy); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, og[1].header_len); ogg_sync_wrote(&oy,og[1].header_len); memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, og[1].body_len); ogg_sync_wrote(&oy,og[1].body_len); memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, og[2].header_len); ogg_sync_wrote(&oy,og[2].header_len); memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header, og[2].header_len); ogg_sync_wrote(&oy,og[2].header_len); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body, og[2].body_len-5); ogg_sync_wrote(&oy,og[2].body_len-5); memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header, og[3].header_len); ogg_sync_wrote(&oy,og[3].header_len); memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body, og[3].body_len); ogg_sync_wrote(&oy,og[3].body_len); if(ogg_sync_pageout(&oy,&og_de)>0)error(); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); fprintf(stderr,"ok.\n"); } } return(0); }
void test_pack(const int *pl, const int **headers){ unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */ long inptr=0; long outptr=0; long deptr=0; long depacket=0; long granule_pos=7,pageno=0; int i,j,packets,pageout=0; int eosflag=0; int bosflag=0; ogg_stream_reset(&os_en); ogg_stream_reset(&os_de); ogg_sync_reset(&oy); for(packets=0;;packets++)if(pl[packets]==-1)break; for(i=0;i<packets;i++){ /* construct a test packet */ ogg_packet op; int len=pl[i]; op.packet=data+inptr; op.bytes=len; op.e_o_s=(pl[i+1]<0?1:0); op.granulepos=granule_pos; granule_pos+=1024; for(j=0;j<len;j++)data[inptr++]=i+j; /* submit the test packet */ ogg_stream_packetin(&os_en,&op); /* retrieve any finished pages */ { ogg_page og; while(ogg_stream_pageout(&os_en,&og)){ /* We have a page. Check it carefully */ fprintf(stderr,"%ld, ",pageno); if(headers[pageno]==NULL){ fprintf(stderr,"coded too many pages!\n"); exit(1); } check_page(data+outptr,headers[pageno],&og); outptr+=og.body_len; pageno++; /* have a complete page; submit it to sync/decode */ { ogg_page og_de; ogg_packet op_de,op_de2; char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len); memcpy(buf,og.header,og.header_len); memcpy(buf+og.header_len,og.body,og.body_len); ogg_sync_wrote(&oy,og.header_len+og.body_len); while(ogg_sync_pageout(&oy,&og_de)>0){ /* got a page. Happy happy. Verify that it's good. */ check_page(data+deptr,headers[pageout],&og_de); deptr+=og_de.body_len; pageout++; /* submit it to deconstitution */ ogg_stream_pagein(&os_de,&og_de); /* packets out? */ while(ogg_stream_packetpeek(&os_de,&op_de2)>0){ ogg_stream_packetpeek(&os_de,NULL); ogg_stream_packetout(&os_de,&op_de); /* just catching them all */ /* verify peek and out match */ if(memcmp(&op_de,&op_de2,sizeof(op_de))){ fprintf(stderr,"packetout != packetpeek! pos=%ld\n", depacket); exit(1); } /* verify the packet! */ /* check data */ if(memcmp(data+depacket,op_de.packet,op_de.bytes)){ fprintf(stderr,"packet data mismatch in decode! pos=%ld\n", depacket); exit(1); } /* check bos flag */ if(bosflag==0 && op_de.b_o_s==0){ fprintf(stderr,"b_o_s flag not set on packet!\n"); exit(1); } if(bosflag && op_de.b_o_s){ fprintf(stderr,"b_o_s flag incorrectly set on packet!\n"); exit(1); } bosflag=1; depacket+=op_de.bytes; /* check eos flag */ if(eosflag){ fprintf(stderr,"Multiple decoded packets with eos flag!\n"); exit(1); } if(op_de.e_o_s)eosflag=1; /* check granulepos flag */ if(op_de.granulepos!=-1){ fprintf(stderr," granule:%ld ",(long)op_de.granulepos); } } } } } } } _ogg_free(data); if(headers[pageno]!=NULL){ fprintf(stderr,"did not write last page!\n"); exit(1); } if(headers[pageout]!=NULL){ fprintf(stderr,"did not decode last page!\n"); exit(1); } if(inptr!=outptr){ fprintf(stderr,"encoded page data incomplete!\n"); exit(1); } if(inptr!=deptr){ fprintf(stderr,"decoded page data incomplete!\n"); exit(1); } if(inptr!=depacket){ fprintf(stderr,"decoded packet data incomplete!\n"); exit(1); } if(!eosflag){ fprintf(stderr,"Never got a packet with EOS set!\n"); exit(1); } fprintf(stderr,"ok.\n"); }
void _vi_psy_free(vorbis_info_psy *i){ if(i){ memset(i,0,sizeof(*i)); _ogg_free(i); } }
void _vp_global_free(vorbis_look_psy_global *look){ if(look){ memset(look,0,sizeof(*look)); _ogg_free(look); } }
int vorbis_analysis_headerout(vorbis_dsp_state *v, vorbis_comment *vc, ogg_packet *op, ogg_packet *op_comm, ogg_packet *op_code){ int ret=OV_EIMPL; vorbis_info *vi=v->vi; oggpack_buffer opb; private_state *b=v->backend_state; if(!b){ ret=OV_EFAULT; goto err_out; } /* first header packet **********************************************/ oggpack_writeinit(&opb); if(_vorbis_pack_info(&opb,vi))goto err_out; /* build the packet */ if(b->header)_ogg_free(b->header); b->header=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header,opb.buffer,oggpack_bytes(&opb)); op->packet=b->header; op->bytes=oggpack_bytes(&opb); op->b_o_s=1; op->e_o_s=0; op->granulepos=0; op->packetno=0; /* second header packet (comments) **********************************/ oggpack_reset(&opb); if(_vorbis_pack_comment(&opb,vc))goto err_out; if(b->header1)_ogg_free(b->header1); b->header1=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header1,opb.buffer,oggpack_bytes(&opb)); op_comm->packet=b->header1; op_comm->bytes=oggpack_bytes(&opb); op_comm->b_o_s=0; op_comm->e_o_s=0; op_comm->granulepos=0; op_comm->packetno=1; /* third header packet (modes/codebooks) ****************************/ oggpack_reset(&opb); if(_vorbis_pack_books(&opb,vi))goto err_out; if(b->header2)_ogg_free(b->header2); b->header2=_ogg_malloc(oggpack_bytes(&opb)); memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); op_code->packet=b->header2; op_code->bytes=oggpack_bytes(&opb); op_code->b_o_s=0; op_code->e_o_s=0; op_code->granulepos=0; op_code->packetno=2; oggpack_writeclear(&opb); return(0); err_out: memset(op,0,sizeof(*op)); memset(op_comm,0,sizeof(*op_comm)); memset(op_code,0,sizeof(*op_code)); if(b){ oggpack_writeclear(&opb); if(b->header)_ogg_free(b->header); if(b->header1)_ogg_free(b->header1); if(b->header2)_ogg_free(b->header2); b->header=NULL; b->header1=NULL; b->header2=NULL; } return(ret); }
int oc_quant_params_unpack(oc_pack_buf *_opb,th_quant_info *_qinfo){ th_quant_base *base_mats; long val; int nbase_mats; int sizes[64]; int indices[64]; int nbits; int bmi; int ci; int qti; int pli; int qri; int qi; int i; val=oc_pack_read(_opb,3); nbits=(int)val; for(qi=0;qi<64;qi++){ val=oc_pack_read(_opb,nbits); _qinfo->loop_filter_limits[qi]=(unsigned char)val; } val=oc_pack_read(_opb,4); nbits=(int)val+1; for(qi=0;qi<64;qi++){ val=oc_pack_read(_opb,nbits); _qinfo->ac_scale[qi]=(ogg_uint16_t)val; } val=oc_pack_read(_opb,4); nbits=(int)val+1; for(qi=0;qi<64;qi++){ val=oc_pack_read(_opb,nbits); _qinfo->dc_scale[qi]=(ogg_uint16_t)val; } val=oc_pack_read(_opb,9); nbase_mats=(int)val+1; base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0])); if(base_mats==NULL)return TH_EFAULT; for(bmi=0;bmi<nbase_mats;bmi++){ for(ci=0;ci<64;ci++){ val=oc_pack_read(_opb,8); base_mats[bmi][ci]=(unsigned char)val; } } nbits=oc_ilog(nbase_mats-1); for(i=0;i<6;i++){ th_quant_ranges *qranges; th_quant_base *qrbms; int *qrsizes; qti=i/3; pli=i%3; qranges=_qinfo->qi_ranges[qti]+pli; if(i>0){ val=oc_pack_read1(_opb); if(!val){ int qtj; int plj; if(qti>0){ val=oc_pack_read1(_opb); if(val){ qtj=qti-1; plj=pli; } else{ qtj=(i-1)/3; plj=(i-1)%3; } } else{ qtj=(i-1)/3; plj=(i-1)%3; } *qranges=*(_qinfo->qi_ranges[qtj]+plj); continue; } } val=oc_pack_read(_opb,nbits); indices[0]=(int)val; for(qi=qri=0;qi<63;){ val=oc_pack_read(_opb,oc_ilog(62-qi)); sizes[qri]=(int)val+1; qi+=(int)val+1; val=oc_pack_read(_opb,nbits); indices[++qri]=(int)val; } /*Note: The caller is responsible for cleaning up any partially constructed qinfo.*/ if(qi>63){ _ogg_free(base_mats); return TH_EBADHEADER; } qranges->nranges=qri; qranges->sizes=qrsizes=(int *)_ogg_malloc(qri*sizeof(qrsizes[0])); if(qranges->sizes==NULL){ /*Note: The caller is responsible for cleaning up any partially constructed qinfo.*/ _ogg_free(base_mats); return TH_EFAULT; } memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0])); qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0])); if(qrbms==NULL){ /*Note: The caller is responsible for cleaning up any partially constructed qinfo.*/ _ogg_free(base_mats); return TH_EFAULT; } qranges->base_matrices=(const th_quant_base *)qrbms; do{ bmi=indices[qri]; /*Note: The caller is responsible for cleaning up any partially constructed qinfo.*/ if(bmi>=nbase_mats){ _ogg_free(base_mats); return TH_EBADHEADER; } memcpy(qrbms[qri],base_mats[bmi],sizeof(qrbms[qri])); } while(qri-->0); } _ogg_free(base_mats); return 0; }