Imported Upstream version 1.1.1
[platform/upstream/libtheora.git] / lib / dequant.c
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 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 }