Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52867 views
1
/*
2
* Copyright (C) 2001-2011 Michael Niedermayer <[email protected]>
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;
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;
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
av_assert0(srcSliceH > 1);
1063
1064
copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1065
srcPtr += 2 * srcStride[0];
1066
dstPtr += 2 * dstStride[0];
1067
1068
for (i = 2; i < srcSliceH - 2; i += 2) {
1069
interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1070
srcPtr += 2 * srcStride[0];
1071
dstPtr += 2 * dstStride[0];
1072
}
1073
1074
if (i + 1 == srcSliceH) {
1075
copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->srcW);
1076
} else if (i < srcSliceH)
1077
copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
1078
return srcSliceH;
1079
}
1080
1081
static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
1082
int srcSliceH, uint8_t* dst[], int dstStride[])
1083
{
1084
const uint8_t *srcPtr= src[0];
1085
uint8_t *dstY= dst[0];
1086
uint8_t *dstU= dst[1];
1087
uint8_t *dstV= dst[2];
1088
int i;
1089
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);
1090
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);
1091
1092
switch(c->srcFormat) {
1093
#define CASE(pixfmt, prefix) \
1094
case pixfmt: copy = bayer_##prefix##_to_yv12_copy; \
1095
interpolate = bayer_##prefix##_to_yv12_interpolate; \
1096
break;
1097
CASE(AV_PIX_FMT_BAYER_BGGR8, bggr8)
1098
CASE(AV_PIX_FMT_BAYER_BGGR16LE, bggr16le)
1099
CASE(AV_PIX_FMT_BAYER_BGGR16BE, bggr16be)
1100
CASE(AV_PIX_FMT_BAYER_RGGB8, rggb8)
1101
CASE(AV_PIX_FMT_BAYER_RGGB16LE, rggb16le)
1102
CASE(AV_PIX_FMT_BAYER_RGGB16BE, rggb16be)
1103
CASE(AV_PIX_FMT_BAYER_GBRG8, gbrg8)
1104
CASE(AV_PIX_FMT_BAYER_GBRG16LE, gbrg16le)
1105
CASE(AV_PIX_FMT_BAYER_GBRG16BE, gbrg16be)
1106
CASE(AV_PIX_FMT_BAYER_GRBG8, grbg8)
1107
CASE(AV_PIX_FMT_BAYER_GRBG16LE, grbg16le)
1108
CASE(AV_PIX_FMT_BAYER_GRBG16BE, grbg16be)
1109
#undef CASE
1110
default: return 0;
1111
}
1112
1113
av_assert0(srcSliceH > 1);
1114
1115
copy(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
for (i = 2; i < srcSliceH - 2; i += 2) {
1122
interpolate(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1123
srcPtr += 2 * srcStride[0];
1124
dstY += 2 * dstStride[0];
1125
dstU += dstStride[1];
1126
dstV += dstStride[1];
1127
}
1128
1129
if (i + 1 == srcSliceH) {
1130
copy(srcPtr, -srcStride[0], dstY, dstU, dstV, -dstStride[0], c->srcW, c->input_rgb2yuv_table);
1131
} else if (i < srcSliceH)
1132
copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
1133
return srcSliceH;
1134
}
1135
1136
#define isRGBA32(x) ( \
1137
(x) == AV_PIX_FMT_ARGB \
1138
|| (x) == AV_PIX_FMT_RGBA \
1139
|| (x) == AV_PIX_FMT_BGRA \
1140
|| (x) == AV_PIX_FMT_ABGR \
1141
)
1142
1143
#define isRGBA64(x) ( \
1144
(x) == AV_PIX_FMT_RGBA64LE \
1145
|| (x) == AV_PIX_FMT_RGBA64BE \
1146
|| (x) == AV_PIX_FMT_BGRA64LE \
1147
|| (x) == AV_PIX_FMT_BGRA64BE \
1148
)
1149
1150
#define isRGB48(x) ( \
1151
(x) == AV_PIX_FMT_RGB48LE \
1152
|| (x) == AV_PIX_FMT_RGB48BE \
1153
|| (x) == AV_PIX_FMT_BGR48LE \
1154
|| (x) == AV_PIX_FMT_BGR48BE \
1155
)
1156
1157
/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1158
typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
1159
static rgbConvFn findRgbConvFn(SwsContext *c)
1160
{
1161
const enum AVPixelFormat srcFormat = c->srcFormat;
1162
const enum AVPixelFormat dstFormat = c->dstFormat;
1163
const int srcId = c->srcFormatBpp;
1164
const int dstId = c->dstFormatBpp;
1165
rgbConvFn conv = NULL;
1166
1167
#define IS_NOT_NE(bpp, desc) \
1168
(((bpp + 7) >> 3) == 2 && \
1169
(!(desc->flags & AV_PIX_FMT_FLAG_BE) != !HAVE_BIGENDIAN))
1170
1171
#define CONV_IS(src, dst) (srcFormat == AV_PIX_FMT_##src && dstFormat == AV_PIX_FMT_##dst)
1172
1173
if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
1174
if ( CONV_IS(ABGR, RGBA)
1175
|| CONV_IS(ARGB, BGRA)
1176
|| CONV_IS(BGRA, ARGB)
1177
|| CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
1178
else if (CONV_IS(ABGR, ARGB)
1179
|| CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
1180
else if (CONV_IS(ABGR, BGRA)
1181
|| CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
1182
else if (CONV_IS(BGRA, RGBA)
1183
|| CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
1184
else if (CONV_IS(BGRA, ABGR)
1185
|| CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
1186
} else if (isRGB48(srcFormat) && isRGB48(dstFormat)) {
1187
if (CONV_IS(RGB48LE, BGR48LE)
1188
|| CONV_IS(BGR48LE, RGB48LE)
1189
|| CONV_IS(RGB48BE, BGR48BE)
1190
|| CONV_IS(BGR48BE, RGB48BE)) conv = rgb48tobgr48_nobswap;
1191
else if (CONV_IS(RGB48LE, BGR48BE)
1192
|| CONV_IS(BGR48LE, RGB48BE)
1193
|| CONV_IS(RGB48BE, BGR48LE)
1194
|| CONV_IS(BGR48BE, RGB48LE)) conv = rgb48tobgr48_bswap;
1195
} else if (isRGBA64(srcFormat) && isRGB48(dstFormat)) {
1196
if (CONV_IS(RGBA64LE, BGR48LE)
1197
|| CONV_IS(BGRA64LE, RGB48LE)
1198
|| CONV_IS(RGBA64BE, BGR48BE)
1199
|| CONV_IS(BGRA64BE, RGB48BE)) conv = rgb64tobgr48_nobswap;
1200
else if (CONV_IS(RGBA64LE, BGR48BE)
1201
|| CONV_IS(BGRA64LE, RGB48BE)
1202
|| CONV_IS(RGBA64BE, BGR48LE)
1203
|| CONV_IS(BGRA64BE, RGB48LE)) conv = rgb64tobgr48_bswap;
1204
else if (CONV_IS(RGBA64LE, RGB48LE)
1205
|| CONV_IS(BGRA64LE, BGR48LE)
1206
|| CONV_IS(RGBA64BE, RGB48BE)
1207
|| CONV_IS(BGRA64BE, BGR48BE)) conv = rgb64to48_nobswap;
1208
else if (CONV_IS(RGBA64LE, RGB48BE)
1209
|| CONV_IS(BGRA64LE, BGR48BE)
1210
|| CONV_IS(RGBA64BE, RGB48LE)
1211
|| CONV_IS(BGRA64BE, BGR48LE)) conv = rgb64to48_bswap;
1212
} else
1213
/* BGR -> BGR */
1214
if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
1215
(isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
1216
switch (srcId | (dstId << 16)) {
1217
case 0x000F000C: conv = rgb12to15; break;
1218
case 0x000F0010: conv = rgb16to15; break;
1219
case 0x000F0018: conv = rgb24to15; break;
1220
case 0x000F0020: conv = rgb32to15; break;
1221
case 0x0010000F: conv = rgb15to16; break;
1222
case 0x00100018: conv = rgb24to16; break;
1223
case 0x00100020: conv = rgb32to16; break;
1224
case 0x0018000F: conv = rgb15to24; break;
1225
case 0x00180010: conv = rgb16to24; break;
1226
case 0x00180020: conv = rgb32to24; break;
1227
case 0x0020000F: conv = rgb15to32; break;
1228
case 0x00200010: conv = rgb16to32; break;
1229
case 0x00200018: conv = rgb24to32; break;
1230
}
1231
} else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) ||
1232
(isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
1233
switch (srcId | (dstId << 16)) {
1234
case 0x000C000C: conv = rgb12tobgr12; break;
1235
case 0x000F000F: conv = rgb15tobgr15; break;
1236
case 0x000F0010: conv = rgb16tobgr15; break;
1237
case 0x000F0018: conv = rgb24tobgr15; break;
1238
case 0x000F0020: conv = rgb32tobgr15; break;
1239
case 0x0010000F: conv = rgb15tobgr16; break;
1240
case 0x00100010: conv = rgb16tobgr16; break;
1241
case 0x00100018: conv = rgb24tobgr16; break;
1242
case 0x00100020: conv = rgb32tobgr16; break;
1243
case 0x0018000F: conv = rgb15tobgr24; break;
1244
case 0x00180010: conv = rgb16tobgr24; break;
1245
case 0x00180018: conv = rgb24tobgr24; break;
1246
case 0x00180020: conv = rgb32tobgr24; break;
1247
case 0x0020000F: conv = rgb15tobgr32; break;
1248
case 0x00200010: conv = rgb16tobgr32; break;
1249
case 0x00200018: conv = rgb24tobgr32; break;
1250
}
1251
}
1252
1253
if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0)
1254
return NULL;
1255
1256
// Maintain symmetry between endianness
1257
if (c->flags & SWS_BITEXACT)
1258
if ((dstFormat == AV_PIX_FMT_RGB32 || dstFormat == AV_PIX_FMT_BGR32 ) && !isRGBA32(srcFormat) && ALT32_CORR>0)
1259
return NULL;
1260
1261
return conv;
1262
}
1263
1264
/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
1265
static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
1266
int srcSliceY, int srcSliceH, uint8_t *dst[],
1267
int dstStride[])
1268
1269
{
1270
const enum AVPixelFormat srcFormat = c->srcFormat;
1271
const enum AVPixelFormat dstFormat = c->dstFormat;
1272
const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1273
const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1274
const int srcBpp = (c->srcFormatBpp + 7) >> 3;
1275
const int dstBpp = (c->dstFormatBpp + 7) >> 3;
1276
rgbConvFn conv = findRgbConvFn(c);
1277
1278
if (!conv) {
1279
av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
1280
av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
1281
} else {
1282
const uint8_t *srcPtr = src[0];
1283
uint8_t *dstPtr = dst[0];
1284
int src_bswap = IS_NOT_NE(c->srcFormatBpp, desc_src);
1285
int dst_bswap = IS_NOT_NE(c->dstFormatBpp, desc_dst);
1286
1287
if ((srcFormat == AV_PIX_FMT_RGB32_1 || srcFormat == AV_PIX_FMT_BGR32_1) &&
1288
!isRGBA32(dstFormat))
1289
srcPtr += ALT32_CORR;
1290
1291
if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) &&
1292
!isRGBA32(srcFormat)) {
1293
int i;
1294
av_assert0(ALT32_CORR == 1);
1295
for (i = 0; i < srcSliceH; i++)
1296
dstPtr[dstStride[0] * (srcSliceY + i)] = 255;
1297
dstPtr += ALT32_CORR;
1298
}
1299
1300
if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
1301
!(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap)
1302
conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
1303
(srcSliceH - 1) * srcStride[0] + c->srcW * srcBpp);
1304
else {
1305
int i, j;
1306
dstPtr += dstStride[0] * srcSliceY;
1307
1308
for (i = 0; i < srcSliceH; i++) {
1309
if(src_bswap) {
1310
for(j=0; j<c->srcW; j++)
1311
((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]);
1312
conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp);
1313
}else
1314
conv(srcPtr, dstPtr, c->srcW * srcBpp);
1315
if(dst_bswap)
1316
for(j=0; j<c->srcW; j++)
1317
((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]);
1318
srcPtr += srcStride[0];
1319
dstPtr += dstStride[0];
1320
}
1321
}
1322
}
1323
return srcSliceH;
1324
}
1325
1326
static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
1327
int srcStride[], int srcSliceY, int srcSliceH,
1328
uint8_t *dst[], int dstStride[])
1329
{
1330
ff_rgb24toyv12(
1331
src[0],
1332
dst[0] + srcSliceY * dstStride[0],
1333
dst[1] + (srcSliceY >> 1) * dstStride[1],
1334
dst[2] + (srcSliceY >> 1) * dstStride[2],
1335
c->srcW, srcSliceH,
1336
dstStride[0], dstStride[1], srcStride[0],
1337
c->input_rgb2yuv_table);
1338
if (dst[3])
1339
fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1340
return srcSliceH;
1341
}
1342
1343
static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[],
1344
int srcStride[], int srcSliceY, int srcSliceH,
1345
uint8_t *dst[], int dstStride[])
1346
{
1347
copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
1348
dst[0], dstStride[0]);
1349
1350
planar2x(src[1], dst[1] + dstStride[1] * (srcSliceY >> 1), c->chrSrcW,
1351
srcSliceH >> 2, srcStride[1], dstStride[1]);
1352
planar2x(src[2], dst[2] + dstStride[2] * (srcSliceY >> 1), c->chrSrcW,
1353
srcSliceH >> 2, srcStride[2], dstStride[2]);
1354
if (dst[3])
1355
fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
1356
return srcSliceH;
1357
}
1358
1359
/* unscaled copy like stuff (assumes nearly identical formats) */
1360
static int packedCopyWrapper(SwsContext *c, const uint8_t *src[],
1361
int srcStride[], int srcSliceY, int srcSliceH,
1362
uint8_t *dst[], int dstStride[])
1363
{
1364
if (dstStride[0] == srcStride[0] && srcStride[0] > 0)
1365
memcpy(dst[0] + dstStride[0] * srcSliceY, src[0], srcSliceH * dstStride[0]);
1366
else {
1367
int i;
1368
const uint8_t *srcPtr = src[0];
1369
uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
1370
int length = 0;
1371
1372
/* universal length finder */
1373
while (length + c->srcW <= FFABS(dstStride[0]) &&
1374
length + c->srcW <= FFABS(srcStride[0]))
1375
length += c->srcW;
1376
av_assert1(length != 0);
1377
1378
for (i = 0; i < srcSliceH; i++) {
1379
memcpy(dstPtr, srcPtr, length);
1380
srcPtr += srcStride[0];
1381
dstPtr += dstStride[0];
1382
}
1383
}
1384
return srcSliceH;
1385
}
1386
1387
#define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
1388
uint16_t scale= dither_scale[dst_depth-1][src_depth-1];\
1389
int shift= src_depth-dst_depth + dither_scale[src_depth-2][dst_depth-1];\
1390
for (i = 0; i < height; i++) {\
1391
const uint8_t *dither= dithers[src_depth-9][i&7];\
1392
for (j = 0; j < length-7; j+=8){\
1393
dst[j+0] = dbswap((bswap(src[j+0]) + dither[0])*scale>>shift);\
1394
dst[j+1] = dbswap((bswap(src[j+1]) + dither[1])*scale>>shift);\
1395
dst[j+2] = dbswap((bswap(src[j+2]) + dither[2])*scale>>shift);\
1396
dst[j+3] = dbswap((bswap(src[j+3]) + dither[3])*scale>>shift);\
1397
dst[j+4] = dbswap((bswap(src[j+4]) + dither[4])*scale>>shift);\
1398
dst[j+5] = dbswap((bswap(src[j+5]) + dither[5])*scale>>shift);\
1399
dst[j+6] = dbswap((bswap(src[j+6]) + dither[6])*scale>>shift);\
1400
dst[j+7] = dbswap((bswap(src[j+7]) + dither[7])*scale>>shift);\
1401
}\
1402
for (; j < length; j++)\
1403
dst[j] = dbswap((bswap(src[j]) + dither[j&7])*scale>>shift);\
1404
dst += dstStride;\
1405
src += srcStride;\
1406
}
1407
1408
static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
1409
int srcStride[], int srcSliceY, int srcSliceH,
1410
uint8_t *dst[], int dstStride[])
1411
{
1412
const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
1413
const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
1414
int plane, i, j;
1415
for (plane = 0; plane < 4; plane++) {
1416
int length = (plane == 0 || plane == 3) ? c->srcW : AV_CEIL_RSHIFT(c->srcW, c->chrDstHSubSample);
1417
int y = (plane == 0 || plane == 3) ? srcSliceY: AV_CEIL_RSHIFT(srcSliceY, c->chrDstVSubSample);
1418
int height = (plane == 0 || plane == 3) ? srcSliceH: AV_CEIL_RSHIFT(srcSliceH, c->chrDstVSubSample);
1419
const uint8_t *srcPtr = src[plane];
1420
uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
1421
int shiftonly = plane == 1 || plane == 2 || (!c->srcRange && plane == 0);
1422
1423
if (!dst[plane])
1424
continue;
1425
// ignore palette for GRAY8
1426
if (plane == 1 && !dst[2]) continue;
1427
if (!src[plane] || (plane == 1 && !src[2])) {
1428
if (is16BPS(c->dstFormat) || isNBPS(c->dstFormat)) {
1429
fillPlane16(dst[plane], dstStride[plane], length, height, y,
1430
plane == 3, desc_dst->comp[plane].depth,
1431
isBE(c->dstFormat));
1432
} else {
1433
fillPlane(dst[plane], dstStride[plane], length, height, y,
1434
(plane == 3) ? 255 : 128);
1435
}
1436
} else {
1437
if(isNBPS(c->srcFormat) || isNBPS(c->dstFormat)
1438
|| (is16BPS(c->srcFormat) != is16BPS(c->dstFormat))
1439
) {
1440
const int src_depth = desc_src->comp[plane].depth;
1441
const int dst_depth = desc_dst->comp[plane].depth;
1442
const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
1443
uint16_t *dstPtr2 = (uint16_t*)dstPtr;
1444
1445
if (dst_depth == 8) {
1446
if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1447
DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , )
1448
} else {
1449
DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, av_bswap16, )
1450
}
1451
} else if (src_depth == 8) {
1452
for (i = 0; i < height; i++) {
1453
#define COPY816(w)\
1454
if (shiftonly) {\
1455
for (j = 0; j < length; j++)\
1456
w(&dstPtr2[j], srcPtr[j]<<(dst_depth-8));\
1457
} else {\
1458
for (j = 0; j < length; j++)\
1459
w(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) |\
1460
(srcPtr[j]>>(2*8-dst_depth)));\
1461
}
1462
if(isBE(c->dstFormat)){
1463
COPY816(AV_WB16)
1464
} else {
1465
COPY816(AV_WL16)
1466
}
1467
dstPtr2 += dstStride[plane]/2;
1468
srcPtr += srcStride[plane];
1469
}
1470
} else if (src_depth <= dst_depth) {
1471
for (i = 0; i < height; i++) {
1472
j = 0;
1473
if(isBE(c->srcFormat) == HAVE_BIGENDIAN &&
1474
isBE(c->dstFormat) == HAVE_BIGENDIAN &&
1475
shiftonly) {
1476
unsigned shift = dst_depth - src_depth;
1477
#if HAVE_FAST_64BIT
1478
#define FAST_COPY_UP(shift) \
1479
for (; j < length - 3; j += 4) { \
1480
uint64_t v = AV_RN64A(srcPtr2 + j); \
1481
AV_WN64A(dstPtr2 + j, v << shift); \
1482
}
1483
#else
1484
#define FAST_COPY_UP(shift) \
1485
for (; j < length - 1; j += 2) { \
1486
uint32_t v = AV_RN32A(srcPtr2 + j); \
1487
AV_WN32A(dstPtr2 + j, v << shift); \
1488
}
1489
#endif
1490
switch (shift)
1491
{
1492
case 6: FAST_COPY_UP(6); break;
1493
case 7: FAST_COPY_UP(7); break;
1494
}
1495
}
1496
#define COPY_UP(r,w) \
1497
if(shiftonly){\
1498
for (; j < length; j++){ \
1499
unsigned int v= r(&srcPtr2[j]);\
1500
w(&dstPtr2[j], v<<(dst_depth-src_depth));\
1501
}\
1502
}else{\
1503
for (; j < length; j++){ \
1504
unsigned int v= r(&srcPtr2[j]);\
1505
w(&dstPtr2[j], (v<<(dst_depth-src_depth)) | \
1506
(v>>(2*src_depth-dst_depth)));\
1507
}\
1508
}
1509
if(isBE(c->srcFormat)){
1510
if(isBE(c->dstFormat)){
1511
COPY_UP(AV_RB16, AV_WB16)
1512
} else {
1513
COPY_UP(AV_RB16, AV_WL16)
1514
}
1515
} else {
1516
if(isBE(c->dstFormat)){
1517
COPY_UP(AV_RL16, AV_WB16)
1518
} else {
1519
COPY_UP(AV_RL16, AV_WL16)
1520
}
1521
}
1522
dstPtr2 += dstStride[plane]/2;
1523
srcPtr2 += srcStride[plane]/2;
1524
}
1525
} else {
1526
if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
1527
if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1528
DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , )
1529
} else {
1530
DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , av_bswap16)
1531
}
1532
}else{
1533
if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
1534
DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, )
1535
} else {
1536
DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, av_bswap16)
1537
}
1538
}
1539
}
1540
} else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
1541
isBE(c->srcFormat) != isBE(c->dstFormat)) {
1542
1543
for (i = 0; i < height; i++) {
1544
for (j = 0; j < length; j++)
1545
((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);
1546
srcPtr += srcStride[plane];
1547
dstPtr += dstStride[plane];
1548
}
1549
} else if (dstStride[plane] == srcStride[plane] &&
1550
srcStride[plane] > 0 && srcStride[plane] == length) {
1551
memcpy(dst[plane] + dstStride[plane] * y, src[plane],
1552
height * dstStride[plane]);
1553
} else {
1554
if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
1555
length *= 2;
1556
else if (desc_src->comp[0].depth == 1)
1557
length >>= 3; // monowhite/black
1558
for (i = 0; i < height; i++) {
1559
memcpy(dstPtr, srcPtr, length);
1560
srcPtr += srcStride[plane];
1561
dstPtr += dstStride[plane];
1562
}
1563
}
1564
}
1565
}
1566
return srcSliceH;
1567
}
1568
1569
1570
#define IS_DIFFERENT_ENDIANESS(src_fmt, dst_fmt, pix_fmt) \
1571
((src_fmt == pix_fmt ## BE && dst_fmt == pix_fmt ## LE) || \
1572
(src_fmt == pix_fmt ## LE && dst_fmt == pix_fmt ## BE))
1573
1574
1575
void ff_get_unscaled_swscale(SwsContext *c)
1576
{
1577
const enum AVPixelFormat srcFormat = c->srcFormat;
1578
const enum AVPixelFormat dstFormat = c->dstFormat;
1579
const int flags = c->flags;
1580
const int dstH = c->dstH;
1581
int needsDither;
1582
1583
needsDither = isAnyRGB(dstFormat) &&
1584
c->dstFormatBpp < 24 &&
1585
(c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
1586
1587
/* yv12_to_nv12 */
1588
if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
1589
(dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
1590
c->swscale = planarToNv12Wrapper;
1591
}
1592
/* nv12_to_yv12 */
1593
if (dstFormat == AV_PIX_FMT_YUV420P &&
1594
(srcFormat == AV_PIX_FMT_NV12 || srcFormat == AV_PIX_FMT_NV21)) {
1595
c->swscale = nv12ToPlanarWrapper;
1596
}
1597
/* yuv2bgr */
1598
if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
1599
srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
1600
!(flags & SWS_ACCURATE_RND) && (c->dither == SWS_DITHER_BAYER || c->dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
1601
c->swscale = ff_yuv2rgb_get_func_ptr(c);
1602
}
1603
1604
if (srcFormat == AV_PIX_FMT_YUV410P && !(dstH & 3) &&
1605
(dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1606
!(flags & SWS_BITEXACT)) {
1607
c->swscale = yvu9ToYv12Wrapper;
1608
}
1609
1610
/* bgr24toYV12 */
1611
if (srcFormat == AV_PIX_FMT_BGR24 &&
1612
(dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
1613
!(flags & SWS_ACCURATE_RND))
1614
c->swscale = bgr24ToYv12Wrapper;
1615
1616
/* RGB/BGR -> RGB/BGR (no dither needed forms) */
1617
if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
1618
&& (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
1619
c->swscale = rgbToRgbWrapper;
1620
1621
/* RGB to planar RGB */
1622
if ((srcFormat == AV_PIX_FMT_GBRP && dstFormat == AV_PIX_FMT_GBRAP) ||
1623
(srcFormat == AV_PIX_FMT_GBRAP && dstFormat == AV_PIX_FMT_GBRP))
1624
c->swscale = planarRgbToplanarRgbWrapper;
1625
1626
#define isByteRGB(f) ( \
1627
f == AV_PIX_FMT_RGB32 || \
1628
f == AV_PIX_FMT_RGB32_1 || \
1629
f == AV_PIX_FMT_RGB24 || \
1630
f == AV_PIX_FMT_BGR32 || \
1631
f == AV_PIX_FMT_BGR32_1 || \
1632
f == AV_PIX_FMT_BGR24)
1633
1634
if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
1635
c->swscale = planarRgbToRgbWrapper;
1636
1637
if ((srcFormat == AV_PIX_FMT_RGB48LE || srcFormat == AV_PIX_FMT_RGB48BE ||
1638
srcFormat == AV_PIX_FMT_BGR48LE || srcFormat == AV_PIX_FMT_BGR48BE ||
1639
srcFormat == AV_PIX_FMT_RGBA64LE || srcFormat == AV_PIX_FMT_RGBA64BE ||
1640
srcFormat == AV_PIX_FMT_BGRA64LE || srcFormat == AV_PIX_FMT_BGRA64BE) &&
1641
(dstFormat == AV_PIX_FMT_GBRP9LE || dstFormat == AV_PIX_FMT_GBRP9BE ||
1642
dstFormat == AV_PIX_FMT_GBRP10LE || dstFormat == AV_PIX_FMT_GBRP10BE ||
1643
dstFormat == AV_PIX_FMT_GBRP12LE || dstFormat == AV_PIX_FMT_GBRP12BE ||
1644
dstFormat == AV_PIX_FMT_GBRP14LE || dstFormat == AV_PIX_FMT_GBRP14BE ||
1645
dstFormat == AV_PIX_FMT_GBRP16LE || dstFormat == AV_PIX_FMT_GBRP16BE ||
1646
dstFormat == AV_PIX_FMT_GBRAP16LE || dstFormat == AV_PIX_FMT_GBRAP16BE ))
1647
c->swscale = Rgb16ToPlanarRgb16Wrapper;
1648
1649
if ((srcFormat == AV_PIX_FMT_GBRP9LE || srcFormat == AV_PIX_FMT_GBRP9BE ||
1650
srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
1651
srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
1652
srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
1653
srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE ||
1654
srcFormat == AV_PIX_FMT_GBRAP16LE || srcFormat == AV_PIX_FMT_GBRAP16BE) &&
1655
(dstFormat == AV_PIX_FMT_RGB48LE || dstFormat == AV_PIX_FMT_RGB48BE ||
1656
dstFormat == AV_PIX_FMT_BGR48LE || dstFormat == AV_PIX_FMT_BGR48BE ||
1657
dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
1658
dstFormat == AV_PIX_FMT_BGRA64LE || dstFormat == AV_PIX_FMT_BGRA64BE))
1659
c->swscale = planarRgb16ToRgb16Wrapper;
1660
1661
if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth == 8 &&
1662
isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
1663
c->swscale = rgbToPlanarRgbWrapper;
1664
1665
if (isBayer(srcFormat)) {
1666
if (dstFormat == AV_PIX_FMT_RGB24)
1667
c->swscale = bayer_to_rgb24_wrapper;
1668
else if (dstFormat == AV_PIX_FMT_YUV420P)
1669
c->swscale = bayer_to_yv12_wrapper;
1670
else if (!isBayer(dstFormat)) {
1671
av_log(c, AV_LOG_ERROR, "unsupported bayer conversion\n");
1672
av_assert0(0);
1673
}
1674
}
1675
1676
/* bswap 16 bits per pixel/component packed formats */
1677
if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_BGGR16) ||
1678
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_RGGB16) ||
1679
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GBRG16) ||
1680
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BAYER_GRBG16) ||
1681
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) ||
1682
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR48) ||
1683
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
1684
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) ||
1685
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) ||
1686
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
1687
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) ||
1688
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YA16) ||
1689
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_AYUV64) ||
1690
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP9) ||
1691
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP10) ||
1692
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP12) ||
1693
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP14) ||
1694
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRP16) ||
1695
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GBRAP16) ||
1696
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) ||
1697
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48) ||
1698
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
1699
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) ||
1700
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) ||
1701
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
1702
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12) ||
1703
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P9) ||
1704
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P10) ||
1705
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P12) ||
1706
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P14) ||
1707
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV420P16) ||
1708
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P9) ||
1709
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P10) ||
1710
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P12) ||
1711
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P14) ||
1712
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV422P16) ||
1713
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV440P10) ||
1714
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV440P12) ||
1715
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P9) ||
1716
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P10) ||
1717
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P12) ||
1718
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P14) ||
1719
IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_YUV444P16))
1720
c->swscale = packed_16bpc_bswap;
1721
1722
if (usePal(srcFormat) && isByteRGB(dstFormat))
1723
c->swscale = palToRgbWrapper;
1724
1725
if (srcFormat == AV_PIX_FMT_YUV422P) {
1726
if (dstFormat == AV_PIX_FMT_YUYV422)
1727
c->swscale = yuv422pToYuy2Wrapper;
1728
else if (dstFormat == AV_PIX_FMT_UYVY422)
1729
c->swscale = yuv422pToUyvyWrapper;
1730
}
1731
1732
/* LQ converters if -sws 0 or -sws 4*/
1733
if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
1734
/* yv12_to_yuy2 */
1735
if (srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) {
1736
if (dstFormat == AV_PIX_FMT_YUYV422)
1737
c->swscale = planarToYuy2Wrapper;
1738
else if (dstFormat == AV_PIX_FMT_UYVY422)
1739
c->swscale = planarToUyvyWrapper;
1740
}
1741
}
1742
if (srcFormat == AV_PIX_FMT_YUYV422 &&
1743
(dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1744
c->swscale = yuyvToYuv420Wrapper;
1745
if (srcFormat == AV_PIX_FMT_UYVY422 &&
1746
(dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
1747
c->swscale = uyvyToYuv420Wrapper;
1748
if (srcFormat == AV_PIX_FMT_YUYV422 && dstFormat == AV_PIX_FMT_YUV422P)
1749
c->swscale = yuyvToYuv422Wrapper;
1750
if (srcFormat == AV_PIX_FMT_UYVY422 && dstFormat == AV_PIX_FMT_YUV422P)
1751
c->swscale = uyvyToYuv422Wrapper;
1752
1753
#define isPlanarGray(x) (isGray(x) && (x) != AV_PIX_FMT_YA8 && (x) != AV_PIX_FMT_YA16LE && (x) != AV_PIX_FMT_YA16BE)
1754
/* simple copy */
1755
if ( srcFormat == dstFormat ||
1756
(srcFormat == AV_PIX_FMT_YUVA420P && dstFormat == AV_PIX_FMT_YUV420P) ||
1757
(srcFormat == AV_PIX_FMT_YUV420P && dstFormat == AV_PIX_FMT_YUVA420P) ||
1758
(isPlanarYUV(srcFormat) && isPlanarGray(dstFormat)) ||
1759
(isPlanarYUV(dstFormat) && isPlanarGray(srcFormat)) ||
1760
(isPlanarGray(dstFormat) && isPlanarGray(srcFormat)) ||
1761
(isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) &&
1762
c->chrDstHSubSample == c->chrSrcHSubSample &&
1763
c->chrDstVSubSample == c->chrSrcVSubSample &&
1764
dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21 &&
1765
dstFormat != AV_PIX_FMT_P010LE && dstFormat != AV_PIX_FMT_P010BE &&
1766
srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21 &&
1767
srcFormat != AV_PIX_FMT_P010LE && srcFormat != AV_PIX_FMT_P010BE))
1768
{
1769
if (isPacked(c->srcFormat))
1770
c->swscale = packedCopyWrapper;
1771
else /* Planar YUV or gray */
1772
c->swscale = planarCopyWrapper;
1773
}
1774
1775
if (ARCH_PPC)
1776
ff_get_unscaled_swscale_ppc(c);
1777
if (ARCH_ARM)
1778
ff_get_unscaled_swscale_arm(c);
1779
}
1780
1781
/* Convert the palette to the same packed 32-bit format as the palette */
1782
void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst,
1783
int num_pixels, const uint8_t *palette)
1784
{
1785
int i;
1786
1787
for (i = 0; i < num_pixels; i++)
1788
((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
1789
}
1790
1791
/* Palette format: ABCD -> dst format: ABC */
1792
void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst,
1793
int num_pixels, const uint8_t *palette)
1794
{
1795
int i;
1796
1797
for (i = 0; i < num_pixels; i++) {
1798
//FIXME slow?
1799
dst[0] = palette[src[i] * 4 + 0];
1800
dst[1] = palette[src[i] * 4 + 1];
1801
dst[2] = palette[src[i] * 4 + 2];
1802
dst += 3;
1803
}
1804
}
1805
1806