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 FILES *
37  *==============*/
38 
39 #include "pm_c_util.h"
40 #include "all.h"
41 #include "mtypes.h"
42 #include "frames.h"
43 #include "bitio.h"
44 #include "prototypes.h"
45 
46 #include "subsample.h"
47 
48 
49 static void
computePrevFyFx(MpegFrame * const prevFrame,int const by,int const bx,vector const m,uint8 *** const prevP,int * const fyP,int * const fxP)50 computePrevFyFx(MpegFrame * const prevFrame,
51                 int         const by,
52                 int         const bx,
53                 vector      const m,
54                 uint8 ***   const prevP,
55                 int *       const fyP,
56                 int *       const fxP) {
57 
58     boolean const xHalf = (ABS(m.x) % 2 == 1);
59     boolean const yHalf = (ABS(m.y) % 2 == 1);
60 
61     MotionToFrameCoord(by, bx, m.y/2, m.x/2, fyP, fxP);
62 
63     if (xHalf) {
64         if (m.x < 0)
65             --*fxP;
66 
67         if (yHalf) {
68             if (m.y < 0)
69                 --*fyP;
70 
71             *prevP = prevFrame->halfBoth;
72         } else
73             *prevP = prevFrame->halfX;
74     } else if (yHalf) {
75         if (m.y < 0)
76             --*fyP;
77 
78         *prevP = prevFrame->halfY;
79     } else
80         *prevP = prevFrame->ref_y;
81 }
82 
83 
84 
85 static int32
evenColDiff(const uint8 * const macross,const int32 * const currentRow)86 evenColDiff(const uint8 * const macross,
87             const int32 * const currentRow) {
88 
89     return 0
90         + ABS(macross[ 0] - currentRow[ 0])
91         + ABS(macross[ 2] - currentRow[ 2])
92         + ABS(macross[ 4] - currentRow[ 4])
93         + ABS(macross[ 6] - currentRow[ 6])
94         + ABS(macross[ 8] - currentRow[ 8])
95         + ABS(macross[10] - currentRow[10])
96         + ABS(macross[12] - currentRow[12])
97         + ABS(macross[14] - currentRow[14]);
98 }
99 
100 
101 
102 static int32
oddColDiff(const uint8 * const macross,const int32 * const currentRow)103 oddColDiff(const uint8 * const macross,
104            const int32 * const currentRow) {
105 
106     return 0
107         + ABS(macross[ 1] - currentRow[ 1])
108         + ABS(macross[ 3] - currentRow[ 3])
109         + ABS(macross[ 5] - currentRow[ 5])
110         + ABS(macross[ 7] - currentRow[ 7])
111         + ABS(macross[ 9] - currentRow[ 9])
112         + ABS(macross[11] - currentRow[11])
113         + ABS(macross[13] - currentRow[13])
114         + ABS(macross[15] - currentRow[15]);
115 }
116 
117 
118 
119 /*===========================================================================*
120  *
121  * LumMotionErrorA
122  *
123  *  compute the motion error for the A subsampling pattern
124  *
125  * RETURNS: the error, or some number greater if it is worse
126  *
127  * SIDE EFFECTS:    none
128  *
129  *===========================================================================*/
130 int32
LumMotionErrorA(const LumBlock * const currentBlockP,MpegFrame * const prevFrame,int const by,int const bx,vector const m,int32 const bestSoFar)131 LumMotionErrorA(const LumBlock * const currentBlockP,
132                 MpegFrame *      const prevFrame,
133                 int              const by,
134                 int              const bx,
135                 vector           const m,
136                 int32            const bestSoFar) {
137 
138     int32 diff; /* max value of diff is 255*256 = 65280 */
139     uint8 ** prev;
140     int fy, fx;
141     unsigned int rowNumber;
142 
143     computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
144 
145     diff = 0;  /* initial value */
146 
147     for (rowNumber = 0; rowNumber < 16; rowNumber +=2) {
148         uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
149         const int32 * const currentRow = currentBlockP->l[rowNumber];
150 
151         diff += evenColDiff(macross, currentRow);
152 
153         if (diff > bestSoFar)
154             return diff;
155     }
156     return diff;
157 }
158 
159 
160 
161 /*===========================================================================*
162  *
163  * LumMotionErrorB
164  *
165  *  compute the motion error for the B subsampling pattern
166  *
167  * RETURNS: the error, or some number greater if it is worse
168  *
169  * SIDE EFFECTS:    none
170  *
171  *===========================================================================*/
172 int32
LumMotionErrorB(const LumBlock * const currentBlockP,MpegFrame * const prevFrame,int const by,int const bx,vector const m,int32 const bestSoFar)173 LumMotionErrorB(const LumBlock * const currentBlockP,
174                 MpegFrame *      const prevFrame,
175                 int              const by,
176                 int              const bx,
177                 vector           const m,
178                 int32            const bestSoFar) {
179 
180     int32 diff;  /* max value of diff is 255*256 = 65280 */
181     uint8 **prev;
182     int fy, fx;
183     unsigned int rowNumber;
184 
185     computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
186 
187     diff = 0;  /* initial value */
188 
189     for (rowNumber = 0; rowNumber < 16; rowNumber +=2) {
190         uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
191         const int32 * const currentRow = currentBlockP->l[rowNumber];
192 
193         diff += oddColDiff(macross, currentRow);
194 
195         if (diff > bestSoFar)
196             return diff;
197     }
198     return diff;
199 }
200 
201 
202 /*===========================================================================*
203  *
204  * LumMotionErrorC
205  *
206  *  compute the motion error for the C subsampling pattern
207  *
208  * RETURNS: the error, or some number greater if it is worse
209  *
210  * SIDE EFFECTS:    none
211  *
212  *===========================================================================*/
213 int32
LumMotionErrorC(const LumBlock * const currentBlockP,MpegFrame * const prevFrame,int const by,int const bx,vector const m,int32 const bestSoFar)214 LumMotionErrorC(const LumBlock * const currentBlockP,
215                 MpegFrame *      const prevFrame,
216                 int              const by,
217                 int              const bx,
218                 vector           const m,
219                 int32            const bestSoFar) {
220 
221     int32 diff;        /* max value of diff is 255*256 = 65280 */
222     uint8 **prev;
223     int fy, fx;
224     unsigned int rowNumber;
225 
226     computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
227 
228     diff = 0;  /* initial value */
229 
230     for (rowNumber = 1; rowNumber < 16; rowNumber +=2) {
231         uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
232         const int32 * const currentRow = currentBlockP->l[rowNumber];
233 
234         diff += evenColDiff(macross, currentRow);
235 
236         if (diff > bestSoFar)
237             return diff;
238     }
239     return diff;
240 }
241 
242 
243 /*===========================================================================*
244  *
245  * LumMotionErrorD
246  *
247  *  compute the motion error for the D subsampling pattern
248  *
249  * RETURNS: the error, or some number greater if it is worse
250  *
251  * SIDE EFFECTS:    none
252  *
253  *===========================================================================*/
254 int32
LumMotionErrorD(const LumBlock * const currentBlockP,MpegFrame * const prevFrame,int const by,int const bx,vector const m,int32 const bestSoFar)255 LumMotionErrorD(const LumBlock * const currentBlockP,
256                 MpegFrame *      const prevFrame,
257                 int              const by,
258                 int              const bx,
259                 vector           const m,
260                 int32            const bestSoFar) {
261 
262     int32 diff;     /* max value of diff is 255*256 = 65280 */
263     uint8 ** prev;
264     int fy, fx;
265     unsigned int rowNumber;
266 
267     computePrevFyFx(prevFrame, by, bx, m, &prev, &fy, &fx);
268 
269     diff = 0;  /* initial value */
270 
271     for (rowNumber = 1; rowNumber < 16; rowNumber +=2) {
272         uint8 *       const macross    = &(prev[fy + rowNumber][fx]);
273         const int32 * const currentRow = currentBlockP->l[rowNumber];
274 
275         diff += oddColDiff(macross, currentRow);
276 
277         if (diff > bestSoFar)
278             return diff;
279     }
280     return diff;
281 }
282