Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52868 views
1
/*
2
* software YUV to RGB converter
3
*
4
* Copyright (C) 2009 Konstantin Shishkov
5
*
6
* 1,4,8bpp support and context / deglobalize stuff
7
* by Michael Niedermayer ([email protected])
8
*
9
* This file is part of FFmpeg.
10
*
11
* FFmpeg is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU Lesser General Public
13
* License as published by the Free Software Foundation; either
14
* version 2.1 of the License, or (at your option) any later version.
15
*
16
* FFmpeg is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
* Lesser General Public License for more details.
20
*
21
* You should have received a copy of the GNU Lesser General Public
22
* License along with FFmpeg; if not, write to the Free Software
23
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
*/
25
26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <inttypes.h>
29
30
#include "libavutil/cpu.h"
31
#include "libavutil/bswap.h"
32
#include "config.h"
33
#include "rgb2rgb.h"
34
#include "swscale.h"
35
#include "swscale_internal.h"
36
#include "libavutil/pixdesc.h"
37
38
/* Color space conversion coefficients for YCbCr -> RGB mapping.
39
*
40
* Entries are {crv, cbu, cgu, cgv}
41
*
42
* crv = (255 / 224) * 65536 * (1 - cr) / 0.5
43
* cbu = (255 / 224) * 65536 * (1 - cb) / 0.5
44
* cgu = (255 / 224) * 65536 * (cb / cg) * (1 - cb) / 0.5
45
* cgv = (255 / 224) * 65536 * (cr / cg) * (1 - cr) / 0.5
46
*
47
* where Y = cr * R + cg * G + cb * B and cr + cg + cb = 1.
48
*/
49
const int32_t ff_yuv2rgb_coeffs[8][4] = {
50
{ 117504, 138453, 13954, 34903 }, /* no sequence_display_extension */
51
{ 117504, 138453, 13954, 34903 }, /* ITU-R Rec. 709 (1990) */
52
{ 104597, 132201, 25675, 53279 }, /* unspecified */
53
{ 104597, 132201, 25675, 53279 }, /* reserved */
54
{ 104448, 132798, 24759, 53109 }, /* FCC */
55
{ 104597, 132201, 25675, 53279 }, /* ITU-R Rec. 624-4 System B, G */
56
{ 104597, 132201, 25675, 53279 }, /* SMPTE 170M */
57
{ 117579, 136230, 16907, 35559 } /* SMPTE 240M (1987) */
58
};
59
60
const int *sws_getCoefficients(int colorspace)
61
{
62
if (colorspace > 7 || colorspace < 0)
63
colorspace = SWS_CS_DEFAULT;
64
return ff_yuv2rgb_coeffs[colorspace];
65
}
66
67
#define LOADCHROMA(i) \
68
U = pu[i]; \
69
V = pv[i]; \
70
r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM]; \
71
g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] + c->table_gV[V+YUVRGB_TABLE_HEADROOM]); \
72
b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM];
73
74
#define PUTRGB(dst, src, i) \
75
Y = src[2 * i]; \
76
dst[2 * i] = r[Y] + g[Y] + b[Y]; \
77
Y = src[2 * i + 1]; \
78
dst[2 * i + 1] = r[Y] + g[Y] + b[Y];
79
80
#define PUTRGB24(dst, src, i) \
81
Y = src[2 * i]; \
82
dst[6 * i + 0] = r[Y]; \
83
dst[6 * i + 1] = g[Y]; \
84
dst[6 * i + 2] = b[Y]; \
85
Y = src[2 * i + 1]; \
86
dst[6 * i + 3] = r[Y]; \
87
dst[6 * i + 4] = g[Y]; \
88
dst[6 * i + 5] = b[Y];
89
90
#define PUTBGR24(dst, src, i) \
91
Y = src[2 * i]; \
92
dst[6 * i + 0] = b[Y]; \
93
dst[6 * i + 1] = g[Y]; \
94
dst[6 * i + 2] = r[Y]; \
95
Y = src[2 * i + 1]; \
96
dst[6 * i + 3] = b[Y]; \
97
dst[6 * i + 4] = g[Y]; \
98
dst[6 * i + 5] = r[Y];
99
100
#define PUTRGBA(dst, ysrc, asrc, i, s) \
101
Y = ysrc[2 * i]; \
102
dst[2 * i] = r[Y] + g[Y] + b[Y] + (asrc[2 * i] << s); \
103
Y = ysrc[2 * i + 1]; \
104
dst[2 * i + 1] = r[Y] + g[Y] + b[Y] + (asrc[2 * i + 1] << s);
105
106
#define PUTRGB48(dst, src, i) \
107
Y = src[ 2 * i]; \
108
dst[12 * i + 0] = dst[12 * i + 1] = r[Y]; \
109
dst[12 * i + 2] = dst[12 * i + 3] = g[Y]; \
110
dst[12 * i + 4] = dst[12 * i + 5] = b[Y]; \
111
Y = src[ 2 * i + 1]; \
112
dst[12 * i + 6] = dst[12 * i + 7] = r[Y]; \
113
dst[12 * i + 8] = dst[12 * i + 9] = g[Y]; \
114
dst[12 * i + 10] = dst[12 * i + 11] = b[Y];
115
116
#define PUTBGR48(dst, src, i) \
117
Y = src[2 * i]; \
118
dst[12 * i + 0] = dst[12 * i + 1] = b[Y]; \
119
dst[12 * i + 2] = dst[12 * i + 3] = g[Y]; \
120
dst[12 * i + 4] = dst[12 * i + 5] = r[Y]; \
121
Y = src[2 * i + 1]; \
122
dst[12 * i + 6] = dst[12 * i + 7] = b[Y]; \
123
dst[12 * i + 8] = dst[12 * i + 9] = g[Y]; \
124
dst[12 * i + 10] = dst[12 * i + 11] = r[Y];
125
126
#define YUV2RGBFUNC(func_name, dst_type, alpha) \
127
static int func_name(SwsContext *c, const uint8_t *src[], \
128
int srcStride[], int srcSliceY, int srcSliceH, \
129
uint8_t *dst[], int dstStride[]) \
130
{ \
131
int y; \
132
\
133
if (!alpha && c->srcFormat == AV_PIX_FMT_YUV422P) { \
134
srcStride[1] *= 2; \
135
srcStride[2] *= 2; \
136
} \
137
for (y = 0; y < srcSliceH; y += 2) { \
138
dst_type *dst_1 = \
139
(dst_type *)(dst[0] + (y + srcSliceY) * dstStride[0]); \
140
dst_type *dst_2 = \
141
(dst_type *)(dst[0] + (y + srcSliceY + 1) * dstStride[0]); \
142
dst_type av_unused *r, *g, *b; \
143
const uint8_t *py_1 = src[0] + y * srcStride[0]; \
144
const uint8_t *py_2 = py_1 + srcStride[0]; \
145
const uint8_t *pu = src[1] + (y >> 1) * srcStride[1]; \
146
const uint8_t *pv = src[2] + (y >> 1) * srcStride[2]; \
147
const uint8_t av_unused *pa_1, *pa_2; \
148
unsigned int h_size = c->dstW >> 3; \
149
if (alpha) { \
150
pa_1 = src[3] + y * srcStride[3]; \
151
pa_2 = pa_1 + srcStride[3]; \
152
} \
153
while (h_size--) { \
154
int av_unused U, V, Y; \
155
156
#define ENDYUV2RGBLINE(dst_delta, ss) \
157
pu += 4 >> ss; \
158
pv += 4 >> ss; \
159
py_1 += 8 >> ss; \
160
py_2 += 8 >> ss; \
161
dst_1 += dst_delta >> ss; \
162
dst_2 += dst_delta >> ss; \
163
} \
164
if (c->dstW & (4 >> ss)) { \
165
int av_unused Y, U, V; \
166
167
#define ENDYUV2RGBFUNC() \
168
} \
169
} \
170
return srcSliceH; \
171
}
172
173
#define CLOSEYUV2RGBFUNC(dst_delta) \
174
ENDYUV2RGBLINE(dst_delta, 0) \
175
ENDYUV2RGBFUNC()
176
177
YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
178
LOADCHROMA(0);
179
PUTRGB48(dst_1, py_1, 0);
180
PUTRGB48(dst_2, py_2, 0);
181
182
LOADCHROMA(1);
183
PUTRGB48(dst_2, py_2, 1);
184
PUTRGB48(dst_1, py_1, 1);
185
186
LOADCHROMA(2);
187
PUTRGB48(dst_1, py_1, 2);
188
PUTRGB48(dst_2, py_2, 2);
189
190
LOADCHROMA(3);
191
PUTRGB48(dst_2, py_2, 3);
192
PUTRGB48(dst_1, py_1, 3);
193
ENDYUV2RGBLINE(48, 0)
194
LOADCHROMA(0);
195
PUTRGB48(dst_1, py_1, 0);
196
PUTRGB48(dst_2, py_2, 0);
197
198
LOADCHROMA(1);
199
PUTRGB48(dst_2, py_2, 1);
200
PUTRGB48(dst_1, py_1, 1);
201
ENDYUV2RGBLINE(48, 1)
202
LOADCHROMA(0);
203
PUTRGB48(dst_1, py_1, 0);
204
PUTRGB48(dst_2, py_2, 0);
205
ENDYUV2RGBFUNC()
206
207
YUV2RGBFUNC(yuv2rgb_c_bgr48, uint8_t, 0)
208
LOADCHROMA(0);
209
PUTBGR48(dst_1, py_1, 0);
210
PUTBGR48(dst_2, py_2, 0);
211
212
LOADCHROMA(1);
213
PUTBGR48(dst_2, py_2, 1);
214
PUTBGR48(dst_1, py_1, 1);
215
216
LOADCHROMA(2);
217
PUTBGR48(dst_1, py_1, 2);
218
PUTBGR48(dst_2, py_2, 2);
219
220
LOADCHROMA(3);
221
PUTBGR48(dst_2, py_2, 3);
222
PUTBGR48(dst_1, py_1, 3);
223
ENDYUV2RGBLINE(48, 0)
224
LOADCHROMA(0);
225
PUTBGR48(dst_1, py_1, 0);
226
PUTBGR48(dst_2, py_2, 0);
227
228
LOADCHROMA(1);
229
PUTBGR48(dst_2, py_2, 1);
230
PUTBGR48(dst_1, py_1, 1);
231
ENDYUV2RGBLINE(48, 1)
232
LOADCHROMA(0);
233
PUTBGR48(dst_1, py_1, 0);
234
PUTBGR48(dst_2, py_2, 0);
235
ENDYUV2RGBFUNC()
236
237
YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
238
LOADCHROMA(0);
239
PUTRGB(dst_1, py_1, 0);
240
PUTRGB(dst_2, py_2, 0);
241
242
LOADCHROMA(1);
243
PUTRGB(dst_2, py_2, 1);
244
PUTRGB(dst_1, py_1, 1);
245
246
LOADCHROMA(2);
247
PUTRGB(dst_1, py_1, 2);
248
PUTRGB(dst_2, py_2, 2);
249
250
LOADCHROMA(3);
251
PUTRGB(dst_2, py_2, 3);
252
PUTRGB(dst_1, py_1, 3);
253
ENDYUV2RGBLINE(8, 0)
254
LOADCHROMA(0);
255
PUTRGB(dst_1, py_1, 0);
256
PUTRGB(dst_2, py_2, 0);
257
258
LOADCHROMA(1);
259
PUTRGB(dst_2, py_2, 1);
260
PUTRGB(dst_1, py_1, 1);
261
ENDYUV2RGBLINE(8, 1)
262
LOADCHROMA(0);
263
PUTRGB(dst_1, py_1, 0);
264
PUTRGB(dst_2, py_2, 0);
265
ENDYUV2RGBFUNC()
266
267
YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
268
LOADCHROMA(0);
269
PUTRGBA(dst_1, py_1, pa_1, 0, 24);
270
PUTRGBA(dst_2, py_2, pa_2, 0, 24);
271
272
LOADCHROMA(1);
273
PUTRGBA(dst_2, py_2, pa_2, 1, 24);
274
PUTRGBA(dst_1, py_1, pa_1, 1, 24);
275
276
LOADCHROMA(2);
277
PUTRGBA(dst_1, py_1, pa_1, 2, 24);
278
PUTRGBA(dst_2, py_2, pa_2, 2, 24);
279
280
LOADCHROMA(3);
281
PUTRGBA(dst_2, py_2, pa_2, 3, 24);
282
PUTRGBA(dst_1, py_1, pa_1, 3, 24);
283
pa_1 += 8;
284
pa_2 += 8;
285
ENDYUV2RGBLINE(8, 0)
286
LOADCHROMA(0);
287
PUTRGBA(dst_1, py_1, pa_1, 0, 24);
288
PUTRGBA(dst_2, py_2, pa_2, 0, 24);
289
290
LOADCHROMA(1);
291
PUTRGBA(dst_2, py_2, pa_2, 1, 24);
292
PUTRGBA(dst_1, py_1, pa_1, 1, 24);
293
pa_1 += 4;
294
pa_2 += 4;
295
ENDYUV2RGBLINE(8, 1)
296
LOADCHROMA(0);
297
PUTRGBA(dst_1, py_1, pa_1, 0, 24);
298
PUTRGBA(dst_2, py_2, pa_2, 0, 24);
299
ENDYUV2RGBFUNC()
300
301
YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
302
LOADCHROMA(0);
303
PUTRGBA(dst_1, py_1, pa_1, 0, 0);
304
PUTRGBA(dst_2, py_2, pa_2, 0, 0);
305
306
LOADCHROMA(1);
307
PUTRGBA(dst_2, py_2, pa_2, 1, 0);
308
PUTRGBA(dst_1, py_1, pa_1, 1, 0);
309
310
LOADCHROMA(2);
311
PUTRGBA(dst_1, py_1, pa_1, 2, 0);
312
PUTRGBA(dst_2, py_2, pa_2, 2, 0);
313
314
LOADCHROMA(3);
315
PUTRGBA(dst_2, py_2, pa_2, 3, 0);
316
PUTRGBA(dst_1, py_1, pa_1, 3, 0);
317
pa_1 += 8;
318
pa_2 += 8;
319
ENDYUV2RGBLINE(8, 0)
320
LOADCHROMA(0);
321
PUTRGBA(dst_1, py_1, pa_1, 0, 0);
322
PUTRGBA(dst_2, py_2, pa_2, 0, 0);
323
324
LOADCHROMA(1);
325
PUTRGBA(dst_2, py_2, pa_2, 1, 0);
326
PUTRGBA(dst_1, py_1, pa_1, 1, 0);
327
pa_1 += 4;
328
pa_2 += 4;
329
ENDYUV2RGBLINE(8, 1)
330
LOADCHROMA(0);
331
PUTRGBA(dst_1, py_1, pa_1, 0, 0);
332
PUTRGBA(dst_2, py_2, pa_2, 0, 0);
333
ENDYUV2RGBFUNC()
334
335
YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0)
336
LOADCHROMA(0);
337
PUTRGB24(dst_1, py_1, 0);
338
PUTRGB24(dst_2, py_2, 0);
339
340
LOADCHROMA(1);
341
PUTRGB24(dst_2, py_2, 1);
342
PUTRGB24(dst_1, py_1, 1);
343
344
LOADCHROMA(2);
345
PUTRGB24(dst_1, py_1, 2);
346
PUTRGB24(dst_2, py_2, 2);
347
348
LOADCHROMA(3);
349
PUTRGB24(dst_2, py_2, 3);
350
PUTRGB24(dst_1, py_1, 3);
351
ENDYUV2RGBLINE(24, 0)
352
LOADCHROMA(0);
353
PUTRGB24(dst_1, py_1, 0);
354
PUTRGB24(dst_2, py_2, 0);
355
356
LOADCHROMA(1);
357
PUTRGB24(dst_2, py_2, 1);
358
PUTRGB24(dst_1, py_1, 1);
359
ENDYUV2RGBLINE(24, 1)
360
LOADCHROMA(0);
361
PUTRGB24(dst_1, py_1, 0);
362
PUTRGB24(dst_2, py_2, 0);
363
ENDYUV2RGBFUNC()
364
365
// only trivial mods from yuv2rgb_c_24_rgb
366
YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0)
367
LOADCHROMA(0);
368
PUTBGR24(dst_1, py_1, 0);
369
PUTBGR24(dst_2, py_2, 0);
370
371
LOADCHROMA(1);
372
PUTBGR24(dst_2, py_2, 1);
373
PUTBGR24(dst_1, py_1, 1);
374
375
LOADCHROMA(2);
376
PUTBGR24(dst_1, py_1, 2);
377
PUTBGR24(dst_2, py_2, 2);
378
379
LOADCHROMA(3);
380
PUTBGR24(dst_2, py_2, 3);
381
PUTBGR24(dst_1, py_1, 3);
382
ENDYUV2RGBLINE(24, 0)
383
LOADCHROMA(0);
384
PUTBGR24(dst_1, py_1, 0);
385
PUTBGR24(dst_2, py_2, 0);
386
387
LOADCHROMA(1);
388
PUTBGR24(dst_2, py_2, 1);
389
PUTBGR24(dst_1, py_1, 1);
390
ENDYUV2RGBLINE(24, 1)
391
LOADCHROMA(0);
392
PUTBGR24(dst_1, py_1, 0);
393
PUTBGR24(dst_2, py_2, 0);
394
ENDYUV2RGBFUNC()
395
396
YUV2RGBFUNC(yuv2rgb_c_16_ordered_dither, uint16_t, 0)
397
const uint8_t *d16 = ff_dither_2x2_8[y & 1];
398
const uint8_t *e16 = ff_dither_2x2_4[y & 1];
399
const uint8_t *f16 = ff_dither_2x2_8[(y & 1)^1];
400
401
#define PUTRGB16(dst, src, i, o) \
402
Y = src[2 * i]; \
403
dst[2 * i] = r[Y + d16[0 + o]] + \
404
g[Y + e16[0 + o]] + \
405
b[Y + f16[0 + o]]; \
406
Y = src[2 * i + 1]; \
407
dst[2 * i + 1] = r[Y + d16[1 + o]] + \
408
g[Y + e16[1 + o]] + \
409
b[Y + f16[1 + o]];
410
LOADCHROMA(0);
411
PUTRGB16(dst_1, py_1, 0, 0);
412
PUTRGB16(dst_2, py_2, 0, 0 + 8);
413
414
LOADCHROMA(1);
415
PUTRGB16(dst_2, py_2, 1, 2 + 8);
416
PUTRGB16(dst_1, py_1, 1, 2);
417
418
LOADCHROMA(2);
419
PUTRGB16(dst_1, py_1, 2, 4);
420
PUTRGB16(dst_2, py_2, 2, 4 + 8);
421
422
LOADCHROMA(3);
423
PUTRGB16(dst_2, py_2, 3, 6 + 8);
424
PUTRGB16(dst_1, py_1, 3, 6);
425
CLOSEYUV2RGBFUNC(8)
426
427
YUV2RGBFUNC(yuv2rgb_c_15_ordered_dither, uint16_t, 0)
428
const uint8_t *d16 = ff_dither_2x2_8[y & 1];
429
const uint8_t *e16 = ff_dither_2x2_8[(y & 1)^1];
430
431
#define PUTRGB15(dst, src, i, o) \
432
Y = src[2 * i]; \
433
dst[2 * i] = r[Y + d16[0 + o]] + \
434
g[Y + d16[1 + o]] + \
435
b[Y + e16[0 + o]]; \
436
Y = src[2 * i + 1]; \
437
dst[2 * i + 1] = r[Y + d16[1 + o]] + \
438
g[Y + d16[0 + o]] + \
439
b[Y + e16[1 + o]];
440
LOADCHROMA(0);
441
PUTRGB15(dst_1, py_1, 0, 0);
442
PUTRGB15(dst_2, py_2, 0, 0 + 8);
443
444
LOADCHROMA(1);
445
PUTRGB15(dst_2, py_2, 1, 2 + 8);
446
PUTRGB15(dst_1, py_1, 1, 2);
447
448
LOADCHROMA(2);
449
PUTRGB15(dst_1, py_1, 2, 4);
450
PUTRGB15(dst_2, py_2, 2, 4 + 8);
451
452
LOADCHROMA(3);
453
PUTRGB15(dst_2, py_2, 3, 6 + 8);
454
PUTRGB15(dst_1, py_1, 3, 6);
455
CLOSEYUV2RGBFUNC(8)
456
457
// r, g, b, dst_1, dst_2
458
YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
459
const uint8_t *d16 = ff_dither_4x4_16[y & 3];
460
461
#define PUTRGB12(dst, src, i, o) \
462
Y = src[2 * i]; \
463
dst[2 * i] = r[Y + d16[0 + o]] + \
464
g[Y + d16[0 + o]] + \
465
b[Y + d16[0 + o]]; \
466
Y = src[2 * i + 1]; \
467
dst[2 * i + 1] = r[Y + d16[1 + o]] + \
468
g[Y + d16[1 + o]] + \
469
b[Y + d16[1 + o]];
470
471
LOADCHROMA(0);
472
PUTRGB12(dst_1, py_1, 0, 0);
473
PUTRGB12(dst_2, py_2, 0, 0 + 8);
474
475
LOADCHROMA(1);
476
PUTRGB12(dst_2, py_2, 1, 2 + 8);
477
PUTRGB12(dst_1, py_1, 1, 2);
478
479
LOADCHROMA(2);
480
PUTRGB12(dst_1, py_1, 2, 4);
481
PUTRGB12(dst_2, py_2, 2, 4 + 8);
482
483
LOADCHROMA(3);
484
PUTRGB12(dst_2, py_2, 3, 6 + 8);
485
PUTRGB12(dst_1, py_1, 3, 6);
486
CLOSEYUV2RGBFUNC(8)
487
488
// r, g, b, dst_1, dst_2
489
YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
490
const uint8_t *d32 = ff_dither_8x8_32[y & 7];
491
const uint8_t *d64 = ff_dither_8x8_73[y & 7];
492
493
#define PUTRGB8(dst, src, i, o) \
494
Y = src[2 * i]; \
495
dst[2 * i] = r[Y + d32[0 + o]] + \
496
g[Y + d32[0 + o]] + \
497
b[Y + d64[0 + o]]; \
498
Y = src[2 * i + 1]; \
499
dst[2 * i + 1] = r[Y + d32[1 + o]] + \
500
g[Y + d32[1 + o]] + \
501
b[Y + d64[1 + o]];
502
503
LOADCHROMA(0);
504
PUTRGB8(dst_1, py_1, 0, 0);
505
PUTRGB8(dst_2, py_2, 0, 0 + 8);
506
507
LOADCHROMA(1);
508
PUTRGB8(dst_2, py_2, 1, 2 + 8);
509
PUTRGB8(dst_1, py_1, 1, 2);
510
511
LOADCHROMA(2);
512
PUTRGB8(dst_1, py_1, 2, 4);
513
PUTRGB8(dst_2, py_2, 2, 4 + 8);
514
515
LOADCHROMA(3);
516
PUTRGB8(dst_2, py_2, 3, 6 + 8);
517
PUTRGB8(dst_1, py_1, 3, 6);
518
519
ENDYUV2RGBLINE(8, 0)
520
const uint8_t *d32 = ff_dither_8x8_32[y & 7];
521
const uint8_t *d64 = ff_dither_8x8_73[y & 7];
522
LOADCHROMA(0);
523
PUTRGB8(dst_1, py_1, 0, 0);
524
PUTRGB8(dst_2, py_2, 0, 0 + 8);
525
526
LOADCHROMA(1);
527
PUTRGB8(dst_2, py_2, 1, 2 + 8);
528
PUTRGB8(dst_1, py_1, 1, 2);
529
530
ENDYUV2RGBLINE(8, 1)
531
const uint8_t *d32 = ff_dither_8x8_32[y & 7];
532
const uint8_t *d64 = ff_dither_8x8_73[y & 7];
533
LOADCHROMA(0);
534
PUTRGB8(dst_1, py_1, 0, 0);
535
PUTRGB8(dst_2, py_2, 0, 0 + 8);
536
537
ENDYUV2RGBFUNC()
538
539
540
YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
541
const uint8_t * d64 = ff_dither_8x8_73[y & 7];
542
const uint8_t *d128 = ff_dither_8x8_220[y & 7];
543
int acc;
544
545
#define PUTRGB4D(dst, src, i, o) \
546
Y = src[2 * i]; \
547
acc = r[Y + d128[0 + o]] + \
548
g[Y + d64[0 + o]] + \
549
b[Y + d128[0 + o]]; \
550
Y = src[2 * i + 1]; \
551
acc |= (r[Y + d128[1 + o]] + \
552
g[Y + d64[1 + o]] + \
553
b[Y + d128[1 + o]]) << 4; \
554
dst[i] = acc;
555
556
LOADCHROMA(0);
557
PUTRGB4D(dst_1, py_1, 0, 0);
558
PUTRGB4D(dst_2, py_2, 0, 0 + 8);
559
560
LOADCHROMA(1);
561
PUTRGB4D(dst_2, py_2, 1, 2 + 8);
562
PUTRGB4D(dst_1, py_1, 1, 2);
563
564
LOADCHROMA(2);
565
PUTRGB4D(dst_1, py_1, 2, 4);
566
PUTRGB4D(dst_2, py_2, 2, 4 + 8);
567
568
LOADCHROMA(3);
569
PUTRGB4D(dst_2, py_2, 3, 6 + 8);
570
PUTRGB4D(dst_1, py_1, 3, 6);
571
572
ENDYUV2RGBLINE(4, 0)
573
const uint8_t * d64 = ff_dither_8x8_73[y & 7];
574
const uint8_t *d128 = ff_dither_8x8_220[y & 7];
575
int acc;
576
LOADCHROMA(0);
577
PUTRGB4D(dst_1, py_1, 0, 0);
578
PUTRGB4D(dst_2, py_2, 0, 0 + 8);
579
580
LOADCHROMA(1);
581
PUTRGB4D(dst_2, py_2, 1, 2 + 8);
582
PUTRGB4D(dst_1, py_1, 1, 2);
583
584
ENDYUV2RGBLINE(4, 1)
585
const uint8_t * d64 = ff_dither_8x8_73[y & 7];
586
const uint8_t *d128 = ff_dither_8x8_220[y & 7];
587
int acc;
588
LOADCHROMA(0);
589
PUTRGB4D(dst_1, py_1, 0, 0);
590
PUTRGB4D(dst_2, py_2, 0, 0 + 8);
591
ENDYUV2RGBFUNC()
592
593
YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
594
const uint8_t *d64 = ff_dither_8x8_73[y & 7];
595
const uint8_t *d128 = ff_dither_8x8_220[y & 7];
596
597
#define PUTRGB4DB(dst, src, i, o) \
598
Y = src[2 * i]; \
599
dst[2 * i] = r[Y + d128[0 + o]] + \
600
g[Y + d64[0 + o]] + \
601
b[Y + d128[0 + o]]; \
602
Y = src[2 * i + 1]; \
603
dst[2 * i + 1] = r[Y + d128[1 + o]] + \
604
g[Y + d64[1 + o]] + \
605
b[Y + d128[1 + o]];
606
607
LOADCHROMA(0);
608
PUTRGB4DB(dst_1, py_1, 0, 0);
609
PUTRGB4DB(dst_2, py_2, 0, 0 + 8);
610
611
LOADCHROMA(1);
612
PUTRGB4DB(dst_2, py_2, 1, 2 + 8);
613
PUTRGB4DB(dst_1, py_1, 1, 2);
614
615
LOADCHROMA(2);
616
PUTRGB4DB(dst_1, py_1, 2, 4);
617
PUTRGB4DB(dst_2, py_2, 2, 4 + 8);
618
619
LOADCHROMA(3);
620
PUTRGB4DB(dst_2, py_2, 3, 6 + 8);
621
PUTRGB4DB(dst_1, py_1, 3, 6);
622
ENDYUV2RGBLINE(8, 0)
623
const uint8_t *d64 = ff_dither_8x8_73[y & 7];
624
const uint8_t *d128 = ff_dither_8x8_220[y & 7];
625
LOADCHROMA(0);
626
PUTRGB4DB(dst_1, py_1, 0, 0);
627
PUTRGB4DB(dst_2, py_2, 0, 0 + 8);
628
629
LOADCHROMA(1);
630
PUTRGB4DB(dst_2, py_2, 1, 2 + 8);
631
PUTRGB4DB(dst_1, py_1, 1, 2);
632
ENDYUV2RGBLINE(8, 1)
633
const uint8_t *d64 = ff_dither_8x8_73[y & 7];
634
const uint8_t *d128 = ff_dither_8x8_220[y & 7];
635
LOADCHROMA(0);
636
PUTRGB4DB(dst_1, py_1, 0, 0);
637
PUTRGB4DB(dst_2, py_2, 0, 0 + 8);
638
ENDYUV2RGBFUNC()
639
640
YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
641
const uint8_t *d128 = ff_dither_8x8_220[y & 7];
642
char out_1 = 0, out_2 = 0;
643
g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
644
645
#define PUTRGB1(out, src, i, o) \
646
Y = src[2 * i]; \
647
out += out + g[Y + d128[0 + o]]; \
648
Y = src[2 * i + 1]; \
649
out += out + g[Y + d128[1 + o]];
650
651
PUTRGB1(out_1, py_1, 0, 0);
652
PUTRGB1(out_2, py_2, 0, 0 + 8);
653
654
PUTRGB1(out_2, py_2, 1, 2 + 8);
655
PUTRGB1(out_1, py_1, 1, 2);
656
657
PUTRGB1(out_1, py_1, 2, 4);
658
PUTRGB1(out_2, py_2, 2, 4 + 8);
659
660
PUTRGB1(out_2, py_2, 3, 6 + 8);
661
PUTRGB1(out_1, py_1, 3, 6);
662
663
dst_1[0] = out_1;
664
dst_2[0] = out_2;
665
CLOSEYUV2RGBFUNC(1)
666
667
SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
668
{
669
SwsFunc t = NULL;
670
671
if (ARCH_PPC)
672
t = ff_yuv2rgb_init_ppc(c);
673
if (ARCH_X86)
674
t = ff_yuv2rgb_init_x86(c);
675
676
if (t)
677
return t;
678
679
av_log(c, AV_LOG_WARNING,
680
"No accelerated colorspace conversion found from %s to %s.\n",
681
av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
682
683
switch (c->dstFormat) {
684
case AV_PIX_FMT_BGR48BE:
685
case AV_PIX_FMT_BGR48LE:
686
return yuv2rgb_c_bgr48;
687
case AV_PIX_FMT_RGB48BE:
688
case AV_PIX_FMT_RGB48LE:
689
return yuv2rgb_c_48;
690
case AV_PIX_FMT_ARGB:
691
case AV_PIX_FMT_ABGR:
692
if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat))
693
return yuva2argb_c;
694
case AV_PIX_FMT_RGBA:
695
case AV_PIX_FMT_BGRA:
696
return (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) ? yuva2rgba_c : yuv2rgb_c_32;
697
case AV_PIX_FMT_RGB24:
698
return yuv2rgb_c_24_rgb;
699
case AV_PIX_FMT_BGR24:
700
return yuv2rgb_c_24_bgr;
701
case AV_PIX_FMT_RGB565:
702
case AV_PIX_FMT_BGR565:
703
return yuv2rgb_c_16_ordered_dither;
704
case AV_PIX_FMT_RGB555:
705
case AV_PIX_FMT_BGR555:
706
return yuv2rgb_c_15_ordered_dither;
707
case AV_PIX_FMT_RGB444:
708
case AV_PIX_FMT_BGR444:
709
return yuv2rgb_c_12_ordered_dither;
710
case AV_PIX_FMT_RGB8:
711
case AV_PIX_FMT_BGR8:
712
return yuv2rgb_c_8_ordered_dither;
713
case AV_PIX_FMT_RGB4:
714
case AV_PIX_FMT_BGR4:
715
return yuv2rgb_c_4_ordered_dither;
716
case AV_PIX_FMT_RGB4_BYTE:
717
case AV_PIX_FMT_BGR4_BYTE:
718
return yuv2rgb_c_4b_ordered_dither;
719
case AV_PIX_FMT_MONOBLACK:
720
return yuv2rgb_c_1_ordered_dither;
721
}
722
return NULL;
723
}
724
725
static void fill_table(uint8_t* table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize,
726
const int64_t inc, void *y_tab)
727
{
728
int i;
729
uint8_t *y_table = y_tab;
730
731
y_table -= elemsize * (inc >> 9);
732
733
for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
734
int64_t cb = av_clip_uint8(i-YUVRGB_TABLE_HEADROOM)*inc;
735
table[i] = y_table + elemsize * (cb >> 16);
736
}
737
}
738
739
static void fill_gv_table(int table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize, const int64_t inc)
740
{
741
int i;
742
int off = -(inc >> 9);
743
744
for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
745
int64_t cb = av_clip_uint8(i-YUVRGB_TABLE_HEADROOM)*inc;
746
table[i] = elemsize * (off + (cb >> 16));
747
}
748
}
749
750
static uint16_t roundToInt16(int64_t f)
751
{
752
int r = (f + (1 << 15)) >> 16;
753
754
if (r < -0x7FFF)
755
return 0x8000;
756
else if (r > 0x7FFF)
757
return 0x7FFF;
758
else
759
return r;
760
}
761
762
av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4],
763
int fullRange, int brightness,
764
int contrast, int saturation)
765
{
766
const int isRgb = c->dstFormat == AV_PIX_FMT_RGB32 ||
767
c->dstFormat == AV_PIX_FMT_RGB32_1 ||
768
c->dstFormat == AV_PIX_FMT_BGR24 ||
769
c->dstFormat == AV_PIX_FMT_RGB565BE ||
770
c->dstFormat == AV_PIX_FMT_RGB565LE ||
771
c->dstFormat == AV_PIX_FMT_RGB555BE ||
772
c->dstFormat == AV_PIX_FMT_RGB555LE ||
773
c->dstFormat == AV_PIX_FMT_RGB444BE ||
774
c->dstFormat == AV_PIX_FMT_RGB444LE ||
775
c->dstFormat == AV_PIX_FMT_RGB8 ||
776
c->dstFormat == AV_PIX_FMT_RGB4 ||
777
c->dstFormat == AV_PIX_FMT_RGB4_BYTE ||
778
c->dstFormat == AV_PIX_FMT_MONOBLACK;
779
const int isNotNe = c->dstFormat == AV_PIX_FMT_NE(RGB565LE, RGB565BE) ||
780
c->dstFormat == AV_PIX_FMT_NE(RGB555LE, RGB555BE) ||
781
c->dstFormat == AV_PIX_FMT_NE(RGB444LE, RGB444BE) ||
782
c->dstFormat == AV_PIX_FMT_NE(BGR565LE, BGR565BE) ||
783
c->dstFormat == AV_PIX_FMT_NE(BGR555LE, BGR555BE) ||
784
c->dstFormat == AV_PIX_FMT_NE(BGR444LE, BGR444BE);
785
const int bpp = c->dstFormatBpp;
786
uint8_t *y_table;
787
uint16_t *y_table16;
788
uint32_t *y_table32;
789
int i, base, rbase, gbase, bbase, av_uninit(abase), needAlpha;
790
const int yoffs = (fullRange ? 384 : 326) + YUVRGB_TABLE_LUMA_HEADROOM;
791
const int table_plane_size = 1024 + 2*YUVRGB_TABLE_LUMA_HEADROOM;
792
793
int64_t crv = inv_table[0];
794
int64_t cbu = inv_table[1];
795
int64_t cgu = -inv_table[2];
796
int64_t cgv = -inv_table[3];
797
int64_t cy = 1 << 16;
798
int64_t oy = 0;
799
int64_t yb = 0;
800
801
if (!fullRange) {
802
cy = (cy * 255) / 219;
803
oy = 16 << 16;
804
} else {
805
crv = (crv * 224) / 255;
806
cbu = (cbu * 224) / 255;
807
cgu = (cgu * 224) / 255;
808
cgv = (cgv * 224) / 255;
809
}
810
811
cy = (cy * contrast) >> 16;
812
crv = (crv * contrast * saturation) >> 32;
813
cbu = (cbu * contrast * saturation) >> 32;
814
cgu = (cgu * contrast * saturation) >> 32;
815
cgv = (cgv * contrast * saturation) >> 32;
816
oy -= 256 * brightness;
817
818
c->uOffset = 0x0400040004000400LL;
819
c->vOffset = 0x0400040004000400LL;
820
c->yCoeff = roundToInt16(cy * 8192) * 0x0001000100010001ULL;
821
c->vrCoeff = roundToInt16(crv * 8192) * 0x0001000100010001ULL;
822
c->ubCoeff = roundToInt16(cbu * 8192) * 0x0001000100010001ULL;
823
c->vgCoeff = roundToInt16(cgv * 8192) * 0x0001000100010001ULL;
824
c->ugCoeff = roundToInt16(cgu * 8192) * 0x0001000100010001ULL;
825
c->yOffset = roundToInt16(oy * 8) * 0x0001000100010001ULL;
826
827
c->yuv2rgb_y_coeff = (int16_t)roundToInt16(cy << 13);
828
c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9);
829
c->yuv2rgb_v2r_coeff = (int16_t)roundToInt16(crv << 13);
830
c->yuv2rgb_v2g_coeff = (int16_t)roundToInt16(cgv << 13);
831
c->yuv2rgb_u2g_coeff = (int16_t)roundToInt16(cgu << 13);
832
c->yuv2rgb_u2b_coeff = (int16_t)roundToInt16(cbu << 13);
833
834
//scale coefficients by cy
835
crv = ((crv << 16) + 0x8000) / FFMAX(cy, 1);
836
cbu = ((cbu << 16) + 0x8000) / FFMAX(cy, 1);
837
cgu = ((cgu << 16) + 0x8000) / FFMAX(cy, 1);
838
cgv = ((cgv << 16) + 0x8000) / FFMAX(cy, 1);
839
840
av_freep(&c->yuvTable);
841
842
#define ALLOC_YUV_TABLE(x) \
843
c->yuvTable = av_malloc(x); \
844
if (!c->yuvTable) \
845
return AVERROR(ENOMEM);
846
switch (bpp) {
847
case 1:
848
ALLOC_YUV_TABLE(table_plane_size);
849
y_table = c->yuvTable;
850
yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
851
for (i = 0; i < table_plane_size - 110; i++) {
852
y_table[i + 110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7;
853
yb += cy;
854
}
855
fill_table(c->table_gU, 1, cgu, y_table + yoffs);
856
fill_gv_table(c->table_gV, 1, cgv);
857
break;
858
case 4:
859
case 4 | 128:
860
rbase = isRgb ? 3 : 0;
861
gbase = 1;
862
bbase = isRgb ? 0 : 3;
863
ALLOC_YUV_TABLE(table_plane_size * 3);
864
y_table = c->yuvTable;
865
yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
866
for (i = 0; i < table_plane_size - 110; i++) {
867
int yval = av_clip_uint8((yb + 0x8000) >> 16);
868
y_table[i + 110] = (yval >> 7) << rbase;
869
y_table[i + 37 + table_plane_size] = ((yval + 43) / 85) << gbase;
870
y_table[i + 110 + 2*table_plane_size] = (yval >> 7) << bbase;
871
yb += cy;
872
}
873
fill_table(c->table_rV, 1, crv, y_table + yoffs);
874
fill_table(c->table_gU, 1, cgu, y_table + yoffs + table_plane_size);
875
fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2*table_plane_size);
876
fill_gv_table(c->table_gV, 1, cgv);
877
break;
878
case 8:
879
rbase = isRgb ? 5 : 0;
880
gbase = isRgb ? 2 : 3;
881
bbase = isRgb ? 0 : 6;
882
ALLOC_YUV_TABLE(table_plane_size * 3);
883
y_table = c->yuvTable;
884
yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
885
for (i = 0; i < table_plane_size - 38; i++) {
886
int yval = av_clip_uint8((yb + 0x8000) >> 16);
887
y_table[i + 16] = ((yval + 18) / 36) << rbase;
888
y_table[i + 16 + table_plane_size] = ((yval + 18) / 36) << gbase;
889
y_table[i + 37 + 2*table_plane_size] = ((yval + 43) / 85) << bbase;
890
yb += cy;
891
}
892
fill_table(c->table_rV, 1, crv, y_table + yoffs);
893
fill_table(c->table_gU, 1, cgu, y_table + yoffs + table_plane_size);
894
fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2*table_plane_size);
895
fill_gv_table(c->table_gV, 1, cgv);
896
break;
897
case 12:
898
rbase = isRgb ? 8 : 0;
899
gbase = 4;
900
bbase = isRgb ? 0 : 8;
901
ALLOC_YUV_TABLE(table_plane_size * 3 * 2);
902
y_table16 = c->yuvTable;
903
yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
904
for (i = 0; i < table_plane_size; i++) {
905
uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
906
y_table16[i] = (yval >> 4) << rbase;
907
y_table16[i + table_plane_size] = (yval >> 4) << gbase;
908
y_table16[i + 2*table_plane_size] = (yval >> 4) << bbase;
909
yb += cy;
910
}
911
if (isNotNe)
912
for (i = 0; i < table_plane_size * 3; i++)
913
y_table16[i] = av_bswap16(y_table16[i]);
914
fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
915
fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + table_plane_size);
916
fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2*table_plane_size);
917
fill_gv_table(c->table_gV, 2, cgv);
918
break;
919
case 15:
920
case 16:
921
rbase = isRgb ? bpp - 5 : 0;
922
gbase = 5;
923
bbase = isRgb ? 0 : (bpp - 5);
924
ALLOC_YUV_TABLE(table_plane_size * 3 * 2);
925
y_table16 = c->yuvTable;
926
yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
927
for (i = 0; i < table_plane_size; i++) {
928
uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
929
y_table16[i] = (yval >> 3) << rbase;
930
y_table16[i + table_plane_size] = (yval >> (18 - bpp)) << gbase;
931
y_table16[i + 2*table_plane_size] = (yval >> 3) << bbase;
932
yb += cy;
933
}
934
if (isNotNe)
935
for (i = 0; i < table_plane_size * 3; i++)
936
y_table16[i] = av_bswap16(y_table16[i]);
937
fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
938
fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + table_plane_size);
939
fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2*table_plane_size);
940
fill_gv_table(c->table_gV, 2, cgv);
941
break;
942
case 24:
943
case 48:
944
ALLOC_YUV_TABLE(table_plane_size);
945
y_table = c->yuvTable;
946
yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
947
for (i = 0; i < table_plane_size; i++) {
948
y_table[i] = av_clip_uint8((yb + 0x8000) >> 16);
949
yb += cy;
950
}
951
fill_table(c->table_rV, 1, crv, y_table + yoffs);
952
fill_table(c->table_gU, 1, cgu, y_table + yoffs);
953
fill_table(c->table_bU, 1, cbu, y_table + yoffs);
954
fill_gv_table(c->table_gV, 1, cgv);
955
break;
956
case 32:
957
case 64:
958
base = (c->dstFormat == AV_PIX_FMT_RGB32_1 ||
959
c->dstFormat == AV_PIX_FMT_BGR32_1) ? 8 : 0;
960
rbase = base + (isRgb ? 16 : 0);
961
gbase = base + 8;
962
bbase = base + (isRgb ? 0 : 16);
963
needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
964
if (!needAlpha)
965
abase = (base + 24) & 31;
966
ALLOC_YUV_TABLE(table_plane_size * 3 * 4);
967
y_table32 = c->yuvTable;
968
yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
969
for (i = 0; i < table_plane_size; i++) {
970
unsigned yval = av_clip_uint8((yb + 0x8000) >> 16);
971
y_table32[i] = (yval << rbase) +
972
(needAlpha ? 0 : (255u << abase));
973
y_table32[i + table_plane_size] = yval << gbase;
974
y_table32[i + 2*table_plane_size] = yval << bbase;
975
yb += cy;
976
}
977
fill_table(c->table_rV, 4, crv, y_table32 + yoffs);
978
fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + table_plane_size);
979
fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2*table_plane_size);
980
fill_gv_table(c->table_gV, 4, cgv);
981
break;
982
default:
983
if(!isPlanar(c->dstFormat) || bpp <= 24)
984
av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
985
return -1;
986
}
987
return 0;
988
}
989
990