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
24int 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
146void 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