michael@0: /******************************************************************** michael@0: * * michael@0: * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * michael@0: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * michael@0: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * michael@0: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * michael@0: * * michael@0: * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * michael@0: * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * michael@0: * * michael@0: ******************************************************************** michael@0: michael@0: function: michael@0: last mod: $Id: dequant.c 16503 2009-08-22 18:14:02Z giles $ michael@0: michael@0: ********************************************************************/ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include "dequant.h" michael@0: #include "decint.h" michael@0: michael@0: int oc_quant_params_unpack(oc_pack_buf *_opb,th_quant_info *_qinfo){ michael@0: th_quant_base *base_mats; michael@0: long val; michael@0: int nbase_mats; michael@0: int sizes[64]; michael@0: int indices[64]; michael@0: int nbits; michael@0: int bmi; michael@0: int ci; michael@0: int qti; michael@0: int pli; michael@0: int qri; michael@0: int qi; michael@0: int i; michael@0: val=oc_pack_read(_opb,3); michael@0: nbits=(int)val; michael@0: for(qi=0;qi<64;qi++){ michael@0: val=oc_pack_read(_opb,nbits); michael@0: _qinfo->loop_filter_limits[qi]=(unsigned char)val; michael@0: } michael@0: val=oc_pack_read(_opb,4); michael@0: nbits=(int)val+1; michael@0: for(qi=0;qi<64;qi++){ michael@0: val=oc_pack_read(_opb,nbits); michael@0: _qinfo->ac_scale[qi]=(ogg_uint16_t)val; michael@0: } michael@0: val=oc_pack_read(_opb,4); michael@0: nbits=(int)val+1; michael@0: for(qi=0;qi<64;qi++){ michael@0: val=oc_pack_read(_opb,nbits); michael@0: _qinfo->dc_scale[qi]=(ogg_uint16_t)val; michael@0: } michael@0: val=oc_pack_read(_opb,9); michael@0: nbase_mats=(int)val+1; michael@0: base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0])); michael@0: if(base_mats==NULL)return TH_EFAULT; michael@0: for(bmi=0;bmiqi_ranges[qti]+pli; michael@0: if(i>0){ michael@0: val=oc_pack_read1(_opb); michael@0: if(!val){ michael@0: int qtj; michael@0: int plj; michael@0: if(qti>0){ michael@0: val=oc_pack_read1(_opb); michael@0: if(val){ michael@0: qtj=qti-1; michael@0: plj=pli; michael@0: } michael@0: else{ michael@0: qtj=(i-1)/3; michael@0: plj=(i-1)%3; michael@0: } michael@0: } michael@0: else{ michael@0: qtj=(i-1)/3; michael@0: plj=(i-1)%3; michael@0: } michael@0: *qranges=*(_qinfo->qi_ranges[qtj]+plj); michael@0: continue; michael@0: } michael@0: } michael@0: val=oc_pack_read(_opb,nbits); michael@0: indices[0]=(int)val; michael@0: for(qi=qri=0;qi<63;){ michael@0: val=oc_pack_read(_opb,oc_ilog(62-qi)); michael@0: sizes[qri]=(int)val+1; michael@0: qi+=(int)val+1; michael@0: val=oc_pack_read(_opb,nbits); michael@0: indices[++qri]=(int)val; michael@0: } michael@0: /*Note: The caller is responsible for cleaning up any partially michael@0: constructed qinfo.*/ michael@0: if(qi>63){ michael@0: _ogg_free(base_mats); michael@0: return TH_EBADHEADER; michael@0: } michael@0: qranges->nranges=qri; michael@0: qranges->sizes=qrsizes=(int *)_ogg_malloc(qri*sizeof(qrsizes[0])); michael@0: if(qranges->sizes==NULL){ michael@0: /*Note: The caller is responsible for cleaning up any partially michael@0: constructed qinfo.*/ michael@0: _ogg_free(base_mats); michael@0: return TH_EFAULT; michael@0: } michael@0: memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0])); michael@0: qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0])); michael@0: if(qrbms==NULL){ michael@0: /*Note: The caller is responsible for cleaning up any partially michael@0: constructed qinfo.*/ michael@0: _ogg_free(base_mats); michael@0: return TH_EFAULT; michael@0: } michael@0: qranges->base_matrices=(const th_quant_base *)qrbms; michael@0: do{ michael@0: bmi=indices[qri]; michael@0: /*Note: The caller is responsible for cleaning up any partially michael@0: constructed qinfo.*/ michael@0: if(bmi>=nbase_mats){ michael@0: _ogg_free(base_mats); michael@0: return TH_EBADHEADER; michael@0: } michael@0: memcpy(qrbms[qri],base_mats[bmi],sizeof(qrbms[qri])); michael@0: } michael@0: while(qri-->0); michael@0: } michael@0: _ogg_free(base_mats); michael@0: return 0; michael@0: } michael@0: michael@0: void oc_quant_params_clear(th_quant_info *_qinfo){ michael@0: int i; michael@0: for(i=6;i-->0;){ michael@0: int qti; michael@0: int pli; michael@0: qti=i/3; michael@0: pli=i%3; michael@0: /*Clear any duplicate pointer references.*/ michael@0: if(i>0){ michael@0: int qtj; michael@0: int plj; michael@0: qtj=(i-1)/3; michael@0: plj=(i-1)%3; michael@0: if(_qinfo->qi_ranges[qti][pli].sizes== michael@0: _qinfo->qi_ranges[qtj][plj].sizes){ michael@0: _qinfo->qi_ranges[qti][pli].sizes=NULL; michael@0: } michael@0: if(_qinfo->qi_ranges[qti][pli].base_matrices== michael@0: _qinfo->qi_ranges[qtj][plj].base_matrices){ michael@0: _qinfo->qi_ranges[qti][pli].base_matrices=NULL; michael@0: } michael@0: } michael@0: if(qti>0){ michael@0: if(_qinfo->qi_ranges[1][pli].sizes== michael@0: _qinfo->qi_ranges[0][pli].sizes){ michael@0: _qinfo->qi_ranges[1][pli].sizes=NULL; michael@0: } michael@0: if(_qinfo->qi_ranges[1][pli].base_matrices== michael@0: _qinfo->qi_ranges[0][pli].base_matrices){ michael@0: _qinfo->qi_ranges[1][pli].base_matrices=NULL; michael@0: } michael@0: } michael@0: /*Now free all the non-duplicate storage.*/ michael@0: _ogg_free((void *)_qinfo->qi_ranges[qti][pli].sizes); michael@0: _ogg_free((void *)_qinfo->qi_ranges[qti][pli].base_matrices); michael@0: } michael@0: }