123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /********************************************************************
- * *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE 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 Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 *
- * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
- * *
- ********************************************************************
- function:
- last mod: $Id$
- ********************************************************************/
- #include <stdlib.h>
- #include <string.h>
- #include <ogg/ogg.h>
- #include "dequant.h"
- #include "decint.h"
- 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;
- }
- 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);
- }
- }
|