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