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$ |
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 | 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 | val=oc_pack_read(_opb,3); |
39 | nbits=(int)val; |
40 | for(qi=0;qi<64;qi++){ |
41 | val=oc_pack_read(_opb,nbits); |
42 | _qinfo->loop_filter_limits[qi]=(unsigned char)val; |
43 | } |
44 | val=oc_pack_read(_opb,4); |
45 | nbits=(int)val+1; |
46 | for(qi=0;qi<64;qi++){ |
47 | val=oc_pack_read(_opb,nbits); |
48 | _qinfo->ac_scale[qi]=(ogg_uint16_t)val; |
49 | } |
50 | val=oc_pack_read(_opb,4); |
51 | nbits=(int)val+1; |
52 | for(qi=0;qi<64;qi++){ |
53 | val=oc_pack_read(_opb,nbits); |
54 | _qinfo->dc_scale[qi]=(ogg_uint16_t)val; |
55 | } |
56 | val=oc_pack_read(_opb,9); |
57 | nbase_mats=(int)val+1; |
58 | base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0])); |
59 | if(base_mats==NULL)return TH_EFAULT; |
60 | for(bmi=0;bmi<nbase_mats;bmi++){ |
61 | for(ci=0;ci<64;ci++){ |
62 | val=oc_pack_read(_opb,8); |
63 | base_mats[bmi][ci]=(unsigned char)val; |
64 | } |
65 | } |
66 | nbits=oc_ilog(nbase_mats-1); |
67 | for(i=0;i<6;i++){ |
68 | th_quant_ranges *qranges; |
69 | th_quant_base *qrbms; |
70 | int *qrsizes; |
71 | qti=i/3; |
72 | pli=i%3; |
73 | qranges=_qinfo->qi_ranges[qti]+pli; |
74 | if(i>0){ |
75 | val=oc_pack_read1(_opb); |
76 | if(!val){ |
77 | int qtj; |
78 | int plj; |
79 | if(qti>0){ |
80 | val=oc_pack_read1(_opb); |
81 | if(val){ |
82 | qtj=qti-1; |
83 | plj=pli; |
84 | } |
85 | else{ |
86 | qtj=(i-1)/3; |
87 | plj=(i-1)%3; |
88 | } |
89 | } |
90 | else{ |
91 | qtj=(i-1)/3; |
92 | plj=(i-1)%3; |
93 | } |
94 | *qranges=*(_qinfo->qi_ranges[qtj]+plj); |
95 | continue; |
96 | } |
97 | } |
98 | val=oc_pack_read(_opb,nbits); |
99 | indices[0]=(int)val; |
100 | for(qi=qri=0;qi<63;){ |
101 | val=oc_pack_read(_opb,oc_ilog(62-qi)); |
102 | sizes[qri]=(int)val+1; |
103 | qi+=(int)val+1; |
104 | val=oc_pack_read(_opb,nbits); |
105 | indices[++qri]=(int)val; |
106 | } |
107 | /*Note: The caller is responsible for cleaning up any partially |
108 | constructed qinfo.*/ |
109 | if(qi>63){ |
110 | _ogg_free(base_mats); |
111 | return TH_EBADHEADER; |
112 | } |
113 | qranges->nranges=qri; |
114 | qranges->sizes=qrsizes=(int *)_ogg_malloc(qri*sizeof(qrsizes[0])); |
115 | if(qranges->sizes==NULL){ |
116 | /*Note: The caller is responsible for cleaning up any partially |
117 | constructed qinfo.*/ |
118 | _ogg_free(base_mats); |
119 | return TH_EFAULT; |
120 | } |
121 | memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0])); |
122 | qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0])); |
123 | if(qrbms==NULL){ |
124 | /*Note: The caller is responsible for cleaning up any partially |
125 | constructed qinfo.*/ |
126 | _ogg_free(base_mats); |
127 | return TH_EFAULT; |
128 | } |
129 | qranges->base_matrices=(const th_quant_base *)qrbms; |
130 | do{ |
131 | bmi=indices[qri]; |
132 | /*Note: The caller is responsible for cleaning up any partially |
133 | constructed qinfo.*/ |
134 | if(bmi>=nbase_mats){ |
135 | _ogg_free(base_mats); |
136 | return TH_EBADHEADER; |
137 | } |
138 | memcpy(qrbms[qri],base_mats[bmi],sizeof(qrbms[qri])); |
139 | } |
140 | while(qri-->0); |
141 | } |
142 | _ogg_free(base_mats); |
143 | return 0; |
144 | } |
145 | |
146 | void oc_quant_params_clear(th_quant_info *_qinfo){ |
147 | int i; |
148 | for(i=6;i-->0;){ |
149 | int qti; |
150 | int pli; |
151 | qti=i/3; |
152 | pli=i%3; |
153 | /*Clear any duplicate pointer references.*/ |
154 | if(i>0){ |
155 | int qtj; |
156 | int plj; |
157 | qtj=(i-1)/3; |
158 | plj=(i-1)%3; |
159 | if(_qinfo->qi_ranges[qti][pli].sizes== |
160 | _qinfo->qi_ranges[qtj][plj].sizes){ |
161 | _qinfo->qi_ranges[qti][pli].sizes=NULL; |
162 | } |
163 | if(_qinfo->qi_ranges[qti][pli].base_matrices== |
164 | _qinfo->qi_ranges[qtj][plj].base_matrices){ |
165 | _qinfo->qi_ranges[qti][pli].base_matrices=NULL; |
166 | } |
167 | } |
168 | if(qti>0){ |
169 | if(_qinfo->qi_ranges[1][pli].sizes== |
170 | _qinfo->qi_ranges[0][pli].sizes){ |
171 | _qinfo->qi_ranges[1][pli].sizes=NULL; |
172 | } |
173 | if(_qinfo->qi_ranges[1][pli].base_matrices== |
174 | _qinfo->qi_ranges[0][pli].base_matrices){ |
175 | _qinfo->qi_ranges[1][pli].base_matrices=NULL; |
176 | } |
177 | } |
178 | /*Now free all the non-duplicate storage.*/ |
179 | _ogg_free((void *)_qinfo->qi_ranges[qti][pli].sizes); |
180 | _ogg_free((void *)_qinfo->qi_ranges[qti][pli].base_matrices); |
181 | } |
182 | } |
183 | |