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