23 #define _SVID_SOURCE // needed for MAP_ANONYMOUS
24 #define _DARWIN_C_SOURCE // needed for MAP_ANON
31 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
32 #define MAP_ANONYMOUS MAP_ANON
36 #define WIN32_LEAN_AND_MEAN
67 return FFMPEG_CONFIGURATION;
72 #define LICENSE_PREFIX "libswscale license: "
248 return ((d * dist + c) * dist + b) * dist +
a;
251 b + 2.0 * c + 3.0 * d,
253 -b - 3.0 * c - 6.0 * d,
259 if (pos == -1 || pos <= -513) {
260 pos = (128 << chr_subsample) - 128;
263 return pos >> chr_subsample;
280 {
SWS_POINT,
"nearest neighbor / point", -1 },
283 {
SWS_X,
"experimental", 8 },
287 int *outFilterSize,
int xInc,
int srcW,
288 int dstW,
int filterAlign,
int one,
289 int flags,
int cpu_flags,
291 double param[2],
int srcPos,
int dstPos)
298 int64_t *filter2 =
NULL;
299 const int64_t fone = 1LL << (54 -
FFMIN(
av_log2(srcW/dstW), 8));
307 if (
FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) {
311 dstW,
sizeof(*filter) * filterSize, fail);
313 for (i = 0; i < dstW; i++) {
314 filter[i * filterSize] = fone;
322 dstW,
sizeof(*filter) * filterSize, fail);
324 xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
325 for (i = 0; i < dstW; i++) {
326 int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
328 (*filterPos)[i] = xx;
332 }
else if ((xInc <= (1 << 16) && (flags &
SWS_AREA)) ||
338 dstW,
sizeof(*filter) * filterSize, fail);
340 xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
341 for (i = 0; i < dstW; i++) {
342 int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
345 (*filterPos)[i] = xx;
347 for (j = 0; j < filterSize; j++) {
348 int64_t
coeff= fone -
FFABS(((int64_t)xx<<16) - xDstInSrc)*(fone>>16);
351 filter[i * filterSize + j] =
coeff;
361 if (flags & scale_algorithms[i].flag && scale_algorithms[i].size_factor > 0) {
371 filterSize = 1 + sizeFactor;
373 filterSize = 1 + (sizeFactor * srcW + dstW - 1) / dstW;
375 filterSize =
FFMIN(filterSize, srcW - 2);
376 filterSize =
FFMAX(filterSize, 1);
379 dstW,
sizeof(*filter) * filterSize, fail);
381 xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7);
382 for (i = 0; i < dstW; i++) {
383 int xx = (xDstInSrc - ((int64_t)(filterSize - 2) << 16)) / (1 << 17);
385 (*filterPos)[i] = xx;
386 for (j = 0; j < filterSize; j++) {
387 int64_t d = (
FFABS(((int64_t)xx << 17) - xDstInSrc)) << 13;
393 floatd = d * (1.0 / (1 << 30));
399 if (d >= 1LL << 31) {
402 int64_t dd = (d * d) >> 30;
403 int64_t ddd = (dd * d) >> 30;
406 coeff = (12 * (1 << 24) - 9 * B - 6 * C) * ddd +
407 (-18 * (1 << 24) + 12 * B + 6 * C) * dd +
408 (6 * (1 << 24) - 2 * B) * (1 << 30);
410 coeff = (-B - 6 * C) * ddd +
411 (6 * B + 30 * C) * dd +
412 (-12 * B - 48 * C) * d +
413 (8 * B + 24 * C) * (1 << 30);
415 coeff /= (1LL<<54)/fone;
418 else if (flags &
SWS_X) {
419 double p = param ? param * 0.01 : 0.3;
420 coeff = d ? sin(d *
M_PI) / (d *
M_PI) : 1.0;
421 coeff *= pow(2.0, -p * d * d);
424 else if (flags & SWS_X) {
429 c = cos(floatd *
M_PI);
436 coeff = (c * 0.5 + 0.5) * fone;
438 int64_t d2 = d - (1 << 29);
439 if (d2 * xInc < -(1LL << (29 + 16)))
440 coeff = 1.0 * (1LL << (30 + 16));
441 else if (d2 * xInc < (1LL << (29 + 16)))
442 coeff = -d2 * xInc + (1LL << (29 + 16));
445 coeff *= fone >> (30 + 16);
448 coeff = (pow(2.0, -p * floatd * floatd)) * fone;
450 coeff = (d ? sin(floatd *
M_PI) / (floatd *
M_PI) : 1.0) * fone;
451 }
else if (flags & SWS_LANCZOS) {
453 coeff = (d ? sin(floatd *
M_PI) * sin(floatd * M_PI / p) /
454 (floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;
458 coeff = (1 << 30) - d;
463 double p = -2.196152422706632;
469 filter[i * filterSize + j] =
coeff;
472 xDstInSrc += 2 * xInc;
480 filter2Size = filterSize;
482 filter2Size += srcFilter->
length - 1;
484 filter2Size += dstFilter->
length - 1;
488 for (i = 0; i < dstW; i++) {
492 for (k = 0; k < srcFilter->
length; k++) {
493 for (j = 0; j < filterSize; j++)
494 filter2[i * filter2Size + k + j] +=
495 srcFilter->
coeff[k] * filter[i * filterSize + j];
498 for (j = 0; j < filterSize; j++)
499 filter2[i * filter2Size + j] = filter[i * filterSize + j];
503 (*filterPos)[i] += (filterSize - 1) / 2 - (filter2Size - 1) / 2;
510 for (i = dstW - 1; i >= 0; i--) {
511 int min = filter2Size;
513 int64_t cutOff = 0.0;
516 for (j = 0; j < filter2Size; j++) {
518 cutOff +=
FFABS(filter2[i * filter2Size]);
525 if (i < dstW - 1 && (*filterPos)[i] >= (*filterPos)[i + 1])
529 for (k = 1; k < filter2Size; k++)
530 filter2[i * filter2Size + k - 1] = filter2[i * filter2Size + k];
531 filter2[i * filter2Size + k - 1] = 0;
537 for (j = filter2Size - 1; j > 0; j--) {
538 cutOff +=
FFABS(filter2[i * filter2Size + j]);
545 if (min > minFilterSize)
551 if (minFilterSize < 5)
557 if (minFilterSize < 3)
563 if (minFilterSize == 1 && filterAlign == 2)
568 filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));
578 *outFilterSize = filterSize;
582 "SwScaler: reducing / aligning filtersize %d -> %d\n",
583 filter2Size, filterSize);
585 for (i = 0; i < dstW; i++) {
588 for (j = 0; j < filterSize; j++) {
589 if (j >= filter2Size)
590 filter[i * filterSize + j] = 0;
592 filter[i * filterSize + j] = filter2[i * filter2Size + j];
594 filter[i * filterSize + j] = 0;
601 for (i = 0; i < dstW; i++) {
603 if ((*filterPos)[i] < 0) {
605 for (j = 1; j < filterSize; j++) {
606 int left =
FFMAX(j + (*filterPos)[i], 0);
607 filter[i * filterSize + left] += filter[i * filterSize + j];
608 filter[i * filterSize + j] = 0;
613 if ((*filterPos)[i] + filterSize > srcW) {
614 int shift = (*filterPos)[i] +
FFMIN(filterSize - srcW, 0);
617 for (j = filterSize - 1; j >= 0; j--) {
618 if ((*filterPos)[i] + j >= srcW) {
619 acc += filter[i * filterSize + j];
620 filter[i * filterSize + j] = 0;
623 for (j = filterSize - 1; j >= 0; j--) {
625 filter[i * filterSize + j] = 0;
627 filter[i * filterSize + j] = filter[i * filterSize + j -
shift];
631 (*filterPos)[i]-=
shift;
632 filter[i * filterSize + srcW - 1 - (*filterPos)[i]] +=
acc;
636 if ((*filterPos)[i] + filterSize > srcW) {
637 for (j = 0; j < filterSize; j++) {
638 av_assert0((*filterPos)[i] + j < srcW || !filter[i * filterSize + j]);
646 (dstW + 3), *outFilterSize *
sizeof(int16_t), fail);
649 for (i = 0; i < dstW; i++) {
654 for (j = 0; j < filterSize; j++) {
655 sum += filter[i * filterSize + j];
657 sum = (sum + one / 2) / one;
662 for (j = 0; j < *outFilterSize; j++) {
663 int64_t
v = filter[i * filterSize + j] + error;
665 (*outFilter)[i * (*outFilterSize) + j] = intV;
666 error = v - intV * sum;
670 (*filterPos)[dstW + 0] =
671 (*filterPos)[dstW + 1] =
672 (*filterPos)[dstW + 2] = (*filterPos)[dstW - 1];
674 for (i = 0; i < *outFilterSize; i++) {
675 int k = (dstW - 1) * (*outFilterSize) + i;
676 (*outFilter)[k + 1 * (*outFilterSize)] =
677 (*outFilter)[k + 2 * (*outFilterSize)] =
678 (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];
693 int64_t
W,
V, Z, Cy, Cu, Cv;
694 int64_t vr = table[0];
695 int64_t ub = table[1];
696 int64_t ug = -table[2];
697 int64_t vg = -table[3];
702 static const int8_t map[] = {
727 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
728 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
729 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
730 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
731 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
732 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
733 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
734 -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
771 c->input_rgb2yuv_table[
BY_IDX] = ((int)(0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
772 c->input_rgb2yuv_table[
BV_IDX] = (-(int)(0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
773 c->input_rgb2yuv_table[
BU_IDX] = ((int)(0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
774 c->input_rgb2yuv_table[
GY_IDX] = ((int)(0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
775 c->input_rgb2yuv_table[
GV_IDX] = (-(int)(0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
776 c->input_rgb2yuv_table[
GU_IDX] = (-(int)(0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
777 c->input_rgb2yuv_table[
RY_IDX] = ((int)(0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
778 c->input_rgb2yuv_table[
RV_IDX] = ((int)(0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
779 c->input_rgb2yuv_table[
RU_IDX] = (-(int)(0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5));
782 AV_WL16(p + 16*4 + 2*i, map[i] >= 0 ?
c->input_rgb2yuv_table[map[i]] : 0);
792 static const int16_t xyz2rgb_matrix[3][4] = {
793 {13270, -6295, -2041},
795 { 228, -835, 4329} };
796 static const int16_t rgb2xyz_matrix[3][4] = {
800 static int16_t xyzgamma_tab[4096], rgbgamma_tab[4096], xyzgammainv_tab[4096], rgbgammainv_tab[4096];
809 if (rgbgamma_tab[4095])
813 for (i = 0; i < 4096; i++) {
814 xyzgamma_tab[i] =
lrint(pow(i / 4095.0, xyzgamma) * 4095.0);
815 rgbgamma_tab[i] =
lrint(pow(i / 4095.0, rgbgamma) * 4095.0);
816 xyzgammainv_tab[i] =
lrint(pow(i / 4095.0, xyzgammainv) * 4095.0);
817 rgbgammainv_tab[i] =
lrint(pow(i / 4095.0, rgbgammainv) * 4095.0);
822 int srcRange,
const int table[4],
int dstRange,
823 int brightness,
int contrast,
int saturation)
861 contrast, saturation);
866 contrast, saturation);
875 int *srcRange,
int **
table,
int *dstRange,
876 int *brightness,
int *contrast,
int *saturation)
967 int usesVFilter, usesHFilter;
974 int dst_stride =
FFALIGN(dstW *
sizeof(int16_t) + 66, 16);
975 int flags, cpu_flags;
988 unscaled = (srcW == dstW && srcH == dstH);
994 av_log(c,
AV_LOG_WARNING,
"deprecated pixel format used, make sure you did set range correctly\n");
1035 if (dstW < srcW && dstH < srcH)
1037 else if (dstW > srcW && dstH > srcH)
1042 }
else if (i & (i - 1)) {
1044 "Exactly one scaler algorithm must be chosen, got %X\n", i);
1048 if (srcW < 1 || srcH < 1 || dstW < 1 || dstH < 1) {
1052 srcW, srcH, dstW, dstH);
1057 dstFilter = &dummyFilter;
1059 srcFilter = &dummyFilter;
1061 c->
lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW;
1062 c->
lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH;
1065 c->
vRounder = 4 * 0x0001000100010001ULL;
1067 usesVFilter = (srcFilter->
lumV && srcFilter->
lumV->
length > 1) ||
1071 usesHFilter = (srcFilter->
lumH && srcFilter->
lumH->
length > 1) ||
1091 av_log(c,
AV_LOG_DEBUG,
"Forcing full internal H chroma due to input having non subsampled chroma\n");
1108 if (!(flags & SWS_FULL_CHR_H_INT)) {
1111 "Desired dithering only supported in full chroma interpolation for destination format '%s'\n",
1117 if (flags & SWS_FULL_CHR_H_INT) {
1120 "Ordered dither is not supported in full chroma interpolation for destination format '%s'\n",
1127 if (!(flags & SWS_FULL_CHR_H_INT)) {
1129 "%s output is not supported with half chroma resolution, switching to full\n",
1138 if (flags & SWS_FULL_CHR_H_INT &&
1153 "full chroma interpolation for destination format '%s' not yet implemented\n",
1155 flags &= ~SWS_FULL_CHR_H_INT;
1158 if (
isAnyRGB(dstFormat) && !(flags & SWS_FULL_CHR_H_INT))
1209 "output width is not a multiple of 32 -> no MMXEXT scaler\n");
1226 if (flags & SWS_FAST_BILINEAR) {
1233 c->
lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20;
1244 srcW, srcH, tmpFormat, 64);
1249 srcW, srcH, tmpFormat,
1255 dstW, dstH, dstFormat,
1263 #define USE_MMAP (HAVE_MMAP && HAVE_MPROTECT && defined MAP_ANONYMOUS)
1267 #if HAVE_MMXEXT_INLINE
1277 PROT_READ | PROT_WRITE,
1278 MAP_PRIVATE | MAP_ANONYMOUS,
1281 PROT_READ | PROT_WRITE,
1282 MAP_PRIVATE | MAP_ANONYMOUS,
1284 #elif HAVE_VIRTUALALLOC
1288 PAGE_EXECUTE_READWRITE);
1292 PAGE_EXECUTE_READWRITE);
1298 #ifdef MAP_ANONYMOUS
1328 const int filterAlign =
X86_MMX(cpu_flags) ? 4 :
1333 srcW, dstW, filterAlign, 1 << 14,
1335 cpu_flags, srcFilter->
lumH, dstFilter->
lumH,
1343 (flags & SWS_BICUBLIN) ? (flags |
SWS_BILINEAR) : flags,
1344 cpu_flags, srcFilter->
chrH, dstFilter->
chrH,
1354 const int filterAlign =
X86_MMX(cpu_flags) ? 2 :
1358 c->
lumYInc, srcH, dstH, filterAlign, (1 << 12),
1360 cpu_flags, srcFilter->
lumV, dstFilter->
lumV,
1367 filterAlign, (1 << 12),
1368 (flags & SWS_BICUBLIN) ? (flags |
SWS_BILINEAR) : flags,
1369 cpu_flags, srcFilter->
chrV, dstFilter->
chrV,
1382 short *p = (
short *)&c->vYCoeffsBank[i];
1383 for (j = 0; j < 8; j++)
1389 short *p = (
short *)&c->vCCoeffsBank[i];
1390 for (j = 0; j < 8; j++)
1399 for (i = 0; i < dstH; i++) {
1400 int chrI = (int64_t)i * c->
chrDstH / dstH;
1415 for (i = 0; i < 4; i++)
1430 dst_stride + 16, fail);
1438 dst_stride * 2 + 32, fail);
1443 if (CONFIG_SWSCALE_ALPHA && c->
alpPixBuf)
1446 dst_stride + 16, fail);
1454 for(j=0; j<dst_stride/2+1; j++)
1457 for(j=0; j<dst_stride+1; j++)
1463 const char *scaler =
NULL, *cpucaps;
1466 if (flags & scale_algorithms[i].flag) {
1472 scaler =
"ehh flags invalid?!";
1493 cpucaps =
"AltiVec";
1501 "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1504 "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1510 if (unscaled && !usesHFilter && !usesVFilter &&
1515 if (flags & SWS_PRINT_INFO)
1517 "using unscaled %s -> %s special converter\n",
1527 int tmpW = sqrt(srcW * (int64_t)dstW);
1528 int tmpH = sqrt(srcH * (int64_t)dstH);
1531 if (srcW*(int64_t)srcH <= 4LL*dstW*dstH)
1535 tmpW, tmpH, tmpFormat, 64);
1540 tmpW, tmpH, tmpFormat,
1546 dstW, dstH, dstFormat,
1558 SwsFilter *dstFilter,
const double *param)
1574 c->
param[0] = param[0];
1575 c->
param[1] = param[1];
1587 float lumaSharpen,
float chromaSharpen,
1588 float chromaHShift,
float chromaVShift,
1595 if (lumaGBlur != 0.0) {
1603 if (chromaGBlur != 0.0) {
1620 if (chromaSharpen != 0.0) {
1629 if (lumaSharpen != 0.0) {
1638 if (chromaHShift != 0.0)
1641 if (chromaVShift != 0.0)
1676 const int length = (int)(variance * quality + 0.5) | 1;
1678 double middle = (length - 1) * 0.5;
1681 if(variance < 0 || quality < 0)
1689 for (i = 0; i <
length; i++) {
1690 double dist = i - middle;
1691 vec->
coeff[i] = exp(-dist * dist / (2 * variance * variance)) /
1692 sqrt(2 * variance *
M_PI);
1708 for (i = 0; i <
length; i++)
1724 for (i = 0; i < a->
length; i++)
1734 for (i = 0; i < a->
length; i++)
1735 a->
coeff[i] *= scalar;
1752 for (i = 0; i < a->
length; i++) {
1753 for (j = 0; j < b->
length; j++) {
1770 for (i = 0; i < a->
length; i++)
1787 for (i = 0; i < a->
length; i++)
1805 for (i = 0; i < a->
length; i++) {
1806 vec->
coeff[i + (length - 1) / 2 -
1868 for (i = 0; i < a->
length; i++)
1869 if (a->
coeff[i] > max)
1872 for (i = 0; i < a->
length; i++)
1873 if (a->
coeff[i] < min)
1878 for (i = 0; i < a->
length; i++) {
1879 int x = (int)((a->
coeff[i] - min) * 60.0 / range + 0.5);
1880 av_log(log_ctx, log_level,
"%1.3f ", a->
coeff[i]);
1882 av_log(log_ctx, log_level,
" ");
1883 av_log(log_ctx, log_level,
"|\n");
1927 if (CONFIG_SWSCALE_ALPHA && c->
alpPixBuf) {
1933 for (i = 0; i < 4; i++)
1956 #elif HAVE_VIRTUALALLOC
1986 const double *
param)
1994 param = default_param;
1997 (context->
srcW != srcW ||
1998 context->
srcH != srcH ||
2000 context->
dstW != dstW ||
2001 context->
dstH != dstH ||
2003 context->
flags != flags ||
2004 context->
param[0] != param[0] ||
2005 context->
param[1] != param[1])) {
2025 context->
param[0] = param[0];
2026 context->
param[1] = param[1];