00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022
00023 #define _SVID_SOURCE // needed for MAP_ANONYMOUS
00024 #define _DARWIN_C_SOURCE // needed for MAP_ANON
00025 #include <inttypes.h>
00026 #include <math.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #if HAVE_SYS_MMAN_H
00030 #include <sys/mman.h>
00031 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
00032 #define MAP_ANONYMOUS MAP_ANON
00033 #endif
00034 #endif
00035 #if HAVE_VIRTUALALLOC
00036 #define WIN32_LEAN_AND_MEAN
00037 #include <windows.h>
00038 #endif
00039
00040 #include "libavutil/attributes.h"
00041 #include "libavutil/avassert.h"
00042 #include "libavutil/avutil.h"
00043 #include "libavutil/bswap.h"
00044 #include "libavutil/cpu.h"
00045 #include "libavutil/intreadwrite.h"
00046 #include "libavutil/mathematics.h"
00047 #include "libavutil/opt.h"
00048 #include "libavutil/pixdesc.h"
00049 #include "libavutil/x86/asm.h"
00050 #include "libavutil/x86/cpu.h"
00051 #include "rgb2rgb.h"
00052 #include "swscale.h"
00053 #include "swscale_internal.h"
00054
00055 unsigned swscale_version(void)
00056 {
00057 av_assert0(LIBSWSCALE_VERSION_MICRO >= 100);
00058 return LIBSWSCALE_VERSION_INT;
00059 }
00060
00061 const char *swscale_configuration(void)
00062 {
00063 return FFMPEG_CONFIGURATION;
00064 }
00065
00066 const char *swscale_license(void)
00067 {
00068 #define LICENSE_PREFIX "libswscale license: "
00069 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
00070 }
00071
00072 #define RET 0xC3 // near return opcode for x86
00073
00074 typedef struct FormatEntry {
00075 int is_supported_in, is_supported_out;
00076 } FormatEntry;
00077
00078 static const FormatEntry format_entries[PIX_FMT_NB] = {
00079 [PIX_FMT_YUV420P] = { 1, 1 },
00080 [PIX_FMT_YUYV422] = { 1, 1 },
00081 [PIX_FMT_RGB24] = { 1, 1 },
00082 [PIX_FMT_BGR24] = { 1, 1 },
00083 [PIX_FMT_YUV422P] = { 1, 1 },
00084 [PIX_FMT_YUV444P] = { 1, 1 },
00085 [PIX_FMT_YUV410P] = { 1, 1 },
00086 [PIX_FMT_YUV411P] = { 1, 1 },
00087 [PIX_FMT_GRAY8] = { 1, 1 },
00088 [PIX_FMT_MONOWHITE] = { 1, 1 },
00089 [PIX_FMT_MONOBLACK] = { 1, 1 },
00090 [PIX_FMT_PAL8] = { 1, 0 },
00091 [PIX_FMT_YUVJ420P] = { 1, 1 },
00092 [PIX_FMT_YUVJ422P] = { 1, 1 },
00093 [PIX_FMT_YUVJ444P] = { 1, 1 },
00094 [PIX_FMT_UYVY422] = { 1, 1 },
00095 [PIX_FMT_UYYVYY411] = { 0, 0 },
00096 [PIX_FMT_BGR8] = { 1, 1 },
00097 [PIX_FMT_BGR4] = { 0, 1 },
00098 [PIX_FMT_BGR4_BYTE] = { 1, 1 },
00099 [PIX_FMT_RGB8] = { 1, 1 },
00100 [PIX_FMT_RGB4] = { 0, 1 },
00101 [PIX_FMT_RGB4_BYTE] = { 1, 1 },
00102 [PIX_FMT_NV12] = { 1, 1 },
00103 [PIX_FMT_NV21] = { 1, 1 },
00104 [PIX_FMT_ARGB] = { 1, 1 },
00105 [PIX_FMT_RGBA] = { 1, 1 },
00106 [PIX_FMT_ABGR] = { 1, 1 },
00107 [PIX_FMT_BGRA] = { 1, 1 },
00108 [PIX_FMT_0RGB] = { 1, 1 },
00109 [PIX_FMT_RGB0] = { 1, 1 },
00110 [PIX_FMT_0BGR] = { 1, 1 },
00111 [PIX_FMT_BGR0] = { 1, 1 },
00112 [PIX_FMT_GRAY16BE] = { 1, 1 },
00113 [PIX_FMT_GRAY16LE] = { 1, 1 },
00114 [PIX_FMT_YUV440P] = { 1, 1 },
00115 [PIX_FMT_YUVJ440P] = { 1, 1 },
00116 [PIX_FMT_YUVA420P] = { 1, 1 },
00117 [PIX_FMT_YUVA422P] = { 1, 1 },
00118 [PIX_FMT_YUVA444P] = { 1, 1 },
00119 [PIX_FMT_RGB48BE] = { 1, 1 },
00120 [PIX_FMT_RGB48LE] = { 1, 1 },
00121 [PIX_FMT_RGBA64BE] = { 1, 0 },
00122 [PIX_FMT_RGBA64LE] = { 1, 0 },
00123 [PIX_FMT_RGB565BE] = { 1, 1 },
00124 [PIX_FMT_RGB565LE] = { 1, 1 },
00125 [PIX_FMT_RGB555BE] = { 1, 1 },
00126 [PIX_FMT_RGB555LE] = { 1, 1 },
00127 [PIX_FMT_BGR565BE] = { 1, 1 },
00128 [PIX_FMT_BGR565LE] = { 1, 1 },
00129 [PIX_FMT_BGR555BE] = { 1, 1 },
00130 [PIX_FMT_BGR555LE] = { 1, 1 },
00131 [PIX_FMT_YUV420P16LE] = { 1, 1 },
00132 [PIX_FMT_YUV420P16BE] = { 1, 1 },
00133 [PIX_FMT_YUV422P16LE] = { 1, 1 },
00134 [PIX_FMT_YUV422P16BE] = { 1, 1 },
00135 [PIX_FMT_YUV444P16LE] = { 1, 1 },
00136 [PIX_FMT_YUV444P16BE] = { 1, 1 },
00137 [PIX_FMT_RGB444LE] = { 1, 1 },
00138 [PIX_FMT_RGB444BE] = { 1, 1 },
00139 [PIX_FMT_BGR444LE] = { 1, 1 },
00140 [PIX_FMT_BGR444BE] = { 1, 1 },
00141 [PIX_FMT_Y400A] = { 1, 0 },
00142 [PIX_FMT_BGR48BE] = { 1, 1 },
00143 [PIX_FMT_BGR48LE] = { 1, 1 },
00144 [PIX_FMT_BGRA64BE] = { 0, 0 },
00145 [PIX_FMT_BGRA64LE] = { 0, 0 },
00146 [PIX_FMT_YUV420P9BE] = { 1, 1 },
00147 [PIX_FMT_YUV420P9LE] = { 1, 1 },
00148 [PIX_FMT_YUV420P10BE] = { 1, 1 },
00149 [PIX_FMT_YUV420P10LE] = { 1, 1 },
00150 [PIX_FMT_YUV420P12BE] = { 1, 1 },
00151 [PIX_FMT_YUV420P12LE] = { 1, 1 },
00152 [PIX_FMT_YUV420P14BE] = { 1, 1 },
00153 [PIX_FMT_YUV420P14LE] = { 1, 1 },
00154 [PIX_FMT_YUV422P9BE] = { 1, 1 },
00155 [PIX_FMT_YUV422P9LE] = { 1, 1 },
00156 [PIX_FMT_YUV422P10BE] = { 1, 1 },
00157 [PIX_FMT_YUV422P10LE] = { 1, 1 },
00158 [PIX_FMT_YUV422P12BE] = { 1, 1 },
00159 [PIX_FMT_YUV422P12LE] = { 1, 1 },
00160 [PIX_FMT_YUV422P14BE] = { 1, 1 },
00161 [PIX_FMT_YUV422P14LE] = { 1, 1 },
00162 [PIX_FMT_YUV444P9BE] = { 1, 1 },
00163 [PIX_FMT_YUV444P9LE] = { 1, 1 },
00164 [PIX_FMT_YUV444P10BE] = { 1, 1 },
00165 [PIX_FMT_YUV444P10LE] = { 1, 1 },
00166 [PIX_FMT_YUV444P12BE] = { 1, 1 },
00167 [PIX_FMT_YUV444P12LE] = { 1, 1 },
00168 [PIX_FMT_YUV444P14BE] = { 1, 1 },
00169 [PIX_FMT_YUV444P14LE] = { 1, 1 },
00170 [PIX_FMT_GBRP] = { 1, 0 },
00171 [PIX_FMT_GBRP9LE] = { 1, 0 },
00172 [PIX_FMT_GBRP9BE] = { 1, 0 },
00173 [PIX_FMT_GBRP10LE] = { 1, 0 },
00174 [PIX_FMT_GBRP10BE] = { 1, 0 },
00175 [PIX_FMT_GBRP12LE] = { 1, 0 },
00176 [PIX_FMT_GBRP12BE] = { 1, 0 },
00177 [PIX_FMT_GBRP14LE] = { 1, 0 },
00178 [PIX_FMT_GBRP14BE] = { 1, 0 },
00179 [PIX_FMT_GBRP16LE] = { 1, 0 },
00180 [PIX_FMT_GBRP16BE] = { 1, 0 },
00181 };
00182
00183 int sws_isSupportedInput(enum PixelFormat pix_fmt)
00184 {
00185 return (unsigned)pix_fmt < PIX_FMT_NB ?
00186 format_entries[pix_fmt].is_supported_in : 0;
00187 }
00188
00189 int sws_isSupportedOutput(enum PixelFormat pix_fmt)
00190 {
00191 return (unsigned)pix_fmt < PIX_FMT_NB ?
00192 format_entries[pix_fmt].is_supported_out : 0;
00193 }
00194
00195 extern const int32_t ff_yuv2rgb_coeffs[8][4];
00196
00197 #if FF_API_SWS_FORMAT_NAME
00198 const char *sws_format_name(enum PixelFormat format)
00199 {
00200 return av_get_pix_fmt_name(format);
00201 }
00202 #endif
00203
00204 static double getSplineCoeff(double a, double b, double c, double d,
00205 double dist)
00206 {
00207 if (dist <= 1.0)
00208 return ((d * dist + c) * dist + b) * dist + a;
00209 else
00210 return getSplineCoeff(0.0,
00211 b + 2.0 * c + 3.0 * d,
00212 c + 3.0 * d,
00213 -b - 3.0 * c - 6.0 * d,
00214 dist - 1.0);
00215 }
00216
00217 static int initFilter(int16_t **outFilter, int32_t **filterPos,
00218 int *outFilterSize, int xInc, int srcW, int dstW,
00219 int filterAlign, int one, int flags, int cpu_flags,
00220 SwsVector *srcFilter, SwsVector *dstFilter,
00221 double param[2])
00222 {
00223 int i;
00224 int filterSize;
00225 int filter2Size;
00226 int minFilterSize;
00227 int64_t *filter = NULL;
00228 int64_t *filter2 = NULL;
00229 const int64_t fone = 1LL << 54;
00230 int ret = -1;
00231
00232 emms_c();
00233
00234
00235 FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW + 3) * sizeof(**filterPos), fail);
00236
00237 if (FFABS(xInc - 0x10000) < 10) {
00238 int i;
00239 filterSize = 1;
00240 FF_ALLOCZ_OR_GOTO(NULL, filter,
00241 dstW * sizeof(*filter) * filterSize, fail);
00242
00243 for (i = 0; i < dstW; i++) {
00244 filter[i * filterSize] = fone;
00245 (*filterPos)[i] = i;
00246 }
00247 } else if (flags & SWS_POINT) {
00248 int i;
00249 int64_t xDstInSrc;
00250 filterSize = 1;
00251 FF_ALLOC_OR_GOTO(NULL, filter,
00252 dstW * sizeof(*filter) * filterSize, fail);
00253
00254 xDstInSrc = xInc / 2 - 0x8000;
00255 for (i = 0; i < dstW; i++) {
00256 int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
00257
00258 (*filterPos)[i] = xx;
00259 filter[i] = fone;
00260 xDstInSrc += xInc;
00261 }
00262 } else if ((xInc <= (1 << 16) && (flags & SWS_AREA)) ||
00263 (flags & SWS_FAST_BILINEAR)) {
00264 int i;
00265 int64_t xDstInSrc;
00266 filterSize = 2;
00267 FF_ALLOC_OR_GOTO(NULL, filter,
00268 dstW * sizeof(*filter) * filterSize, fail);
00269
00270 xDstInSrc = xInc / 2 - 0x8000;
00271 for (i = 0; i < dstW; i++) {
00272 int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
00273 int j;
00274
00275 (*filterPos)[i] = xx;
00276
00277 for (j = 0; j < filterSize; j++) {
00278 int64_t coeff= fone - FFABS(((int64_t)xx<<16) - xDstInSrc)*(fone>>16);
00279 if (coeff < 0)
00280 coeff = 0;
00281 filter[i * filterSize + j] = coeff;
00282 xx++;
00283 }
00284 xDstInSrc += xInc;
00285 }
00286 } else {
00287 int64_t xDstInSrc;
00288 int sizeFactor;
00289
00290 if (flags & SWS_BICUBIC)
00291 sizeFactor = 4;
00292 else if (flags & SWS_X)
00293 sizeFactor = 8;
00294 else if (flags & SWS_AREA)
00295 sizeFactor = 1;
00296 else if (flags & SWS_GAUSS)
00297 sizeFactor = 8;
00298 else if (flags & SWS_LANCZOS)
00299 sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;
00300 else if (flags & SWS_SINC)
00301 sizeFactor = 20;
00302 else if (flags & SWS_SPLINE)
00303 sizeFactor = 20;
00304 else if (flags & SWS_BILINEAR)
00305 sizeFactor = 2;
00306 else {
00307 av_assert0(0);
00308 }
00309
00310 if (xInc <= 1 << 16)
00311 filterSize = 1 + sizeFactor;
00312 else
00313 filterSize = 1 + (sizeFactor * srcW + dstW - 1) / dstW;
00314
00315 filterSize = FFMIN(filterSize, srcW - 2);
00316 filterSize = FFMAX(filterSize, 1);
00317
00318 FF_ALLOC_OR_GOTO(NULL, filter,
00319 dstW * sizeof(*filter) * filterSize, fail);
00320
00321 xDstInSrc = xInc - 0x10000;
00322 for (i = 0; i < dstW; i++) {
00323 int xx = (xDstInSrc - ((filterSize - 2) << 16)) / (1 << 17);
00324 int j;
00325 (*filterPos)[i] = xx;
00326 for (j = 0; j < filterSize; j++) {
00327 int64_t d = (FFABS(((int64_t)xx << 17) - xDstInSrc)) << 13;
00328 double floatd;
00329 int64_t coeff;
00330
00331 if (xInc > 1 << 16)
00332 d = d * dstW / srcW;
00333 floatd = d * (1.0 / (1 << 30));
00334
00335 if (flags & SWS_BICUBIC) {
00336 int64_t B = (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1 << 24);
00337 int64_t C = (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1 << 24);
00338
00339 if (d >= 1LL << 31) {
00340 coeff = 0.0;
00341 } else {
00342 int64_t dd = (d * d) >> 30;
00343 int64_t ddd = (dd * d) >> 30;
00344
00345 if (d < 1LL << 30)
00346 coeff = (12 * (1 << 24) - 9 * B - 6 * C) * ddd +
00347 (-18 * (1 << 24) + 12 * B + 6 * C) * dd +
00348 (6 * (1 << 24) - 2 * B) * (1 << 30);
00349 else
00350 coeff = (-B - 6 * C) * ddd +
00351 (6 * B + 30 * C) * dd +
00352 (-12 * B - 48 * C) * d +
00353 (8 * B + 24 * C) * (1 << 30);
00354 }
00355 coeff *= fone >> (30 + 24);
00356 }
00357 #if 0
00358 else if (flags & SWS_X) {
00359 double p = param ? param * 0.01 : 0.3;
00360 coeff = d ? sin(d * M_PI) / (d * M_PI) : 1.0;
00361 coeff *= pow(2.0, -p * d * d);
00362 }
00363 #endif
00364 else if (flags & SWS_X) {
00365 double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;
00366 double c;
00367
00368 if (floatd < 1.0)
00369 c = cos(floatd * M_PI);
00370 else
00371 c = -1.0;
00372 if (c < 0.0)
00373 c = -pow(-c, A);
00374 else
00375 c = pow(c, A);
00376 coeff = (c * 0.5 + 0.5) * fone;
00377 } else if (flags & SWS_AREA) {
00378 int64_t d2 = d - (1 << 29);
00379 if (d2 * xInc < -(1LL << (29 + 16)))
00380 coeff = 1.0 * (1LL << (30 + 16));
00381 else if (d2 * xInc < (1LL << (29 + 16)))
00382 coeff = -d2 * xInc + (1LL << (29 + 16));
00383 else
00384 coeff = 0.0;
00385 coeff *= fone >> (30 + 16);
00386 } else if (flags & SWS_GAUSS) {
00387 double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
00388 coeff = (pow(2.0, -p * floatd * floatd)) * fone;
00389 } else if (flags & SWS_SINC) {
00390 coeff = (d ? sin(floatd * M_PI) / (floatd * M_PI) : 1.0) * fone;
00391 } else if (flags & SWS_LANCZOS) {
00392 double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
00393 coeff = (d ? sin(floatd * M_PI) * sin(floatd * M_PI / p) /
00394 (floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;
00395 if (floatd > p)
00396 coeff = 0;
00397 } else if (flags & SWS_BILINEAR) {
00398 coeff = (1 << 30) - d;
00399 if (coeff < 0)
00400 coeff = 0;
00401 coeff *= fone >> 30;
00402 } else if (flags & SWS_SPLINE) {
00403 double p = -2.196152422706632;
00404 coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;
00405 } else {
00406 av_assert0(0);
00407 }
00408
00409 filter[i * filterSize + j] = coeff;
00410 xx++;
00411 }
00412 xDstInSrc += 2 * xInc;
00413 }
00414 }
00415
00416
00417
00418
00419 av_assert0(filterSize > 0);
00420 filter2Size = filterSize;
00421 if (srcFilter)
00422 filter2Size += srcFilter->length - 1;
00423 if (dstFilter)
00424 filter2Size += dstFilter->length - 1;
00425 av_assert0(filter2Size > 0);
00426 FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size * dstW * sizeof(*filter2), fail);
00427
00428 for (i = 0; i < dstW; i++) {
00429 int j, k;
00430
00431 if (srcFilter) {
00432 for (k = 0; k < srcFilter->length; k++) {
00433 for (j = 0; j < filterSize; j++)
00434 filter2[i * filter2Size + k + j] +=
00435 srcFilter->coeff[k] * filter[i * filterSize + j];
00436 }
00437 } else {
00438 for (j = 0; j < filterSize; j++)
00439 filter2[i * filter2Size + j] = filter[i * filterSize + j];
00440 }
00441
00442
00443 (*filterPos)[i] += (filterSize - 1) / 2 - (filter2Size - 1) / 2;
00444 }
00445 av_freep(&filter);
00446
00447
00448
00449 minFilterSize = 0;
00450 for (i = dstW - 1; i >= 0; i--) {
00451 int min = filter2Size;
00452 int j;
00453 int64_t cutOff = 0.0;
00454
00455
00456 for (j = 0; j < filter2Size; j++) {
00457 int k;
00458 cutOff += FFABS(filter2[i * filter2Size]);
00459
00460 if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
00461 break;
00462
00463
00464
00465 if (i < dstW - 1 && (*filterPos)[i] >= (*filterPos)[i + 1])
00466 break;
00467
00468
00469 for (k = 1; k < filter2Size; k++)
00470 filter2[i * filter2Size + k - 1] = filter2[i * filter2Size + k];
00471 filter2[i * filter2Size + k - 1] = 0;
00472 (*filterPos)[i]++;
00473 }
00474
00475 cutOff = 0;
00476
00477 for (j = filter2Size - 1; j > 0; j--) {
00478 cutOff += FFABS(filter2[i * filter2Size + j]);
00479
00480 if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
00481 break;
00482 min--;
00483 }
00484
00485 if (min > minFilterSize)
00486 minFilterSize = min;
00487 }
00488
00489 if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) {
00490
00491 if (minFilterSize < 5)
00492 filterAlign = 4;
00493
00494
00495
00496
00497 if (minFilterSize < 3)
00498 filterAlign = 1;
00499 }
00500
00501 if (INLINE_MMX(cpu_flags)) {
00502
00503 if (minFilterSize == 1 && filterAlign == 2)
00504 filterAlign = 1;
00505 }
00506
00507 av_assert0(minFilterSize > 0);
00508 filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));
00509 av_assert0(filterSize > 0);
00510 filter = av_malloc(filterSize * dstW * sizeof(*filter));
00511 if (filterSize >= MAX_FILTER_SIZE * 16 /
00512 ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter)
00513 goto fail;
00514 *outFilterSize = filterSize;
00515
00516 if (flags & SWS_PRINT_INFO)
00517 av_log(NULL, AV_LOG_VERBOSE,
00518 "SwScaler: reducing / aligning filtersize %d -> %d\n",
00519 filter2Size, filterSize);
00520
00521 for (i = 0; i < dstW; i++) {
00522 int j;
00523
00524 for (j = 0; j < filterSize; j++) {
00525 if (j >= filter2Size)
00526 filter[i * filterSize + j] = 0;
00527 else
00528 filter[i * filterSize + j] = filter2[i * filter2Size + j];
00529 if ((flags & SWS_BITEXACT) && j >= minFilterSize)
00530 filter[i * filterSize + j] = 0;
00531 }
00532 }
00533
00534
00535
00536
00537 for (i = 0; i < dstW; i++) {
00538 int j;
00539 if ((*filterPos)[i] < 0) {
00540
00541 for (j = 1; j < filterSize; j++) {
00542 int left = FFMAX(j + (*filterPos)[i], 0);
00543 filter[i * filterSize + left] += filter[i * filterSize + j];
00544 filter[i * filterSize + j] = 0;
00545 }
00546 (*filterPos)[i]= 0;
00547 }
00548
00549 if ((*filterPos)[i] + filterSize > srcW) {
00550 int shift = (*filterPos)[i] + filterSize - srcW;
00551
00552 for (j = filterSize - 2; j >= 0; j--) {
00553 int right = FFMIN(j + shift, filterSize - 1);
00554 filter[i * filterSize + right] += filter[i * filterSize + j];
00555 filter[i * filterSize + j] = 0;
00556 }
00557 (*filterPos)[i]= srcW - filterSize;
00558 }
00559 }
00560
00561
00562
00563 FF_ALLOCZ_OR_GOTO(NULL, *outFilter,
00564 *outFilterSize * (dstW + 3) * sizeof(int16_t), fail);
00565
00566
00567 for (i = 0; i < dstW; i++) {
00568 int j;
00569 int64_t error = 0;
00570 int64_t sum = 0;
00571
00572 for (j = 0; j < filterSize; j++) {
00573 sum += filter[i * filterSize + j];
00574 }
00575 sum = (sum + one / 2) / one;
00576 for (j = 0; j < *outFilterSize; j++) {
00577 int64_t v = filter[i * filterSize + j] + error;
00578 int intV = ROUNDED_DIV(v, sum);
00579 (*outFilter)[i * (*outFilterSize) + j] = intV;
00580 error = v - intV * sum;
00581 }
00582 }
00583
00584 (*filterPos)[dstW + 0] =
00585 (*filterPos)[dstW + 1] =
00586 (*filterPos)[dstW + 2] = (*filterPos)[dstW - 1];
00587
00588 for (i = 0; i < *outFilterSize; i++) {
00589 int k = (dstW - 1) * (*outFilterSize) + i;
00590 (*outFilter)[k + 1 * (*outFilterSize)] =
00591 (*outFilter)[k + 2 * (*outFilterSize)] =
00592 (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];
00593 }
00594
00595 ret = 0;
00596
00597 fail:
00598 av_free(filter);
00599 av_free(filter2);
00600 return ret;
00601 }
00602
00603 #if HAVE_MMXEXT_INLINE
00604 static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode,
00605 int16_t *filter, int32_t *filterPos, int numSplits)
00606 {
00607 uint8_t *fragmentA;
00608 x86_reg imm8OfPShufW1A;
00609 x86_reg imm8OfPShufW2A;
00610 x86_reg fragmentLengthA;
00611 uint8_t *fragmentB;
00612 x86_reg imm8OfPShufW1B;
00613 x86_reg imm8OfPShufW2B;
00614 x86_reg fragmentLengthB;
00615 int fragmentPos;
00616
00617 int xpos, i;
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 __asm__ volatile (
00629 "jmp 9f \n\t"
00630
00631 "0: \n\t"
00632 "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t"
00633 "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t"
00634 "movd 1(%%"REG_c", %%"REG_S"), %%mm1 \n\t"
00635 "punpcklbw %%mm7, %%mm1 \n\t"
00636 "punpcklbw %%mm7, %%mm0 \n\t"
00637 "pshufw $0xFF, %%mm1, %%mm1 \n\t"
00638 "1: \n\t"
00639 "pshufw $0xFF, %%mm0, %%mm0 \n\t"
00640 "2: \n\t"
00641 "psubw %%mm1, %%mm0 \n\t"
00642 "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t"
00643 "pmullw %%mm3, %%mm0 \n\t"
00644 "psllw $7, %%mm1 \n\t"
00645 "paddw %%mm1, %%mm0 \n\t"
00646
00647 "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t"
00648
00649 "add $8, %%"REG_a" \n\t"
00650
00651 "9: \n\t"
00652
00653 "lea " LOCAL_MANGLE(0b) ", %0 \n\t"
00654 "lea " LOCAL_MANGLE(1b) ", %1 \n\t"
00655 "lea " LOCAL_MANGLE(2b) ", %2 \n\t"
00656 "dec %1 \n\t"
00657 "dec %2 \n\t"
00658 "sub %0, %1 \n\t"
00659 "sub %0, %2 \n\t"
00660 "lea " LOCAL_MANGLE(9b) ", %3 \n\t"
00661 "sub %0, %3 \n\t"
00662
00663
00664 : "=r" (fragmentA), "=r" (imm8OfPShufW1A), "=r" (imm8OfPShufW2A),
00665 "=r" (fragmentLengthA)
00666 );
00667
00668 __asm__ volatile (
00669 "jmp 9f \n\t"
00670
00671 "0: \n\t"
00672 "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t"
00673 "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t"
00674 "punpcklbw %%mm7, %%mm0 \n\t"
00675 "pshufw $0xFF, %%mm0, %%mm1 \n\t"
00676 "1: \n\t"
00677 "pshufw $0xFF, %%mm0, %%mm0 \n\t"
00678 "2: \n\t"
00679 "psubw %%mm1, %%mm0 \n\t"
00680 "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t"
00681 "pmullw %%mm3, %%mm0 \n\t"
00682 "psllw $7, %%mm1 \n\t"
00683 "paddw %%mm1, %%mm0 \n\t"
00684
00685 "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t"
00686
00687 "add $8, %%"REG_a" \n\t"
00688
00689 "9: \n\t"
00690
00691 "lea " LOCAL_MANGLE(0b) ", %0 \n\t"
00692 "lea " LOCAL_MANGLE(1b) ", %1 \n\t"
00693 "lea " LOCAL_MANGLE(2b) ", %2 \n\t"
00694 "dec %1 \n\t"
00695 "dec %2 \n\t"
00696 "sub %0, %1 \n\t"
00697 "sub %0, %2 \n\t"
00698 "lea " LOCAL_MANGLE(9b) ", %3 \n\t"
00699 "sub %0, %3 \n\t"
00700
00701
00702 : "=r" (fragmentB), "=r" (imm8OfPShufW1B), "=r" (imm8OfPShufW2B),
00703 "=r" (fragmentLengthB)
00704 );
00705
00706 xpos = 0;
00707 fragmentPos = 0;
00708
00709 for (i = 0; i < dstW / numSplits; i++) {
00710 int xx = xpos >> 16;
00711
00712 if ((i & 3) == 0) {
00713 int a = 0;
00714 int b = ((xpos + xInc) >> 16) - xx;
00715 int c = ((xpos + xInc * 2) >> 16) - xx;
00716 int d = ((xpos + xInc * 3) >> 16) - xx;
00717 int inc = (d + 1 < 4);
00718 uint8_t *fragment = (d + 1 < 4) ? fragmentB : fragmentA;
00719 x86_reg imm8OfPShufW1 = (d + 1 < 4) ? imm8OfPShufW1B : imm8OfPShufW1A;
00720 x86_reg imm8OfPShufW2 = (d + 1 < 4) ? imm8OfPShufW2B : imm8OfPShufW2A;
00721 x86_reg fragmentLength = (d + 1 < 4) ? fragmentLengthB : fragmentLengthA;
00722 int maxShift = 3 - (d + inc);
00723 int shift = 0;
00724
00725 if (filterCode) {
00726 filter[i] = ((xpos & 0xFFFF) ^ 0xFFFF) >> 9;
00727 filter[i + 1] = (((xpos + xInc) & 0xFFFF) ^ 0xFFFF) >> 9;
00728 filter[i + 2] = (((xpos + xInc * 2) & 0xFFFF) ^ 0xFFFF) >> 9;
00729 filter[i + 3] = (((xpos + xInc * 3) & 0xFFFF) ^ 0xFFFF) >> 9;
00730 filterPos[i / 2] = xx;
00731
00732 memcpy(filterCode + fragmentPos, fragment, fragmentLength);
00733
00734 filterCode[fragmentPos + imm8OfPShufW1] = (a + inc) |
00735 ((b + inc) << 2) |
00736 ((c + inc) << 4) |
00737 ((d + inc) << 6);
00738 filterCode[fragmentPos + imm8OfPShufW2] = a | (b << 2) |
00739 (c << 4) |
00740 (d << 6);
00741
00742 if (i + 4 - inc >= dstW)
00743 shift = maxShift;
00744 else if ((filterPos[i / 2] & 3) <= maxShift)
00745 shift = filterPos[i / 2] & 3;
00746
00747 if (shift && i >= shift) {
00748 filterCode[fragmentPos + imm8OfPShufW1] += 0x55 * shift;
00749 filterCode[fragmentPos + imm8OfPShufW2] += 0x55 * shift;
00750 filterPos[i / 2] -= shift;
00751 }
00752 }
00753
00754 fragmentPos += fragmentLength;
00755
00756 if (filterCode)
00757 filterCode[fragmentPos] = RET;
00758 }
00759 xpos += xInc;
00760 }
00761 if (filterCode)
00762 filterPos[((i / 2) + 1) & (~1)] = xpos >> 16;
00763
00764 return fragmentPos + 1;
00765 }
00766 #endif
00767
00768 static void getSubSampleFactors(int *h, int *v, enum PixelFormat format)
00769 {
00770 *h = av_pix_fmt_descriptors[format].log2_chroma_w;
00771 *v = av_pix_fmt_descriptors[format].log2_chroma_h;
00772 }
00773
00774 int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
00775 int srcRange, const int table[4], int dstRange,
00776 int brightness, int contrast, int saturation)
00777 {
00778 memcpy(c->srcColorspaceTable, inv_table, sizeof(int) * 4);
00779 memcpy(c->dstColorspaceTable, table, sizeof(int) * 4);
00780
00781 c->brightness = brightness;
00782 c->contrast = contrast;
00783 c->saturation = saturation;
00784 c->srcRange = srcRange;
00785 c->dstRange = dstRange;
00786 if (isYUV(c->dstFormat) || isGray(c->dstFormat))
00787 return -1;
00788
00789 c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->dstFormat]);
00790 c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->srcFormat]);
00791
00792 ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
00793 contrast, saturation);
00794
00795
00796 if (HAVE_ALTIVEC && av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)
00797 ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness,
00798 contrast, saturation);
00799 return 0;
00800 }
00801
00802 int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
00803 int *srcRange, int **table, int *dstRange,
00804 int *brightness, int *contrast, int *saturation)
00805 {
00806 if (!c || isYUV(c->dstFormat) || isGray(c->dstFormat))
00807 return -1;
00808
00809 *inv_table = c->srcColorspaceTable;
00810 *table = c->dstColorspaceTable;
00811 *srcRange = c->srcRange;
00812 *dstRange = c->dstRange;
00813 *brightness = c->brightness;
00814 *contrast = c->contrast;
00815 *saturation = c->saturation;
00816
00817 return 0;
00818 }
00819
00820 static int handle_jpeg(enum PixelFormat *format)
00821 {
00822 switch (*format) {
00823 case PIX_FMT_YUVJ420P:
00824 *format = PIX_FMT_YUV420P;
00825 return 1;
00826 case PIX_FMT_YUVJ422P:
00827 *format = PIX_FMT_YUV422P;
00828 return 1;
00829 case PIX_FMT_YUVJ444P:
00830 *format = PIX_FMT_YUV444P;
00831 return 1;
00832 case PIX_FMT_YUVJ440P:
00833 *format = PIX_FMT_YUV440P;
00834 return 1;
00835 default:
00836 return 0;
00837 }
00838 }
00839
00840 static int handle_0alpha(enum PixelFormat *format)
00841 {
00842 switch (*format) {
00843 case PIX_FMT_0BGR : *format = PIX_FMT_ABGR ; return 1;
00844 case PIX_FMT_BGR0 : *format = PIX_FMT_BGRA ; return 4;
00845 case PIX_FMT_0RGB : *format = PIX_FMT_ARGB ; return 1;
00846 case PIX_FMT_RGB0 : *format = PIX_FMT_RGBA ; return 4;
00847 default: return 0;
00848 }
00849 }
00850
00851 SwsContext *sws_alloc_context(void)
00852 {
00853 SwsContext *c = av_mallocz(sizeof(SwsContext));
00854
00855 c->av_class = &sws_context_class;
00856 av_opt_set_defaults(c);
00857
00858 return c;
00859 }
00860
00861 av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
00862 SwsFilter *dstFilter)
00863 {
00864 int i, j;
00865 int usesVFilter, usesHFilter;
00866 int unscaled;
00867 SwsFilter dummyFilter = { NULL, NULL, NULL, NULL };
00868 int srcW = c->srcW;
00869 int srcH = c->srcH;
00870 int dstW = c->dstW;
00871 int dstH = c->dstH;
00872 int dst_stride = FFALIGN(dstW * sizeof(int16_t) + 66, 16);
00873 int flags, cpu_flags;
00874 enum PixelFormat srcFormat = c->srcFormat;
00875 enum PixelFormat dstFormat = c->dstFormat;
00876
00877 cpu_flags = av_get_cpu_flags();
00878 flags = c->flags;
00879 emms_c();
00880 if (!rgb15to16)
00881 sws_rgb2rgb_init();
00882
00883 unscaled = (srcW == dstW && srcH == dstH);
00884
00885 handle_jpeg(&srcFormat);
00886 handle_jpeg(&dstFormat);
00887 handle_0alpha(&srcFormat);
00888 handle_0alpha(&dstFormat);
00889
00890 if(srcFormat!=c->srcFormat || dstFormat!=c->dstFormat){
00891 av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
00892 c->srcFormat= srcFormat;
00893 c->dstFormat= dstFormat;
00894 }
00895
00896 if (!sws_isSupportedInput(srcFormat)) {
00897 av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
00898 av_get_pix_fmt_name(srcFormat));
00899 return AVERROR(EINVAL);
00900 }
00901 if (!sws_isSupportedOutput(dstFormat)) {
00902 av_log(c, AV_LOG_ERROR, "%s is not supported as output pixel format\n",
00903 av_get_pix_fmt_name(dstFormat));
00904 return AVERROR(EINVAL);
00905 }
00906
00907 i = flags & (SWS_POINT |
00908 SWS_AREA |
00909 SWS_BILINEAR |
00910 SWS_FAST_BILINEAR |
00911 SWS_BICUBIC |
00912 SWS_X |
00913 SWS_GAUSS |
00914 SWS_LANCZOS |
00915 SWS_SINC |
00916 SWS_SPLINE |
00917 SWS_BICUBLIN);
00918 if (!i || (i & (i - 1))) {
00919 av_log(c, AV_LOG_ERROR, "Exactly one scaler algorithm must be chosen, got %X\n", i);
00920 return AVERROR(EINVAL);
00921 }
00922
00923 if (srcW < 4 || srcH < 1 || dstW < 8 || dstH < 1) {
00924
00925
00926 av_log(c, AV_LOG_ERROR, "%dx%d -> %dx%d is invalid scaling dimension\n",
00927 srcW, srcH, dstW, dstH);
00928 return AVERROR(EINVAL);
00929 }
00930
00931 if (!dstFilter)
00932 dstFilter = &dummyFilter;
00933 if (!srcFilter)
00934 srcFilter = &dummyFilter;
00935
00936 c->lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW;
00937 c->lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH;
00938 c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[dstFormat]);
00939 c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[srcFormat]);
00940 c->vRounder = 4 * 0x0001000100010001ULL;
00941
00942 usesVFilter = (srcFilter->lumV && srcFilter->lumV->length > 1) ||
00943 (srcFilter->chrV && srcFilter->chrV->length > 1) ||
00944 (dstFilter->lumV && dstFilter->lumV->length > 1) ||
00945 (dstFilter->chrV && dstFilter->chrV->length > 1);
00946 usesHFilter = (srcFilter->lumH && srcFilter->lumH->length > 1) ||
00947 (srcFilter->chrH && srcFilter->chrH->length > 1) ||
00948 (dstFilter->lumH && dstFilter->lumH->length > 1) ||
00949 (dstFilter->chrH && dstFilter->chrH->length > 1);
00950
00951 getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);
00952 getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
00953
00954
00955 if (isAnyRGB(dstFormat) && !(flags&SWS_FULL_CHR_H_INT)) {
00956 if (dstW&1) {
00957 av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to odd output size\n");
00958 flags |= SWS_FULL_CHR_H_INT;
00959 c->flags = flags;
00960 }
00961 }
00962
00963
00964 if (flags & SWS_FULL_CHR_H_INT &&
00965 isAnyRGB(dstFormat) &&
00966 dstFormat != PIX_FMT_RGBA &&
00967 dstFormat != PIX_FMT_ARGB &&
00968 dstFormat != PIX_FMT_BGRA &&
00969 dstFormat != PIX_FMT_ABGR &&
00970 dstFormat != PIX_FMT_RGB24 &&
00971 dstFormat != PIX_FMT_BGR24) {
00972 av_log(c, AV_LOG_WARNING,
00973 "full chroma interpolation for destination format '%s' not yet implemented\n",
00974 av_get_pix_fmt_name(dstFormat));
00975 flags &= ~SWS_FULL_CHR_H_INT;
00976 c->flags = flags;
00977 }
00978 if (isAnyRGB(dstFormat) && !(flags & SWS_FULL_CHR_H_INT))
00979 c->chrDstHSubSample = 1;
00980
00981
00982 c->vChrDrop = (flags & SWS_SRC_V_CHR_DROP_MASK) >>
00983 SWS_SRC_V_CHR_DROP_SHIFT;
00984 c->chrSrcVSubSample += c->vChrDrop;
00985
00986
00987
00988 if (isAnyRGB(srcFormat) && !(flags & SWS_FULL_CHR_H_INP) &&
00989 srcFormat != PIX_FMT_RGB8 && srcFormat != PIX_FMT_BGR8 &&
00990 srcFormat != PIX_FMT_RGB4 && srcFormat != PIX_FMT_BGR4 &&
00991 srcFormat != PIX_FMT_RGB4_BYTE && srcFormat != PIX_FMT_BGR4_BYTE &&
00992 ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
00993 (flags & SWS_FAST_BILINEAR)))
00994 c->chrSrcHSubSample = 1;
00995
00996
00997 c->chrSrcW = -((-srcW) >> c->chrSrcHSubSample);
00998 c->chrSrcH = -((-srcH) >> c->chrSrcVSubSample);
00999 c->chrDstW = -((-dstW) >> c->chrDstHSubSample);
01000 c->chrDstH = -((-dstH) >> c->chrDstVSubSample);
01001
01002 FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail);
01003
01004
01005 if (unscaled && !usesHFilter && !usesVFilter &&
01006 (c->srcRange == c->dstRange || isAnyRGB(dstFormat))) {
01007 ff_get_unscaled_swscale(c);
01008
01009 if (c->swScale) {
01010 if (flags & SWS_PRINT_INFO)
01011 av_log(c, AV_LOG_INFO,
01012 "using unscaled %s -> %s special converter\n",
01013 av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
01014 return 0;
01015 }
01016 }
01017
01018 c->srcBpc = 1 + av_pix_fmt_descriptors[srcFormat].comp[0].depth_minus1;
01019 if (c->srcBpc < 8)
01020 c->srcBpc = 8;
01021 c->dstBpc = 1 + av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1;
01022 if (c->dstBpc < 8)
01023 c->dstBpc = 8;
01024 if (isAnyRGB(srcFormat) || srcFormat == PIX_FMT_PAL8)
01025 c->srcBpc = 16;
01026 if (c->dstBpc == 16)
01027 dst_stride <<= 1;
01028 if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 14) {
01029 c->canMMX2BeUsed = (dstW >= srcW && (dstW & 31) == 0 &&
01030 (srcW & 15) == 0) ? 1 : 0;
01031 if (!c->canMMX2BeUsed && dstW >= srcW && (srcW & 15) == 0
01032 && (flags & SWS_FAST_BILINEAR)) {
01033 if (flags & SWS_PRINT_INFO)
01034 av_log(c, AV_LOG_INFO,
01035 "output width is not a multiple of 32 -> no MMX2 scaler\n");
01036 }
01037 if (usesHFilter || isNBPS(c->srcFormat) || is16BPS(c->srcFormat) || isAnyRGB(c->srcFormat))
01038 c->canMMX2BeUsed=0;
01039 } else
01040 c->canMMX2BeUsed = 0;
01041
01042 c->chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW;
01043 c->chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH;
01044
01045
01046
01047
01048
01049
01050
01051
01052 if (flags & SWS_FAST_BILINEAR) {
01053 if (c->canMMX2BeUsed) {
01054 c->lumXInc += 20;
01055 c->chrXInc += 20;
01056 }
01057
01058 else if (INLINE_MMX(cpu_flags) && c->dstBpc <= 14) {
01059 c->lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20;
01060 c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20;
01061 }
01062 }
01063
01064
01065 {
01066 #if HAVE_MMXEXT_INLINE
01067
01068 if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) {
01069 c->lumMmx2FilterCodeSize = initMMX2HScaler(dstW, c->lumXInc, NULL,
01070 NULL, NULL, 8);
01071 c->chrMmx2FilterCodeSize = initMMX2HScaler(c->chrDstW, c->chrXInc,
01072 NULL, NULL, NULL, 4);
01073
01074 #ifdef MAP_ANONYMOUS
01075 c->lumMmx2FilterCode = mmap(NULL, c->lumMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
01076 c->chrMmx2FilterCode = mmap(NULL, c->chrMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
01077 #elif HAVE_VIRTUALALLOC
01078 c->lumMmx2FilterCode = VirtualAlloc(NULL, c->lumMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
01079 c->chrMmx2FilterCode = VirtualAlloc(NULL, c->chrMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
01080 #else
01081 c->lumMmx2FilterCode = av_malloc(c->lumMmx2FilterCodeSize);
01082 c->chrMmx2FilterCode = av_malloc(c->chrMmx2FilterCodeSize);
01083 #endif
01084
01085 #ifdef MAP_ANONYMOUS
01086 if (c->lumMmx2FilterCode == MAP_FAILED || c->chrMmx2FilterCode == MAP_FAILED)
01087 #else
01088 if (!c->lumMmx2FilterCode || !c->chrMmx2FilterCode)
01089 #endif
01090 {
01091 av_log(c, AV_LOG_ERROR, "Failed to allocate MMX2FilterCode\n");
01092 return AVERROR(ENOMEM);
01093 }
01094
01095 FF_ALLOCZ_OR_GOTO(c, c->hLumFilter, (dstW / 8 + 8) * sizeof(int16_t), fail);
01096 FF_ALLOCZ_OR_GOTO(c, c->hChrFilter, (c->chrDstW / 4 + 8) * sizeof(int16_t), fail);
01097 FF_ALLOCZ_OR_GOTO(c, c->hLumFilterPos, (dstW / 2 / 8 + 8) * sizeof(int32_t), fail);
01098 FF_ALLOCZ_OR_GOTO(c, c->hChrFilterPos, (c->chrDstW / 2 / 4 + 8) * sizeof(int32_t), fail);
01099
01100 initMMX2HScaler( dstW, c->lumXInc, c->lumMmx2FilterCode,
01101 c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8);
01102 initMMX2HScaler(c->chrDstW, c->chrXInc, c->chrMmx2FilterCode,
01103 c->hChrFilter, (uint32_t*)c->hChrFilterPos, 4);
01104
01105 #ifdef MAP_ANONYMOUS
01106 mprotect(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
01107 mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
01108 #endif
01109 } else
01110 #endif
01111 {
01112 const int filterAlign =
01113 (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 4 :
01114 (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
01115 1;
01116
01117 if (initFilter(&c->hLumFilter, &c->hLumFilterPos,
01118 &c->hLumFilterSize, c->lumXInc,
01119 srcW, dstW, filterAlign, 1 << 14,
01120 (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
01121 cpu_flags, srcFilter->lumH, dstFilter->lumH,
01122 c->param) < 0)
01123 goto fail;
01124 if (initFilter(&c->hChrFilter, &c->hChrFilterPos,
01125 &c->hChrFilterSize, c->chrXInc,
01126 c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
01127 (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
01128 cpu_flags, srcFilter->chrH, dstFilter->chrH,
01129 c->param) < 0)
01130 goto fail;
01131 }
01132 }
01133
01134
01135 {
01136 const int filterAlign =
01137 (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 2 :
01138 (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
01139 1;
01140
01141 if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
01142 c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
01143 (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
01144 cpu_flags, srcFilter->lumV, dstFilter->lumV,
01145 c->param) < 0)
01146 goto fail;
01147 if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
01148 c->chrYInc, c->chrSrcH, c->chrDstH,
01149 filterAlign, (1 << 12),
01150 (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
01151 cpu_flags, srcFilter->chrV, dstFilter->chrV,
01152 c->param) < 0)
01153 goto fail;
01154
01155 #if HAVE_ALTIVEC
01156 FF_ALLOC_OR_GOTO(c, c->vYCoeffsBank, sizeof(vector signed short) * c->vLumFilterSize * c->dstH, fail);
01157 FF_ALLOC_OR_GOTO(c, c->vCCoeffsBank, sizeof(vector signed short) * c->vChrFilterSize * c->chrDstH, fail);
01158
01159 for (i = 0; i < c->vLumFilterSize * c->dstH; i++) {
01160 int j;
01161 short *p = (short *)&c->vYCoeffsBank[i];
01162 for (j = 0; j < 8; j++)
01163 p[j] = c->vLumFilter[i];
01164 }
01165
01166 for (i = 0; i < c->vChrFilterSize * c->chrDstH; i++) {
01167 int j;
01168 short *p = (short *)&c->vCCoeffsBank[i];
01169 for (j = 0; j < 8; j++)
01170 p[j] = c->vChrFilter[i];
01171 }
01172 #endif
01173 }
01174
01175
01176 c->vLumBufSize = c->vLumFilterSize;
01177 c->vChrBufSize = c->vChrFilterSize;
01178 for (i = 0; i < dstH; i++) {
01179 int chrI = (int64_t)i * c->chrDstH / dstH;
01180 int nextSlice = FFMAX(c->vLumFilterPos[i] + c->vLumFilterSize - 1,
01181 ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)
01182 << c->chrSrcVSubSample));
01183
01184 nextSlice >>= c->chrSrcVSubSample;
01185 nextSlice <<= c->chrSrcVSubSample;
01186 if (c->vLumFilterPos[i] + c->vLumBufSize < nextSlice)
01187 c->vLumBufSize = nextSlice - c->vLumFilterPos[i];
01188 if (c->vChrFilterPos[chrI] + c->vChrBufSize <
01189 (nextSlice >> c->chrSrcVSubSample))
01190 c->vChrBufSize = (nextSlice >> c->chrSrcVSubSample) -
01191 c->vChrFilterPos[chrI];
01192 }
01193
01194
01195
01196 FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize * 3 * sizeof(int16_t *), fail);
01197 FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail);
01198 FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail);
01199 if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat))
01200 FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize * 3 * sizeof(int16_t *), fail);
01201
01202
01203
01204 for (i = 0; i < c->vLumBufSize; i++) {
01205 FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i + c->vLumBufSize],
01206 dst_stride + 16, fail);
01207 c->lumPixBuf[i] = c->lumPixBuf[i + c->vLumBufSize];
01208 }
01209
01210 c->uv_off = (dst_stride>>1) + 64 / (c->dstBpc &~ 7);
01211 c->uv_offx2 = dst_stride + 16;
01212 for (i = 0; i < c->vChrBufSize; i++) {
01213 FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i + c->vChrBufSize],
01214 dst_stride * 2 + 32, fail);
01215 c->chrUPixBuf[i] = c->chrUPixBuf[i + c->vChrBufSize];
01216 c->chrVPixBuf[i] = c->chrVPixBuf[i + c->vChrBufSize]
01217 = c->chrUPixBuf[i] + (dst_stride >> 1) + 8;
01218 }
01219 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
01220 for (i = 0; i < c->vLumBufSize; i++) {
01221 FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf[i + c->vLumBufSize],
01222 dst_stride + 16, fail);
01223 c->alpPixBuf[i] = c->alpPixBuf[i + c->vLumBufSize];
01224 }
01225
01226
01227 for (i = 0; i < c->vChrBufSize; i++)
01228 if(av_pix_fmt_descriptors[c->dstFormat].comp[0].depth_minus1 == 15){
01229 av_assert0(c->dstBpc > 14);
01230 for(j=0; j<dst_stride/2+1; j++)
01231 ((int32_t*)(c->chrUPixBuf[i]))[j] = 1<<18;
01232 } else
01233 for(j=0; j<dst_stride+1; j++)
01234 ((int16_t*)(c->chrUPixBuf[i]))[j] = 1<<14;
01235
01236 av_assert0(c->chrDstH <= dstH);
01237
01238 if (flags & SWS_PRINT_INFO) {
01239 if (flags & SWS_FAST_BILINEAR)
01240 av_log(c, AV_LOG_INFO, "FAST_BILINEAR scaler, ");
01241 else if (flags & SWS_BILINEAR)
01242 av_log(c, AV_LOG_INFO, "BILINEAR scaler, ");
01243 else if (flags & SWS_BICUBIC)
01244 av_log(c, AV_LOG_INFO, "BICUBIC scaler, ");
01245 else if (flags & SWS_X)
01246 av_log(c, AV_LOG_INFO, "Experimental scaler, ");
01247 else if (flags & SWS_POINT)
01248 av_log(c, AV_LOG_INFO, "Nearest Neighbor / POINT scaler, ");
01249 else if (flags & SWS_AREA)
01250 av_log(c, AV_LOG_INFO, "Area Averaging scaler, ");
01251 else if (flags & SWS_BICUBLIN)
01252 av_log(c, AV_LOG_INFO, "luma BICUBIC / chroma BILINEAR scaler, ");
01253 else if (flags & SWS_GAUSS)
01254 av_log(c, AV_LOG_INFO, "Gaussian scaler, ");
01255 else if (flags & SWS_SINC)
01256 av_log(c, AV_LOG_INFO, "Sinc scaler, ");
01257 else if (flags & SWS_LANCZOS)
01258 av_log(c, AV_LOG_INFO, "Lanczos scaler, ");
01259 else if (flags & SWS_SPLINE)
01260 av_log(c, AV_LOG_INFO, "Bicubic spline scaler, ");
01261 else
01262 av_log(c, AV_LOG_INFO, "ehh flags invalid?! ");
01263
01264 av_log(c, AV_LOG_INFO, "from %s to %s%s ",
01265 av_get_pix_fmt_name(srcFormat),
01266 #ifdef DITHER1XBPP
01267 dstFormat == PIX_FMT_BGR555 || dstFormat == PIX_FMT_BGR565 ||
01268 dstFormat == PIX_FMT_RGB444BE || dstFormat == PIX_FMT_RGB444LE ||
01269 dstFormat == PIX_FMT_BGR444BE || dstFormat == PIX_FMT_BGR444LE ?
01270 "dithered " : "",
01271 #else
01272 "",
01273 #endif
01274 av_get_pix_fmt_name(dstFormat));
01275
01276 if (INLINE_MMXEXT(cpu_flags))
01277 av_log(c, AV_LOG_INFO, "using MMX2\n");
01278 else if (INLINE_AMD3DNOW(cpu_flags))
01279 av_log(c, AV_LOG_INFO, "using 3DNOW\n");
01280 else if (INLINE_MMX(cpu_flags))
01281 av_log(c, AV_LOG_INFO, "using MMX\n");
01282 else if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC)
01283 av_log(c, AV_LOG_INFO, "using AltiVec\n");
01284 else
01285 av_log(c, AV_LOG_INFO, "using C\n");
01286
01287 av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
01288 av_log(c, AV_LOG_DEBUG,
01289 "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
01290 c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);
01291 av_log(c, AV_LOG_DEBUG,
01292 "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
01293 c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH,
01294 c->chrXInc, c->chrYInc);
01295 }
01296
01297 c->swScale = ff_getSwsFunc(c);
01298 return 0;
01299 fail:
01300 return -1;
01301 }
01302
01303 #if FF_API_SWS_GETCONTEXT
01304 SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
01305 int dstW, int dstH, enum PixelFormat dstFormat,
01306 int flags, SwsFilter *srcFilter,
01307 SwsFilter *dstFilter, const double *param)
01308 {
01309 SwsContext *c;
01310
01311 if (!(c = sws_alloc_context()))
01312 return NULL;
01313
01314 c->flags = flags;
01315 c->srcW = srcW;
01316 c->srcH = srcH;
01317 c->dstW = dstW;
01318 c->dstH = dstH;
01319 c->srcRange = handle_jpeg(&srcFormat);
01320 c->dstRange = handle_jpeg(&dstFormat);
01321 c->src0Alpha = handle_0alpha(&srcFormat);
01322 c->dst0Alpha = handle_0alpha(&dstFormat);
01323 c->srcFormat = srcFormat;
01324 c->dstFormat = dstFormat;
01325
01326 if (param) {
01327 c->param[0] = param[0];
01328 c->param[1] = param[1];
01329 }
01330 sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->srcRange,
01331 ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] ,
01332 c->dstRange, 0, 1 << 16, 1 << 16);
01333
01334 if (sws_init_context(c, srcFilter, dstFilter) < 0) {
01335 sws_freeContext(c);
01336 return NULL;
01337 }
01338
01339 return c;
01340 }
01341 #endif
01342
01343 SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
01344 float lumaSharpen, float chromaSharpen,
01345 float chromaHShift, float chromaVShift,
01346 int verbose)
01347 {
01348 SwsFilter *filter = av_malloc(sizeof(SwsFilter));
01349 if (!filter)
01350 return NULL;
01351
01352 if (lumaGBlur != 0.0) {
01353 filter->lumH = sws_getGaussianVec(lumaGBlur, 3.0);
01354 filter->lumV = sws_getGaussianVec(lumaGBlur, 3.0);
01355 } else {
01356 filter->lumH = sws_getIdentityVec();
01357 filter->lumV = sws_getIdentityVec();
01358 }
01359
01360 if (chromaGBlur != 0.0) {
01361 filter->chrH = sws_getGaussianVec(chromaGBlur, 3.0);
01362 filter->chrV = sws_getGaussianVec(chromaGBlur, 3.0);
01363 } else {
01364 filter->chrH = sws_getIdentityVec();
01365 filter->chrV = sws_getIdentityVec();
01366 }
01367
01368 if (chromaSharpen != 0.0) {
01369 SwsVector *id = sws_getIdentityVec();
01370 sws_scaleVec(filter->chrH, -chromaSharpen);
01371 sws_scaleVec(filter->chrV, -chromaSharpen);
01372 sws_addVec(filter->chrH, id);
01373 sws_addVec(filter->chrV, id);
01374 sws_freeVec(id);
01375 }
01376
01377 if (lumaSharpen != 0.0) {
01378 SwsVector *id = sws_getIdentityVec();
01379 sws_scaleVec(filter->lumH, -lumaSharpen);
01380 sws_scaleVec(filter->lumV, -lumaSharpen);
01381 sws_addVec(filter->lumH, id);
01382 sws_addVec(filter->lumV, id);
01383 sws_freeVec(id);
01384 }
01385
01386 if (chromaHShift != 0.0)
01387 sws_shiftVec(filter->chrH, (int)(chromaHShift + 0.5));
01388
01389 if (chromaVShift != 0.0)
01390 sws_shiftVec(filter->chrV, (int)(chromaVShift + 0.5));
01391
01392 sws_normalizeVec(filter->chrH, 1.0);
01393 sws_normalizeVec(filter->chrV, 1.0);
01394 sws_normalizeVec(filter->lumH, 1.0);
01395 sws_normalizeVec(filter->lumV, 1.0);
01396
01397 if (verbose)
01398 sws_printVec2(filter->chrH, NULL, AV_LOG_DEBUG);
01399 if (verbose)
01400 sws_printVec2(filter->lumH, NULL, AV_LOG_DEBUG);
01401
01402 return filter;
01403 }
01404
01405 SwsVector *sws_allocVec(int length)
01406 {
01407 SwsVector *vec = av_malloc(sizeof(SwsVector));
01408 if (!vec)
01409 return NULL;
01410 vec->length = length;
01411 vec->coeff = av_malloc(sizeof(double) * length);
01412 if (!vec->coeff)
01413 av_freep(&vec);
01414 return vec;
01415 }
01416
01417 SwsVector *sws_getGaussianVec(double variance, double quality)
01418 {
01419 const int length = (int)(variance * quality + 0.5) | 1;
01420 int i;
01421 double middle = (length - 1) * 0.5;
01422 SwsVector *vec = sws_allocVec(length);
01423
01424 if (!vec)
01425 return NULL;
01426
01427 for (i = 0; i < length; i++) {
01428 double dist = i - middle;
01429 vec->coeff[i] = exp(-dist * dist / (2 * variance * variance)) /
01430 sqrt(2 * variance * M_PI);
01431 }
01432
01433 sws_normalizeVec(vec, 1.0);
01434
01435 return vec;
01436 }
01437
01438 SwsVector *sws_getConstVec(double c, int length)
01439 {
01440 int i;
01441 SwsVector *vec = sws_allocVec(length);
01442
01443 if (!vec)
01444 return NULL;
01445
01446 for (i = 0; i < length; i++)
01447 vec->coeff[i] = c;
01448
01449 return vec;
01450 }
01451
01452 SwsVector *sws_getIdentityVec(void)
01453 {
01454 return sws_getConstVec(1.0, 1);
01455 }
01456
01457 static double sws_dcVec(SwsVector *a)
01458 {
01459 int i;
01460 double sum = 0;
01461
01462 for (i = 0; i < a->length; i++)
01463 sum += a->coeff[i];
01464
01465 return sum;
01466 }
01467
01468 void sws_scaleVec(SwsVector *a, double scalar)
01469 {
01470 int i;
01471
01472 for (i = 0; i < a->length; i++)
01473 a->coeff[i] *= scalar;
01474 }
01475
01476 void sws_normalizeVec(SwsVector *a, double height)
01477 {
01478 sws_scaleVec(a, height / sws_dcVec(a));
01479 }
01480
01481 static SwsVector *sws_getConvVec(SwsVector *a, SwsVector *b)
01482 {
01483 int length = a->length + b->length - 1;
01484 int i, j;
01485 SwsVector *vec = sws_getConstVec(0.0, length);
01486
01487 if (!vec)
01488 return NULL;
01489
01490 for (i = 0; i < a->length; i++) {
01491 for (j = 0; j < b->length; j++) {
01492 vec->coeff[i + j] += a->coeff[i] * b->coeff[j];
01493 }
01494 }
01495
01496 return vec;
01497 }
01498
01499 static SwsVector *sws_sumVec(SwsVector *a, SwsVector *b)
01500 {
01501 int length = FFMAX(a->length, b->length);
01502 int i;
01503 SwsVector *vec = sws_getConstVec(0.0, length);
01504
01505 if (!vec)
01506 return NULL;
01507
01508 for (i = 0; i < a->length; i++)
01509 vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
01510 for (i = 0; i < b->length; i++)
01511 vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] += b->coeff[i];
01512
01513 return vec;
01514 }
01515
01516 static SwsVector *sws_diffVec(SwsVector *a, SwsVector *b)
01517 {
01518 int length = FFMAX(a->length, b->length);
01519 int i;
01520 SwsVector *vec = sws_getConstVec(0.0, length);
01521
01522 if (!vec)
01523 return NULL;
01524
01525 for (i = 0; i < a->length; i++)
01526 vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
01527 for (i = 0; i < b->length; i++)
01528 vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] -= b->coeff[i];
01529
01530 return vec;
01531 }
01532
01533
01534 static SwsVector *sws_getShiftedVec(SwsVector *a, int shift)
01535 {
01536 int length = a->length + FFABS(shift) * 2;
01537 int i;
01538 SwsVector *vec = sws_getConstVec(0.0, length);
01539
01540 if (!vec)
01541 return NULL;
01542
01543 for (i = 0; i < a->length; i++) {
01544 vec->coeff[i + (length - 1) / 2 -
01545 (a->length - 1) / 2 - shift] = a->coeff[i];
01546 }
01547
01548 return vec;
01549 }
01550
01551 void sws_shiftVec(SwsVector *a, int shift)
01552 {
01553 SwsVector *shifted = sws_getShiftedVec(a, shift);
01554 av_free(a->coeff);
01555 a->coeff = shifted->coeff;
01556 a->length = shifted->length;
01557 av_free(shifted);
01558 }
01559
01560 void sws_addVec(SwsVector *a, SwsVector *b)
01561 {
01562 SwsVector *sum = sws_sumVec(a, b);
01563 av_free(a->coeff);
01564 a->coeff = sum->coeff;
01565 a->length = sum->length;
01566 av_free(sum);
01567 }
01568
01569 void sws_subVec(SwsVector *a, SwsVector *b)
01570 {
01571 SwsVector *diff = sws_diffVec(a, b);
01572 av_free(a->coeff);
01573 a->coeff = diff->coeff;
01574 a->length = diff->length;
01575 av_free(diff);
01576 }
01577
01578 void sws_convVec(SwsVector *a, SwsVector *b)
01579 {
01580 SwsVector *conv = sws_getConvVec(a, b);
01581 av_free(a->coeff);
01582 a->coeff = conv->coeff;
01583 a->length = conv->length;
01584 av_free(conv);
01585 }
01586
01587 SwsVector *sws_cloneVec(SwsVector *a)
01588 {
01589 int i;
01590 SwsVector *vec = sws_allocVec(a->length);
01591
01592 if (!vec)
01593 return NULL;
01594
01595 for (i = 0; i < a->length; i++)
01596 vec->coeff[i] = a->coeff[i];
01597
01598 return vec;
01599 }
01600
01601 void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
01602 {
01603 int i;
01604 double max = 0;
01605 double min = 0;
01606 double range;
01607
01608 for (i = 0; i < a->length; i++)
01609 if (a->coeff[i] > max)
01610 max = a->coeff[i];
01611
01612 for (i = 0; i < a->length; i++)
01613 if (a->coeff[i] < min)
01614 min = a->coeff[i];
01615
01616 range = max - min;
01617
01618 for (i = 0; i < a->length; i++) {
01619 int x = (int)((a->coeff[i] - min) * 60.0 / range + 0.5);
01620 av_log(log_ctx, log_level, "%1.3f ", a->coeff[i]);
01621 for (; x > 0; x--)
01622 av_log(log_ctx, log_level, " ");
01623 av_log(log_ctx, log_level, "|\n");
01624 }
01625 }
01626
01627 void sws_freeVec(SwsVector *a)
01628 {
01629 if (!a)
01630 return;
01631 av_freep(&a->coeff);
01632 a->length = 0;
01633 av_free(a);
01634 }
01635
01636 void sws_freeFilter(SwsFilter *filter)
01637 {
01638 if (!filter)
01639 return;
01640
01641 if (filter->lumH)
01642 sws_freeVec(filter->lumH);
01643 if (filter->lumV)
01644 sws_freeVec(filter->lumV);
01645 if (filter->chrH)
01646 sws_freeVec(filter->chrH);
01647 if (filter->chrV)
01648 sws_freeVec(filter->chrV);
01649 av_free(filter);
01650 }
01651
01652 void sws_freeContext(SwsContext *c)
01653 {
01654 int i;
01655 if (!c)
01656 return;
01657
01658 if (c->lumPixBuf) {
01659 for (i = 0; i < c->vLumBufSize; i++)
01660 av_freep(&c->lumPixBuf[i]);
01661 av_freep(&c->lumPixBuf);
01662 }
01663
01664 if (c->chrUPixBuf) {
01665 for (i = 0; i < c->vChrBufSize; i++)
01666 av_freep(&c->chrUPixBuf[i]);
01667 av_freep(&c->chrUPixBuf);
01668 av_freep(&c->chrVPixBuf);
01669 }
01670
01671 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
01672 for (i = 0; i < c->vLumBufSize; i++)
01673 av_freep(&c->alpPixBuf[i]);
01674 av_freep(&c->alpPixBuf);
01675 }
01676
01677 av_freep(&c->vLumFilter);
01678 av_freep(&c->vChrFilter);
01679 av_freep(&c->hLumFilter);
01680 av_freep(&c->hChrFilter);
01681 #if HAVE_ALTIVEC
01682 av_freep(&c->vYCoeffsBank);
01683 av_freep(&c->vCCoeffsBank);
01684 #endif
01685
01686 av_freep(&c->vLumFilterPos);
01687 av_freep(&c->vChrFilterPos);
01688 av_freep(&c->hLumFilterPos);
01689 av_freep(&c->hChrFilterPos);
01690
01691 #if HAVE_MMX_INLINE
01692 #ifdef MAP_ANONYMOUS
01693 if (c->lumMmx2FilterCode)
01694 munmap(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize);
01695 if (c->chrMmx2FilterCode)
01696 munmap(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize);
01697 #elif HAVE_VIRTUALALLOC
01698 if (c->lumMmx2FilterCode)
01699 VirtualFree(c->lumMmx2FilterCode, 0, MEM_RELEASE);
01700 if (c->chrMmx2FilterCode)
01701 VirtualFree(c->chrMmx2FilterCode, 0, MEM_RELEASE);
01702 #else
01703 av_free(c->lumMmx2FilterCode);
01704 av_free(c->chrMmx2FilterCode);
01705 #endif
01706 c->lumMmx2FilterCode = NULL;
01707 c->chrMmx2FilterCode = NULL;
01708 #endif
01709
01710 av_freep(&c->yuvTable);
01711 av_freep(&c->formatConvBuffer);
01712
01713 av_free(c);
01714 }
01715
01716 struct SwsContext *sws_getCachedContext(struct SwsContext *context, int srcW,
01717 int srcH, enum PixelFormat srcFormat,
01718 int dstW, int dstH,
01719 enum PixelFormat dstFormat, int flags,
01720 SwsFilter *srcFilter,
01721 SwsFilter *dstFilter,
01722 const double *param)
01723 {
01724 static const double default_param[2] = { SWS_PARAM_DEFAULT,
01725 SWS_PARAM_DEFAULT };
01726
01727 if (!param)
01728 param = default_param;
01729
01730 if (context &&
01731 (context->srcW != srcW ||
01732 context->srcH != srcH ||
01733 context->srcFormat != srcFormat ||
01734 context->dstW != dstW ||
01735 context->dstH != dstH ||
01736 context->dstFormat != dstFormat ||
01737 context->flags != flags ||
01738 context->param[0] != param[0] ||
01739 context->param[1] != param[1])) {
01740 sws_freeContext(context);
01741 context = NULL;
01742 }
01743
01744 if (!context) {
01745 if (!(context = sws_alloc_context()))
01746 return NULL;
01747 context->srcW = srcW;
01748 context->srcH = srcH;
01749 context->srcRange = handle_jpeg(&srcFormat);
01750 context->src0Alpha = handle_0alpha(&srcFormat);
01751 context->srcFormat = srcFormat;
01752 context->dstW = dstW;
01753 context->dstH = dstH;
01754 context->dstRange = handle_jpeg(&dstFormat);
01755 context->dst0Alpha = handle_0alpha(&dstFormat);
01756 context->dstFormat = dstFormat;
01757 context->flags = flags;
01758 context->param[0] = param[0];
01759 context->param[1] = param[1];
01760 sws_setColorspaceDetails(context, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT],
01761 context->srcRange,
01762 ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] ,
01763 context->dstRange, 0, 1 << 16, 1 << 16);
01764 if (sws_init_context(context, srcFilter, dstFilter) < 0) {
01765 sws_freeContext(context);
01766 return NULL;
01767 }
01768 }
01769 return context;
01770 }