Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / ffmpeg / 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_GRAY8A) {
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, const uint8_t *src[],
882                                        int srcStride[], int srcSliceY, int srcSliceH,
883                                        uint8_t *dst[], int dstStride[])
884 {
885     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
886               dst[0], dstStride[0]);
887     copyPlane(src[1], srcStride[1], srcSliceY, srcSliceH, c->srcW,
888               dst[1], dstStride[1]);
889     copyPlane(src[2], srcStride[2], srcSliceY, srcSliceH, c->srcW,
890               dst[2], dstStride[2]);
891     if (dst[3])
892         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
893
894     return srcSliceH;
895 }
896
897 static void packedtogbr24p(const uint8_t *src, int srcStride,
898                            uint8_t *dst[], int dstStride[], int srcSliceH,
899                            int alpha_first, int inc_size, int width)
900 {
901     uint8_t *dest[3];
902     int x, h;
903
904     dest[0] = dst[0];
905     dest[1] = dst[1];
906     dest[2] = dst[2];
907
908     if (alpha_first)
909         src++;
910
911     for (h = 0; h < srcSliceH; h++) {
912         for (x = 0; x < width; x++) {
913             dest[0][x] = src[0];
914             dest[1][x] = src[1];
915             dest[2][x] = src[2];
916
917             src += inc_size;
918         }
919         src     += srcStride - width * inc_size;
920         dest[0] += dstStride[0];
921         dest[1] += dstStride[1];
922         dest[2] += dstStride[2];
923     }
924 }
925
926 static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[],
927                                  int srcStride[], int srcSliceY, int srcSliceH,
928                                  uint8_t *dst[], int dstStride[])
929 {
930     int alpha_first = 0;
931     int stride102[] = { dstStride[1], dstStride[0], dstStride[2] };
932     int stride201[] = { dstStride[2], dstStride[0], dstStride[1] };
933     uint8_t *dst102[] = { dst[1] + srcSliceY * dstStride[1],
934                           dst[0] + srcSliceY * dstStride[0],
935                           dst[2] + srcSliceY * dstStride[2] };
936     uint8_t *dst201[] = { dst[2] + srcSliceY * dstStride[2],
937                           dst[0] + srcSliceY * dstStride[0],
938                           dst[1] + srcSliceY * dstStride[1] };
939
940     switch (c->srcFormat) {
941     case AV_PIX_FMT_RGB24:
942         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
943                        stride201, srcSliceH, alpha_first, 3, c->srcW);
944         break;
945     case AV_PIX_FMT_BGR24:
946         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
947                        stride102, srcSliceH, alpha_first, 3, c->srcW);
948         break;
949     case AV_PIX_FMT_ARGB:
950         alpha_first = 1;
951     case AV_PIX_FMT_RGBA:
952         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
953                        stride201, srcSliceH, alpha_first, 4, c->srcW);
954         break;
955     case AV_PIX_FMT_ABGR:
956         alpha_first = 1;
957     case AV_PIX_FMT_BGRA:
958         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
959                        stride102, srcSliceH, alpha_first, 4, c->srcW);
960         break;
961     default:
962         av_log(c, AV_LOG_ERROR,
963                "unsupported planar RGB conversion %s -> %s\n",
964                av_get_pix_fmt_name(c->srcFormat),
965                av_get_pix_fmt_name(c->dstFormat));
966     }
967
968     return srcSliceH;
969 }
970
971 #define BAYER_GBRG
972 #define BAYER_8
973 #define BAYER_RENAME(x) bayer_gbrg8_to_##x
974 #include "bayer_template.c"
975
976 #define BAYER_GBRG
977 #define BAYER_16LE
978 #define BAYER_RENAME(x) bayer_gbrg16le_to_##x
979 #include "bayer_template.c"
980
981 #define BAYER_GBRG
982 #define BAYER_16BE
983 #define BAYER_RENAME(x) bayer_gbrg16be_to_##x
984 #include "bayer_template.c"
985
986 #define BAYER_GRBG
987 #define BAYER_8
988 #define BAYER_RENAME(x) bayer_grbg8_to_##x
989 #include "bayer_template.c"
990
991 #define BAYER_GRBG
992 #define BAYER_16LE
993 #define BAYER_RENAME(x) bayer_grbg16le_to_##x
994 #include "bayer_template.c"
995
996 #define BAYER_GRBG
997 #define BAYER_16BE
998 #define BAYER_RENAME(x) bayer_grbg16be_to_##x
999 #include "bayer_template.c"
1000
1001 #define BAYER_BGGR
1002 #define BAYER_8
1003 #define BAYER_RENAME(x) bayer_bggr8_to_##x
1004 #include "bayer_template.c"
1005
1006 #define BAYER_BGGR
1007 #define BAYER_16LE
1008 #define BAYER_RENAME(x) bayer_bggr16le_to_##x
1009 #include "bayer_template.c"
1010
1011 #define BAYER_BGGR
1012 #define BAYER_16BE
1013 #define BAYER_RENAME(x) bayer_bggr16be_to_##x
1014 #include "bayer_template.c"
1015
1016 #define BAYER_RGGB
1017 #define BAYER_8
1018 #define BAYER_RENAME(x) bayer_rggb8_to_##x
1019 #include "bayer_template.c"
1020
1021 #define BAYER_RGGB
1022 #define BAYER_16LE
1023 #define BAYER_RENAME(x) bayer_rggb16le_to_##x
1024 #include "bayer_template.c"
1025
1026 #define BAYER_RGGB
1027 #define BAYER_16BE
1028 #define BAYER_RENAME(x) bayer_rggb16be_to_##x
1029 #include "bayer_template.c"
1030
1031 static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1032                                   int srcSliceH, uint8_t* dst[], int dstStride[])
1033 {
1034     uint8_t *dstPtr= dst[0];
1035     const uint8_t *srcPtr= src[0];
1036     int i;
1037     void (*copy)       (const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
1038     void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
1039
1040     switch(c->srcFormat) {
1041 #define CASE(pixfmt, prefix) \
1042     case pixfmt: copy        = bayer_##prefix##_to_rgb24_copy; \
1043                  interpolate = bayer_##prefix##_to_rgb24_interpolate; \
1044                  break;
1045     CASE(AV_PIX_FMT_BAYER_BGGR8,    bggr8)
1046     CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le)
1047     CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be)
1048     CASE(AV_PIX_FMT_BAYER_RGGB8,    rggb8)
1049     CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le)
1050     CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be)
1051     CASE(AV_PIX_FMT_BAYER_GBRG8,    gbrg8)
1052     CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le)
1053     CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be)
1054     CASE(AV_PIX_FMT_BAYER_GRBG8,    grbg8)
1055     CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le)
1056     CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be)
1057 #undef CASE
1058     default: return 0;
1059     }
1060
1061     copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1062     srcPtr += 2 * srcStride[0];
1063     dstPtr += 2 * dstStride[0];
1064
1065     for (i = 2; i < srcSliceH - 2; i += 2) {
1066         interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1067         srcPtr += 2 * srcStride[0];
1068         dstPtr += 2 * dstStride[0];
1069     }
1070
1071     copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1072     return srcSliceH;
1073 }
1074
1075 static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1076                                  int srcSliceH, uint8_t* dst[], int dstStride[])
1077 {
1078     const uint8_t *srcPtr= src[0];
1079     uint8_t *dstY= dst[0];
1080     uint8_t *dstU= dst[1];
1081     uint8_t *dstV= dst[2];
1082     int i;
1083     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);
1084     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);
1085
1086     switch(c->srcFormat) {
1087 #define CASE(pixfmt, prefix) \
1088     case pixfmt: copy        = bayer_##prefix##_to_yv12_copy; \
1089                  interpolate = bayer_##prefix##_to_yv12_interpolate; \
1090                  break;
1091     CASE(AV_PIX_FMT_BAYER_BGGR8,    bggr8)
1092     CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le)
1093     CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be)
1094     CASE(AV_PIX_FMT_BAYER_RGGB8,    rggb8)
1095     CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le)
1096     CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be)
1097     CASE(AV_PIX_FMT_BAYER_GBRG8,    gbrg8)
1098     CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le)
1099     CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be)
1100     CASE(AV_PIX_FMT_BAYER_GRBG8,    grbg8)
1101     CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le)
1102     CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be)
1103 #undef CASE
1104     default: return 0;
1105     }
1106
1107     copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1108     srcPtr += 2 * srcStride[0];
1109     dstY   += 2 * dstStride[0];
1110     dstU   +=     dstStride[1];
1111     dstV   +=     dstStride[1];
1112
1113     for (i = 2; i < srcSliceH - 2; i += 2) {
1114         interpolate(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1115         srcPtr += 2 * srcStride[0];
1116         dstY   += 2 * dstStride[0];
1117         dstU   +=     dstStride[1];
1118         dstV   +=     dstStride[1];
1119     }
1120
1121     copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1122     return srcSliceH;
1123 }
1124
1125 #define isRGBA32(x) (            \
1126            (x) == AV_PIX_FMT_ARGB   \
1127         || (x) == AV_PIX_FMT_RGBA   \
1128         || (x) == AV_PIX_FMT_BGRA   \
1129         || (x) == AV_PIX_FMT_ABGR   \
1130         )
1131
1132 #define isRGBA64(x) (                \
1133            (x) == AV_PIX_FMT_RGBA64LE   \
1134         || (x) == AV_PIX_FMT_RGBA64BE   \
1135         || (x) == AV_PIX_FMT_BGRA64LE   \
1136         || (x) == AV_PIX_FMT_BGRA64BE   \
1137         )
1138
1139 #define isRGB48(x) (                \
1140            (x) == AV_PIX_FMT_RGB48LE   \
1141         || (x) == AV_PIX_FMT_RGB48BE   \
1142         || (x) == AV_PIX_FMT_BGR48LE   \
1143         || (x) == AV_PIX_FMT_BGR48BE   \
1144         )
1145
1146 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1147 typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
1148 static rgbConvFn findRgbConvFn(SwsContext *c)
1149 {
1150     const enum AVPixelFormat srcFormat = c->srcFormat;
1151     const enum AVPixelFormat dstFormat = c->dstFormat;
1152     const int srcId = c->srcFormatBpp;
1153     const int dstId = c->dstFormatBpp;
1154     rgbConvFn conv = NULL;
1155
1156 #define IS_NOT_NE(bpp, desc) \
1157     (((bpp + 7) >> 3) == 2 && \
1158      (!(desc->flags & AV_PIX_FMT_FLAG_BE) != !HAVE_BIGENDIAN))
1159
1160 #define CONV_IS(src, dst) (srcFormat == AV_PIX_FMT_##src && dstFormat == AV_PIX_FMT_##dst)
1161
1162     if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
1163         if (     CONV_IS(ABGR, RGBA)
1164               || CONV_IS(ARGB, BGRA)
1165               || CONV_IS(BGRA, ARGB)
1166               || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
1167         else if (CONV_IS(ABGR, ARGB)
1168               || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
1169         else if (CONV_IS(ABGR, BGRA)
1170               || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
1171         else if (CONV_IS(BGRA, RGBA)
1172               || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
1173         else if (CONV_IS(BGRA, ABGR)
1174               || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
1175     } else if (isRGB48(srcFormat) && isRGB48(dstFormat)) {
1176         if      (CONV_IS(RGB48LE, BGR48LE)
1177               || CONV_IS(BGR48LE, RGB48LE)
1178               || CONV_IS(RGB48BE, BGR48BE)
1179               || CONV_IS(BGR48BE, RGB48BE)) conv = rgb48tobgr48_nobswap;
1180         else if (CONV_IS(RGB48LE, BGR48BE)
1181               || CONV_IS(BGR48LE, RGB48BE)
1182               || CONV_IS(RGB48BE, BGR48LE)
1183               || CONV_IS(BGR48BE, RGB48LE)) conv = rgb48tobgr48_bswap;
1184     } else if (isRGBA64(srcFormat) && isRGB48(dstFormat)) {
1185         if      (CONV_IS(RGBA64LE, BGR48LE)
1186               || CONV_IS(BGRA64LE, RGB48LE)
1187               || CONV_IS(RGBA64BE, BGR48BE)
1188               || CONV_IS(BGRA64BE, RGB48BE)) conv = rgb64tobgr48_nobswap;
1189         else if (CONV_IS(RGBA64LE, BGR48BE)
1190               || CONV_IS(BGRA64LE, RGB48BE)
1191               || CONV_IS(RGBA64BE, BGR48LE)
1192               || CONV_IS(BGRA64BE, RGB48LE)) conv = rgb64tobgr48_bswap;
1193         else if (CONV_IS(RGBA64LE, RGB48LE)
1194               || CONV_IS(BGRA64LE, BGR48LE)
1195               || CONV_IS(RGBA64BE, RGB48BE)
1196               || CONV_IS(BGRA64BE, BGR48BE)) conv = rgb64to48_nobswap;
1197         else if (CONV_IS(RGBA64LE, RGB48BE)
1198               || CONV_IS(BGRA64LE, BGR48BE)
1199               || CONV_IS(RGBA64BE, RGB48LE)
1200               || CONV_IS(BGRA64BE, BGR48LE)) conv = rgb64to48_bswap;
1201     } else
1202     /* BGR -> BGR */
1203     if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
1204         (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
1205         switch (srcId | (dstId << 16)) {
1206         case 0x000F000C: conv = rgb12to15; break;
1207         case 0x000F0010: conv = rgb16to15; break;
1208         case 0x000F0018: conv = rgb24to15; break;
1209         case 0x000F0020: conv = rgb32to15; break;
1210         case 0x0010000F: conv = rgb15to16; break;
1211         case 0x00100018: conv = rgb24to16; break;
1212         case 0x00100020: conv = rgb32to16; break;
1213         case 0x0018000F: conv = rgb15to24; break;
1214         case 0x00180010: conv = rgb16to24; break;
1215         case 0x00180020: conv = rgb32to24; break;
1216         case 0x0020000F: conv = rgb15to32; break;
1217         case 0x00200010: conv = rgb16to32; break;
1218         case 0x00200018: conv = rgb24to32; break;
1219         }
1220     } else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) ||
1221                (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
1222         switch (srcId | (dstId << 16)) {
1223         case 0x000C000C: conv = rgb12tobgr12; break;
1224         case 0x000F000F: conv = rgb15tobgr15; break;
1225         case 0x000F0010: conv = rgb16tobgr15; break;
1226         case 0x000F0018: conv = rgb24tobgr15; break;
1227         case 0x000F0020: conv = rgb32tobgr15; break;
1228         case 0x0010000F: conv = rgb15tobgr16; break;
1229         case 0x00100010: conv = rgb16tobgr16; break;
1230         case 0x00100018: conv = rgb24tobgr16; break;
1231         case 0x00100020: conv = rgb32tobgr16; break;
1232         case 0x0018000F: conv = rgb15tobgr24; break;
1233         case 0x00180010: conv = rgb16tobgr24; break;
1234         case 0x00180018: conv = rgb24tobgr24; break;
1235         case 0x00180020: conv = rgb32tobgr24; break;
1236         case 0x0020000F: conv = rgb15tobgr32; break;
1237         case 0x00200010: conv = rgb16tobgr32; break;
1238         case 0x00200018: conv = rgb24tobgr32; break;
1239         }
1240     }
1241
1242     if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0)
1243         return NULL;
1244
1245     return conv;
1246 }
1247
1248 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1249 static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
1250                            int srcSliceY, int srcSliceH, uint8_t *dst[],
1251                            int dstStride[])
1252
1253 {
1254     const enum AVPixelFormat srcFormat = c->srcFormat;
1255     const enum AVPixelFormat dstFormat = c->dstFormat;
1256     const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1257     const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1258     const int srcBpp = (c->srcFormatBpp + 7) >> 3;
1259     const int dstBpp = (c->dstFormatBpp + 7) >> 3;
1260     rgbConvFn conv = findRgbConvFn(c);
1261
1262     if (!conv) {
1263         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
1264                av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1265     } else {
1266         const uint8_t *srcPtr = src[0];
1267               uint8_t *dstPtr = dst[0];
1268         int src_bswap = IS_NOT_NE(c->srcFormatBpp, desc_src);
1269         int dst_bswap = IS_NOT_NE(c->dstFormatBpp, desc_dst);
1270
1271         if ((srcFormat == AV_PIX_FMT_RGB32_1 || srcFormat == AV_PIX_FMT_BGR32_1) &&
1272             !isRGBA32(dstFormat))
1273             srcPtr += ALT32_CORR;
1274
1275         if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) &&
1276             !isRGBA32(srcFormat)) {
1277             int i;
1278             av_assert0(ALT32_CORR == 1);
1279             for (i = 0; i < srcSliceH; i++)
1280                 dstPtr[dstStride[0] * (srcSliceY + i)] = 255;
1281             dstPtr += ALT32_CORR;
1282         }
1283
1284         if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
1285             !(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap)
1286             conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
1287                  srcSliceH * srcStride[0]);
1288         else {
1289             int i, j;
1290             dstPtr += dstStride[0] * srcSliceY;
1291
1292             for (i = 0; i < srcSliceH; i++) {
1293                 if(src_bswap) {
1294                     for(j=0; j<c->srcW; j++)
1295                         ((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]);
1296                     conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp);
1297                 }else
1298                     conv(srcPtr, dstPtr, c->srcW * srcBpp);
1299                 if(dst_bswap)
1300                     for(j=0; j<c->srcW; j++)
1301                         ((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]);
1302                 srcPtr += srcStride[0];
1303                 dstPtr += dstStride[0];
1304             }
1305         }
1306     }
1307     return srcSliceH;
1308 }
1309
1310 static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
1311                               int srcStride[], int srcSliceY, int srcSliceH,
1312                               uint8_t *dst[], int dstStride[])
1313 {
1314     ff_rgb24toyv12(
1315         src[0],
1316         dst[0] +  srcSliceY       * dstStride[0],
1317         dst[1] + (srcSliceY >> 1) * dstStride[1],
1318         dst[2] + (srcSliceY >> 1) * dstStride[2],
1319         c->srcW, srcSliceH,
1320         dstStride[0], dstStride[1], srcStride[0],
1321         c->input_rgb2yuv_table);
1322     if (dst[3])
1323         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1324     return srcSliceH;
1325 }
1326
1327 static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
1328                              int srcStride[], int srcSliceY, int srcSliceH,
1329                              uint8_t *dst[], int dstStride[])
1330 {
1331     copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
1332               dst[0], dstStride[0]);
1333
1334     planar2x(src[1], dst[1] + dstStride[1] * (srcSliceY >> 1), c->chrSrcW,
1335              srcSliceH >> 2, srcStride[1], dstStride[1]);
1336     planar2x(src[2], dst[2] + dstStride[2] * (srcSliceY >> 1), c->chrSrcW,
1337              srcSliceH >> 2, srcStride[2], dstStride[2]);
1338     if (dst[3])
1339         fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1340     return srcSliceH;
1341 }
1342
1343 /* unscaled copy like stuff (assumes nearly identical formats) */
1344 static int packedCopyWrapper(SwsContext *c, const uint8_t *src[],
1345                              int srcStride[], int srcSliceY, int srcSliceH,
1346                              uint8_t *dst[], int dstStride[])
1347 {
1348     if (dstStride[0] == srcStride[0] && srcStride[0] > 0)
1349         memcpy(dst[0] + dstStride[0] * srcSliceY, src[0], srcSliceH * dstStride[0]);
1350     else {
1351         int i;
1352         const uint8_t *srcPtr = src[0];
1353         uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
1354         int length = 0;
1355
1356         /* universal length finder */
1357         while (length + c->srcW <= FFABS(dstStride[0]) &&
1358                length + c->srcW <= FFABS(srcStride[0]))
1359             length += c->srcW;
1360         av_assert1(length != 0);
1361
1362         for (i = 0; i < srcSliceH; i++) {
1363             memcpy(dstPtr, srcPtr, length);
1364             srcPtr += srcStride[0];
1365             dstPtr += dstStride[0];
1366         }
1367     }
1368     return srcSliceH;
1369 }
1370
1371 #define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
1372     uint16_t scale= dither_scale[dst_depth-1][src_depth-1];\
1373     int shift= src_depth-dst_depth + dither_scale[src_depth-2][dst_depth-1];\
1374     for (i = 0; i < height; i++) {\
1375         const uint8_t *dither= dithers[src_depth-9][i&7];\
1376         for (j = 0; j < length-7; j+=8){\
1377             dst[j+0] = dbswap((bswap(src[j+0]) + dither[0])*scale>>shift);\
1378             dst[j+1] = dbswap((bswap(src[j+1]) + dither[1])*scale>>shift);\
1379             dst[j+2] = dbswap((bswap(src[j+2]) + dither[2])*scale>>shift);\
1380             dst[j+3] = dbswap((bswap(src[j+3]) + dither[3])*scale>>shift);\
1381             dst[j+4] = dbswap((bswap(src[j+4]) + dither[4])*scale>>shift);\
1382             dst[j+5] = dbswap((bswap(src[j+5]) + dither[5])*scale>>shift);\
1383             dst[j+6] = dbswap((bswap(src[j+6]) + dither[6])*scale>>shift);\
1384             dst[j+7] = dbswap((bswap(src[j+7]) + dither[7])*scale>>shift);\
1385         }\
1386         for (; j < length; j++)\
1387             dst[j] = dbswap((bswap(src[j]) + dither[j&7])*scale>>shift);\
1388         dst += dstStride;\
1389         src += srcStride;\
1390     }
1391
1392 static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
1393                              int srcStride[], int srcSliceY, int srcSliceH,
1394                              uint8_t *dst[], int dstStride[])
1395 {
1396     const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1397     const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1398     int plane, i, j;
1399     for (plane = 0; plane < 4; plane++) {
1400         int length = (plane == 0 || plane == 3) ? c->srcW  : FF_CEIL_RSHIFT(c->srcW,   c->chrDstHSubSample);
1401         int y =      (plane == 0 || plane == 3) ? srcSliceY: FF_CEIL_RSHIFT(srcSliceY, c->chrDstVSubSample);
1402         int height = (plane == 0 || plane == 3) ? srcSliceH: FF_CEIL_RSHIFT(srcSliceH, c->chrDstVSubSample);
1403         const uint8_t *srcPtr = src[plane];
1404         uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
1405         int shiftonly= plane==1 || plane==2 || (!c->srcRange && plane==0);
1406
1407         if (!dst[plane])
1408             continue;
1409         // ignore palette for GRAY8
1410         if (plane == 1 && !dst[2]) continue;
1411         if (!src[plane] || (plane == 1 && !src[2])) {
1412             if (is16BPS(c->dstFormat) || isNBPS(c->dstFormat)) {
1413                 fillPlane16(dst[plane], dstStride[plane], length, height, y,
1414                         plane == 3, desc_dst->comp[plane].depth_minus1,
1415                         isBE(c->dstFormat));
1416             } else {
1417                 fillPlane(dst[plane], dstStride[plane], length, height, y,
1418                         (plane == 3) ? 255 : 128);
1419             }
1420         } else {
1421             if(isNBPS(c->srcFormat) || isNBPS(c->dstFormat)
1422                || (is16BPS(c->srcFormat) != is16BPS(c->dstFormat))
1423             ) {
1424                 const int src_depth = desc_src->comp[plane].depth_minus1 + 1;
1425                 const int dst_depth = desc_dst->comp[plane].depth_minus1 + 1;
1426                 const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
1427                 uint16_t *dstPtr2 = (uint16_t*)dstPtr;
1428
1429                 if (dst_depth == 8) {
1430                     if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1431                         DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , )
1432                     } else {
1433                         DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, av_bswap16, )
1434                     }
1435                 } else if (src_depth == 8) {
1436                     for (i = 0; i < height; i++) {
1437                         #define COPY816(w)\
1438                         if(shiftonly){\
1439                             for (j = 0; j < length; j++)\
1440                                 w(&dstPtr2[j], srcPtr[j]<<(dst_depth-8));\
1441                         }else{\
1442                             for (j = 0; j < length; j++)\
1443                                 w(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) |\
1444                                                (srcPtr[j]>>(2*8-dst_depth)));\
1445                         }
1446                         if(isBE(c->dstFormat)){
1447                             COPY816(AV_WB16)
1448                         } else {
1449                             COPY816(AV_WL16)
1450                         }
1451                         dstPtr2 += dstStride[plane]/2;
1452                         srcPtr  += srcStride[plane];
1453                     }
1454                 } else if (src_depth <= dst_depth) {
1455                     for (i = 0; i < height; i++) {
1456                         j = 0;
1457                         if(isBE(c->srcFormat) == HAVE_BIGENDIAN &&
1458                            isBE(c->dstFormat) == HAVE_BIGENDIAN &&
1459                            shiftonly) {
1460                              unsigned shift = dst_depth - src_depth;
1461 #if HAVE_FAST_64BIT
1462 #define FAST_COPY_UP(shift) \
1463     for (; j < length - 3; j += 4) { \
1464         uint64_t v = AV_RN64A(srcPtr2 + j); \
1465         AV_WN64A(dstPtr2 + j, v << shift); \
1466     }
1467 #else
1468 #define FAST_COPY_UP(shift) \
1469     for (; j < length - 1; j += 2) { \
1470         uint32_t v = AV_RN32A(srcPtr2 + j); \
1471         AV_WN32A(dstPtr2 + j, v << shift); \
1472     }
1473 #endif
1474                              switch (shift)
1475                              {
1476                              case 6: FAST_COPY_UP(6); break;
1477                              case 7: FAST_COPY_UP(7); break;
1478                              }
1479                         }
1480 #define COPY_UP(r,w) \
1481     if(shiftonly){\
1482         for (; j < length; j++){ \
1483             unsigned int v= r(&srcPtr2[j]);\
1484             w(&dstPtr2[j], v<<(dst_depth-src_depth));\
1485         }\
1486     }else{\
1487         for (; j < length; j++){ \
1488             unsigned int v= r(&srcPtr2[j]);\
1489             w(&dstPtr2[j], (v<<(dst_depth-src_depth)) | \
1490                         (v>>(2*src_depth-dst_depth)));\
1491         }\
1492     }
1493                         if(isBE(c->srcFormat)){
1494                             if(isBE(c->dstFormat)){
1495                                 COPY_UP(AV_RB16, AV_WB16)
1496                             } else {
1497                                 COPY_UP(AV_RB16, AV_WL16)
1498                             }
1499                         } else {
1500                             if(isBE(c->dstFormat)){
1501                                 COPY_UP(AV_RL16, AV_WB16)
1502                             } else {
1503                                 COPY_UP(AV_RL16, AV_WL16)
1504                             }
1505                         }
1506                         dstPtr2 += dstStride[plane]/2;
1507                         srcPtr2 += srcStride[plane]/2;
1508                     }
1509                 } else {
1510                     if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1511                         if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1512                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , )
1513                         } else {
1514                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , av_bswap16)
1515                         }
1516                     }else{
1517                         if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1518                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, )
1519                         } else {
1520                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, av_bswap16)
1521                         }
1522                     }
1523                 }
1524             } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
1525                       isBE(c->srcFormat) != isBE(c->dstFormat)) {
1526
1527                 for (i = 0; i < height; i++) {
1528                     for (j = 0; j < length; j++)
1529                         ((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);
1530                     srcPtr += srcStride[plane];
1531                     dstPtr += dstStride[plane];
1532                 }
1533             } else if (dstStride[plane] == srcStride[plane] &&
1534                        srcStride[plane] > 0 && srcStride[plane] == length) {
1535                 memcpy(dst[plane] + dstStride[plane] * y, src[plane],
1536                        height * dstStride[plane]);
1537             } else {
1538                 if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
1539                     length *= 2;
1540                 else if (!desc_src->comp[0].depth_minus1)
1541                     length >>= 3; // monowhite/black
1542                 for (i = 0; i < height; i++) {
1543                     memcpy(dstPtr, srcPtr, length);
1544                     srcPtr += srcStride[plane];
1545                     dstPtr += dstStride[plane];
1546                 }
1547             }
1548         }
1549     }
1550     return srcSliceH;
1551 }
1552
1553
1554 #define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt)          \
1555     ((src_fmt == pix_fmt ## BE && dst_fmt == pix_fmt ## LE) ||     \
1556      (src_fmt == pix_fmt ## LE && dst_fmt == pix_fmt ## BE))
1557
1558
1559 void ff_get_unscaled_swscale(SwsContext *c)
1560 {
1561     const enum AVPixelFormat srcFormat = c->srcFormat;
1562     const enum AVPixelFormat dstFormat = c->dstFormat;
1563     const int flags = c->flags;
1564     const int dstH = c->dstH;
1565     int needsDither;
1566
1567     needsDither = isAnyRGB(dstFormat) &&
1568             c->dstFormatBpp < 24 &&
1569            (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
1570
1571     /* yv12_to_nv12 */
1572     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
1573         (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
1574         c->swscale = planarToNv12Wrapper;
1575     }
1576     /* nv12_to_yv12 */
1577     if (dstFormat == AV_PIX_FMT_YUV420P &&
1578         (srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
1579         c->swscale = nv12ToPlanarWrapper;
1580     }
1581     /* yuv2bgr */
1582     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
1583          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
1584         !(flags & SWS_ACCURATE_RND) && (c->dither == SWS_DITHER_BAYER || c->dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
1585         c->swscale = ff_yuv2rgb_get_func_ptr(c);
1586     }
1587
1588     if (srcFormat == AV_PIX_FMT_YUV410P && !(dstH & 3) &&
1589         (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1590         !(flags & SWS_BITEXACT)) {
1591         c->swscale = yvu9ToYv12Wrapper;
1592     }
1593
1594     /* bgr24toYV12 */
1595     if (srcFormat == AV_PIX_FMT_BGR24 &&
1596         (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1597         !(flags & SWS_ACCURATE_RND))
1598         c->swscale = bgr24ToYv12Wrapper;
1599
1600     /* RGB/BGR -> RGB/BGR (no dither needed forms) */
1601     if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
1602         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
1603         c->swscale = rgbToRgbWrapper;
1604
1605     if ((srcFormat == AV_PIX_FMT_GBRP && dstFormat == AV_PIX_FMT_GBRAP) ||
1606         (srcFormat == AV_PIX_FMT_GBRAP && dstFormat == AV_PIX_FMT_GBRP))
1607         c->swscale = planarRgbToplanarRgbWrapper;
1608
1609 #define isByteRGB(f) (             \
1610         f == AV_PIX_FMT_RGB32   || \
1611         f == AV_PIX_FMT_RGB32_1 || \
1612         f == AV_PIX_FMT_RGB24   || \
1613         f == AV_PIX_FMT_BGR32   || \
1614         f == AV_PIX_FMT_BGR32_1 || \
1615         f == AV_PIX_FMT_BGR24)
1616
1617     if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
1618         c->swscale = planarRgbToRgbWrapper;
1619
1620     if ((srcFormat == AV_PIX_FMT_RGB48LE  || srcFormat == AV_PIX_FMT_RGB48BE  ||
1621          srcFormat == AV_PIX_FMT_BGR48LE  || srcFormat == AV_PIX_FMT_BGR48BE  ||
1622          srcFormat == AV_PIX_FMT_RGBA64LE || srcFormat == AV_PIX_FMT_RGBA64BE ||
1623          srcFormat == AV_PIX_FMT_BGRA64LE || srcFormat == AV_PIX_FMT_BGRA64BE) &&
1624         (dstFormat == AV_PIX_FMT_GBRP9LE  || dstFormat == AV_PIX_FMT_GBRP9BE  ||
1625          dstFormat == AV_PIX_FMT_GBRP10LE || dstFormat == AV_PIX_FMT_GBRP10BE ||
1626          dstFormat == AV_PIX_FMT_GBRP12LE || dstFormat == AV_PIX_FMT_GBRP12BE ||
1627          dstFormat == AV_PIX_FMT_GBRP14LE || dstFormat == AV_PIX_FMT_GBRP14BE ||
1628          dstFormat == AV_PIX_FMT_GBRP16LE || dstFormat == AV_PIX_FMT_GBRP16BE ||
1629          dstFormat == AV_PIX_FMT_GBRAP16LE || dstFormat == AV_PIX_FMT_GBRAP16BE ))
1630         c->swscale = Rgb16ToPlanarRgb16Wrapper;
1631
1632     if ((srcFormat == AV_PIX_FMT_GBRP9LE  || srcFormat == AV_PIX_FMT_GBRP9BE  ||
1633          srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
1634          srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
1635          srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
1636          srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE ||
1637          srcFormat == AV_PIX_FMT_GBRAP16LE || srcFormat == AV_PIX_FMT_GBRAP16BE) &&
1638         (dstFormat == AV_PIX_FMT_RGB48LE  || dstFormat == AV_PIX_FMT_RGB48BE  ||
1639          dstFormat == AV_PIX_FMT_BGR48LE  || dstFormat == AV_PIX_FMT_BGR48BE  ||
1640          dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
1641          dstFormat == AV_PIX_FMT_BGRA64LE || dstFormat == AV_PIX_FMT_BGRA64BE))
1642         c->swscale = planarRgb16ToRgb16Wrapper;
1643
1644     if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth_minus1 == 7 &&
1645         isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
1646         c->swscale = rgbToPlanarRgbWrapper;
1647
1648     if (isBayer(srcFormat)) {
1649         if (dstFormat == AV_PIX_FMT_RGB24)
1650             c->swscale = bayer_to_rgb24_wrapper;
1651         else if (dstFormat == AV_PIX_FMT_YUV420P)
1652             c->swscale = bayer_to_yv12_wrapper;
1653         else if (!isBayer(dstFormat)) {
1654             av_log(c, AV_LOG_ERROR, "unsupported bayer conversion\n");
1655             av_assert0(0);
1656         }
1657     }
1658
1659     /* bswap 16 bits per pixel/component packed formats */
1660     if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_BGGR16) ||
1661         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_RGGB16) ||
1662         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GBRG16) ||
1663         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GRBG16) ||
1664         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) ||
1665         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR48)  ||
1666         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
1667         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) ||
1668         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) ||
1669         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
1670         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) ||
1671         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP9)  ||
1672         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP10) ||
1673         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP12) ||
1674         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP14) ||
1675         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP16) ||
1676         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP16) ||
1677         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) ||
1678         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48)  ||
1679         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
1680         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) ||
1681         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) ||
1682         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
1683         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12)  ||
1684         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P9)  ||
1685         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P10) ||
1686         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P12) ||
1687         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P14) ||
1688         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P16) ||
1689         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P9)  ||
1690         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P10) ||
1691         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P12) ||
1692         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P14) ||
1693         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P16) ||
1694         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P9)  ||
1695         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P10) ||
1696         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P12) ||
1697         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P14) ||
1698         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P16))
1699         c->swscale = packed_16bpc_bswap;
1700
1701     if (usePal(srcFormat) && isByteRGB(dstFormat))
1702         c->swscale = palToRgbWrapper;
1703
1704     if (srcFormat == AV_PIX_FMT_YUV422P) {
1705         if (dstFormat == AV_PIX_FMT_YUYV422)
1706             c->swscale = yuv422pToYuy2Wrapper;
1707         else if (dstFormat == AV_PIX_FMT_UYVY422)
1708             c->swscale = yuv422pToUyvyWrapper;
1709     }
1710
1711     /* LQ converters if -sws 0 or -sws 4*/
1712     if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
1713         /* yv12_to_yuy2 */
1714         if (srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) {
1715             if (dstFormat == AV_PIX_FMT_YUYV422)
1716                 c->swscale = planarToYuy2Wrapper;
1717             else if (dstFormat == AV_PIX_FMT_UYVY422)
1718                 c->swscale = planarToUyvyWrapper;
1719         }
1720     }
1721     if (srcFormat == AV_PIX_FMT_YUYV422 &&
1722        (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1723         c->swscale = yuyvToYuv420Wrapper;
1724     if (srcFormat == AV_PIX_FMT_UYVY422 &&
1725        (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1726         c->swscale = uyvyToYuv420Wrapper;
1727     if (srcFormat == AV_PIX_FMT_YUYV422 && dstFormat == AV_PIX_FMT_YUV422P)
1728         c->swscale = yuyvToYuv422Wrapper;
1729     if (srcFormat == AV_PIX_FMT_UYVY422 && dstFormat == AV_PIX_FMT_YUV422P)
1730         c->swscale = uyvyToYuv422Wrapper;
1731
1732 #define isPlanarGray(x) (isGray(x) && (x) != AV_PIX_FMT_GRAY8A)
1733     /* simple copy */
1734     if ( srcFormat == dstFormat ||
1735         (srcFormat == AV_PIX_FMT_YUVA420P && dstFormat == AV_PIX_FMT_YUV420P) ||
1736         (srcFormat == AV_PIX_FMT_YUV420P && dstFormat == AV_PIX_FMT_YUVA420P) ||
1737         (isPlanarYUV(srcFormat) && isPlanarGray(dstFormat)) ||
1738         (isPlanarYUV(dstFormat) && isPlanarGray(srcFormat)) ||
1739         (isPlanarGray(dstFormat) && isPlanarGray(srcFormat)) ||
1740         (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) &&
1741          c->chrDstHSubSample == c->chrSrcHSubSample &&
1742          c->chrDstVSubSample == c->chrSrcVSubSample &&
1743          dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 &&
1744          srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21))
1745     {
1746         if (isPacked(c->srcFormat))
1747             c->swscale = packedCopyWrapper;
1748         else /* Planar YUV or gray */
1749             c->swscale = planarCopyWrapper;
1750     }
1751
1752     if (ARCH_PPC)
1753         ff_get_unscaled_swscale_ppc(c);
1754 //     if (ARCH_ARM)
1755 //         ff_get_unscaled_swscale_arm(c);
1756 }
1757
1758 /* Convert the palette to the same packed 32-bit format as the palette */
1759 void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst,
1760                                    int num_pixels, const uint8_t *palette)
1761 {
1762     int i;
1763
1764     for (i = 0; i < num_pixels; i++)
1765         ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
1766 }
1767
1768 /* Palette format: ABCD -> dst format: ABC */
1769 void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst,
1770                                    int num_pixels, const uint8_t *palette)
1771 {
1772     int i;
1773
1774     for (i = 0; i < num_pixels; i++) {
1775         //FIXME slow?
1776         dst[0] = palette[src[i] * 4 + 0];
1777         dst[1] = palette[src[i] * 4 + 1];
1778         dst[2] = palette[src[i] * 4 + 2];
1779         dst += 3;
1780     }
1781 }