Merge commit '2268db2cd052674fde55c7d48b7a5098ce89b4ba'
[ffmpeg.git] / libswscale / swscale_unscaled.c
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
37 DECLARE_ALIGNED(8, static const uint8_t, dithers)[8][8][8]={
38 {
39   {   0,  1,  0,  1,  0,  1,  0,  1,},
40   {   1,  0,  1,  0,  1,  0,  1,  0,},
41   {   0,  1,  0,  1,  0,  1,  0,  1,},
42   {   1,  0,  1,  0,  1,  0,  1,  0,},
43   {   0,  1,  0,  1,  0,  1,  0,  1,},
44   {   1,  0,  1,  0,  1,  0,  1,  0,},
45   {   0,  1,  0,  1,  0,  1,  0,  1,},
46   {   1,  0,  1,  0,  1,  0,  1,  0,},
47 },{
48   {   1,  2,  1,  2,  1,  2,  1,  2,},
49   {   3,  0,  3,  0,  3,  0,  3,  0,},
50   {   1,  2,  1,  2,  1,  2,  1,  2,},
51   {   3,  0,  3,  0,  3,  0,  3,  0,},
52   {   1,  2,  1,  2,  1,  2,  1,  2,},
53   {   3,  0,  3,  0,  3,  0,  3,  0,},
54   {   1,  2,  1,  2,  1,  2,  1,  2,},
55   {   3,  0,  3,  0,  3,  0,  3,  0,},
56 },{
57   {   2,  4,  3,  5,  2,  4,  3,  5,},
58   {   6,  0,  7,  1,  6,  0,  7,  1,},
59   {   3,  5,  2,  4,  3,  5,  2,  4,},
60   {   7,  1,  6,  0,  7,  1,  6,  0,},
61   {   2,  4,  3,  5,  2,  4,  3,  5,},
62   {   6,  0,  7,  1,  6,  0,  7,  1,},
63   {   3,  5,  2,  4,  3,  5,  2,  4,},
64   {   7,  1,  6,  0,  7,  1,  6,  0,},
65 },{
66   {   4,  8,  7, 11,  4,  8,  7, 11,},
67   {  12,  0, 15,  3, 12,  0, 15,  3,},
68   {   6, 10,  5,  9,  6, 10,  5,  9,},
69   {  14,  2, 13,  1, 14,  2, 13,  1,},
70   {   4,  8,  7, 11,  4,  8,  7, 11,},
71   {  12,  0, 15,  3, 12,  0, 15,  3,},
72   {   6, 10,  5,  9,  6, 10,  5,  9,},
73   {  14,  2, 13,  1, 14,  2, 13,  1,},
74 },{
75   {   9, 17, 15, 23,  8, 16, 14, 22,},
76   {  25,  1, 31,  7, 24,  0, 30,  6,},
77   {  13, 21, 11, 19, 12, 20, 10, 18,},
78   {  29,  5, 27,  3, 28,  4, 26,  2,},
79   {   8, 16, 14, 22,  9, 17, 15, 23,},
80   {  24,  0, 30,  6, 25,  1, 31,  7,},
81   {  12, 20, 10, 18, 13, 21, 11, 19,},
82   {  28,  4, 26,  2, 29,  5, 27,  3,},
83 },{
84   {  18, 34, 30, 46, 17, 33, 29, 45,},
85   {  50,  2, 62, 14, 49,  1, 61, 13,},
86   {  26, 42, 22, 38, 25, 41, 21, 37,},
87   {  58, 10, 54,  6, 57,  9, 53,  5,},
88   {  16, 32, 28, 44, 19, 35, 31, 47,},
89   {  48,  0, 60, 12, 51,  3, 63, 15,},
90   {  24, 40, 20, 36, 27, 43, 23, 39,},
91   {  56,  8, 52,  4, 59, 11, 55,  7,},
92 },{
93   {  18, 34, 30, 46, 17, 33, 29, 45,},
94   {  50,  2, 62, 14, 49,  1, 61, 13,},
95   {  26, 42, 22, 38, 25, 41, 21, 37,},
96   {  58, 10, 54,  6, 57,  9, 53,  5,},
97   {  16, 32, 28, 44, 19, 35, 31, 47,},
98   {  48,  0, 60, 12, 51,  3, 63, 15,},
99   {  24, 40, 20, 36, 27, 43, 23, 39,},
100   {  56,  8, 52,  4, 59, 11, 55,  7,},
101 },{
102   {  36, 68, 60, 92, 34, 66, 58, 90,},
103   { 100,  4,124, 28, 98,  2,122, 26,},
104   {  52, 84, 44, 76, 50, 82, 42, 74,},
105   { 116, 20,108, 12,114, 18,106, 10,},
106   {  32, 64, 56, 88, 38, 70, 62, 94,},
107   {  96,  0,120, 24,102,  6,126, 30,},
108   {  48, 80, 40, 72, 54, 86, 46, 78,},
109   { 112, 16,104,  8,118, 22,110, 14,},
110 }};
111
112 static const uint16_t dither_scale[15][16]={
113 {    2,    3,    3,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,},
114 {    2,    3,    7,    7,   13,   13,   25,   25,   25,   25,   25,   25,   25,   25,   25,   25,},
115 {    3,    3,    4,   15,   15,   29,   57,   57,   57,  113,  113,  113,  113,  113,  113,  113,},
116 {    3,    4,    4,    5,   31,   31,   61,  121,  241,  241,  241,  241,  481,  481,  481,  481,},
117 {    3,    4,    5,    5,    6,   63,   63,  125,  249,  497,  993,  993,  993,  993,  993, 1985,},
118 {    3,    5,    6,    6,    6,    7,  127,  127,  253,  505, 1009, 2017, 4033, 4033, 4033, 4033,},
119 {    3,    5,    6,    7,    7,    7,    8,  255,  255,  509, 1017, 2033, 4065, 8129,16257,16257,},
120 {    3,    5,    6,    8,    8,    8,    8,    9,  511,  511, 1021, 2041, 4081, 8161,16321,32641,},
121 {    3,    5,    7,    8,    9,    9,    9,    9,   10, 1023, 1023, 2045, 4089, 8177,16353,32705,},
122 {    3,    5,    7,    8,   10,   10,   10,   10,   10,   11, 2047, 2047, 4093, 8185,16369,32737,},
123 {    3,    5,    7,    8,   10,   11,   11,   11,   11,   11,   12, 4095, 4095, 8189,16377,32753,},
124 {    3,    5,    7,    9,   10,   12,   12,   12,   12,   12,   12,   13, 8191, 8191,16381,32761,},
125 {    3,    5,    7,    9,   10,   12,   13,   13,   13,   13,   13,   13,   14,16383,16383,32765,},
126 {    3,    5,    7,    9,   10,   12,   14,   14,   14,   14,   14,   14,   14,   15,32767,32767,},
127 {    3,    5,    7,    9,   11,   12,   14,   15,   15,   15,   15,   15,   15,   15,   16,65535,},
128 };
129
130
131 static void fillPlane(uint8_t *plane, int stride, int width, int height, int y,
132                       uint8_t val)
133 {
134     int i;
135     uint8_t *ptr = plane + stride * y;
136     for (i = 0; i < height; i++) {
137         memset(ptr, val, width);
138         ptr += stride;
139     }
140 }
141
142 static void copyPlane(const uint8_t *src, int srcStride,
143                       int srcSliceY, int srcSliceH, int width,
144                       uint8_t *dst, int dstStride)
145 {
146     dst += dstStride * srcSliceY;
147     if (dstStride == srcStride && srcStride > 0) {
148         memcpy(dst, src, srcSliceH * dstStride);
149     } else {
150         int i;
151         for (i = 0; i < srcSliceH; i++) {
152             memcpy(dst, src, width);
153             src += srcStride;
154             dst += dstStride;
155         }
156     }
157 }
158
159 static int planarToNv12Wrapper(SwsContext *c, const uint8_t *src[],
160                                int srcStride[], int srcSliceY,
161                                int srcSliceH, uint8_t *dstParam[],
162                                int dstStride[])
163 {
164     uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY / 2;
165
166     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
167               dstParam[0], dstStride[0]);
168
169     if (c->dstFormat == AV_PIX_FMT_NV12)
170         interleaveBytes(src[1], src[2], dst, c->srcW / 2, srcSliceH / 2,
171                         srcStride[1], srcStride[2], dstStride[1]);
172     else
173         interleaveBytes(src[2], src[1], dst, c->srcW / 2, srcSliceH / 2,
174                         srcStride[2], srcStride[1], dstStride[1]);
175
176     return srcSliceH;
177 }
178
179 static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[],
180                                int srcStride[], int srcSliceY,
181                                int srcSliceH, uint8_t *dstParam[],
182                                int dstStride[])
183 {
184     uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
185     uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
186
187     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
188               dstParam[0], dstStride[0]);
189
190     if (c->srcFormat == AV_PIX_FMT_NV12)
191         deinterleaveBytes(src[1], dst1, dst2,c->srcW / 2, srcSliceH / 2,
192                           srcStride[1], dstStride[1], dstStride[2]);
193     else
194         deinterleaveBytes(src[1], dst2, dst1, c->srcW / 2, srcSliceH / 2,
195                           srcStride[1], dstStride[2], dstStride[1]);
196
197     return srcSliceH;
198 }
199
200 static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
201                                int srcStride[], int srcSliceY, int srcSliceH,
202                                uint8_t *dstParam[], int dstStride[])
203 {
204     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
205
206     yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
207                srcStride[1], dstStride[0]);
208
209     return srcSliceH;
210 }
211
212 static int planarToUyvyWrapper(SwsContext *c, const uint8_t *src[],
213                                int srcStride[], int srcSliceY, int srcSliceH,
214                                uint8_t *dstParam[], int dstStride[])
215 {
216     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
217
218     yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
219                srcStride[1], dstStride[0]);
220
221     return srcSliceH;
222 }
223
224 static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
225                                 int srcStride[], int srcSliceY, int srcSliceH,
226                                 uint8_t *dstParam[], int dstStride[])
227 {
228     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
229
230     yuv422ptoyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
231                   srcStride[1], dstStride[0]);
232
233     return srcSliceH;
234 }
235
236 static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t *src[],
237                                 int srcStride[], int srcSliceY, int srcSliceH,
238                                 uint8_t *dstParam[], int dstStride[])
239 {
240     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
241
242     yuv422ptouyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
243                   srcStride[1], dstStride[0]);
244
245     return srcSliceH;
246 }
247
248 static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
249                                int srcStride[], int srcSliceY, int srcSliceH,
250                                uint8_t *dstParam[], int dstStride[])
251 {
252     uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
253     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
254     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
255
256     yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
257                  dstStride[1], srcStride[0]);
258
259     if (dstParam[3])
260         fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
261
262     return srcSliceH;
263 }
264
265 static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
266                                int srcStride[], int srcSliceY, int srcSliceH,
267                                uint8_t *dstParam[], int dstStride[])
268 {
269     uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
270     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
271     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
272
273     yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
274                  dstStride[1], srcStride[0]);
275
276     return srcSliceH;
277 }
278
279 static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
280                                int srcStride[], int srcSliceY, int srcSliceH,
281                                uint8_t *dstParam[], int dstStride[])
282 {
283     uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
284     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
285     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
286
287     uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
288                  dstStride[1], srcStride[0]);
289
290     if (dstParam[3])
291         fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
292
293     return srcSliceH;
294 }
295
296 static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
297                                int srcStride[], int srcSliceY, int srcSliceH,
298                                uint8_t *dstParam[], int dstStride[])
299 {
300     uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
301     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
302     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
303
304     uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
305                  dstStride[1], srcStride[0]);
306
307     return srcSliceH;
308 }
309
310 static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels,
311                              const uint8_t *palette)
312 {
313     int i;
314     for (i = 0; i < num_pixels; i++)
315         ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | (src[(i << 1) + 1] << 24);
316 }
317
318 static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels,
319                                const uint8_t *palette)
320 {
321     int i;
322
323     for (i = 0; i < num_pixels; i++)
324         ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | src[(i << 1) + 1];
325 }
326
327 static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels,
328                              const uint8_t *palette)
329 {
330     int i;
331
332     for (i = 0; i < num_pixels; i++) {
333         //FIXME slow?
334         dst[0] = palette[src[i << 1] * 4 + 0];
335         dst[1] = palette[src[i << 1] * 4 + 1];
336         dst[2] = palette[src[i << 1] * 4 + 2];
337         dst += 3;
338     }
339 }
340
341 static int packed_16bpc_bswap(SwsContext *c, const uint8_t *src[],
342                               int srcStride[], int srcSliceY, int srcSliceH,
343                               uint8_t *dst[], int dstStride[])
344 {
345     int i, j, p;
346
347     for (p = 0; p < 4; p++) {
348         int srcstr = srcStride[p] / 2;
349         int dststr = dstStride[p] / 2;
350         uint16_t       *dstPtr =       (uint16_t *) dst[p];
351         const uint16_t *srcPtr = (const uint16_t *) src[p];
352         int min_stride         = FFMIN(FFABS(srcstr), FFABS(dststr));
353         if(!dstPtr || !srcPtr)
354             continue;
355         for (i = 0; i < (srcSliceH >> c->chrDstVSubSample); i++) {
356             for (j = 0; j < min_stride; j++) {
357                 dstPtr[j] = av_bswap16(srcPtr[j]);
358             }
359             srcPtr += srcstr;
360             dstPtr += dststr;
361         }
362     }
363
364     return srcSliceH;
365 }
366
367 static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
368                            int srcSliceY, int srcSliceH, uint8_t *dst[],
369                            int dstStride[])
370 {
371     const enum AVPixelFormat srcFormat = c->srcFormat;
372     const enum AVPixelFormat dstFormat = c->dstFormat;
373     void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels,
374                  const uint8_t *palette) = NULL;
375     int i;
376     uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
377     const uint8_t *srcPtr = src[0];
378
379     if (srcFormat == AV_PIX_FMT_YA8) {
380         switch (dstFormat) {
381         case AV_PIX_FMT_RGB32  : conv = gray8aToPacked32; break;
382         case AV_PIX_FMT_BGR32  : conv = gray8aToPacked32; break;
383         case AV_PIX_FMT_BGR32_1: conv = gray8aToPacked32_1; break;
384         case AV_PIX_FMT_RGB32_1: conv = gray8aToPacked32_1; break;
385         case AV_PIX_FMT_RGB24  : conv = gray8aToPacked24; break;
386         case AV_PIX_FMT_BGR24  : conv = gray8aToPacked24; break;
387         }
388     } else if (usePal(srcFormat)) {
389         switch (dstFormat) {
390         case AV_PIX_FMT_RGB32  : conv = sws_convertPalette8ToPacked32; break;
391         case AV_PIX_FMT_BGR32  : conv = sws_convertPalette8ToPacked32; break;
392         case AV_PIX_FMT_BGR32_1: conv = sws_convertPalette8ToPacked32; break;
393         case AV_PIX_FMT_RGB32_1: conv = sws_convertPalette8ToPacked32; break;
394         case AV_PIX_FMT_RGB24  : conv = sws_convertPalette8ToPacked24; break;
395         case AV_PIX_FMT_BGR24  : conv = sws_convertPalette8ToPacked24; break;
396         }
397     }
398
399     if (!conv)
400         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
401                av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
402     else {
403         for (i = 0; i < srcSliceH; i++) {
404             conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
405             srcPtr += srcStride[0];
406             dstPtr += dstStride[0];
407         }
408     }
409
410     return srcSliceH;
411 }
412
413 static void packed16togbra16(const uint8_t *src, int srcStride,
414                              uint16_t *dst[], int dstStride[], int srcSliceH,
415                              int src_alpha, int swap, int shift, int width)
416 {
417     int x, h, i;
418     int dst_alpha = dst[3] != NULL;
419     for (h = 0; h < srcSliceH; h++) {
420         uint16_t *src_line = (uint16_t *)(src + srcStride * h);
421         switch (swap) {
422         case 3:
423             if (src_alpha && dst_alpha) {
424                 for (x = 0; x < width; x++) {
425                     dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
426                     dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
427                     dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
428                     dst[3][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
429                 }
430             } else if (dst_alpha) {
431                 for (x = 0; x < width; x++) {
432                     dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
433                     dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
434                     dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
435                     dst[3][x] = 0xFFFF;
436                 }
437             } else if (src_alpha) {
438                 for (x = 0; x < width; x++) {
439                     dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
440                     dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
441                     dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
442                     src_line++;
443                 }
444             } else {
445                 for (x = 0; x < width; x++) {
446                     dst[0][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
447                     dst[1][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
448                     dst[2][x] = av_bswap16(av_bswap16(*src_line++) >> shift);
449                 }
450             }
451             break;
452         case 2:
453             if (src_alpha && dst_alpha) {
454                 for (x = 0; x < width; x++) {
455                     dst[0][x] = av_bswap16(*src_line++ >> shift);
456                     dst[1][x] = av_bswap16(*src_line++ >> shift);
457                     dst[2][x] = av_bswap16(*src_line++ >> shift);
458                     dst[3][x] = av_bswap16(*src_line++ >> shift);
459                 }
460             } else if (dst_alpha) {
461                 for (x = 0; x < width; x++) {
462                     dst[0][x] = av_bswap16(*src_line++ >> shift);
463                     dst[1][x] = av_bswap16(*src_line++ >> shift);
464                     dst[2][x] = av_bswap16(*src_line++ >> shift);
465                     dst[3][x] = 0xFFFF;
466                 }
467             } else if (src_alpha) {
468                 for (x = 0; x < width; x++) {
469                     dst[0][x] = av_bswap16(*src_line++ >> shift);
470                     dst[1][x] = av_bswap16(*src_line++ >> shift);
471                     dst[2][x] = av_bswap16(*src_line++ >> shift);
472                     src_line++;
473                 }
474             } else {
475                 for (x = 0; x < width; x++) {
476                     dst[0][x] = av_bswap16(*src_line++ >> shift);
477                     dst[1][x] = av_bswap16(*src_line++ >> shift);
478                     dst[2][x] = av_bswap16(*src_line++ >> shift);
479                 }
480             }
481             break;
482         case 1:
483             if (src_alpha && dst_alpha) {
484                 for (x = 0; x < width; x++) {
485                     dst[0][x] = av_bswap16(*src_line++) >> shift;
486                     dst[1][x] = av_bswap16(*src_line++) >> shift;
487                     dst[2][x] = av_bswap16(*src_line++) >> shift;
488                     dst[3][x] = av_bswap16(*src_line++) >> shift;
489                 }
490             } else if (dst_alpha) {
491                 for (x = 0; x < width; x++) {
492                     dst[0][x] = av_bswap16(*src_line++) >> shift;
493                     dst[1][x] = av_bswap16(*src_line++) >> shift;
494                     dst[2][x] = av_bswap16(*src_line++) >> shift;
495                     dst[3][x] = 0xFFFF;
496                 }
497             } else if (src_alpha) {
498                 for (x = 0; x < width; x++) {
499                     dst[0][x] = av_bswap16(*src_line++) >> shift;
500                     dst[1][x] = av_bswap16(*src_line++) >> shift;
501                     dst[2][x] = av_bswap16(*src_line++) >> shift;
502                     src_line++;
503                 }
504             } else {
505                 for (x = 0; x < width; x++) {
506                     dst[0][x] = av_bswap16(*src_line++) >> shift;
507                     dst[1][x] = av_bswap16(*src_line++) >> shift;
508                     dst[2][x] = av_bswap16(*src_line++) >> shift;
509                 }
510             }
511             break;
512         default:
513             if (src_alpha && dst_alpha) {
514                 for (x = 0; x < width; x++) {
515                     dst[0][x] = *src_line++ >> shift;
516                     dst[1][x] = *src_line++ >> shift;
517                     dst[2][x] = *src_line++ >> shift;
518                     dst[3][x] = *src_line++ >> shift;
519                 }
520             } else if (dst_alpha) {
521                 for (x = 0; x < width; x++) {
522                     dst[0][x] = *src_line++ >> shift;
523                     dst[1][x] = *src_line++ >> shift;
524                     dst[2][x] = *src_line++ >> shift;
525                     dst[3][x] = 0xFFFF;
526                 }
527             } else if (src_alpha) {
528                 for (x = 0; x < width; x++) {
529                     dst[0][x] = *src_line++ >> shift;
530                     dst[1][x] = *src_line++ >> shift;
531                     dst[2][x] = *src_line++ >> shift;
532                     src_line++;
533                 }
534             } else {
535                 for (x = 0; x < width; x++) {
536                     dst[0][x] = *src_line++ >> shift;
537                     dst[1][x] = *src_line++ >> shift;
538                     dst[2][x] = *src_line++ >> shift;
539                 }
540             }
541         }
542         for (i = 0; i < 4; i++)
543             dst[i] += dstStride[i] >> 1;
544     }
545 }
546
547 static int Rgb16ToPlanarRgb16Wrapper(SwsContext *c, const uint8_t *src[],
548                                      int srcStride[], int srcSliceY, int srcSliceH,
549                                      uint8_t *dst[], int dstStride[])
550 {
551     uint16_t *dst2013[] = { (uint16_t *)dst[2], (uint16_t *)dst[0], (uint16_t *)dst[1], (uint16_t *)dst[3] };
552     uint16_t *dst1023[] = { (uint16_t *)dst[1], (uint16_t *)dst[0], (uint16_t *)dst[2], (uint16_t *)dst[3] };
553     int stride2013[] = { dstStride[2], dstStride[0], dstStride[1], dstStride[3] };
554     int stride1023[] = { dstStride[1], dstStride[0], dstStride[2], dstStride[3] };
555     const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
556     const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
557     int bpc = dst_format->comp[0].depth_minus1 + 1;
558     int alpha = src_format->flags & AV_PIX_FMT_FLAG_ALPHA;
559     int swap = 0;
560     if ( HAVE_BIGENDIAN && !(src_format->flags & AV_PIX_FMT_FLAG_BE) ||
561         !HAVE_BIGENDIAN &&   src_format->flags & AV_PIX_FMT_FLAG_BE)
562         swap++;
563     if ( HAVE_BIGENDIAN && !(dst_format->flags & AV_PIX_FMT_FLAG_BE) ||
564         !HAVE_BIGENDIAN &&   dst_format->flags & AV_PIX_FMT_FLAG_BE)
565         swap += 2;
566
567     if ((dst_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) !=
568         (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) || bpc < 9) {
569         av_log(c, AV_LOG_ERROR, "unsupported conversion to planar RGB %s -> %s\n",
570                src_format->name, dst_format->name);
571         return srcSliceH;
572     }
573     switch (c->srcFormat) {
574     case AV_PIX_FMT_RGB48LE:
575     case AV_PIX_FMT_RGB48BE:
576     case AV_PIX_FMT_RGBA64LE:
577     case AV_PIX_FMT_RGBA64BE:
578         packed16togbra16(src[0] + srcSliceY * srcStride[0], srcStride[0],
579                          dst2013, stride2013, srcSliceH, alpha, swap,
580                          16 - bpc, c->srcW);
581         break;
582     case AV_PIX_FMT_BGR48LE:
583     case AV_PIX_FMT_BGR48BE:
584     case AV_PIX_FMT_BGRA64LE:
585     case AV_PIX_FMT_BGRA64BE:
586         packed16togbra16(src[0] + srcSliceY * srcStride[0], srcStride[0],
587                          dst1023, stride1023, srcSliceH, alpha, swap,
588                          16 - bpc, c->srcW);
589         break;
590     default:
591         av_log(c, AV_LOG_ERROR,
592                "unsupported conversion to planar RGB %s -> %s\n",
593                src_format->name, dst_format->name);
594     }
595
596     return srcSliceH;
597 }
598
599 static void gbr16ptopacked16(const uint16_t *src[], int srcStride[],
600                              uint8_t *dst, int dstStride, int srcSliceH,
601                              int alpha, int swap, int bpp, int width)
602 {
603     int x, h, i;
604     int src_alpha = src[3] != NULL;
605     int scale_high = 16 - bpp, scale_low = (bpp - 8) * 2;
606     for (h = 0; h < srcSliceH; h++) {
607         uint16_t *dest = (uint16_t *)(dst + dstStride * h);
608         uint16_t component;
609
610         switch(swap) {
611         case 3:
612             if (alpha && !src_alpha) {
613                 for (x = 0; x < width; x++) {
614                     component = av_bswap16(src[0][x]);
615                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
616                     component = av_bswap16(src[1][x]);
617                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
618                     component = av_bswap16(src[2][x]);
619                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
620                     *dest++ = 0xffff;
621                 }
622             } else if (alpha && src_alpha) {
623                 for (x = 0; x < width; x++) {
624                     component = av_bswap16(src[0][x]);
625                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
626                     component = av_bswap16(src[1][x]);
627                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
628                     component = av_bswap16(src[2][x]);
629                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
630                     component = av_bswap16(src[3][x]);
631                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
632                 }
633             } else {
634                 for (x = 0; x < width; x++) {
635                     component = av_bswap16(src[0][x]);
636                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
637                     component = av_bswap16(src[1][x]);
638                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
639                     component = av_bswap16(src[2][x]);
640                     *dest++ = av_bswap16(component << scale_high | component >> scale_low);
641                 }
642             }
643             break;
644         case 2:
645             if (alpha && !src_alpha) {
646                 for (x = 0; x < width; x++) {
647                     *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
648                     *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
649                     *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
650                     *dest++ = 0xffff;
651                 }
652             } else if (alpha && src_alpha) {
653                 for (x = 0; x < width; x++) {
654                     *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
655                     *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
656                     *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
657                     *dest++ = av_bswap16(src[3][x] << scale_high | src[3][x] >> scale_low);
658                 }
659             } else {
660                 for (x = 0; x < width; x++) {
661                     *dest++ = av_bswap16(src[0][x] << scale_high | src[0][x] >> scale_low);
662                     *dest++ = av_bswap16(src[1][x] << scale_high | src[1][x] >> scale_low);
663                     *dest++ = av_bswap16(src[2][x] << scale_high | src[2][x] >> scale_low);
664                 }
665             }
666             break;
667         case 1:
668             if (alpha && !src_alpha) {
669                 for (x = 0; x < width; x++) {
670                     *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
671                     *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
672                     *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
673                     *dest++ = 0xffff;
674                 }
675             } else if (alpha && src_alpha) {
676                 for (x = 0; x < width; x++) {
677                     *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
678                     *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
679                     *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
680                     *dest++ = av_bswap16(src[3][x]) << scale_high | av_bswap16(src[3][x]) >> scale_low;
681                 }
682             } else {
683                 for (x = 0; x < width; x++) {
684                     *dest++ = av_bswap16(src[0][x]) << scale_high | av_bswap16(src[0][x]) >> scale_low;
685                     *dest++ = av_bswap16(src[1][x]) << scale_high | av_bswap16(src[1][x]) >> scale_low;
686                     *dest++ = av_bswap16(src[2][x]) << scale_high | av_bswap16(src[2][x]) >> scale_low;
687                 }
688             }
689             break;
690         default:
691             if (alpha && !src_alpha) {
692                 for (x = 0; x < width; x++) {
693                     *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
694                     *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
695                     *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
696                     *dest++ = 0xffff;
697                 }
698             } else if (alpha && src_alpha) {
699                 for (x = 0; x < width; x++) {
700                     *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
701                     *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
702                     *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
703                     *dest++ = src[3][x] << scale_high | src[3][x] >> scale_low;
704                 }
705             } else {
706                 for (x = 0; x < width; x++) {
707                     *dest++ = src[0][x] << scale_high | src[0][x] >> scale_low;
708                     *dest++ = src[1][x] << scale_high | src[1][x] >> scale_low;
709                     *dest++ = src[2][x] << scale_high | src[2][x] >> scale_low;
710                 }
711             }
712         }
713         for (i = 0; i < 3 + src_alpha; i++)
714             src[i] += srcStride[i] >> 1;
715     }
716 }
717
718 static int planarRgb16ToRgb16Wrapper(SwsContext *c, const uint8_t *src[],
719                                      int srcStride[], int srcSliceY, int srcSliceH,
720                                      uint8_t *dst[], int dstStride[])
721 {
722     const uint16_t *src102[] = { (uint16_t *)src[1], (uint16_t *)src[0], (uint16_t *)src[2], (uint16_t *)src[3] };
723     const uint16_t *src201[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1], (uint16_t *)src[3] };
724     int stride102[] = { srcStride[1], srcStride[0], srcStride[2], srcStride[3] };
725     int stride201[] = { srcStride[2], srcStride[0], srcStride[1], srcStride[3] };
726     const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
727     const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
728     int bits_per_sample = src_format->comp[0].depth_minus1 + 1;
729     int swap = 0;
730     if ( HAVE_BIGENDIAN && !(src_format->flags & AV_PIX_FMT_FLAG_BE) ||
731         !HAVE_BIGENDIAN &&   src_format->flags & AV_PIX_FMT_FLAG_BE)
732         swap++;
733     if ( HAVE_BIGENDIAN && !(dst_format->flags & AV_PIX_FMT_FLAG_BE) ||
734         !HAVE_BIGENDIAN &&   dst_format->flags & AV_PIX_FMT_FLAG_BE)
735         swap += 2;
736
737     if ((src_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) !=
738         (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) ||
739         bits_per_sample <= 8) {
740         av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
741                src_format->name, dst_format->name);
742         return srcSliceH;
743     }
744     switch (c->dstFormat) {
745     case AV_PIX_FMT_BGR48LE:
746     case AV_PIX_FMT_BGR48BE:
747         gbr16ptopacked16(src102, stride102,
748                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
749                          srcSliceH, 0, swap, bits_per_sample, c->srcW);
750         break;
751     case AV_PIX_FMT_RGB48LE:
752     case AV_PIX_FMT_RGB48BE:
753         gbr16ptopacked16(src201, stride201,
754                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
755                          srcSliceH, 0, swap, bits_per_sample, c->srcW);
756         break;
757     case AV_PIX_FMT_RGBA64LE:
758     case AV_PIX_FMT_RGBA64BE:
759          gbr16ptopacked16(src201, stride201,
760                           dst[0] + srcSliceY * dstStride[0], dstStride[0],
761                           srcSliceH, 1, swap, bits_per_sample, c->srcW);
762         break;
763     case AV_PIX_FMT_BGRA64LE:
764     case AV_PIX_FMT_BGRA64BE:
765         gbr16ptopacked16(src102, stride102,
766                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
767                          srcSliceH, 1, swap, bits_per_sample, c->srcW);
768         break;
769     default:
770         av_log(c, AV_LOG_ERROR,
771                "unsupported planar RGB conversion %s -> %s\n",
772                src_format->name, dst_format->name);
773     }
774
775     return srcSliceH;
776 }
777
778 static void gbr24ptopacked24(const uint8_t *src[], int srcStride[],
779                              uint8_t *dst, int dstStride, int srcSliceH,
780                              int width)
781 {
782     int x, h, i;
783     for (h = 0; h < srcSliceH; h++) {
784         uint8_t *dest = dst + dstStride * h;
785         for (x = 0; x < width; x++) {
786             *dest++ = src[0][x];
787             *dest++ = src[1][x];
788             *dest++ = src[2][x];
789         }
790
791         for (i = 0; i < 3; i++)
792             src[i] += srcStride[i];
793     }
794 }
795
796 static void gbr24ptopacked32(const uint8_t *src[], int srcStride[],
797                              uint8_t *dst, int dstStride, int srcSliceH,
798                              int alpha_first, int width)
799 {
800     int x, h, i;
801     for (h = 0; h < srcSliceH; h++) {
802         uint8_t *dest = dst + dstStride * h;
803
804         if (alpha_first) {
805             for (x = 0; x < width; x++) {
806                 *dest++ = 0xff;
807                 *dest++ = src[0][x];
808                 *dest++ = src[1][x];
809                 *dest++ = src[2][x];
810             }
811         } else {
812             for (x = 0; x < width; x++) {
813                 *dest++ = src[0][x];
814                 *dest++ = src[1][x];
815                 *dest++ = src[2][x];
816                 *dest++ = 0xff;
817             }
818         }
819
820         for (i = 0; i < 3; i++)
821             src[i] += srcStride[i];
822     }
823 }
824
825 static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[],
826                                  int srcStride[], int srcSliceY, int srcSliceH,
827                                  uint8_t *dst[], int dstStride[])
828 {
829     int alpha_first = 0;
830     const uint8_t *src102[] = { src[1], src[0], src[2] };
831     const uint8_t *src201[] = { src[2], src[0], src[1] };
832     int stride102[] = { srcStride[1], srcStride[0], srcStride[2] };
833     int stride201[] = { srcStride[2], srcStride[0], srcStride[1] };
834
835     if (c->srcFormat != AV_PIX_FMT_GBRP) {
836         av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
837                av_get_pix_fmt_name(c->srcFormat),
838                av_get_pix_fmt_name(c->dstFormat));
839         return srcSliceH;
840     }
841
842     switch (c->dstFormat) {
843     case AV_PIX_FMT_BGR24:
844         gbr24ptopacked24(src102, stride102,
845                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
846                          srcSliceH, c->srcW);
847         break;
848
849     case AV_PIX_FMT_RGB24:
850         gbr24ptopacked24(src201, stride201,
851                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
852                          srcSliceH, c->srcW);
853         break;
854
855     case AV_PIX_FMT_ARGB:
856         alpha_first = 1;
857     case AV_PIX_FMT_RGBA:
858         gbr24ptopacked32(src201, stride201,
859                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
860                          srcSliceH, alpha_first, c->srcW);
861         break;
862
863     case AV_PIX_FMT_ABGR:
864         alpha_first = 1;
865     case AV_PIX_FMT_BGRA:
866         gbr24ptopacked32(src102, stride102,
867                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
868                          srcSliceH, alpha_first, c->srcW);
869         break;
870
871     default:
872         av_log(c, AV_LOG_ERROR,
873                "unsupported planar RGB conversion %s -> %s\n",
874                av_get_pix_fmt_name(c->srcFormat),
875                av_get_pix_fmt_name(c->dstFormat));
876     }
877
878     return srcSliceH;
879 }
880
881 static int planarRgbToplanarRgbWrapper(SwsContext *c,
882                                        const uint8_t *src[], int srcStride[],
883                                        int srcSliceY, int srcSliceH,
884                                        uint8_t *dst[], int dstStride[])
885 {
886     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
887               dst[0], dstStride[0]);
888     copyPlane(src[1], srcStride[1], srcSliceY, srcSliceH, c->srcW,
889               dst[1], dstStride[1]);
890     copyPlane(src[2], srcStride[2], srcSliceY, srcSliceH, c->srcW,
891               dst[2], dstStride[2]);
892     if (dst[3])
893         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
894
895     return srcSliceH;
896 }
897
898 static void packedtogbr24p(const uint8_t *src, int srcStride,
899                            uint8_t *dst[], int dstStride[], int srcSliceH,
900                            int alpha_first, int inc_size, int width)
901 {
902     uint8_t *dest[3];
903     int x, h;
904
905     dest[0] = dst[0];
906     dest[1] = dst[1];
907     dest[2] = dst[2];
908
909     if (alpha_first)
910         src++;
911
912     for (h = 0; h < srcSliceH; h++) {
913         for (x = 0; x < width; x++) {
914             dest[0][x] = src[0];
915             dest[1][x] = src[1];
916             dest[2][x] = src[2];
917
918             src += inc_size;
919         }
920         src     += srcStride - width * inc_size;
921         dest[0] += dstStride[0];
922         dest[1] += dstStride[1];
923         dest[2] += dstStride[2];
924     }
925 }
926
927 static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[],
928                                  int srcStride[], int srcSliceY, int srcSliceH,
929                                  uint8_t *dst[], int dstStride[])
930 {
931     int alpha_first = 0;
932     int stride102[] = { dstStride[1], dstStride[0], dstStride[2] };
933     int stride201[] = { dstStride[2], dstStride[0], dstStride[1] };
934     uint8_t *dst102[] = { dst[1] + srcSliceY * dstStride[1],
935                           dst[0] + srcSliceY * dstStride[0],
936                           dst[2] + srcSliceY * dstStride[2] };
937     uint8_t *dst201[] = { dst[2] + srcSliceY * dstStride[2],
938                           dst[0] + srcSliceY * dstStride[0],
939                           dst[1] + srcSliceY * dstStride[1] };
940
941     switch (c->srcFormat) {
942     case AV_PIX_FMT_RGB24:
943         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
944                        stride201, srcSliceH, alpha_first, 3, c->srcW);
945         break;
946     case AV_PIX_FMT_BGR24:
947         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
948                        stride102, srcSliceH, alpha_first, 3, c->srcW);
949         break;
950     case AV_PIX_FMT_ARGB:
951         alpha_first = 1;
952     case AV_PIX_FMT_RGBA:
953         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
954                        stride201, srcSliceH, alpha_first, 4, c->srcW);
955         break;
956     case AV_PIX_FMT_ABGR:
957         alpha_first = 1;
958     case AV_PIX_FMT_BGRA:
959         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
960                        stride102, srcSliceH, alpha_first, 4, c->srcW);
961         break;
962     default:
963         av_log(c, AV_LOG_ERROR,
964                "unsupported planar RGB conversion %s -> %s\n",
965                av_get_pix_fmt_name(c->srcFormat),
966                av_get_pix_fmt_name(c->dstFormat));
967     }
968
969     return srcSliceH;
970 }
971
972 #define BAYER_GBRG
973 #define BAYER_8
974 #define BAYER_RENAME(x) bayer_gbrg8_to_##x
975 #include "bayer_template.c"
976
977 #define BAYER_GBRG
978 #define BAYER_16LE
979 #define BAYER_RENAME(x) bayer_gbrg16le_to_##x
980 #include "bayer_template.c"
981
982 #define BAYER_GBRG
983 #define BAYER_16BE
984 #define BAYER_RENAME(x) bayer_gbrg16be_to_##x
985 #include "bayer_template.c"
986
987 #define BAYER_GRBG
988 #define BAYER_8
989 #define BAYER_RENAME(x) bayer_grbg8_to_##x
990 #include "bayer_template.c"
991
992 #define BAYER_GRBG
993 #define BAYER_16LE
994 #define BAYER_RENAME(x) bayer_grbg16le_to_##x
995 #include "bayer_template.c"
996
997 #define BAYER_GRBG
998 #define BAYER_16BE
999 #define BAYER_RENAME(x) bayer_grbg16be_to_##x
1000 #include "bayer_template.c"
1001
1002 #define BAYER_BGGR
1003 #define BAYER_8
1004 #define BAYER_RENAME(x) bayer_bggr8_to_##x
1005 #include "bayer_template.c"
1006
1007 #define BAYER_BGGR
1008 #define BAYER_16LE
1009 #define BAYER_RENAME(x) bayer_bggr16le_to_##x
1010 #include "bayer_template.c"
1011
1012 #define BAYER_BGGR
1013 #define BAYER_16BE
1014 #define BAYER_RENAME(x) bayer_bggr16be_to_##x
1015 #include "bayer_template.c"
1016
1017 #define BAYER_RGGB
1018 #define BAYER_8
1019 #define BAYER_RENAME(x) bayer_rggb8_to_##x
1020 #include "bayer_template.c"
1021
1022 #define BAYER_RGGB
1023 #define BAYER_16LE
1024 #define BAYER_RENAME(x) bayer_rggb16le_to_##x
1025 #include "bayer_template.c"
1026
1027 #define BAYER_RGGB
1028 #define BAYER_16BE
1029 #define BAYER_RENAME(x) bayer_rggb16be_to_##x
1030 #include "bayer_template.c"
1031
1032 static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1033                                   int srcSliceH, uint8_t* dst[], int dstStride[])
1034 {
1035     uint8_t *dstPtr= dst[0];
1036     const uint8_t *srcPtr= src[0];
1037     int i;
1038     void (*copy)       (const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
1039     void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
1040
1041     switch(c->srcFormat) {
1042 #define CASE(pixfmt, prefix) \
1043     case pixfmt: copy        = bayer_##prefix##_to_rgb24_copy; \
1044                  interpolate = bayer_##prefix##_to_rgb24_interpolate; \
1045                  break;
1046     CASE(AV_PIX_FMT_BAYER_BGGR8,    bggr8)
1047     CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le)
1048     CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be)
1049     CASE(AV_PIX_FMT_BAYER_RGGB8,    rggb8)
1050     CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le)
1051     CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be)
1052     CASE(AV_PIX_FMT_BAYER_GBRG8,    gbrg8)
1053     CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le)
1054     CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be)
1055     CASE(AV_PIX_FMT_BAYER_GRBG8,    grbg8)
1056     CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le)
1057     CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be)
1058 #undef CASE
1059     default: return 0;
1060     }
1061
1062     copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1063     srcPtr += 2 * srcStride[0];
1064     dstPtr += 2 * dstStride[0];
1065
1066     for (i = 2; i < srcSliceH - 2; i += 2) {
1067         interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1068         srcPtr += 2 * srcStride[0];
1069         dstPtr += 2 * dstStride[0];
1070     }
1071
1072     copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1073     return srcSliceH;
1074 }
1075
1076 static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1077                                  int srcSliceH, uint8_t* dst[], int dstStride[])
1078 {
1079     const uint8_t *srcPtr= src[0];
1080     uint8_t *dstY= dst[0];
1081     uint8_t *dstU= dst[1];
1082     uint8_t *dstV= dst[2];
1083     int i;
1084     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);
1085     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);
1086
1087     switch(c->srcFormat) {
1088 #define CASE(pixfmt, prefix) \
1089     case pixfmt: copy        = bayer_##prefix##_to_yv12_copy; \
1090                  interpolate = bayer_##prefix##_to_yv12_interpolate; \
1091                  break;
1092     CASE(AV_PIX_FMT_BAYER_BGGR8,    bggr8)
1093     CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le)
1094     CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be)
1095     CASE(AV_PIX_FMT_BAYER_RGGB8,    rggb8)
1096     CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le)
1097     CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be)
1098     CASE(AV_PIX_FMT_BAYER_GBRG8,    gbrg8)
1099     CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le)
1100     CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be)
1101     CASE(AV_PIX_FMT_BAYER_GRBG8,    grbg8)
1102     CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le)
1103     CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be)
1104 #undef CASE
1105     default: return 0;
1106     }
1107
1108     copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1109     srcPtr += 2 * srcStride[0];
1110     dstY   += 2 * dstStride[0];
1111     dstU   +=     dstStride[1];
1112     dstV   +=     dstStride[1];
1113
1114     for (i = 2; i < srcSliceH - 2; i += 2) {
1115         interpolate(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1116         srcPtr += 2 * srcStride[0];
1117         dstY   += 2 * dstStride[0];
1118         dstU   +=     dstStride[1];
1119         dstV   +=     dstStride[1];
1120     }
1121
1122     copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1123     return srcSliceH;
1124 }
1125
1126 #define isRGBA32(x) (            \
1127            (x) == AV_PIX_FMT_ARGB   \
1128         || (x) == AV_PIX_FMT_RGBA   \
1129         || (x) == AV_PIX_FMT_BGRA   \
1130         || (x) == AV_PIX_FMT_ABGR   \
1131         )
1132
1133 #define isRGBA64(x) (                \
1134            (x) == AV_PIX_FMT_RGBA64LE   \
1135         || (x) == AV_PIX_FMT_RGBA64BE   \
1136         || (x) == AV_PIX_FMT_BGRA64LE   \
1137         || (x) == AV_PIX_FMT_BGRA64BE   \
1138         )
1139
1140 #define isRGB48(x) (                \
1141            (x) == AV_PIX_FMT_RGB48LE   \
1142         || (x) == AV_PIX_FMT_RGB48BE   \
1143         || (x) == AV_PIX_FMT_BGR48LE   \
1144         || (x) == AV_PIX_FMT_BGR48BE   \
1145         )
1146
1147 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1148 typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
1149 static rgbConvFn findRgbConvFn(SwsContext *c)
1150 {
1151     const enum AVPixelFormat srcFormat = c->srcFormat;
1152     const enum AVPixelFormat dstFormat = c->dstFormat;
1153     const int srcId = c->srcFormatBpp;
1154     const int dstId = c->dstFormatBpp;
1155     rgbConvFn conv = NULL;
1156
1157 #define IS_NOT_NE(bpp, desc) \
1158     (((bpp + 7) >> 3) == 2 && \
1159      (!(desc->flags & AV_PIX_FMT_FLAG_BE) != !HAVE_BIGENDIAN))
1160
1161 #define CONV_IS(src, dst) (srcFormat == AV_PIX_FMT_##src && dstFormat == AV_PIX_FMT_##dst)
1162
1163     if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
1164         if (     CONV_IS(ABGR, RGBA)
1165               || CONV_IS(ARGB, BGRA)
1166               || CONV_IS(BGRA, ARGB)
1167               || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
1168         else if (CONV_IS(ABGR, ARGB)
1169               || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
1170         else if (CONV_IS(ABGR, BGRA)
1171               || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
1172         else if (CONV_IS(BGRA, RGBA)
1173               || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
1174         else if (CONV_IS(BGRA, ABGR)
1175               || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
1176     } else if (isRGB48(srcFormat) && isRGB48(dstFormat)) {
1177         if      (CONV_IS(RGB48LE, BGR48LE)
1178               || CONV_IS(BGR48LE, RGB48LE)
1179               || CONV_IS(RGB48BE, BGR48BE)
1180               || CONV_IS(BGR48BE, RGB48BE)) conv = rgb48tobgr48_nobswap;
1181         else if (CONV_IS(RGB48LE, BGR48BE)
1182               || CONV_IS(BGR48LE, RGB48BE)
1183               || CONV_IS(RGB48BE, BGR48LE)
1184               || CONV_IS(BGR48BE, RGB48LE)) conv = rgb48tobgr48_bswap;
1185     } else if (isRGBA64(srcFormat) && isRGB48(dstFormat)) {
1186         if      (CONV_IS(RGBA64LE, BGR48LE)
1187               || CONV_IS(BGRA64LE, RGB48LE)
1188               || CONV_IS(RGBA64BE, BGR48BE)
1189               || CONV_IS(BGRA64BE, RGB48BE)) conv = rgb64tobgr48_nobswap;
1190         else if (CONV_IS(RGBA64LE, BGR48BE)
1191               || CONV_IS(BGRA64LE, RGB48BE)
1192               || CONV_IS(RGBA64BE, BGR48LE)
1193               || CONV_IS(BGRA64BE, RGB48LE)) conv = rgb64tobgr48_bswap;
1194         else if (CONV_IS(RGBA64LE, RGB48LE)
1195               || CONV_IS(BGRA64LE, BGR48LE)
1196               || CONV_IS(RGBA64BE, RGB48BE)
1197               || CONV_IS(BGRA64BE, BGR48BE)) conv = rgb64to48_nobswap;
1198         else if (CONV_IS(RGBA64LE, RGB48BE)
1199               || CONV_IS(BGRA64LE, BGR48BE)
1200               || CONV_IS(RGBA64BE, RGB48LE)
1201               || CONV_IS(BGRA64BE, BGR48LE)) conv = rgb64to48_bswap;
1202     } else
1203     /* BGR -> BGR */
1204     if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
1205         (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
1206         switch (srcId | (dstId << 16)) {
1207         case 0x000F000C: conv = rgb12to15; break;
1208         case 0x000F0010: conv = rgb16to15; break;
1209         case 0x000F0018: conv = rgb24to15; break;
1210         case 0x000F0020: conv = rgb32to15; break;
1211         case 0x0010000F: conv = rgb15to16; break;
1212         case 0x00100018: conv = rgb24to16; break;
1213         case 0x00100020: conv = rgb32to16; break;
1214         case 0x0018000F: conv = rgb15to24; break;
1215         case 0x00180010: conv = rgb16to24; break;
1216         case 0x00180020: conv = rgb32to24; break;
1217         case 0x0020000F: conv = rgb15to32; break;
1218         case 0x00200010: conv = rgb16to32; break;
1219         case 0x00200018: conv = rgb24to32; break;
1220         }
1221     } else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) ||
1222                (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
1223         switch (srcId | (dstId << 16)) {
1224         case 0x000C000C: conv = rgb12tobgr12; break;
1225         case 0x000F000F: conv = rgb15tobgr15; break;
1226         case 0x000F0010: conv = rgb16tobgr15; break;
1227         case 0x000F0018: conv = rgb24tobgr15; break;
1228         case 0x000F0020: conv = rgb32tobgr15; break;
1229         case 0x0010000F: conv = rgb15tobgr16; break;
1230         case 0x00100010: conv = rgb16tobgr16; break;
1231         case 0x00100018: conv = rgb24tobgr16; break;
1232         case 0x00100020: conv = rgb32tobgr16; break;
1233         case 0x0018000F: conv = rgb15tobgr24; break;
1234         case 0x00180010: conv = rgb16tobgr24; break;
1235         case 0x00180018: conv = rgb24tobgr24; break;
1236         case 0x00180020: conv = rgb32tobgr24; break;
1237         case 0x0020000F: conv = rgb15tobgr32; break;
1238         case 0x00200010: conv = rgb16tobgr32; break;
1239         case 0x00200018: conv = rgb24tobgr32; break;
1240         }
1241     }
1242
1243     if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0)
1244         return NULL;
1245
1246     // Maintain symmetry between endianness
1247     if (c->flags & SWS_BITEXACT)
1248         if ((dstFormat == AV_PIX_FMT_RGB32   || dstFormat == AV_PIX_FMT_BGR32  ) && !isRGBA32(srcFormat) && ALT32_CORR>0)
1249             return NULL;
1250
1251     return conv;
1252 }
1253
1254 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1255 static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
1256                            int srcSliceY, int srcSliceH, uint8_t *dst[],
1257                            int dstStride[])
1258
1259 {
1260     const enum AVPixelFormat srcFormat = c->srcFormat;
1261     const enum AVPixelFormat dstFormat = c->dstFormat;
1262     const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1263     const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1264     const int srcBpp = (c->srcFormatBpp + 7) >> 3;
1265     const int dstBpp = (c->dstFormatBpp + 7) >> 3;
1266     rgbConvFn conv = findRgbConvFn(c);
1267
1268     if (!conv) {
1269         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
1270                av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1271     } else {
1272         const uint8_t *srcPtr = src[0];
1273               uint8_t *dstPtr = dst[0];
1274         int src_bswap = IS_NOT_NE(c->srcFormatBpp, desc_src);
1275         int dst_bswap = IS_NOT_NE(c->dstFormatBpp, desc_dst);
1276
1277         if ((srcFormat == AV_PIX_FMT_RGB32_1 || srcFormat == AV_PIX_FMT_BGR32_1) &&
1278             !isRGBA32(dstFormat))
1279             srcPtr += ALT32_CORR;
1280
1281         if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) &&
1282             !isRGBA32(srcFormat)) {
1283             int i;
1284             av_assert0(ALT32_CORR == 1);
1285             for (i = 0; i < srcSliceH; i++)
1286                 dstPtr[dstStride[0] * (srcSliceY + i)] = 255;
1287             dstPtr += ALT32_CORR;
1288         }
1289
1290         if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
1291             !(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap)
1292             conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
1293                  (srcSliceH - 1) * srcStride[0] + c->srcW * srcBpp);
1294         else {
1295             int i, j;
1296             dstPtr += dstStride[0] * srcSliceY;
1297
1298             for (i = 0; i < srcSliceH; i++) {
1299                 if(src_bswap) {
1300                     for(j=0; j<c->srcW; j++)
1301                         ((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]);
1302                     conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp);
1303                 }else
1304                     conv(srcPtr, dstPtr, c->srcW * srcBpp);
1305                 if(dst_bswap)
1306                     for(j=0; j<c->srcW; j++)
1307                         ((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]);
1308                 srcPtr += srcStride[0];
1309                 dstPtr += dstStride[0];
1310             }
1311         }
1312     }
1313     return srcSliceH;
1314 }
1315
1316 static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
1317                               int srcStride[], int srcSliceY, int srcSliceH,
1318                               uint8_t *dst[], int dstStride[])
1319 {
1320     ff_rgb24toyv12(
1321         src[0],
1322         dst[0] +  srcSliceY       * dstStride[0],
1323         dst[1] + (srcSliceY >> 1) * dstStride[1],
1324         dst[2] + (srcSliceY >> 1) * dstStride[2],
1325         c->srcW, srcSliceH,
1326         dstStride[0], dstStride[1], srcStride[0],
1327         c->input_rgb2yuv_table);
1328     if (dst[3])
1329         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1330     return srcSliceH;
1331 }
1332
1333 static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
1334                              int srcStride[], int srcSliceY, int srcSliceH,
1335                              uint8_t *dst[], int dstStride[])
1336 {
1337     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
1338               dst[0], dstStride[0]);
1339
1340     planar2x(src[1], dst[1] + dstStride[1] * (srcSliceY >> 1), c->chrSrcW,
1341              srcSliceH >> 2, srcStride[1], dstStride[1]);
1342     planar2x(src[2], dst[2] + dstStride[2] * (srcSliceY >> 1), c->chrSrcW,
1343              srcSliceH >> 2, srcStride[2], dstStride[2]);
1344     if (dst[3])
1345         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1346     return srcSliceH;
1347 }
1348
1349 /* unscaled copy like stuff (assumes nearly identical formats) */
1350 static int packedCopyWrapper(SwsContext *c, const uint8_t *src[],
1351                              int srcStride[], int srcSliceY, int srcSliceH,
1352                              uint8_t *dst[], int dstStride[])
1353 {
1354     if (dstStride[0] == srcStride[0] && srcStride[0] > 0)
1355         memcpy(dst[0] + dstStride[0] * srcSliceY, src[0], srcSliceH * dstStride[0]);
1356     else {
1357         int i;
1358         const uint8_t *srcPtr = src[0];
1359         uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
1360         int length = 0;
1361
1362         /* universal length finder */
1363         while (length + c->srcW <= FFABS(dstStride[0]) &&
1364                length + c->srcW <= FFABS(srcStride[0]))
1365             length += c->srcW;
1366         av_assert1(length != 0);
1367
1368         for (i = 0; i < srcSliceH; i++) {
1369             memcpy(dstPtr, srcPtr, length);
1370             srcPtr += srcStride[0];
1371             dstPtr += dstStride[0];
1372         }
1373     }
1374     return srcSliceH;
1375 }
1376
1377 #define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
1378     uint16_t scale= dither_scale[dst_depth-1][src_depth-1];\
1379     int shift= src_depth-dst_depth + dither_scale[src_depth-2][dst_depth-1];\
1380     for (i = 0; i < height; i++) {\
1381         const uint8_t *dither= dithers[src_depth-9][i&7];\
1382         for (j = 0; j < length-7; j+=8){\
1383             dst[j+0] = dbswap((bswap(src[j+0]) + dither[0])*scale>>shift);\
1384             dst[j+1] = dbswap((bswap(src[j+1]) + dither[1])*scale>>shift);\
1385             dst[j+2] = dbswap((bswap(src[j+2]) + dither[2])*scale>>shift);\
1386             dst[j+3] = dbswap((bswap(src[j+3]) + dither[3])*scale>>shift);\
1387             dst[j+4] = dbswap((bswap(src[j+4]) + dither[4])*scale>>shift);\
1388             dst[j+5] = dbswap((bswap(src[j+5]) + dither[5])*scale>>shift);\
1389             dst[j+6] = dbswap((bswap(src[j+6]) + dither[6])*scale>>shift);\
1390             dst[j+7] = dbswap((bswap(src[j+7]) + dither[7])*scale>>shift);\
1391         }\
1392         for (; j < length; j++)\
1393             dst[j] = dbswap((bswap(src[j]) + dither[j&7])*scale>>shift);\
1394         dst += dstStride;\
1395         src += srcStride;\
1396     }
1397
1398 static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
1399                              int srcStride[], int srcSliceY, int srcSliceH,
1400                              uint8_t *dst[], int dstStride[])
1401 {
1402     const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1403     const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1404     int plane, i, j;
1405     for (plane = 0; plane < 4; plane++) {
1406         int length = (plane == 0 || plane == 3) ? c->srcW  : FF_CEIL_RSHIFT(c->srcW,   c->chrDstHSubSample);
1407         int y =      (plane == 0 || plane == 3) ? srcSliceY: FF_CEIL_RSHIFT(srcSliceY, c->chrDstVSubSample);
1408         int height = (plane == 0 || plane == 3) ? srcSliceH: FF_CEIL_RSHIFT(srcSliceH, c->chrDstVSubSample);
1409         const uint8_t *srcPtr = src[plane];
1410         uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
1411         int shiftonly = plane == 1 || plane == 2 || (!c->srcRange && plane == 0);
1412
1413         if (!dst[plane])
1414             continue;
1415         // ignore palette for GRAY8
1416         if (plane == 1 && !dst[2]) continue;
1417         if (!src[plane] || (plane == 1 && !src[2])) {
1418             if (is16BPS(c->dstFormat) || isNBPS(c->dstFormat)) {
1419                 fillPlane16(dst[plane], dstStride[plane], length, height, y,
1420                         plane == 3, desc_dst->comp[plane].depth,
1421                         isBE(c->dstFormat));
1422             } else {
1423                 fillPlane(dst[plane], dstStride[plane], length, height, y,
1424                         (plane == 3) ? 255 : 128);
1425             }
1426         } else {
1427             if(isNBPS(c->srcFormat) || isNBPS(c->dstFormat)
1428                || (is16BPS(c->srcFormat) != is16BPS(c->dstFormat))
1429             ) {
1430                 const int src_depth = desc_src->comp[plane].depth;
1431                 const int dst_depth = desc_dst->comp[plane].depth;
1432                 const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
1433                 uint16_t *dstPtr2 = (uint16_t*)dstPtr;
1434
1435                 if (dst_depth == 8) {
1436                     if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1437                         DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , )
1438                     } else {
1439                         DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, av_bswap16, )
1440                     }
1441                 } else if (src_depth == 8) {
1442                     for (i = 0; i < height; i++) {
1443                         #define COPY816(w)\
1444                         if (shiftonly) {\
1445                             for (j = 0; j < length; j++)\
1446                                 w(&dstPtr2[j], srcPtr[j]<<(dst_depth-8));\
1447                         } else {\
1448                             for (j = 0; j < length; j++)\
1449                                 w(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) |\
1450                                                (srcPtr[j]>>(2*8-dst_depth)));\
1451                         }
1452                         if(isBE(c->dstFormat)){
1453                             COPY816(AV_WB16)
1454                         } else {
1455                             COPY816(AV_WL16)
1456                         }
1457                         dstPtr2 += dstStride[plane]/2;
1458                         srcPtr  += srcStride[plane];
1459                     }
1460                 } else if (src_depth <= dst_depth) {
1461                     for (i = 0; i < height; i++) {
1462                         j = 0;
1463                         if(isBE(c->srcFormat) == HAVE_BIGENDIAN &&
1464                            isBE(c->dstFormat) == HAVE_BIGENDIAN &&
1465                            shiftonly) {
1466                              unsigned shift = dst_depth - src_depth;
1467 #if HAVE_FAST_64BIT
1468 #define FAST_COPY_UP(shift) \
1469     for (; j < length - 3; j += 4) { \
1470         uint64_t v = AV_RN64A(srcPtr2 + j); \
1471         AV_WN64A(dstPtr2 + j, v << shift); \
1472     }
1473 #else
1474 #define FAST_COPY_UP(shift) \
1475     for (; j < length - 1; j += 2) { \
1476         uint32_t v = AV_RN32A(srcPtr2 + j); \
1477         AV_WN32A(dstPtr2 + j, v << shift); \
1478     }
1479 #endif
1480                              switch (shift)
1481                              {
1482                              case 6: FAST_COPY_UP(6); break;
1483                              case 7: FAST_COPY_UP(7); break;
1484                              }
1485                         }
1486 #define COPY_UP(r,w) \
1487     if(shiftonly){\
1488         for (; j < length; j++){ \
1489             unsigned int v= r(&srcPtr2[j]);\
1490             w(&dstPtr2[j], v<<(dst_depth-src_depth));\
1491         }\
1492     }else{\
1493         for (; j < length; j++){ \
1494             unsigned int v= r(&srcPtr2[j]);\
1495             w(&dstPtr2[j], (v<<(dst_depth-src_depth)) | \
1496                         (v>>(2*src_depth-dst_depth)));\
1497         }\
1498     }
1499                         if(isBE(c->srcFormat)){
1500                             if(isBE(c->dstFormat)){
1501                                 COPY_UP(AV_RB16, AV_WB16)
1502                             } else {
1503                                 COPY_UP(AV_RB16, AV_WL16)
1504                             }
1505                         } else {
1506                             if(isBE(c->dstFormat)){
1507                                 COPY_UP(AV_RL16, AV_WB16)
1508                             } else {
1509                                 COPY_UP(AV_RL16, AV_WL16)
1510                             }
1511                         }
1512                         dstPtr2 += dstStride[plane]/2;
1513                         srcPtr2 += srcStride[plane]/2;
1514                     }
1515                 } else {
1516                     if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1517                         if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1518                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , )
1519                         } else {
1520                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , av_bswap16)
1521                         }
1522                     }else{
1523                         if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1524                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, )
1525                         } else {
1526                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, av_bswap16)
1527                         }
1528                     }
1529                 }
1530             } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
1531                       isBE(c->srcFormat) != isBE(c->dstFormat)) {
1532
1533                 for (i = 0; i < height; i++) {
1534                     for (j = 0; j < length; j++)
1535                         ((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);
1536                     srcPtr += srcStride[plane];
1537                     dstPtr += dstStride[plane];
1538                 }
1539             } else if (dstStride[plane] == srcStride[plane] &&
1540                        srcStride[plane] > 0 && srcStride[plane] == length) {
1541                 memcpy(dst[plane] + dstStride[plane] * y, src[plane],
1542                        height * dstStride[plane]);
1543             } else {
1544                 if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
1545                     length *= 2;
1546                 else if (desc_src->comp[0].depth == 1)
1547                     length >>= 3; // monowhite/black
1548                 for (i = 0; i < height; i++) {
1549                     memcpy(dstPtr, srcPtr, length);
1550                     srcPtr += srcStride[plane];
1551                     dstPtr += dstStride[plane];
1552                 }
1553             }
1554         }
1555     }
1556     return srcSliceH;
1557 }
1558
1559
1560 #define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt)          \
1561     ((src_fmt == pix_fmt ## BE && dst_fmt == pix_fmt ## LE) ||     \
1562      (src_fmt == pix_fmt ## LE && dst_fmt == pix_fmt ## BE))
1563
1564
1565 void ff_get_unscaled_swscale(SwsContext *c)
1566 {
1567     const enum AVPixelFormat srcFormat = c->srcFormat;
1568     const enum AVPixelFormat dstFormat = c->dstFormat;
1569     const int flags = c->flags;
1570     const int dstH = c->dstH;
1571     int needsDither;
1572
1573     needsDither = isAnyRGB(dstFormat) &&
1574             c->dstFormatBpp < 24 &&
1575            (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
1576
1577     /* yv12_to_nv12 */
1578     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
1579         (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
1580         c->swscale = planarToNv12Wrapper;
1581     }
1582     /* nv12_to_yv12 */
1583     if (dstFormat == AV_PIX_FMT_YUV420P &&
1584         (srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
1585         c->swscale = nv12ToPlanarWrapper;
1586     }
1587     /* yuv2bgr */
1588     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
1589          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
1590         !(flags & SWS_ACCURATE_RND) && (c->dither == SWS_DITHER_BAYER || c->dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
1591         c->swscale = ff_yuv2rgb_get_func_ptr(c);
1592     }
1593
1594     if (srcFormat == AV_PIX_FMT_YUV410P && !(dstH & 3) &&
1595         (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1596         !(flags & SWS_BITEXACT)) {
1597         c->swscale = yvu9ToYv12Wrapper;
1598     }
1599
1600     /* bgr24toYV12 */
1601     if (srcFormat == AV_PIX_FMT_BGR24 &&
1602         (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1603         !(flags & SWS_ACCURATE_RND))
1604         c->swscale = bgr24ToYv12Wrapper;
1605
1606     /* RGB/BGR -> RGB/BGR (no dither needed forms) */
1607     if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
1608         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
1609         c->swscale = rgbToRgbWrapper;
1610
1611     /* RGB to planar RGB */
1612     if ((srcFormat == AV_PIX_FMT_GBRP && dstFormat == AV_PIX_FMT_GBRAP) ||
1613         (srcFormat == AV_PIX_FMT_GBRAP && dstFormat == AV_PIX_FMT_GBRP))
1614         c->swscale = planarRgbToplanarRgbWrapper;
1615
1616 #define isByteRGB(f) (             \
1617         f == AV_PIX_FMT_RGB32   || \
1618         f == AV_PIX_FMT_RGB32_1 || \
1619         f == AV_PIX_FMT_RGB24   || \
1620         f == AV_PIX_FMT_BGR32   || \
1621         f == AV_PIX_FMT_BGR32_1 || \
1622         f == AV_PIX_FMT_BGR24)
1623
1624     if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
1625         c->swscale = planarRgbToRgbWrapper;
1626
1627     if ((srcFormat == AV_PIX_FMT_RGB48LE  || srcFormat == AV_PIX_FMT_RGB48BE  ||
1628          srcFormat == AV_PIX_FMT_BGR48LE  || srcFormat == AV_PIX_FMT_BGR48BE  ||
1629          srcFormat == AV_PIX_FMT_RGBA64LE || srcFormat == AV_PIX_FMT_RGBA64BE ||
1630          srcFormat == AV_PIX_FMT_BGRA64LE || srcFormat == AV_PIX_FMT_BGRA64BE) &&
1631         (dstFormat == AV_PIX_FMT_GBRP9LE  || dstFormat == AV_PIX_FMT_GBRP9BE  ||
1632          dstFormat == AV_PIX_FMT_GBRP10LE || dstFormat == AV_PIX_FMT_GBRP10BE ||
1633          dstFormat == AV_PIX_FMT_GBRP12LE || dstFormat == AV_PIX_FMT_GBRP12BE ||
1634          dstFormat == AV_PIX_FMT_GBRP14LE || dstFormat == AV_PIX_FMT_GBRP14BE ||
1635          dstFormat == AV_PIX_FMT_GBRP16LE || dstFormat == AV_PIX_FMT_GBRP16BE ||
1636          dstFormat == AV_PIX_FMT_GBRAP16LE || dstFormat == AV_PIX_FMT_GBRAP16BE ))
1637         c->swscale = Rgb16ToPlanarRgb16Wrapper;
1638
1639     if ((srcFormat == AV_PIX_FMT_GBRP9LE  || srcFormat == AV_PIX_FMT_GBRP9BE  ||
1640          srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
1641          srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
1642          srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
1643          srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE ||
1644          srcFormat == AV_PIX_FMT_GBRAP16LE || srcFormat == AV_PIX_FMT_GBRAP16BE) &&
1645         (dstFormat == AV_PIX_FMT_RGB48LE  || dstFormat == AV_PIX_FMT_RGB48BE  ||
1646          dstFormat == AV_PIX_FMT_BGR48LE  || dstFormat == AV_PIX_FMT_BGR48BE  ||
1647          dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
1648          dstFormat == AV_PIX_FMT_BGRA64LE || dstFormat == AV_PIX_FMT_BGRA64BE))
1649         c->swscale = planarRgb16ToRgb16Wrapper;
1650
1651     if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth == 8 &&
1652         isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
1653         c->swscale = rgbToPlanarRgbWrapper;
1654
1655     if (isBayer(srcFormat)) {
1656         if (dstFormat == AV_PIX_FMT_RGB24)
1657             c->swscale = bayer_to_rgb24_wrapper;
1658         else if (dstFormat == AV_PIX_FMT_YUV420P)
1659             c->swscale = bayer_to_yv12_wrapper;
1660         else if (!isBayer(dstFormat)) {
1661             av_log(c, AV_LOG_ERROR, "unsupported bayer conversion\n");
1662             av_assert0(0);
1663         }
1664     }
1665
1666     /* bswap 16 bits per pixel/component packed formats */
1667     if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_BGGR16) ||
1668         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_RGGB16) ||
1669         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GBRG16) ||
1670         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GRBG16) ||
1671         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) ||
1672         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR48)  ||
1673         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
1674         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) ||
1675         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) ||
1676         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
1677         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) ||
1678         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YA16)   ||
1679         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_AYUV64) ||
1680         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP9)  ||
1681         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP10) ||
1682         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP12) ||
1683         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP14) ||
1684         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP16) ||
1685         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP16) ||
1686         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) ||
1687         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48)  ||
1688         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
1689         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) ||
1690         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) ||
1691         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
1692         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12)  ||
1693         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P9)  ||
1694         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P10) ||
1695         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P12) ||
1696         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P14) ||
1697         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P16) ||
1698         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P9)  ||
1699         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P10) ||
1700         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P12) ||
1701         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P14) ||
1702         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P16) ||
1703         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV440P10) ||
1704         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV440P12) ||
1705         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P9)  ||
1706         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P10) ||
1707         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P12) ||
1708         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P14) ||
1709         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P16))
1710         c->swscale = packed_16bpc_bswap;
1711
1712     if (usePal(srcFormat) && isByteRGB(dstFormat))
1713         c->swscale = palToRgbWrapper;
1714
1715     if (srcFormat == AV_PIX_FMT_YUV422P) {
1716         if (dstFormat == AV_PIX_FMT_YUYV422)
1717             c->swscale = yuv422pToYuy2Wrapper;
1718         else if (dstFormat == AV_PIX_FMT_UYVY422)
1719             c->swscale = yuv422pToUyvyWrapper;
1720     }
1721
1722     /* LQ converters if -sws 0 or -sws 4*/
1723     if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
1724         /* yv12_to_yuy2 */
1725         if (srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) {
1726             if (dstFormat == AV_PIX_FMT_YUYV422)
1727                 c->swscale = planarToYuy2Wrapper;
1728             else if (dstFormat == AV_PIX_FMT_UYVY422)
1729                 c->swscale = planarToUyvyWrapper;
1730         }
1731     }
1732     if (srcFormat == AV_PIX_FMT_YUYV422 &&
1733        (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1734         c->swscale = yuyvToYuv420Wrapper;
1735     if (srcFormat == AV_PIX_FMT_UYVY422 &&
1736        (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1737         c->swscale = uyvyToYuv420Wrapper;
1738     if (srcFormat == AV_PIX_FMT_YUYV422 && dstFormat == AV_PIX_FMT_YUV422P)
1739         c->swscale = yuyvToYuv422Wrapper;
1740     if (srcFormat == AV_PIX_FMT_UYVY422 && dstFormat == AV_PIX_FMT_YUV422P)
1741         c->swscale = uyvyToYuv422Wrapper;
1742
1743 #define isPlanarGray(x) (isGray(x) && (x) != AV_PIX_FMT_YA8 && (x) != AV_PIX_FMT_YA16LE && (x) != AV_PIX_FMT_YA16BE)
1744     /* simple copy */
1745     if ( srcFormat == dstFormat ||
1746         (srcFormat == AV_PIX_FMT_YUVA420P && dstFormat == AV_PIX_FMT_YUV420P) ||
1747         (srcFormat == AV_PIX_FMT_YUV420P && dstFormat == AV_PIX_FMT_YUVA420P) ||
1748         (isPlanarYUV(srcFormat) && isPlanarGray(dstFormat)) ||
1749         (isPlanarYUV(dstFormat) && isPlanarGray(srcFormat)) ||
1750         (isPlanarGray(dstFormat) && isPlanarGray(srcFormat)) ||
1751         (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) &&
1752          c->chrDstHSubSample == c->chrSrcHSubSample &&
1753          c->chrDstVSubSample == c->chrSrcVSubSample &&
1754          dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 &&
1755          srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21))
1756     {
1757         if (isPacked(c->srcFormat))
1758             c->swscale = packedCopyWrapper;
1759         else /* Planar YUV or gray */
1760             c->swscale = planarCopyWrapper;
1761     }
1762
1763     if (ARCH_PPC)
1764         ff_get_unscaled_swscale_ppc(c);
1765 //     if (ARCH_ARM)
1766 //         ff_get_unscaled_swscale_arm(c);
1767 }
1768
1769 /* Convert the palette to the same packed 32-bit format as the palette */
1770 void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst,
1771                                    int num_pixels, const uint8_t *palette)
1772 {
1773     int i;
1774
1775     for (i = 0; i < num_pixels; i++)
1776         ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
1777 }
1778
1779 /* Palette format: ABCD -> dst format: ABC */
1780 void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst,
1781                                    int num_pixels, const uint8_t *palette)
1782 {
1783     int i;
1784
1785     for (i = 0; i < num_pixels; i++) {
1786         //FIXME slow?
1787         dst[0] = palette[src[i] * 4 + 0];
1788         dst[1] = palette[src[i] * 4 + 1];
1789         dst[2] = palette[src[i] * 4 + 2];
1790         dst += 3;
1791     }
1792 }