34
34
#include "libavutil/bswap.h"
35
35
#include "libavutil/pixdesc.h"
37
DECLARE_ALIGNED(8, const uint8_t, dither_8x8_1)[8][8] = {
38
{ 0, 1, 0, 1, 0, 1, 0, 1,},
39
{ 1, 0, 1, 0, 1, 0, 1, 0,},
40
{ 0, 1, 0, 1, 0, 1, 0, 1,},
41
{ 1, 0, 1, 0, 1, 0, 1, 0,},
42
{ 0, 1, 0, 1, 0, 1, 0, 1,},
43
{ 1, 0, 1, 0, 1, 0, 1, 0,},
44
{ 0, 1, 0, 1, 0, 1, 0, 1,},
45
{ 1, 0, 1, 0, 1, 0, 1, 0,},
47
DECLARE_ALIGNED(8, const uint8_t, dither_8x8_3)[8][8] = {
48
{ 1, 2, 1, 2, 1, 2, 1, 2,},
49
{ 3, 0, 3, 0, 3, 0, 3, 0,},
50
{ 1, 2, 1, 2, 1, 2, 1, 2,},
51
{ 3, 0, 3, 0, 3, 0, 3, 0,},
52
{ 1, 2, 1, 2, 1, 2, 1, 2,},
53
{ 3, 0, 3, 0, 3, 0, 3, 0,},
54
{ 1, 2, 1, 2, 1, 2, 1, 2,},
55
{ 3, 0, 3, 0, 3, 0, 3, 0,},
57
DECLARE_ALIGNED(8, const uint8_t, dither_8x8_64)[8][8] = {
58
{ 18, 34, 30, 46, 17, 33, 29, 45,},
59
{ 50, 2, 62, 14, 49, 1, 61, 13,},
60
{ 26, 42, 22, 38, 25, 41, 21, 37,},
61
{ 58, 10, 54, 6, 57, 9, 53, 5,},
62
{ 16, 32, 28, 44, 19, 35, 31, 47,},
63
{ 48, 0, 60, 12, 51, 3, 63, 15,},
64
{ 24, 40, 20, 36, 27, 43, 23, 39,},
65
{ 56, 8, 52, 4, 59, 11, 55, 7,},
67
extern const uint8_t dither_8x8_128[8][8];
68
DECLARE_ALIGNED(8, const uint8_t, dither_8x8_256)[8][8] = {
69
{ 72, 136, 120, 184, 68, 132, 116, 180,},
70
{ 200, 8, 248, 56, 196, 4, 244, 52,},
71
{ 104, 168, 88, 152, 100, 164, 84, 148,},
72
{ 232, 40, 216, 24, 228, 36, 212, 20,},
73
{ 64, 128, 102, 176, 76, 140, 124, 188,},
74
{ 192, 0, 240, 48, 204, 12, 252, 60,},
75
{ 96, 160, 80, 144, 108, 172, 92, 156,},
76
{ 224, 32, 208, 16, 236, 44, 220, 28,},
37
79
#define RGB2YUV_SHIFT 15
38
#define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
39
#define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
40
#define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
41
#define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
42
#define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
43
#define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
44
#define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
45
#define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
46
#define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
80
#define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
81
#define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
82
#define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
83
#define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
84
#define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
85
#define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
86
#define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
87
#define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
88
#define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
48
static void fillPlane(uint8_t* plane, int stride, int width, int height, int y, uint8_t val)
90
static void fillPlane(uint8_t *plane, int stride, int width, int height, int y,
51
uint8_t *ptr = plane + stride*y;
52
for (i=0; i<height; i++) {
94
uint8_t *ptr = plane + stride * y;
95
for (i = 0; i < height; i++) {
53
96
memset(ptr, val, width);
75
static int planarToNv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
76
int srcSliceH, uint8_t* dstParam[], int dstStride[])
118
static int planarToNv12Wrapper(SwsContext *c, const uint8_t *src[],
119
int srcStride[], int srcSliceY,
120
int srcSliceH, uint8_t *dstParam[],
78
uint8_t *dst = dstParam[1] + dstStride[1]*srcSliceY/2;
123
uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY / 2;
80
125
copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
81
126
dstParam[0], dstStride[0]);
83
128
if (c->dstFormat == PIX_FMT_NV12)
84
interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]);
129
interleaveBytes(src[1], src[2], dst, c->srcW / 2, srcSliceH / 2,
130
srcStride[1], srcStride[2], dstStride[0]);
86
interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]);
91
static int planarToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
92
int srcSliceH, uint8_t* dstParam[], int dstStride[])
94
uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
96
yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
101
static int planarToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
102
int srcSliceH, uint8_t* dstParam[], int dstStride[])
104
uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
106
yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
111
static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
112
int srcSliceH, uint8_t* dstParam[], int dstStride[])
114
uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
116
yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
121
static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
122
int srcSliceH, uint8_t* dstParam[], int dstStride[])
124
uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
126
yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
131
static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
132
int srcSliceH, uint8_t* dstParam[], int dstStride[])
134
uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
135
uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
136
uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
138
yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
141
fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
146
static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
147
int srcSliceH, uint8_t* dstParam[], int dstStride[])
149
uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
150
uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
151
uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
153
yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
158
static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
159
int srcSliceH, uint8_t* dstParam[], int dstStride[])
161
uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
162
uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
163
uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
165
uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
168
fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
173
static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
174
int srcSliceH, uint8_t* dstParam[], int dstStride[])
176
uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
177
uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
178
uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
180
uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
185
static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
188
for (i=0; i<num_pixels; i++)
189
((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | (src[(i<<1)+1] << 24);
192
static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
196
for (i=0; i<num_pixels; i++)
197
((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | src[(i<<1)+1];
200
static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
204
for (i=0; i<num_pixels; i++) {
132
interleaveBytes(src[2], src[1], dst, c->srcW / 2, srcSliceH / 2,
133
srcStride[2], srcStride[1], dstStride[0]);
138
static int planarToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
139
int srcStride[], int srcSliceY, int srcSliceH,
140
uint8_t *dstParam[], int dstStride[])
142
uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
144
yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
145
srcStride[1], dstStride[0]);
150
static int planarToUyvyWrapper(SwsContext *c, const uint8_t *src[],
151
int srcStride[], int srcSliceY, int srcSliceH,
152
uint8_t *dstParam[], int dstStride[])
154
uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
156
yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
157
srcStride[1], dstStride[0]);
162
static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t *src[],
163
int srcStride[], int srcSliceY, int srcSliceH,
164
uint8_t *dstParam[], int dstStride[])
166
uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
168
yuv422ptoyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
169
srcStride[1], dstStride[0]);
174
static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t *src[],
175
int srcStride[], int srcSliceY, int srcSliceH,
176
uint8_t *dstParam[], int dstStride[])
178
uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
180
yuv422ptouyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
181
srcStride[1], dstStride[0]);
186
static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
187
int srcStride[], int srcSliceY, int srcSliceH,
188
uint8_t *dstParam[], int dstStride[])
190
uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
191
uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
192
uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
194
yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
195
dstStride[1], srcStride[0]);
198
fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
203
static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
204
int srcStride[], int srcSliceY, int srcSliceH,
205
uint8_t *dstParam[], int dstStride[])
207
uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
208
uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
209
uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
211
yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
212
dstStride[1], srcStride[0]);
217
static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t *src[],
218
int srcStride[], int srcSliceY, int srcSliceH,
219
uint8_t *dstParam[], int dstStride[])
221
uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
222
uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
223
uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
225
uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
226
dstStride[1], srcStride[0]);
229
fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
234
static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t *src[],
235
int srcStride[], int srcSliceY, int srcSliceH,
236
uint8_t *dstParam[], int dstStride[])
238
uint8_t *ydst = dstParam[0] + dstStride[0] * srcSliceY;
239
uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
240
uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
242
uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
243
dstStride[1], srcStride[0]);
248
static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels,
249
const uint8_t *palette)
252
for (i = 0; i < num_pixels; i++)
253
((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | (src[(i << 1) + 1] << 24);
256
static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, int num_pixels,
257
const uint8_t *palette)
261
for (i = 0; i < num_pixels; i++)
262
((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i << 1]] | src[(i << 1) + 1];
265
static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels,
266
const uint8_t *palette)
270
for (i = 0; i < num_pixels; i++) {
206
dst[0]= palette[src[i<<1]*4+0];
207
dst[1]= palette[src[i<<1]*4+1];
208
dst[2]= palette[src[i<<1]*4+2];
213
static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
214
int srcSliceH, uint8_t* dst[], int dstStride[])
216
const enum PixelFormat srcFormat= c->srcFormat;
217
const enum PixelFormat dstFormat= c->dstFormat;
272
dst[0] = palette[src[i << 1] * 4 + 0];
273
dst[1] = palette[src[i << 1] * 4 + 1];
274
dst[2] = palette[src[i << 1] * 4 + 2];
279
static int packed_16bpc_bswap(SwsContext *c, const uint8_t *src[],
280
int srcStride[], int srcSliceY, int srcSliceH,
281
uint8_t *dst[], int dstStride[])
284
int srcstr = srcStride[0] >> 1;
285
int dststr = dstStride[0] >> 1;
286
uint16_t *dstPtr = (uint16_t *) dst[0];
287
const uint16_t *srcPtr = (const uint16_t *) src[0];
288
int min_stride = FFMIN(srcstr, dststr);
290
for (i = 0; i < srcSliceH; i++) {
291
for (j = 0; j < min_stride; j++) {
292
dstPtr[j] = av_bswap16(srcPtr[j]);
301
static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
302
int srcSliceY, int srcSliceH, uint8_t *dst[],
305
const enum PixelFormat srcFormat = c->srcFormat;
306
const enum PixelFormat dstFormat = c->dstFormat;
218
307
void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels,
219
const uint8_t *palette)=NULL;
308
const uint8_t *palette) = NULL;
221
uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
222
const uint8_t *srcPtr= src[0];
310
uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
311
const uint8_t *srcPtr = src[0];
224
313
if (srcFormat == PIX_FMT_Y400A) {
225
314
switch (dstFormat) {
291
381
|| CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
294
if ( (isBGRinInt(srcFormat) && isBGRinInt(dstFormat))
295
|| (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
296
switch(srcId | (dstId<<4)) {
297
case 0x34: conv= rgb16to15; break;
298
case 0x36: conv= rgb24to15; break;
299
case 0x38: conv= rgb32to15; break;
300
case 0x43: conv= rgb15to16; break;
301
case 0x46: conv= rgb24to16; break;
302
case 0x48: conv= rgb32to16; break;
303
case 0x63: conv= rgb15to24; break;
304
case 0x64: conv= rgb16to24; break;
305
case 0x68: conv= rgb32to24; break;
306
case 0x83: conv= rgb15to32; break;
307
case 0x84: conv= rgb16to32; break;
308
case 0x86: conv= rgb24to32; break;
384
if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
385
(isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
386
switch (srcId | (dstId << 16)) {
387
case 0x000F0010: conv = rgb16to15; break;
388
case 0x000F0018: conv = rgb24to15; break;
389
case 0x000F0020: conv = rgb32to15; break;
390
case 0x0010000F: conv = rgb15to16; break;
391
case 0x00100018: conv = rgb24to16; break;
392
case 0x00100020: conv = rgb32to16; break;
393
case 0x0018000F: conv = rgb15to24; break;
394
case 0x00180010: conv = rgb16to24; break;
395
case 0x00180020: conv = rgb32to24; break;
396
case 0x0020000F: conv = rgb15to32; break;
397
case 0x00200010: conv = rgb16to32; break;
398
case 0x00200018: conv = rgb24to32; break;
310
} else if ( (isBGRinInt(srcFormat) && isRGBinInt(dstFormat))
311
|| (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
312
switch(srcId | (dstId<<4)) {
313
case 0x33: conv= rgb15tobgr15; break;
314
case 0x34: conv= rgb16tobgr15; break;
315
case 0x36: conv= rgb24tobgr15; break;
316
case 0x38: conv= rgb32tobgr15; break;
317
case 0x43: conv= rgb15tobgr16; break;
318
case 0x44: conv= rgb16tobgr16; break;
319
case 0x46: conv= rgb24tobgr16; break;
320
case 0x48: conv= rgb32tobgr16; break;
321
case 0x63: conv= rgb15tobgr24; break;
322
case 0x64: conv= rgb16tobgr24; break;
323
case 0x66: conv= rgb24tobgr24; break;
324
case 0x68: conv= rgb32tobgr24; break;
325
case 0x83: conv= rgb15tobgr32; break;
326
case 0x84: conv= rgb16tobgr32; break;
327
case 0x86: conv= rgb24tobgr32; break;
400
} else if ((isBGRinInt(srcFormat) && isRGBinInt(dstFormat)) ||
401
(isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
402
switch (srcId | (dstId << 16)) {
403
case 0x000F000F: conv = rgb15tobgr15; break;
404
case 0x000F0010: conv = rgb16tobgr15; break;
405
case 0x000F0018: conv = rgb24tobgr15; break;
406
case 0x000F0020: conv = rgb32tobgr15; break;
407
case 0x0010000F: conv = rgb15tobgr16; break;
408
case 0x00100010: conv = rgb16tobgr16; break;
409
case 0x00100018: conv = rgb24tobgr16; break;
410
case 0x00100020: conv = rgb32tobgr16; break;
411
case 0x0018000F: conv = rgb15tobgr24; break;
412
case 0x00180010: conv = rgb16tobgr24; break;
413
case 0x00180018: conv = rgb24tobgr24; break;
414
case 0x00180020: conv = rgb32tobgr24; break;
415
case 0x0020000F: conv = rgb15tobgr32; break;
416
case 0x00200010: conv = rgb16tobgr32; break;
417
case 0x00200018: conv = rgb24tobgr32; break;
389
485
/* unscaled copy like stuff (assumes nearly identical formats) */
390
static int packedCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
391
int srcSliceH, uint8_t* dst[], int dstStride[])
486
static int packedCopyWrapper(SwsContext *c, const uint8_t *src[],
487
int srcStride[], int srcSliceY, int srcSliceH,
488
uint8_t *dst[], int dstStride[])
393
if (dstStride[0]==srcStride[0] && srcStride[0] > 0)
394
memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]);
490
if (dstStride[0] == srcStride[0] && srcStride[0] > 0)
491
memcpy(dst[0] + dstStride[0] * srcSliceY, src[0], srcSliceH * dstStride[0]);
397
const uint8_t *srcPtr= src[0];
398
uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
494
const uint8_t *srcPtr = src[0];
495
uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
401
498
/* universal length finder */
402
while(length+c->srcW <= FFABS(dstStride[0])
403
&& length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW;
499
while (length + c->srcW <= FFABS(dstStride[0]) &&
500
length + c->srcW <= FFABS(srcStride[0]))
406
for (i=0; i<srcSliceH; i++) {
504
for (i = 0; i < srcSliceH; i++) {
407
505
memcpy(dstPtr, srcPtr, length);
408
srcPtr+= srcStride[0];
409
dstPtr+= dstStride[0];
506
srcPtr += srcStride[0];
507
dstPtr += dstStride[0];
412
510
return srcSliceH;
415
static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
416
int srcSliceH, uint8_t* dst[], int dstStride[])
513
#define clip9(x) av_clip_uintp2(x, 9)
514
#define clip10(x) av_clip_uintp2(x, 10)
515
#define DITHER_COPY(dst, dstStride, wfunc, src, srcStride, rfunc, dithers, shift, clip) \
516
for (i = 0; i < height; i++) { \
517
const uint8_t *dither = dithers[i & 7]; \
518
for (j = 0; j < length - 7; j += 8) { \
519
wfunc(&dst[j + 0], clip((rfunc(&src[j + 0]) + dither[0]) >> shift)); \
520
wfunc(&dst[j + 1], clip((rfunc(&src[j + 1]) + dither[1]) >> shift)); \
521
wfunc(&dst[j + 2], clip((rfunc(&src[j + 2]) + dither[2]) >> shift)); \
522
wfunc(&dst[j + 3], clip((rfunc(&src[j + 3]) + dither[3]) >> shift)); \
523
wfunc(&dst[j + 4], clip((rfunc(&src[j + 4]) + dither[4]) >> shift)); \
524
wfunc(&dst[j + 5], clip((rfunc(&src[j + 5]) + dither[5]) >> shift)); \
525
wfunc(&dst[j + 6], clip((rfunc(&src[j + 6]) + dither[6]) >> shift)); \
526
wfunc(&dst[j + 7], clip((rfunc(&src[j + 7]) + dither[7]) >> shift)); \
528
for (; j < length; j++) \
529
wfunc(&dst[j], (rfunc(&src[j]) + dither[j & 7]) >> shift); \
534
static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
535
int srcStride[], int srcSliceY, int srcSliceH,
536
uint8_t *dst[], int dstStride[])
419
for (plane=0; plane<4; plane++) {
420
int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample);
421
int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample);
422
int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample);
423
const uint8_t *srcPtr= src[plane];
424
uint8_t *dstPtr= dst[plane] + dstStride[plane]*y;
539
for (plane = 0; plane < 4; plane++) {
540
int length = (plane == 0 || plane == 3) ? c->srcW : -((-c->srcW ) >> c->chrDstHSubSample);
541
int y = (plane == 0 || plane == 3) ? srcSliceY: -((-srcSliceY) >> c->chrDstVSubSample);
542
int height = (plane == 0 || plane == 3) ? srcSliceH: -((-srcSliceH) >> c->chrDstVSubSample);
543
const uint8_t *srcPtr = src[plane];
544
uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
426
if (!dst[plane]) continue;
427
548
// ignore palette for GRAY8
428
549
if (plane == 1 && !dst[2]) continue;
429
550
if (!src[plane] || (plane == 1 && !src[2])) {
430
if(is16BPS(c->dstFormat))
432
fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128);
551
if (is16BPS(c->dstFormat))
553
fillPlane(dst[plane], dstStride[plane], length, height, y,
554
(plane == 3) ? 255 : 128);
434
if(is9_OR_10BPS(c->srcFormat)) {
435
const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1+1;
436
const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1+1;
437
const uint16_t *srcPtr2 = (const uint16_t*)srcPtr;
556
if (is9_OR_10BPS(c->srcFormat)) {
557
const int src_depth = av_pix_fmt_descriptors[c->srcFormat].comp[plane].depth_minus1 + 1;
558
const int dst_depth = av_pix_fmt_descriptors[c->dstFormat].comp[plane].depth_minus1 + 1;
559
const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
439
561
if (is16BPS(c->dstFormat)) {
440
uint16_t *dstPtr2 = (uint16_t*)dstPtr;
562
uint16_t *dstPtr2 = (uint16_t *) dstPtr;
441
563
#define COPY9_OR_10TO16(rfunc, wfunc) \
442
564
for (i = 0; i < height; i++) { \
443
565
for (j = 0; j < length; j++) { \
444
566
int srcpx = rfunc(&srcPtr2[j]); \
445
wfunc(&dstPtr2[j], (srcpx<<(16-src_depth)) | (srcpx>>(2*src_depth-16))); \
567
wfunc(&dstPtr2[j], (srcpx << (16 - src_depth)) | (srcpx >> (2 * src_depth - 16))); \
447
dstPtr2 += dstStride[plane]/2; \
448
srcPtr2 += srcStride[plane]/2; \
569
dstPtr2 += dstStride[plane] / 2; \
570
srcPtr2 += srcStride[plane] / 2; \
450
572
if (isBE(c->dstFormat)) {
451
573
if (isBE(c->srcFormat)) {
551
679
COPY8TO9_OR_10(AV_WL16);
554
} else if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
555
if (!isBE(c->srcFormat)) srcPtr++;
556
for (i=0; i<height; i++) {
557
for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
558
srcPtr+= srcStride[plane];
559
dstPtr+= dstStride[plane];
682
} else if (is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
683
const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
684
#define COPY16TO8(rfunc) \
685
DITHER_COPY(dstPtr, dstStride[plane], W8, \
686
srcPtr2, srcStride[plane] / 2, rfunc, \
687
dither_8x8_256, 8, av_clip_uint8);
688
if (isBE(c->srcFormat)) {
561
} else if(!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
562
for (i=0; i<height; i++) {
563
for (j=0; j<length; j++) {
564
dstPtr[ j<<1 ] = srcPtr[j];
565
dstPtr[(j<<1)+1] = srcPtr[j];
693
} else if (!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
694
for (i = 0; i < height; i++) {
695
for (j = 0; j < length; j++) {
696
dstPtr[ j << 1 ] = srcPtr[j];
697
dstPtr[(j << 1) + 1] = srcPtr[j];
567
srcPtr+= srcStride[plane];
568
dstPtr+= dstStride[plane];
699
srcPtr += srcStride[plane];
700
dstPtr += dstStride[plane];
570
} else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)
571
&& isBE(c->srcFormat) != isBE(c->dstFormat)) {
702
} else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
703
isBE(c->srcFormat) != isBE(c->dstFormat)) {
573
for (i=0; i<height; i++) {
574
for (j=0; j<length; j++)
575
((uint16_t*)dstPtr)[j] = av_bswap16(((const uint16_t*)srcPtr)[j]);
576
srcPtr+= srcStride[plane];
577
dstPtr+= dstStride[plane];
705
for (i = 0; i < height; i++) {
706
for (j = 0; j < length; j++)
707
((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);
708
srcPtr += srcStride[plane];
709
dstPtr += dstStride[plane];
579
711
} else if (dstStride[plane] == srcStride[plane] &&
580
712
srcStride[plane] > 0 && srcStride[plane] == length) {
581
memcpy(dst[plane] + dstStride[plane]*y, src[plane],
582
height*dstStride[plane]);
713
memcpy(dst[plane] + dstStride[plane] * y, src[plane],
714
height * dstStride[plane]);
584
if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
586
for (i=0; i<height; i++) {
716
if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
718
for (i = 0; i < height; i++) {
587
719
memcpy(dstPtr, srcPtr, length);
588
srcPtr+= srcStride[plane];
589
dstPtr+= dstStride[plane];
720
srcPtr += srcStride[plane];
721
dstPtr += dstStride[plane];
826
988
// copy strides, so they can safely be modified
827
989
if (c->sliceDir == 1) {
828
990
// slices go from top to bottom
829
int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]};
830
int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]};
991
int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],
993
int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],
832
996
reset_ptr(src2, c->srcFormat);
833
reset_ptr((const uint8_t**)dst2, c->dstFormat);
997
reset_ptr((const uint8_t **) dst2, c->dstFormat);
835
999
/* reset slice direction at end of frame */
836
1000
if (srcSliceY + srcSliceH == c->srcH)
837
1001
c->sliceDir = 0;
839
return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2);
1003
return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
841
1006
// slices go from bottom to top => we flip the image internally
842
int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]};
843
int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]};
1007
int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],
1009
int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],
845
src2[0] += (srcSliceH-1)*srcStride[0];
1012
src2[0] += (srcSliceH - 1) * srcStride[0];
846
1013
if (!usePal(c->srcFormat))
847
src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1];
848
src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2];
849
src2[3] += (srcSliceH-1)*srcStride[3];
850
dst2[0] += ( c->dstH -1)*dstStride[0];
851
dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1];
852
dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2];
853
dst2[3] += ( c->dstH -1)*dstStride[3];
1014
src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
1015
src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
1016
src2[3] += (srcSliceH - 1) * srcStride[3];
1017
dst2[0] += ( c->dstH - 1) * dstStride[0];
1018
dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
1019
dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
1020
dst2[3] += ( c->dstH - 1) * dstStride[3];
855
1022
reset_ptr(src2, c->srcFormat);
856
reset_ptr((const uint8_t**)dst2, c->dstFormat);
1023
reset_ptr((const uint8_t **) dst2, c->dstFormat);
858
1025
/* reset slice direction at end of frame */
860
1027
c->sliceDir = 0;
862
return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2);
1029
return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
1030
srcSliceH, dst2, dstStride2);
866
1034
/* Convert the palette to the same packed 32-bit format as the palette */
867
void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
1035
void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst,
1036
int num_pixels, const uint8_t *palette)
871
for (i=0; i<num_pixels; i++)
1040
for (i = 0; i < num_pixels; i++)
872
1041
((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
875
1044
/* Palette format: ABCD -> dst format: ABC */
876
void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette)
1045
void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst,
1046
int num_pixels, const uint8_t *palette)
880
for (i=0; i<num_pixels; i++) {
1050
for (i = 0; i < num_pixels; i++) {
882
dst[0]= palette[src[i]*4+0];
883
dst[1]= palette[src[i]*4+1];
884
dst[2]= palette[src[i]*4+2];
1052
dst[0] = palette[src[i] * 4 + 0];
1053
dst[1] = palette[src[i] * 4 + 1];
1054
dst[2] = palette[src[i] * 4 + 2];