Line data Source code
1 : /********************************************************************
2 : * *
3 : * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4 : * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 : * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 : * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 : * *
8 : * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 *
9 : * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
10 : * *
11 : ********************************************************************
12 :
13 : function:
14 : last mod: $Id: dequant.c 16503 2009-08-22 18:14:02Z giles $
15 :
16 : ********************************************************************/
17 :
18 : #include <stdlib.h>
19 : #include <string.h>
20 : #include <ogg/ogg.h>
21 : #include "dequant.h"
22 : #include "decint.h"
23 :
24 0 : int oc_quant_params_unpack(oc_pack_buf *_opb,th_quant_info *_qinfo){
25 : th_quant_base *base_mats;
26 : long val;
27 : int nbase_mats;
28 : int sizes[64];
29 : int indices[64];
30 : int nbits;
31 : int bmi;
32 : int ci;
33 : int qti;
34 : int pli;
35 : int qri;
36 : int qi;
37 : int i;
38 0 : val=oc_pack_read(_opb,3);
39 0 : nbits=(int)val;
40 0 : for(qi=0;qi<64;qi++){
41 0 : val=oc_pack_read(_opb,nbits);
42 0 : _qinfo->loop_filter_limits[qi]=(unsigned char)val;
43 : }
44 0 : val=oc_pack_read(_opb,4);
45 0 : nbits=(int)val+1;
46 0 : for(qi=0;qi<64;qi++){
47 0 : val=oc_pack_read(_opb,nbits);
48 0 : _qinfo->ac_scale[qi]=(ogg_uint16_t)val;
49 : }
50 0 : val=oc_pack_read(_opb,4);
51 0 : nbits=(int)val+1;
52 0 : for(qi=0;qi<64;qi++){
53 0 : val=oc_pack_read(_opb,nbits);
54 0 : _qinfo->dc_scale[qi]=(ogg_uint16_t)val;
55 : }
56 0 : val=oc_pack_read(_opb,9);
57 0 : nbase_mats=(int)val+1;
58 0 : base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0]));
59 0 : if(base_mats==NULL)return TH_EFAULT;
60 0 : for(bmi=0;bmi<nbase_mats;bmi++){
61 0 : for(ci=0;ci<64;ci++){
62 0 : val=oc_pack_read(_opb,8);
63 0 : base_mats[bmi][ci]=(unsigned char)val;
64 : }
65 : }
66 0 : nbits=oc_ilog(nbase_mats-1);
67 0 : for(i=0;i<6;i++){
68 : th_quant_ranges *qranges;
69 : th_quant_base *qrbms;
70 : int *qrsizes;
71 0 : qti=i/3;
72 0 : pli=i%3;
73 0 : qranges=_qinfo->qi_ranges[qti]+pli;
74 0 : if(i>0){
75 0 : val=oc_pack_read1(_opb);
76 0 : if(!val){
77 : int qtj;
78 : int plj;
79 0 : if(qti>0){
80 0 : val=oc_pack_read1(_opb);
81 0 : if(val){
82 0 : qtj=qti-1;
83 0 : plj=pli;
84 : }
85 : else{
86 0 : qtj=(i-1)/3;
87 0 : plj=(i-1)%3;
88 : }
89 : }
90 : else{
91 0 : qtj=(i-1)/3;
92 0 : plj=(i-1)%3;
93 : }
94 0 : *qranges=*(_qinfo->qi_ranges[qtj]+plj);
95 0 : continue;
96 : }
97 : }
98 0 : val=oc_pack_read(_opb,nbits);
99 0 : indices[0]=(int)val;
100 0 : for(qi=qri=0;qi<63;){
101 0 : val=oc_pack_read(_opb,oc_ilog(62-qi));
102 0 : sizes[qri]=(int)val+1;
103 0 : qi+=(int)val+1;
104 0 : val=oc_pack_read(_opb,nbits);
105 0 : indices[++qri]=(int)val;
106 : }
107 : /*Note: The caller is responsible for cleaning up any partially
108 : constructed qinfo.*/
109 0 : if(qi>63){
110 0 : _ogg_free(base_mats);
111 0 : return TH_EBADHEADER;
112 : }
113 0 : qranges->nranges=qri;
114 0 : qranges->sizes=qrsizes=(int *)_ogg_malloc(qri*sizeof(qrsizes[0]));
115 0 : if(qranges->sizes==NULL){
116 : /*Note: The caller is responsible for cleaning up any partially
117 : constructed qinfo.*/
118 0 : _ogg_free(base_mats);
119 0 : return TH_EFAULT;
120 : }
121 0 : memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0]));
122 0 : qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0]));
123 0 : if(qrbms==NULL){
124 : /*Note: The caller is responsible for cleaning up any partially
125 : constructed qinfo.*/
126 0 : _ogg_free(base_mats);
127 0 : return TH_EFAULT;
128 : }
129 0 : qranges->base_matrices=(const th_quant_base *)qrbms;
130 : do{
131 0 : bmi=indices[qri];
132 : /*Note: The caller is responsible for cleaning up any partially
133 : constructed qinfo.*/
134 0 : if(bmi>=nbase_mats){
135 0 : _ogg_free(base_mats);
136 0 : return TH_EBADHEADER;
137 : }
138 0 : memcpy(qrbms[qri],base_mats[bmi],sizeof(qrbms[qri]));
139 : }
140 0 : while(qri-->0);
141 : }
142 0 : _ogg_free(base_mats);
143 0 : return 0;
144 : }
145 :
146 0 : void oc_quant_params_clear(th_quant_info *_qinfo){
147 : int i;
148 0 : for(i=6;i-->0;){
149 : int qti;
150 : int pli;
151 0 : qti=i/3;
152 0 : pli=i%3;
153 : /*Clear any duplicate pointer references.*/
154 0 : if(i>0){
155 : int qtj;
156 : int plj;
157 0 : qtj=(i-1)/3;
158 0 : plj=(i-1)%3;
159 0 : if(_qinfo->qi_ranges[qti][pli].sizes==
160 0 : _qinfo->qi_ranges[qtj][plj].sizes){
161 0 : _qinfo->qi_ranges[qti][pli].sizes=NULL;
162 : }
163 0 : if(_qinfo->qi_ranges[qti][pli].base_matrices==
164 0 : _qinfo->qi_ranges[qtj][plj].base_matrices){
165 0 : _qinfo->qi_ranges[qti][pli].base_matrices=NULL;
166 : }
167 : }
168 0 : if(qti>0){
169 0 : if(_qinfo->qi_ranges[1][pli].sizes==
170 0 : _qinfo->qi_ranges[0][pli].sizes){
171 0 : _qinfo->qi_ranges[1][pli].sizes=NULL;
172 : }
173 0 : if(_qinfo->qi_ranges[1][pli].base_matrices==
174 0 : _qinfo->qi_ranges[0][pli].base_matrices){
175 0 : _qinfo->qi_ranges[1][pli].base_matrices=NULL;
176 : }
177 : }
178 : /*Now free all the non-duplicate storage.*/
179 0 : _ogg_free((void *)_qinfo->qi_ranges[qti][pli].sizes);
180 0 : _ogg_free((void *)_qinfo->qi_ranges[qti][pli].base_matrices);
181 : }
182 0 : }
|