/src/theora/lib/encfrag.c
Line | Count | Source (jump to first uncovered line) |
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 http://www.xiph.org/ * |
10 | | * * |
11 | | ******************************************************************** |
12 | | |
13 | | function: |
14 | | last mod: $Id$ |
15 | | |
16 | | ********************************************************************/ |
17 | | #include <stdlib.h> |
18 | | #include <string.h> |
19 | | #include "encint.h" |
20 | | |
21 | | |
22 | | void oc_enc_frag_sub_c(ogg_int16_t _diff[64],const unsigned char *_src, |
23 | 0 | const unsigned char *_ref,int _ystride){ |
24 | 0 | int i; |
25 | 0 | for(i=0;i<8;i++){ |
26 | 0 | int j; |
27 | 0 | for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-_ref[j]); |
28 | 0 | _src+=_ystride; |
29 | 0 | _ref+=_ystride; |
30 | 0 | } |
31 | 0 | } |
32 | | |
33 | | void oc_enc_frag_sub_128_c(ogg_int16_t *_diff, |
34 | 0 | const unsigned char *_src,int _ystride){ |
35 | 0 | int i; |
36 | 0 | for(i=0;i<8;i++){ |
37 | 0 | int j; |
38 | 0 | for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-128); |
39 | 0 | _src+=_ystride; |
40 | 0 | } |
41 | 0 | } |
42 | | |
43 | | unsigned oc_enc_frag_sad_c(const unsigned char *_src, |
44 | 0 | const unsigned char *_ref,int _ystride){ |
45 | 0 | unsigned sad; |
46 | 0 | int i; |
47 | 0 | sad=0; |
48 | 0 | for(i=8;i-->0;){ |
49 | 0 | int j; |
50 | 0 | for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]); |
51 | 0 | _src+=_ystride; |
52 | 0 | _ref+=_ystride; |
53 | 0 | } |
54 | 0 | return sad; |
55 | 0 | } |
56 | | |
57 | | unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src, |
58 | 0 | const unsigned char *_ref,int _ystride,unsigned _thresh){ |
59 | 0 | unsigned sad; |
60 | 0 | int i; |
61 | 0 | sad=0; |
62 | 0 | for(i=8;i-->0;){ |
63 | 0 | int j; |
64 | 0 | for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]); |
65 | 0 | if(sad>_thresh)break; |
66 | 0 | _src+=_ystride; |
67 | 0 | _ref+=_ystride; |
68 | 0 | } |
69 | 0 | return sad; |
70 | 0 | } |
71 | | |
72 | | unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src, |
73 | | const unsigned char *_ref1,const unsigned char *_ref2,int _ystride, |
74 | 0 | unsigned _thresh){ |
75 | 0 | unsigned sad; |
76 | 0 | int i; |
77 | 0 | sad=0; |
78 | 0 | for(i=8;i-->0;){ |
79 | 0 | int j; |
80 | 0 | for(j=0;j<8;j++)sad+=abs(_src[j]-(_ref1[j]+_ref2[j]>>1)); |
81 | 0 | if(sad>_thresh)break; |
82 | 0 | _src+=_ystride; |
83 | 0 | _ref1+=_ystride; |
84 | 0 | _ref2+=_ystride; |
85 | 0 | } |
86 | 0 | return sad; |
87 | 0 | } |
88 | | |
89 | 0 | unsigned oc_enc_frag_intra_sad_c(const unsigned char *_src, int _ystride){ |
90 | 0 | const unsigned char *src = _src; |
91 | 0 | unsigned dc; |
92 | 0 | unsigned sad; |
93 | 0 | int i; |
94 | 0 | dc=0; |
95 | 0 | for(i=8;i-->0;){ |
96 | 0 | int j; |
97 | 0 | for(j=0;j<8;j++)dc+=src[j]; |
98 | 0 | src+=_ystride; |
99 | 0 | } |
100 | 0 | dc=dc+32>>6; |
101 | 0 | sad=0; |
102 | 0 | for(i=8;i-->0;){ |
103 | 0 | int j; |
104 | 0 | for(j=0;j<8;j++)sad+=abs(_src[j]-dc); |
105 | 0 | _src+=_ystride; |
106 | 0 | } |
107 | 0 | return sad; |
108 | 0 | } |
109 | | |
110 | | static void oc_diff_hadamard(ogg_int16_t _buf[64],const unsigned char *_src, |
111 | 0 | const unsigned char *_ref,int _ystride){ |
112 | 0 | int i; |
113 | 0 | for(i=0;i<8;i++){ |
114 | 0 | int t0; |
115 | 0 | int t1; |
116 | 0 | int t2; |
117 | 0 | int t3; |
118 | 0 | int t4; |
119 | 0 | int t5; |
120 | 0 | int t6; |
121 | 0 | int t7; |
122 | 0 | int r; |
123 | | /*Hadamard stage 1:*/ |
124 | 0 | t0=_src[0]-_ref[0]+_src[4]-_ref[4]; |
125 | 0 | t4=_src[0]-_ref[0]-_src[4]+_ref[4]; |
126 | 0 | t1=_src[1]-_ref[1]+_src[5]-_ref[5]; |
127 | 0 | t5=_src[1]-_ref[1]-_src[5]+_ref[5]; |
128 | 0 | t2=_src[2]-_ref[2]+_src[6]-_ref[6]; |
129 | 0 | t6=_src[2]-_ref[2]-_src[6]+_ref[6]; |
130 | 0 | t3=_src[3]-_ref[3]+_src[7]-_ref[7]; |
131 | 0 | t7=_src[3]-_ref[3]-_src[7]+_ref[7]; |
132 | | /*Hadamard stage 2:*/ |
133 | 0 | r=t0; |
134 | 0 | t0+=t2; |
135 | 0 | t2=r-t2; |
136 | 0 | r=t1; |
137 | 0 | t1+=t3; |
138 | 0 | t3=r-t3; |
139 | 0 | r=t4; |
140 | 0 | t4+=t6; |
141 | 0 | t6=r-t6; |
142 | 0 | r=t5; |
143 | 0 | t5+=t7; |
144 | 0 | t7=r-t7; |
145 | | /*Hadamard stage 3:*/ |
146 | 0 | _buf[0*8+i]=(ogg_int16_t)(t0+t1); |
147 | 0 | _buf[1*8+i]=(ogg_int16_t)(t0-t1); |
148 | 0 | _buf[2*8+i]=(ogg_int16_t)(t2+t3); |
149 | 0 | _buf[3*8+i]=(ogg_int16_t)(t2-t3); |
150 | 0 | _buf[4*8+i]=(ogg_int16_t)(t4+t5); |
151 | 0 | _buf[5*8+i]=(ogg_int16_t)(t4-t5); |
152 | 0 | _buf[6*8+i]=(ogg_int16_t)(t6+t7); |
153 | 0 | _buf[7*8+i]=(ogg_int16_t)(t6-t7); |
154 | 0 | _src+=_ystride; |
155 | 0 | _ref+=_ystride; |
156 | 0 | } |
157 | 0 | } |
158 | | |
159 | | static void oc_diff_hadamard2(ogg_int16_t _buf[64],const unsigned char *_src, |
160 | 0 | const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){ |
161 | 0 | int i; |
162 | 0 | for(i=0;i<8;i++){ |
163 | 0 | int t0; |
164 | 0 | int t1; |
165 | 0 | int t2; |
166 | 0 | int t3; |
167 | 0 | int t4; |
168 | 0 | int t5; |
169 | 0 | int t6; |
170 | 0 | int t7; |
171 | 0 | int r; |
172 | | /*Hadamard stage 1:*/ |
173 | 0 | r=_ref1[0]+_ref2[0]>>1; |
174 | 0 | t4=_ref1[4]+_ref2[4]>>1; |
175 | 0 | t0=_src[0]-r+_src[4]-t4; |
176 | 0 | t4=_src[0]-r-_src[4]+t4; |
177 | 0 | r=_ref1[1]+_ref2[1]>>1; |
178 | 0 | t5=_ref1[5]+_ref2[5]>>1; |
179 | 0 | t1=_src[1]-r+_src[5]-t5; |
180 | 0 | t5=_src[1]-r-_src[5]+t5; |
181 | 0 | r=_ref1[2]+_ref2[2]>>1; |
182 | 0 | t6=_ref1[6]+_ref2[6]>>1; |
183 | 0 | t2=_src[2]-r+_src[6]-t6; |
184 | 0 | t6=_src[2]-r-_src[6]+t6; |
185 | 0 | r=_ref1[3]+_ref2[3]>>1; |
186 | 0 | t7=_ref1[7]+_ref2[7]>>1; |
187 | 0 | t3=_src[3]-r+_src[7]-t7; |
188 | 0 | t7=_src[3]-r-_src[7]+t7; |
189 | | /*Hadamard stage 2:*/ |
190 | 0 | r=t0; |
191 | 0 | t0+=t2; |
192 | 0 | t2=r-t2; |
193 | 0 | r=t1; |
194 | 0 | t1+=t3; |
195 | 0 | t3=r-t3; |
196 | 0 | r=t4; |
197 | 0 | t4+=t6; |
198 | 0 | t6=r-t6; |
199 | 0 | r=t5; |
200 | 0 | t5+=t7; |
201 | 0 | t7=r-t7; |
202 | | /*Hadamard stage 3:*/ |
203 | 0 | _buf[0*8+i]=(ogg_int16_t)(t0+t1); |
204 | 0 | _buf[1*8+i]=(ogg_int16_t)(t0-t1); |
205 | 0 | _buf[2*8+i]=(ogg_int16_t)(t2+t3); |
206 | 0 | _buf[3*8+i]=(ogg_int16_t)(t2-t3); |
207 | 0 | _buf[4*8+i]=(ogg_int16_t)(t4+t5); |
208 | 0 | _buf[5*8+i]=(ogg_int16_t)(t4-t5); |
209 | 0 | _buf[6*8+i]=(ogg_int16_t)(t6+t7); |
210 | 0 | _buf[7*8+i]=(ogg_int16_t)(t6-t7); |
211 | 0 | _src+=_ystride; |
212 | 0 | _ref1+=_ystride; |
213 | 0 | _ref2+=_ystride; |
214 | 0 | } |
215 | 0 | } |
216 | | |
217 | | static void oc_intra_hadamard(ogg_int16_t _buf[64],const unsigned char *_src, |
218 | 0 | int _ystride){ |
219 | 0 | int i; |
220 | 0 | for(i=0;i<8;i++){ |
221 | 0 | int t0; |
222 | 0 | int t1; |
223 | 0 | int t2; |
224 | 0 | int t3; |
225 | 0 | int t4; |
226 | 0 | int t5; |
227 | 0 | int t6; |
228 | 0 | int t7; |
229 | 0 | int r; |
230 | | /*Hadamard stage 1:*/ |
231 | 0 | t0=_src[0]+_src[4]; |
232 | 0 | t4=_src[0]-_src[4]; |
233 | 0 | t1=_src[1]+_src[5]; |
234 | 0 | t5=_src[1]-_src[5]; |
235 | 0 | t2=_src[2]+_src[6]; |
236 | 0 | t6=_src[2]-_src[6]; |
237 | 0 | t3=_src[3]+_src[7]; |
238 | 0 | t7=_src[3]-_src[7]; |
239 | | /*Hadamard stage 2:*/ |
240 | 0 | r=t0; |
241 | 0 | t0+=t2; |
242 | 0 | t2=r-t2; |
243 | 0 | r=t1; |
244 | 0 | t1+=t3; |
245 | 0 | t3=r-t3; |
246 | 0 | r=t4; |
247 | 0 | t4+=t6; |
248 | 0 | t6=r-t6; |
249 | 0 | r=t5; |
250 | 0 | t5+=t7; |
251 | 0 | t7=r-t7; |
252 | | /*Hadamard stage 3:*/ |
253 | 0 | _buf[0*8+i]=(ogg_int16_t)(t0+t1); |
254 | 0 | _buf[1*8+i]=(ogg_int16_t)(t0-t1); |
255 | 0 | _buf[2*8+i]=(ogg_int16_t)(t2+t3); |
256 | 0 | _buf[3*8+i]=(ogg_int16_t)(t2-t3); |
257 | 0 | _buf[4*8+i]=(ogg_int16_t)(t4+t5); |
258 | 0 | _buf[5*8+i]=(ogg_int16_t)(t4-t5); |
259 | 0 | _buf[6*8+i]=(ogg_int16_t)(t6+t7); |
260 | 0 | _buf[7*8+i]=(ogg_int16_t)(t6-t7); |
261 | 0 | _src+=_ystride; |
262 | 0 | } |
263 | 0 | } |
264 | | |
265 | 0 | unsigned oc_hadamard_sad(int *_dc,const ogg_int16_t _buf[64]){ |
266 | 0 | unsigned sad; |
267 | 0 | int dc; |
268 | 0 | int t0; |
269 | 0 | int t1; |
270 | 0 | int t2; |
271 | 0 | int t3; |
272 | 0 | int t4; |
273 | 0 | int t5; |
274 | 0 | int t6; |
275 | 0 | int t7; |
276 | 0 | int r; |
277 | 0 | int i; |
278 | 0 | sad=dc=0; |
279 | 0 | for(i=0;i<8;i++){ |
280 | | /*Hadamard stage 1:*/ |
281 | 0 | t0=_buf[i*8+0]+_buf[i*8+4]; |
282 | 0 | t4=_buf[i*8+0]-_buf[i*8+4]; |
283 | 0 | t1=_buf[i*8+1]+_buf[i*8+5]; |
284 | 0 | t5=_buf[i*8+1]-_buf[i*8+5]; |
285 | 0 | t2=_buf[i*8+2]+_buf[i*8+6]; |
286 | 0 | t6=_buf[i*8+2]-_buf[i*8+6]; |
287 | 0 | t3=_buf[i*8+3]+_buf[i*8+7]; |
288 | 0 | t7=_buf[i*8+3]-_buf[i*8+7]; |
289 | | /*Hadamard stage 2:*/ |
290 | 0 | r=t0; |
291 | 0 | t0+=t2; |
292 | 0 | t2=r-t2; |
293 | 0 | r=t1; |
294 | 0 | t1+=t3; |
295 | 0 | t3=r-t3; |
296 | 0 | r=t4; |
297 | 0 | t4+=t6; |
298 | 0 | t6=r-t6; |
299 | 0 | r=t5; |
300 | 0 | t5+=t7; |
301 | 0 | t7=r-t7; |
302 | | /*Hadamard stage 3:*/ |
303 | 0 | r=abs(t0+t1)&-(i>0); |
304 | 0 | r+=abs(t0-t1); |
305 | 0 | r+=abs(t2+t3); |
306 | 0 | r+=abs(t2-t3); |
307 | 0 | r+=abs(t4+t5); |
308 | 0 | r+=abs(t4-t5); |
309 | 0 | r+=abs(t6+t7); |
310 | 0 | r+=abs(t6-t7); |
311 | 0 | sad+=r; |
312 | 0 | } |
313 | 0 | dc=_buf[0]+_buf[1]+_buf[2]+_buf[3]+_buf[4]+_buf[5]+_buf[6]+_buf[7]; |
314 | 0 | *_dc=dc; |
315 | 0 | return sad; |
316 | 0 | } |
317 | | |
318 | | unsigned oc_enc_frag_satd_c(int *_dc,const unsigned char *_src, |
319 | 0 | const unsigned char *_ref,int _ystride){ |
320 | 0 | ogg_int16_t buf[64]; |
321 | 0 | oc_diff_hadamard(buf,_src,_ref,_ystride); |
322 | 0 | return oc_hadamard_sad(_dc,buf); |
323 | 0 | } |
324 | | |
325 | | unsigned oc_enc_frag_satd2_c(int *_dc,const unsigned char *_src, |
326 | 0 | const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){ |
327 | 0 | ogg_int16_t buf[64]; |
328 | 0 | oc_diff_hadamard2(buf,_src,_ref1,_ref2,_ystride); |
329 | 0 | return oc_hadamard_sad(_dc,buf); |
330 | 0 | } |
331 | | |
332 | | unsigned oc_enc_frag_intra_satd_c(int *_dc, |
333 | 0 | const unsigned char *_src,int _ystride){ |
334 | 0 | ogg_int16_t buf[64]; |
335 | 0 | oc_intra_hadamard(buf,_src,_ystride); |
336 | 0 | return oc_hadamard_sad(_dc,buf); |
337 | 0 | } |
338 | | |
339 | | unsigned oc_enc_frag_ssd_c(const unsigned char *_src, |
340 | 0 | const unsigned char *_ref,int _ystride){ |
341 | 0 | unsigned ret; |
342 | 0 | int y; |
343 | 0 | int x; |
344 | 0 | ret=0; |
345 | 0 | for(y=0;y<8;y++){ |
346 | 0 | for(x=0;x<8;x++)ret+=(_src[x]-_ref[x])*(_src[x]-_ref[x]); |
347 | 0 | _src+=_ystride; |
348 | 0 | _ref+=_ystride; |
349 | 0 | } |
350 | 0 | return ret; |
351 | 0 | } |
352 | | |
353 | | unsigned oc_enc_frag_border_ssd_c(const unsigned char *_src, |
354 | 0 | const unsigned char *_ref,int _ystride,ogg_int64_t _mask){ |
355 | 0 | unsigned ret; |
356 | 0 | int y; |
357 | 0 | int x; |
358 | 0 | ret=0; |
359 | 0 | for(y=0;y<8;y++){ |
360 | 0 | for(x=0;x<8;x++,_mask>>=1){ |
361 | 0 | if(_mask&1)ret+=(_src[x]-_ref[x])*(_src[x]-_ref[x]); |
362 | 0 | } |
363 | 0 | _src+=_ystride; |
364 | 0 | _ref+=_ystride; |
365 | 0 | } |
366 | 0 | return ret; |
367 | 0 | } |
368 | | |
369 | | void oc_enc_frag_copy2_c(unsigned char *_dst, |
370 | 0 | const unsigned char *_src1,const unsigned char *_src2,int _ystride){ |
371 | 0 | int i; |
372 | 0 | int j; |
373 | 0 | for(i=8;i-->0;){ |
374 | 0 | for(j=0;j<8;j++)_dst[j]=_src1[j]+_src2[j]>>1; |
375 | 0 | _dst+=_ystride; |
376 | 0 | _src1+=_ystride; |
377 | 0 | _src2+=_ystride; |
378 | 0 | } |
379 | 0 | } |