1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 /**
20 * @file
21 *@brief IntraX8 frame subdecoder image manipulation routines
22 */
23
26
27 /*
28 * area positions, #3 is 1 pixel only, other are 8 pixels
29 * |66666666|
30 * 3|44444444|55555555|
31 * - -+--------+--------+
32 * 1 2|XXXXXXXX|
33 * 1 2|XXXXXXXX|
34 * 1 2|XXXXXXXX|
35 * 1 2|XXXXXXXX|
36 * 1 2|XXXXXXXX|
37 * 1 2|XXXXXXXX|
38 * 1 2|XXXXXXXX|
39 * 1 2|XXXXXXXX|
40 * ^-start
41 */
42
46 #define area4 (8 + 8 + 1)
47 #define area5 (8 + 8 + 1 + 8)
48 #define area6 (8 + 8 + 1 + 16)
49
50 /**
51 Collect statistics and prepare the edge pixels required by the other spatial compensation functions.
52
53 * @param src pointer to the beginning of the processed block
54 * @param dst pointer to emu_edge, edge pixels are stored the way other compensation routines do.
55 * @param linesize byte offset between 2 vertical pixels in the source image
56 * @param range pointer to the variable where the edge pixel range is to be stored (max-min values)
57 * @param psum pointer to the variable where the edge pixel sum is to be stored
58 * @param edges Informs this routine that the block is on an image border, so it has to interpolate the missing edge pixels.
59 and some of the edge pixels should be interpolated, the flag has the following meaning:
60 1 - mb_x==0 - first block in the row, interpolate area #1,#2,#3;
61 2 - mb_y==0 - first row, interpolate area #3,#4,#5,#6;
62 note: 1|2 - mb_x==mb_y==0 - first block, use 0x80 value for all areas;
63 4 - mb_x>= (mb_width-1) last block in the row, interpolate area #5;
64 -*/
67 int *psum, int edges)
68 {
69 uint8_t *ptr;
70 int sum;
72 int min_pix, max_pix;
74
75 if ((edges & 3) == 3) {
76 *psum = 0x80 * (8 + 1 + 8 + 2);
78 memset(
dst, 0x80, 16 + 1 + 16 + 8);
79 /* this triggers flat_dc for sure. flat_dc avoids all (other)
80 * prediction modes, but requires dc_level decoding. */
81 return;
82 }
83
84 min_pix = 256;
85 max_pix = -1;
86
87 sum = 0;
88
89 if (!(edges & 1)) { // (mb_x != 0) // there is previous block on this row
90 ptr =
src - 1;
// left column, area 2
91 for (
i = 7;
i >= 0;
i--) {
92 c = *(ptr - 1);
// area1, same mb as area2, no need to check
95
97 min_pix =
FFMIN(min_pix,
c);
98 max_pix =
FFMAX(max_pix,
c);
100
102 }
103 }
104
105 if (!(edges & 2)) { // (mb_y != 0) // there is row above
107 for (
i = 0;
i < 8;
i++) {
110 min_pix =
FFMIN(min_pix,
c);
111 max_pix =
FFMAX(max_pix,
c);
112 }
113 if (edges & 4) { // last block on the row?
114 memset(
dst +
area5,
c, 8);
// set with last pixel fr
116 } else {
117 memcpy(
dst +
area4, ptr, 16);
// both area4 and 5
118 }
119 // area6 always present in the above block
121 }
122 // now calculate the stuff we need
123 if (edges & 3) { // mb_x ==0 || mb_y == 0) {
124 int avg = (sum + 4) >> 3;
125
126 if (edges & 1) // (mb_x == 0) { // implies mb_y !=0
127 memset(
dst +
area1,
avg, 8 + 8 + 1);
// areas 1, 2, 3 are averaged
128 else // implies y == 0 x != 0
129 memset(
dst +
area3,
avg, 1 + 16 + 8);
// areas 3, 4, 5, 6
130
132 } else {
133 // the edge pixel, in the top line and left column
137 // edge pixel is not part of min/max
138 }
139 *
range = max_pix - min_pix;
141 *psum = sum;
142 }
143
145 640, 640, 669, 480, 708, 354, 748, 257,
146 792, 198, 760, 143, 808, 101, 772, 72,
147 480, 669, 537, 537, 598, 416, 661, 316,
148 719, 250, 707, 185, 768, 134, 745, 97,
149 354, 708, 416, 598, 488, 488, 564, 388,
150 634, 317, 642, 241, 716, 179, 706, 132,
151 257, 748, 316, 661, 388, 564, 469, 469,
152 543, 395, 571, 311, 655, 238, 660, 180,
153 198, 792, 250, 719, 317, 634, 395, 543,
154 469, 469, 507, 380, 597, 299, 616, 231,
155 161, 855, 206, 788, 266, 710, 340, 623,
156 411, 548, 455, 455, 548, 366, 576, 288,
157 122, 972, 159, 914, 211, 842, 276, 758,
158 341, 682, 389, 584, 483, 483, 520, 390,
159 110, 1172, 144, 1107, 193, 1028, 254, 932,
160 317, 846, 366, 731, 458, 611, 499, 499,
161 };
162
164 {
166 int x, y;
167 unsigned int p; // power divided by 2
169 uint16_t left_sum[2][8] = { { 0 } };
170 uint16_t top_sum[2][8] = { { 0 } };
171
172 for (
i = 0;
i < 8;
i++) {
174 for (j = 0; j < 8; j++) {
176 left_sum[p & 1][j] +=
a >> (p >> 1);
177 }
178 }
179
180 for (
i = 0;
i < 8;
i++) {
182 for (j = 0; j < 8; j++) {
184 top_sum[p & 1][j] +=
a >> (p >> 1);
185 }
186 }
187 for (;
i < 10;
i++) {
189 for (j = 5; j < 8; j++) {
191 top_sum[p & 1][j] +=
a >> (p >> 1);
192 }
193 }
194 for (;
i < 12;
i++) {
196 for (j = 7; j < 8; j++) {
198 top_sum[p & 1][j] +=
a >> (p >> 1);
199 }
200 }
201
202 for (
i = 0;
i < 8;
i++) {
203 top_sum[0][
i] += (top_sum[1][
i] * 181 + 128) >> 8;
// 181 is sqrt(2)/2
204 left_sum[0][
i] += (left_sum[1][
i] * 181 + 128) >> 8;
205 }
206 for (y = 0; y < 8; y++) {
207 for (x = 0; x < 8; x++)
210 0x8000) >> 16;
212 }
213 }
214
216 {
217 int x, y;
218
219 for (y = 0; y < 8; y++) {
220 for (x = 0; x < 8; x++)
223 }
224 }
225
227 {
228 int x, y;
229
230 for (y = 0; y < 8; y++) {
231 for (x = 0; x < 8; x++)
234 }
235 }
236
238 {
239 int x, y;
240
241 for (y = 0; y < 8; y++) {
242 for (x = 0; x < 8; x++)
245 }
246 }
247
249 {
250 int x, y;
251
252 for (y = 0; y < 8; y++) {
253 for (x = 0; x < 8; x++)
256 }
257 }
258
260 {
261 int x, y;
262
263 for (y = 0; y < 8; y++) {
264 for (x = 0; x < 8; x++) {
265 if (2 * x - y < 0)
267 else
269 }
271 }
272 }
273
275 {
276 int x, y;
277
278 for (y = 0; y < 8; y++) {
279 for (x = 0; x < 8; x++)
282 }
283 }
284
286 {
287 int x, y;
288
289 for (y = 0; y < 8; y++) {
290 for (x = 0; x < 8; x++) {
291 if (x - 2 * y > 0)
293 else
295 }
297 }
298 }
299
301 {
302 int x, y;
303
304 for (y = 0; y < 8; y++) {
305 for (x = 0; x < 8; x++)
308 }
309 }
310
312 {
313 int x, y;
314
315 for (y = 0; y < 8; y++) {
316 for (x = 0; x < 8; x++)
319 }
320 }
321
323 {
324 int x, y;
325
326 for (y = 0; y < 8; y++) {
327 for (x = 0; x < 8; x++)
330 }
331 }
332
334 {
335 int x, y;
336
337 for (y = 0; y < 8; y++) {
338 for (x = 0; x < 8; x++)
341 }
342 }
343
345 const ptrdiff_t b_stride,
int quant)
346 {
348 int p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
349 int ql = (
quant + 10) >> 3;
350
351 for (
i = 0;
i < 8;
i++, ptr += b_stride) {
352 p0 = ptr[-5 * a_stride];
353 p1 = ptr[-4 * a_stride];
354 p2 = ptr[-3 * a_stride];
355 p3 = ptr[-2 * a_stride];
356 p4 = ptr[-1 * a_stride];
357 p5 = ptr[0];
358 p6 = ptr[1 * a_stride];
359 p7 = ptr[2 * a_stride];
360 p8 = ptr[3 * a_stride];
361 p9 = ptr[4 * a_stride];
362
363 t = (
FFABS(p1 - p2) <= ql) +
364 (
FFABS(p2 - p3) <= ql) +
365 (
FFABS(p3 - p4) <= ql) +
366 (
FFABS(p4 - p5) <= ql);
367
368 // You need at least 1 to be able to reach a total score of 6.
369 if (t > 0) {
370 t += (
FFABS(p5 - p6) <= ql) +
371 (
FFABS(p6 - p7) <= ql) +
372 (
FFABS(p7 - p8) <= ql) +
373 (
FFABS(p8 - p9) <= ql) +
374 (
FFABS(p0 - p1) <= ql);
375 if (t >= 6) {
377
395 ptr[-2 * a_stride] = (4 * p2 + 3 * p3 + 1 * p7 + 4) >> 3;
396 ptr[-1 * a_stride] = (3 * p2 + 3 * p4 + 2 * p7 + 4) >> 3;
397 ptr[0] = (2 * p2 + 3 * p5 + 3 * p7 + 4) >> 3;
398 ptr[1 * a_stride] = (1 * p2 + 3 * p6 + 4 * p7 + 4) >> 3;
399 continue;
400 }
401 }
402 }
403 }
404 {
405 int x, x0, x1, x2;
406 int m;
407
408 x0 = (2 * p3 - 5 * p4 + 5 * p5 - 2 * p6 + 4) >> 3;
410 x1 = (2 * p1 - 5 * p2 + 5 * p3 - 2 * p4 + 4) >> 3;
411 x2 = (2 * p5 - 5 * p6 + 5 * p7 - 2 * p8 + 4) >> 3;
412
414 m = p4 - p5;
415
416 if (x > 0 && (m ^ x0) < 0) {
418
419 sign = m >> 31;
420 m = (m ^ sign) - sign; // abs(m)
421 m >>= 1;
422
423 x = 5 * x >> 3;
424
425 if (x > m)
426 x = m;
427
428 x = (x ^ sign) - sign;
429
430 ptr[-1 * a_stride] -= x;
431 ptr[0] += x;
432 }
433 }
434 }
435 }
436 }
437
439 {
441 }
442
444 {
446 }
447
449 {
465 }