00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #include "avcodec.h"
00026 #include "dsputil.h"
00027
00028 #ifdef USE_FASTMEMCPY
00029 #include "fastmemcpy.h"
00030 #endif
00031
00032 #define NB_COMPONENTS 3
00033
00034 #define PHASE_BITS 4
00035 #define NB_PHASES (1 << PHASE_BITS)
00036 #define NB_TAPS 4
00037 #define FCENTER 1
00038
00039
00040 #define POS_FRAC_BITS 16
00041 #define POS_FRAC (1 << POS_FRAC_BITS)
00042
00043 #define FILTER_BITS 8
00044
00045 #define LINE_BUF_HEIGHT (NB_TAPS * 4)
00046
00047 struct ImgReSampleContext {
00048 int iwidth, iheight, owidth, oheight;
00049 int topBand, bottomBand, leftBand, rightBand;
00050 int padtop, padbottom, padleft, padright;
00051 int pad_owidth, pad_oheight;
00052 int h_incr, v_incr;
00053 int16_t h_filters[NB_PHASES][NB_TAPS] __align8;
00054 int16_t v_filters[NB_PHASES][NB_TAPS] __align8;
00055 uint8_t *line_buf;
00056 };
00057
00058 void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type);
00059
00060 static inline int get_phase(int pos)
00061 {
00062 return ((pos) >> (POS_FRAC_BITS - PHASE_BITS)) & ((1 << PHASE_BITS) - 1);
00063 }
00064
00065
00066 static void h_resample_fast(uint8_t *dst, int dst_width, const uint8_t *src,
00067 int src_width, int src_start, int src_incr,
00068 int16_t *filters)
00069 {
00070 int src_pos, phase, sum, i;
00071 const uint8_t *s;
00072 int16_t *filter;
00073
00074 src_pos = src_start;
00075 for(i=0;i<dst_width;i++) {
00076 #ifdef TEST
00077
00078 if ((src_pos >> POS_FRAC_BITS) < 0 ||
00079 (src_pos >> POS_FRAC_BITS) > (src_width - NB_TAPS))
00080 av_abort();
00081 #endif
00082 s = src + (src_pos >> POS_FRAC_BITS);
00083 phase = get_phase(src_pos);
00084 filter = filters + phase * NB_TAPS;
00085 #if NB_TAPS == 4
00086 sum = s[0] * filter[0] +
00087 s[1] * filter[1] +
00088 s[2] * filter[2] +
00089 s[3] * filter[3];
00090 #else
00091 {
00092 int j;
00093 sum = 0;
00094 for(j=0;j<NB_TAPS;j++)
00095 sum += s[j] * filter[j];
00096 }
00097 #endif
00098 sum = sum >> FILTER_BITS;
00099 if (sum < 0)
00100 sum = 0;
00101 else if (sum > 255)
00102 sum = 255;
00103 dst[0] = sum;
00104 src_pos += src_incr;
00105 dst++;
00106 }
00107 }
00108
00109
00110 static void v_resample(uint8_t *dst, int dst_width, const uint8_t *src,
00111 int wrap, int16_t *filter)
00112 {
00113 int sum, i;
00114 const uint8_t *s;
00115
00116 s = src;
00117 for(i=0;i<dst_width;i++) {
00118 #if NB_TAPS == 4
00119 sum = s[0 * wrap] * filter[0] +
00120 s[1 * wrap] * filter[1] +
00121 s[2 * wrap] * filter[2] +
00122 s[3 * wrap] * filter[3];
00123 #else
00124 {
00125 int j;
00126 uint8_t *s1 = s;
00127
00128 sum = 0;
00129 for(j=0;j<NB_TAPS;j++) {
00130 sum += s1[0] * filter[j];
00131 s1 += wrap;
00132 }
00133 }
00134 #endif
00135 sum = sum >> FILTER_BITS;
00136 if (sum < 0)
00137 sum = 0;
00138 else if (sum > 255)
00139 sum = 255;
00140 dst[0] = sum;
00141 dst++;
00142 s++;
00143 }
00144 }
00145
00146 #ifdef HAVE_MMX
00147
00148 #include "i386/mmx.h"
00149
00150 #define FILTER4(reg) \
00151 {\
00152 s = src + (src_pos >> POS_FRAC_BITS);\
00153 phase = get_phase(src_pos);\
00154 filter = filters + phase * NB_TAPS;\
00155 movq_m2r(*s, reg);\
00156 punpcklbw_r2r(mm7, reg);\
00157 movq_m2r(*filter, mm6);\
00158 pmaddwd_r2r(reg, mm6);\
00159 movq_r2r(mm6, reg);\
00160 psrlq_i2r(32, reg);\
00161 paddd_r2r(mm6, reg);\
00162 psrad_i2r(FILTER_BITS, reg);\
00163 src_pos += src_incr;\
00164 }
00165
00166 #define DUMP(reg) movq_r2m(reg, tmp); printf(#reg "=%016Lx\n", tmp.uq);
00167
00168
00169 static void h_resample_fast4_mmx(uint8_t *dst, int dst_width,
00170 const uint8_t *src, int src_width,
00171 int src_start, int src_incr, int16_t *filters)
00172 {
00173 int src_pos, phase;
00174 const uint8_t *s;
00175 int16_t *filter;
00176 mmx_t tmp;
00177
00178 src_pos = src_start;
00179 pxor_r2r(mm7, mm7);
00180
00181 while (dst_width >= 4) {
00182
00183 FILTER4(mm0);
00184 FILTER4(mm1);
00185 FILTER4(mm2);
00186 FILTER4(mm3);
00187
00188 packuswb_r2r(mm7, mm0);
00189 packuswb_r2r(mm7, mm1);
00190 packuswb_r2r(mm7, mm3);
00191 packuswb_r2r(mm7, mm2);
00192 movq_r2m(mm0, tmp);
00193 dst[0] = tmp.ub[0];
00194 movq_r2m(mm1, tmp);
00195 dst[1] = tmp.ub[0];
00196 movq_r2m(mm2, tmp);
00197 dst[2] = tmp.ub[0];
00198 movq_r2m(mm3, tmp);
00199 dst[3] = tmp.ub[0];
00200 dst += 4;
00201 dst_width -= 4;
00202 }
00203 while (dst_width > 0) {
00204 FILTER4(mm0);
00205 packuswb_r2r(mm7, mm0);
00206 movq_r2m(mm0, tmp);
00207 dst[0] = tmp.ub[0];
00208 dst++;
00209 dst_width--;
00210 }
00211 emms();
00212 }
00213
00214 static void v_resample4_mmx(uint8_t *dst, int dst_width, const uint8_t *src,
00215 int wrap, int16_t *filter)
00216 {
00217 int sum, i, v;
00218 const uint8_t *s;
00219 mmx_t tmp;
00220 mmx_t coefs[4];
00221
00222 for(i=0;i<4;i++) {
00223 v = filter[i];
00224 coefs[i].uw[0] = v;
00225 coefs[i].uw[1] = v;
00226 coefs[i].uw[2] = v;
00227 coefs[i].uw[3] = v;
00228 }
00229
00230 pxor_r2r(mm7, mm7);
00231 s = src;
00232 while (dst_width >= 4) {
00233 movq_m2r(s[0 * wrap], mm0);
00234 punpcklbw_r2r(mm7, mm0);
00235 movq_m2r(s[1 * wrap], mm1);
00236 punpcklbw_r2r(mm7, mm1);
00237 movq_m2r(s[2 * wrap], mm2);
00238 punpcklbw_r2r(mm7, mm2);
00239 movq_m2r(s[3 * wrap], mm3);
00240 punpcklbw_r2r(mm7, mm3);
00241
00242 pmullw_m2r(coefs[0], mm0);
00243 pmullw_m2r(coefs[1], mm1);
00244 pmullw_m2r(coefs[2], mm2);
00245 pmullw_m2r(coefs[3], mm3);
00246
00247 paddw_r2r(mm1, mm0);
00248 paddw_r2r(mm3, mm2);
00249 paddw_r2r(mm2, mm0);
00250 psraw_i2r(FILTER_BITS, mm0);
00251
00252 packuswb_r2r(mm7, mm0);
00253 movq_r2m(mm0, tmp);
00254
00255 *(uint32_t *)dst = tmp.ud[0];
00256 dst += 4;
00257 s += 4;
00258 dst_width -= 4;
00259 }
00260 while (dst_width > 0) {
00261 sum = s[0 * wrap] * filter[0] +
00262 s[1 * wrap] * filter[1] +
00263 s[2 * wrap] * filter[2] +
00264 s[3 * wrap] * filter[3];
00265 sum = sum >> FILTER_BITS;
00266 if (sum < 0)
00267 sum = 0;
00268 else if (sum > 255)
00269 sum = 255;
00270 dst[0] = sum;
00271 dst++;
00272 s++;
00273 dst_width--;
00274 }
00275 emms();
00276 }
00277 #endif
00278
00279 #ifdef HAVE_ALTIVEC
00280 typedef union {
00281 vector unsigned char v;
00282 unsigned char c[16];
00283 } vec_uc_t;
00284
00285 typedef union {
00286 vector signed short v;
00287 signed short s[8];
00288 } vec_ss_t;
00289
00290 void v_resample16_altivec(uint8_t *dst, int dst_width, const uint8_t *src,
00291 int wrap, int16_t *filter)
00292 {
00293 int sum, i;
00294 const uint8_t *s;
00295 vector unsigned char *tv, tmp, dstv, zero;
00296 vec_ss_t srchv[4], srclv[4], fv[4];
00297 vector signed short zeros, sumhv, sumlv;
00298 s = src;
00299
00300 for(i=0;i<4;i++)
00301 {
00302
00303
00304
00305
00306
00307
00308 fv[i].s[0] = filter[i] << (15-FILTER_BITS);
00309 fv[i].v = vec_splat(fv[i].v, 0);
00310 }
00311
00312 zero = vec_splat_u8(0);
00313 zeros = vec_splat_s16(0);
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 i = (-(int)dst) & 0xf;
00324 while(i>0) {
00325 sum = s[0 * wrap] * filter[0] +
00326 s[1 * wrap] * filter[1] +
00327 s[2 * wrap] * filter[2] +
00328 s[3 * wrap] * filter[3];
00329 sum = sum >> FILTER_BITS;
00330 if (sum<0) sum = 0; else if (sum>255) sum=255;
00331 dst[0] = sum;
00332 dst++;
00333 s++;
00334 dst_width--;
00335 i--;
00336 }
00337
00338
00339 while(dst_width>=16) {
00340
00341
00342
00343
00344
00345
00346
00347 tv = (vector unsigned char *) &s[0 * wrap];
00348 tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[i * wrap]));
00349 srchv[0].v = (vector signed short) vec_mergeh(zero, tmp);
00350 srclv[0].v = (vector signed short) vec_mergel(zero, tmp);
00351 sumhv = vec_madds(srchv[0].v, fv[0].v, zeros);
00352 sumlv = vec_madds(srclv[0].v, fv[0].v, zeros);
00353
00354 tv = (vector unsigned char *) &s[1 * wrap];
00355 tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[1 * wrap]));
00356 srchv[1].v = (vector signed short) vec_mergeh(zero, tmp);
00357 srclv[1].v = (vector signed short) vec_mergel(zero, tmp);
00358 sumhv = vec_madds(srchv[1].v, fv[1].v, sumhv);
00359 sumlv = vec_madds(srclv[1].v, fv[1].v, sumlv);
00360
00361 tv = (vector unsigned char *) &s[2 * wrap];
00362 tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[2 * wrap]));
00363 srchv[2].v = (vector signed short) vec_mergeh(zero, tmp);
00364 srclv[2].v = (vector signed short) vec_mergel(zero, tmp);
00365 sumhv = vec_madds(srchv[2].v, fv[2].v, sumhv);
00366 sumlv = vec_madds(srclv[2].v, fv[2].v, sumlv);
00367
00368 tv = (vector unsigned char *) &s[3 * wrap];
00369 tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[3 * wrap]));
00370 srchv[3].v = (vector signed short) vec_mergeh(zero, tmp);
00371 srclv[3].v = (vector signed short) vec_mergel(zero, tmp);
00372 sumhv = vec_madds(srchv[3].v, fv[3].v, sumhv);
00373 sumlv = vec_madds(srclv[3].v, fv[3].v, sumlv);
00374
00375
00376
00377
00378
00379 dstv = vec_packsu(sumhv, sumlv) ;
00380 vec_st(dstv, 0, (vector unsigned char *) dst);
00381
00382 dst+=16;
00383 s+=16;
00384 dst_width-=16;
00385 }
00386
00387
00388
00389
00390
00391 while(dst_width>0) {
00392 sum = s[0 * wrap] * filter[0] +
00393 s[1 * wrap] * filter[1] +
00394 s[2 * wrap] * filter[2] +
00395 s[3 * wrap] * filter[3];
00396 sum = sum >> FILTER_BITS;
00397 if (sum<0) sum = 0; else if (sum>255) sum=255;
00398 dst[0] = sum;
00399 dst++;
00400 s++;
00401 dst_width--;
00402 }
00403 }
00404 #endif
00405
00406
00407 static void h_resample_slow(uint8_t *dst, int dst_width,
00408 const uint8_t *src, int src_width,
00409 int src_start, int src_incr, int16_t *filters)
00410 {
00411 int src_pos, phase, sum, j, v, i;
00412 const uint8_t *s, *src_end;
00413 int16_t *filter;
00414
00415 src_end = src + src_width;
00416 src_pos = src_start;
00417 for(i=0;i<dst_width;i++) {
00418 s = src + (src_pos >> POS_FRAC_BITS);
00419 phase = get_phase(src_pos);
00420 filter = filters + phase * NB_TAPS;
00421 sum = 0;
00422 for(j=0;j<NB_TAPS;j++) {
00423 if (s < src)
00424 v = src[0];
00425 else if (s >= src_end)
00426 v = src_end[-1];
00427 else
00428 v = s[0];
00429 sum += v * filter[j];
00430 s++;
00431 }
00432 sum = sum >> FILTER_BITS;
00433 if (sum < 0)
00434 sum = 0;
00435 else if (sum > 255)
00436 sum = 255;
00437 dst[0] = sum;
00438 src_pos += src_incr;
00439 dst++;
00440 }
00441 }
00442
00443 static void h_resample(uint8_t *dst, int dst_width, const uint8_t *src,
00444 int src_width, int src_start, int src_incr,
00445 int16_t *filters)
00446 {
00447 int n, src_end;
00448
00449 if (src_start < 0) {
00450 n = (0 - src_start + src_incr - 1) / src_incr;
00451 h_resample_slow(dst, n, src, src_width, src_start, src_incr, filters);
00452 dst += n;
00453 dst_width -= n;
00454 src_start += n * src_incr;
00455 }
00456 src_end = src_start + dst_width * src_incr;
00457 if (src_end > ((src_width - NB_TAPS) << POS_FRAC_BITS)) {
00458 n = (((src_width - NB_TAPS + 1) << POS_FRAC_BITS) - 1 - src_start) /
00459 src_incr;
00460 } else {
00461 n = dst_width;
00462 }
00463 #ifdef HAVE_MMX
00464 if ((mm_flags & MM_MMX) && NB_TAPS == 4)
00465 h_resample_fast4_mmx(dst, n,
00466 src, src_width, src_start, src_incr, filters);
00467 else
00468 #endif
00469 h_resample_fast(dst, n,
00470 src, src_width, src_start, src_incr, filters);
00471 if (n < dst_width) {
00472 dst += n;
00473 dst_width -= n;
00474 src_start += n * src_incr;
00475 h_resample_slow(dst, dst_width,
00476 src, src_width, src_start, src_incr, filters);
00477 }
00478 }
00479
00480 static void component_resample(ImgReSampleContext *s,
00481 uint8_t *output, int owrap, int owidth, int oheight,
00482 uint8_t *input, int iwrap, int iwidth, int iheight)
00483 {
00484 int src_y, src_y1, last_src_y, ring_y, phase_y, y1, y;
00485 uint8_t *new_line, *src_line;
00486
00487 last_src_y = - FCENTER - 1;
00488
00489 src_y = (last_src_y + NB_TAPS) * POS_FRAC;
00490 ring_y = NB_TAPS;
00491 for(y=0;y<oheight;y++) {
00492
00493 src_y1 = src_y >> POS_FRAC_BITS;
00494 while (last_src_y < src_y1) {
00495 if (++ring_y >= LINE_BUF_HEIGHT + NB_TAPS)
00496 ring_y = NB_TAPS;
00497 last_src_y++;
00498
00499
00500 y1 = last_src_y;
00501 if (y1 < 0) {
00502 y1 = 0;
00503 } else if (y1 >= iheight) {
00504 y1 = iheight - 1;
00505 }
00506 src_line = input + y1 * iwrap;
00507 new_line = s->line_buf + ring_y * owidth;
00508
00509 h_resample(new_line, owidth,
00510 src_line, iwidth, - FCENTER * POS_FRAC, s->h_incr,
00511 &s->h_filters[0][0]);
00512
00513 if (ring_y >= LINE_BUF_HEIGHT) {
00514 memcpy(s->line_buf + (ring_y - LINE_BUF_HEIGHT) * owidth,
00515 new_line, owidth);
00516 }
00517 }
00518
00519 phase_y = get_phase(src_y);
00520 #ifdef HAVE_MMX
00521
00522 if ((mm_flags & MM_MMX) && NB_TAPS == 4 && 0)
00523 v_resample4_mmx(output, owidth,
00524 s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth,
00525 &s->v_filters[phase_y][0]);
00526 else
00527 #endif
00528 #ifdef HAVE_ALTIVEC
00529 if ((mm_flags & MM_ALTIVEC) && NB_TAPS == 4 && FILTER_BITS <= 6)
00530 v_resample16_altivec(output, owidth,
00531 s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth,
00532 &s->v_filters[phase_y][0]);
00533 else
00534 #endif
00535 v_resample(output, owidth,
00536 s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth,
00537 &s->v_filters[phase_y][0]);
00538
00539 src_y += s->v_incr;
00540
00541 output += owrap;
00542 }
00543 }
00544
00545 ImgReSampleContext *img_resample_init(int owidth, int oheight,
00546 int iwidth, int iheight)
00547 {
00548 return img_resample_full_init(owidth, oheight, iwidth, iheight,
00549 0, 0, 0, 0, 0, 0, 0, 0);
00550 }
00551
00552 ImgReSampleContext *img_resample_full_init(int owidth, int oheight,
00553 int iwidth, int iheight,
00554 int topBand, int bottomBand,
00555 int leftBand, int rightBand,
00556 int padtop, int padbottom,
00557 int padleft, int padright)
00558 {
00559 ImgReSampleContext *s;
00560
00561 s = av_mallocz(sizeof(ImgReSampleContext));
00562 if (!s)
00563 return NULL;
00564 if((unsigned)owidth >= UINT_MAX / (LINE_BUF_HEIGHT + NB_TAPS))
00565 return NULL;
00566 s->line_buf = av_mallocz(owidth * (LINE_BUF_HEIGHT + NB_TAPS));
00567 if (!s->line_buf)
00568 goto fail;
00569
00570 s->owidth = owidth;
00571 s->oheight = oheight;
00572 s->iwidth = iwidth;
00573 s->iheight = iheight;
00574
00575 s->topBand = topBand;
00576 s->bottomBand = bottomBand;
00577 s->leftBand = leftBand;
00578 s->rightBand = rightBand;
00579
00580 s->padtop = padtop;
00581 s->padbottom = padbottom;
00582 s->padleft = padleft;
00583 s->padright = padright;
00584
00585 s->pad_owidth = owidth - (padleft + padright);
00586 s->pad_oheight = oheight - (padtop + padbottom);
00587
00588 s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth;
00589 s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight;
00590
00591 av_build_filter(&s->h_filters[0][0], (float) s->pad_owidth /
00592 (float) (iwidth - leftBand - rightBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);
00593 av_build_filter(&s->v_filters[0][0], (float) s->pad_oheight /
00594 (float) (iheight - topBand - bottomBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);
00595
00596 return s;
00597 fail:
00598 av_free(s);
00599 return NULL;
00600 }
00601
00602 void img_resample(ImgReSampleContext *s,
00603 AVPicture *output, const AVPicture *input)
00604 {
00605 int i, shift;
00606 uint8_t* optr;
00607
00608 for (i=0;i<3;i++) {
00609 shift = (i == 0) ? 0 : 1;
00610
00611 optr = output->data[i] + (((output->linesize[i] *
00612 s->padtop) + s->padleft) >> shift);
00613
00614 component_resample(s, optr, output->linesize[i],
00615 s->pad_owidth >> shift, s->pad_oheight >> shift,
00616 input->data[i] + (input->linesize[i] *
00617 (s->topBand >> shift)) + (s->leftBand >> shift),
00618 input->linesize[i], ((s->iwidth - s->leftBand -
00619 s->rightBand) >> shift),
00620 (s->iheight - s->topBand - s->bottomBand) >> shift);
00621 }
00622 }
00623
00624 void img_resample_close(ImgReSampleContext *s)
00625 {
00626 av_free(s->line_buf);
00627 av_free(s);
00628 }
00629
00630 #ifdef TEST
00631 #include <stdio.h>
00632
00633
00634 #define XSIZE 256
00635 #define YSIZE 256
00636 uint8_t img[XSIZE * YSIZE];
00637
00638
00639 #define XSIZE1 512
00640 #define YSIZE1 512
00641 uint8_t img1[XSIZE1 * YSIZE1];
00642 uint8_t img2[XSIZE1 * YSIZE1];
00643
00644 void save_pgm(const char *filename, uint8_t *img, int xsize, int ysize)
00645 {
00646 FILE *f;
00647 f=fopen(filename,"w");
00648 fprintf(f,"P5\n%d %d\n%d\n", xsize, ysize, 255);
00649 fwrite(img,1, xsize * ysize,f);
00650 fclose(f);
00651 }
00652
00653 static void dump_filter(int16_t *filter)
00654 {
00655 int i, ph;
00656
00657 for(ph=0;ph<NB_PHASES;ph++) {
00658 av_log(NULL, AV_LOG_INFO, "%2d: ", ph);
00659 for(i=0;i<NB_TAPS;i++) {
00660 av_log(NULL, AV_LOG_INFO, " %5.2f", filter[ph * NB_TAPS + i] / 256.0);
00661 }
00662 av_log(NULL, AV_LOG_INFO, "\n");
00663 }
00664 }
00665
00666 #ifdef HAVE_MMX
00667 int mm_flags;
00668 #endif
00669
00670 int main(int argc, char **argv)
00671 {
00672 int x, y, v, i, xsize, ysize;
00673 ImgReSampleContext *s;
00674 float fact, factors[] = { 1/2.0, 3.0/4.0, 1.0, 4.0/3.0, 16.0/9.0, 2.0 };
00675 char buf[256];
00676
00677
00678 for(y=0;y<YSIZE;y++) {
00679 for(x=0;x<XSIZE;x++) {
00680 if (x < XSIZE/2 && y < YSIZE/2) {
00681 if (x < XSIZE/4 && y < YSIZE/4) {
00682 if ((x % 10) <= 6 &&
00683 (y % 10) <= 6)
00684 v = 0xff;
00685 else
00686 v = 0x00;
00687 } else if (x < XSIZE/4) {
00688 if (x & 1)
00689 v = 0xff;
00690 else
00691 v = 0;
00692 } else if (y < XSIZE/4) {
00693 if (y & 1)
00694 v = 0xff;
00695 else
00696 v = 0;
00697 } else {
00698 if (y < YSIZE*3/8) {
00699 if ((y+x) & 1)
00700 v = 0xff;
00701 else
00702 v = 0;
00703 } else {
00704 if (((x+3) % 4) <= 1 &&
00705 ((y+3) % 4) <= 1)
00706 v = 0xff;
00707 else
00708 v = 0x00;
00709 }
00710 }
00711 } else if (x < XSIZE/2) {
00712 v = ((x - (XSIZE/2)) * 255) / (XSIZE/2);
00713 } else if (y < XSIZE/2) {
00714 v = ((y - (XSIZE/2)) * 255) / (XSIZE/2);
00715 } else {
00716 v = ((x + y - XSIZE) * 255) / XSIZE;
00717 }
00718 img[(YSIZE - y) * XSIZE + (XSIZE - x)] = v;
00719 }
00720 }
00721 save_pgm("/tmp/in.pgm", img, XSIZE, YSIZE);
00722 for(i=0;i<sizeof(factors)/sizeof(float);i++) {
00723 fact = factors[i];
00724 xsize = (int)(XSIZE * fact);
00725 ysize = (int)((YSIZE - 100) * fact);
00726 s = img_resample_full_init(xsize, ysize, XSIZE, YSIZE, 50 ,50, 0, 0, 0, 0, 0, 0);
00727 av_log(NULL, AV_LOG_INFO, "Factor=%0.2f\n", fact);
00728 dump_filter(&s->h_filters[0][0]);
00729 component_resample(s, img1, xsize, xsize, ysize,
00730 img + 50 * XSIZE, XSIZE, XSIZE, YSIZE - 100);
00731 img_resample_close(s);
00732
00733 snprintf(buf, sizeof(buf), "/tmp/out%d.pgm", i);
00734 save_pgm(buf, img1, xsize, ysize);
00735 }
00736
00737
00738 #ifdef HAVE_MMX
00739 av_log(NULL, AV_LOG_INFO, "MMX test\n");
00740 fact = 0.72;
00741 xsize = (int)(XSIZE * fact);
00742 ysize = (int)(YSIZE * fact);
00743 mm_flags = MM_MMX;
00744 s = img_resample_init(xsize, ysize, XSIZE, YSIZE);
00745 component_resample(s, img1, xsize, xsize, ysize,
00746 img, XSIZE, XSIZE, YSIZE);
00747
00748 mm_flags = 0;
00749 s = img_resample_init(xsize, ysize, XSIZE, YSIZE);
00750 component_resample(s, img2, xsize, xsize, ysize,
00751 img, XSIZE, XSIZE, YSIZE);
00752 if (memcmp(img1, img2, xsize * ysize) != 0) {
00753 av_log(NULL, AV_LOG_ERROR, "mmx error\n");
00754 exit(1);
00755 }
00756 av_log(NULL, AV_LOG_INFO, "MMX OK\n");
00757 #endif
00758 return 0;
00759 }
00760
00761 #endif