Libav
swscale_unscaled.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 <inttypes.h>
22 #include <string.h>
23 #include <math.h>
24 #include <stdio.h>
25 #include "config.h"
26 #include <assert.h>
27 #include "swscale.h"
28 #include "swscale_internal.h"
29 #include "rgb2rgb.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/cpu.h"
32 #include "libavutil/avutil.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/bswap.h"
35 #include "libavutil/pixdesc.h"
36 
37 DECLARE_ALIGNED(8, static const uint8_t, dither_8x8_1)[8][8] = {
38  { 0, 1, 0, 1, 0, 1, 0, 1,},
39  { 1, 0, 1, 0, 1, 0, 1, 0,},
40  { 0, 1, 0, 1, 0, 1, 0, 1,},
41  { 1, 0, 1, 0, 1, 0, 1, 0,},
42  { 0, 1, 0, 1, 0, 1, 0, 1,},
43  { 1, 0, 1, 0, 1, 0, 1, 0,},
44  { 0, 1, 0, 1, 0, 1, 0, 1,},
45  { 1, 0, 1, 0, 1, 0, 1, 0,},
46 };
47 DECLARE_ALIGNED(8, static const uint8_t, dither_8x8_3)[8][8] = {
48  { 1, 2, 1, 2, 1, 2, 1, 2,},
49  { 3, 0, 3, 0, 3, 0, 3, 0,},
50  { 1, 2, 1, 2, 1, 2, 1, 2,},
51  { 3, 0, 3, 0, 3, 0, 3, 0,},
52  { 1, 2, 1, 2, 1, 2, 1, 2,},
53  { 3, 0, 3, 0, 3, 0, 3, 0,},
54  { 1, 2, 1, 2, 1, 2, 1, 2,},
55  { 3, 0, 3, 0, 3, 0, 3, 0,},
56 };
57 DECLARE_ALIGNED(8, static const uint8_t, dither_8x8_64)[8][8] = {
58  { 18, 34, 30, 46, 17, 33, 29, 45,},
59  { 50, 2, 62, 14, 49, 1, 61, 13,},
60  { 26, 42, 22, 38, 25, 41, 21, 37,},
61  { 58, 10, 54, 6, 57, 9, 53, 5,},
62  { 16, 32, 28, 44, 19, 35, 31, 47,},
63  { 48, 0, 60, 12, 51, 3, 63, 15,},
64  { 24, 40, 20, 36, 27, 43, 23, 39,},
65  { 56, 8, 52, 4, 59, 11, 55, 7,},
66 };
67 DECLARE_ALIGNED(8, static const uint8_t, dither_8x8_256)[8][8] = {
68  { 72, 136, 120, 184, 68, 132, 116, 180,},
69  { 200, 8, 248, 56, 196, 4, 244, 52,},
70  { 104, 168, 88, 152, 100, 164, 84, 148,},
71  { 232, 40, 216, 24, 228, 36, 212, 20,},
72  { 64, 128, 102, 176, 76, 140, 124, 188,},
73  { 192, 0, 240, 48, 204, 12, 252, 60,},
74  { 96, 160, 80, 144, 108, 172, 92, 156,},
75  { 224, 32, 208, 16, 236, 44, 220, 28,},
76 };
77 
78 #define RGB2YUV_SHIFT 15
79 #define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
80 #define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
81 #define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
82 #define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
83 #define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
84 #define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
85 #define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
86 #define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
87 #define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
88 
89 static void fillPlane(uint8_t *plane, int stride, int width, int height, int y,
90  uint8_t val)
91 {
92  int i;
93  uint8_t *ptr = plane + stride * y;
94  for (i = 0; i < height; i++) {
95  memset(ptr, val, width);
96  ptr += stride;
97  }
98 }
99 
100 static void fill_plane9or10(uint8_t *plane, int stride, int width,
101  int height, int y, uint8_t val,
102  const int dst_depth, const int big_endian)
103 {
104  int i, j;
105  uint16_t *dst = (uint16_t *) (plane + stride * y);
106 #define FILL8TO9_OR_10(wfunc) \
107  for (i = 0; i < height; i++) { \
108  for (j = 0; j < width; j++) { \
109  wfunc(&dst[j], (val << (dst_depth - 8)) | \
110  (val >> (16 - dst_depth))); \
111  } \
112  dst += stride / 2; \
113  }
114  if (big_endian) {
116  } else {
118  }
119 }
120 
121 static void copyPlane(const uint8_t *src, int srcStride,
122  int srcSliceY, int srcSliceH, int width,
123  uint8_t *dst, int dstStride)
124 {
125  dst += dstStride * srcSliceY;
126  if (dstStride == srcStride && srcStride > 0) {
127  memcpy(dst, src, srcSliceH * dstStride);
128  } else {
129  int i;
130  for (i = 0; i < srcSliceH; i++) {
131  memcpy(dst, src, width);
132  src += srcStride;
133  dst += dstStride;
134  }
135  }
136 }
137 
138 static int planarToNv12Wrapper(SwsContext *c, const uint8_t *src[],
139  int srcStride[], int srcSliceY,
140  int srcSliceH, uint8_t *dstParam[],
141  int dstStride[])
142 {
143  uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY / 2;
144 
145  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
146  dstParam[0], dstStride[0]);
147 
148  if (c->dstFormat == AV_PIX_FMT_NV12)
149  interleaveBytes(src[1], src[2], dst, c->srcW / 2, srcSliceH / 2,
150  srcStride[1], srcStride[2], dstStride[1]);
151  else
152  interleaveBytes(src[2], src[1], dst, c->srcW / 2, srcSliceH / 2,
153  srcStride[2], srcStride[1], dstStride[1]);
154 
155  return srcSliceH;
156 }
157 
158 static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[],
159  int srcStride[], int srcSliceY,
160  int srcSliceH, uint8_t *dstParam[],
161  int dstStride[])
162 {
163  uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
164  uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
165 
166  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
167  dstParam[0], dstStride[0]);
168 
169  if (c->srcFormat == AV_PIX_FMT_NV12)
170  deinterleaveBytes(src[1], dst1, dst2,c->srcW / 2, srcSliceH / 2,
171  srcStride[1], dstStride[1], dstStride[2]);
172  else
173  deinterleaveBytes(src[1], dst2, dst1, c->srcW / 2, srcSliceH / 2,
174  srcStride[1], dstStride[2], dstStride[1]);
175 
176  return srcSliceH;
177 }
178 
179 static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
180  int srcStride[], int srcSliceY, int srcSliceH,
181  uint8_t *dstParam[], int dstStride[])
182 {
183  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
184 
185  yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
186  srcStride[1], dstStride[0]);
187 
188  return srcSliceH;
189 }
190 
191 static int planarToUyvyWrapper(SwsContext *c, const uint8_t *src[],
192  int srcStride[], int srcSliceY, int srcSliceH,
193  uint8_t *dstParam[], int dstStride[])
194 {
195  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
196 
197  yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
198  srcStride[1], dstStride[0]);
199 
200  return srcSliceH;
201 }
202 
203 static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
204  int srcStride[], int srcSliceY, int srcSliceH,
205  uint8_t *dstParam[], int dstStride[])
206 {
207  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
208 
209  yuv422ptoyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
210  srcStride[1], dstStride[0]);
211 
212  return srcSliceH;
213 }
214 
215 static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t *src[],
216  int srcStride[], int srcSliceY, int srcSliceH,
217  uint8_t *dstParam[], int dstStride[])
218 {
219  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
220 
221  yuv422ptouyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
222  srcStride[1], dstStride[0]);
223 
224  return srcSliceH;
225 }
226 
227 static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
228  int srcStride[], int srcSliceY, int srcSliceH,
229  uint8_t *dstParam[], int dstStride[])
230 {
231  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
232  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
233  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
234 
235  yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
236  dstStride[1], srcStride[0]);
237 
238  if (dstParam[3])
239  fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
240 
241  return srcSliceH;
242 }
243 
244 static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
245  int srcStride[], int srcSliceY, int srcSliceH,
246  uint8_t *dstParam[], int dstStride[])
247 {
248  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
249  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
250  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
251 
252  yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
253  dstStride[1], srcStride[0]);
254 
255  return srcSliceH;
256 }
257 
258 static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
259  int srcStride[], int srcSliceY, int srcSliceH,
260  uint8_t *dstParam[], int dstStride[])
261 {
262  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
263  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
264  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
265 
266  uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
267  dstStride[1], srcStride[0]);
268 
269  if (dstParam[3])
270  fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
271 
272  return srcSliceH;
273 }
274 
275 static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
276  int srcStride[], int srcSliceY, int srcSliceH,
277  uint8_t *dstParam[], int dstStride[])
278 {
279  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
280  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
281  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
282 
283  uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
284  dstStride[1], srcStride[0]);
285 
286  return srcSliceH;
287 }
288 
289 static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels,
290  const uint8_t *palette)
291 {
292  int i;
293  for (i = 0; i < num_pixels; i++)
294  ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | (src[(i << 1) + 1] << 24);
295 }
296 
297 static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels,
298  const uint8_t *palette)
299 {
300  int i;
301 
302  for (i = 0; i < num_pixels; i++)
303  ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | src[(i << 1) + 1];
304 }
305 
306 static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels,
307  const uint8_t *palette)
308 {
309  int i;
310 
311  for (i = 0; i < num_pixels; i++) {
312  //FIXME slow?
313  dst[0] = palette[src[i << 1] * 4 + 0];
314  dst[1] = palette[src[i << 1] * 4 + 1];
315  dst[2] = palette[src[i << 1] * 4 + 2];
316  dst += 3;
317  }
318 }
319 
320 static int packed_16bpc_bswap(SwsContext *c, const uint8_t *src[],
321  int srcStride[], int srcSliceY, int srcSliceH,
322  uint8_t *dst[], int dstStride[])
323 {
324  int i, j;
325  int srcstr = srcStride[0] >> 1;
326  int dststr = dstStride[0] >> 1;
327  uint16_t *dstPtr = (uint16_t *) dst[0];
328  const uint16_t *srcPtr = (const uint16_t *) src[0];
329  int min_stride = FFMIN(srcstr, dststr);
330 
331  for (i = 0; i < srcSliceH; i++) {
332  for (j = 0; j < min_stride; j++) {
333  dstPtr[j] = av_bswap16(srcPtr[j]);
334  }
335  srcPtr += srcstr;
336  dstPtr += dststr;
337  }
338 
339  return srcSliceH;
340 }
341 
342 static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
343  int srcSliceY, int srcSliceH, uint8_t *dst[],
344  int dstStride[])
345 {
346  const enum AVPixelFormat srcFormat = c->srcFormat;
347  const enum AVPixelFormat dstFormat = c->dstFormat;
348  void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels,
349  const uint8_t *palette) = NULL;
350  int i;
351  uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
352  const uint8_t *srcPtr = src[0];
353 
354  if (srcFormat == AV_PIX_FMT_YA8) {
355  switch (dstFormat) {
356  case AV_PIX_FMT_RGB32 : conv = gray8aToPacked32; break;
357  case AV_PIX_FMT_BGR32 : conv = gray8aToPacked32; break;
358  case AV_PIX_FMT_BGR32_1: conv = gray8aToPacked32_1; break;
359  case AV_PIX_FMT_RGB32_1: conv = gray8aToPacked32_1; break;
360  case AV_PIX_FMT_RGB24 : conv = gray8aToPacked24; break;
361  case AV_PIX_FMT_BGR24 : conv = gray8aToPacked24; break;
362  }
363  } else if (usePal(srcFormat)) {
364  switch (dstFormat) {
365  case AV_PIX_FMT_RGB32 : conv = sws_convertPalette8ToPacked32; break;
366  case AV_PIX_FMT_BGR32 : conv = sws_convertPalette8ToPacked32; break;
369  case AV_PIX_FMT_RGB24 : conv = sws_convertPalette8ToPacked24; break;
370  case AV_PIX_FMT_BGR24 : conv = sws_convertPalette8ToPacked24; break;
371  }
372  }
373 
374  if (!conv)
375  av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
376  sws_format_name(srcFormat), sws_format_name(dstFormat));
377  else {
378  for (i = 0; i < srcSliceH; i++) {
379  conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
380  srcPtr += srcStride[0];
381  dstPtr += dstStride[0];
382  }
383  }
384 
385  return srcSliceH;
386 }
387 
388 static void gbr24ptopacked24(const uint8_t *src[], int srcStride[],
389  uint8_t *dst, int dstStride, int srcSliceH,
390  int width)
391 {
392  int x, h, i;
393  for (h = 0; h < srcSliceH; h++) {
394  uint8_t *dest = dst + dstStride * h;
395  for (x = 0; x < width; x++) {
396  *dest++ = src[0][x];
397  *dest++ = src[1][x];
398  *dest++ = src[2][x];
399  }
400 
401  for (i = 0; i < 3; i++)
402  src[i] += srcStride[i];
403  }
404 }
405 
406 static void gbr24ptopacked32(const uint8_t *src[], int srcStride[],
407  uint8_t *dst, int dstStride, int srcSliceH,
408  int alpha_first, int width)
409 {
410  int x, h, i;
411  for (h = 0; h < srcSliceH; h++) {
412  uint8_t *dest = dst + dstStride * h;
413 
414  if (alpha_first) {
415  for (x = 0; x < width; x++) {
416  *dest++ = 0xff;
417  *dest++ = src[0][x];
418  *dest++ = src[1][x];
419  *dest++ = src[2][x];
420  }
421  } else {
422  for (x = 0; x < width; x++) {
423  *dest++ = src[0][x];
424  *dest++ = src[1][x];
425  *dest++ = src[2][x];
426  *dest++ = 0xff;
427  }
428  }
429 
430  for (i = 0; i < 3; i++)
431  src[i] += srcStride[i];
432  }
433 }
434 
435 static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[],
436  int srcStride[], int srcSliceY, int srcSliceH,
437  uint8_t *dst[], int dstStride[])
438 {
439  int alpha_first = 0;
440  const uint8_t *src102[] = { src[1], src[0], src[2] };
441  const uint8_t *src201[] = { src[2], src[0], src[1] };
442  int stride102[] = { srcStride[1], srcStride[0], srcStride[2] };
443  int stride201[] = { srcStride[2], srcStride[0], srcStride[1] };
444 
445  if (c->srcFormat != AV_PIX_FMT_GBRP) {
446  av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
449  return srcSliceH;
450  }
451 
452  switch (c->dstFormat) {
453  case AV_PIX_FMT_BGR24:
454  gbr24ptopacked24(src102, stride102,
455  dst[0] + srcSliceY * dstStride[0], dstStride[0],
456  srcSliceH, c->srcW);
457  break;
458 
459  case AV_PIX_FMT_RGB24:
460  gbr24ptopacked24(src201, stride201,
461  dst[0] + srcSliceY * dstStride[0], dstStride[0],
462  srcSliceH, c->srcW);
463  break;
464 
465  case AV_PIX_FMT_ARGB:
466  alpha_first = 1;
467  case AV_PIX_FMT_RGBA:
468  gbr24ptopacked32(src201, stride201,
469  dst[0] + srcSliceY * dstStride[0], dstStride[0],
470  srcSliceH, alpha_first, c->srcW);
471  break;
472 
473  case AV_PIX_FMT_ABGR:
474  alpha_first = 1;
475  case AV_PIX_FMT_BGRA:
476  gbr24ptopacked32(src102, stride102,
477  dst[0] + srcSliceY * dstStride[0], dstStride[0],
478  srcSliceH, alpha_first, c->srcW);
479  break;
480 
481  default:
482  av_log(c, AV_LOG_ERROR,
483  "unsupported planar RGB conversion %s -> %s\n",
486  }
487 
488  return srcSliceH;
489 }
490 
491 static void packedtogbr24p(const uint8_t *src, int srcStride,
492  uint8_t *dst[], int dstStride[], int srcSliceH,
493  int alpha_first, int inc_size, int width)
494 {
495  uint8_t *dest[3];
496  int x, h;
497 
498  dest[0] = dst[0];
499  dest[1] = dst[1];
500  dest[2] = dst[2];
501 
502  if (alpha_first)
503  src++;
504 
505  for (h = 0; h < srcSliceH; h++) {
506  for (x = 0; x < width; x++) {
507  dest[0][x] = src[0];
508  dest[1][x] = src[1];
509  dest[2][x] = src[2];
510 
511  src += inc_size;
512  }
513  src += srcStride - width * inc_size;
514  dest[0] += dstStride[0];
515  dest[1] += dstStride[1];
516  dest[2] += dstStride[2];
517  }
518 }
519 
520 static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[],
521  int srcStride[], int srcSliceY, int srcSliceH,
522  uint8_t *dst[], int dstStride[])
523 {
524  int alpha_first = 0;
525  int stride102[] = { dstStride[1], dstStride[0], dstStride[2] };
526  int stride201[] = { dstStride[2], dstStride[0], dstStride[1] };
527  uint8_t *dst102[] = { dst[1] + srcSliceY * dstStride[1],
528  dst[0] + srcSliceY * dstStride[0],
529  dst[2] + srcSliceY * dstStride[2] };
530  uint8_t *dst201[] = { dst[2] + srcSliceY * dstStride[2],
531  dst[0] + srcSliceY * dstStride[0],
532  dst[1] + srcSliceY * dstStride[1] };
533 
534  switch (c->srcFormat) {
535  case AV_PIX_FMT_RGB24:
536  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
537  stride201, srcSliceH, alpha_first, 3, c->srcW);
538  break;
539  case AV_PIX_FMT_BGR24:
540  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
541  stride102, srcSliceH, alpha_first, 3, c->srcW);
542  break;
543  case AV_PIX_FMT_ARGB:
544  alpha_first = 1;
545  case AV_PIX_FMT_RGBA:
546  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
547  stride201, srcSliceH, alpha_first, 4, c->srcW);
548  break;
549  case AV_PIX_FMT_ABGR:
550  alpha_first = 1;
551  case AV_PIX_FMT_BGRA:
552  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
553  stride102, srcSliceH, alpha_first, 4, c->srcW);
554  break;
555  default:
556  av_log(c, AV_LOG_ERROR,
557  "unsupported planar RGB conversion %s -> %s\n",
560  }
561 
562  return srcSliceH;
563 }
564 
565 #define isRGBA32(x) ( \
566  (x) == AV_PIX_FMT_ARGB \
567  || (x) == AV_PIX_FMT_RGBA \
568  || (x) == AV_PIX_FMT_BGRA \
569  || (x) == AV_PIX_FMT_ABGR \
570  )
571 
572 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
573 typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
575 {
576  const enum AVPixelFormat srcFormat = c->srcFormat;
577  const enum AVPixelFormat dstFormat = c->dstFormat;
578  const int srcId = c->srcFormatBpp;
579  const int dstId = c->dstFormatBpp;
580  rgbConvFn conv = NULL;
581  const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(srcFormat);
582  const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(dstFormat);
583 
584 #define IS_NOT_NE(bpp, desc) \
585  (((bpp + 7) >> 3) == 2 && \
586  (!(desc->flags & AV_PIX_FMT_FLAG_BE) != !HAVE_BIGENDIAN))
587 
588  /* if this is non-native rgb444/555/565, don't handle it here. */
589  if (IS_NOT_NE(srcId, desc_src) || IS_NOT_NE(dstId, desc_dst))
590  return NULL;
591 
592 #define CONV_IS(src, dst) (srcFormat == AV_PIX_FMT_##src && dstFormat == AV_PIX_FMT_##dst)
593 
594  if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
595  if ( CONV_IS(ABGR, RGBA)
596  || CONV_IS(ARGB, BGRA)
597  || CONV_IS(BGRA, ARGB)
598  || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
599  else if (CONV_IS(ABGR, ARGB)
600  || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
601  else if (CONV_IS(ABGR, BGRA)
602  || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
603  else if (CONV_IS(BGRA, RGBA)
604  || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
605  else if (CONV_IS(BGRA, ABGR)
606  || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
607  } else
608  /* BGR -> BGR */
609  if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
610  (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
611  switch (srcId | (dstId << 16)) {
612  case 0x000F000C: conv = rgb12to15; break;
613  case 0x000F0010: conv = rgb16to15; break;
614  case 0x000F0018: conv = rgb24to15; break;
615  case 0x000F0020: conv = rgb32to15; break;
616  case 0x0010000F: conv = rgb15to16; break;
617  case 0x00100018: conv = rgb24to16; break;
618  case 0x00100020: conv = rgb32to16; break;
619  case 0x0018000F: conv = rgb15to24; break;
620  case 0x00180010: conv = rgb16to24; break;
621  case 0x00180020: conv = rgb32to24; break;
622  case 0x0020000F: conv = rgb15to32; break;
623  case 0x00200010: conv = rgb16to32; break;
624  case 0x00200018: conv = rgb24to32; break;
625  }
626  } else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) ||
627  (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
628  switch (srcId | (dstId << 16)) {
629  case 0x000C000C: conv = rgb12tobgr12; break;
630  case 0x000F000F: conv = rgb15tobgr15; break;
631  case 0x000F0010: conv = rgb16tobgr15; break;
632  case 0x000F0018: conv = rgb24tobgr15; break;
633  case 0x000F0020: conv = rgb32tobgr15; break;
634  case 0x0010000F: conv = rgb15tobgr16; break;
635  case 0x00100010: conv = rgb16tobgr16; break;
636  case 0x00100018: conv = rgb24tobgr16; break;
637  case 0x00100020: conv = rgb32tobgr16; break;
638  case 0x0018000F: conv = rgb15tobgr24; break;
639  case 0x00180010: conv = rgb16tobgr24; break;
640  case 0x00180018: conv = rgb24tobgr24; break;
641  case 0x00180020: conv = rgb32tobgr24; break;
642  case 0x0020000F: conv = rgb15tobgr32; break;
643  case 0x00200010: conv = rgb16tobgr32; break;
644  case 0x00200018: conv = rgb24tobgr32; break;
645  }
646  }
647 
648  return conv;
649 }
650 
651 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
652 static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
653  int srcSliceY, int srcSliceH, uint8_t *dst[],
654  int dstStride[])
655 
656 {
657  const enum AVPixelFormat srcFormat = c->srcFormat;
658  const enum AVPixelFormat dstFormat = c->dstFormat;
659  const int srcBpp = (c->srcFormatBpp + 7) >> 3;
660  const int dstBpp = (c->dstFormatBpp + 7) >> 3;
661  rgbConvFn conv = findRgbConvFn(c);
662 
663  if (!conv) {
664  av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
665  sws_format_name(srcFormat), sws_format_name(dstFormat));
666  } else {
667  const uint8_t *srcPtr = src[0];
668  uint8_t *dstPtr = dst[0];
669  if ((srcFormat == AV_PIX_FMT_RGB32_1 || srcFormat == AV_PIX_FMT_BGR32_1) &&
670  !isRGBA32(dstFormat))
671  srcPtr += ALT32_CORR;
672 
673  if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) &&
674  !isRGBA32(srcFormat))
675  dstPtr += ALT32_CORR;
676 
677  if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
678  !(srcStride[0] % srcBpp))
679  conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
680  (srcSliceH - 1) * srcStride[0] + c->srcW * srcBpp);
681  else {
682  int i;
683  dstPtr += dstStride[0] * srcSliceY;
684 
685  for (i = 0; i < srcSliceH; i++) {
686  conv(srcPtr, dstPtr, c->srcW * srcBpp);
687  srcPtr += srcStride[0];
688  dstPtr += dstStride[0];
689  }
690  }
691  }
692  return srcSliceH;
693 }
694 
695 static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
696  int srcStride[], int srcSliceY, int srcSliceH,
697  uint8_t *dst[], int dstStride[])
698 {
699  rgb24toyv12(
700  src[0],
701  dst[0] + srcSliceY * dstStride[0],
702  dst[1] + (srcSliceY >> 1) * dstStride[1],
703  dst[2] + (srcSliceY >> 1) * dstStride[2],
704  c->srcW, srcSliceH,
705  dstStride[0], dstStride[1], srcStride[0]);
706  if (dst[3])
707  fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
708  return srcSliceH;
709 }
710 
711 static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
712  int srcStride[], int srcSliceY, int srcSliceH,
713  uint8_t *dst[], int dstStride[])
714 {
715  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
716  dst[0], dstStride[0]);
717 
718  planar2x(src[1], dst[1] + dstStride[1] * (srcSliceY >> 1), c->chrSrcW,
719  srcSliceH >> 2, srcStride[1], dstStride[1]);
720  planar2x(src[2], dst[2] + dstStride[2] * (srcSliceY >> 1), c->chrSrcW,
721  srcSliceH >> 2, srcStride[2], dstStride[2]);
722  if (dst[3])
723  fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
724  return srcSliceH;
725 }
726 
727 /* unscaled copy like stuff (assumes nearly identical formats) */
728 static int packedCopyWrapper(SwsContext *c, const uint8_t *src[],
729  int srcStride[], int srcSliceY, int srcSliceH,
730  uint8_t *dst[], int dstStride[])
731 {
732  if (dstStride[0] == srcStride[0] && srcStride[0] > 0)
733  memcpy(dst[0] + dstStride[0] * srcSliceY, src[0], srcSliceH * dstStride[0]);
734  else {
735  int i;
736  const uint8_t *srcPtr = src[0];
737  uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
738  int length = 0;
739 
740  /* universal length finder */
741  while (length + c->srcW <= FFABS(dstStride[0]) &&
742  length + c->srcW <= FFABS(srcStride[0]))
743  length += c->srcW;
744  assert(length != 0);
745 
746  for (i = 0; i < srcSliceH; i++) {
747  memcpy(dstPtr, srcPtr, length);
748  srcPtr += srcStride[0];
749  dstPtr += dstStride[0];
750  }
751  }
752  return srcSliceH;
753 }
754 
755 #define clip9(x) av_clip_uintp2(x, 9)
756 #define clip10(x) av_clip_uintp2(x, 10)
757 #define DITHER_COPY(dst, dstStride, wfunc, src, srcStride, rfunc, dithers, shift, clip) \
758  for (i = 0; i < height; i++) { \
759  const uint8_t *dither = dithers[i & 7]; \
760  for (j = 0; j < length - 7; j += 8) { \
761  wfunc(&dst[j + 0], clip((rfunc(&src[j + 0]) + dither[0]) >> shift)); \
762  wfunc(&dst[j + 1], clip((rfunc(&src[j + 1]) + dither[1]) >> shift)); \
763  wfunc(&dst[j + 2], clip((rfunc(&src[j + 2]) + dither[2]) >> shift)); \
764  wfunc(&dst[j + 3], clip((rfunc(&src[j + 3]) + dither[3]) >> shift)); \
765  wfunc(&dst[j + 4], clip((rfunc(&src[j + 4]) + dither[4]) >> shift)); \
766  wfunc(&dst[j + 5], clip((rfunc(&src[j + 5]) + dither[5]) >> shift)); \
767  wfunc(&dst[j + 6], clip((rfunc(&src[j + 6]) + dither[6]) >> shift)); \
768  wfunc(&dst[j + 7], clip((rfunc(&src[j + 7]) + dither[7]) >> shift)); \
769  } \
770  for (; j < length; j++) \
771  wfunc(&dst[j], (rfunc(&src[j]) + dither[j & 7]) >> shift); \
772  dst += dstStride; \
773  src += srcStride; \
774  }
775 
776 static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
777  int srcStride[], int srcSliceY, int srcSliceH,
778  uint8_t *dst[], int dstStride[])
779 {
780  const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
781  const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
782  int plane, i, j;
783  for (plane = 0; plane < 4; plane++) {
784  int length = (plane == 0 || plane == 3) ? c->srcW : -((-c->srcW ) >> c->chrDstHSubSample);
785  int y = (plane == 0 || plane == 3) ? srcSliceY: -((-srcSliceY) >> c->chrDstVSubSample);
786  int height = (plane == 0 || plane == 3) ? srcSliceH: -((-srcSliceH) >> c->chrDstVSubSample);
787  const uint8_t *srcPtr = src[plane];
788  uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
789 
790  if (!dst[plane])
791  continue;
792  // ignore palette for GRAY8
793  if (plane == 1 && !dst[2]) continue;
794  if (!src[plane] || (plane == 1 && !src[2])) {
795  int val = (plane == 3) ? 255 : 128;
796  if (is16BPS(c->dstFormat))
797  length *= 2;
798  if (is9_OR_10BPS(c->dstFormat)) {
799  fill_plane9or10(dst[plane], dstStride[plane],
800  length, height, y, val,
801  desc_dst->comp[plane].depth_minus1 + 1,
802  isBE(c->dstFormat));
803  } else
804  fillPlane(dst[plane], dstStride[plane], length, height, y,
805  val);
806  } else {
807  if (is9_OR_10BPS(c->srcFormat)) {
808  const int src_depth = desc_src->comp[plane].depth_minus1 + 1;
809  const int dst_depth = desc_dst->comp[plane].depth_minus1 + 1;
810  const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
811 
812  if (is16BPS(c->dstFormat)) {
813  uint16_t *dstPtr2 = (uint16_t *) dstPtr;
814 #define COPY9_OR_10TO16(rfunc, wfunc) \
815  for (i = 0; i < height; i++) { \
816  for (j = 0; j < length; j++) { \
817  int srcpx = rfunc(&srcPtr2[j]); \
818  wfunc(&dstPtr2[j], (srcpx << (16 - src_depth)) | (srcpx >> (2 * src_depth - 16))); \
819  } \
820  dstPtr2 += dstStride[plane] / 2; \
821  srcPtr2 += srcStride[plane] / 2; \
822  }
823  if (isBE(c->dstFormat)) {
824  if (isBE(c->srcFormat)) {
826  } else {
828  }
829  } else {
830  if (isBE(c->srcFormat)) {
832  } else {
834  }
835  }
836  } else if (is9_OR_10BPS(c->dstFormat)) {
837  uint16_t *dstPtr2 = (uint16_t *) dstPtr;
838 #define COPY9_OR_10TO9_OR_10(loop) \
839  for (i = 0; i < height; i++) { \
840  for (j = 0; j < length; j++) { \
841  loop; \
842  } \
843  dstPtr2 += dstStride[plane] / 2; \
844  srcPtr2 += srcStride[plane] / 2; \
845  }
846 #define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \
847  if (dst_depth > src_depth) { \
848  COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \
849  wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \
850  } else if (dst_depth < src_depth) { \
851  DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
852  srcPtr2, srcStride[plane] / 2, rfunc, \
853  dither_8x8_1, 1, clip9); \
854  } else { \
855  COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \
856  }
857  if (isBE(c->dstFormat)) {
858  if (isBE(c->srcFormat)) {
860  } else {
862  }
863  } else {
864  if (isBE(c->srcFormat)) {
866  } else {
868  }
869  }
870  } else {
871 #define W8(a, b) { *(a) = (b); }
872 #define COPY9_OR_10TO8(rfunc) \
873  if (src_depth == 9) { \
874  DITHER_COPY(dstPtr, dstStride[plane], W8, \
875  srcPtr2, srcStride[plane] / 2, rfunc, \
876  dither_8x8_1, 1, av_clip_uint8); \
877  } else { \
878  DITHER_COPY(dstPtr, dstStride[plane], W8, \
879  srcPtr2, srcStride[plane] / 2, rfunc, \
880  dither_8x8_3, 2, av_clip_uint8); \
881  }
882  if (isBE(c->srcFormat)) {
884  } else {
886  }
887  }
888  } else if (is9_OR_10BPS(c->dstFormat)) {
889  const int dst_depth = desc_dst->comp[plane].depth_minus1 + 1;
890  uint16_t *dstPtr2 = (uint16_t *) dstPtr;
891 
892  if (is16BPS(c->srcFormat)) {
893  const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
894 #define COPY16TO9_OR_10(rfunc, wfunc) \
895  if (dst_depth == 9) { \
896  DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
897  srcPtr2, srcStride[plane] / 2, rfunc, \
898  ff_dither_8x8_128, 7, clip9); \
899  } else { \
900  DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
901  srcPtr2, srcStride[plane] / 2, rfunc, \
902  dither_8x8_64, 6, clip10); \
903  }
904  if (isBE(c->dstFormat)) {
905  if (isBE(c->srcFormat)) {
907  } else {
909  }
910  } else {
911  if (isBE(c->srcFormat)) {
913  } else {
915  }
916  }
917  } else /* 8bit */ {
918 #define COPY8TO9_OR_10(wfunc) \
919  for (i = 0; i < height; i++) { \
920  for (j = 0; j < length; j++) { \
921  const int srcpx = srcPtr[j]; \
922  wfunc(&dstPtr2[j], (srcpx << (dst_depth - 8)) | (srcpx >> (16 - dst_depth))); \
923  } \
924  dstPtr2 += dstStride[plane] / 2; \
925  srcPtr += srcStride[plane]; \
926  }
927  if (isBE(c->dstFormat)) {
929  } else {
931  }
932  }
933  } else if (is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
934  const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
935 #define COPY16TO8(rfunc) \
936  DITHER_COPY(dstPtr, dstStride[plane], W8, \
937  srcPtr2, srcStride[plane] / 2, rfunc, \
938  dither_8x8_256, 8, av_clip_uint8);
939  if (isBE(c->srcFormat)) {
941  } else {
943  }
944  } else if (!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
945  for (i = 0; i < height; i++) {
946  for (j = 0; j < length; j++) {
947  dstPtr[ j << 1 ] = srcPtr[j];
948  dstPtr[(j << 1) + 1] = srcPtr[j];
949  }
950  srcPtr += srcStride[plane];
951  dstPtr += dstStride[plane];
952  }
953  } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
954  isBE(c->srcFormat) != isBE(c->dstFormat)) {
955 
956  for (i = 0; i < height; i++) {
957  for (j = 0; j < length; j++)
958  ((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);
959  srcPtr += srcStride[plane];
960  dstPtr += dstStride[plane];
961  }
962  } else if (dstStride[plane] == srcStride[plane] &&
963  srcStride[plane] > 0 && srcStride[plane] == length) {
964  memcpy(dst[plane] + dstStride[plane] * y, src[plane],
965  height * dstStride[plane]);
966  } else {
967  if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
968  length *= 2;
969  else if (!desc_src->comp[0].depth_minus1)
970  length >>= 3; // monowhite/black
971  for (i = 0; i < height; i++) {
972  memcpy(dstPtr, srcPtr, length);
973  srcPtr += srcStride[plane];
974  dstPtr += dstStride[plane];
975  }
976  }
977  }
978  }
979  return srcSliceH;
980 }
981 
982 
983 #define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt) \
984  ((src_fmt == pix_fmt ## BE && dst_fmt == pix_fmt ## LE) || \
985  (src_fmt == pix_fmt ## LE && dst_fmt == pix_fmt ## BE))
986 
987 
989 {
990  const enum AVPixelFormat srcFormat = c->srcFormat;
991  const enum AVPixelFormat dstFormat = c->dstFormat;
992  const int flags = c->flags;
993  const int dstH = c->dstH;
994  int needsDither;
995 
996  needsDither = isAnyRGB(dstFormat) &&
997  c->dstFormatBpp < 24 &&
998  (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
999 
1000  /* yv12_to_nv12 */
1001  if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
1002  (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
1004  }
1005  /* nv12_to_yv12 */
1006  if (dstFormat == AV_PIX_FMT_YUV420P &&
1007  (srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
1009  }
1010  /* yuv2bgr */
1011  if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
1012  srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
1013  !(flags & SWS_ACCURATE_RND) && !(dstH & 1)) {
1015  }
1016 
1017  if (srcFormat == AV_PIX_FMT_YUV410P &&
1018  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1019  !(flags & SWS_BITEXACT)) {
1021  }
1022 
1023  /* bgr24toYV12 */
1024  if (srcFormat == AV_PIX_FMT_BGR24 &&
1025  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1026  !(flags & SWS_ACCURATE_RND))
1028 
1029  /* RGB/BGR -> RGB/BGR (no dither needed forms) */
1030  if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
1031  && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
1032  c->swscale = rgbToRgbWrapper;
1033 
1034 #define isByteRGB(f) ( \
1035  f == AV_PIX_FMT_RGB32 || \
1036  f == AV_PIX_FMT_RGB32_1 || \
1037  f == AV_PIX_FMT_RGB24 || \
1038  f == AV_PIX_FMT_BGR32 || \
1039  f == AV_PIX_FMT_BGR32_1 || \
1040  f == AV_PIX_FMT_BGR24)
1041 
1042  if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
1044 
1045  if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth_minus1 == 7 &&
1046  isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
1048 
1049  /* bswap 16 bits per pixel/component packed formats */
1050  if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) ||
1051  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR48) ||
1052  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) ||
1053  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) ||
1054  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
1055  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) ||
1056  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YA16) ||
1057  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) ||
1058  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48) ||
1059  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) ||
1060  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) ||
1061  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
1062  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12))
1064 
1065  if ((usePal(srcFormat) && (
1066  dstFormat == AV_PIX_FMT_RGB32 ||
1067  dstFormat == AV_PIX_FMT_RGB32_1 ||
1068  dstFormat == AV_PIX_FMT_RGB24 ||
1069  dstFormat == AV_PIX_FMT_BGR32 ||
1070  dstFormat == AV_PIX_FMT_BGR32_1 ||
1071  dstFormat == AV_PIX_FMT_BGR24)))
1072  c->swscale = palToRgbWrapper;
1073 
1074  if (srcFormat == AV_PIX_FMT_YUV422P) {
1075  if (dstFormat == AV_PIX_FMT_YUYV422)
1077  else if (dstFormat == AV_PIX_FMT_UYVY422)
1079  }
1080 
1081  /* LQ converters if -sws 0 or -sws 4*/
1082  if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
1083  /* yv12_to_yuy2 */
1084  if (srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) {
1085  if (dstFormat == AV_PIX_FMT_YUYV422)
1087  else if (dstFormat == AV_PIX_FMT_UYVY422)
1089  }
1090  }
1091  if (srcFormat == AV_PIX_FMT_YUYV422 &&
1092  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1094  if (srcFormat == AV_PIX_FMT_UYVY422 &&
1095  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1097  if (srcFormat == AV_PIX_FMT_YUYV422 && dstFormat == AV_PIX_FMT_YUV422P)
1099  if (srcFormat == AV_PIX_FMT_UYVY422 && dstFormat == AV_PIX_FMT_YUV422P)
1101 
1102  /* simple copy */
1103  if ( srcFormat == dstFormat ||
1104  (srcFormat == AV_PIX_FMT_YUVA420P && dstFormat == AV_PIX_FMT_YUV420P) ||
1105  (srcFormat == AV_PIX_FMT_YUV420P && dstFormat == AV_PIX_FMT_YUVA420P) ||
1106  (isPlanarYUV(srcFormat) && isGray(dstFormat)) ||
1107  (isPlanarYUV(dstFormat) && isGray(srcFormat)) ||
1108  (isGray(dstFormat) && isGray(srcFormat)) ||
1109  (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) &&
1112  dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 &&
1113  srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21))
1114  {
1115  if (isPacked(c->srcFormat))
1117  else /* Planar YUV or gray */
1119  }
1120 
1121  if (ARCH_PPC)
1123 }
1124 
1125 static void reset_ptr(const uint8_t *src[], int format)
1126 {
1127  if (!isALPHA(format))
1128  src[3] = NULL;
1129  if (!isPlanar(format)) {
1130  src[3] = src[2] = NULL;
1131 
1132  if (!usePal(format))
1133  src[1] = NULL;
1134  }
1135 }
1136 
1138  const int linesizes[4])
1139 {
1140  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
1141  int i;
1142 
1143  for (i = 0; i < 4; i++) {
1144  int plane = desc->comp[i].plane;
1145  if (!data[plane] || !linesizes[plane])
1146  return 0;
1147  }
1148 
1149  return 1;
1150 }
1151 
1157  const uint8_t * const srcSlice[],
1158  const int srcStride[], int srcSliceY,
1159  int srcSliceH, uint8_t *const dst[],
1160  const int dstStride[])
1161 {
1162  int i;
1163  const uint8_t *src2[4] = { srcSlice[0], srcSlice[1], srcSlice[2], srcSlice[3] };
1164  uint8_t *dst2[4] = { dst[0], dst[1], dst[2], dst[3] };
1165 
1166  // do not mess up sliceDir if we have a "trailing" 0-size slice
1167  if (srcSliceH == 0)
1168  return 0;
1169 
1170  if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
1171  av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
1172  return 0;
1173  }
1174  if (!check_image_pointers(dst, c->dstFormat, dstStride)) {
1175  av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
1176  return 0;
1177  }
1178 
1179  if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
1180  av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
1181  return 0;
1182  }
1183  if (c->sliceDir == 0) {
1184  if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
1185  }
1186 
1187  if (usePal(c->srcFormat)) {
1188  for (i = 0; i < 256; i++) {
1189  int r, g, b, y, u, v;
1190  if (c->srcFormat == AV_PIX_FMT_PAL8) {
1191  uint32_t p = ((const uint32_t *)(srcSlice[1]))[i];
1192  r = (p >> 16) & 0xFF;
1193  g = (p >> 8) & 0xFF;
1194  b = p & 0xFF;
1195  } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
1196  r = ( i >> 5 ) * 36;
1197  g = ((i >> 2) & 7) * 36;
1198  b = ( i & 3) * 85;
1199  } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
1200  b = ( i >> 6 ) * 85;
1201  g = ((i >> 3) & 7) * 36;
1202  r = ( i & 7) * 36;
1203  } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
1204  r = ( i >> 3 ) * 255;
1205  g = ((i >> 1) & 3) * 85;
1206  b = ( i & 1) * 255;
1207  } else if (c->srcFormat == AV_PIX_FMT_GRAY8 ||
1208  c->srcFormat == AV_PIX_FMT_YA8) {
1209  r = g = b = i;
1210  } else {
1211  assert(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);
1212  b = ( i >> 3 ) * 255;
1213  g = ((i >> 1) & 3) * 85;
1214  r = ( i & 1) * 255;
1215  }
1216  y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
1217  u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
1218  v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
1219  c->pal_yuv[i] = y + (u << 8) + (v << 16) + (0xFFU << 24);
1220 
1221  switch (c->dstFormat) {
1222  case AV_PIX_FMT_BGR32:
1223 #if !HAVE_BIGENDIAN
1224  case AV_PIX_FMT_RGB24:
1225 #endif
1226  c->pal_rgb[i] = r + (g << 8) + (b << 16) + (0xFFU << 24);
1227  break;
1228  case AV_PIX_FMT_BGR32_1:
1229 #if HAVE_BIGENDIAN
1230  case AV_PIX_FMT_BGR24:
1231 #endif
1232  c->pal_rgb[i] = 0xFF + (r << 8) + (g << 16) + ((unsigned)b << 24);
1233  break;
1234  case AV_PIX_FMT_RGB32_1:
1235 #if HAVE_BIGENDIAN
1236  case AV_PIX_FMT_RGB24:
1237 #endif
1238  c->pal_rgb[i] = 0xFF + (b << 8) + (g << 16) + ((unsigned)r << 24);
1239  break;
1240  case AV_PIX_FMT_RGB32:
1241 #if !HAVE_BIGENDIAN
1242  case AV_PIX_FMT_BGR24:
1243 #endif
1244  default:
1245  c->pal_rgb[i] = b + (g << 8) + (r << 16) + (0xFFU << 24);
1246  }
1247  }
1248  }
1249 
1250  // copy strides, so they can safely be modified
1251  if (c->sliceDir == 1) {
1252  // slices go from top to bottom
1253  int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],
1254  srcStride[3] };
1255  int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],
1256  dstStride[3] };
1257 
1258  reset_ptr(src2, c->srcFormat);
1259  reset_ptr((const uint8_t **) dst2, c->dstFormat);
1260 
1261  /* reset slice direction at end of frame */
1262  if (srcSliceY + srcSliceH == c->srcH)
1263  c->sliceDir = 0;
1264 
1265  return c->swscale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
1266  dstStride2);
1267  } else {
1268  // slices go from bottom to top => we flip the image internally
1269  int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],
1270  -srcStride[3] };
1271  int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],
1272  -dstStride[3] };
1273 
1274  src2[0] += (srcSliceH - 1) * srcStride[0];
1275  if (!usePal(c->srcFormat))
1276  src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
1277  src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
1278  src2[3] += (srcSliceH - 1) * srcStride[3];
1279  dst2[0] += ( c->dstH - 1) * dstStride[0];
1280  dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
1281  dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
1282  dst2[3] += ( c->dstH - 1) * dstStride[3];
1283 
1284  reset_ptr(src2, c->srcFormat);
1285  reset_ptr((const uint8_t **) dst2, c->dstFormat);
1286 
1287  /* reset slice direction at end of frame */
1288  if (!srcSliceY)
1289  c->sliceDir = 0;
1290 
1291  return c->swscale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
1292  srcSliceH, dst2, dstStride2);
1293  }
1294 }
1295 
1296 /* Convert the palette to the same packed 32-bit format as the palette */
1298  int num_pixels, const uint8_t *palette)
1299 {
1300  int i;
1301 
1302  for (i = 0; i < num_pixels; i++)
1303  ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
1304 }
1305 
1306 /* Palette format: ABCD -> dst format: ABC */
1308  int num_pixels, const uint8_t *palette)
1309 {
1310  int i;
1311 
1312  for (i = 0; i < num_pixels; i++) {
1313  //FIXME slow?
1314  dst[0] = palette[src[i] * 4 + 0];
1315  dst[1] = palette[src[i] * 4 + 1];
1316  dst[2] = palette[src[i] * 4 + 2];
1317  dst += 3;
1318  }
1319 }
#define IS_NOT_NE(bpp, desc)
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:84
static void reset_ptr(const uint8_t *src[], int format)
void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, int src_size)
const char * sws_format_name(enum AVPixelFormat format)
Definition: utils.c:205
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1599
static const uint8_t dither_8x8_3[8][8]
static int packed_16bpc_bswap(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
Convert an 8-bit paletted frame into a frame with a color depth of 32 bits.
void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
Convert an 8-bit paletted frame into a frame with a color depth of 24 bits.
8bit gray, 8bit alpha
Definition: pixfmt.h:144
void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:177
uint32_t pal_rgb[256]
void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:309
void shuffle_bytes_3012(const uint8_t *src, uint8_t *dst, int src_size)
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:67
#define BU
void(* planar2x)(const uint8_t *src, uint8_t *dst, int width, int height, int srcStride, int dstStride)
Definition: rgb2rgb.c:80
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:233
void shuffle_bytes_3210(const uint8_t *src, uint8_t *dst, int src_size)
Definition: vf_drawbox.c:37
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:163
void rgb16tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:232
static void gbr24ptopacked32(const uint8_t *src[], int srcStride[], uint8_t *dst, int dstStride, int srcSliceH, int alpha_first, int width)
void(* yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, int width, int height, int lumStride, int chromStride, int srcStride)
Definition: rgb2rgb.c:107
#define av_bswap16
Definition: bswap.h:31
int dstFormatBpp
Number of bits per pixel of the destination pixel format.
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:58
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:238
void(* yuv422ptouyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, int width, int height, int lumStride, int chromStride, int dstStride)
Width should be a multiple of 16.
Definition: rgb2rgb.c:68
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
external API header
#define AV_RL16
Definition: intreadwrite.h:42
#define isRGBA32(x)
static void gbr24ptopacked24(const uint8_t *src[], int srcStride[], uint8_t *dst, int dstStride, int srcSliceH, int width)
#define RGBA(r, g, b, a)
Definition: dvbsubdec.c:151
#define COPY16TO9_OR_10(rfunc, wfunc)
void(* rgb32to16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:45
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:232
int stride
Definition: mace.c:144
static const uint8_t dither_8x8_1[8][8]
int srcH
Height of source luma/alpha planes.
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:88
void(* rgb16to15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:50
void(* uyvytoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, int width, int height, int lumStride, int chromStride, int srcStride)
Definition: rgb2rgb.c:98
void(* uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, int width, int height, int lumStride, int chromStride, int srcStride)
Definition: rgb2rgb.c:101
static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
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...
static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:97
uint8_t
#define isByteRGB(f)
void(* yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, int width, int height, int lumStride, int chromStride, int dstStride)
Width should be a multiple of 16.
Definition: rgb2rgb.c:64
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:76
static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define GU
static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
#define isRGBinInt(x)
static const uint8_t dither_8x8_64[8][8]
#define BY
#define COPY9_OR_10TO8(rfunc)
#define b
Definition: input.c:52
#define GV
void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:218
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:97
void(* rgb15tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:43
#define SWS_FAST_BILINEAR
Definition: swscale.h:57
const char data[16]
Definition: mxf.c:70
static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
static int flags
Definition: log.c:44
#define COPY9_OR_10TO16(rfunc, wfunc)
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:234
#define RGB2YUV_SHIFT
#define isAnyRGB(x)
external api for the swscale stuff
enum AVPixelFormat dstFormat
Destination pixel format.
#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...
#define r
Definition: input.c:51
void(* yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, int width, int height, int lumStride, int chromStride, int dstStride)
Height should be a multiple of 2 and width should be a multiple of 16.
Definition: rgb2rgb.c:60
int dstH
Height of destination luma/alpha 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...
static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
uint16_t depth_minus1
Number of bits in the component minus 1.
Definition: pixdesc.h:57
#define CONV_IS(src, dst)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
#define AV_PIX_FMT_BGR32_1
Definition: pixfmt.h:225
#define isBGRinInt(x)
static int planarToNv12Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
void(* interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst, int width, int height, int src1Stride, int src2Stride, int dstStride)
Definition: rgb2rgb.c:82
static rgbConvFn findRgbConvFn(SwsContext *c)
static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
#define AV_RB16
Definition: intreadwrite.h:53
void(* rgb16to32)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:49
void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size)
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:98
void(* rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:38
g
Definition: yuv2rgb.c:535
void(* rgb24to15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:48
#define AV_PIX_FMT_YA16
Definition: pixfmt.h:228
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
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:229
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:169
static void fillPlane(uint8_t *plane, int stride, int width, int height, int y, uint8_t val)
static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:95
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:96
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:69
static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:288
as above, but U and V bytes are swapped
Definition: pixfmt.h:93
#define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc)
#define GY
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:227
#define FFMIN(a, b)
Definition: common.h:57
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:91
static void fill_plane9or10(uint8_t *plane, int stride, int width, int height, int y, uint8_t val, const int dst_depth, const int big_endian)
void(* rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:37
static av_always_inline int is9_OR_10BPS(enum AVPixelFormat pix_fmt)
#define RV
#define FFABS(a)
Definition: common.h:52
void(* rgbConvFn)(const uint8_t *, uint8_t *, int)
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:68
void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:199
enum AVPixelFormat pix_fmt
Definition: movenc.c:843
static int check_image_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, const int linesizes[4])
int sliceDir
Direction that slices are fed to the scaler (1 = top-to-bottom, -1 = bottom-to-top).
static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
#define AV_PIX_FMT_BGR555
Definition: pixfmt.h:236
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:224
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
#define attribute_align_arg
Definition: internal.h:54
NULL
Definition: eval.c:55
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:86
void(* rgb15to32)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:52
static int width
Definition: utils.c:156
void(* rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, int width, int height, int lumStride, int chromStride, int srcStride)
Height should be a multiple of 2 and width should be a multiple of 2.
Definition: rgb2rgb.c:76
void(* rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:51
static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
#define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt)
static void(WINAPI *cond_broadcast)(pthread_cond_t *cond)
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:222
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:66
int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
void rgb32to24(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:139
void(* rgb32to15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:46
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:71
#define AV_PIX_FMT_XYZ12
Definition: pixfmt.h:264
void(* shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:54
SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
Definition: yuv2rgb.c:559
#define SWS_ACCURATE_RND
Definition: swscale.h:82
byte swapping routines
#define AV_WB16(p, d)
Definition: intreadwrite.h:213
static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
#define RU
#define isGray(x)
Definition: swscale-test.c:38
static const uint8_t dither_8x8_256[8][8]
void rgb24to32(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:157
#define SWS_POINT
Definition: swscale.h:61
static int planarCopyWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:235
void(* rgb24tobgr15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:41
#define ARCH_PPC
Definition: config.h:24
#define BV
static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define SWS_BITEXACT
Definition: swscale.h:83
void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:298
int height
Definition: gxfenc.c:72
void(* yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, int width, int height, int lumStride, int chromStride, int dstStride)
Height should be a multiple of 2 and width should be a multiple of 16.
Definition: rgb2rgb.c:56
uint16_t plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:34
#define FILL8TO9_OR_10(wfunc)
static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:65
Y , 8bpp.
Definition: pixfmt.h:73
#define COPY16TO8(rfunc)
void(* yuyvtoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, int width, int height, int lumStride, int chromStride, int srcStride)
Definition: rgb2rgb.c:104
void(* rgb24tobgr16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:40
#define AV_PIX_FMT_BGR444
Definition: pixfmt.h:237
enum AVPixelFormat srcFormat
Source pixel format.
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:89
static void packedtogbr24p(const uint8_t *src, int srcStride, uint8_t *dst[], int dstStride[], int srcSliceH, int alpha_first, int inc_size, int width)
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:231
static void copyPlane(const uint8_t *src, int srcStride, int srcSliceY, int srcSliceH, int width, uint8_t *dst, int dstStride)
void(* rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:35
SwsFunc swscale
Note that src, dst, srcStride, dstStride will be copied in the sws_scale() wrapper so they can be fre...
void(* rgb24to16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:47
void(* rgb16tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:42
static int planarToUyvyWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
#define RY
void(* rgb32tobgr16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:36
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:223
void rgb15tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:252
static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
int srcFormatBpp
Number of bits per pixel of the source pixel format.
av_cold void ff_get_unscaled_swscale_ppc(SwsContext *c)
#define COPY8TO9_OR_10(wfunc)
static int packedCopyWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:230
static av_always_inline int isPackedRGB(enum AVPixelFormat pix_fmt)
void(* deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2, int width, int height, int srcStride, int dst1Stride, int dst2Stride)
Definition: rgb2rgb.c:85
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:83
static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
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
#define AV_WL16(p, d)
Definition: intreadwrite.h:225
static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
#define ALT32_CORR
int chrDstHSubSample
Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in destination...
int chrSrcW
Width of source chroma planes.
int srcW
Width of source luma/alpha planes.
void rgb16tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:242
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
uint32_t pal_yuv[256]
void(* rgb24tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:39
void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:274