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