Libav
utils.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config.h"
22 
23 #define _SVID_SOURCE // needed for MAP_ANONYMOUS
24 #include <assert.h>
25 #include <inttypes.h>
26 #include <math.h>
27 #include <stdio.h>
28 #include <string.h>
29 #if HAVE_SYS_MMAN_H
30 #include <sys/mman.h>
31 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
32 #define MAP_ANONYMOUS MAP_ANON
33 #endif
34 #endif
35 #if HAVE_VIRTUALALLOC
36 #define WIN32_LEAN_AND_MEAN
37 #include <windows.h>
38 #endif
39 
40 #include "libavutil/attributes.h"
41 #include "libavutil/avutil.h"
42 #include "libavutil/bswap.h"
43 #include "libavutil/cpu.h"
44 #include "libavutil/intreadwrite.h"
45 #include "libavutil/mathematics.h"
46 #include "libavutil/opt.h"
47 #include "libavutil/pixdesc.h"
48 #include "libavutil/ppc/cpu.h"
49 #include "libavutil/x86/asm.h"
50 #include "libavutil/x86/cpu.h"
51 #include "rgb2rgb.h"
52 #include "swscale.h"
53 #include "swscale_internal.h"
54 
55 unsigned swscale_version(void)
56 {
58 }
59 
60 const char *swscale_configuration(void)
61 {
62  return LIBAV_CONFIGURATION;
63 }
64 
65 const char *swscale_license(void)
66 {
67 #define LICENSE_PREFIX "libswscale license: "
68  return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
69 }
70 
71 #define RET 0xC3 // near return opcode for x86
72 
73 typedef struct FormatEntry {
77 } FormatEntry;
78 
80  [AV_PIX_FMT_YUV420P] = { 1, 1 },
81  [AV_PIX_FMT_YUYV422] = { 1, 1 },
82  [AV_PIX_FMT_RGB24] = { 1, 1 },
83  [AV_PIX_FMT_BGR24] = { 1, 1 },
84  [AV_PIX_FMT_YUV422P] = { 1, 1 },
85  [AV_PIX_FMT_YUV444P] = { 1, 1 },
86  [AV_PIX_FMT_YUV410P] = { 1, 1 },
87  [AV_PIX_FMT_YUV411P] = { 1, 1 },
88  [AV_PIX_FMT_GRAY8] = { 1, 1 },
89  [AV_PIX_FMT_MONOWHITE] = { 1, 1 },
90  [AV_PIX_FMT_MONOBLACK] = { 1, 1 },
91  [AV_PIX_FMT_PAL8] = { 1, 0 },
92  [AV_PIX_FMT_YUVJ420P] = { 1, 1 },
93  [AV_PIX_FMT_YUVJ422P] = { 1, 1 },
94  [AV_PIX_FMT_YUVJ444P] = { 1, 1 },
95  [AV_PIX_FMT_YVYU422] = { 1, 1 },
96  [AV_PIX_FMT_UYVY422] = { 1, 1 },
97  [AV_PIX_FMT_UYYVYY411] = { 0, 0 },
98  [AV_PIX_FMT_BGR8] = { 1, 1 },
99  [AV_PIX_FMT_BGR4] = { 0, 1 },
100  [AV_PIX_FMT_BGR4_BYTE] = { 1, 1 },
101  [AV_PIX_FMT_RGB8] = { 1, 1 },
102  [AV_PIX_FMT_RGB4] = { 0, 1 },
103  [AV_PIX_FMT_RGB4_BYTE] = { 1, 1 },
104  [AV_PIX_FMT_NV12] = { 1, 1 },
105  [AV_PIX_FMT_NV21] = { 1, 1 },
106  [AV_PIX_FMT_ARGB] = { 1, 1 },
107  [AV_PIX_FMT_RGBA] = { 1, 1 },
108  [AV_PIX_FMT_ABGR] = { 1, 1 },
109  [AV_PIX_FMT_BGRA] = { 1, 1 },
110  [AV_PIX_FMT_GRAY16BE] = { 1, 1 },
111  [AV_PIX_FMT_GRAY16LE] = { 1, 1 },
112  [AV_PIX_FMT_YUV440P] = { 1, 1 },
113  [AV_PIX_FMT_YUVJ440P] = { 1, 1 },
114  [AV_PIX_FMT_YUVA420P] = { 1, 1 },
115  [AV_PIX_FMT_YUVA422P] = { 1, 1 },
116  [AV_PIX_FMT_YUVA444P] = { 1, 1 },
117  [AV_PIX_FMT_YUVA420P9BE] = { 1, 1 },
118  [AV_PIX_FMT_YUVA420P9LE] = { 1, 1 },
119  [AV_PIX_FMT_YUVA422P9BE] = { 1, 1 },
120  [AV_PIX_FMT_YUVA422P9LE] = { 1, 1 },
121  [AV_PIX_FMT_YUVA444P9BE] = { 1, 1 },
122  [AV_PIX_FMT_YUVA444P9LE] = { 1, 1 },
123  [AV_PIX_FMT_YUVA420P10BE]= { 1, 1 },
124  [AV_PIX_FMT_YUVA420P10LE]= { 1, 1 },
125  [AV_PIX_FMT_YUVA422P10BE]= { 1, 1 },
126  [AV_PIX_FMT_YUVA422P10LE]= { 1, 1 },
127  [AV_PIX_FMT_YUVA444P10BE]= { 1, 1 },
128  [AV_PIX_FMT_YUVA444P10LE]= { 1, 1 },
129  [AV_PIX_FMT_YUVA420P16BE]= { 1, 1 },
130  [AV_PIX_FMT_YUVA420P16LE]= { 1, 1 },
131  [AV_PIX_FMT_YUVA422P16BE]= { 1, 1 },
132  [AV_PIX_FMT_YUVA422P16LE]= { 1, 1 },
133  [AV_PIX_FMT_YUVA444P16BE]= { 1, 1 },
134  [AV_PIX_FMT_YUVA444P16LE]= { 1, 1 },
135  [AV_PIX_FMT_RGB48BE] = { 1, 1 },
136  [AV_PIX_FMT_RGB48LE] = { 1, 1 },
137  [AV_PIX_FMT_RGBA64BE] = { 0, 0, 1 },
138  [AV_PIX_FMT_RGBA64LE] = { 0, 0, 1 },
139  [AV_PIX_FMT_RGB565BE] = { 1, 1 },
140  [AV_PIX_FMT_RGB565LE] = { 1, 1 },
141  [AV_PIX_FMT_RGB555BE] = { 1, 1 },
142  [AV_PIX_FMT_RGB555LE] = { 1, 1 },
143  [AV_PIX_FMT_BGR565BE] = { 1, 1 },
144  [AV_PIX_FMT_BGR565LE] = { 1, 1 },
145  [AV_PIX_FMT_BGR555BE] = { 1, 1 },
146  [AV_PIX_FMT_BGR555LE] = { 1, 1 },
147  [AV_PIX_FMT_YUV420P16LE] = { 1, 1 },
148  [AV_PIX_FMT_YUV420P16BE] = { 1, 1 },
149  [AV_PIX_FMT_YUV422P16LE] = { 1, 1 },
150  [AV_PIX_FMT_YUV422P16BE] = { 1, 1 },
151  [AV_PIX_FMT_YUV444P16LE] = { 1, 1 },
152  [AV_PIX_FMT_YUV444P16BE] = { 1, 1 },
153  [AV_PIX_FMT_RGB444LE] = { 1, 1 },
154  [AV_PIX_FMT_RGB444BE] = { 1, 1 },
155  [AV_PIX_FMT_BGR444LE] = { 1, 1 },
156  [AV_PIX_FMT_BGR444BE] = { 1, 1 },
157  [AV_PIX_FMT_YA8] = { 1, 0 },
158  [AV_PIX_FMT_YA16BE] = { 1, 0 },
159  [AV_PIX_FMT_YA16LE] = { 1, 0 },
160  [AV_PIX_FMT_BGR48BE] = { 1, 1 },
161  [AV_PIX_FMT_BGR48LE] = { 1, 1 },
162  [AV_PIX_FMT_BGRA64BE] = { 0, 0, 1 },
163  [AV_PIX_FMT_BGRA64LE] = { 0, 0, 1 },
164  [AV_PIX_FMT_YUV420P9BE] = { 1, 1 },
165  [AV_PIX_FMT_YUV420P9LE] = { 1, 1 },
166  [AV_PIX_FMT_YUV420P10BE] = { 1, 1 },
167  [AV_PIX_FMT_YUV420P10LE] = { 1, 1 },
168  [AV_PIX_FMT_YUV422P9BE] = { 1, 1 },
169  [AV_PIX_FMT_YUV422P9LE] = { 1, 1 },
170  [AV_PIX_FMT_YUV422P10BE] = { 1, 1 },
171  [AV_PIX_FMT_YUV422P10LE] = { 1, 1 },
172  [AV_PIX_FMT_YUV444P9BE] = { 1, 1 },
173  [AV_PIX_FMT_YUV444P9LE] = { 1, 1 },
174  [AV_PIX_FMT_YUV444P10BE] = { 1, 1 },
175  [AV_PIX_FMT_YUV444P10LE] = { 1, 1 },
176  [AV_PIX_FMT_GBRP] = { 1, 1 },
177  [AV_PIX_FMT_GBRP9LE] = { 1, 1 },
178  [AV_PIX_FMT_GBRP9BE] = { 1, 1 },
179  [AV_PIX_FMT_GBRP10LE] = { 1, 1 },
180  [AV_PIX_FMT_GBRP10BE] = { 1, 1 },
181  [AV_PIX_FMT_GBRP16LE] = { 1, 0 },
182  [AV_PIX_FMT_GBRP16BE] = { 1, 0 },
183  [AV_PIX_FMT_XYZ12BE] = { 0, 0, 1 },
184  [AV_PIX_FMT_XYZ12LE] = { 0, 0, 1 },
185 };
186 
188 {
189  return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
190  format_entries[pix_fmt].is_supported_in : 0;
191 }
192 
194 {
195  return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
196  format_entries[pix_fmt].is_supported_out : 0;
197 }
198 
200 {
201  return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
202  format_entries[pix_fmt].is_supported_endianness : 0;
203 }
204 
205 const char *sws_format_name(enum AVPixelFormat format)
206 {
207  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
208  if (desc)
209  return desc->name;
210  else
211  return "Unknown format";
212 }
213 
214 static double getSplineCoeff(double a, double b, double c, double d,
215  double dist)
216 {
217  if (dist <= 1.0)
218  return ((d * dist + c) * dist + b) * dist + a;
219  else
220  return getSplineCoeff(0.0,
221  b + 2.0 * c + 3.0 * d,
222  c + 3.0 * d,
223  -b - 3.0 * c - 6.0 * d,
224  dist - 1.0);
225 }
226 
227 static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
228  int *outFilterSize, int xInc, int srcW,
229  int dstW, int filterAlign, int one,
230  int flags, int cpu_flags,
231  SwsVector *srcFilter, SwsVector *dstFilter,
232  double param[2], int is_horizontal)
233 {
234  int i;
235  int filterSize;
236  int filter2Size;
237  int minFilterSize;
238  int64_t *filter = NULL;
239  int64_t *filter2 = NULL;
240  const int64_t fone = 1LL << 54;
241  int ret = -1;
242 
243  emms_c(); // FIXME should not be required but IS (even for non-MMX versions)
244 
245  // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end
246  FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW + 3) * sizeof(**filterPos), fail);
247 
248  if (FFABS(xInc - 0x10000) < 10) { // unscaled
249  int i;
250  filterSize = 1;
251  FF_ALLOCZ_OR_GOTO(NULL, filter,
252  dstW * sizeof(*filter) * filterSize, fail);
253 
254  for (i = 0; i < dstW; i++) {
255  filter[i * filterSize] = fone;
256  (*filterPos)[i] = i;
257  }
258  } else if (flags & SWS_POINT) { // lame looking point sampling mode
259  int i;
260  int xDstInSrc;
261  filterSize = 1;
262  FF_ALLOC_OR_GOTO(NULL, filter,
263  dstW * sizeof(*filter) * filterSize, fail);
264 
265  xDstInSrc = xInc / 2 - 0x8000;
266  for (i = 0; i < dstW; i++) {
267  int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
268 
269  (*filterPos)[i] = xx;
270  filter[i] = fone;
271  xDstInSrc += xInc;
272  }
273  } else if ((xInc <= (1 << 16) && (flags & SWS_AREA)) ||
274  (flags & SWS_FAST_BILINEAR)) { // bilinear upscale
275  int i;
276  int xDstInSrc;
277  filterSize = 2;
278  FF_ALLOC_OR_GOTO(NULL, filter,
279  dstW * sizeof(*filter) * filterSize, fail);
280 
281  xDstInSrc = xInc / 2 - 0x8000;
282  for (i = 0; i < dstW; i++) {
283  int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;
284  int j;
285 
286  (*filterPos)[i] = xx;
287  // bilinear upscale / linear interpolate / area averaging
288  for (j = 0; j < filterSize; j++) {
289  int64_t coeff = fone - FFABS((xx << 16) - xDstInSrc) *
290  (fone >> 16);
291  if (coeff < 0)
292  coeff = 0;
293  filter[i * filterSize + j] = coeff;
294  xx++;
295  }
296  xDstInSrc += xInc;
297  }
298  } else {
299  int64_t xDstInSrc;
300  int sizeFactor;
301 
302  if (flags & SWS_BICUBIC)
303  sizeFactor = 4;
304  else if (flags & SWS_X)
305  sizeFactor = 8;
306  else if (flags & SWS_AREA)
307  sizeFactor = 1; // downscale only, for upscale it is bilinear
308  else if (flags & SWS_GAUSS)
309  sizeFactor = 8; // infinite ;)
310  else if (flags & SWS_LANCZOS)
311  sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;
312  else if (flags & SWS_SINC)
313  sizeFactor = 20; // infinite ;)
314  else if (flags & SWS_SPLINE)
315  sizeFactor = 20; // infinite ;)
316  else if (flags & SWS_BILINEAR)
317  sizeFactor = 2;
318  else {
319  sizeFactor = 0; // GCC warning killer
320  assert(0);
321  }
322 
323  if (xInc <= 1 << 16)
324  filterSize = 1 + sizeFactor; // upscale
325  else
326  filterSize = 1 + (sizeFactor * srcW + dstW - 1) / dstW;
327 
328  filterSize = FFMIN(filterSize, srcW - 2);
329  filterSize = FFMAX(filterSize, 1);
330 
331  FF_ALLOC_OR_GOTO(NULL, filter,
332  dstW * sizeof(*filter) * filterSize, fail);
333 
334  xDstInSrc = xInc - 0x10000;
335  for (i = 0; i < dstW; i++) {
336  int xx = (xDstInSrc - ((int64_t)(filterSize - 2) << 16)) / (1 << 17);
337  int j;
338  (*filterPos)[i] = xx;
339  for (j = 0; j < filterSize; j++) {
340  int64_t d = (FFABS(((int64_t)xx << 17) - xDstInSrc)) << 13;
341  double floatd;
342  int64_t coeff;
343 
344  if (xInc > 1 << 16)
345  d = d * dstW / srcW;
346  floatd = d * (1.0 / (1 << 30));
347 
348  if (flags & SWS_BICUBIC) {
349  int64_t B = (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1 << 24);
350  int64_t C = (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1 << 24);
351 
352  if (d >= 1LL << 31) {
353  coeff = 0.0;
354  } else {
355  int64_t dd = (d * d) >> 30;
356  int64_t ddd = (dd * d) >> 30;
357 
358  if (d < 1LL << 30)
359  coeff = (12 * (1 << 24) - 9 * B - 6 * C) * ddd +
360  (-18 * (1 << 24) + 12 * B + 6 * C) * dd +
361  (6 * (1 << 24) - 2 * B) * (1 << 30);
362  else
363  coeff = (-B - 6 * C) * ddd +
364  (6 * B + 30 * C) * dd +
365  (-12 * B - 48 * C) * d +
366  (8 * B + 24 * C) * (1 << 30);
367  }
368  coeff *= fone >> (30 + 24);
369  }
370 #if 0
371  else if (flags & SWS_X) {
372  double p = param ? param * 0.01 : 0.3;
373  coeff = d ? sin(d * M_PI) / (d * M_PI) : 1.0;
374  coeff *= pow(2.0, -p * d * d);
375  }
376 #endif
377  else if (flags & SWS_X) {
378  double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;
379  double c;
380 
381  if (floatd < 1.0)
382  c = cos(floatd * M_PI);
383  else
384  c = -1.0;
385  if (c < 0.0)
386  c = -pow(-c, A);
387  else
388  c = pow(c, A);
389  coeff = (c * 0.5 + 0.5) * fone;
390  } else if (flags & SWS_AREA) {
391  int64_t d2 = d - (1 << 29);
392  if (d2 * xInc < -(1LL << (29 + 16)))
393  coeff = 1.0 * (1LL << (30 + 16));
394  else if (d2 * xInc < (1LL << (29 + 16)))
395  coeff = -d2 * xInc + (1LL << (29 + 16));
396  else
397  coeff = 0.0;
398  coeff *= fone >> (30 + 16);
399  } else if (flags & SWS_GAUSS) {
400  double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
401  coeff = (pow(2.0, -p * floatd * floatd)) * fone;
402  } else if (flags & SWS_SINC) {
403  coeff = (d ? sin(floatd * M_PI) / (floatd * M_PI) : 1.0) * fone;
404  } else if (flags & SWS_LANCZOS) {
405  double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
406  coeff = (d ? sin(floatd * M_PI) * sin(floatd * M_PI / p) /
407  (floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;
408  if (floatd > p)
409  coeff = 0;
410  } else if (flags & SWS_BILINEAR) {
411  coeff = (1 << 30) - d;
412  if (coeff < 0)
413  coeff = 0;
414  coeff *= fone >> 30;
415  } else if (flags & SWS_SPLINE) {
416  double p = -2.196152422706632;
417  coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;
418  } else {
419  coeff = 0.0; // GCC warning killer
420  assert(0);
421  }
422 
423  filter[i * filterSize + j] = coeff;
424  xx++;
425  }
426  xDstInSrc += 2 * xInc;
427  }
428  }
429 
430  /* apply src & dst Filter to filter -> filter2
431  * av_free(filter);
432  */
433  assert(filterSize > 0);
434  filter2Size = filterSize;
435  if (srcFilter)
436  filter2Size += srcFilter->length - 1;
437  if (dstFilter)
438  filter2Size += dstFilter->length - 1;
439  assert(filter2Size > 0);
440  FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size * dstW * sizeof(*filter2), fail);
441 
442  for (i = 0; i < dstW; i++) {
443  int j, k;
444 
445  if (srcFilter) {
446  for (k = 0; k < srcFilter->length; k++) {
447  for (j = 0; j < filterSize; j++)
448  filter2[i * filter2Size + k + j] +=
449  srcFilter->coeff[k] * filter[i * filterSize + j];
450  }
451  } else {
452  for (j = 0; j < filterSize; j++)
453  filter2[i * filter2Size + j] = filter[i * filterSize + j];
454  }
455  // FIXME dstFilter
456 
457  (*filterPos)[i] += (filterSize - 1) / 2 - (filter2Size - 1) / 2;
458  }
459  av_freep(&filter);
460 
461  /* try to reduce the filter-size (step1 find size and shift left) */
462  // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not).
463  minFilterSize = 0;
464  for (i = dstW - 1; i >= 0; i--) {
465  int min = filter2Size;
466  int j;
467  int64_t cutOff = 0.0;
468 
469  /* get rid of near zero elements on the left by shifting left */
470  for (j = 0; j < filter2Size; j++) {
471  int k;
472  cutOff += FFABS(filter2[i * filter2Size]);
473 
474  if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
475  break;
476 
477  /* preserve monotonicity because the core can't handle the
478  * filter otherwise */
479  if (i < dstW - 1 && (*filterPos)[i] >= (*filterPos)[i + 1])
480  break;
481 
482  // move filter coefficients left
483  for (k = 1; k < filter2Size; k++)
484  filter2[i * filter2Size + k - 1] = filter2[i * filter2Size + k];
485  filter2[i * filter2Size + k - 1] = 0;
486  (*filterPos)[i]++;
487  }
488 
489  cutOff = 0;
490  /* count near zeros on the right */
491  for (j = filter2Size - 1; j > 0; j--) {
492  cutOff += FFABS(filter2[i * filter2Size + j]);
493 
494  if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)
495  break;
496  min--;
497  }
498 
499  if (min > minFilterSize)
500  minFilterSize = min;
501  }
502 
503  if (PPC_ALTIVEC(cpu_flags)) {
504  // we can handle the special case 4, so we don't want to go the full 8
505  if (minFilterSize < 5)
506  filterAlign = 4;
507 
508  /* We really don't want to waste our time doing useless computation, so
509  * fall back on the scalar C code for very small filters.
510  * Vectorizing is worth it only if you have a decent-sized vector. */
511  if (minFilterSize < 3)
512  filterAlign = 1;
513  }
514 
515  if (INLINE_MMX(cpu_flags)) {
516  // special case for unscaled vertical filtering
517  if (minFilterSize == 1 && filterAlign == 2)
518  filterAlign = 1;
519  }
520 
521  assert(minFilterSize > 0);
522  filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));
523  assert(filterSize > 0);
524  filter = av_malloc(filterSize * dstW * sizeof(*filter));
525  if (filterSize >= MAX_FILTER_SIZE * 16 /
526  ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter)
527  goto fail;
528  *outFilterSize = filterSize;
529 
530  if (flags & SWS_PRINT_INFO)
532  "SwScaler: reducing / aligning filtersize %d -> %d\n",
533  filter2Size, filterSize);
534  /* try to reduce the filter-size (step2 reduce it) */
535  for (i = 0; i < dstW; i++) {
536  int j;
537 
538  for (j = 0; j < filterSize; j++) {
539  if (j >= filter2Size)
540  filter[i * filterSize + j] = 0;
541  else
542  filter[i * filterSize + j] = filter2[i * filter2Size + j];
543  if ((flags & SWS_BITEXACT) && j >= minFilterSize)
544  filter[i * filterSize + j] = 0;
545  }
546  }
547 
548  // FIXME try to align filterPos if possible
549 
550  // fix borders
551  if (is_horizontal) {
552  for (i = 0; i < dstW; i++) {
553  int j;
554  if ((*filterPos)[i] < 0) {
555  // move filter coefficients left to compensate for filterPos
556  for (j = 1; j < filterSize; j++) {
557  int left = FFMAX(j + (*filterPos)[i], 0);
558  filter[i * filterSize + left] += filter[i * filterSize + j];
559  filter[i * filterSize + j] = 0;
560  }
561  (*filterPos)[i] = 0;
562  }
563 
564  if ((*filterPos)[i] + filterSize > srcW) {
565  int shift = (*filterPos)[i] + filterSize - srcW;
566  // move filter coefficients right to compensate for filterPos
567  for (j = filterSize - 2; j >= 0; j--) {
568  int right = FFMIN(j + shift, filterSize - 1);
569  filter[i * filterSize + right] += filter[i * filterSize + j];
570  filter[i * filterSize + j] = 0;
571  }
572  (*filterPos)[i] = srcW - filterSize;
573  }
574  }
575  }
576 
577  // Note the +1 is for the MMX scaler which reads over the end
578  /* align at 16 for AltiVec (needed by hScale_altivec_real) */
579  FF_ALLOCZ_OR_GOTO(NULL, *outFilter,
580  *outFilterSize * (dstW + 3) * sizeof(int16_t), fail);
581 
582  /* normalize & store in outFilter */
583  for (i = 0; i < dstW; i++) {
584  int j;
585  int64_t error = 0;
586  int64_t sum = 0;
587 
588  for (j = 0; j < filterSize; j++) {
589  sum += filter[i * filterSize + j];
590  }
591  sum = (sum + one / 2) / one;
592  for (j = 0; j < *outFilterSize; j++) {
593  int64_t v = filter[i * filterSize + j] + error;
594  int intV = ROUNDED_DIV(v, sum);
595  (*outFilter)[i * (*outFilterSize) + j] = intV;
596  error = v - intV * sum;
597  }
598  }
599 
600  (*filterPos)[dstW + 0] =
601  (*filterPos)[dstW + 1] =
602  (*filterPos)[dstW + 2] = (*filterPos)[dstW - 1]; /* the MMX/SSE scaler will
603  * read over the end */
604  for (i = 0; i < *outFilterSize; i++) {
605  int k = (dstW - 1) * (*outFilterSize) + i;
606  (*outFilter)[k + 1 * (*outFilterSize)] =
607  (*outFilter)[k + 2 * (*outFilterSize)] =
608  (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];
609  }
610 
611  ret = 0;
612 
613 fail:
614  av_free(filter);
615  av_free(filter2);
616  return ret;
617 }
618 
619 #if HAVE_MMXEXT_INLINE
620 static av_cold int init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode,
621  int16_t *filter, int32_t *filterPos,
622  int numSplits)
623 {
624  uint8_t *fragmentA;
625  x86_reg imm8OfPShufW1A;
626  x86_reg imm8OfPShufW2A;
627  x86_reg fragmentLengthA;
628  uint8_t *fragmentB;
629  x86_reg imm8OfPShufW1B;
630  x86_reg imm8OfPShufW2B;
631  x86_reg fragmentLengthB;
632  int fragmentPos;
633 
634  int xpos, i;
635 
636  // create an optimized horizontal scaling routine
637  /* This scaler is made of runtime-generated MMXEXT code using specially tuned
638  * pshufw instructions. For every four output pixels, if four input pixels
639  * are enough for the fast bilinear scaling, then a chunk of fragmentB is
640  * used. If five input pixels are needed, then a chunk of fragmentA is used.
641  */
642 
643  // code fragment
644 
645  __asm__ volatile (
646  "jmp 9f \n\t"
647  // Begin
648  "0: \n\t"
649  "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t"
650  "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t"
651  "movd 1(%%"REG_c", %%"REG_S"), %%mm1 \n\t"
652  "punpcklbw %%mm7, %%mm1 \n\t"
653  "punpcklbw %%mm7, %%mm0 \n\t"
654  "pshufw $0xFF, %%mm1, %%mm1 \n\t"
655  "1: \n\t"
656  "pshufw $0xFF, %%mm0, %%mm0 \n\t"
657  "2: \n\t"
658  "psubw %%mm1, %%mm0 \n\t"
659  "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t"
660  "pmullw %%mm3, %%mm0 \n\t"
661  "psllw $7, %%mm1 \n\t"
662  "paddw %%mm1, %%mm0 \n\t"
663 
664  "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t"
665 
666  "add $8, %%"REG_a" \n\t"
667  // End
668  "9: \n\t"
669  // "int $3 \n\t"
670  "lea " LOCAL_MANGLE(0b) ", %0 \n\t"
671  "lea " LOCAL_MANGLE(1b) ", %1 \n\t"
672  "lea " LOCAL_MANGLE(2b) ", %2 \n\t"
673  "dec %1 \n\t"
674  "dec %2 \n\t"
675  "sub %0, %1 \n\t"
676  "sub %0, %2 \n\t"
677  "lea " LOCAL_MANGLE(9b) ", %3 \n\t"
678  "sub %0, %3 \n\t"
679 
680 
681  : "=r" (fragmentA), "=r" (imm8OfPShufW1A), "=r" (imm8OfPShufW2A),
682  "=r" (fragmentLengthA)
683  );
684 
685  __asm__ volatile (
686  "jmp 9f \n\t"
687  // Begin
688  "0: \n\t"
689  "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t"
690  "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t"
691  "punpcklbw %%mm7, %%mm0 \n\t"
692  "pshufw $0xFF, %%mm0, %%mm1 \n\t"
693  "1: \n\t"
694  "pshufw $0xFF, %%mm0, %%mm0 \n\t"
695  "2: \n\t"
696  "psubw %%mm1, %%mm0 \n\t"
697  "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t"
698  "pmullw %%mm3, %%mm0 \n\t"
699  "psllw $7, %%mm1 \n\t"
700  "paddw %%mm1, %%mm0 \n\t"
701 
702  "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t"
703 
704  "add $8, %%"REG_a" \n\t"
705  // End
706  "9: \n\t"
707  // "int $3 \n\t"
708  "lea " LOCAL_MANGLE(0b) ", %0 \n\t"
709  "lea " LOCAL_MANGLE(1b) ", %1 \n\t"
710  "lea " LOCAL_MANGLE(2b) ", %2 \n\t"
711  "dec %1 \n\t"
712  "dec %2 \n\t"
713  "sub %0, %1 \n\t"
714  "sub %0, %2 \n\t"
715  "lea " LOCAL_MANGLE(9b) ", %3 \n\t"
716  "sub %0, %3 \n\t"
717 
718 
719  : "=r" (fragmentB), "=r" (imm8OfPShufW1B), "=r" (imm8OfPShufW2B),
720  "=r" (fragmentLengthB)
721  );
722 
723  xpos = 0; // lumXInc/2 - 0x8000; // difference between pixel centers
724  fragmentPos = 0;
725 
726  for (i = 0; i < dstW / numSplits; i++) {
727  int xx = xpos >> 16;
728 
729  if ((i & 3) == 0) {
730  int a = 0;
731  int b = ((xpos + xInc) >> 16) - xx;
732  int c = ((xpos + xInc * 2) >> 16) - xx;
733  int d = ((xpos + xInc * 3) >> 16) - xx;
734  int inc = (d + 1 < 4);
735  uint8_t *fragment = (d + 1 < 4) ? fragmentB : fragmentA;
736  x86_reg imm8OfPShufW1 = (d + 1 < 4) ? imm8OfPShufW1B : imm8OfPShufW1A;
737  x86_reg imm8OfPShufW2 = (d + 1 < 4) ? imm8OfPShufW2B : imm8OfPShufW2A;
738  x86_reg fragmentLength = (d + 1 < 4) ? fragmentLengthB : fragmentLengthA;
739  int maxShift = 3 - (d + inc);
740  int shift = 0;
741 
742  if (filterCode) {
743  filter[i] = ((xpos & 0xFFFF) ^ 0xFFFF) >> 9;
744  filter[i + 1] = (((xpos + xInc) & 0xFFFF) ^ 0xFFFF) >> 9;
745  filter[i + 2] = (((xpos + xInc * 2) & 0xFFFF) ^ 0xFFFF) >> 9;
746  filter[i + 3] = (((xpos + xInc * 3) & 0xFFFF) ^ 0xFFFF) >> 9;
747  filterPos[i / 2] = xx;
748 
749  memcpy(filterCode + fragmentPos, fragment, fragmentLength);
750 
751  filterCode[fragmentPos + imm8OfPShufW1] = (a + inc) |
752  ((b + inc) << 2) |
753  ((c + inc) << 4) |
754  ((d + inc) << 6);
755  filterCode[fragmentPos + imm8OfPShufW2] = a | (b << 2) |
756  (c << 4) |
757  (d << 6);
758 
759  if (i + 4 - inc >= dstW)
760  shift = maxShift; // avoid overread
761  else if ((filterPos[i / 2] & 3) <= maxShift)
762  shift = filterPos[i / 2] & 3; // align
763 
764  if (shift && i >= shift) {
765  filterCode[fragmentPos + imm8OfPShufW1] += 0x55 * shift;
766  filterCode[fragmentPos + imm8OfPShufW2] += 0x55 * shift;
767  filterPos[i / 2] -= shift;
768  }
769  }
770 
771  fragmentPos += fragmentLength;
772 
773  if (filterCode)
774  filterCode[fragmentPos] = RET;
775  }
776  xpos += xInc;
777  }
778  if (filterCode)
779  filterPos[((i / 2) + 1) & (~1)] = xpos >> 16; // needed to jump to the next part
780 
781  return fragmentPos + 1;
782 }
783 #endif /* HAVE_MMXEXT_INLINE */
784 
785 static void getSubSampleFactors(int *h, int *v, enum AVPixelFormat format)
786 {
787  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
788  *h = desc->log2_chroma_w;
789  *v = desc->log2_chroma_h;
790 }
791 
792 int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
793  int srcRange, const int table[4], int dstRange,
794  int brightness, int contrast, int saturation)
795 {
796  const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
797  const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
798  memcpy(c->srcColorspaceTable, inv_table, sizeof(int) * 4);
799  memcpy(c->dstColorspaceTable, table, sizeof(int) * 4);
800 
801  c->brightness = brightness;
802  c->contrast = contrast;
803  c->saturation = saturation;
804  c->srcRange = srcRange;
805  c->dstRange = dstRange;
806  if (isYUV(c->dstFormat) || isGray(c->dstFormat))
807  return -1;
808 
809  c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
810  c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
811 
812  ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
813  contrast, saturation);
814  // FIXME factorize
815 
816  if (ARCH_PPC)
817  ff_yuv2rgb_init_tables_ppc(c, inv_table, brightness,
818  contrast, saturation);
819  return 0;
820 }
821 
822 int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
823  int *srcRange, int **table, int *dstRange,
824  int *brightness, int *contrast, int *saturation)
825 {
826  if (isYUV(c->dstFormat) || isGray(c->dstFormat))
827  return -1;
828 
829  *inv_table = c->srcColorspaceTable;
830  *table = c->dstColorspaceTable;
831  *srcRange = c->srcRange;
832  *dstRange = c->dstRange;
833  *brightness = c->brightness;
834  *contrast = c->contrast;
835  *saturation = c->saturation;
836 
837  return 0;
838 }
839 
840 static int handle_jpeg(enum AVPixelFormat *format)
841 {
842  switch (*format) {
843  case AV_PIX_FMT_YUVJ420P:
844  *format = AV_PIX_FMT_YUV420P;
845  return 1;
846  case AV_PIX_FMT_YUVJ422P:
847  *format = AV_PIX_FMT_YUV422P;
848  return 1;
849  case AV_PIX_FMT_YUVJ444P:
850  *format = AV_PIX_FMT_YUV444P;
851  return 1;
852  case AV_PIX_FMT_YUVJ440P:
853  *format = AV_PIX_FMT_YUV440P;
854  return 1;
855  default:
856  return 0;
857  }
858 }
859 
861 {
862  SwsContext *c = av_mallocz(sizeof(SwsContext));
863 
864  if (c) {
867  }
868 
869  return c;
870 }
871 
873  SwsFilter *dstFilter)
874 {
875  int i;
876  int usesVFilter, usesHFilter;
877  int unscaled;
878  SwsFilter dummyFilter = { NULL, NULL, NULL, NULL };
879  int srcW = c->srcW;
880  int srcH = c->srcH;
881  int dstW = c->dstW;
882  int dstH = c->dstH;
883  int dst_stride = FFALIGN(dstW * sizeof(int16_t) + 16, 16);
884  int dst_stride_px = dst_stride >> 1;
885  int flags, cpu_flags;
886  enum AVPixelFormat srcFormat = c->srcFormat;
887  enum AVPixelFormat dstFormat = c->dstFormat;
888  const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(srcFormat);
889  const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(dstFormat);
890 
891  cpu_flags = av_get_cpu_flags();
892  flags = c->flags;
893  emms_c();
894  if (!rgb15to16)
896 
897  unscaled = (srcW == dstW && srcH == dstH);
898 
899  if (!(unscaled && sws_isSupportedEndiannessConversion(srcFormat) &&
900  av_pix_fmt_swap_endianness(srcFormat) == dstFormat)) {
901  if (!sws_isSupportedInput(srcFormat)) {
902  av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
903  sws_format_name(srcFormat));
904  return AVERROR(EINVAL);
905  }
906  if (!sws_isSupportedOutput(dstFormat)) {
907  av_log(c, AV_LOG_ERROR, "%s is not supported as output pixel format\n",
908  sws_format_name(dstFormat));
909  return AVERROR(EINVAL);
910  }
911  }
912 
913  i = flags & (SWS_POINT |
914  SWS_AREA |
915  SWS_BILINEAR |
917  SWS_BICUBIC |
918  SWS_X |
919  SWS_GAUSS |
920  SWS_LANCZOS |
921  SWS_SINC |
922  SWS_SPLINE |
923  SWS_BICUBLIN);
924 
925  /* provide a default scaler if not set by caller */
926  if (!i) {
927  if (dstW < srcW && dstH < srcH)
928  flags |= SWS_GAUSS;
929  else if (dstW > srcW && dstH > srcH)
930  flags |= SWS_SINC;
931  else
932  flags |= SWS_LANCZOS;
933  c->flags = flags;
934  } else if (i & (i - 1)) {
935  av_log(c, AV_LOG_ERROR,
936  "Exactly one scaler algorithm must be chosen\n");
937  return AVERROR(EINVAL);
938  }
939  /* sanity check */
940  if (srcW < 4 || srcH < 1 || dstW < 8 || dstH < 1) {
941  /* FIXME check if these are enough and try to lower them after
942  * fixing the relevant parts of the code */
943  av_log(c, AV_LOG_ERROR, "%dx%d -> %dx%d is invalid scaling dimension\n",
944  srcW, srcH, dstW, dstH);
945  return AVERROR(EINVAL);
946  }
947 
948  if (!dstFilter)
949  dstFilter = &dummyFilter;
950  if (!srcFilter)
951  srcFilter = &dummyFilter;
952 
953  c->lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW;
954  c->lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH;
955  c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
956  c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
957  c->vRounder = 4 * 0x0001000100010001ULL;
958 
959  usesVFilter = (srcFilter->lumV && srcFilter->lumV->length > 1) ||
960  (srcFilter->chrV && srcFilter->chrV->length > 1) ||
961  (dstFilter->lumV && dstFilter->lumV->length > 1) ||
962  (dstFilter->chrV && dstFilter->chrV->length > 1);
963  usesHFilter = (srcFilter->lumH && srcFilter->lumH->length > 1) ||
964  (srcFilter->chrH && srcFilter->chrH->length > 1) ||
965  (dstFilter->lumH && dstFilter->lumH->length > 1) ||
966  (dstFilter->chrH && dstFilter->chrH->length > 1);
967 
970 
971  if (isPlanarRGB(dstFormat)) {
972  if (!(flags & SWS_FULL_CHR_H_INT)) {
973  av_log(c, AV_LOG_DEBUG,
974  "%s output is not supported with half chroma resolution, switching to full\n",
975  av_get_pix_fmt_name(dstFormat));
976  flags |= SWS_FULL_CHR_H_INT;
977  c->flags = flags;
978  }
979  }
980 
981  /* reuse chroma for 2 pixels RGB/BGR unless user wants full
982  * chroma interpolation */
983  if (flags & SWS_FULL_CHR_H_INT &&
984  isAnyRGB(dstFormat) &&
985  !isPlanarRGB(dstFormat) &&
986  dstFormat != AV_PIX_FMT_RGBA &&
987  dstFormat != AV_PIX_FMT_ARGB &&
988  dstFormat != AV_PIX_FMT_BGRA &&
989  dstFormat != AV_PIX_FMT_ABGR &&
990  dstFormat != AV_PIX_FMT_RGB24 &&
991  dstFormat != AV_PIX_FMT_BGR24) {
992  av_log(c, AV_LOG_ERROR,
993  "full chroma interpolation for destination format '%s' not yet implemented\n",
994  sws_format_name(dstFormat));
995  flags &= ~SWS_FULL_CHR_H_INT;
996  c->flags = flags;
997  }
998  if (isAnyRGB(dstFormat) && !(flags & SWS_FULL_CHR_H_INT))
999  c->chrDstHSubSample = 1;
1000 
1001  // drop some chroma lines if the user wants it
1002  c->vChrDrop = (flags & SWS_SRC_V_CHR_DROP_MASK) >>
1004  c->chrSrcVSubSample += c->vChrDrop;
1005 
1006  /* drop every other pixel for chroma calculation unless user
1007  * wants full chroma */
1008  if (isAnyRGB(srcFormat) && !(flags & SWS_FULL_CHR_H_INP) &&
1009  srcFormat != AV_PIX_FMT_RGB8 && srcFormat != AV_PIX_FMT_BGR8 &&
1010  srcFormat != AV_PIX_FMT_RGB4 && srcFormat != AV_PIX_FMT_BGR4 &&
1011  srcFormat != AV_PIX_FMT_RGB4_BYTE && srcFormat != AV_PIX_FMT_BGR4_BYTE &&
1012  srcFormat != AV_PIX_FMT_GBRP9BE && srcFormat != AV_PIX_FMT_GBRP9LE &&
1013  srcFormat != AV_PIX_FMT_GBRP10BE && srcFormat != AV_PIX_FMT_GBRP10LE &&
1014  srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE &&
1015  ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
1016  (flags & SWS_FAST_BILINEAR)))
1017  c->chrSrcHSubSample = 1;
1018 
1019  // Note the -((-x)>>y) is so that we always round toward +inf.
1020  c->chrSrcW = -((-srcW) >> c->chrSrcHSubSample);
1021  c->chrSrcH = -((-srcH) >> c->chrSrcVSubSample);
1022  c->chrDstW = -((-dstW) >> c->chrDstHSubSample);
1023  c->chrDstH = -((-dstH) >> c->chrDstVSubSample);
1024 
1025  /* unscaled special cases */
1026  if (unscaled && !usesHFilter && !usesVFilter &&
1027  (c->srcRange == c->dstRange || isAnyRGB(dstFormat))) {
1029 
1030  if (c->swscale) {
1031  if (flags & SWS_PRINT_INFO)
1032  av_log(c, AV_LOG_INFO,
1033  "using unscaled %s -> %s special converter\n",
1034  sws_format_name(srcFormat), sws_format_name(dstFormat));
1035  return 0;
1036  }
1037  }
1038 
1039  c->srcBpc = 1 + desc_src->comp[0].depth_minus1;
1040  if (c->srcBpc < 8)
1041  c->srcBpc = 8;
1042  c->dstBpc = 1 + desc_dst->comp[0].depth_minus1;
1043  if (c->dstBpc < 8)
1044  c->dstBpc = 8;
1045  if (c->dstBpc == 16)
1046  dst_stride <<= 1;
1048  (FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3) + 16,
1049  fail);
1050  if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 10) {
1051  c->canMMXEXTBeUsed = (dstW >= srcW && (dstW & 31) == 0 &&
1052  (srcW & 15) == 0) ? 1 : 0;
1053  if (!c->canMMXEXTBeUsed && dstW >= srcW && (srcW & 15) == 0
1054  && (flags & SWS_FAST_BILINEAR)) {
1055  if (flags & SWS_PRINT_INFO)
1056  av_log(c, AV_LOG_INFO,
1057  "output width is not a multiple of 32 -> no MMXEXT scaler\n");
1058  }
1059  if (usesHFilter)
1060  c->canMMXEXTBeUsed = 0;
1061  } else
1062  c->canMMXEXTBeUsed = 0;
1063 
1064  c->chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW;
1065  c->chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH;
1066 
1067  /* Match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src
1068  * to pixel n-2 of dst, but only for the FAST_BILINEAR mode otherwise do
1069  * correct scaling.
1070  * n-2 is the last chrominance sample available.
1071  * This is not perfect, but no one should notice the difference, the more
1072  * correct variant would be like the vertical one, but that would require
1073  * some special code for the first and last pixel */
1074  if (flags & SWS_FAST_BILINEAR) {
1075  if (c->canMMXEXTBeUsed) {
1076  c->lumXInc += 20;
1077  c->chrXInc += 20;
1078  }
1079  // we don't use the x86 asm scaler if MMX is available
1080  else if (INLINE_MMX(cpu_flags)) {
1081  c->lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20;
1082  c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20;
1083  }
1084  }
1085 
1086 #define USE_MMAP (HAVE_MMAP && HAVE_MPROTECT && defined MAP_ANONYMOUS)
1087 
1088  /* precalculate horizontal scaler filter coefficients */
1089  {
1090 #if HAVE_MMXEXT_INLINE
1091 // can't downscale !!!
1092  if (c->canMMXEXTBeUsed && (flags & SWS_FAST_BILINEAR)) {
1093  c->lumMmxextFilterCodeSize = init_hscaler_mmxext(dstW, c->lumXInc, NULL,
1094  NULL, NULL, 8);
1095  c->chrMmxextFilterCodeSize = init_hscaler_mmxext(c->chrDstW, c->chrXInc,
1096  NULL, NULL, NULL, 4);
1097 
1098 #if USE_MMAP
1099  c->lumMmxextFilterCode = mmap(NULL, c->lumMmxextFilterCodeSize,
1100  PROT_READ | PROT_WRITE,
1101  MAP_PRIVATE | MAP_ANONYMOUS,
1102  -1, 0);
1103  c->chrMmxextFilterCode = mmap(NULL, c->chrMmxextFilterCodeSize,
1104  PROT_READ | PROT_WRITE,
1105  MAP_PRIVATE | MAP_ANONYMOUS,
1106  -1, 0);
1107 #elif HAVE_VIRTUALALLOC
1108  c->lumMmxextFilterCode = VirtualAlloc(NULL,
1110  MEM_COMMIT,
1111  PAGE_EXECUTE_READWRITE);
1112  c->chrMmxextFilterCode = VirtualAlloc(NULL,
1114  MEM_COMMIT,
1115  PAGE_EXECUTE_READWRITE);
1116 #else
1119 #endif
1120 
1122  return AVERROR(ENOMEM);
1123  FF_ALLOCZ_OR_GOTO(c, c->hLumFilter, (dstW / 8 + 8) * sizeof(int16_t), fail);
1124  FF_ALLOCZ_OR_GOTO(c, c->hChrFilter, (c->chrDstW / 4 + 8) * sizeof(int16_t), fail);
1125  FF_ALLOCZ_OR_GOTO(c, c->hLumFilterPos, (dstW / 2 / 8 + 8) * sizeof(int32_t), fail);
1126  FF_ALLOCZ_OR_GOTO(c, c->hChrFilterPos, (c->chrDstW / 2 / 4 + 8) * sizeof(int32_t), fail);
1127 
1128  init_hscaler_mmxext(dstW, c->lumXInc, c->lumMmxextFilterCode,
1129  c->hLumFilter, c->hLumFilterPos, 8);
1130  init_hscaler_mmxext(c->chrDstW, c->chrXInc, c->chrMmxextFilterCode,
1131  c->hChrFilter, c->hChrFilterPos, 4);
1132 
1133 #if USE_MMAP
1134  mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ);
1135  mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ);
1136 #endif
1137  } else
1138 #endif /* HAVE_MMXEXT_INLINE */
1139  {
1140  const int filterAlign = X86_MMX(cpu_flags) ? 4 :
1141  PPC_ALTIVEC(cpu_flags) ? 8 : 1;
1142 
1143  if (initFilter(&c->hLumFilter, &c->hLumFilterPos,
1144  &c->hLumFilterSize, c->lumXInc,
1145  srcW, dstW, filterAlign, 1 << 14,
1146  (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
1147  cpu_flags, srcFilter->lumH, dstFilter->lumH,
1148  c->param, 1) < 0)
1149  goto fail;
1150  if (initFilter(&c->hChrFilter, &c->hChrFilterPos,
1151  &c->hChrFilterSize, c->chrXInc,
1152  c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
1153  (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
1154  cpu_flags, srcFilter->chrH, dstFilter->chrH,
1155  c->param, 1) < 0)
1156  goto fail;
1157  }
1158  } // initialize horizontal stuff
1159 
1160  /* precalculate vertical scaler filter coefficients */
1161  {
1162  const int filterAlign = X86_MMX(cpu_flags) ? 2 :
1163  PPC_ALTIVEC(cpu_flags) ? 8 : 1;
1164 
1166  c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
1167  (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
1168  cpu_flags, srcFilter->lumV, dstFilter->lumV,
1169  c->param, 0) < 0)
1170  goto fail;
1172  c->chrYInc, c->chrSrcH, c->chrDstH,
1173  filterAlign, (1 << 12),
1174  (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
1175  cpu_flags, srcFilter->chrV, dstFilter->chrV,
1176  c->param, 0) < 0)
1177  goto fail;
1178 
1179 #if HAVE_ALTIVEC
1180  FF_ALLOC_OR_GOTO(c, c->vYCoeffsBank, sizeof(vector signed short) * c->vLumFilterSize * c->dstH, fail);
1181  FF_ALLOC_OR_GOTO(c, c->vCCoeffsBank, sizeof(vector signed short) * c->vChrFilterSize * c->chrDstH, fail);
1182 
1183  for (i = 0; i < c->vLumFilterSize * c->dstH; i++) {
1184  int j;
1185  short *p = (short *)&c->vYCoeffsBank[i];
1186  for (j = 0; j < 8; j++)
1187  p[j] = c->vLumFilter[i];
1188  }
1189 
1190  for (i = 0; i < c->vChrFilterSize * c->chrDstH; i++) {
1191  int j;
1192  short *p = (short *)&c->vCCoeffsBank[i];
1193  for (j = 0; j < 8; j++)
1194  p[j] = c->vChrFilter[i];
1195  }
1196 #endif
1197  }
1198 
1199  // calculate buffer sizes so that they won't run out while handling these damn slices
1200  c->vLumBufSize = c->vLumFilterSize;
1201  c->vChrBufSize = c->vChrFilterSize;
1202  for (i = 0; i < dstH; i++) {
1203  int chrI = (int64_t)i * c->chrDstH / dstH;
1204  int nextSlice = FFMAX(c->vLumFilterPos[i] + c->vLumFilterSize - 1,
1205  ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)
1206  << c->chrSrcVSubSample));
1207 
1208  nextSlice >>= c->chrSrcVSubSample;
1209  nextSlice <<= c->chrSrcVSubSample;
1210  if (c->vLumFilterPos[i] + c->vLumBufSize < nextSlice)
1211  c->vLumBufSize = nextSlice - c->vLumFilterPos[i];
1212  if (c->vChrFilterPos[chrI] + c->vChrBufSize <
1213  (nextSlice >> c->chrSrcVSubSample))
1214  c->vChrBufSize = (nextSlice >> c->chrSrcVSubSample) -
1215  c->vChrFilterPos[chrI];
1216  }
1217 
1218  /* Allocate pixbufs (we use dynamic allocation because otherwise we would
1219  * need to allocate several megabytes to handle all possible cases) */
1220  FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize * 3 * sizeof(int16_t *), fail);
1221  FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail);
1222  FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail);
1224  FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize * 3 * sizeof(int16_t *), fail);
1225  /* Note we need at least one pixel more at the end because of the MMX code
1226  * (just in case someone wants to replace the 4000/8000). */
1227  /* align at 16 bytes for AltiVec */
1228  for (i = 0; i < c->vLumBufSize; i++) {
1229  FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i + c->vLumBufSize],
1230  dst_stride + 16, fail);
1231  c->lumPixBuf[i] = c->lumPixBuf[i + c->vLumBufSize];
1232  }
1233  // 64 / (c->dstBpc & ~7) is the same as 16 / sizeof(scaling_intermediate)
1234  c->uv_off_px = dst_stride_px + 64 / (c->dstBpc & ~7);
1235  c->uv_off_byte = dst_stride + 16;
1236  for (i = 0; i < c->vChrBufSize; i++) {
1237  FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i + c->vChrBufSize],
1238  dst_stride * 2 + 32, fail);
1239  c->chrUPixBuf[i] = c->chrUPixBuf[i + c->vChrBufSize];
1240  c->chrVPixBuf[i] = c->chrVPixBuf[i + c->vChrBufSize]
1241  = c->chrUPixBuf[i] + (dst_stride >> 1) + 8;
1242  }
1243  if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
1244  for (i = 0; i < c->vLumBufSize; i++) {
1245  FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf[i + c->vLumBufSize],
1246  dst_stride + 16, fail);
1247  c->alpPixBuf[i] = c->alpPixBuf[i + c->vLumBufSize];
1248  }
1249 
1250  // try to avoid drawing green stuff between the right end and the stride end
1251  for (i = 0; i < c->vChrBufSize; i++)
1252  memset(c->chrUPixBuf[i], 64, dst_stride * 2 + 1);
1253 
1254  assert(c->chrDstH <= dstH);
1255 
1256  if (flags & SWS_PRINT_INFO) {
1257  if (flags & SWS_FAST_BILINEAR)
1258  av_log(c, AV_LOG_INFO, "FAST_BILINEAR scaler, ");
1259  else if (flags & SWS_BILINEAR)
1260  av_log(c, AV_LOG_INFO, "BILINEAR scaler, ");
1261  else if (flags & SWS_BICUBIC)
1262  av_log(c, AV_LOG_INFO, "BICUBIC scaler, ");
1263  else if (flags & SWS_X)
1264  av_log(c, AV_LOG_INFO, "Experimental scaler, ");
1265  else if (flags & SWS_POINT)
1266  av_log(c, AV_LOG_INFO, "Nearest Neighbor / POINT scaler, ");
1267  else if (flags & SWS_AREA)
1268  av_log(c, AV_LOG_INFO, "Area Averaging scaler, ");
1269  else if (flags & SWS_BICUBLIN)
1270  av_log(c, AV_LOG_INFO, "luma BICUBIC / chroma BILINEAR scaler, ");
1271  else if (flags & SWS_GAUSS)
1272  av_log(c, AV_LOG_INFO, "Gaussian scaler, ");
1273  else if (flags & SWS_SINC)
1274  av_log(c, AV_LOG_INFO, "Sinc scaler, ");
1275  else if (flags & SWS_LANCZOS)
1276  av_log(c, AV_LOG_INFO, "Lanczos scaler, ");
1277  else if (flags & SWS_SPLINE)
1278  av_log(c, AV_LOG_INFO, "Bicubic spline scaler, ");
1279  else
1280  av_log(c, AV_LOG_INFO, "ehh flags invalid?! ");
1281 
1282  av_log(c, AV_LOG_INFO, "from %s to %s%s ",
1283  sws_format_name(srcFormat),
1284 #ifdef DITHER1XBPP
1285  dstFormat == AV_PIX_FMT_BGR555 || dstFormat == AV_PIX_FMT_BGR565 ||
1286  dstFormat == AV_PIX_FMT_RGB444BE || dstFormat == AV_PIX_FMT_RGB444LE ||
1287  dstFormat == AV_PIX_FMT_BGR444BE || dstFormat == AV_PIX_FMT_BGR444LE ?
1288  "dithered " : "",
1289 #else
1290  "",
1291 #endif
1292  sws_format_name(dstFormat));
1293 
1294  if (INLINE_MMXEXT(cpu_flags))
1295  av_log(c, AV_LOG_INFO, "using MMXEXT\n");
1296  else if (INLINE_AMD3DNOW(cpu_flags))
1297  av_log(c, AV_LOG_INFO, "using 3DNOW\n");
1298  else if (INLINE_MMX(cpu_flags))
1299  av_log(c, AV_LOG_INFO, "using MMX\n");
1300  else if (PPC_ALTIVEC(cpu_flags))
1301  av_log(c, AV_LOG_INFO, "using AltiVec\n");
1302  else
1303  av_log(c, AV_LOG_INFO, "using C\n");
1304 
1305  av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
1306  av_log(c, AV_LOG_DEBUG,
1307  "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1308  c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);
1309  av_log(c, AV_LOG_DEBUG,
1310  "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
1311  c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH,
1312  c->chrXInc, c->chrYInc);
1313  }
1314 
1315  c->swscale = ff_getSwsFunc(c);
1316  return 0;
1317 fail: // FIXME replace things by appropriate error codes
1318  return -1;
1319 }
1320 
1321 SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
1322  int dstW, int dstH, enum AVPixelFormat dstFormat,
1323  int flags, SwsFilter *srcFilter,
1324  SwsFilter *dstFilter, const double *param)
1325 {
1326  SwsContext *c;
1327 
1328  if (!(c = sws_alloc_context()))
1329  return NULL;
1330 
1331  c->flags = flags;
1332  c->srcW = srcW;
1333  c->srcH = srcH;
1334  c->dstW = dstW;
1335  c->dstH = dstH;
1336  c->srcRange = handle_jpeg(&srcFormat);
1337  c->dstRange = handle_jpeg(&dstFormat);
1338  c->srcFormat = srcFormat;
1339  c->dstFormat = dstFormat;
1340 
1341  if (param) {
1342  c->param[0] = param[0];
1343  c->param[1] = param[1];
1344  }
1346  ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] /* FIXME*/,
1347  c->dstRange, 0, 1 << 16, 1 << 16);
1348 
1349  if (sws_init_context(c, srcFilter, dstFilter) < 0) {
1350  sws_freeContext(c);
1351  return NULL;
1352  }
1353 
1354  return c;
1355 }
1356 
1357 SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
1358  float lumaSharpen, float chromaSharpen,
1359  float chromaHShift, float chromaVShift,
1360  int verbose)
1361 {
1362  SwsFilter *filter = av_malloc(sizeof(SwsFilter));
1363  if (!filter)
1364  return NULL;
1365 
1366  if (lumaGBlur != 0.0) {
1367  filter->lumH = sws_getGaussianVec(lumaGBlur, 3.0);
1368  filter->lumV = sws_getGaussianVec(lumaGBlur, 3.0);
1369  } else {
1370  filter->lumH = sws_getIdentityVec();
1371  filter->lumV = sws_getIdentityVec();
1372  }
1373 
1374  if (chromaGBlur != 0.0) {
1375  filter->chrH = sws_getGaussianVec(chromaGBlur, 3.0);
1376  filter->chrV = sws_getGaussianVec(chromaGBlur, 3.0);
1377  } else {
1378  filter->chrH = sws_getIdentityVec();
1379  filter->chrV = sws_getIdentityVec();
1380  }
1381 
1382  if (chromaSharpen != 0.0) {
1383  SwsVector *id = sws_getIdentityVec();
1384  sws_scaleVec(filter->chrH, -chromaSharpen);
1385  sws_scaleVec(filter->chrV, -chromaSharpen);
1386  sws_addVec(filter->chrH, id);
1387  sws_addVec(filter->chrV, id);
1388  sws_freeVec(id);
1389  }
1390 
1391  if (lumaSharpen != 0.0) {
1392  SwsVector *id = sws_getIdentityVec();
1393  sws_scaleVec(filter->lumH, -lumaSharpen);
1394  sws_scaleVec(filter->lumV, -lumaSharpen);
1395  sws_addVec(filter->lumH, id);
1396  sws_addVec(filter->lumV, id);
1397  sws_freeVec(id);
1398  }
1399 
1400  if (chromaHShift != 0.0)
1401  sws_shiftVec(filter->chrH, (int)(chromaHShift + 0.5));
1402 
1403  if (chromaVShift != 0.0)
1404  sws_shiftVec(filter->chrV, (int)(chromaVShift + 0.5));
1405 
1406  sws_normalizeVec(filter->chrH, 1.0);
1407  sws_normalizeVec(filter->chrV, 1.0);
1408  sws_normalizeVec(filter->lumH, 1.0);
1409  sws_normalizeVec(filter->lumV, 1.0);
1410 
1411  if (verbose)
1412  sws_printVec2(filter->chrH, NULL, AV_LOG_DEBUG);
1413  if (verbose)
1414  sws_printVec2(filter->lumH, NULL, AV_LOG_DEBUG);
1415 
1416  return filter;
1417 }
1418 
1420 {
1421  SwsVector *vec = av_malloc(sizeof(SwsVector));
1422  if (!vec)
1423  return NULL;
1424  vec->length = length;
1425  vec->coeff = av_malloc(sizeof(double) * length);
1426  if (!vec->coeff)
1427  av_freep(&vec);
1428  return vec;
1429 }
1430 
1431 SwsVector *sws_getGaussianVec(double variance, double quality)
1432 {
1433  const int length = (int)(variance * quality + 0.5) | 1;
1434  int i;
1435  double middle = (length - 1) * 0.5;
1436  SwsVector *vec = sws_allocVec(length);
1437 
1438  if (!vec)
1439  return NULL;
1440 
1441  for (i = 0; i < length; i++) {
1442  double dist = i - middle;
1443  vec->coeff[i] = exp(-dist * dist / (2 * variance * variance)) /
1444  sqrt(2 * variance * M_PI);
1445  }
1446 
1447  sws_normalizeVec(vec, 1.0);
1448 
1449  return vec;
1450 }
1451 
1452 SwsVector *sws_getConstVec(double c, int length)
1453 {
1454  int i;
1455  SwsVector *vec = sws_allocVec(length);
1456 
1457  if (!vec)
1458  return NULL;
1459 
1460  for (i = 0; i < length; i++)
1461  vec->coeff[i] = c;
1462 
1463  return vec;
1464 }
1465 
1467 {
1468  return sws_getConstVec(1.0, 1);
1469 }
1470 
1471 static double sws_dcVec(SwsVector *a)
1472 {
1473  int i;
1474  double sum = 0;
1475 
1476  for (i = 0; i < a->length; i++)
1477  sum += a->coeff[i];
1478 
1479  return sum;
1480 }
1481 
1482 void sws_scaleVec(SwsVector *a, double scalar)
1483 {
1484  int i;
1485 
1486  for (i = 0; i < a->length; i++)
1487  a->coeff[i] *= scalar;
1488 }
1489 
1491 {
1492  sws_scaleVec(a, height / sws_dcVec(a));
1493 }
1494 
1496 {
1497  int length = a->length + b->length - 1;
1498  int i, j;
1499  SwsVector *vec = sws_getConstVec(0.0, length);
1500 
1501  if (!vec)
1502  return NULL;
1503 
1504  for (i = 0; i < a->length; i++) {
1505  for (j = 0; j < b->length; j++) {
1506  vec->coeff[i + j] += a->coeff[i] * b->coeff[j];
1507  }
1508  }
1509 
1510  return vec;
1511 }
1512 
1514 {
1515  int length = FFMAX(a->length, b->length);
1516  int i;
1517  SwsVector *vec = sws_getConstVec(0.0, length);
1518 
1519  if (!vec)
1520  return NULL;
1521 
1522  for (i = 0; i < a->length; i++)
1523  vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
1524  for (i = 0; i < b->length; i++)
1525  vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] += b->coeff[i];
1526 
1527  return vec;
1528 }
1529 
1531 {
1532  int length = FFMAX(a->length, b->length);
1533  int i;
1534  SwsVector *vec = sws_getConstVec(0.0, length);
1535 
1536  if (!vec)
1537  return NULL;
1538 
1539  for (i = 0; i < a->length; i++)
1540  vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
1541  for (i = 0; i < b->length; i++)
1542  vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] -= b->coeff[i];
1543 
1544  return vec;
1545 }
1546 
1547 /* shift left / or right if "shift" is negative */
1549 {
1550  int length = a->length + FFABS(shift) * 2;
1551  int i;
1552  SwsVector *vec = sws_getConstVec(0.0, length);
1553 
1554  if (!vec)
1555  return NULL;
1556 
1557  for (i = 0; i < a->length; i++) {
1558  vec->coeff[i + (length - 1) / 2 -
1559  (a->length - 1) / 2 - shift] = a->coeff[i];
1560  }
1561 
1562  return vec;
1563 }
1564 
1565 void sws_shiftVec(SwsVector *a, int shift)
1566 {
1567  SwsVector *shifted = sws_getShiftedVec(a, shift);
1568  av_free(a->coeff);
1569  a->coeff = shifted->coeff;
1570  a->length = shifted->length;
1571  av_free(shifted);
1572 }
1573 
1575 {
1576  SwsVector *sum = sws_sumVec(a, b);
1577  av_free(a->coeff);
1578  a->coeff = sum->coeff;
1579  a->length = sum->length;
1580  av_free(sum);
1581 }
1582 
1584 {
1585  SwsVector *diff = sws_diffVec(a, b);
1586  av_free(a->coeff);
1587  a->coeff = diff->coeff;
1588  a->length = diff->length;
1589  av_free(diff);
1590 }
1591 
1593 {
1594  SwsVector *conv = sws_getConvVec(a, b);
1595  av_free(a->coeff);
1596  a->coeff = conv->coeff;
1597  a->length = conv->length;
1598  av_free(conv);
1599 }
1600 
1602 {
1603  int i;
1604  SwsVector *vec = sws_allocVec(a->length);
1605 
1606  if (!vec)
1607  return NULL;
1608 
1609  for (i = 0; i < a->length; i++)
1610  vec->coeff[i] = a->coeff[i];
1611 
1612  return vec;
1613 }
1614 
1615 void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
1616 {
1617  int i;
1618  double max = 0;
1619  double min = 0;
1620  double range;
1621 
1622  for (i = 0; i < a->length; i++)
1623  if (a->coeff[i] > max)
1624  max = a->coeff[i];
1625 
1626  for (i = 0; i < a->length; i++)
1627  if (a->coeff[i] < min)
1628  min = a->coeff[i];
1629 
1630  range = max - min;
1631 
1632  for (i = 0; i < a->length; i++) {
1633  int x = (int)((a->coeff[i] - min) * 60.0 / range + 0.5);
1634  av_log(log_ctx, log_level, "%1.3f ", a->coeff[i]);
1635  for (; x > 0; x--)
1636  av_log(log_ctx, log_level, " ");
1637  av_log(log_ctx, log_level, "|\n");
1638  }
1639 }
1640 
1642 {
1643  if (!a)
1644  return;
1645  av_freep(&a->coeff);
1646  a->length = 0;
1647  av_free(a);
1648 }
1649 
1651 {
1652  if (!filter)
1653  return;
1654 
1655  if (filter->lumH)
1656  sws_freeVec(filter->lumH);
1657  if (filter->lumV)
1658  sws_freeVec(filter->lumV);
1659  if (filter->chrH)
1660  sws_freeVec(filter->chrH);
1661  if (filter->chrV)
1662  sws_freeVec(filter->chrV);
1663  av_free(filter);
1664 }
1665 
1667 {
1668  int i;
1669  if (!c)
1670  return;
1671 
1672  if (c->lumPixBuf) {
1673  for (i = 0; i < c->vLumBufSize; i++)
1674  av_freep(&c->lumPixBuf[i]);
1675  av_freep(&c->lumPixBuf);
1676  }
1677 
1678  if (c->chrUPixBuf) {
1679  for (i = 0; i < c->vChrBufSize; i++)
1680  av_freep(&c->chrUPixBuf[i]);
1681  av_freep(&c->chrUPixBuf);
1682  av_freep(&c->chrVPixBuf);
1683  }
1684 
1685  if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
1686  for (i = 0; i < c->vLumBufSize; i++)
1687  av_freep(&c->alpPixBuf[i]);
1688  av_freep(&c->alpPixBuf);
1689  }
1690 
1691  av_freep(&c->vLumFilter);
1692  av_freep(&c->vChrFilter);
1693  av_freep(&c->hLumFilter);
1694  av_freep(&c->hChrFilter);
1695 #if HAVE_ALTIVEC
1696  av_freep(&c->vYCoeffsBank);
1697  av_freep(&c->vCCoeffsBank);
1698 #endif
1699 
1700  av_freep(&c->vLumFilterPos);
1701  av_freep(&c->vChrFilterPos);
1702  av_freep(&c->hLumFilterPos);
1703  av_freep(&c->hChrFilterPos);
1704 
1705 #if HAVE_MMX_INLINE
1706 #if USE_MMAP
1707  if (c->lumMmxextFilterCode)
1709  if (c->chrMmxextFilterCode)
1711 #elif HAVE_VIRTUALALLOC
1712  if (c->lumMmxextFilterCode)
1713  VirtualFree(c->lumMmxextFilterCode, 0, MEM_RELEASE);
1714  if (c->chrMmxextFilterCode)
1715  VirtualFree(c->chrMmxextFilterCode, 0, MEM_RELEASE);
1716 #else
1719 #endif
1722 #endif /* HAVE_MMX_INLINE */
1723 
1724  av_freep(&c->yuvTable);
1726 
1727  av_free(c);
1728 }
1729 
1730 struct SwsContext *sws_getCachedContext(struct SwsContext *context, int srcW,
1731  int srcH, enum AVPixelFormat srcFormat,
1732  int dstW, int dstH,
1733  enum AVPixelFormat dstFormat, int flags,
1734  SwsFilter *srcFilter,
1735  SwsFilter *dstFilter,
1736  const double *param)
1737 {
1738  static const double default_param[2] = { SWS_PARAM_DEFAULT,
1740 
1741  if (!param)
1742  param = default_param;
1743 
1744  if (context &&
1745  (context->srcW != srcW ||
1746  context->srcH != srcH ||
1747  context->srcFormat != srcFormat ||
1748  context->dstW != dstW ||
1749  context->dstH != dstH ||
1750  context->dstFormat != dstFormat ||
1751  context->flags != flags ||
1752  context->param[0] != param[0] ||
1753  context->param[1] != param[1])) {
1754  sws_freeContext(context);
1755  context = NULL;
1756  }
1757 
1758  if (!context) {
1759  if (!(context = sws_alloc_context()))
1760  return NULL;
1761  context->srcW = srcW;
1762  context->srcH = srcH;
1763  context->srcRange = handle_jpeg(&srcFormat);
1764  context->srcFormat = srcFormat;
1765  context->dstW = dstW;
1766  context->dstH = dstH;
1767  context->dstRange = handle_jpeg(&dstFormat);
1768  context->dstFormat = dstFormat;
1769  context->flags = flags;
1770  context->param[0] = param[0];
1771  context->param[1] = param[1];
1773  context->srcRange,
1774  ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] /* FIXME*/,
1775  context->dstRange, 0, 1 << 16, 1 << 16);
1776  if (sws_init_context(context, srcFilter, dstFilter) < 0) {
1777  sws_freeContext(context);
1778  return NULL;
1779  }
1780  }
1781  return context;
1782 }
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:84
SwsVector * chrV
Definition: swscale.h:132
uint8_t is_supported_out
Definition: utils.c:75
int16_t ** alpPixBuf
Ring buffer for scaled horizontal alpha plane lines to be fed to the vertical scaler.
int sws_isSupportedOutput(enum AVPixelFormat pix_fmt)
Return a positive value if pix_fmt is a supported output format, 0 otherwise.
Definition: utils.c:193
static const FormatEntry format_entries[AV_PIX_FMT_NB]
Definition: utils.c:79
planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:160
ptrdiff_t uv_off_px
offset (in pixels) between u and v planes
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
static SwsVector * sws_sumVec(SwsVector *a, SwsVector *b)
Definition: utils.c:1513
av_cold void ff_yuv2rgb_init_tables_ppc(SwsContext *c, const int inv_table[4], int brightness, int contrast, int saturation)
#define SWS_SRC_V_CHR_DROP_MASK
Definition: swscale.h:69
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1599
int chrSrcH
Height of source chroma planes.
#define SWS_X
Definition: swscale.h:60
static av_always_inline int isPlanarRGB(enum AVPixelFormat pix_fmt)
#define SWS_BICUBIC
Definition: swscale.h:59
uint8_t * chrMmxextFilterCode
Runtime-generated MMXEXT horizontal fast bilinear scaler code for chroma planes.
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:153
8bit gray, 8bit alpha
Definition: pixfmt.h:144
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:200
const char * sws_format_name(enum AVPixelFormat format)
Definition: utils.c:205
uint8_t * lumMmxextFilterCode
Runtime-generated MMXEXT horizontal fast bilinear scaler code for luma/alpha planes.
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:70
SwsVector * lumV
Definition: swscale.h:130
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:67
packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in ...
Definition: pixfmt.h:87
int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation)
Definition: utils.c:822
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:156
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition: pixdesc.c:1571
SwsVector * sws_getGaussianVec(double variance, double quality)
Return a normalized Gaussian curve used to filter stuff quality = 3 is high quality, lower is lower quality.
Definition: utils.c:1431
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:546
int vChrDrop
Binary logarithm of extra vertical subsampling factor in source image chroma planes specified by user...
int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation)
Definition: yuv2rgb.c:660
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:163
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:199
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 ...
Definition: pixfmt.h:118
#define SWS_BICUBLIN
Definition: swscale.h:63
static double getSplineCoeff(double a, double b, double c, double d, double dist)
Definition: utils.c:214
int dstFormatBpp
Number of bits per pixel of the destination pixel format.
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:183
external API header
static int handle_jpeg(enum AVPixelFormat *format)
Definition: utils.c:840
int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
Definition: utils.c:199
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
Definition: pixfmt.h:121
#define SWS_SRC_V_CHR_DROP_SHIFT
Definition: swscale.h:70
const char * swscale_configuration(void)
Return the libswscale build-time configuration.
Definition: utils.c:60
#define LIBAV_CONFIGURATION
Definition: config.h:4
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:150
packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 ...
Definition: pixfmt.h:141
void sws_subVec(SwsVector *a, SwsVector *b)
Definition: utils.c:1583
#define CONFIG_SWSCALE_ALPHA
Definition: config.h:367
int srcRange
0 = MPG YUV range, 1 = JPG YUV range (source image).
#define SWS_PRINT_INFO
Definition: swscale.h:74
enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt)
Utility function to swap the endianness of a pixel format.
Definition: pixdesc.c:1653
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:129
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in ...
Definition: pixfmt.h:90
Macro definitions for various function/variable attributes.
#define FFALIGN(x, a)
Definition: common.h:62
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:116
int srcH
Height of source luma/alpha planes.
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:88
#define SWS_BILINEAR
Definition: swscale.h:58
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian ...
Definition: pixfmt.h:173
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
Definition: pixfmt.h:184
const int32_t ff_yuv2rgb_coeffs[8][4]
Definition: yuv2rgb.c:38
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:104
int chrDstVSubSample
Binary logarithm of vertical subsampling factor between luma/alpha and chroma planes in destination i...
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:97
uint8_t
#define av_cold
Definition: attributes.h:66
int length
number of coefficients in the vector
Definition: swscale.h:124
#define SWS_LANCZOS
Definition: swscale.h:66
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:76
AVOptions.
int x86_reg
Definition: asm.h:70
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:113
int vChrFilterSize
Vertical filter size for chroma pixels.
#define b
Definition: input.c:52
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:197
int16_t ** lumPixBuf
Ring buffer for scaled horizontal luma plane lines to be fed to the vertical scaler.
packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 ...
Definition: pixfmt.h:140
void sws_addVec(SwsVector *a, SwsVector *b)
Definition: utils.c:1574
#define emms_c()
Definition: internal.h:47
#define SWS_FULL_CHR_H_INT
Definition: swscale.h:78
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:115
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:97
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:185
#define SWS_FAST_BILINEAR
Definition: swscale.h:57
planar GBR 4:4:4 48bpp, big-endian
Definition: pixfmt.h:168
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range ...
Definition: pixfmt.h:103
static int flags
Definition: log.c:44
SwsContext * sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
Allocate and return an SwsContext.
Definition: utils.c:1321
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_...
Definition: pixfmt.h:78
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
Definition: pixfmt.h:188
av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:872
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:139
#define isAnyRGB(x)
external api for the swscale stuff
enum AVPixelFormat dstFormat
Destination pixel format.
#define B
Definition: huffyuv.h:49
#define isALPHA(x)
Definition: swscale-test.c:49
int chrSrcHSubSample
Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in source imag...
static av_always_inline int isYUV(enum AVPixelFormat pix_fmt)
static SwsVector * sws_getShiftedVec(SwsVector *a, int shift)
Definition: utils.c:1548
uint64_t vRounder
const char * name
Definition: pixdesc.h:70
#define ROUNDED_DIV(a, b)
Definition: common.h:51
int32_t * vChrFilterPos
Array of vertical filter starting positions for each dst[i] for chroma planes.
int dstH
Height of destination luma/alpha planes.
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:151
SwsFilter * sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, float lumaSharpen, float chromaSharpen, float chromaHShift, float chromaVShift, int verbose)
Definition: utils.c:1357
planar GBR 4:4:4 27bpp, big-endian
Definition: pixfmt.h:164
#define INLINE_MMX(flags)
Definition: cpu.h:63
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:159
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:170
uint16_t depth_minus1
Number of bits in the component minus 1.
Definition: pixdesc.h:57
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:186
16bit gray, 16bit alpha (big-endian)
Definition: pixfmt.h:206
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
int16_t ** chrVPixBuf
Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.
int32_t * hChrFilterPos
Array of horizontal filter starting positions for each dst[i] for chroma planes.
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:134
#define AVERROR(e)
Definition: error.h:43
int hLumFilterSize
Horizontal filter size for luma/alpha pixels.
SwsFunc ff_getSwsFunc(SwsContext *c)
Return function pointer to fastest main scaler path function depending on architecture and available ...
Definition: swscale.c:771
#define PPC_ALTIVEC(flags)
Definition: cpu.h:26
#define SWS_MAX_REDUCE_CUTOFF
Definition: swscale.h:101
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:98
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:144
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian
Definition: pixfmt.h:176
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:155
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:92
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:169
planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:132
void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
Print with av_log() a textual representation of the vector a if log_level <= av_log_level.
Definition: utils.c:1615
#define SWS_CS_DEFAULT
Definition: swscale.h:109
int vChrBufSize
Number of vertical chroma lines allocated in the ring buffer.
#define LIBAV_LICENSE
Definition: config.h:5
av_cold void sws_rgb2rgb_init(void)
Definition: rgb2rgb.c:132
#define X86_MMX(flags)
Definition: cpu.h:31
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
Definition: pixfmt.h:177
#define FFMAX(a, b)
Definition: common.h:55
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:95
void sws_scaleVec(SwsVector *a, double scalar)
Scale all the coefficients of a by the scalar value.
Definition: utils.c:1482
int chrDstW
Width of destination chroma planes.
SwsVector * lumH
Definition: swscale.h:129
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:149
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:96
void sws_normalizeVec(SwsVector *a, double height)
Scale all the coefficients of a so that their sum equals height.
Definition: utils.c:1490
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
Definition: pixfmt.h:178
struct SwsContext * sws_getCachedContext(struct SwsContext *context, int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
Check if context can be reused, otherwise reallocate a new one.
Definition: utils.c:1730
#define LICENSE_PREFIX
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:69
int32_t * hLumFilterPos
Array of horizontal filter starting positions for each dst[i] for luma/alpha planes.
void sws_freeFilter(SwsFilter *filter)
Definition: utils.c:1650
int hChrFilterSize
Horizontal filter size for chroma pixels.
static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
Definition: mpegaudioenc.c:307
SwsVector * sws_allocVec(int length)
Allocate and return an uninitialized vector with length coefficients.
Definition: utils.c:1419
ptrdiff_t uv_off_byte
offset (in bytes) between u and v planes
as above, but U and V bytes are swapped
Definition: pixfmt.h:93
int dstRange
0 = MPG YUV range, 1 = JPG YUV range (destination image).
#define APCK_SIZE
#define FFMIN(a, b)
Definition: common.h:57
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:91
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_...
Definition: pixfmt.h:77
#define SWS_GAUSS
Definition: swscale.h:64
SwsVector * chrH
Definition: swscale.h:131
uint8_t * formatConvBuffer
#define INLINE_AMD3DNOW(flags)
Definition: cpu.h:61
int vLumBufSize
Number of vertical luma/alpha lines allocated in the ring buffer.
int16_t ** chrUPixBuf
Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.
int32_t
SwsVector * sws_getIdentityVec(void)
Allocate and return a vector with just one coefficient, with value 1.0.
Definition: utils.c:1466
void sws_freeContext(SwsContext *c)
Free the swscaler context swsContext.
Definition: utils.c:1666
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
Definition: pixfmt.h:182
packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb
Definition: pixfmt.h:202
#define FFABS(a)
Definition: common.h:52
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian
Definition: pixfmt.h:174
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:68
packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big...
Definition: pixfmt.h:192
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:152
enum AVPixelFormat pix_fmt
Definition: movenc.c:843
unsigned swscale_version(void)
Definition: utils.c:55
int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation)
Definition: utils.c:792
int srcColorspaceTable[4]
int dstW
Width of destination luma/alpha planes.
planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:161
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:148
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
Definition: pixfmt.h:120
int32_t * vLumFilterPos
Array of vertical filter starting positions for each dst[i] for luma/alpha planes.
#define AV_PIX_FMT_BGR555
Definition: pixfmt.h:236
NULL
Definition: eval.c:55
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:86
double * coeff
pointer to the list of coefficients
Definition: swscale.h:123
#define AV_LOG_INFO
Standard information.
Definition: log.h:134
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:130
int dstColorspaceTable[4]
const AVClass * av_class
info on struct for av_log
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:171
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
void sws_freeVec(SwsVector *a)
Definition: utils.c:1641
planar GBR 4:4:4 30bpp, big-endian
Definition: pixfmt.h:166
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
Definition: pixfmt.h:186
int chrDstH
Height of destination chroma planes.
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:66
static void getSubSampleFactors(int *h, int *v, enum AVPixelFormat format)
Definition: utils.c:785
#define SWS_AREA
Definition: swscale.h:62
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:71
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:187
static SwsVector * sws_diffVec(SwsVector *a, SwsVector *b)
Definition: utils.c:1530
void sws_shiftVec(SwsVector *a, int shift)
Definition: utils.c:1565
int lumMmxextFilterCodeSize
Runtime-generated MMXEXT horizontal fast bilinear scaler code size for luma/alpha planes...
Describe the class of an AVClass context structure.
Definition: log.h:33
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:189
#define RET
Definition: utils.c:71
Y , 16bpp, big-endian.
Definition: pixfmt.h:100
int vLumFilterSize
Vertical filter size for luma/alpha pixels.
#define SWS_ACCURATE_RND
Definition: swscale.h:82
byte swapping routines
int chrMmxextFilterCodeSize
Runtime-generated MMXEXT horizontal fast bilinear scaler code size for chroma planes.
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian
Definition: pixfmt.h:172
packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 ...
Definition: pixfmt.h:123
int16_t * vChrFilter
Array of vertical filter coefficients for chroma planes.
#define isGray(x)
Definition: swscale-test.c:38
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:47
SwsVector * sws_cloneVec(SwsVector *a)
Allocate and return a clone of the vector a, that is a vector with the same coefficients as a...
Definition: utils.c:1601
#define SWS_POINT
Definition: swscale.h:61
int16_t * hLumFilter
Array of horizontal filter coefficients for luma/alpha planes.
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext.
Definition: utils.c:860
Definition: vf_drawbox.c:37
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:235
#define SWS_SPLINE
Definition: swscale.h:67
#define ARCH_PPC
Definition: config.h:24
#define SWS_SINC
Definition: swscale.h:65
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:181
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 ...
Definition: pixfmt.h:117
#define SWS_BITEXACT
Definition: swscale.h:83
packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1 ...
Definition: pixfmt.h:143
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:157
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:133
int height
Definition: gxfenc.c:72
uint8_t is_supported_in
Definition: utils.c:74
void sws_convVec(SwsVector *a, SwsVector *b)
Definition: utils.c:1592
const AVClass sws_context_class
Definition: options.c:69
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:75
#define INLINE_MMXEXT(flags)
Definition: cpu.h:64
static double sws_dcVec(SwsVector *a)
Definition: utils.c:1471
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:65
Y , 8bpp.
Definition: pixfmt.h:73
double param[2]
Input parameters for scaling algorithms that need them.
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:74
#define FF_ALLOC_OR_GOTO(ctx, p, size, label)
Definition: internal.h:117
planar GBR 4:4:4 27bpp, little-endian
Definition: pixfmt.h:165
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:112
enum AVPixelFormat srcFormat
Source pixel format.
planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:131
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_...
Definition: pixfmt.h:79
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:89
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:72
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:179
#define SWS_PARAM_DEFAULT
Definition: swscale.h:72
#define SWS_FULL_CHR_H_INP
Definition: swscale.h:80
SwsFunc swscale
Note that src, dst, srcStride, dstStride will be copied in the sws_scale() wrapper so they can be fre...
#define MAX_FILTER_SIZE
packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as lit...
Definition: pixfmt.h:191
int srcFormatBpp
Number of bits per pixel of the source pixel format.
Y , 16bpp, little-endian.
Definition: pixfmt.h:101
uint8_t is_supported_endianness
Definition: utils.c:76
16bit gray, 16bit alpha (little-endian)
Definition: pixfmt.h:207
int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
Return a positive value if pix_fmt is a supported input format, 0 otherwise.
Definition: utils.c:187
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
Definition: pixfmt.h:180
static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, int *outFilterSize, int xInc, int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags, SwsVector *srcFilter, SwsVector *dstFilter, double param[2], int is_horizontal)
Definition: utils.c:227
packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 ...
Definition: pixfmt.h:122
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:209
int16_t * vLumFilter
Array of vertical filter coefficients for luma/alpha planes.
SwsVector * sws_getConstVec(double c, int length)
Allocate and return a vector with length coefficients, all with the same value c. ...
Definition: utils.c:1452
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:102
planar GBR 4:4:4 48bpp, little-endian
Definition: pixfmt.h:169
int16_t * hChrFilter
Array of horizontal filter coefficients for chroma planes.
#define LOCAL_MANGLE(a)
Definition: asm.h:107
packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1 ...
Definition: pixfmt.h:142
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:1540
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian
Definition: pixfmt.h:175
int chrDstHSubSample
Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in destination...
int chrSrcW
Width of source chroma planes.
void ff_get_unscaled_swscale(SwsContext *c)
Set c->swscale to an unscaled converter if one exists for the specific source and destination formats...
int srcW
Width of source luma/alpha planes.
packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
Definition: pixfmt.h:85
float min
int chrSrcVSubSample
Binary logarithm of vertical subsampling factor between luma/alpha and chroma planes in source image...
int flags
Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
AVPixelFormat
Pixel format.
Definition: pixfmt.h:63
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
void(* rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:51
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:158
for(j=16;j >0;--j)
#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)
Definition: internal.h:126
planar GBR 4:4:4 30bpp, little-endian
Definition: pixfmt.h:167
static SwsVector * sws_getConvVec(SwsVector *a, SwsVector *b)
Definition: utils.c:1495
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:198
#define LIBSWSCALE_VERSION_INT
Definition: version.h:33
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:154
const char * swscale_license(void)
Return the libswscale license.
Definition: utils.c:65