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