FFmpeg
swscale_unscaled.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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 "swscale.h"
27 #include "swscale_internal.h"
28 #include "rgb2rgb.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/cpu.h"
31 #include "libavutil/avutil.h"
32 #include "libavutil/mathematics.h"
33 #include "libavutil/bswap.h"
34 #include "libavutil/pixdesc.h"
35 #include "libavutil/avassert.h"
36 #include "libavutil/avconfig.h"
37 
38 DECLARE_ALIGNED(8, static const uint8_t, dithers)[8][8][8]={
39 {
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  { 0, 1, 0, 1, 0, 1, 0, 1,},
47  { 1, 0, 1, 0, 1, 0, 1, 0,},
48 },{
49  { 1, 2, 1, 2, 1, 2, 1, 2,},
50  { 3, 0, 3, 0, 3, 0, 3, 0,},
51  { 1, 2, 1, 2, 1, 2, 1, 2,},
52  { 3, 0, 3, 0, 3, 0, 3, 0,},
53  { 1, 2, 1, 2, 1, 2, 1, 2,},
54  { 3, 0, 3, 0, 3, 0, 3, 0,},
55  { 1, 2, 1, 2, 1, 2, 1, 2,},
56  { 3, 0, 3, 0, 3, 0, 3, 0,},
57 },{
58  { 2, 4, 3, 5, 2, 4, 3, 5,},
59  { 6, 0, 7, 1, 6, 0, 7, 1,},
60  { 3, 5, 2, 4, 3, 5, 2, 4,},
61  { 7, 1, 6, 0, 7, 1, 6, 0,},
62  { 2, 4, 3, 5, 2, 4, 3, 5,},
63  { 6, 0, 7, 1, 6, 0, 7, 1,},
64  { 3, 5, 2, 4, 3, 5, 2, 4,},
65  { 7, 1, 6, 0, 7, 1, 6, 0,},
66 },{
67  { 4, 8, 7, 11, 4, 8, 7, 11,},
68  { 12, 0, 15, 3, 12, 0, 15, 3,},
69  { 6, 10, 5, 9, 6, 10, 5, 9,},
70  { 14, 2, 13, 1, 14, 2, 13, 1,},
71  { 4, 8, 7, 11, 4, 8, 7, 11,},
72  { 12, 0, 15, 3, 12, 0, 15, 3,},
73  { 6, 10, 5, 9, 6, 10, 5, 9,},
74  { 14, 2, 13, 1, 14, 2, 13, 1,},
75 },{
76  { 9, 17, 15, 23, 8, 16, 14, 22,},
77  { 25, 1, 31, 7, 24, 0, 30, 6,},
78  { 13, 21, 11, 19, 12, 20, 10, 18,},
79  { 29, 5, 27, 3, 28, 4, 26, 2,},
80  { 8, 16, 14, 22, 9, 17, 15, 23,},
81  { 24, 0, 30, 6, 25, 1, 31, 7,},
82  { 12, 20, 10, 18, 13, 21, 11, 19,},
83  { 28, 4, 26, 2, 29, 5, 27, 3,},
84 },{
85  { 18, 34, 30, 46, 17, 33, 29, 45,},
86  { 50, 2, 62, 14, 49, 1, 61, 13,},
87  { 26, 42, 22, 38, 25, 41, 21, 37,},
88  { 58, 10, 54, 6, 57, 9, 53, 5,},
89  { 16, 32, 28, 44, 19, 35, 31, 47,},
90  { 48, 0, 60, 12, 51, 3, 63, 15,},
91  { 24, 40, 20, 36, 27, 43, 23, 39,},
92  { 56, 8, 52, 4, 59, 11, 55, 7,},
93 },{
94  { 18, 34, 30, 46, 17, 33, 29, 45,},
95  { 50, 2, 62, 14, 49, 1, 61, 13,},
96  { 26, 42, 22, 38, 25, 41, 21, 37,},
97  { 58, 10, 54, 6, 57, 9, 53, 5,},
98  { 16, 32, 28, 44, 19, 35, 31, 47,},
99  { 48, 0, 60, 12, 51, 3, 63, 15,},
100  { 24, 40, 20, 36, 27, 43, 23, 39,},
101  { 56, 8, 52, 4, 59, 11, 55, 7,},
102 },{
103  { 36, 68, 60, 92, 34, 66, 58, 90,},
104  { 100, 4,124, 28, 98, 2,122, 26,},
105  { 52, 84, 44, 76, 50, 82, 42, 74,},
106  { 116, 20,108, 12,114, 18,106, 10,},
107  { 32, 64, 56, 88, 38, 70, 62, 94,},
108  { 96, 0,120, 24,102, 6,126, 30,},
109  { 48, 80, 40, 72, 54, 86, 46, 78,},
110  { 112, 16,104, 8,118, 22,110, 14,},
111 }};
112 
113 
114 static void fillPlane(uint8_t *plane, int stride, int width, int height, int y,
115  uint8_t val)
116 {
117  int i;
118  uint8_t *ptr = plane + stride * y;
119  for (i = 0; i < height; i++) {
120  memset(ptr, val, width);
121  ptr += stride;
122  }
123 }
124 
125 static void copyPlane(const uint8_t *src, int srcStride,
126  int srcSliceY, int srcSliceH, int width,
127  uint8_t *dst, int dstStride)
128 {
129  dst += dstStride * srcSliceY;
130  if (dstStride == srcStride && srcStride > 0) {
131  memcpy(dst, src, srcSliceH * dstStride);
132  } else {
133  int i;
134  for (i = 0; i < srcSliceH; i++) {
135  memcpy(dst, src, width);
136  src += srcStride;
137  dst += dstStride;
138  }
139  }
140 }
141 
143  int srcStride[], int srcSliceY,
144  int srcSliceH, uint8_t *dstParam[],
145  int dstStride[])
146 {
147  uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY / 2;
148 
149  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
150  dstParam[0], dstStride[0]);
151 
152  if (c->dstFormat == AV_PIX_FMT_NV12)
153  interleaveBytes(src[1], src[2], dst, c->chrSrcW, (srcSliceH + 1) / 2,
154  srcStride[1], srcStride[2], dstStride[1]);
155  else
156  interleaveBytes(src[2], src[1], dst, c->chrSrcW, (srcSliceH + 1) / 2,
157  srcStride[2], srcStride[1], dstStride[1]);
158 
159  return srcSliceH;
160 }
161 
163  int srcStride[], int srcSliceY,
164  int srcSliceH, uint8_t *dstParam[],
165  int dstStride[])
166 {
167  uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
168  uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
169 
170  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
171  dstParam[0], dstStride[0]);
172 
173  if (c->srcFormat == AV_PIX_FMT_NV12)
174  deinterleaveBytes(src[1], dst1, dst2, c->chrSrcW, (srcSliceH + 1) / 2,
175  srcStride[1], dstStride[1], dstStride[2]);
176  else
177  deinterleaveBytes(src[1], dst2, dst1, c->chrSrcW, (srcSliceH + 1) / 2,
178  srcStride[1], dstStride[2], dstStride[1]);
179 
180  return srcSliceH;
181 }
182 
184  int srcStride[], int srcSliceY,
185  int srcSliceH, uint8_t *dstParam[],
186  int dstStride[])
187 {
188  uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY;
189 
190  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
191  dstParam[0], dstStride[0]);
192 
193  if (c->dstFormat == AV_PIX_FMT_NV24)
194  interleaveBytes(src[1], src[2], dst, c->chrSrcW, srcSliceH,
195  srcStride[1], srcStride[2], dstStride[1]);
196  else
197  interleaveBytes(src[2], src[1], dst, c->chrSrcW, srcSliceH,
198  srcStride[2], srcStride[1], dstStride[1]);
199 
200  return srcSliceH;
201 }
202 
204  int srcStride[], int srcSliceY,
205  int srcSliceH, uint8_t *dstParam[],
206  int dstStride[])
207 {
208  uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY;
209  uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY;
210 
211  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
212  dstParam[0], dstStride[0]);
213 
214  if (c->srcFormat == AV_PIX_FMT_NV24)
215  deinterleaveBytes(src[1], dst1, dst2, c->chrSrcW, srcSliceH,
216  srcStride[1], dstStride[1], dstStride[2]);
217  else
218  deinterleaveBytes(src[1], dst2, dst1, c->chrSrcW, srcSliceH,
219  srcStride[1], dstStride[2], dstStride[1]);
220 
221  return srcSliceH;
222 }
223 
224 static int planarToP01xWrapper(SwsContext *c, const uint8_t *src8[],
225  int srcStride[], int srcSliceY,
226  int srcSliceH, uint8_t *dstParam8[],
227  int dstStride[])
228 {
229  const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
230  const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
231  const uint16_t **src = (const uint16_t**)src8;
232  uint16_t *dstY = (uint16_t*)(dstParam8[0] + dstStride[0] * srcSliceY);
233  uint16_t *dstUV = (uint16_t*)(dstParam8[1] + dstStride[1] * srcSliceY / 2);
234  int x, y;
235 
236  /* Calculate net shift required for values. */
237  const int shift[3] = {
238  dst_format->comp[0].depth + dst_format->comp[0].shift -
239  src_format->comp[0].depth - src_format->comp[0].shift,
240  dst_format->comp[1].depth + dst_format->comp[1].shift -
241  src_format->comp[1].depth - src_format->comp[1].shift,
242  dst_format->comp[2].depth + dst_format->comp[2].shift -
243  src_format->comp[2].depth - src_format->comp[2].shift,
244  };
245 
246  av_assert0(!(srcStride[0] % 2 || srcStride[1] % 2 || srcStride[2] % 2 ||
247  dstStride[0] % 2 || dstStride[1] % 2));
248 
249  for (y = 0; y < srcSliceH; y++) {
250  uint16_t *tdstY = dstY;
251  const uint16_t *tsrc0 = src[0];
252  for (x = c->srcW; x > 0; x--) {
253  *tdstY++ = *tsrc0++ << shift[0];
254  }
255  src[0] += srcStride[0] / 2;
256  dstY += dstStride[0] / 2;
257 
258  if (!(y & 1)) {
259  uint16_t *tdstUV = dstUV;
260  const uint16_t *tsrc1 = src[1];
261  const uint16_t *tsrc2 = src[2];
262  for (x = c->srcW / 2; x > 0; x--) {
263  *tdstUV++ = *tsrc1++ << shift[1];
264  *tdstUV++ = *tsrc2++ << shift[2];
265  }
266  src[1] += srcStride[1] / 2;
267  src[2] += srcStride[2] / 2;
268  dstUV += dstStride[1] / 2;
269  }
270  }
271 
272  return srcSliceH;
273 }
274 
275 #if AV_HAVE_BIGENDIAN
276 #define output_pixel(p, v) do { \
277  uint16_t *pp = (p); \
278  AV_WL16(pp, (v)); \
279  } while(0)
280 #else
281 #define output_pixel(p, v) (*p) = (v)
282 #endif
283 
285  int srcStride[], int srcSliceY,
286  int srcSliceH, uint8_t *dstParam8[],
287  int dstStride[])
288 {
289  uint16_t *dstY = (uint16_t*)(dstParam8[0] + dstStride[0] * srcSliceY);
290  uint16_t *dstUV = (uint16_t*)(dstParam8[1] + dstStride[1] * srcSliceY / 2);
291  int x, y, t;
292 
293  av_assert0(!(dstStride[0] % 2 || dstStride[1] % 2));
294 
295  for (y = 0; y < srcSliceH; y++) {
296  uint16_t *tdstY = dstY;
297  const uint8_t *tsrc0 = src[0];
298  for (x = c->srcW; x > 0; x--) {
299  t = *tsrc0++;
300  output_pixel(tdstY++, t | (t << 8));
301  }
302  src[0] += srcStride[0];
303  dstY += dstStride[0] / 2;
304 
305  if (!(y & 1)) {
306  uint16_t *tdstUV = dstUV;
307  const uint8_t *tsrc1 = src[1];
308  const uint8_t *tsrc2 = src[2];
309  for (x = c->srcW / 2; x > 0; x--) {
310  t = *tsrc1++;
311  output_pixel(tdstUV++, t | (t << 8));
312  t = *tsrc2++;
313  output_pixel(tdstUV++, t | (t << 8));
314  }
315  src[1] += srcStride[1];
316  src[2] += srcStride[2];
317  dstUV += dstStride[1] / 2;
318  }
319  }
320 
321  return srcSliceH;
322 }
323 
324 #undef output_pixel
325 
327  int srcStride[], int srcSliceY, int srcSliceH,
328  uint8_t *dstParam[], int dstStride[])
329 {
330  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
331 
332  yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
333  srcStride[1], dstStride[0]);
334 
335  return srcSliceH;
336 }
337 
339  int srcStride[], int srcSliceY, int srcSliceH,
340  uint8_t *dstParam[], int dstStride[])
341 {
342  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
343 
344  yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
345  srcStride[1], dstStride[0]);
346 
347  return srcSliceH;
348 }
349 
351  int srcStride[], int srcSliceY, int srcSliceH,
352  uint8_t *dstParam[], int dstStride[])
353 {
354  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
355 
356  yuv422ptoyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
357  srcStride[1], dstStride[0]);
358 
359  return srcSliceH;
360 }
361 
363  int srcStride[], int srcSliceY, int srcSliceH,
364  uint8_t *dstParam[], int dstStride[])
365 {
366  uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
367 
368  yuv422ptouyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
369  srcStride[1], dstStride[0]);
370 
371  return srcSliceH;
372 }
373 
375  int srcStride[], int srcSliceY, int srcSliceH,
376  uint8_t *dstParam[], int dstStride[])
377 {
378  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
379  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
380  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
381 
382  yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
383  dstStride[1], srcStride[0]);
384 
385  if (dstParam[3])
386  fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
387 
388  return srcSliceH;
389 }
390 
392  int srcStride[], int srcSliceY, int srcSliceH,
393  uint8_t *dstParam[], int dstStride[])
394 {
395  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
396  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
397  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
398 
399  yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
400  dstStride[1], srcStride[0]);
401 
402  return srcSliceH;
403 }
404 
406  int srcStride[], int srcSliceY, int srcSliceH,
407  uint8_t *dstParam[], int dstStride[])
408 {
409  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
410  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
411  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
412 
413  uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
414  dstStride[1], srcStride[0]);
415 
416  if (dstParam[3])
417  fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
418 
419  return srcSliceH;
420 }
421 
423  int srcStride[], int srcSliceY, int srcSliceH,
424  uint8_t *dstParam[], int dstStride[])
425 {
426  uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
427  uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
428  uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
429 
430  uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
431  dstStride[1], srcStride[0]);
432 
433  return srcSliceH;
434 }
435 
436 static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels,
437  const uint8_t *palette)
438 {
439  int i;
440  for (i = 0; i < num_pixels; i++)
441  ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | (src[(i << 1) + 1] << 24);
442 }
443 
444 static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels,
445  const uint8_t *palette)
446 {
447  int i;
448 
449  for (i = 0; i < num_pixels; i++)
450  ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | src[(i << 1) + 1];
451 }
452 
453 static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels,
454  const uint8_t *palette)
455 {
456  int i;
457 
458  for (i = 0; i < num_pixels; i++) {
459  //FIXME slow?
460  dst[0] = palette[src[i << 1] * 4 + 0];
461  dst[1] = palette[src[i << 1] * 4 + 1];
462  dst[2] = palette[src[i << 1] * 4 + 2];
463  dst += 3;
464  }
465 }
466 
467 static int bswap_16bpc(SwsContext *c, const uint8_t *src[],
468  int srcStride[], int srcSliceY, int srcSliceH,
469  uint8_t *dst[], int dstStride[])
470 {
471  int i, j, p;
472 
473  for (p = 0; p < 4; p++) {
474  int srcstr = srcStride[p] / 2;
475  int dststr = dstStride[p] / 2;
476  uint16_t *dstPtr = (uint16_t *) dst[p];
477  const uint16_t *srcPtr = (const uint16_t *) src[p];
478  int min_stride = FFMIN(FFABS(srcstr), FFABS(dststr));
479  if(!dstPtr || !srcPtr)
480  continue;
481  dstPtr += (srcSliceY >> c->chrDstVSubSample) * dststr;
482  for (i = 0; i < (srcSliceH >> c->chrDstVSubSample); i++) {
483  for (j = 0; j < min_stride; j++) {
484  dstPtr[j] = av_bswap16(srcPtr[j]);
485  }
486  srcPtr += srcstr;
487  dstPtr += dststr;
488  }
489  }
490 
491  return srcSliceH;
492 }
493 
494 static int bswap_32bpc(SwsContext *c, const uint8_t *src[],
495  int srcStride[], int srcSliceY, int srcSliceH,
496  uint8_t *dst[], int dstStride[])
497 {
498  int i, j, p;
499 
500  for (p = 0; p < 4; p++) {
501  int srcstr = srcStride[p] / 4;
502  int dststr = dstStride[p] / 4;
503  uint32_t *dstPtr = (uint32_t *) dst[p];
504  const uint32_t *srcPtr = (const uint32_t *) src[p];
505  int min_stride = FFMIN(FFABS(srcstr), FFABS(dststr));
506  if(!dstPtr || !srcPtr)
507  continue;
508  dstPtr += (srcSliceY >> c->chrDstVSubSample) * dststr;
509  for (i = 0; i < (srcSliceH >> c->chrDstVSubSample); i++) {
510  for (j = 0; j < min_stride; j++) {
511  dstPtr[j] = av_bswap32(srcPtr[j]);
512  }
513  srcPtr += srcstr;
514  dstPtr += dststr;
515  }
516  }
517 
518  return srcSliceH;
519 }
520 
521 
522 static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
523  int srcSliceY, int srcSliceH, uint8_t *dst[],
524  int dstStride[])
525 {
526  const enum AVPixelFormat srcFormat = c->srcFormat;
527  const enum AVPixelFormat dstFormat = c->dstFormat;
528  void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels,
529  const uint8_t *palette) = NULL;
530  int i;
531  uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
532  const uint8_t *srcPtr = src[0];
533 
534  if (srcFormat == AV_PIX_FMT_YA8) {
535  switch (dstFormat) {
536  case AV_PIX_FMT_RGB32 : conv = gray8aToPacked32; break;
537  case AV_PIX_FMT_BGR32 : conv = gray8aToPacked32; break;
540  case AV_PIX_FMT_RGB24 : conv = gray8aToPacked24; break;
541  case AV_PIX_FMT_BGR24 : conv = gray8aToPacked24; break;
542  }
543  } else if (usePal(srcFormat)) {
544  switch (dstFormat) {
551  }
552  }
553 
554  if (!conv)
555  av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
556  av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
557  else {
558  for (i = 0; i < srcSliceH; i++) {
559  conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
560  srcPtr += srcStride[0];
561  dstPtr += dstStride[0];
562  }
563  }
564 
565  return srcSliceH;
566 }
567 
568 static void packed16togbra16(const uint8_t *src, int srcStride,
569  uint16_t *dst[], int dstStride[], int srcSliceH,
570  int src_alpha, int swap, int shift, int width)
571 {
572  int x, h, i;
573  int dst_alpha = dst[3] != NULL;
574  for (h = 0; h < srcSliceH; h++) {
575  uint16_t *src_line = (uint16_t *)(src + srcStride * h);
576  switch (swap) {
577  case 3:
578  if (src_alpha && dst_alpha) {
579  for (x = 0; x < width; x++) {
580  dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
581  dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
582  dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
583  dst[3][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
584  }
585  } else if (dst_alpha) {
586  for (x = 0; x < width; x++) {
587  dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
588  dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
589  dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
590  dst[3][x] = 0xFFFF;
591  }
592  } else if (src_alpha) {
593  for (x = 0; x < width; x++) {
594  dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
595  dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
596  dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
597  src_line++;
598  }
599  } else {
600  for (x = 0; x < width; x++) {
601  dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
602  dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
603  dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
604  }
605  }
606  break;
607  case 2:
608  if (src_alpha && dst_alpha) {
609  for (x = 0; x < width; x++) {
610  dst[0][x] = av_bswap16(*src_line++ >> shift);
611  dst[1][x] = av_bswap16(*src_line++ >> shift);
612  dst[2][x] = av_bswap16(*src_line++ >> shift);
613  dst[3][x] = av_bswap16(*src_line++ >> shift);
614  }
615  } else if (dst_alpha) {
616  for (x = 0; x < width; x++) {
617  dst[0][x] = av_bswap16(*src_line++ >> shift);
618  dst[1][x] = av_bswap16(*src_line++ >> shift);
619  dst[2][x] = av_bswap16(*src_line++ >> shift);
620  dst[3][x] = 0xFFFF;
621  }
622  } else if (src_alpha) {
623  for (x = 0; x < width; x++) {
624  dst[0][x] = av_bswap16(*src_line++ >> shift);
625  dst[1][x] = av_bswap16(*src_line++ >> shift);
626  dst[2][x] = av_bswap16(*src_line++ >> shift);
627  src_line++;
628  }
629  } else {
630  for (x = 0; x < width; x++) {
631  dst[0][x] = av_bswap16(*src_line++ >> shift);
632  dst[1][x] = av_bswap16(*src_line++ >> shift);
633  dst[2][x] = av_bswap16(*src_line++ >> shift);
634  }
635  }
636  break;
637  case 1:
638  if (src_alpha && dst_alpha) {
639  for (x = 0; x < width; x++) {
640  dst[0][x] = av_bswap16(*src_line++) >> shift;
641  dst[1][x] = av_bswap16(*src_line++) >> shift;
642  dst[2][x] = av_bswap16(*src_line++) >> shift;
643  dst[3][x] = av_bswap16(*src_line++) >> shift;
644  }
645  } else if (dst_alpha) {
646  for (x = 0; x < width; x++) {
647  dst[0][x] = av_bswap16(*src_line++) >> shift;
648  dst[1][x] = av_bswap16(*src_line++) >> shift;
649  dst[2][x] = av_bswap16(*src_line++) >> shift;
650  dst[3][x] = 0xFFFF;
651  }
652  } else if (src_alpha) {
653  for (x = 0; x < width; x++) {
654  dst[0][x] = av_bswap16(*src_line++) >> shift;
655  dst[1][x] = av_bswap16(*src_line++) >> shift;
656  dst[2][x] = av_bswap16(*src_line++) >> shift;
657  src_line++;
658  }
659  } else {
660  for (x = 0; x < width; x++) {
661  dst[0][x] = av_bswap16(*src_line++) >> shift;
662  dst[1][x] = av_bswap16(*src_line++) >> shift;
663  dst[2][x] = av_bswap16(*src_line++) >> shift;
664  }
665  }
666  break;
667  default:
668  if (src_alpha && dst_alpha) {
669  for (x = 0; x < width; x++) {
670  dst[0][x] = *src_line++ >> shift;
671  dst[1][x] = *src_line++ >> shift;
672  dst[2][x] = *src_line++ >> shift;
673  dst[3][x] = *src_line++ >> shift;
674  }
675  } else if (dst_alpha) {
676  for (x = 0; x < width; x++) {
677  dst[0][x] = *src_line++ >> shift;
678  dst[1][x] = *src_line++ >> shift;
679  dst[2][x] = *src_line++ >> shift;
680  dst[3][x] = 0xFFFF;
681  }
682  } else if (src_alpha) {
683  for (x = 0; x < width; x++) {
684  dst[0][x] = *src_line++ >> shift;
685  dst[1][x] = *src_line++ >> shift;
686  dst[2][x] = *src_line++ >> shift;
687  src_line++;
688  }
689  } else {
690  for (x = 0; x < width; x++) {
691  dst[0][x] = *src_line++ >> shift;
692  dst[1][x] = *src_line++ >> shift;
693  dst[2][x] = *src_line++ >> shift;
694  }
695  }
696  }
697  for (i = 0; i < 4; i++)
698  dst[i] += dstStride[i] >> 1;
699  }
700 }
701 
703  int srcStride[], int srcSliceY, int srcSliceH,
704  uint8_t *dst[], int dstStride[])
705 {
706  uint16_t *dst2013[] = { (uint16_t *)dst[2], (uint16_t *)dst[0], (uint16_t *)dst[1], (uint16_t *)dst[3] };
707  uint16_t *dst1023[] = { (uint16_t *)dst[1], (uint16_t *)dst[0], (uint16_t *)dst[2], (uint16_t *)dst[3] };
708  int stride2013[] = { dstStride[2], dstStride[0], dstStride[1], dstStride[3] };
709  int stride1023[] = { dstStride[1], dstStride[0], dstStride[2], dstStride[3] };
710  const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
711  const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
712  int bpc = dst_format->comp[0].depth;
713  int alpha = src_format->flags & AV_PIX_FMT_FLAG_ALPHA;
714  int swap = 0;
715  int i;
716 
717  if ( HAVE_BIGENDIAN && !(src_format->flags & AV_PIX_FMT_FLAG_BE) ||
718  !HAVE_BIGENDIAN && src_format->flags & AV_PIX_FMT_FLAG_BE)
719  swap++;
720  if ( HAVE_BIGENDIAN && !(dst_format->flags & AV_PIX_FMT_FLAG_BE) ||
721  !HAVE_BIGENDIAN && dst_format->flags & AV_PIX_FMT_FLAG_BE)
722  swap += 2;
723 
724  if ((dst_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) !=
726  av_log(c, AV_LOG_ERROR, "unsupported conversion to planar RGB %s -> %s\n",
727  src_format->name, dst_format->name);
728  return srcSliceH;
729  }
730 
731  for(i=0; i<4; i++) {
732  dst2013[i] += stride2013[i] * srcSliceY / 2;
733  dst1023[i] += stride1023[i] * srcSliceY / 2;
734  }
735 
736  switch (c->srcFormat) {
737  case AV_PIX_FMT_RGB48LE:
738  case AV_PIX_FMT_RGB48BE:
739  case AV_PIX_FMT_RGBA64LE:
740  case AV_PIX_FMT_RGBA64BE:
741  packed16togbra16(src[0], srcStride[0],
742  dst2013, stride2013, srcSliceH, alpha, swap,
743  16 - bpc, c->srcW);
744  break;
745  case AV_PIX_FMT_BGR48LE:
746  case AV_PIX_FMT_BGR48BE:
747  case AV_PIX_FMT_BGRA64LE:
748  case AV_PIX_FMT_BGRA64BE:
749  packed16togbra16(src[0], srcStride[0],
750  dst1023, stride1023, srcSliceH, alpha, swap,
751  16 - bpc, c->srcW);
752  break;
753  default:
754  av_log(c, AV_LOG_ERROR,
755  "unsupported conversion to planar RGB %s -> %s\n",
756  src_format->name, dst_format->name);
757  }
758 
759  return srcSliceH;
760 }
761 
762 static void gbr16ptopacked16(const uint16_t *src[], int srcStride[],
763  uint8_t *dst, int dstStride, int srcSliceH,
764  int alpha, int swap, int bpp, int width)
765 {
766  int x, h, i;
767  int src_alpha = src[3] != NULL;
768  int scale_high = 16 - bpp, scale_low = (bpp - 8) * 2;
769  for (h = 0; h < srcSliceH; h++) {
770  uint16_t *dest = (uint16_t *)(dst + dstStride * h);
771  uint16_t component;
772 
773  switch(swap) {
774  case 3:
775  if (alpha && !src_alpha) {
776  for (x = 0; x < width; x++) {
777  component = av_bswap16(src[0][x]);
778  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
779  component = av_bswap16(src[1][x]);
780  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
781  component = av_bswap16(src[2][x]);
782  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
783  *dest++ = 0xffff;
784  }
785  } else if (alpha && src_alpha) {
786  for (x = 0; x < width; x++) {
787  component = av_bswap16(src[0][x]);
788  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
789  component = av_bswap16(src[1][x]);
790  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
791  component = av_bswap16(src[2][x]);
792  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
793  component = av_bswap16(src[3][x]);
794  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
795  }
796  } else {
797  for (x = 0; x < width; x++) {
798  component = av_bswap16(src[0][x]);
799  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
800  component = av_bswap16(src[1][x]);
801  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
802  component = av_bswap16(src[2][x]);
803  *dest++ = av_bswap16(component << scale_high | component >> scale_low);
804  }
805  }
806  break;
807  case 2:
808  if (alpha && !src_alpha) {
809  for (x = 0; x < width; x++) {
810  *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
811  *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
812  *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
813  *dest++ = 0xffff;
814  }
815  } else if (alpha && src_alpha) {
816  for (x = 0; x < width; x++) {
817  *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
818  *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
819  *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
820  *dest++ = av_bswap16(src[3][x] << scale_high | src[3][x] >> scale_low);
821  }
822  } else {
823  for (x = 0; x < width; x++) {
824  *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
825  *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
826  *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
827  }
828  }
829  break;
830  case 1:
831  if (alpha && !src_alpha) {
832  for (x = 0; x < width; x++) {
833  *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
834  *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
835  *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
836  *dest++ = 0xffff;
837  }
838  } else if (alpha && src_alpha) {
839  for (x = 0; x < width; x++) {
840  *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
841  *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
842  *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
843  *dest++ = av_bswap16(src[3][x]) << scale_high | av_bswap16(src[3][x]) >> scale_low;
844  }
845  } else {
846  for (x = 0; x < width; x++) {
847  *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
848  *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
849  *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
850  }
851  }
852  break;
853  default:
854  if (alpha && !src_alpha) {
855  for (x = 0; x < width; x++) {
856  *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
857  *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
858  *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
859  *dest++ = 0xffff;
860  }
861  } else if (alpha && src_alpha) {
862  for (x = 0; x < width; x++) {
863  *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
864  *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
865  *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
866  *dest++ = src[3][x] << scale_high | src[3][x] >> scale_low;
867  }
868  } else {
869  for (x = 0; x < width; x++) {
870  *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
871  *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
872  *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
873  }
874  }
875  }
876  for (i = 0; i < 3 + src_alpha; i++)
877  src[i] += srcStride[i] >> 1;
878  }
879 }
880 
882  int srcStride[], int srcSliceY, int srcSliceH,
883  uint8_t *dst[], int dstStride[])
884 {
885  const uint16_t *src102[] = { (uint16_t *)src[1], (uint16_t *)src[0], (uint16_t *)src[2], (uint16_t *)src[3] };
886  const uint16_t *src201[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1], (uint16_t *)src[3] };
887  int stride102[] = { srcStride[1], srcStride[0], srcStride[2], srcStride[3] };
888  int stride201[] = { srcStride[2], srcStride[0], srcStride[1], srcStride[3] };
889  const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
890  const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
891  int bits_per_sample = src_format->comp[0].depth;
892  int swap = 0;
893  if ( HAVE_BIGENDIAN && !(src_format->flags & AV_PIX_FMT_FLAG_BE) ||
894  !HAVE_BIGENDIAN && src_format->flags & AV_PIX_FMT_FLAG_BE)
895  swap++;
896  if ( HAVE_BIGENDIAN && !(dst_format->flags & AV_PIX_FMT_FLAG_BE) ||
897  !HAVE_BIGENDIAN && dst_format->flags & AV_PIX_FMT_FLAG_BE)
898  swap += 2;
899 
900  if ((src_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) !=
902  bits_per_sample <= 8) {
903  av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
904  src_format->name, dst_format->name);
905  return srcSliceH;
906  }
907  switch (c->dstFormat) {
908  case AV_PIX_FMT_BGR48LE:
909  case AV_PIX_FMT_BGR48BE:
910  gbr16ptopacked16(src102, stride102,
911  dst[0] + srcSliceY * dstStride[0], dstStride[0],
912  srcSliceH, 0, swap, bits_per_sample, c->srcW);
913  break;
914  case AV_PIX_FMT_RGB48LE:
915  case AV_PIX_FMT_RGB48BE:
916  gbr16ptopacked16(src201, stride201,
917  dst[0] + srcSliceY * dstStride[0], dstStride[0],
918  srcSliceH, 0, swap, bits_per_sample, c->srcW);
919  break;
920  case AV_PIX_FMT_RGBA64LE:
921  case AV_PIX_FMT_RGBA64BE:
922  gbr16ptopacked16(src201, stride201,
923  dst[0] + srcSliceY * dstStride[0], dstStride[0],
924  srcSliceH, 1, swap, bits_per_sample, c->srcW);
925  break;
926  case AV_PIX_FMT_BGRA64LE:
927  case AV_PIX_FMT_BGRA64BE:
928  gbr16ptopacked16(src102, stride102,
929  dst[0] + srcSliceY * dstStride[0], dstStride[0],
930  srcSliceH, 1, swap, bits_per_sample, c->srcW);
931  break;
932  default:
933  av_log(c, AV_LOG_ERROR,
934  "unsupported planar RGB conversion %s -> %s\n",
935  src_format->name, dst_format->name);
936  }
937 
938  return srcSliceH;
939 }
940 
941 static void gbr24ptopacked24(const uint8_t *src[], int srcStride[],
942  uint8_t *dst, int dstStride, int srcSliceH,
943  int width)
944 {
945  int x, h, i;
946  for (h = 0; h < srcSliceH; h++) {
947  uint8_t *dest = dst + dstStride * h;
948  for (x = 0; x < width; x++) {
949  *dest++ = src[0][x];
950  *dest++ = src[1][x];
951  *dest++ = src[2][x];
952  }
953 
954  for (i = 0; i < 3; i++)
955  src[i] += srcStride[i];
956  }
957 }
958 
959 static void gbr24ptopacked32(const uint8_t *src[], int srcStride[],
960  uint8_t *dst, int dstStride, int srcSliceH,
961  int alpha_first, int width)
962 {
963  int x, h, i;
964  for (h = 0; h < srcSliceH; h++) {
965  uint8_t *dest = dst + dstStride * h;
966 
967  if (alpha_first) {
968  for (x = 0; x < width; x++) {
969  *dest++ = 0xff;
970  *dest++ = src[0][x];
971  *dest++ = src[1][x];
972  *dest++ = src[2][x];
973  }
974  } else {
975  for (x = 0; x < width; x++) {
976  *dest++ = src[0][x];
977  *dest++ = src[1][x];
978  *dest++ = src[2][x];
979  *dest++ = 0xff;
980  }
981  }
982 
983  for (i = 0; i < 3; i++)
984  src[i] += srcStride[i];
985  }
986 }
987 
988 static void gbraptopacked32(const uint8_t *src[], int srcStride[],
989  uint8_t *dst, int dstStride, int srcSliceH,
990  int alpha_first, int width)
991 {
992  int x, h, i;
993  for (h = 0; h < srcSliceH; h++) {
994  uint8_t *dest = dst + dstStride * h;
995 
996  if (alpha_first) {
997  for (x = 0; x < width; x++) {
998  *dest++ = src[3][x];
999  *dest++ = src[0][x];
1000  *dest++ = src[1][x];
1001  *dest++ = src[2][x];
1002  }
1003  } else {
1004  for (x = 0; x < width; x++) {
1005  *dest++ = src[0][x];
1006  *dest++ = src[1][x];
1007  *dest++ = src[2][x];
1008  *dest++ = src[3][x];
1009  }
1010  }
1011 
1012  for (i = 0; i < 4; i++)
1013  src[i] += srcStride[i];
1014  }
1015 }
1016 
1018  int srcStride[], int srcSliceY, int srcSliceH,
1019  uint8_t *dst[], int dstStride[])
1020 {
1021  int alpha_first = 0;
1022  const uint8_t *src102[] = { src[1], src[0], src[2], src[3] };
1023  const uint8_t *src201[] = { src[2], src[0], src[1], src[3] };
1024  int stride102[] = { srcStride[1], srcStride[0], srcStride[2], srcStride[3] };
1025  int stride201[] = { srcStride[2], srcStride[0], srcStride[1], srcStride[3] };
1026 
1027  if (c->srcFormat != AV_PIX_FMT_GBRAP) {
1028  av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
1031  return srcSliceH;
1032  }
1033 
1034  switch (c->dstFormat) {
1035  case AV_PIX_FMT_BGR24:
1036  gbr24ptopacked24(src102, stride102,
1037  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1038  srcSliceH, c->srcW);
1039  break;
1040 
1041  case AV_PIX_FMT_RGB24:
1042  gbr24ptopacked24(src201, stride201,
1043  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1044  srcSliceH, c->srcW);
1045  break;
1046 
1047  case AV_PIX_FMT_ARGB:
1048  alpha_first = 1;
1049  case AV_PIX_FMT_RGBA:
1050  gbraptopacked32(src201, stride201,
1051  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1052  srcSliceH, alpha_first, c->srcW);
1053  break;
1054 
1055  case AV_PIX_FMT_ABGR:
1056  alpha_first = 1;
1057  case AV_PIX_FMT_BGRA:
1058  gbraptopacked32(src102, stride102,
1059  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1060  srcSliceH, alpha_first, c->srcW);
1061  break;
1062 
1063  default:
1064  av_log(c, AV_LOG_ERROR,
1065  "unsupported planar RGB conversion %s -> %s\n",
1068  }
1069 
1070  return srcSliceH;
1071 }
1072 
1074  int srcStride[], int srcSliceY, int srcSliceH,
1075  uint8_t *dst[], int dstStride[])
1076 {
1077  int alpha_first = 0;
1078  const uint8_t *src102[] = { src[1], src[0], src[2] };
1079  const uint8_t *src201[] = { src[2], src[0], src[1] };
1080  int stride102[] = { srcStride[1], srcStride[0], srcStride[2] };
1081  int stride201[] = { srcStride[2], srcStride[0], srcStride[1] };
1082 
1083  if (c->srcFormat != AV_PIX_FMT_GBRP) {
1084  av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
1087  return srcSliceH;
1088  }
1089 
1090  switch (c->dstFormat) {
1091  case AV_PIX_FMT_BGR24:
1092  gbr24ptopacked24(src102, stride102,
1093  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1094  srcSliceH, c->srcW);
1095  break;
1096 
1097  case AV_PIX_FMT_RGB24:
1098  gbr24ptopacked24(src201, stride201,
1099  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1100  srcSliceH, c->srcW);
1101  break;
1102 
1103  case AV_PIX_FMT_ARGB:
1104  alpha_first = 1;
1105  case AV_PIX_FMT_RGBA:
1106  gbr24ptopacked32(src201, stride201,
1107  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1108  srcSliceH, alpha_first, c->srcW);
1109  break;
1110 
1111  case AV_PIX_FMT_ABGR:
1112  alpha_first = 1;
1113  case AV_PIX_FMT_BGRA:
1114  gbr24ptopacked32(src102, stride102,
1115  dst[0] + srcSliceY * dstStride[0], dstStride[0],
1116  srcSliceH, alpha_first, c->srcW);
1117  break;
1118 
1119  default:
1120  av_log(c, AV_LOG_ERROR,
1121  "unsupported planar RGB conversion %s -> %s\n",
1124  }
1125 
1126  return srcSliceH;
1127 }
1128 
1130  const uint8_t *src[], int srcStride[],
1131  int srcSliceY, int srcSliceH,
1132  uint8_t *dst[], int dstStride[])
1133 {
1134  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
1135  dst[0], dstStride[0]);
1136  copyPlane(src[1], srcStride[1], srcSliceY, srcSliceH, c->srcW,
1137  dst[1], dstStride[1]);
1138  copyPlane(src[2], srcStride[2], srcSliceY, srcSliceH, c->srcW,
1139  dst[2], dstStride[2]);
1140  if (dst[3])
1141  fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1142 
1143  return srcSliceH;
1144 }
1145 
1146 static void packedtogbr24p(const uint8_t *src, int srcStride,
1147  uint8_t *dst[], int dstStride[], int srcSliceH,
1148  int alpha_first, int inc_size, int width)
1149 {
1150  uint8_t *dest[3];
1151  int x, h;
1152 
1153  dest[0] = dst[0];
1154  dest[1] = dst[1];
1155  dest[2] = dst[2];
1156 
1157  if (alpha_first)
1158  src++;
1159 
1160  for (h = 0; h < srcSliceH; h++) {
1161  for (x = 0; x < width; x++) {
1162  dest[0][x] = src[0];
1163  dest[1][x] = src[1];
1164  dest[2][x] = src[2];
1165 
1166  src += inc_size;
1167  }
1168  src += srcStride - width * inc_size;
1169  dest[0] += dstStride[0];
1170  dest[1] += dstStride[1];
1171  dest[2] += dstStride[2];
1172  }
1173 }
1174 
1176  int srcStride[], int srcSliceY, int srcSliceH,
1177  uint8_t *dst[], int dstStride[])
1178 {
1179  int alpha_first = 0;
1180  int stride102[] = { dstStride[1], dstStride[0], dstStride[2] };
1181  int stride201[] = { dstStride[2], dstStride[0], dstStride[1] };
1182  uint8_t *dst102[] = { dst[1] + srcSliceY * dstStride[1],
1183  dst[0] + srcSliceY * dstStride[0],
1184  dst[2] + srcSliceY * dstStride[2] };
1185  uint8_t *dst201[] = { dst[2] + srcSliceY * dstStride[2],
1186  dst[0] + srcSliceY * dstStride[0],
1187  dst[1] + srcSliceY * dstStride[1] };
1188 
1189  switch (c->srcFormat) {
1190  case AV_PIX_FMT_RGB24:
1191  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
1192  stride201, srcSliceH, alpha_first, 3, c->srcW);
1193  break;
1194  case AV_PIX_FMT_BGR24:
1195  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
1196  stride102, srcSliceH, alpha_first, 3, c->srcW);
1197  break;
1198  case AV_PIX_FMT_ARGB:
1199  alpha_first = 1;
1200  case AV_PIX_FMT_RGBA:
1201  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
1202  stride201, srcSliceH, alpha_first, 4, c->srcW);
1203  break;
1204  case AV_PIX_FMT_ABGR:
1205  alpha_first = 1;
1206  case AV_PIX_FMT_BGRA:
1207  packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
1208  stride102, srcSliceH, alpha_first, 4, c->srcW);
1209  break;
1210  default:
1211  av_log(c, AV_LOG_ERROR,
1212  "unsupported planar RGB conversion %s -> %s\n",
1215  }
1216 
1217  return srcSliceH;
1218 }
1219 
1220 #define BAYER_GBRG
1221 #define BAYER_8
1222 #define BAYER_RENAME(x) bayer_gbrg8_to_##x
1223 #include "bayer_template.c"
1224 
1225 #define BAYER_GBRG
1226 #define BAYER_16LE
1227 #define BAYER_RENAME(x) bayer_gbrg16le_to_##x
1228 #include "bayer_template.c"
1229 
1230 #define BAYER_GBRG
1231 #define BAYER_16BE
1232 #define BAYER_RENAME(x) bayer_gbrg16be_to_##x
1233 #include "bayer_template.c"
1234 
1235 #define BAYER_GRBG
1236 #define BAYER_8
1237 #define BAYER_RENAME(x) bayer_grbg8_to_##x
1238 #include "bayer_template.c"
1239 
1240 #define BAYER_GRBG
1241 #define BAYER_16LE
1242 #define BAYER_RENAME(x) bayer_grbg16le_to_##x
1243 #include "bayer_template.c"
1244 
1245 #define BAYER_GRBG
1246 #define BAYER_16BE
1247 #define BAYER_RENAME(x) bayer_grbg16be_to_##x
1248 #include "bayer_template.c"
1249 
1250 #define BAYER_BGGR
1251 #define BAYER_8
1252 #define BAYER_RENAME(x) bayer_bggr8_to_##x
1253 #include "bayer_template.c"
1254 
1255 #define BAYER_BGGR
1256 #define BAYER_16LE
1257 #define BAYER_RENAME(x) bayer_bggr16le_to_##x
1258 #include "bayer_template.c"
1259 
1260 #define BAYER_BGGR
1261 #define BAYER_16BE
1262 #define BAYER_RENAME(x) bayer_bggr16be_to_##x
1263 #include "bayer_template.c"
1264 
1265 #define BAYER_RGGB
1266 #define BAYER_8
1267 #define BAYER_RENAME(x) bayer_rggb8_to_##x
1268 #include "bayer_template.c"
1269 
1270 #define BAYER_RGGB
1271 #define BAYER_16LE
1272 #define BAYER_RENAME(x) bayer_rggb16le_to_##x
1273 #include "bayer_template.c"
1274 
1275 #define BAYER_RGGB
1276 #define BAYER_16BE
1277 #define BAYER_RENAME(x) bayer_rggb16be_to_##x
1278 #include "bayer_template.c"
1279 
1280 static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1281  int srcSliceH, uint8_t* dst[], int dstStride[])
1282 {
1283  uint8_t *dstPtr= dst[0] + srcSliceY * dstStride[0];
1284  const uint8_t *srcPtr= src[0];
1285  int i;
1286  void (*copy) (const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
1287  void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
1288 
1289  switch(c->srcFormat) {
1290 #define CASE(pixfmt, prefix) \
1291  case pixfmt: copy = bayer_##prefix##_to_rgb24_copy; \
1292  interpolate = bayer_##prefix##_to_rgb24_interpolate; \
1293  break;
1295  CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le)
1296  CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be)
1298  CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le)
1299  CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be)
1301  CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le)
1302  CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be)
1304  CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le)
1305  CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be)
1306 #undef CASE
1307  default: return 0;
1308  }
1309 
1310  av_assert0(srcSliceH > 1);
1311 
1312  copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1313  srcPtr += 2 * srcStride[0];
1314  dstPtr += 2 * dstStride[0];
1315 
1316  for (i = 2; i < srcSliceH - 2; i += 2) {
1317  interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1318  srcPtr += 2 * srcStride[0];
1319  dstPtr += 2 * dstStride[0];
1320  }
1321 
1322  if (i + 1 == srcSliceH) {
1323  copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->srcW);
1324  } else if (i < srcSliceH)
1325  copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1326  return srcSliceH;
1327 }
1328 
1329 static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1330  int srcSliceH, uint8_t* dst[], int dstStride[])
1331 {
1332  const uint8_t *srcPtr= src[0];
1333  uint8_t *dstY= dst[0] + srcSliceY * dstStride[0];
1334  uint8_t *dstU= dst[1] + srcSliceY * dstStride[1] / 2;
1335  uint8_t *dstV= dst[2] + srcSliceY * dstStride[2] / 2;
1336  int i;
1337  void (*copy) (const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv);
1338  void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv);
1339 
1340  switch(c->srcFormat) {
1341 #define CASE(pixfmt, prefix) \
1342  case pixfmt: copy = bayer_##prefix##_to_yv12_copy; \
1343  interpolate = bayer_##prefix##_to_yv12_interpolate; \
1344  break;
1346  CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le)
1347  CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be)
1349  CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le)
1350  CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be)
1352  CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le)
1353  CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be)
1355  CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le)
1356  CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be)
1357 #undef CASE
1358  default: return 0;
1359  }
1360 
1361  av_assert0(srcSliceH > 1);
1362 
1363  copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1364  srcPtr += 2 * srcStride[0];
1365  dstY += 2 * dstStride[0];
1366  dstU += dstStride[1];
1367  dstV += dstStride[1];
1368 
1369  for (i = 2; i < srcSliceH - 2; i += 2) {
1370  interpolate(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1371  srcPtr += 2 * srcStride[0];
1372  dstY += 2 * dstStride[0];
1373  dstU += dstStride[1];
1374  dstV += dstStride[1];
1375  }
1376 
1377  if (i + 1 == srcSliceH) {
1378  copy(srcPtr, -srcStride[0], dstY, dstU, dstV, -dstStride[0], c->srcW, c->input_rgb2yuv_table);
1379  } else if (i < srcSliceH)
1380  copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1381  return srcSliceH;
1382 }
1383 
1384 #define isRGBA32(x) ( \
1385  (x) == AV_PIX_FMT_ARGB \
1386  || (x) == AV_PIX_FMT_RGBA \
1387  || (x) == AV_PIX_FMT_BGRA \
1388  || (x) == AV_PIX_FMT_ABGR \
1389  )
1390 
1391 #define isRGBA64(x) ( \
1392  (x) == AV_PIX_FMT_RGBA64LE \
1393  || (x) == AV_PIX_FMT_RGBA64BE \
1394  || (x) == AV_PIX_FMT_BGRA64LE \
1395  || (x) == AV_PIX_FMT_BGRA64BE \
1396  )
1397 
1398 #define isRGB48(x) ( \
1399  (x) == AV_PIX_FMT_RGB48LE \
1400  || (x) == AV_PIX_FMT_RGB48BE \
1401  || (x) == AV_PIX_FMT_BGR48LE \
1402  || (x) == AV_PIX_FMT_BGR48BE \
1403  )
1404 
1405 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1406 typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
1408 {
1409  const enum AVPixelFormat srcFormat = c->srcFormat;
1410  const enum AVPixelFormat dstFormat = c->dstFormat;
1411  const int srcId = c->srcFormatBpp;
1412  const int dstId = c->dstFormatBpp;
1413  rgbConvFn conv = NULL;
1414 
1415 #define IS_NOT_NE(bpp, desc) \
1416  (((bpp + 7) >> 3) == 2 && \
1417  (!(desc->flags & AV_PIX_FMT_FLAG_BE) != !HAVE_BIGENDIAN))
1418 
1419 #define CONV_IS(src, dst) (srcFormat == AV_PIX_FMT_##src && dstFormat == AV_PIX_FMT_##dst)
1420 
1421  if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
1422  if ( CONV_IS(ABGR, RGBA)
1423  || CONV_IS(ARGB, BGRA)
1424  || CONV_IS(BGRA, ARGB)
1425  || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
1426  else if (CONV_IS(ABGR, ARGB)
1427  || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
1428  else if (CONV_IS(ABGR, BGRA)
1429  || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
1430  else if (CONV_IS(BGRA, RGBA)
1431  || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
1432  else if (CONV_IS(BGRA, ABGR)
1433  || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
1434  } else if (isRGB48(srcFormat) && isRGB48(dstFormat)) {
1435  if (CONV_IS(RGB48LE, BGR48LE)
1436  || CONV_IS(BGR48LE, RGB48LE)
1437  || CONV_IS(RGB48BE, BGR48BE)
1438  || CONV_IS(BGR48BE, RGB48BE)) conv = rgb48tobgr48_nobswap;
1439  else if (CONV_IS(RGB48LE, BGR48BE)
1440  || CONV_IS(BGR48LE, RGB48BE)
1441  || CONV_IS(RGB48BE, BGR48LE)
1442  || CONV_IS(BGR48BE, RGB48LE)) conv = rgb48tobgr48_bswap;
1443  } else if (isRGB48(srcFormat) && isRGBA64(dstFormat)) {
1444  if (CONV_IS(RGB48LE, BGRA64LE)
1445  || CONV_IS(BGR48LE, RGBA64LE)
1446  || CONV_IS(RGB48BE, BGRA64BE)
1447  || CONV_IS(BGR48BE, RGBA64BE)) conv = rgb48tobgr64_nobswap;
1448  else if (CONV_IS(RGB48LE, BGRA64BE)
1449  || CONV_IS(BGR48LE, RGBA64BE)
1450  || CONV_IS(RGB48BE, BGRA64LE)
1451  || CONV_IS(BGR48BE, RGBA64LE)) conv = rgb48tobgr64_bswap;
1452  if (CONV_IS(RGB48LE, RGBA64LE)
1453  || CONV_IS(BGR48LE, BGRA64LE)
1454  || CONV_IS(RGB48BE, RGBA64BE)
1455  || CONV_IS(BGR48BE, BGRA64BE)) conv = rgb48to64_nobswap;
1456  else if (CONV_IS(RGB48LE, RGBA64BE)
1457  || CONV_IS(BGR48LE, BGRA64BE)
1458  || CONV_IS(RGB48BE, RGBA64LE)
1459  || CONV_IS(BGR48BE, BGRA64LE)) conv = rgb48to64_bswap;
1460  } else if (isRGBA64(srcFormat) && isRGB48(dstFormat)) {
1461  if (CONV_IS(RGBA64LE, BGR48LE)
1462  || CONV_IS(BGRA64LE, RGB48LE)
1463  || CONV_IS(RGBA64BE, BGR48BE)
1464  || CONV_IS(BGRA64BE, RGB48BE)) conv = rgb64tobgr48_nobswap;
1465  else if (CONV_IS(RGBA64LE, BGR48BE)
1466  || CONV_IS(BGRA64LE, RGB48BE)
1467  || CONV_IS(RGBA64BE, BGR48LE)
1468  || CONV_IS(BGRA64BE, RGB48LE)) conv = rgb64tobgr48_bswap;
1469  else if (CONV_IS(RGBA64LE, RGB48LE)
1470  || CONV_IS(BGRA64LE, BGR48LE)
1471  || CONV_IS(RGBA64BE, RGB48BE)
1472  || CONV_IS(BGRA64BE, BGR48BE)) conv = rgb64to48_nobswap;
1473  else if (CONV_IS(RGBA64LE, RGB48BE)
1474  || CONV_IS(BGRA64LE, BGR48BE)
1475  || CONV_IS(RGBA64BE, RGB48LE)
1476  || CONV_IS(BGRA64BE, BGR48LE)) conv = rgb64to48_bswap;
1477  } else
1478  /* BGR -> BGR */
1479  if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
1480  (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
1481  switch (srcId | (dstId << 16)) {
1482  case 0x000F000C: conv = rgb12to15; break;
1483  case 0x000F0010: conv = rgb16to15; break;
1484  case 0x000F0018: conv = rgb24to15; break;
1485  case 0x000F0020: conv = rgb32to15; break;
1486  case 0x0010000F: conv = rgb15to16; break;
1487  case 0x00100018: conv = rgb24to16; break;
1488  case 0x00100020: conv = rgb32to16; break;
1489  case 0x0018000F: conv = rgb15to24; break;
1490  case 0x00180010: conv = rgb16to24; break;
1491  case 0x00180020: conv = rgb32to24; break;
1492  case 0x0020000F: conv = rgb15to32; break;
1493  case 0x00200010: conv = rgb16to32; break;
1494  case 0x00200018: conv = rgb24to32; break;
1495  }
1496  } else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) ||
1497  (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
1498  switch (srcId | (dstId << 16)) {
1499  case 0x000C000C: conv = rgb12tobgr12; break;
1500  case 0x000F000F: conv = rgb15tobgr15; break;
1501  case 0x000F0010: conv = rgb16tobgr15; break;
1502  case 0x000F0018: conv = rgb24tobgr15; break;
1503  case 0x000F0020: conv = rgb32tobgr15; break;
1504  case 0x0010000F: conv = rgb15tobgr16; break;
1505  case 0x00100010: conv = rgb16tobgr16; break;
1506  case 0x00100018: conv = rgb24tobgr16; break;
1507  case 0x00100020: conv = rgb32tobgr16; break;
1508  case 0x0018000F: conv = rgb15tobgr24; break;
1509  case 0x00180010: conv = rgb16tobgr24; break;
1510  case 0x00180018: conv = rgb24tobgr24; break;
1511  case 0x00180020: conv = rgb32tobgr24; break;
1512  case 0x0020000F: conv = rgb15tobgr32; break;
1513  case 0x00200010: conv = rgb16tobgr32; break;
1514  case 0x00200018: conv = rgb24tobgr32; break;
1515  }
1516  }
1517 
1518  if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0)
1519  return NULL;
1520 
1521  // Maintain symmetry between endianness
1522  if (c->flags & SWS_BITEXACT)
1523  if ((dstFormat == AV_PIX_FMT_RGB32 || dstFormat == AV_PIX_FMT_BGR32 ) && !isRGBA32(srcFormat) && ALT32_CORR>0)
1524  return NULL;
1525 
1526  return conv;
1527 }
1528 
1529 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1530 static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
1531  int srcSliceY, int srcSliceH, uint8_t *dst[],
1532  int dstStride[])
1533 
1534 {
1535  const enum AVPixelFormat srcFormat = c->srcFormat;
1536  const enum AVPixelFormat dstFormat = c->dstFormat;
1537  const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1538  const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1539  const int srcBpp = (c->srcFormatBpp + 7) >> 3;
1540  const int dstBpp = (c->dstFormatBpp + 7) >> 3;
1542 
1543  if (!conv) {
1544  av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
1545  av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1546  } else {
1547  const uint8_t *srcPtr = src[0];
1548  uint8_t *dstPtr = dst[0];
1549  int src_bswap = IS_NOT_NE(c->srcFormatBpp, desc_src);
1550  int dst_bswap = IS_NOT_NE(c->dstFormatBpp, desc_dst);
1551 
1552  if ((srcFormat == AV_PIX_FMT_RGB32_1 || srcFormat == AV_PIX_FMT_BGR32_1) &&
1553  !isRGBA32(dstFormat))
1554  srcPtr += ALT32_CORR;
1555 
1556  if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) &&
1557  !isRGBA32(srcFormat)) {
1558  int i;
1559  av_assert0(ALT32_CORR == 1);
1560  for (i = 0; i < srcSliceH; i++)
1561  dstPtr[dstStride[0] * (srcSliceY + i)] = 255;
1562  dstPtr += ALT32_CORR;
1563  }
1564 
1565  if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
1566  !(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap)
1567  conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
1568  (srcSliceH - 1) * srcStride[0] + c->srcW * srcBpp);
1569  else {
1570  int i, j;
1571  dstPtr += dstStride[0] * srcSliceY;
1572 
1573  for (i = 0; i < srcSliceH; i++) {
1574  if(src_bswap) {
1575  for(j=0; j<c->srcW; j++)
1576  ((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]);
1577  conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp);
1578  }else
1579  conv(srcPtr, dstPtr, c->srcW * srcBpp);
1580  if(dst_bswap)
1581  for(j=0; j<c->srcW; j++)
1582  ((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]);
1583  srcPtr += srcStride[0];
1584  dstPtr += dstStride[0];
1585  }
1586  }
1587  }
1588  return srcSliceH;
1589 }
1590 
1592  int srcStride[], int srcSliceY, int srcSliceH,
1593  uint8_t *dst[], int dstStride[])
1594 {
1596  src[0],
1597  dst[0] + srcSliceY * dstStride[0],
1598  dst[1] + (srcSliceY >> 1) * dstStride[1],
1599  dst[2] + (srcSliceY >> 1) * dstStride[2],
1600  c->srcW, srcSliceH,
1601  dstStride[0], dstStride[1], srcStride[0],
1602  c->input_rgb2yuv_table);
1603  if (dst[3])
1604  fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1605  return srcSliceH;
1606 }
1607 
1608 static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
1609  int srcStride[], int srcSliceY, int srcSliceH,
1610  uint8_t *dst[], int dstStride[])
1611 {
1612  copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
1613  dst[0], dstStride[0]);
1614 
1615  planar2x(src[1], dst[1] + dstStride[1] * (srcSliceY >> 1), c->chrSrcW,
1616  srcSliceH >> 2, srcStride[1], dstStride[1]);
1617  planar2x(src[2], dst[2] + dstStride[2] * (srcSliceY >> 1), c->chrSrcW,
1618  srcSliceH >> 2, srcStride[2], dstStride[2]);
1619  if (dst[3])
1620  fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1621  return srcSliceH;
1622 }
1623 
1625  int srcStride[], int srcSliceY,
1626  int srcSliceH, uint8_t *dst[], int dstStride[])
1627 {
1628  int y, x;
1629  ptrdiff_t dstStrideFloat = dstStride[0] >> 2;
1630  const uint8_t *srcPtr = src[0];
1631  float *dstPtr = (float *)(dst[0] + dstStride[0] * srcSliceY);
1632 
1633  for (y = 0; y < srcSliceH; ++y){
1634  for (x = 0; x < c->srcW; ++x){
1635  dstPtr[x] = c->uint2float_lut[srcPtr[x]];
1636  }
1637  srcPtr += srcStride[0];
1638  dstPtr += dstStrideFloat;
1639  }
1640 
1641  return srcSliceH;
1642 }
1643 
1645  int srcStride[], int srcSliceY,
1646  int srcSliceH, uint8_t* dst[], int dstStride[])
1647 {
1648  int y, x;
1649  ptrdiff_t srcStrideFloat = srcStride[0] >> 2;
1650  const float *srcPtr = (const float *)src[0];
1651  uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
1652 
1653  for (y = 0; y < srcSliceH; ++y){
1654  for (x = 0; x < c->srcW; ++x){
1655  dstPtr[x] = av_clip_uint8(lrintf(255.0f * srcPtr[x]));
1656  }
1657  srcPtr += srcStrideFloat;
1658  dstPtr += dstStride[0];
1659  }
1660 
1661  return srcSliceH;
1662 }
1663 
1664 /* unscaled copy like stuff (assumes nearly identical formats) */
1665 static int packedCopyWrapper(SwsContext *c, const uint8_t *src[],
1666  int srcStride[], int srcSliceY, int srcSliceH,
1667  uint8_t *dst[], int dstStride[])
1668 {
1669  if (dstStride[0] == srcStride[0] && srcStride[0] > 0)
1670  memcpy(dst[0] + dstStride[0] * srcSliceY, src[0], srcSliceH * dstStride[0]);
1671  else {
1672  int i;
1673  const uint8_t *srcPtr = src[0];
1674  uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
1675  int length = 0;
1676 
1677  /* universal length finder */
1678  while (length + c->srcW <= FFABS(dstStride[0]) &&
1679  length + c->srcW <= FFABS(srcStride[0]))
1680  length += c->srcW;
1681  av_assert1(length != 0);
1682 
1683  for (i = 0; i < srcSliceH; i++) {
1684  memcpy(dstPtr, srcPtr, length);
1685  srcPtr += srcStride[0];
1686  dstPtr += dstStride[0];
1687  }
1688  }
1689  return srcSliceH;
1690 }
1691 
1692 #define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
1693  unsigned shift= src_depth-dst_depth, tmp;\
1694  if (c->dither == SWS_DITHER_NONE) {\
1695  for (i = 0; i < height; i++) {\
1696  for (j = 0; j < length-7; j+=8) {\
1697  dst[j+0] = dbswap(bswap(src[j+0])>>shift);\
1698  dst[j+1] = dbswap(bswap(src[j+1])>>shift);\
1699  dst[j+2] = dbswap(bswap(src[j+2])>>shift);\
1700  dst[j+3] = dbswap(bswap(src[j+3])>>shift);\
1701  dst[j+4] = dbswap(bswap(src[j+4])>>shift);\
1702  dst[j+5] = dbswap(bswap(src[j+5])>>shift);\
1703  dst[j+6] = dbswap(bswap(src[j+6])>>shift);\
1704  dst[j+7] = dbswap(bswap(src[j+7])>>shift);\
1705  }\
1706  for (; j < length; j++) {\
1707  dst[j] = dbswap(bswap(src[j])>>shift);\
1708  }\
1709  dst += dstStride;\
1710  src += srcStride;\
1711  }\
1712  } else if (shiftonly) {\
1713  for (i = 0; i < height; i++) {\
1714  const uint8_t *dither= dithers[shift-1][i&7];\
1715  for (j = 0; j < length-7; j+=8) {\
1716  tmp = (bswap(src[j+0]) + dither[0])>>shift; dst[j+0] = dbswap(tmp - (tmp>>dst_depth));\
1717  tmp = (bswap(src[j+1]) + dither[1])>>shift; dst[j+1] = dbswap(tmp - (tmp>>dst_depth));\
1718  tmp = (bswap(src[j+2]) + dither[2])>>shift; dst[j+2] = dbswap(tmp - (tmp>>dst_depth));\
1719  tmp = (bswap(src[j+3]) + dither[3])>>shift; dst[j+3] = dbswap(tmp - (tmp>>dst_depth));\
1720  tmp = (bswap(src[j+4]) + dither[4])>>shift; dst[j+4] = dbswap(tmp - (tmp>>dst_depth));\
1721  tmp = (bswap(src[j+5]) + dither[5])>>shift; dst[j+5] = dbswap(tmp - (tmp>>dst_depth));\
1722  tmp = (bswap(src[j+6]) + dither[6])>>shift; dst[j+6] = dbswap(tmp - (tmp>>dst_depth));\
1723  tmp = (bswap(src[j+7]) + dither[7])>>shift; dst[j+7] = dbswap(tmp - (tmp>>dst_depth));\
1724  }\
1725  for (; j < length; j++) {\
1726  tmp = (bswap(src[j]) + dither[j&7])>>shift; dst[j] = dbswap(tmp - (tmp>>dst_depth));\
1727  }\
1728  dst += dstStride;\
1729  src += srcStride;\
1730  }\
1731  } else {\
1732  for (i = 0; i < height; i++) {\
1733  const uint8_t *dither= dithers[shift-1][i&7];\
1734  for (j = 0; j < length-7; j+=8) {\
1735  tmp = bswap(src[j+0]); dst[j+0] = dbswap((tmp - (tmp>>dst_depth) + dither[0])>>shift);\
1736  tmp = bswap(src[j+1]); dst[j+1] = dbswap((tmp - (tmp>>dst_depth) + dither[1])>>shift);\
1737  tmp = bswap(src[j+2]); dst[j+2] = dbswap((tmp - (tmp>>dst_depth) + dither[2])>>shift);\
1738  tmp = bswap(src[j+3]); dst[j+3] = dbswap((tmp - (tmp>>dst_depth) + dither[3])>>shift);\
1739  tmp = bswap(src[j+4]); dst[j+4] = dbswap((tmp - (tmp>>dst_depth) + dither[4])>>shift);\
1740  tmp = bswap(src[j+5]); dst[j+5] = dbswap((tmp - (tmp>>dst_depth) + dither[5])>>shift);\
1741  tmp = bswap(src[j+6]); dst[j+6] = dbswap((tmp - (tmp>>dst_depth) + dither[6])>>shift);\
1742  tmp = bswap(src[j+7]); dst[j+7] = dbswap((tmp - (tmp>>dst_depth) + dither[7])>>shift);\
1743  }\
1744  for (; j < length; j++) {\
1745  tmp = bswap(src[j]); dst[j] = dbswap((tmp - (tmp>>dst_depth) + dither[j&7])>>shift);\
1746  }\
1747  dst += dstStride;\
1748  src += srcStride;\
1749  }\
1750  }
1751 
1752 static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
1753  int srcStride[], int srcSliceY, int srcSliceH,
1754  uint8_t *dst[], int dstStride[])
1755 {
1756  const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1757  const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1758  int plane, i, j;
1759  for (plane = 0; plane < 4; plane++) {
1760  int length = (plane == 0 || plane == 3) ? c->srcW : AV_CEIL_RSHIFT(c->srcW, c->chrDstHSubSample);
1761  int y = (plane == 0 || plane == 3) ? srcSliceY: AV_CEIL_RSHIFT(srcSliceY, c->chrDstVSubSample);
1762  int height = (plane == 0 || plane == 3) ? srcSliceH: AV_CEIL_RSHIFT(srcSliceH, c->chrDstVSubSample);
1763  const uint8_t *srcPtr = src[plane];
1764  uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
1765  int shiftonly = plane == 1 || plane == 2 || (!c->srcRange && plane == 0);
1766 
1767  if (!dst[plane])
1768  continue;
1769  // ignore palette for GRAY8
1770  if (plane == 1 && !dst[2]) continue;
1771  if (!src[plane] || (plane == 1 && !src[2])) {
1772  if (is16BPS(c->dstFormat) || isNBPS(c->dstFormat)) {
1773  fillPlane16(dst[plane], dstStride[plane], length, height, y,
1774  plane == 3, desc_dst->comp[plane].depth,
1775  isBE(c->dstFormat));
1776  } else {
1777  fillPlane(dst[plane], dstStride[plane], length, height, y,
1778  (plane == 3) ? 255 : 128);
1779  }
1780  } else {
1781  if(isNBPS(c->srcFormat) || isNBPS(c->dstFormat)
1782  || (is16BPS(c->srcFormat) != is16BPS(c->dstFormat))
1783  ) {
1784  const int src_depth = desc_src->comp[plane].depth;
1785  const int dst_depth = desc_dst->comp[plane].depth;
1786  const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
1787  uint16_t *dstPtr2 = (uint16_t*)dstPtr;
1788 
1789  if (dst_depth == 8) {
1790  if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1791  DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , )
1792  } else {
1793  DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, av_bswap16, )
1794  }
1795  } else if (src_depth == 8) {
1796  for (i = 0; i < height; i++) {
1797  #define COPY816(w)\
1798  if (shiftonly) {\
1799  for (j = 0; j < length; j++)\
1800  w(&dstPtr2[j], srcPtr[j]<<(dst_depth-8));\
1801  } else {\
1802  for (j = 0; j < length; j++)\
1803  w(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) |\
1804  (srcPtr[j]>>(2*8-dst_depth)));\
1805  }
1806  if(isBE(c->dstFormat)){
1807  COPY816(AV_WB16)
1808  } else {
1809  COPY816(AV_WL16)
1810  }
1811  dstPtr2 += dstStride[plane]/2;
1812  srcPtr += srcStride[plane];
1813  }
1814  } else if (src_depth <= dst_depth) {
1815  for (i = 0; i < height; i++) {
1816  j = 0;
1817  if(isBE(c->srcFormat) == HAVE_BIGENDIAN &&
1818  isBE(c->dstFormat) == HAVE_BIGENDIAN &&
1819  shiftonly) {
1820  unsigned shift = dst_depth - src_depth;
1821 #if HAVE_FAST_64BIT
1822 #define FAST_COPY_UP(shift) \
1823  for (; j < length - 3; j += 4) { \
1824  uint64_t v = AV_RN64A(srcPtr2 + j); \
1825  AV_WN64A(dstPtr2 + j, v << shift); \
1826  }
1827 #else
1828 #define FAST_COPY_UP(shift) \
1829  for (; j < length - 1; j += 2) { \
1830  uint32_t v = AV_RN32A(srcPtr2 + j); \
1831  AV_WN32A(dstPtr2 + j, v << shift); \
1832  }
1833 #endif
1834  switch (shift)
1835  {
1836  case 6: FAST_COPY_UP(6); break;
1837  case 7: FAST_COPY_UP(7); break;
1838  }
1839  }
1840 #define COPY_UP(r,w) \
1841  if(shiftonly){\
1842  for (; j < length; j++){ \
1843  unsigned int v= r(&srcPtr2[j]);\
1844  w(&dstPtr2[j], v<<(dst_depth-src_depth));\
1845  }\
1846  }else{\
1847  for (; j < length; j++){ \
1848  unsigned int v= r(&srcPtr2[j]);\
1849  w(&dstPtr2[j], (v<<(dst_depth-src_depth)) | \
1850  (v>>(2*src_depth-dst_depth)));\
1851  }\
1852  }
1853  if(isBE(c->srcFormat)){
1854  if(isBE(c->dstFormat)){
1856  } else {
1858  }
1859  } else {
1860  if(isBE(c->dstFormat)){
1862  } else {
1864  }
1865  }
1866  dstPtr2 += dstStride[plane]/2;
1867  srcPtr2 += srcStride[plane]/2;
1868  }
1869  } else {
1870  if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1871  if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1872  DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , )
1873  } else {
1874  DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , av_bswap16)
1875  }
1876  }else{
1877  if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1878  DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, )
1879  } else {
1880  DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, av_bswap16)
1881  }
1882  }
1883  }
1884  } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
1885  isBE(c->srcFormat) != isBE(c->dstFormat)) {
1886 
1887  for (i = 0; i < height; i++) {
1888  for (j = 0; j < length; j++)
1889  ((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);
1890  srcPtr += srcStride[plane];
1891  dstPtr += dstStride[plane];
1892  }
1893  } else if (isFloat(c->srcFormat) && isFloat(c->dstFormat) &&
1894  isBE(c->srcFormat) != isBE(c->dstFormat)) { /* swap float plane */
1895  for (i = 0; i < height; i++) {
1896  for (j = 0; j < length; j++)
1897  ((uint32_t *) dstPtr)[j] = av_bswap32(((const uint32_t *) srcPtr)[j]);
1898  srcPtr += srcStride[plane];
1899  dstPtr += dstStride[plane];
1900  }
1901  } else if (dstStride[plane] == srcStride[plane] &&
1902  srcStride[plane] > 0 && srcStride[plane] == length) {
1903  memcpy(dst[plane] + dstStride[plane] * y, src[plane],
1904  height * dstStride[plane]);
1905  } else {
1906  if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
1907  length *= 2;
1908  else if (desc_src->comp[0].depth == 1)
1909  length >>= 3; // monowhite/black
1910  for (i = 0; i < height; i++) {
1911  memcpy(dstPtr, srcPtr, length);
1912  srcPtr += srcStride[plane];
1913  dstPtr += dstStride[plane];
1914  }
1915  }
1916  }
1917  }
1918  return srcSliceH;
1919 }
1920 
1921 
1922 #define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt) \
1923  ((src_fmt == pix_fmt ## BE && dst_fmt == pix_fmt ## LE) || \
1924  (src_fmt == pix_fmt ## LE && dst_fmt == pix_fmt ## BE))
1925 
1926 
1928 {
1929  const enum AVPixelFormat srcFormat = c->srcFormat;
1930  const enum AVPixelFormat dstFormat = c->dstFormat;
1931  const int flags = c->flags;
1932  const int dstH = c->dstH;
1933  int needsDither;
1934 
1935  needsDither = isAnyRGB(dstFormat) &&
1936  c->dstFormatBpp < 24 &&
1937  (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
1938 
1939  /* yv12_to_nv12 */
1940  if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
1941  (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
1943  }
1944  /* yv24_to_nv24 */
1945  if ((srcFormat == AV_PIX_FMT_YUV444P || srcFormat == AV_PIX_FMT_YUVA444P) &&
1946  (dstFormat == AV_PIX_FMT_NV24 || dstFormat == AV_PIX_FMT_NV42)) {
1948  }
1949  /* nv12_to_yv12 */
1950  if (dstFormat == AV_PIX_FMT_YUV420P &&
1951  (srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
1953  }
1954  /* nv24_to_yv24 */
1955  if (dstFormat == AV_PIX_FMT_YUV444P &&
1956  (srcFormat == AV_PIX_FMT_NV24 || srcFormat == AV_PIX_FMT_NV42)) {
1958  }
1959  /* yuv2bgr */
1960  if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
1961  srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
1962  !(flags & SWS_ACCURATE_RND) && (c->dither == SWS_DITHER_BAYER || c->dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
1964  }
1965  /* yuv420p1x_to_p01x */
1966  if ((srcFormat == AV_PIX_FMT_YUV420P10 || srcFormat == AV_PIX_FMT_YUVA420P10 ||
1967  srcFormat == AV_PIX_FMT_YUV420P12 ||
1968  srcFormat == AV_PIX_FMT_YUV420P14 ||
1969  srcFormat == AV_PIX_FMT_YUV420P16 || srcFormat == AV_PIX_FMT_YUVA420P16) &&
1970  (dstFormat == AV_PIX_FMT_P010 || dstFormat == AV_PIX_FMT_P016)) {
1972  }
1973  /* yuv420p_to_p01xle */
1974  if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
1975  (dstFormat == AV_PIX_FMT_P010LE || dstFormat == AV_PIX_FMT_P016LE)) {
1977  }
1978 
1979  if (srcFormat == AV_PIX_FMT_YUV410P && !(dstH & 3) &&
1980  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1981  !(flags & SWS_BITEXACT)) {
1983  }
1984 
1985  /* bgr24toYV12 */
1986  if (srcFormat == AV_PIX_FMT_BGR24 &&
1987  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1988  !(flags & SWS_ACCURATE_RND))
1990 
1991  /* RGB/BGR -> RGB/BGR (no dither needed forms) */
1992  if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
1993  && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
1994  c->swscale = rgbToRgbWrapper;
1995 
1996  /* RGB to planar RGB */
1997  if ((srcFormat == AV_PIX_FMT_GBRP && dstFormat == AV_PIX_FMT_GBRAP) ||
1998  (srcFormat == AV_PIX_FMT_GBRAP && dstFormat == AV_PIX_FMT_GBRP))
2000 
2001 #define isByteRGB(f) ( \
2002  f == AV_PIX_FMT_RGB32 || \
2003  f == AV_PIX_FMT_RGB32_1 || \
2004  f == AV_PIX_FMT_RGB24 || \
2005  f == AV_PIX_FMT_BGR32 || \
2006  f == AV_PIX_FMT_BGR32_1 || \
2007  f == AV_PIX_FMT_BGR24)
2008 
2009  if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
2011 
2012  if (srcFormat == AV_PIX_FMT_GBRAP && isByteRGB(dstFormat))
2014 
2015  if ((srcFormat == AV_PIX_FMT_RGB48LE || srcFormat == AV_PIX_FMT_RGB48BE ||
2016  srcFormat == AV_PIX_FMT_BGR48LE || srcFormat == AV_PIX_FMT_BGR48BE ||
2017  srcFormat == AV_PIX_FMT_RGBA64LE || srcFormat == AV_PIX_FMT_RGBA64BE ||
2018  srcFormat == AV_PIX_FMT_BGRA64LE || srcFormat == AV_PIX_FMT_BGRA64BE) &&
2019  (dstFormat == AV_PIX_FMT_GBRP9LE || dstFormat == AV_PIX_FMT_GBRP9BE ||
2020  dstFormat == AV_PIX_FMT_GBRP10LE || dstFormat == AV_PIX_FMT_GBRP10BE ||
2021  dstFormat == AV_PIX_FMT_GBRP12LE || dstFormat == AV_PIX_FMT_GBRP12BE ||
2022  dstFormat == AV_PIX_FMT_GBRP14LE || dstFormat == AV_PIX_FMT_GBRP14BE ||
2023  dstFormat == AV_PIX_FMT_GBRP16LE || dstFormat == AV_PIX_FMT_GBRP16BE ||
2024  dstFormat == AV_PIX_FMT_GBRAP10LE || dstFormat == AV_PIX_FMT_GBRAP10BE ||
2025  dstFormat == AV_PIX_FMT_GBRAP12LE || dstFormat == AV_PIX_FMT_GBRAP12BE ||
2026  dstFormat == AV_PIX_FMT_GBRAP16LE || dstFormat == AV_PIX_FMT_GBRAP16BE ))
2028 
2029  if ((srcFormat == AV_PIX_FMT_GBRP9LE || srcFormat == AV_PIX_FMT_GBRP9BE ||
2030  srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
2031  srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
2032  srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
2033  srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE ||
2034  srcFormat == AV_PIX_FMT_GBRAP10LE || srcFormat == AV_PIX_FMT_GBRAP10BE ||
2035  srcFormat == AV_PIX_FMT_GBRAP12LE || srcFormat == AV_PIX_FMT_GBRAP12BE ||
2036  srcFormat == AV_PIX_FMT_GBRAP16LE || srcFormat == AV_PIX_FMT_GBRAP16BE) &&
2037  (dstFormat == AV_PIX_FMT_RGB48LE || dstFormat == AV_PIX_FMT_RGB48BE ||
2038  dstFormat == AV_PIX_FMT_BGR48LE || dstFormat == AV_PIX_FMT_BGR48BE ||
2039  dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
2040  dstFormat == AV_PIX_FMT_BGRA64LE || dstFormat == AV_PIX_FMT_BGRA64BE))
2042 
2043  if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth == 8 &&
2044  isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
2046 
2047  if (isBayer(srcFormat)) {
2048  if (dstFormat == AV_PIX_FMT_RGB24)
2050  else if (dstFormat == AV_PIX_FMT_YUV420P)
2052  else if (!isBayer(dstFormat)) {
2053  av_log(c, AV_LOG_ERROR, "unsupported bayer conversion\n");
2054  av_assert0(0);
2055  }
2056  }
2057 
2058  /* bswap 16 bits per pixel/component packed formats */
2059  if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_BGGR16) ||
2060  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_RGGB16) ||
2061  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GBRG16) ||
2062  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GRBG16) ||
2063  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) ||
2064  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR48) ||
2065  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) ||
2066  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) ||
2067  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
2068  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY9) ||
2069  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY10) ||
2070  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY12) ||
2071  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY14) ||
2072  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) ||
2073  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YA16) ||
2074  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_AYUV64) ||
2075  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP9) ||
2076  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP10) ||
2077  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP12) ||
2078  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP14) ||
2079  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP16) ||
2080  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP10) ||
2081  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP12) ||
2082  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP16) ||
2083  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) ||
2084  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48) ||
2085  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) ||
2086  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) ||
2087  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
2088  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12) ||
2089  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P9) ||
2090  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P10) ||
2091  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P12) ||
2092  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P14) ||
2093  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P16) ||
2094  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P9) ||
2095  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P10) ||
2096  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P12) ||
2097  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P14) ||
2098  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P16) ||
2099  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV440P10) ||
2100  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV440P12) ||
2101  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P9) ||
2102  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P10) ||
2103  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P12) ||
2104  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P14) ||
2105  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P16))
2106  c->swscale = bswap_16bpc;
2107 
2108  /* bswap 32 bits per pixel/component formats */
2109  if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRPF32) ||
2110  IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAPF32))
2111  c->swscale = bswap_32bpc;
2112 
2113  if (usePal(srcFormat) && isByteRGB(dstFormat))
2114  c->swscale = palToRgbWrapper;
2115 
2116  if (srcFormat == AV_PIX_FMT_YUV422P) {
2117  if (dstFormat == AV_PIX_FMT_YUYV422)
2119  else if (dstFormat == AV_PIX_FMT_UYVY422)
2121  }
2122 
2123  /* uint Y to float Y */
2124  if (srcFormat == AV_PIX_FMT_GRAY8 && dstFormat == AV_PIX_FMT_GRAYF32){
2126  }
2127 
2128  /* float Y to uint Y */
2129  if (srcFormat == AV_PIX_FMT_GRAYF32 && dstFormat == AV_PIX_FMT_GRAY8){
2131  }
2132 
2133  /* LQ converters if -sws 0 or -sws 4*/
2134  if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
2135  /* yv12_to_yuy2 */
2136  if (srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) {
2137  if (dstFormat == AV_PIX_FMT_YUYV422)
2139  else if (dstFormat == AV_PIX_FMT_UYVY422)
2141  }
2142  }
2143  if (srcFormat == AV_PIX_FMT_YUYV422 &&
2144  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
2146  if (srcFormat == AV_PIX_FMT_UYVY422 &&
2147  (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
2149  if (srcFormat == AV_PIX_FMT_YUYV422 && dstFormat == AV_PIX_FMT_YUV422P)
2151  if (srcFormat == AV_PIX_FMT_UYVY422 && dstFormat == AV_PIX_FMT_YUV422P)
2153 
2154 #define isPlanarGray(x) (isGray(x) && (x) != AV_PIX_FMT_YA8 && (x) != AV_PIX_FMT_YA16LE && (x) != AV_PIX_FMT_YA16BE)
2155  /* simple copy */
2156  if ( srcFormat == dstFormat ||
2157  (srcFormat == AV_PIX_FMT_YUVA420P && dstFormat == AV_PIX_FMT_YUV420P) ||
2158  (srcFormat == AV_PIX_FMT_YUV420P && dstFormat == AV_PIX_FMT_YUVA420P) ||
2159  (isFloat(srcFormat) == isFloat(dstFormat)) && ((isPlanarYUV(srcFormat) && isPlanarGray(dstFormat)) ||
2160  (isPlanarYUV(dstFormat) && isPlanarGray(srcFormat)) ||
2161  (isPlanarGray(dstFormat) && isPlanarGray(srcFormat)) ||
2162  (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) &&
2165  !isSemiPlanarYUV(srcFormat) && !isSemiPlanarYUV(dstFormat))))
2166  {
2167  if (isPacked(c->srcFormat))
2169  else /* Planar YUV or gray */
2171  }
2172 
2173  if (ARCH_PPC)
2175  if (ARCH_ARM)
2177  if (ARCH_AARCH64)
2179 }
2180 
2181 /* Convert the palette to the same packed 32-bit format as the palette */
2183  int num_pixels, const uint8_t *palette)
2184 {
2185  int i;
2186 
2187  for (i = 0; i < num_pixels; i++)
2188  ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
2189 }
2190 
2191 /* Palette format: ABCD -> dst format: ABC */
2193  int num_pixels, const uint8_t *palette)
2194 {
2195  int i;
2196 
2197  for (i = 0; i < num_pixels; i++) {
2198  //FIXME slow?
2199  dst[0] = palette[src[i] * 4 + 0];
2200  dst[1] = palette[src[i] * 4 + 1];
2201  dst[2] = palette[src[i] * 4 + 2];
2202  dst += 3;
2203  }
2204 }
#define IS_NOT_NE(bpp, desc)
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:61
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:81
planar GBR 4:4:4:4 40bpp, little-endian
Definition: pixfmt.h:291
void(* rgb15to32)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:52
#define NULL
Definition: coverity.c:32
static av_always_inline int isAnyRGB(enum AVPixelFormat pix_fmt)
static int shift(int a, int b)
Definition: sonic.c:82
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:401
static void copy(const float *p1, float *p2, const int length)
#define COPY816(w)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
#define isPlanarGray(x)
static void gbraptopacked32(const uint8_t *src[], int srcStride[], uint8_t *dst, int dstStride, int srcSliceH, int alpha_first, int width)
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.
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:436
static int conv(int samples, float **pcm, char *buf, int channels)
Definition: libvorbisdec.c:131
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.
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:409
8 bits gray, 8 bits alpha
Definition: pixfmt.h:143
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:419
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:208
void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:184
uint32_t pal_rgb[256]
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:316
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
static void packed16togbra16(const uint8_t *src, int srcStride, uint16_t *dst[], int dstStride[], int srcSliceH, int src_alpha, int swap, int shift, int width)
void(* shuffle_bytes_3012)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:57
return srcSliceH
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:389
bayer, GBGB..(odd line), RGRG..(even line), 8-bit samples
Definition: pixfmt.h:262
bayer, GRGR..(odd line), BGBG..(even line), 8-bit samples
Definition: pixfmt.h:263
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
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:207
void rgb16tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:239
void(* rgb32tobgr16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:36
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:415
bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian
Definition: pixfmt.h:270
static void gbr24ptopacked32(const uint8_t *src[], int srcStride[], uint8_t *dst, int dstStride, int srcSliceH, int alpha_first, int width)
#define av_bswap16
Definition: bswap.h:31
int dstFormatBpp
Number of bits per pixel of the destination pixel format.
void rgb48tobgr64_bswap(const uint8_t *src, uint8_t *dst, int src_size)
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:394
static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
Convenience header that includes libavutil&#39;s core.
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:379
#define isRGBA32(x)
planar GBR 4:4:4 36bpp, little-endian
Definition: pixfmt.h:255
static void gbr24ptopacked24(const uint8_t *src[], int srcStride[], uint8_t *dst, int dstStride, int srcSliceH, int width)
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:403
#define RGBA(r, g, b, a)
Definition: dvbsubdec.c:39
int srcRange
0 = MPG YUV range, 1 = JPG YUV range (source image).
bayer, BGBG..(odd line), GRGR..(even line), 8-bit samples
Definition: pixfmt.h:260
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:87
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:388
#define CASE(pixfmt, prefix)
int dstY
Last destination vertical line output from last slice.
planar GBR 4:4:4 36bpp, big-endian
Definition: pixfmt.h:254
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
void(* rgb16tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:42
void rgb48tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size)
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:380
#define AV_PIX_FMT_P016
Definition: pixfmt.h:449
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:381
static int planarToNv24Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
void(* rgb24tobgr16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:40
#define AV_PIX_FMT_P010
Definition: pixfmt.h:448
planar GBRA 4:4:4:4 64bpp, big-endian
Definition: pixfmt.h:216
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
void(* shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:55
void(* rgb32to16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:45
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
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:117
uint8_t
#define isByteRGB(f)
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:177
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:65
static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
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:103
#define f(width, name)
Definition: cbs_vp9.c:255
bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian
Definition: pixfmt.h:268
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian
Definition: pixfmt.h:269
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:205
void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:225
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:414
void(* shuffle_bytes_3210)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:58
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
static void interpolate(float *out, float v1, float v2, int size)
Definition: twinvq.c:84
#define SWS_FAST_BILINEAR
Definition: swscale.h:58
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
Definition: mem.h:112
#define height
static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
planar GBR 4:4:4 48bpp, big-endian
Definition: pixfmt.h:174
static int planarRgbToplanarRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:390
#define lrintf(x)
Definition: libm_mips.h:70
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
external API header
enum AVPixelFormat dstFormat
Destination pixel format.
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:404
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:441
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, little-endian
Definition: pixfmt.h:264
int chrSrcHSubSample
Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in source imag...
#define AV_PIX_FMT_BAYER_GRBG16
Definition: pixfmt.h:426
#define av_log(a,...)
float uint2float_lut[256]
#define COPY_UP(r, w)
const char * name
Definition: pixdesc.h:82
void rgb48to64_bswap(const uint8_t *src, uint8_t *dst, int src_size)
int dstH
Height of destination luma/alpha planes.
#define src
Definition: vp8dsp.c:254
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[])
planar GBR 4:4:4 27bpp, big-endian
Definition: pixfmt.h:170
void rgb64to48_nobswap(const uint8_t *src, uint8_t *dst, int src_size)
#define CONV_IS(src, dst)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
#define AV_PIX_FMT_BGR32_1
Definition: pixfmt.h:375
static int planarToNv12Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static rgbConvFn findRgbConvFn(SwsContext *c)
static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
#define output_pixel(p, v)
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
#define FAST_COPY_UP(shift)
static int planarRgb16ToRgb16Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
void(* shuffle_bytes_1230)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:56
#define AV_PIX_FMT_YA16
Definition: pixfmt.h:384
void(* rgbConvFn)(const uint8_t *, uint8_t *, int)
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:420
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:385
simple assert() macros that are a bit more flexible than ISO C assert().
GLsizei GLsizei * length
Definition: opengl_enc.c:114
like NV12, with 16bpp per component, little-endian
Definition: pixfmt.h:300
static void fillPlane(uint8_t *plane, int stride, int width, int height, int y, uint8_t val)
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
void(* rgb15tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:43
void(* rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:37
static av_always_inline int isSemiPlanarYUV(enum AVPixelFormat pix_fmt)
void(* ff_rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, int width, int height, int lumStride, int chromStride, int srcStride, int32_t *rgb2yuv)
Height should be a multiple of 2 and width should be a multiple of 2.
Definition: rgb2rgb.c:81
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
static const uint8_t dithers[8][8][8]
static int planarToP01xWrapper(SwsContext *c, const uint8_t *src8[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam8[], int dstStride[])
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:421
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:93
void(* rgb24to16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:47
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
static int planarRgbaToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
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[])
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:348
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:397
void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:295
as above, but U and V bytes are swapped
Definition: pixfmt.h:90
planar GBR 4:4:4:4 48bpp, big-endian
Definition: pixfmt.h:287
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:88
planar GBR 4:4:4:4 40bpp, big-endian
Definition: pixfmt.h:290
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:418
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
#define FFMIN(a, b)
Definition: common.h:96
uint8_t * formatConvBuffer
#define width
static av_always_inline int isBayer(enum AVPixelFormat pix_fmt)
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
#define isRGBA64(x)
void rgb64tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size)
int32_t
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:69
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:206
void rgb64tobgr48_bswap(const uint8_t *src, uint8_t *dst, int src_size)
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian
Definition: pixfmt.h:284
#define AV_PIX_FMT_BAYER_BGGR16
Definition: pixfmt.h:423
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:398
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
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:417
void(* rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:38
void ff_get_unscaled_swscale_aarch64(SwsContext *c)
static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:83
planar GBR 4:4:4:4 48bpp, little-endian
Definition: pixfmt.h:288
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:410
#define AV_PIX_FMT_BGR555
Definition: pixfmt.h:392
#define AV_PIX_FMT_BAYER_GBRG16
Definition: pixfmt.h:425
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:374
static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
void(* rgb16to15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:50
#define av_bswap32
Definition: bswap.h:33
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:407
void rgb48to64_nobswap(const uint8_t *src, uint8_t *dst, int src_size)
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:91
#define AV_PIX_FMT_GRAYF32
Definition: pixfmt.h:431
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:110
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
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:81
static int planar8ToP01xleWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam8[], int dstStride[])
#define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt)
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:382
static const int16_t alpha[]
Definition: ilbcdata.h:55
bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian
Definition: pixfmt.h:267
planar GBR 4:4:4 30bpp, big-endian
Definition: pixfmt.h:172
bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian
Definition: pixfmt.h:271
static int uint_y_to_float_y_wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:372
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:67
planar GBR 4:4:4 42bpp, little-endian
Definition: pixfmt.h:257
static void gbr16ptopacked16(const uint16_t *src[], int srcStride[], uint8_t *dst, int dstStride, int srcSliceH, int alpha, int swap, int bpp, int width)
void rgb32to24(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:146
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
#define AV_PIX_FMT_XYZ12
Definition: pixfmt.h:445
static av_always_inline int isRGBinInt(enum AVPixelFormat pix_fmt)
as above, but U and V bytes are swapped
Definition: pixfmt.h:349
static int float_y_to_uint_y_wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
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:73
SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
Definition: yuv2rgb.c:679
#define SWS_ACCURATE_RND
Definition: swscale.h:83
byte swapping routines
static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
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:107
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:405
planar GBR 4:4:4 42bpp, big-endian
Definition: pixfmt.h:256
static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:396
void(* rgb24to15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:48
void rgb24to32(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:164
#define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)
#define SWS_POINT
Definition: swscale.h:62
bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian
Definition: pixfmt.h:265
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:104
static void fillPlane16(uint8_t *plane, int stride, int width, int height, int y, int alpha, int bits, const int big_endian)
int shift
Number of least significant bits that must be shifted away to get the value.
Definition: pixdesc.h:53
static int Rgb16ToPlanarRgb16Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
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:391
uint16_t * dstV
Definition: input.c:402
#define AV_PIX_FMT_AYUV64
Definition: pixfmt.h:447
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:408
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:416
void(* shuffle_bytes_0321)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:54
#define flags(name, subs,...)
Definition: cbs_av1.c:560
static int bswap_16bpc(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
void(* rgb16to32)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:49
#define SWS_BITEXACT
Definition: swscale.h:84
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian
Definition: pixfmt.h:266
void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:305
void ff_get_unscaled_swscale_arm(SwsContext *c)
#define AV_PIX_FMT_BAYER_RGGB16
Definition: pixfmt.h:424
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:428
SwsDither dither
void(* rgb24tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:39
void(* rgb24tobgr15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:41
int
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
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:66
Y , 8bpp.
Definition: pixfmt.h:74
#define AV_PIX_FMT_GBRAPF32
Definition: pixfmt.h:429
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
planar GBR 4:4:4 27bpp, little-endian
Definition: pixfmt.h:171
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:102
#define AV_PIX_FMT_BGR444
Definition: pixfmt.h:393
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
enum AVPixelFormat srcFormat
Source pixel format.
bayer, RGRG..(odd line), GBGB..(even line), 8-bit samples
Definition: pixfmt.h:261
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:387
void rgb48tobgr48_bswap(const uint8_t *src, uint8_t *dst, int src_size)
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:128
static void copyPlane(const uint8_t *src, int srcStride, int srcSliceY, int srcSliceH, int width, uint8_t *dst, int dstStride)
SwsFunc swscale
Note that src, dst, srcStride, dstStride will be copied in the sws_scale() wrapper so they can be fre...
static int bswap_32bpc(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static int planarToUyvyWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
void(* rgb32to15)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:46
#define AV_PIX_FMT_RGB32_1
Definition: pixfmt.h:373
static int nv24ToPlanarWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
void rgb15tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:259
static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dstParam[], int dstStride[])
static av_always_inline int isBGRinInt(enum AVPixelFormat pix_fmt)
int srcFormatBpp
Number of bits per pixel of the source pixel format.
void rgb48tobgr64_nobswap(const uint8_t *src, uint8_t *dst, int src_size)
void(* planar2x)(const uint8_t *src, uint8_t *dst, int width, int height, int srcStride, int dstStride)
Definition: rgb2rgb.c:86
void rgb64to48_bswap(const uint8_t *src, uint8_t *dst, int src_size)
void(* rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:35
av_cold void ff_get_unscaled_swscale_ppc(SwsContext *c)
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:386
static av_always_inline int isPackedRGB(enum AVPixelFormat pix_fmt)
int32_t input_rgb2yuv_table[16+40 *4]
RGB2YUV_SHIFT RGB2YUV_SHIFT RGB2YUV_SHIFT RGB2YUV_SHIFT RGB2YUV_SHIFT RGB2YUV_SHIFT RGB2YUV_SHIFT RGB2YUV_SHIFT uint8_t const uint8_t const uint8_t const uint8_t int uint32_t * rgb2yuv
Definition: input.c:400
planar GBR 4:4:4 48bpp, little-endian
Definition: pixfmt.h:175
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:2489
#define stride
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.
static av_always_inline int isFloat(enum AVPixelFormat pix_fmt)
int depth
Number of bits in the component.
Definition: pixdesc.h:58
#define isRGB48(x)
planar GBRA 4:4:4:4 64bpp, little-endian
Definition: pixfmt.h:217
int srcW
Width of source luma/alpha planes.
void rgb16tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:249
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...
static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
static double val(void *priv, double ch)
Definition: aeval.c:76
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:144
void(* rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:51
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:411
static av_always_inline int isNBPS(enum AVPixelFormat pix_fmt)
int i
Definition: input.c:406
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:113
planar GBR 4:4:4 30bpp, little-endian
Definition: pixfmt.h:173
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:206
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size)
Definition: rgb2rgb.c:281