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