Mercurial > mplayer.hg
annotate tremor/res012.c @ 20874:b6d87b58754f
Partial fix for semitransparent glyph outlines.
This fix removes semitransparent area (less then pixel width) between glyph and
it's outline. Instead, it makes them overlap a little. It usually looks much
better this way.
Complete fix seems impossible with the current output format (single color
alpha bitmaps). The right way is to blend both glyph and outline into one
bitmap so that 2 pixels with 50% transparency produce a fully solid one.
This requires RGBA bitmap output from libass.
author | eugeni |
---|---|
date | Mon, 13 Nov 2006 16:35:15 +0000 |
parents | cd6b211be811 |
children | 8dfda4d651ec |
rev | line source |
---|---|
14280 | 1 /******************************************************************** |
2 * * | |
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * | |
4 * * | |
19251
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
cd6b211be811
Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents:
14280
diff
changeset
|
8 * * |
14280 | 9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * |
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * | |
11 * * | |
12 ******************************************************************** | |
13 | |
14 function: residue backend 0, 1 and 2 implementation | |
15 | |
16 ********************************************************************/ | |
17 | |
18 #include <stdlib.h> | |
19 #include <string.h> | |
20 #include <math.h> | |
21 #include "ogg.h" | |
22 #include "ivorbiscodec.h" | |
23 #include "codec_internal.h" | |
24 #include "registry.h" | |
25 #include "codebook.h" | |
26 #include "misc.h" | |
27 #include "os.h" | |
28 | |
29 typedef struct { | |
30 vorbis_info_residue0 *info; | |
31 int map; | |
32 | |
33 int parts; | |
34 int stages; | |
35 codebook *fullbooks; | |
36 codebook *phrasebook; | |
37 codebook ***partbooks; | |
38 | |
39 int partvals; | |
40 int **decodemap; | |
41 | |
42 } vorbis_look_residue0; | |
43 | |
44 void res0_free_info(vorbis_info_residue *i){ | |
45 vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; | |
46 if(info){ | |
47 memset(info,0,sizeof(*info)); | |
48 _ogg_free(info); | |
49 } | |
50 } | |
51 | |
52 void res0_free_look(vorbis_look_residue *i){ | |
53 int j; | |
54 if(i){ | |
55 | |
56 vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; | |
57 | |
58 for(j=0;j<look->parts;j++) | |
59 if(look->partbooks[j])_ogg_free(look->partbooks[j]); | |
60 _ogg_free(look->partbooks); | |
61 for(j=0;j<look->partvals;j++) | |
62 _ogg_free(look->decodemap[j]); | |
63 _ogg_free(look->decodemap); | |
64 | |
65 memset(look,0,sizeof(*look)); | |
66 _ogg_free(look); | |
67 } | |
68 } | |
69 | |
70 static int ilog(unsigned int v){ | |
71 int ret=0; | |
72 while(v){ | |
73 ret++; | |
74 v>>=1; | |
75 } | |
76 return(ret); | |
77 } | |
78 | |
79 static int icount(unsigned int v){ | |
80 int ret=0; | |
81 while(v){ | |
82 ret+=v&1; | |
83 v>>=1; | |
84 } | |
85 return(ret); | |
86 } | |
87 | |
88 /* vorbis_info is for range checking */ | |
89 vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ | |
90 int j,acc=0; | |
91 vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info)); | |
92 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | |
93 | |
94 info->begin=oggpack_read(opb,24); | |
95 info->end=oggpack_read(opb,24); | |
96 info->grouping=oggpack_read(opb,24)+1; | |
97 info->partitions=oggpack_read(opb,6)+1; | |
98 info->groupbook=oggpack_read(opb,8); | |
99 | |
100 for(j=0;j<info->partitions;j++){ | |
101 int cascade=oggpack_read(opb,3); | |
102 if(oggpack_read(opb,1)) | |
103 cascade|=(oggpack_read(opb,5)<<3); | |
104 info->secondstages[j]=cascade; | |
105 | |
106 acc+=icount(cascade); | |
107 } | |
108 for(j=0;j<acc;j++) | |
109 info->booklist[j]=oggpack_read(opb,8); | |
110 | |
111 if(info->groupbook>=ci->books)goto errout; | |
112 for(j=0;j<acc;j++) | |
113 if(info->booklist[j]>=ci->books)goto errout; | |
114 | |
115 return(info); | |
116 errout: | |
117 res0_free_info(info); | |
118 return(NULL); | |
119 } | |
120 | |
121 vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm, | |
122 vorbis_info_residue *vr){ | |
123 vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; | |
124 vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look)); | |
125 codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; | |
126 | |
127 int j,k,acc=0; | |
128 int dim; | |
129 int maxstage=0; | |
130 look->info=info; | |
131 look->map=vm->mapping; | |
132 | |
133 look->parts=info->partitions; | |
134 look->fullbooks=ci->fullbooks; | |
135 look->phrasebook=ci->fullbooks+info->groupbook; | |
136 dim=look->phrasebook->dim; | |
137 | |
138 look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks)); | |
139 | |
140 for(j=0;j<look->parts;j++){ | |
141 int stages=ilog(info->secondstages[j]); | |
142 if(stages){ | |
143 if(stages>maxstage)maxstage=stages; | |
144 look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j])); | |
145 for(k=0;k<stages;k++) | |
146 if(info->secondstages[j]&(1<<k)){ | |
147 look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++]; | |
148 #ifdef TRAIN_RES | |
149 look->training_data[k][j]=calloc(look->partbooks[j][k]->entries, | |
150 sizeof(***look->training_data)); | |
151 #endif | |
152 } | |
153 } | |
154 } | |
155 | |
156 look->partvals=look->parts; | |
157 for(j=1;j<dim;j++)look->partvals*=look->parts; | |
158 look->stages=maxstage; | |
159 look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap)); | |
160 for(j=0;j<look->partvals;j++){ | |
161 long val=j; | |
162 long mult=look->partvals/look->parts; | |
163 look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j])); | |
164 for(k=0;k<dim;k++){ | |
165 long deco=val/mult; | |
166 val-=deco*mult; | |
167 mult/=look->parts; | |
168 look->decodemap[j][k]=deco; | |
169 } | |
170 } | |
171 | |
172 return(look); | |
173 } | |
174 | |
175 | |
176 /* a truncated packet here just means 'stop working'; it's not an error */ | |
177 static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
178 ogg_int32_t **in,int ch, | |
179 long (*decodepart)(codebook *, ogg_int32_t *, | |
180 oggpack_buffer *,int,int)){ | |
181 | |
182 long i,j,k,l,s; | |
183 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; | |
184 vorbis_info_residue0 *info=look->info; | |
185 | |
186 /* move all this setup out later */ | |
187 int samples_per_partition=info->grouping; | |
188 int partitions_per_word=look->phrasebook->dim; | |
189 int n=info->end-info->begin; | |
190 | |
191 int partvals=n/samples_per_partition; | |
192 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; | |
193 int ***partword=(int ***)alloca(ch*sizeof(*partword)); | |
194 | |
195 for(j=0;j<ch;j++) | |
196 partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); | |
197 | |
198 for(s=0;s<look->stages;s++){ | |
199 | |
200 /* each loop decodes on partition codeword containing | |
201 partitions_pre_word partitions */ | |
202 for(i=0,l=0;i<partvals;l++){ | |
203 if(s==0){ | |
204 /* fetch the partition word for each channel */ | |
205 for(j=0;j<ch;j++){ | |
206 int temp=vorbis_book_decode(look->phrasebook,&vb->opb); | |
207 if(temp==-1)goto eopbreak; | |
208 partword[j][l]=look->decodemap[temp]; | |
209 if(partword[j][l]==NULL)goto errout; | |
210 } | |
211 } | |
212 | |
213 /* now we decode residual values for the partitions */ | |
214 for(k=0;k<partitions_per_word && i<partvals;k++,i++) | |
215 for(j=0;j<ch;j++){ | |
216 long offset=info->begin+i*samples_per_partition; | |
217 if(info->secondstages[partword[j][l][k]]&(1<<s)){ | |
218 codebook *stagebook=look->partbooks[partword[j][l][k]][s]; | |
219 if(stagebook){ | |
220 if(decodepart(stagebook,in[j]+offset,&vb->opb, | |
221 samples_per_partition,-8)==-1)goto eopbreak; | |
222 } | |
223 } | |
224 } | |
225 } | |
226 } | |
227 | |
228 errout: | |
229 eopbreak: | |
230 return(0); | |
231 } | |
232 | |
233 int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
234 ogg_int32_t **in,int *nonzero,int ch){ | |
235 int i,used=0; | |
236 for(i=0;i<ch;i++) | |
237 if(nonzero[i]) | |
238 in[used++]=in[i]; | |
239 if(used) | |
240 return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add)); | |
241 else | |
242 return(0); | |
243 } | |
244 | |
245 int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
246 ogg_int32_t **in,int *nonzero,int ch){ | |
247 int i,used=0; | |
248 for(i=0;i<ch;i++) | |
249 if(nonzero[i]) | |
250 in[used++]=in[i]; | |
251 if(used) | |
252 return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add)); | |
253 else | |
254 return(0); | |
255 } | |
256 | |
257 /* duplicate code here as speed is somewhat more important */ | |
258 int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |
259 ogg_int32_t **in,int *nonzero,int ch){ | |
260 long i,k,l,s; | |
261 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; | |
262 vorbis_info_residue0 *info=look->info; | |
263 | |
264 /* move all this setup out later */ | |
265 int samples_per_partition=info->grouping; | |
266 int partitions_per_word=look->phrasebook->dim; | |
267 int n=info->end-info->begin; | |
268 | |
269 int partvals=n/samples_per_partition; | |
270 int partwords=(partvals+partitions_per_word-1)/partitions_per_word; | |
271 int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); | |
272 int beginoff=info->begin/ch; | |
273 | |
274 for(i=0;i<ch;i++)if(nonzero[i])break; | |
275 if(i==ch)return(0); /* no nonzero vectors */ | |
276 | |
277 samples_per_partition/=ch; | |
278 | |
279 for(s=0;s<look->stages;s++){ | |
280 for(i=0,l=0;i<partvals;l++){ | |
281 | |
282 if(s==0){ | |
283 /* fetch the partition word */ | |
284 int temp=vorbis_book_decode(look->phrasebook,&vb->opb); | |
285 if(temp==-1)goto eopbreak; | |
286 partword[l]=look->decodemap[temp]; | |
287 if(partword[l]==NULL)goto errout; | |
288 } | |
289 | |
290 /* now we decode residual values for the partitions */ | |
291 for(k=0;k<partitions_per_word && i<partvals;k++,i++) | |
292 if(info->secondstages[partword[l][k]]&(1<<s)){ | |
293 codebook *stagebook=look->partbooks[partword[l][k]][s]; | |
294 | |
295 if(stagebook){ | |
296 if(vorbis_book_decodevv_add(stagebook,in, | |
297 i*samples_per_partition+beginoff,ch, | |
298 &vb->opb, | |
299 samples_per_partition,-8)==-1) | |
300 goto eopbreak; | |
301 } | |
302 } | |
303 } | |
304 } | |
305 | |
306 errout: | |
307 eopbreak: | |
308 return(0); | |
309 } | |
310 | |
311 | |
312 vorbis_func_residue residue0_exportbundle={ | |
313 &res0_unpack, | |
314 &res0_look, | |
315 &res0_free_info, | |
316 &res0_free_look, | |
317 &res0_inverse | |
318 }; | |
319 | |
320 vorbis_func_residue residue1_exportbundle={ | |
321 &res0_unpack, | |
322 &res0_look, | |
323 &res0_free_info, | |
324 &res0_free_look, | |
325 &res1_inverse | |
326 }; | |
327 | |
328 vorbis_func_residue residue2_exportbundle={ | |
329 &res0_unpack, | |
330 &res0_look, | |
331 &res0_free_info, | |
332 &res0_free_look, | |
333 &res2_inverse | |
334 }; |