1 /*===========================================================================*
2  * subsample.c								     *
3  *									     *
4  *	Procedures concerned with subsampling				     *
5  *									     *
6  * EXPORTED PROCEDURES:							     *
7  *	LumMotionErrorA							     *
8  *	LumMotionErrorB							     *
9  *	LumMotionErrorC							     *
10  *	LumMotionErrorD							     *
11  *									     *
12  *===========================================================================*/
13 
14 /*
15  * Copyright (c) 1995 The Regents of the University of California.
16  * All rights reserved.
17  *
18  * Permission to use, copy, modify, and distribute this software and its
19  * documentation for any purpose, without fee, and without written agreement is
20  * hereby granted, provided that the above copyright notice and the following
21  * two paragraphs appear in all copies of this software.
22  *
23  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
24  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
25  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
26  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
29  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
30  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
31  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
32  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
33  */
34 
35 /*
36  *  $Header$
37  *  $Log$
38  *  Revision 1.5  2004/04/02 15:12:41  rwcox
39  *  Cput
40  *
41  *  Revision 1.4  2004/02/05 21:32:23  rwcox
42  *  Cput
43  *
44  *  Revision 1.3  2003/12/23 13:50:08  rwcox
45  *  Cput
46  *
47  *  Revision 1.2  2003/12/03 14:46:14  rwcox
48  *  Cput
49  *
50  *  Revision 1.1  2001/12/17 16:11:55  rwcox
51  *  Cadd
52  *
53  * Revision 1.6  1995/01/19  23:09:28  eyhung
54  * Changed copyrights
55  *
56  * Revision 1.5  1994/11/12  02:12:01  keving
57  * nothing
58  *
59  * Revision 1.4  1993/12/22  19:19:01  keving
60  * nothing
61  *
62  * Revision 1.4  1993/12/22  19:19:01  keving
63  * nothing
64  *
65  * Revision 1.3  1993/07/22  22:23:43  keving
66  * nothing
67  *
68  * Revision 1.2  1993/06/30  20:06:09  keving
69  * nothing
70  *
71  * Revision 1.1  1993/06/22  21:56:05  keving
72  * nothing
73  *
74  */
75 
76 
77 /*==============*
78  * HEADER FILES *
79  *==============*/
80 
81 #include "all.h"
82 #include "mtypes.h"
83 #include "frames.h"
84 #include "bitio.h"
85 #include "prototypes.h"
86 
87 #undef ABS
88 #define ABS(x)	((x < 0) ? (-x) : x)
89 
90 
91 /*=====================*
92  * EXPORTED PROCEDURES *
93  *=====================*/
94 
95 
96 /*===========================================================================*
97  *
98  * LumMotionErrorA
99  *
100  *	compute the motion error for the A subsampling pattern
101  *
102  * RETURNS:	the error, or some number greater if it is worse
103  *
104  * SIDE EFFECTS:    none
105  *
106  *===========================================================================*/
107 int32
LumMotionErrorA(currentBlock,prevFrame,by,bx,my,mx,bestSoFar)108 LumMotionErrorA(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
109     LumBlock currentBlock;
110     MpegFrame *prevFrame;
111     int by;
112     int bx;
113     int my;
114     int mx;
115     int32 bestSoFar;
116 {
117     register int32    diff = 0;	    /* max value of diff is 255*256 = 65280 */
118     register int32 localDiff;
119     register uint8 *macross;
120     register uint8 **prev;
121     register int    fy, fx;
122     boolean xHalf, yHalf;
123 
124     xHalf = (ABS(mx) % 2 == 1);
125     yHalf = (ABS(my) % 2 == 1);
126 
127     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
128 
129     if ( xHalf ) {
130 	if ( mx < 0 ) {
131 	    fx--;
132 	}
133 
134 	if ( yHalf ) {
135 	    if ( my < 0 ) {
136 		fy--;
137 	    }
138 
139 	    prev = prevFrame->halfBoth;
140 	} else {
141 	    prev = prevFrame->halfX;
142 	}
143     } else if ( yHalf ) {
144 	if ( my < 0 ) {
145 	    fy--;
146 	}
147 
148 	prev = prevFrame->halfY;
149     } else {
150 	prev = prevFrame->ref_y;
151     }
152 
153     macross = &(prev[fy][fx]);
154 
155     localDiff = macross[0]-currentBlock[0][0];     diff += ABS(localDiff);
156     localDiff = macross[2]-currentBlock[0][2];     diff += ABS(localDiff);
157     localDiff = macross[4]-currentBlock[0][4];     diff += ABS(localDiff);
158     localDiff = macross[6]-currentBlock[0][6];     diff += ABS(localDiff);
159     localDiff = macross[8]-currentBlock[0][8];     diff += ABS(localDiff);
160     localDiff = macross[10]-currentBlock[0][10];     diff += ABS(localDiff);
161     localDiff = macross[12]-currentBlock[0][12];     diff += ABS(localDiff);
162     localDiff = macross[14]-currentBlock[0][14];     diff += ABS(localDiff);
163 
164     if ( diff > bestSoFar ) {
165 	return diff;
166     }
167 
168     macross = &(prev[fy+2][fx]);
169 
170     localDiff = macross[0]-currentBlock[2][0];     diff += ABS(localDiff);
171     localDiff = macross[2]-currentBlock[2][2];     diff += ABS(localDiff);
172     localDiff = macross[4]-currentBlock[2][4];     diff += ABS(localDiff);
173     localDiff = macross[6]-currentBlock[2][6];     diff += ABS(localDiff);
174     localDiff = macross[8]-currentBlock[2][8];     diff += ABS(localDiff);
175     localDiff = macross[10]-currentBlock[2][10];     diff += ABS(localDiff);
176     localDiff = macross[12]-currentBlock[2][12];     diff += ABS(localDiff);
177     localDiff = macross[14]-currentBlock[2][14];     diff += ABS(localDiff);
178 
179     if ( diff > bestSoFar ) {
180 	return diff;
181     }
182 
183     macross = &(prev[fy+4][fx]);
184 
185     localDiff = macross[0]-currentBlock[4][0];     diff += ABS(localDiff);
186     localDiff = macross[2]-currentBlock[4][2];     diff += ABS(localDiff);
187     localDiff = macross[4]-currentBlock[4][4];     diff += ABS(localDiff);
188     localDiff = macross[6]-currentBlock[4][6];     diff += ABS(localDiff);
189     localDiff = macross[8]-currentBlock[4][8];     diff += ABS(localDiff);
190     localDiff = macross[10]-currentBlock[4][10];     diff += ABS(localDiff);
191     localDiff = macross[12]-currentBlock[4][12];     diff += ABS(localDiff);
192     localDiff = macross[14]-currentBlock[4][14];     diff += ABS(localDiff);
193 
194     if ( diff > bestSoFar ) {
195 	return diff;
196     }
197 
198     macross = &(prev[fy+6][fx]);
199 
200     localDiff = macross[0]-currentBlock[6][0];     diff += ABS(localDiff);
201     localDiff = macross[2]-currentBlock[6][2];     diff += ABS(localDiff);
202     localDiff = macross[4]-currentBlock[6][4];     diff += ABS(localDiff);
203     localDiff = macross[6]-currentBlock[6][6];     diff += ABS(localDiff);
204     localDiff = macross[8]-currentBlock[6][8];     diff += ABS(localDiff);
205     localDiff = macross[10]-currentBlock[6][10];     diff += ABS(localDiff);
206     localDiff = macross[12]-currentBlock[6][12];     diff += ABS(localDiff);
207     localDiff = macross[14]-currentBlock[6][14];     diff += ABS(localDiff);
208 
209     if ( diff > bestSoFar ) {
210 	return diff;
211     }
212 
213     macross = &(prev[fy+8][fx]);
214 
215     localDiff = macross[0]-currentBlock[8][0];     diff += ABS(localDiff);
216     localDiff = macross[2]-currentBlock[8][2];     diff += ABS(localDiff);
217     localDiff = macross[4]-currentBlock[8][4];     diff += ABS(localDiff);
218     localDiff = macross[6]-currentBlock[8][6];     diff += ABS(localDiff);
219     localDiff = macross[8]-currentBlock[8][8];     diff += ABS(localDiff);
220     localDiff = macross[10]-currentBlock[8][10];     diff += ABS(localDiff);
221     localDiff = macross[12]-currentBlock[8][12];     diff += ABS(localDiff);
222     localDiff = macross[14]-currentBlock[8][14];     diff += ABS(localDiff);
223 
224     if ( diff > bestSoFar ) {
225 	return diff;
226     }
227 
228     macross = &(prev[fy+10][fx]);
229 
230     localDiff = macross[0]-currentBlock[10][0];     diff += ABS(localDiff);
231     localDiff = macross[2]-currentBlock[10][2];     diff += ABS(localDiff);
232     localDiff = macross[4]-currentBlock[10][4];     diff += ABS(localDiff);
233     localDiff = macross[6]-currentBlock[10][6];     diff += ABS(localDiff);
234     localDiff = macross[8]-currentBlock[10][8];     diff += ABS(localDiff);
235     localDiff = macross[10]-currentBlock[10][10];     diff += ABS(localDiff);
236     localDiff = macross[12]-currentBlock[10][12];     diff += ABS(localDiff);
237     localDiff = macross[14]-currentBlock[10][14];     diff += ABS(localDiff);
238 
239     if ( diff > bestSoFar ) {
240 	return diff;
241     }
242 
243     macross = &(prev[fy+12][fx]);
244 
245     localDiff = macross[0]-currentBlock[12][0];     diff += ABS(localDiff);
246     localDiff = macross[2]-currentBlock[12][2];     diff += ABS(localDiff);
247     localDiff = macross[4]-currentBlock[12][4];     diff += ABS(localDiff);
248     localDiff = macross[6]-currentBlock[12][6];     diff += ABS(localDiff);
249     localDiff = macross[8]-currentBlock[12][8];     diff += ABS(localDiff);
250     localDiff = macross[10]-currentBlock[12][10];     diff += ABS(localDiff);
251     localDiff = macross[12]-currentBlock[12][12];     diff += ABS(localDiff);
252     localDiff = macross[14]-currentBlock[12][14];     diff += ABS(localDiff);
253 
254     if ( diff > bestSoFar ) {
255 	return diff;
256     }
257 
258     macross = &(prev[fy+14][fx]);
259 
260     localDiff = macross[0]-currentBlock[14][0];     diff += ABS(localDiff);
261     localDiff = macross[2]-currentBlock[14][2];     diff += ABS(localDiff);
262     localDiff = macross[4]-currentBlock[14][4];     diff += ABS(localDiff);
263     localDiff = macross[6]-currentBlock[14][6];     diff += ABS(localDiff);
264     localDiff = macross[8]-currentBlock[14][8];     diff += ABS(localDiff);
265     localDiff = macross[10]-currentBlock[14][10];     diff += ABS(localDiff);
266     localDiff = macross[12]-currentBlock[14][12];     diff += ABS(localDiff);
267     localDiff = macross[14]-currentBlock[14][14];     diff += ABS(localDiff);
268 
269     return diff;
270 }
271 
272 
273 /*===========================================================================*
274  *
275  * LumMotionErrorB
276  *
277  *	compute the motion error for the B subsampling pattern
278  *
279  * RETURNS:	the error, or some number greater if it is worse
280  *
281  * SIDE EFFECTS:    none
282  *
283  *===========================================================================*/
284 int32
LumMotionErrorB(currentBlock,prevFrame,by,bx,my,mx,bestSoFar)285 LumMotionErrorB(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
286     LumBlock currentBlock;
287     MpegFrame *prevFrame;
288     int by;
289     int bx;
290     int my;
291     int mx;
292     int32 bestSoFar;
293 {
294     register int32    diff = 0;	    /* max value of diff is 255*256 = 65280 */
295     register int32 localDiff;
296     register uint8 *macross;
297     register uint8 **prev;
298     register int    fy, fx;
299     boolean xHalf, yHalf;
300 
301     xHalf = (ABS(mx) % 2 == 1);
302     yHalf = (ABS(my) % 2 == 1);
303 
304     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
305 
306     if ( xHalf ) {
307 	if ( mx < 0 ) {
308 	    fx--;
309 	}
310 
311 	if ( yHalf ) {
312 	    if ( my < 0 ) {
313 		fy--;
314 	    }
315 
316 	    prev = prevFrame->halfBoth;
317 	} else {
318 	    prev = prevFrame->halfX;
319 	}
320     } else if ( yHalf ) {
321 	if ( my < 0 ) {
322 	    fy--;
323 	}
324 
325 	prev = prevFrame->halfY;
326     } else {
327 	prev = prevFrame->ref_y;
328     }
329 
330     macross = &(prev[fy+0][fx]);
331 
332     localDiff = macross[1]-currentBlock[0][1];     diff += ABS(localDiff);
333     localDiff = macross[3]-currentBlock[0][3];     diff += ABS(localDiff);
334     localDiff = macross[5]-currentBlock[0][5];     diff += ABS(localDiff);
335     localDiff = macross[7]-currentBlock[0][7];     diff += ABS(localDiff);
336     localDiff = macross[9]-currentBlock[0][9];     diff += ABS(localDiff);
337     localDiff = macross[11]-currentBlock[0][11];     diff += ABS(localDiff);
338     localDiff = macross[13]-currentBlock[0][13];     diff += ABS(localDiff);
339     localDiff = macross[15]-currentBlock[0][15];     diff += ABS(localDiff);
340 
341     if ( diff > bestSoFar ) {
342 	return diff;
343     }
344 
345     macross = &(prev[fy+2][fx]);
346 
347     localDiff = macross[1]-currentBlock[2][1];     diff += ABS(localDiff);
348     localDiff = macross[3]-currentBlock[2][3];     diff += ABS(localDiff);
349     localDiff = macross[5]-currentBlock[2][5];     diff += ABS(localDiff);
350     localDiff = macross[7]-currentBlock[2][7];     diff += ABS(localDiff);
351     localDiff = macross[9]-currentBlock[2][9];     diff += ABS(localDiff);
352     localDiff = macross[11]-currentBlock[2][11];     diff += ABS(localDiff);
353     localDiff = macross[13]-currentBlock[2][13];     diff += ABS(localDiff);
354     localDiff = macross[15]-currentBlock[2][15];     diff += ABS(localDiff);
355 
356     if ( diff > bestSoFar ) {
357 	return diff;
358     }
359 
360     macross = &(prev[fy+4][fx]);
361 
362     localDiff = macross[1]-currentBlock[4][1];     diff += ABS(localDiff);
363     localDiff = macross[3]-currentBlock[4][3];     diff += ABS(localDiff);
364     localDiff = macross[5]-currentBlock[4][5];     diff += ABS(localDiff);
365     localDiff = macross[7]-currentBlock[4][7];     diff += ABS(localDiff);
366     localDiff = macross[9]-currentBlock[4][9];     diff += ABS(localDiff);
367     localDiff = macross[11]-currentBlock[4][11];     diff += ABS(localDiff);
368     localDiff = macross[13]-currentBlock[4][13];     diff += ABS(localDiff);
369     localDiff = macross[15]-currentBlock[4][15];     diff += ABS(localDiff);
370 
371     if ( diff > bestSoFar ) {
372 	return diff;
373     }
374 
375     macross = &(prev[fy+6][fx]);
376 
377     localDiff = macross[1]-currentBlock[6][1];     diff += ABS(localDiff);
378     localDiff = macross[3]-currentBlock[6][3];     diff += ABS(localDiff);
379     localDiff = macross[5]-currentBlock[6][5];     diff += ABS(localDiff);
380     localDiff = macross[7]-currentBlock[6][7];     diff += ABS(localDiff);
381     localDiff = macross[9]-currentBlock[6][9];     diff += ABS(localDiff);
382     localDiff = macross[11]-currentBlock[6][11];     diff += ABS(localDiff);
383     localDiff = macross[13]-currentBlock[6][13];     diff += ABS(localDiff);
384     localDiff = macross[15]-currentBlock[6][15];     diff += ABS(localDiff);
385 
386     if ( diff > bestSoFar ) {
387 	return diff;
388     }
389 
390     macross = &(prev[fy+8][fx]);
391 
392     localDiff = macross[1]-currentBlock[8][1];     diff += ABS(localDiff);
393     localDiff = macross[3]-currentBlock[8][3];     diff += ABS(localDiff);
394     localDiff = macross[5]-currentBlock[8][5];     diff += ABS(localDiff);
395     localDiff = macross[7]-currentBlock[8][7];     diff += ABS(localDiff);
396     localDiff = macross[9]-currentBlock[8][9];     diff += ABS(localDiff);
397     localDiff = macross[11]-currentBlock[8][11];     diff += ABS(localDiff);
398     localDiff = macross[13]-currentBlock[8][13];     diff += ABS(localDiff);
399     localDiff = macross[15]-currentBlock[8][15];     diff += ABS(localDiff);
400 
401     if ( diff > bestSoFar ) {
402 	return diff;
403     }
404 
405     macross = &(prev[fy+10][fx]);
406 
407     localDiff = macross[1]-currentBlock[10][1];     diff += ABS(localDiff);
408     localDiff = macross[3]-currentBlock[10][3];     diff += ABS(localDiff);
409     localDiff = macross[5]-currentBlock[10][5];     diff += ABS(localDiff);
410     localDiff = macross[7]-currentBlock[10][7];     diff += ABS(localDiff);
411     localDiff = macross[9]-currentBlock[10][9];     diff += ABS(localDiff);
412     localDiff = macross[11]-currentBlock[10][11];     diff += ABS(localDiff);
413     localDiff = macross[13]-currentBlock[10][13];     diff += ABS(localDiff);
414     localDiff = macross[15]-currentBlock[10][15];     diff += ABS(localDiff);
415 
416     if ( diff > bestSoFar ) {
417 	return diff;
418     }
419 
420     macross = &(prev[fy+12][fx]);
421 
422     localDiff = macross[1]-currentBlock[12][1];     diff += ABS(localDiff);
423     localDiff = macross[3]-currentBlock[12][3];     diff += ABS(localDiff);
424     localDiff = macross[5]-currentBlock[12][5];     diff += ABS(localDiff);
425     localDiff = macross[7]-currentBlock[12][7];     diff += ABS(localDiff);
426     localDiff = macross[9]-currentBlock[12][9];     diff += ABS(localDiff);
427     localDiff = macross[11]-currentBlock[12][11];     diff += ABS(localDiff);
428     localDiff = macross[13]-currentBlock[12][13];     diff += ABS(localDiff);
429     localDiff = macross[15]-currentBlock[12][15];     diff += ABS(localDiff);
430 
431     if ( diff > bestSoFar ) {
432 	return diff;
433     }
434 
435     macross = &(prev[fy+14][fx]);
436 
437     localDiff = macross[1]-currentBlock[14][1];     diff += ABS(localDiff);
438     localDiff = macross[3]-currentBlock[14][3];     diff += ABS(localDiff);
439     localDiff = macross[5]-currentBlock[14][5];     diff += ABS(localDiff);
440     localDiff = macross[7]-currentBlock[14][7];     diff += ABS(localDiff);
441     localDiff = macross[9]-currentBlock[14][9];     diff += ABS(localDiff);
442     localDiff = macross[11]-currentBlock[14][11];     diff += ABS(localDiff);
443     localDiff = macross[13]-currentBlock[14][13];     diff += ABS(localDiff);
444     localDiff = macross[15]-currentBlock[14][15];     diff += ABS(localDiff);
445 
446     return diff;
447 }
448 
449 
450 /*===========================================================================*
451  *
452  * LumMotionErrorC
453  *
454  *	compute the motion error for the C subsampling pattern
455  *
456  * RETURNS:	the error, or some number greater if it is worse
457  *
458  * SIDE EFFECTS:    none
459  *
460  *===========================================================================*/
461 int32
LumMotionErrorC(currentBlock,prevFrame,by,bx,my,mx,bestSoFar)462 LumMotionErrorC(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
463     LumBlock currentBlock;
464     MpegFrame *prevFrame;
465     int by;
466     int bx;
467     int my;
468     int mx;
469     int32 bestSoFar;
470 {
471     register int32    diff = 0;	    /* max value of diff is 255*256 = 65280 */
472     register int32 localDiff;
473     register uint8 *macross;
474     register uint8 **prev;
475     register int    fy, fx;
476     boolean xHalf, yHalf;
477 
478     xHalf = (ABS(mx) % 2 == 1);
479     yHalf = (ABS(my) % 2 == 1);
480 
481     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
482 
483     if ( xHalf ) {
484 	if ( mx < 0 ) {
485 	    fx--;
486 	}
487 
488 	if ( yHalf ) {
489 	    if ( my < 0 ) {
490 		fy--;
491 	    }
492 
493 	    prev = prevFrame->halfBoth;
494 	} else {
495 	    prev = prevFrame->halfX;
496 	}
497     } else if ( yHalf ) {
498 	if ( my < 0 ) {
499 	    fy--;
500 	}
501 
502 	prev = prevFrame->halfY;
503     } else {
504 	prev = prevFrame->ref_y;
505     }
506 
507     macross = &(prev[fy+1][fx]);
508 
509     localDiff = macross[0]-currentBlock[1][0];     diff += ABS(localDiff);
510     localDiff = macross[2]-currentBlock[1][2];     diff += ABS(localDiff);
511     localDiff = macross[4]-currentBlock[1][4];     diff += ABS(localDiff);
512     localDiff = macross[6]-currentBlock[1][6];     diff += ABS(localDiff);
513     localDiff = macross[8]-currentBlock[1][8];     diff += ABS(localDiff);
514     localDiff = macross[10]-currentBlock[1][10];     diff += ABS(localDiff);
515     localDiff = macross[12]-currentBlock[1][12];     diff += ABS(localDiff);
516     localDiff = macross[14]-currentBlock[1][14];     diff += ABS(localDiff);
517 
518     if ( diff > bestSoFar ) {
519 	return diff;
520     }
521 
522     macross = &(prev[fy+3][fx]);
523 
524     localDiff = macross[0]-currentBlock[3][0];     diff += ABS(localDiff);
525     localDiff = macross[2]-currentBlock[3][2];     diff += ABS(localDiff);
526     localDiff = macross[4]-currentBlock[3][4];     diff += ABS(localDiff);
527     localDiff = macross[6]-currentBlock[3][6];     diff += ABS(localDiff);
528     localDiff = macross[8]-currentBlock[3][8];     diff += ABS(localDiff);
529     localDiff = macross[10]-currentBlock[3][10];     diff += ABS(localDiff);
530     localDiff = macross[12]-currentBlock[3][12];     diff += ABS(localDiff);
531     localDiff = macross[14]-currentBlock[3][14];     diff += ABS(localDiff);
532 
533     if ( diff > bestSoFar ) {
534 	return diff;
535     }
536 
537     macross = &(prev[fy+5][fx]);
538 
539     localDiff = macross[0]-currentBlock[5][0];     diff += ABS(localDiff);
540     localDiff = macross[2]-currentBlock[5][2];     diff += ABS(localDiff);
541     localDiff = macross[4]-currentBlock[5][4];     diff += ABS(localDiff);
542     localDiff = macross[6]-currentBlock[5][6];     diff += ABS(localDiff);
543     localDiff = macross[8]-currentBlock[5][8];     diff += ABS(localDiff);
544     localDiff = macross[10]-currentBlock[5][10];     diff += ABS(localDiff);
545     localDiff = macross[12]-currentBlock[5][12];     diff += ABS(localDiff);
546     localDiff = macross[14]-currentBlock[5][14];     diff += ABS(localDiff);
547 
548     if ( diff > bestSoFar ) {
549 	return diff;
550     }
551 
552     macross = &(prev[fy+7][fx]);
553 
554     localDiff = macross[0]-currentBlock[7][0];     diff += ABS(localDiff);
555     localDiff = macross[2]-currentBlock[7][2];     diff += ABS(localDiff);
556     localDiff = macross[4]-currentBlock[7][4];     diff += ABS(localDiff);
557     localDiff = macross[6]-currentBlock[7][6];     diff += ABS(localDiff);
558     localDiff = macross[8]-currentBlock[7][8];     diff += ABS(localDiff);
559     localDiff = macross[10]-currentBlock[7][10];     diff += ABS(localDiff);
560     localDiff = macross[12]-currentBlock[7][12];     diff += ABS(localDiff);
561     localDiff = macross[14]-currentBlock[7][14];     diff += ABS(localDiff);
562 
563     if ( diff > bestSoFar ) {
564 	return diff;
565     }
566 
567     macross = &(prev[fy+9][fx]);
568 
569     localDiff = macross[0]-currentBlock[9][0];     diff += ABS(localDiff);
570     localDiff = macross[2]-currentBlock[9][2];     diff += ABS(localDiff);
571     localDiff = macross[4]-currentBlock[9][4];     diff += ABS(localDiff);
572     localDiff = macross[6]-currentBlock[9][6];     diff += ABS(localDiff);
573     localDiff = macross[8]-currentBlock[9][8];     diff += ABS(localDiff);
574     localDiff = macross[10]-currentBlock[9][10];     diff += ABS(localDiff);
575     localDiff = macross[12]-currentBlock[9][12];     diff += ABS(localDiff);
576     localDiff = macross[14]-currentBlock[9][14];     diff += ABS(localDiff);
577 
578     if ( diff > bestSoFar ) {
579 	return diff;
580     }
581 
582     macross = &(prev[fy+11][fx]);
583 
584     localDiff = macross[0]-currentBlock[11][0];     diff += ABS(localDiff);
585     localDiff = macross[2]-currentBlock[11][2];     diff += ABS(localDiff);
586     localDiff = macross[4]-currentBlock[11][4];     diff += ABS(localDiff);
587     localDiff = macross[6]-currentBlock[11][6];     diff += ABS(localDiff);
588     localDiff = macross[8]-currentBlock[11][8];     diff += ABS(localDiff);
589     localDiff = macross[10]-currentBlock[11][10];     diff += ABS(localDiff);
590     localDiff = macross[12]-currentBlock[11][12];     diff += ABS(localDiff);
591     localDiff = macross[14]-currentBlock[11][14];     diff += ABS(localDiff);
592 
593     if ( diff > bestSoFar ) {
594 	return diff;
595     }
596 
597     macross = &(prev[fy+13][fx]);
598 
599     localDiff = macross[0]-currentBlock[13][0];     diff += ABS(localDiff);
600     localDiff = macross[2]-currentBlock[13][2];     diff += ABS(localDiff);
601     localDiff = macross[4]-currentBlock[13][4];     diff += ABS(localDiff);
602     localDiff = macross[6]-currentBlock[13][6];     diff += ABS(localDiff);
603     localDiff = macross[8]-currentBlock[13][8];     diff += ABS(localDiff);
604     localDiff = macross[10]-currentBlock[13][10];     diff += ABS(localDiff);
605     localDiff = macross[12]-currentBlock[13][12];     diff += ABS(localDiff);
606     localDiff = macross[14]-currentBlock[13][14];     diff += ABS(localDiff);
607 
608     if ( diff > bestSoFar ) {
609 	return diff;
610     }
611 
612     macross = &(prev[fy+15][fx]);
613 
614     localDiff = macross[0]-currentBlock[15][0];     diff += ABS(localDiff);
615     localDiff = macross[2]-currentBlock[15][2];     diff += ABS(localDiff);
616     localDiff = macross[4]-currentBlock[15][4];     diff += ABS(localDiff);
617     localDiff = macross[6]-currentBlock[15][6];     diff += ABS(localDiff);
618     localDiff = macross[8]-currentBlock[15][8];     diff += ABS(localDiff);
619     localDiff = macross[10]-currentBlock[15][10];     diff += ABS(localDiff);
620     localDiff = macross[12]-currentBlock[15][12];     diff += ABS(localDiff);
621     localDiff = macross[14]-currentBlock[15][14];     diff += ABS(localDiff);
622 
623     return diff;
624 }
625 
626 
627 /*===========================================================================*
628  *
629  * LumMotionErrorD
630  *
631  *	compute the motion error for the D subsampling pattern
632  *
633  * RETURNS:	the error, or some number greater if it is worse
634  *
635  * SIDE EFFECTS:    none
636  *
637  *===========================================================================*/
638 int32
LumMotionErrorD(currentBlock,prevFrame,by,bx,my,mx,bestSoFar)639 LumMotionErrorD(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
640     LumBlock currentBlock;
641     MpegFrame *prevFrame;
642     int by;
643     int bx;
644     int my;
645     int mx;
646     int32 bestSoFar;
647 {
648     register int32    diff = 0;	    /* max value of diff is 255*256 = 65280 */
649     register int32 localDiff;
650     register uint8 *macross;
651     register uint8 **prev;
652     register int    fy, fx;
653     boolean xHalf, yHalf;
654 
655     xHalf = (ABS(mx) % 2 == 1);
656     yHalf = (ABS(my) % 2 == 1);
657 
658     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
659 
660     if ( xHalf ) {
661 	if ( mx < 0 ) {
662 	    fx--;
663 	}
664 
665 	if ( yHalf ) {
666 	    if ( my < 0 ) {
667 		fy--;
668 	    }
669 	    prev = prevFrame->halfBoth;
670 	} else {
671 	    prev = prevFrame->halfX;
672 	}
673     } else if ( yHalf ) {
674 	if ( my < 0 ) {
675 	    fy--;
676 	}
677 	prev = prevFrame->halfY;
678     } else {
679 	prev = prevFrame->ref_y;
680     }
681 
682     macross = &(prev[fy+1][fx]);
683 
684     localDiff = macross[1]-currentBlock[1][1];     diff += ABS(localDiff);
685     localDiff = macross[3]-currentBlock[1][3];     diff += ABS(localDiff);
686     localDiff = macross[5]-currentBlock[1][5];     diff += ABS(localDiff);
687     localDiff = macross[7]-currentBlock[1][7];     diff += ABS(localDiff);
688     localDiff = macross[9]-currentBlock[1][9];     diff += ABS(localDiff);
689     localDiff = macross[11]-currentBlock[1][11];     diff += ABS(localDiff);
690     localDiff = macross[13]-currentBlock[1][13];     diff += ABS(localDiff);
691     localDiff = macross[15]-currentBlock[1][15];     diff += ABS(localDiff);
692 
693     if ( diff > bestSoFar ) {
694 	return diff;
695     }
696 
697     macross = &(prev[fy+3][fx]);
698 
699     localDiff = macross[1]-currentBlock[3][1];     diff += ABS(localDiff);
700     localDiff = macross[3]-currentBlock[3][3];     diff += ABS(localDiff);
701     localDiff = macross[5]-currentBlock[3][5];     diff += ABS(localDiff);
702     localDiff = macross[7]-currentBlock[3][7];     diff += ABS(localDiff);
703     localDiff = macross[9]-currentBlock[3][9];     diff += ABS(localDiff);
704     localDiff = macross[11]-currentBlock[3][11];     diff += ABS(localDiff);
705     localDiff = macross[13]-currentBlock[3][13];     diff += ABS(localDiff);
706     localDiff = macross[15]-currentBlock[3][15];     diff += ABS(localDiff);
707 
708     if ( diff > bestSoFar ) {
709 	return diff;
710     }
711 
712     macross = &(prev[fy+5][fx]);
713 
714     localDiff = macross[1]-currentBlock[5][1];     diff += ABS(localDiff);
715     localDiff = macross[3]-currentBlock[5][3];     diff += ABS(localDiff);
716     localDiff = macross[5]-currentBlock[5][5];     diff += ABS(localDiff);
717     localDiff = macross[7]-currentBlock[5][7];     diff += ABS(localDiff);
718     localDiff = macross[9]-currentBlock[5][9];     diff += ABS(localDiff);
719     localDiff = macross[11]-currentBlock[5][11];     diff += ABS(localDiff);
720     localDiff = macross[13]-currentBlock[5][13];     diff += ABS(localDiff);
721     localDiff = macross[15]-currentBlock[5][15];     diff += ABS(localDiff);
722 
723     if ( diff > bestSoFar ) {
724 	return diff;
725     }
726 
727     macross = &(prev[fy+7][fx]);
728 
729     localDiff = macross[1]-currentBlock[7][1];     diff += ABS(localDiff);
730     localDiff = macross[3]-currentBlock[7][3];     diff += ABS(localDiff);
731     localDiff = macross[5]-currentBlock[7][5];     diff += ABS(localDiff);
732     localDiff = macross[7]-currentBlock[7][7];     diff += ABS(localDiff);
733     localDiff = macross[9]-currentBlock[7][9];     diff += ABS(localDiff);
734     localDiff = macross[11]-currentBlock[7][11];     diff += ABS(localDiff);
735     localDiff = macross[13]-currentBlock[7][13];     diff += ABS(localDiff);
736     localDiff = macross[15]-currentBlock[7][15];     diff += ABS(localDiff);
737 
738     if ( diff > bestSoFar ) {
739 	return diff;
740     }
741 
742     macross = &(prev[fy+9][fx]);
743 
744     localDiff = macross[1]-currentBlock[9][1];     diff += ABS(localDiff);
745     localDiff = macross[3]-currentBlock[9][3];     diff += ABS(localDiff);
746     localDiff = macross[5]-currentBlock[9][5];     diff += ABS(localDiff);
747     localDiff = macross[7]-currentBlock[9][7];     diff += ABS(localDiff);
748     localDiff = macross[9]-currentBlock[9][9];     diff += ABS(localDiff);
749     localDiff = macross[11]-currentBlock[9][11];     diff += ABS(localDiff);
750     localDiff = macross[13]-currentBlock[9][13];     diff += ABS(localDiff);
751     localDiff = macross[15]-currentBlock[9][15];     diff += ABS(localDiff);
752 
753     if ( diff > bestSoFar ) {
754 	return diff;
755     }
756 
757     macross = &(prev[fy+11][fx]);
758 
759     localDiff = macross[1]-currentBlock[11][1];     diff += ABS(localDiff);
760     localDiff = macross[3]-currentBlock[11][3];     diff += ABS(localDiff);
761     localDiff = macross[5]-currentBlock[11][5];     diff += ABS(localDiff);
762     localDiff = macross[7]-currentBlock[11][7];     diff += ABS(localDiff);
763     localDiff = macross[9]-currentBlock[11][9];     diff += ABS(localDiff);
764     localDiff = macross[11]-currentBlock[11][11];     diff += ABS(localDiff);
765     localDiff = macross[13]-currentBlock[11][13];     diff += ABS(localDiff);
766     localDiff = macross[15]-currentBlock[11][15];     diff += ABS(localDiff);
767 
768     if ( diff > bestSoFar ) {
769 	return diff;
770     }
771 
772     macross = &(prev[fy+13][fx]);
773 
774     localDiff = macross[1]-currentBlock[13][1];     diff += ABS(localDiff);
775     localDiff = macross[3]-currentBlock[13][3];     diff += ABS(localDiff);
776     localDiff = macross[5]-currentBlock[13][5];     diff += ABS(localDiff);
777     localDiff = macross[7]-currentBlock[13][7];     diff += ABS(localDiff);
778     localDiff = macross[9]-currentBlock[13][9];     diff += ABS(localDiff);
779     localDiff = macross[11]-currentBlock[13][11];     diff += ABS(localDiff);
780     localDiff = macross[13]-currentBlock[13][13];     diff += ABS(localDiff);
781     localDiff = macross[15]-currentBlock[13][15];     diff += ABS(localDiff);
782 
783     if ( diff > bestSoFar ) {
784 	return diff;
785     }
786 
787     macross = &(prev[fy+15][fx]);
788 
789     localDiff = macross[1]-currentBlock[15][1];     diff += ABS(localDiff);
790     localDiff = macross[3]-currentBlock[15][3];     diff += ABS(localDiff);
791     localDiff = macross[5]-currentBlock[15][5];     diff += ABS(localDiff);
792     localDiff = macross[7]-currentBlock[15][7];     diff += ABS(localDiff);
793     localDiff = macross[9]-currentBlock[15][9];     diff += ABS(localDiff);
794     localDiff = macross[11]-currentBlock[15][11];     diff += ABS(localDiff);
795     localDiff = macross[13]-currentBlock[15][13];     diff += ABS(localDiff);
796     localDiff = macross[15]-currentBlock[15][15];     diff += ABS(localDiff);
797 
798     return diff;
799 }
800