Mercurial > libavcodec.hg
annotate imgresample.c @ 7351:1502ba3beb72 libavcodec
The codebook generator algorithm involves picking three
different codebook centroids ("high utility", "low
utility" and "closest to the low utility one"). This
change avoid the corner case of choosing two times the
same centroid.
author | vitor |
---|---|
date | Wed, 23 Jul 2008 03:54:31 +0000 |
parents | ccb0813842ea |
children | 4525dcd81357 |
rev | line source |
---|---|
0 | 1 /* |
2967 | 2 * High quality image resampling with polyphase filters |
429 | 3 * Copyright (c) 2001 Fabrice Bellard. |
0 | 4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3589
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3589
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3589
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
429 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3589
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3589
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
429 | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Lesser General Public License for more details. | |
0 | 16 * |
429 | 17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3589
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
2967 | 21 |
1106 | 22 /** |
23 * @file imgresample.c | |
24 * High quality image resampling with polyphase filters . | |
25 */ | |
2967 | 26 |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
18
diff
changeset
|
27 #include "avcodec.h" |
0 | 28 #include "dsputil.h" |
6764 | 29 #include "libswscale/swscale.h" |
0 | 30 |
5750
09f99af1db40
Sanitize altivec code so it can be built with runtime check properly
lu_zero
parents:
5187
diff
changeset
|
31 #ifdef HAVE_ALTIVEC |
09f99af1db40
Sanitize altivec code so it can be built with runtime check properly
lu_zero
parents:
5187
diff
changeset
|
32 #include "ppc/imgresample_altivec.h" |
09f99af1db40
Sanitize altivec code so it can be built with runtime check properly
lu_zero
parents:
5187
diff
changeset
|
33 #endif |
09f99af1db40
Sanitize altivec code so it can be built with runtime check properly
lu_zero
parents:
5187
diff
changeset
|
34 |
0 | 35 #define NB_COMPONENTS 3 |
36 | |
37 #define PHASE_BITS 4 | |
38 #define NB_PHASES (1 << PHASE_BITS) | |
39 #define NB_TAPS 4 | |
40 #define FCENTER 1 /* index of the center of the filter */ | |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
41 //#define TEST 1 /* Test it */ |
0 | 42 |
43 #define POS_FRAC_BITS 16 | |
44 #define POS_FRAC (1 << POS_FRAC_BITS) | |
45 /* 6 bits precision is needed for MMX */ | |
46 #define FILTER_BITS 8 | |
47 | |
48 #define LINE_BUF_HEIGHT (NB_TAPS * 4) | |
49 | |
4065
93163e2a2398
Do not use a fake libavcodec/swscale.h, but always use the real one
lucabe
parents:
4036
diff
changeset
|
50 struct SwsContext { |
6464
0c3cc1d7a0b3
Make av_class a pointer to a const AVClass. Addresses one warning in
takis
parents:
6434
diff
changeset
|
51 const AVClass *av_class; |
4065
93163e2a2398
Do not use a fake libavcodec/swscale.h, but always use the real one
lucabe
parents:
4036
diff
changeset
|
52 struct ImgReSampleContext *resampling_ctx; |
93163e2a2398
Do not use a fake libavcodec/swscale.h, but always use the real one
lucabe
parents:
4036
diff
changeset
|
53 enum PixelFormat src_pix_fmt, dst_pix_fmt; |
93163e2a2398
Do not use a fake libavcodec/swscale.h, but always use the real one
lucabe
parents:
4036
diff
changeset
|
54 }; |
93163e2a2398
Do not use a fake libavcodec/swscale.h, but always use the real one
lucabe
parents:
4036
diff
changeset
|
55 |
0 | 56 struct ImgReSampleContext { |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
57 int iwidth, iheight, owidth, oheight; |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
58 int topBand, bottomBand, leftBand, rightBand; |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
59 int padtop, padbottom, padleft, padright; |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
60 int pad_owidth, pad_oheight; |
0 | 61 int h_incr, v_incr; |
3089 | 62 DECLARE_ALIGNED_8(int16_t, h_filters[NB_PHASES][NB_TAPS]); /* horizontal filters */ |
63 DECLARE_ALIGNED_8(int16_t, v_filters[NB_PHASES][NB_TAPS]); /* vertical filters */ | |
1064 | 64 uint8_t *line_buf; |
0 | 65 }; |
66 | |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
2064
diff
changeset
|
67 void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type); |
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
2064
diff
changeset
|
68 |
0 | 69 static inline int get_phase(int pos) |
70 { | |
71 return ((pos) >> (POS_FRAC_BITS - PHASE_BITS)) & ((1 << PHASE_BITS) - 1); | |
72 } | |
73 | |
74 /* This function must be optimized */ | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
75 static void h_resample_fast(uint8_t *dst, int dst_width, const uint8_t *src, |
2979 | 76 int src_width, int src_start, int src_incr, |
77 int16_t *filters) | |
0 | 78 { |
79 int src_pos, phase, sum, i; | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
80 const uint8_t *s; |
1064 | 81 int16_t *filter; |
0 | 82 |
83 src_pos = src_start; | |
84 for(i=0;i<dst_width;i++) { | |
85 #ifdef TEST | |
86 /* test */ | |
87 if ((src_pos >> POS_FRAC_BITS) < 0 || | |
88 (src_pos >> POS_FRAC_BITS) > (src_width - NB_TAPS)) | |
653 | 89 av_abort(); |
0 | 90 #endif |
91 s = src + (src_pos >> POS_FRAC_BITS); | |
92 phase = get_phase(src_pos); | |
93 filter = filters + phase * NB_TAPS; | |
94 #if NB_TAPS == 4 | |
95 sum = s[0] * filter[0] + | |
96 s[1] * filter[1] + | |
97 s[2] * filter[2] + | |
98 s[3] * filter[3]; | |
99 #else | |
100 { | |
101 int j; | |
102 sum = 0; | |
103 for(j=0;j<NB_TAPS;j++) | |
104 sum += s[j] * filter[j]; | |
105 } | |
106 #endif | |
107 sum = sum >> FILTER_BITS; | |
108 if (sum < 0) | |
109 sum = 0; | |
110 else if (sum > 255) | |
111 sum = 255; | |
112 dst[0] = sum; | |
113 src_pos += src_incr; | |
114 dst++; | |
115 } | |
116 } | |
117 | |
118 /* This function must be optimized */ | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
119 static void v_resample(uint8_t *dst, int dst_width, const uint8_t *src, |
2979 | 120 int wrap, int16_t *filter) |
0 | 121 { |
122 int sum, i; | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
123 const uint8_t *s; |
0 | 124 |
125 s = src; | |
126 for(i=0;i<dst_width;i++) { | |
127 #if NB_TAPS == 4 | |
128 sum = s[0 * wrap] * filter[0] + | |
129 s[1 * wrap] * filter[1] + | |
130 s[2 * wrap] * filter[2] + | |
131 s[3 * wrap] * filter[3]; | |
132 #else | |
133 { | |
134 int j; | |
1064 | 135 uint8_t *s1 = s; |
0 | 136 |
137 sum = 0; | |
138 for(j=0;j<NB_TAPS;j++) { | |
139 sum += s1[0] * filter[j]; | |
140 s1 += wrap; | |
141 } | |
142 } | |
143 #endif | |
144 sum = sum >> FILTER_BITS; | |
145 if (sum < 0) | |
146 sum = 0; | |
147 else if (sum > 255) | |
148 sum = 255; | |
149 dst[0] = sum; | |
150 dst++; | |
151 s++; | |
152 } | |
153 } | |
154 | |
2 | 155 #ifdef HAVE_MMX |
0 | 156 |
157 #include "i386/mmx.h" | |
158 | |
159 #define FILTER4(reg) \ | |
160 {\ | |
161 s = src + (src_pos >> POS_FRAC_BITS);\ | |
162 phase = get_phase(src_pos);\ | |
163 filter = filters + phase * NB_TAPS;\ | |
164 movq_m2r(*s, reg);\ | |
165 punpcklbw_r2r(mm7, reg);\ | |
166 movq_m2r(*filter, mm6);\ | |
167 pmaddwd_r2r(reg, mm6);\ | |
168 movq_r2r(mm6, reg);\ | |
169 psrlq_i2r(32, reg);\ | |
170 paddd_r2r(mm6, reg);\ | |
171 psrad_i2r(FILTER_BITS, reg);\ | |
172 src_pos += src_incr;\ | |
173 } | |
174 | |
4122
daae66c03857
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
4105
diff
changeset
|
175 #define DUMP(reg) movq_r2m(reg, tmp); printf(#reg "=%016"PRIx64"\n", tmp.uq); |
0 | 176 |
177 /* XXX: do four pixels at a time */ | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
178 static void h_resample_fast4_mmx(uint8_t *dst, int dst_width, |
2979 | 179 const uint8_t *src, int src_width, |
1064 | 180 int src_start, int src_incr, int16_t *filters) |
0 | 181 { |
182 int src_pos, phase; | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
183 const uint8_t *s; |
1064 | 184 int16_t *filter; |
0 | 185 mmx_t tmp; |
2967 | 186 |
0 | 187 src_pos = src_start; |
188 pxor_r2r(mm7, mm7); | |
189 | |
190 while (dst_width >= 4) { | |
191 | |
192 FILTER4(mm0); | |
193 FILTER4(mm1); | |
194 FILTER4(mm2); | |
195 FILTER4(mm3); | |
196 | |
197 packuswb_r2r(mm7, mm0); | |
198 packuswb_r2r(mm7, mm1); | |
199 packuswb_r2r(mm7, mm3); | |
200 packuswb_r2r(mm7, mm2); | |
201 movq_r2m(mm0, tmp); | |
202 dst[0] = tmp.ub[0]; | |
203 movq_r2m(mm1, tmp); | |
204 dst[1] = tmp.ub[0]; | |
205 movq_r2m(mm2, tmp); | |
206 dst[2] = tmp.ub[0]; | |
207 movq_r2m(mm3, tmp); | |
208 dst[3] = tmp.ub[0]; | |
209 dst += 4; | |
210 dst_width -= 4; | |
211 } | |
212 while (dst_width > 0) { | |
213 FILTER4(mm0); | |
214 packuswb_r2r(mm7, mm0); | |
215 movq_r2m(mm0, tmp); | |
216 dst[0] = tmp.ub[0]; | |
217 dst++; | |
218 dst_width--; | |
219 } | |
220 emms(); | |
221 } | |
222 | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
223 static void v_resample4_mmx(uint8_t *dst, int dst_width, const uint8_t *src, |
2979 | 224 int wrap, int16_t *filter) |
0 | 225 { |
226 int sum, i, v; | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
227 const uint8_t *s; |
0 | 228 mmx_t tmp; |
229 mmx_t coefs[4]; | |
2967 | 230 |
0 | 231 for(i=0;i<4;i++) { |
232 v = filter[i]; | |
233 coefs[i].uw[0] = v; | |
234 coefs[i].uw[1] = v; | |
235 coefs[i].uw[2] = v; | |
236 coefs[i].uw[3] = v; | |
237 } | |
2967 | 238 |
0 | 239 pxor_r2r(mm7, mm7); |
240 s = src; | |
241 while (dst_width >= 4) { | |
242 movq_m2r(s[0 * wrap], mm0); | |
243 punpcklbw_r2r(mm7, mm0); | |
244 movq_m2r(s[1 * wrap], mm1); | |
245 punpcklbw_r2r(mm7, mm1); | |
246 movq_m2r(s[2 * wrap], mm2); | |
247 punpcklbw_r2r(mm7, mm2); | |
248 movq_m2r(s[3 * wrap], mm3); | |
249 punpcklbw_r2r(mm7, mm3); | |
250 | |
251 pmullw_m2r(coefs[0], mm0); | |
252 pmullw_m2r(coefs[1], mm1); | |
253 pmullw_m2r(coefs[2], mm2); | |
254 pmullw_m2r(coefs[3], mm3); | |
255 | |
256 paddw_r2r(mm1, mm0); | |
257 paddw_r2r(mm3, mm2); | |
258 paddw_r2r(mm2, mm0); | |
259 psraw_i2r(FILTER_BITS, mm0); | |
2967 | 260 |
0 | 261 packuswb_r2r(mm7, mm0); |
262 movq_r2m(mm0, tmp); | |
263 | |
1064 | 264 *(uint32_t *)dst = tmp.ud[0]; |
0 | 265 dst += 4; |
266 s += 4; | |
267 dst_width -= 4; | |
268 } | |
269 while (dst_width > 0) { | |
270 sum = s[0 * wrap] * filter[0] + | |
271 s[1 * wrap] * filter[1] + | |
272 s[2 * wrap] * filter[2] + | |
273 s[3 * wrap] * filter[3]; | |
274 sum = sum >> FILTER_BITS; | |
275 if (sum < 0) | |
276 sum = 0; | |
277 else if (sum > 255) | |
278 sum = 255; | |
279 dst[0] = sum; | |
280 dst++; | |
281 s++; | |
282 dst_width--; | |
283 } | |
284 emms(); | |
285 } | |
5054 | 286 #endif /* HAVE_MMX */ |
0 | 287 |
5963 | 288 /* slow version to handle limit cases. Does not need optimization */ |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
289 static void h_resample_slow(uint8_t *dst, int dst_width, |
2979 | 290 const uint8_t *src, int src_width, |
1064 | 291 int src_start, int src_incr, int16_t *filters) |
0 | 292 { |
293 int src_pos, phase, sum, j, v, i; | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
294 const uint8_t *s, *src_end; |
1064 | 295 int16_t *filter; |
0 | 296 |
297 src_end = src + src_width; | |
298 src_pos = src_start; | |
299 for(i=0;i<dst_width;i++) { | |
300 s = src + (src_pos >> POS_FRAC_BITS); | |
301 phase = get_phase(src_pos); | |
302 filter = filters + phase * NB_TAPS; | |
303 sum = 0; | |
304 for(j=0;j<NB_TAPS;j++) { | |
305 if (s < src) | |
306 v = src[0]; | |
307 else if (s >= src_end) | |
308 v = src_end[-1]; | |
309 else | |
310 v = s[0]; | |
311 sum += v * filter[j]; | |
312 s++; | |
313 } | |
314 sum = sum >> FILTER_BITS; | |
315 if (sum < 0) | |
316 sum = 0; | |
317 else if (sum > 255) | |
318 sum = 255; | |
319 dst[0] = sum; | |
320 src_pos += src_incr; | |
321 dst++; | |
322 } | |
323 } | |
324 | |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
325 static void h_resample(uint8_t *dst, int dst_width, const uint8_t *src, |
2979 | 326 int src_width, int src_start, int src_incr, |
327 int16_t *filters) | |
0 | 328 { |
329 int n, src_end; | |
330 | |
331 if (src_start < 0) { | |
332 n = (0 - src_start + src_incr - 1) / src_incr; | |
333 h_resample_slow(dst, n, src, src_width, src_start, src_incr, filters); | |
334 dst += n; | |
335 dst_width -= n; | |
336 src_start += n * src_incr; | |
337 } | |
338 src_end = src_start + dst_width * src_incr; | |
339 if (src_end > ((src_width - NB_TAPS) << POS_FRAC_BITS)) { | |
2967 | 340 n = (((src_width - NB_TAPS + 1) << POS_FRAC_BITS) - 1 - src_start) / |
0 | 341 src_incr; |
342 } else { | |
343 n = dst_width; | |
344 } | |
2 | 345 #ifdef HAVE_MMX |
4197 | 346 if ((mm_flags & MM_MMX) && NB_TAPS == 4) |
2967 | 347 h_resample_fast4_mmx(dst, n, |
0 | 348 src, src_width, src_start, src_incr, filters); |
349 else | |
350 #endif | |
2967 | 351 h_resample_fast(dst, n, |
0 | 352 src, src_width, src_start, src_incr, filters); |
353 if (n < dst_width) { | |
354 dst += n; | |
355 dst_width -= n; | |
356 src_start += n * src_incr; | |
2967 | 357 h_resample_slow(dst, dst_width, |
0 | 358 src, src_width, src_start, src_incr, filters); |
359 } | |
360 } | |
361 | |
2967 | 362 static void component_resample(ImgReSampleContext *s, |
1064 | 363 uint8_t *output, int owrap, int owidth, int oheight, |
364 uint8_t *input, int iwrap, int iwidth, int iheight) | |
0 | 365 { |
366 int src_y, src_y1, last_src_y, ring_y, phase_y, y1, y; | |
1064 | 367 uint8_t *new_line, *src_line; |
0 | 368 |
369 last_src_y = - FCENTER - 1; | |
370 /* position of the bottom of the filter in the source image */ | |
2967 | 371 src_y = (last_src_y + NB_TAPS) * POS_FRAC; |
0 | 372 ring_y = NB_TAPS; /* position in ring buffer */ |
373 for(y=0;y<oheight;y++) { | |
374 /* apply horizontal filter on new lines from input if needed */ | |
375 src_y1 = src_y >> POS_FRAC_BITS; | |
376 while (last_src_y < src_y1) { | |
377 if (++ring_y >= LINE_BUF_HEIGHT + NB_TAPS) | |
378 ring_y = NB_TAPS; | |
379 last_src_y++; | |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
380 /* handle limit conditions : replicate line (slightly |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
381 inefficient because we filter multiple times) */ |
0 | 382 y1 = last_src_y; |
383 if (y1 < 0) { | |
384 y1 = 0; | |
385 } else if (y1 >= iheight) { | |
386 y1 = iheight - 1; | |
387 } | |
388 src_line = input + y1 * iwrap; | |
389 new_line = s->line_buf + ring_y * owidth; | |
390 /* apply filter and handle limit cases correctly */ | |
2967 | 391 h_resample(new_line, owidth, |
392 src_line, iwidth, - FCENTER * POS_FRAC, s->h_incr, | |
0 | 393 &s->h_filters[0][0]); |
6055 | 394 /* handle ring buffer wrapping */ |
0 | 395 if (ring_y >= LINE_BUF_HEIGHT) { |
396 memcpy(s->line_buf + (ring_y - LINE_BUF_HEIGHT) * owidth, | |
397 new_line, owidth); | |
398 } | |
399 } | |
400 /* apply vertical filter */ | |
401 phase_y = get_phase(src_y); | |
2 | 402 #ifdef HAVE_MMX |
0 | 403 /* desactivated MMX because loss of precision */ |
4197 | 404 if ((mm_flags & MM_MMX) && NB_TAPS == 4 && 0) |
2967 | 405 v_resample4_mmx(output, owidth, |
406 s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, | |
0 | 407 &s->v_filters[phase_y][0]); |
408 else | |
409 #endif | |
894
a408778eff87
altivec accelerated v-resample patch by (Brian Foley <bfoley at compsoc dot nuigalway dot ie>)
michaelni
parents:
653
diff
changeset
|
410 #ifdef HAVE_ALTIVEC |
4197 | 411 if ((mm_flags & MM_ALTIVEC) && NB_TAPS == 4 && FILTER_BITS <= 6) |
894
a408778eff87
altivec accelerated v-resample patch by (Brian Foley <bfoley at compsoc dot nuigalway dot ie>)
michaelni
parents:
653
diff
changeset
|
412 v_resample16_altivec(output, owidth, |
a408778eff87
altivec accelerated v-resample patch by (Brian Foley <bfoley at compsoc dot nuigalway dot ie>)
michaelni
parents:
653
diff
changeset
|
413 s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, |
a408778eff87
altivec accelerated v-resample patch by (Brian Foley <bfoley at compsoc dot nuigalway dot ie>)
michaelni
parents:
653
diff
changeset
|
414 &s->v_filters[phase_y][0]); |
a408778eff87
altivec accelerated v-resample patch by (Brian Foley <bfoley at compsoc dot nuigalway dot ie>)
michaelni
parents:
653
diff
changeset
|
415 else |
a408778eff87
altivec accelerated v-resample patch by (Brian Foley <bfoley at compsoc dot nuigalway dot ie>)
michaelni
parents:
653
diff
changeset
|
416 #endif |
2967 | 417 v_resample(output, owidth, |
418 s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, | |
0 | 419 &s->v_filters[phase_y][0]); |
2967 | 420 |
0 | 421 src_y += s->v_incr; |
2967 | 422 |
0 | 423 output += owrap; |
424 } | |
425 } | |
426 | |
427 ImgReSampleContext *img_resample_init(int owidth, int oheight, | |
428 int iwidth, int iheight) | |
429 { | |
2967 | 430 return img_resample_full_init(owidth, oheight, iwidth, iheight, |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
431 0, 0, 0, 0, 0, 0, 0, 0); |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
432 } |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
433 |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
434 ImgReSampleContext *img_resample_full_init(int owidth, int oheight, |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
435 int iwidth, int iheight, |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
436 int topBand, int bottomBand, |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
437 int leftBand, int rightBand, |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
438 int padtop, int padbottom, |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
439 int padleft, int padright) |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
440 { |
0 | 441 ImgReSampleContext *s; |
442 | |
2904 | 443 if (!owidth || !oheight || !iwidth || !iheight) |
2979 | 444 return NULL; |
2904 | 445 |
0 | 446 s = av_mallocz(sizeof(ImgReSampleContext)); |
447 if (!s) | |
448 return NULL; | |
2422 | 449 if((unsigned)owidth >= UINT_MAX / (LINE_BUF_HEIGHT + NB_TAPS)) |
6912 | 450 goto fail; |
0 | 451 s->line_buf = av_mallocz(owidth * (LINE_BUF_HEIGHT + NB_TAPS)); |
2967 | 452 if (!s->line_buf) |
0 | 453 goto fail; |
2967 | 454 |
0 | 455 s->owidth = owidth; |
456 s->oheight = oheight; | |
457 s->iwidth = iwidth; | |
458 s->iheight = iheight; | |
2967 | 459 |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
460 s->topBand = topBand; |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
461 s->bottomBand = bottomBand; |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
462 s->leftBand = leftBand; |
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
463 s->rightBand = rightBand; |
2967 | 464 |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
465 s->padtop = padtop; |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
466 s->padbottom = padbottom; |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
467 s->padleft = padleft; |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
468 s->padright = padright; |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
469 |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
470 s->pad_owidth = owidth - (padleft + padright); |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
471 s->pad_oheight = oheight - (padtop + padbottom); |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
472 |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
473 s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth; |
2967 | 474 s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight; |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
475 |
2967 | 476 av_build_filter(&s->h_filters[0][0], (float) s->pad_owidth / |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
2064
diff
changeset
|
477 (float) (iwidth - leftBand - rightBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0); |
2967 | 478 av_build_filter(&s->v_filters[0][0], (float) s->pad_oheight / |
2082
3dc9bbe1b152
polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample filters
michael
parents:
2064
diff
changeset
|
479 (float) (iheight - topBand - bottomBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0); |
0 | 480 |
481 return s; | |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
482 fail: |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
18
diff
changeset
|
483 av_free(s); |
0 | 484 return NULL; |
485 } | |
486 | |
2967 | 487 void img_resample(ImgReSampleContext *s, |
1488
766a2f4edbea
avcodec const correctness patch by (Drew Hess <dhess at ilm dot com>)
michaelni
parents:
1106
diff
changeset
|
488 AVPicture *output, const AVPicture *input) |
0 | 489 { |
490 int i, shift; | |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
491 uint8_t* optr; |
0 | 492 |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
493 for (i=0;i<3;i++) { |
0 | 494 shift = (i == 0) ? 0 : 1; |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
495 |
2967 | 496 optr = output->data[i] + (((output->linesize[i] * |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
497 s->padtop) + s->padleft) >> shift); |
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
498 |
2967 | 499 component_resample(s, optr, output->linesize[i], |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
500 s->pad_owidth >> shift, s->pad_oheight >> shift, |
2967 | 501 input->data[i] + (input->linesize[i] * |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
502 (s->topBand >> shift)) + (s->leftBand >> shift), |
2967 | 503 input->linesize[i], ((s->iwidth - s->leftBand - |
1928
0c23a5564489
padding support in ffmpeg patch by (Todd Kirby <doubleshot at pacbell dot net>)
michael
parents:
1488
diff
changeset
|
504 s->rightBand) >> shift), |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
505 (s->iheight - s->topBand - s->bottomBand) >> shift); |
0 | 506 } |
507 } | |
508 | |
509 void img_resample_close(ImgReSampleContext *s) | |
510 { | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
18
diff
changeset
|
511 av_free(s->line_buf); |
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
18
diff
changeset
|
512 av_free(s); |
0 | 513 } |
514 | |
6974 | 515 static const char *context_to_name(void* ptr) |
516 { | |
517 return "imgconvert"; | |
518 } | |
519 | |
520 static const AVClass context_class = { "imgresample", context_to_name, NULL }; | |
6433
d42d5a90f7de
Provide non null class name to avoid crash with ffmpeg -h.
michael
parents:
6055
diff
changeset
|
521 |
3249 | 522 struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, |
523 int dstW, int dstH, int dstFormat, | |
524 int flags, SwsFilter *srcFilter, | |
525 SwsFilter *dstFilter, double *param) | |
526 { | |
527 struct SwsContext *ctx; | |
528 | |
529 ctx = av_malloc(sizeof(struct SwsContext)); | |
6433
d42d5a90f7de
Provide non null class name to avoid crash with ffmpeg -h.
michael
parents:
6055
diff
changeset
|
530 if (!ctx) { |
3249 | 531 av_log(NULL, AV_LOG_ERROR, "Cannot allocate a resampling context!\n"); |
532 | |
533 return NULL; | |
534 } | |
6433
d42d5a90f7de
Provide non null class name to avoid crash with ffmpeg -h.
michael
parents:
6055
diff
changeset
|
535 ctx->av_class = &context_class; |
3249 | 536 |
537 if ((srcH != dstH) || (srcW != dstW)) { | |
538 if ((srcFormat != PIX_FMT_YUV420P) || (dstFormat != PIX_FMT_YUV420P)) { | |
6962 | 539 av_log(ctx, AV_LOG_INFO, "PIX_FMT_YUV420P will be used as an intermediate format for rescaling\n"); |
3249 | 540 } |
541 ctx->resampling_ctx = img_resample_init(dstW, dstH, srcW, srcH); | |
542 } else { | |
543 ctx->resampling_ctx = av_malloc(sizeof(ImgReSampleContext)); | |
544 ctx->resampling_ctx->iheight = srcH; | |
545 ctx->resampling_ctx->iwidth = srcW; | |
546 ctx->resampling_ctx->oheight = dstH; | |
547 ctx->resampling_ctx->owidth = dstW; | |
548 } | |
549 ctx->src_pix_fmt = srcFormat; | |
550 ctx->dst_pix_fmt = dstFormat; | |
551 | |
552 return ctx; | |
553 } | |
554 | |
555 void sws_freeContext(struct SwsContext *ctx) | |
556 { | |
4357
1654075b205c
fix segfault with http://sam.zoy.org/zzuf/lol-ffplay.ogm and
takis
parents:
4197
diff
changeset
|
557 if (!ctx) |
1654075b205c
fix segfault with http://sam.zoy.org/zzuf/lol-ffplay.ogm and
takis
parents:
4197
diff
changeset
|
558 return; |
3249 | 559 if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) || |
560 (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) { | |
561 img_resample_close(ctx->resampling_ctx); | |
562 } else { | |
563 av_free(ctx->resampling_ctx); | |
564 } | |
565 av_free(ctx); | |
566 } | |
567 | |
4036
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
568 |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
569 /** |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
570 * Checks if context is valid or reallocs a new one instead. |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
571 * If context is NULL, just calls sws_getContext() to get a new one. |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
572 * Otherwise, checks if the parameters are the same already saved in context. |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
573 * If that is the case, returns the current context. |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
574 * Otherwise, frees context and gets a new one. |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
575 * |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
576 * Be warned that srcFilter, dstFilter are not checked, they are |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
577 * asumed to remain valid. |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
578 */ |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
579 struct SwsContext *sws_getCachedContext(struct SwsContext *ctx, |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
580 int srcW, int srcH, int srcFormat, |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
581 int dstW, int dstH, int dstFormat, int flags, |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
582 SwsFilter *srcFilter, SwsFilter *dstFilter, double *param) |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
583 { |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
584 if (ctx != NULL) { |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
585 if ((ctx->resampling_ctx->iwidth != srcW) || |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
586 (ctx->resampling_ctx->iheight != srcH) || |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
587 (ctx->src_pix_fmt != srcFormat) || |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
588 (ctx->resampling_ctx->owidth != dstW) || |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
589 (ctx->resampling_ctx->oheight != dstH) || |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
590 (ctx->dst_pix_fmt != dstFormat)) |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
591 { |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
592 sws_freeContext(ctx); |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
593 ctx = NULL; |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
594 } |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
595 } |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
596 if (ctx == NULL) { |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
597 return sws_getContext(srcW, srcH, srcFormat, |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
598 dstW, dstH, dstFormat, flags, |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
599 srcFilter, dstFilter, param); |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
600 } |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
601 return ctx; |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
602 } |
207c22206d53
Implement sws_getCachedContext() in swscale emulation
lucabe
parents:
3947
diff
changeset
|
603 |
3249 | 604 int sws_scale(struct SwsContext *ctx, uint8_t* src[], int srcStride[], |
605 int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) | |
606 { | |
607 AVPicture src_pict, dst_pict; | |
608 int i, res = 0; | |
609 AVPicture picture_format_temp; | |
610 AVPicture picture_resample_temp, *formatted_picture, *resampled_picture; | |
611 uint8_t *buf1 = NULL, *buf2 = NULL; | |
612 enum PixelFormat current_pix_fmt; | |
613 | |
4105 | 614 for (i = 0; i < 4; i++) { |
3249 | 615 src_pict.data[i] = src[i]; |
616 src_pict.linesize[i] = srcStride[i]; | |
617 dst_pict.data[i] = dst[i]; | |
618 dst_pict.linesize[i] = dstStride[i]; | |
619 } | |
620 if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) || | |
621 (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) { | |
622 /* We have to rescale the picture, but only YUV420P rescaling is supported... */ | |
623 | |
624 if (ctx->src_pix_fmt != PIX_FMT_YUV420P) { | |
625 int size; | |
626 | |
627 /* create temporary picture for rescaling input*/ | |
628 size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight); | |
629 buf1 = av_malloc(size); | |
630 if (!buf1) { | |
631 res = -1; | |
632 goto the_end; | |
633 } | |
634 formatted_picture = &picture_format_temp; | |
635 avpicture_fill((AVPicture*)formatted_picture, buf1, | |
636 PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight); | |
637 | |
638 if (img_convert((AVPicture*)formatted_picture, PIX_FMT_YUV420P, | |
639 &src_pict, ctx->src_pix_fmt, | |
640 ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight) < 0) { | |
641 | |
6962 | 642 av_log(ctx, AV_LOG_ERROR, "pixel format conversion not handled\n"); |
3249 | 643 res = -1; |
644 goto the_end; | |
645 } | |
646 } else { | |
647 formatted_picture = &src_pict; | |
648 } | |
649 | |
650 if (ctx->dst_pix_fmt != PIX_FMT_YUV420P) { | |
651 int size; | |
652 | |
653 /* create temporary picture for rescaling output*/ | |
654 size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); | |
655 buf2 = av_malloc(size); | |
656 if (!buf2) { | |
657 res = -1; | |
658 goto the_end; | |
659 } | |
660 resampled_picture = &picture_resample_temp; | |
661 avpicture_fill((AVPicture*)resampled_picture, buf2, | |
662 PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); | |
663 | |
664 } else { | |
665 resampled_picture = &dst_pict; | |
666 } | |
667 | |
668 /* ...and finally rescale!!! */ | |
669 img_resample(ctx->resampling_ctx, resampled_picture, formatted_picture); | |
670 current_pix_fmt = PIX_FMT_YUV420P; | |
671 } else { | |
672 resampled_picture = &src_pict; | |
673 current_pix_fmt = ctx->src_pix_fmt; | |
674 } | |
675 | |
676 if (current_pix_fmt != ctx->dst_pix_fmt) { | |
677 if (img_convert(&dst_pict, ctx->dst_pix_fmt, | |
678 resampled_picture, current_pix_fmt, | |
679 ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight) < 0) { | |
680 | |
6962 | 681 av_log(ctx, AV_LOG_ERROR, "pixel format conversion not handled\n"); |
3249 | 682 |
683 res = -1; | |
684 goto the_end; | |
685 } | |
3516 | 686 } else if (resampled_picture != &dst_pict) { |
4624
6a900f539e2c
Add the prefix "av_" to img_crop(), img_copy() and img_pad(), and rename "img"
takis
parents:
4357
diff
changeset
|
687 av_picture_copy(&dst_pict, resampled_picture, current_pix_fmt, |
3516 | 688 ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); |
3249 | 689 } |
690 | |
691 the_end: | |
692 av_free(buf1); | |
693 av_free(buf2); | |
694 return res; | |
695 } | |
696 | |
697 | |
0 | 698 #ifdef TEST |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
699 #include <stdio.h> |
5055 | 700 #undef exit |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
701 |
0 | 702 /* input */ |
703 #define XSIZE 256 | |
704 #define YSIZE 256 | |
1064 | 705 uint8_t img[XSIZE * YSIZE]; |
0 | 706 |
707 /* output */ | |
708 #define XSIZE1 512 | |
709 #define YSIZE1 512 | |
1064 | 710 uint8_t img1[XSIZE1 * YSIZE1]; |
711 uint8_t img2[XSIZE1 * YSIZE1]; | |
0 | 712 |
1064 | 713 void save_pgm(const char *filename, uint8_t *img, int xsize, int ysize) |
0 | 714 { |
2846
40765c51a7a9
Compilation fixes part 1 patch by (Arvind R. and Burkhard Plaum, plaum, ipf uni-stuttgart de)
michael
parents:
2423
diff
changeset
|
715 #undef fprintf |
0 | 716 FILE *f; |
717 f=fopen(filename,"w"); | |
718 fprintf(f,"P5\n%d %d\n%d\n", xsize, ysize, 255); | |
719 fwrite(img,1, xsize * ysize,f); | |
720 fclose(f); | |
2846
40765c51a7a9
Compilation fixes part 1 patch by (Arvind R. and Burkhard Plaum, plaum, ipf uni-stuttgart de)
michael
parents:
2423
diff
changeset
|
721 #define fprintf please_use_av_log |
0 | 722 } |
723 | |
1064 | 724 static void dump_filter(int16_t *filter) |
0 | 725 { |
726 int i, ph; | |
727 | |
728 for(ph=0;ph<NB_PHASES;ph++) { | |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
729 av_log(NULL, AV_LOG_INFO, "%2d: ", ph); |
0 | 730 for(i=0;i<NB_TAPS;i++) { |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
731 av_log(NULL, AV_LOG_INFO, " %5.2f", filter[ph * NB_TAPS + i] / 256.0); |
0 | 732 } |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
733 av_log(NULL, AV_LOG_INFO, "\n"); |
0 | 734 } |
735 } | |
736 | |
2 | 737 #ifdef HAVE_MMX |
644 | 738 int mm_flags; |
0 | 739 #endif |
740 | |
741 int main(int argc, char **argv) | |
742 { | |
743 int x, y, v, i, xsize, ysize; | |
744 ImgReSampleContext *s; | |
745 float fact, factors[] = { 1/2.0, 3.0/4.0, 1.0, 4.0/3.0, 16.0/9.0, 2.0 }; | |
746 char buf[256]; | |
747 | |
748 /* build test image */ | |
749 for(y=0;y<YSIZE;y++) { | |
750 for(x=0;x<XSIZE;x++) { | |
751 if (x < XSIZE/2 && y < YSIZE/2) { | |
752 if (x < XSIZE/4 && y < YSIZE/4) { | |
753 if ((x % 10) <= 6 && | |
754 (y % 10) <= 6) | |
755 v = 0xff; | |
756 else | |
757 v = 0x00; | |
758 } else if (x < XSIZE/4) { | |
2967 | 759 if (x & 1) |
0 | 760 v = 0xff; |
2967 | 761 else |
0 | 762 v = 0; |
763 } else if (y < XSIZE/4) { | |
2967 | 764 if (y & 1) |
0 | 765 v = 0xff; |
2967 | 766 else |
0 | 767 v = 0; |
768 } else { | |
769 if (y < YSIZE*3/8) { | |
2967 | 770 if ((y+x) & 1) |
0 | 771 v = 0xff; |
2967 | 772 else |
0 | 773 v = 0; |
774 } else { | |
775 if (((x+3) % 4) <= 1 && | |
776 ((y+3) % 4) <= 1) | |
777 v = 0xff; | |
778 else | |
779 v = 0x00; | |
780 } | |
781 } | |
782 } else if (x < XSIZE/2) { | |
783 v = ((x - (XSIZE/2)) * 255) / (XSIZE/2); | |
784 } else if (y < XSIZE/2) { | |
785 v = ((y - (XSIZE/2)) * 255) / (XSIZE/2); | |
786 } else { | |
787 v = ((x + y - XSIZE) * 255) / XSIZE; | |
788 } | |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
789 img[(YSIZE - y) * XSIZE + (XSIZE - x)] = v; |
0 | 790 } |
791 } | |
792 save_pgm("/tmp/in.pgm", img, XSIZE, YSIZE); | |
793 for(i=0;i<sizeof(factors)/sizeof(float);i++) { | |
794 fact = factors[i]; | |
795 xsize = (int)(XSIZE * fact); | |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
796 ysize = (int)((YSIZE - 100) * fact); |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
797 s = img_resample_full_init(xsize, ysize, XSIZE, YSIZE, 50 ,50, 0, 0, 0, 0, 0, 0); |
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
798 av_log(NULL, AV_LOG_INFO, "Factor=%0.2f\n", fact); |
0 | 799 dump_filter(&s->h_filters[0][0]); |
800 component_resample(s, img1, xsize, xsize, ysize, | |
630
b4ee42142ad1
croping patch by (talus25 at speakeasy dot net) with fixes from atmos & me
michaelni
parents:
429
diff
changeset
|
801 img + 50 * XSIZE, XSIZE, XSIZE, YSIZE - 100); |
0 | 802 img_resample_close(s); |
803 | |
2423 | 804 snprintf(buf, sizeof(buf), "/tmp/out%d.pgm", i); |
0 | 805 save_pgm(buf, img1, xsize, ysize); |
806 } | |
807 | |
808 /* mmx test */ | |
2 | 809 #ifdef HAVE_MMX |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
810 av_log(NULL, AV_LOG_INFO, "MMX test\n"); |
0 | 811 fact = 0.72; |
812 xsize = (int)(XSIZE * fact); | |
813 ysize = (int)(YSIZE * fact); | |
814 mm_flags = MM_MMX; | |
815 s = img_resample_init(xsize, ysize, XSIZE, YSIZE); | |
816 component_resample(s, img1, xsize, xsize, ysize, | |
817 img, XSIZE, XSIZE, YSIZE); | |
818 | |
819 mm_flags = 0; | |
820 s = img_resample_init(xsize, ysize, XSIZE, YSIZE); | |
821 component_resample(s, img2, xsize, xsize, ysize, | |
822 img, XSIZE, XSIZE, YSIZE); | |
823 if (memcmp(img1, img2, xsize * ysize) != 0) { | |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
824 av_log(NULL, AV_LOG_ERROR, "mmx error\n"); |
0 | 825 exit(1); |
826 } | |
2400
17ec73c65748
imgresample test cleanup patch by (Panagiotis Issaris <takis )( lumumba d0t luc d0t ac.be>)
michael
parents:
2082
diff
changeset
|
827 av_log(NULL, AV_LOG_INFO, "MMX OK\n"); |
5054 | 828 #endif /* HAVE_MMX */ |
0 | 829 return 0; |
830 } | |
831 | |
5054 | 832 #endif /* TEST */ |