yuv2rgb.c 34.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * software YUV to RGB converter
 *
 * Copyright (C) 2009 Konstantin Shishkov
 *
 * 1,4,8bpp support and context / deglobalize stuff
 * by Michael Niedermayer (michaelni@gmx.at)
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

30 31
#include "libavutil/cpu.h"
#include "libavutil/bswap.h"
32 33 34 35
#include "config.h"
#include "rgb2rgb.h"
#include "swscale.h"
#include "swscale_internal.h"
36
#include "libavutil/pixdesc.h"
37

38 39 40 41 42 43 44 45 46 47 48
/* Color space conversion coefficients for YCbCr -> RGB mapping.
 *
 * Entries are {crv, cbu, cgu, cgv}
 *
 *   crv = (255 / 224) * 65536 * (1 - cr) / 0.5
 *   cbu = (255 / 224) * 65536 * (1 - cb) / 0.5
 *   cgu = (255 / 224) * 65536 * (cb / cg) * (1 - cb) / 0.5
 *   cgv = (255 / 224) * 65536 * (cr / cg) * (1 - cr) / 0.5
 *
 * where Y = cr * R + cg * G + cb * B and cr + cg + cb = 1.
 */
49
const int32_t ff_yuv2rgb_coeffs[11][4] = {
50 51
    { 117489, 138438, 13975, 34925 }, /* no sequence_display_extension */
    { 117489, 138438, 13975, 34925 }, /* ITU-R Rec. 709 (1990) */
52 53 54 55 56
    { 104597, 132201, 25675, 53279 }, /* unspecified */
    { 104597, 132201, 25675, 53279 }, /* reserved */
    { 104448, 132798, 24759, 53109 }, /* FCC */
    { 104597, 132201, 25675, 53279 }, /* ITU-R Rec. 624-4 System B, G */
    { 104597, 132201, 25675, 53279 }, /* SMPTE 170M */
57 58 59 60
    { 117579, 136230, 16907, 35559 }, /* SMPTE 240M (1987) */
    {      0                       }, /* YCgCo */
    { 110013, 140363, 12277, 42626 }, /* Bt-2020-NCL */
    { 110013, 140363, 12277, 42626 }, /* Bt-2020-CL */
61 62
};

63
const int *sws_getCoefficients(int colorspace)
64
{
65
    if (colorspace > 10 || colorspace < 0 || colorspace == 8)
66 67 68 69
        colorspace = SWS_CS_DEFAULT;
    return ff_yuv2rgb_coeffs[colorspace];
}

70 71 72
#define LOADCHROMA(i)                               \
    U = pu[i];                                      \
    V = pv[i];                                      \
73 74 75
    r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM];                     \
    g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] + c->table_gV[V+YUVRGB_TABLE_HEADROOM]);  \
    b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM];
76

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
#define PUTRGB(dst, src, i)                         \
    Y              = src[2 * i];                    \
    dst[2 * i]     = r[Y] + g[Y] + b[Y];            \
    Y              = src[2 * i + 1];                \
    dst[2 * i + 1] = r[Y] + g[Y] + b[Y];

#define PUTRGB24(dst, src, i)                       \
    Y              = src[2 * i];                    \
    dst[6 * i + 0] = r[Y];                          \
    dst[6 * i + 1] = g[Y];                          \
    dst[6 * i + 2] = b[Y];                          \
    Y              = src[2 * i + 1];                \
    dst[6 * i + 3] = r[Y];                          \
    dst[6 * i + 4] = g[Y];                          \
    dst[6 * i + 5] = b[Y];

#define PUTBGR24(dst, src, i)                       \
    Y              = src[2 * i];                    \
    dst[6 * i + 0] = b[Y];                          \
    dst[6 * i + 1] = g[Y];                          \
    dst[6 * i + 2] = r[Y];                          \
    Y              = src[2 * i + 1];                \
    dst[6 * i + 3] = b[Y];                          \
    dst[6 * i + 4] = g[Y];                          \
    dst[6 * i + 5] = r[Y];

#define PUTRGBA(dst, ysrc, asrc, i, s)                                  \
    Y              = ysrc[2 * i];                                       \
    dst[2 * i]     = r[Y] + g[Y] + b[Y] + (asrc[2 * i]     << s);       \
    Y              = ysrc[2 * i + 1];                                   \
    dst[2 * i + 1] = r[Y] + g[Y] + b[Y] + (asrc[2 * i + 1] << s);

#define PUTRGB48(dst, src, i)                       \
    Y                = src[ 2 * i];                 \
    dst[12 * i +  0] = dst[12 * i +  1] = r[Y];     \
    dst[12 * i +  2] = dst[12 * i +  3] = g[Y];     \
    dst[12 * i +  4] = dst[12 * i +  5] = b[Y];     \
    Y                = src[ 2 * i + 1];             \
    dst[12 * i +  6] = dst[12 * i +  7] = r[Y];     \
    dst[12 * i +  8] = dst[12 * i +  9] = g[Y];     \
    dst[12 * i + 10] = dst[12 * i + 11] = b[Y];

#define PUTBGR48(dst, src, i)                       \
    Y                = src[2 * i];                  \
    dst[12 * i +  0] = dst[12 * i +  1] = b[Y];     \
    dst[12 * i +  2] = dst[12 * i +  3] = g[Y];     \
    dst[12 * i +  4] = dst[12 * i +  5] = r[Y];     \
    Y                = src[2  * i +  1];            \
    dst[12 * i +  6] = dst[12 * i +  7] = b[Y];     \
    dst[12 * i +  8] = dst[12 * i +  9] = g[Y];     \
    dst[12 * i + 10] = dst[12 * i + 11] = r[Y];

#define YUV2RGBFUNC(func_name, dst_type, alpha)                             \
    static int func_name(SwsContext *c, const uint8_t *src[],               \
                         int srcStride[], int srcSliceY, int srcSliceH,     \
                         uint8_t *dst[], int dstStride[])                   \
    {                                                                       \
        int y;                                                              \
                                                                            \
136
        if (!alpha && c->srcFormat == AV_PIX_FMT_YUV422P) {                    \
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
            srcStride[1] *= 2;                                              \
            srcStride[2] *= 2;                                              \
        }                                                                   \
        for (y = 0; y < srcSliceH; y += 2) {                                \
            dst_type *dst_1 =                                               \
                (dst_type *)(dst[0] + (y + srcSliceY)     * dstStride[0]);  \
            dst_type *dst_2 =                                               \
                (dst_type *)(dst[0] + (y + srcSliceY + 1) * dstStride[0]);  \
            dst_type av_unused *r, *g, *b;                                  \
            const uint8_t *py_1 = src[0] +  y       * srcStride[0];         \
            const uint8_t *py_2 = py_1   +            srcStride[0];         \
            const uint8_t *pu   = src[1] + (y >> 1) * srcStride[1];         \
            const uint8_t *pv   = src[2] + (y >> 1) * srcStride[2];         \
            const uint8_t av_unused *pa_1, *pa_2;                           \
            unsigned int h_size = c->dstW >> 3;                             \
            if (alpha) {                                                    \
                pa_1 = src[3] + y * srcStride[3];                           \
                pa_2 = pa_1   +     srcStride[3];                           \
            }                                                               \
            while (h_size--) {                                              \
                int av_unused U, V, Y;                                      \

159 160 161 162 163 164 165
#define ENDYUV2RGBLINE(dst_delta, ss)               \
    pu    += 4 >> ss;                               \
    pv    += 4 >> ss;                               \
    py_1  += 8 >> ss;                               \
    py_2  += 8 >> ss;                               \
    dst_1 += dst_delta >> ss;                       \
    dst_2 += dst_delta >> ss;                       \
166
    }                                               \
167
    if (c->dstW & (4 >> ss)) {                      \
168 169 170 171 172 173 174
        int av_unused Y, U, V;                      \

#define ENDYUV2RGBFUNC()                            \
            }                                       \
        }                                           \
        return srcSliceH;                           \
    }
175

176
#define CLOSEYUV2RGBFUNC(dst_delta)                 \
177
    ENDYUV2RGBLINE(dst_delta, 0)                    \
178 179
    ENDYUV2RGBFUNC()

180 181
YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
    LOADCHROMA(0);
182 183
    PUTRGB48(dst_1, py_1, 0);
    PUTRGB48(dst_2, py_2, 0);
184 185

    LOADCHROMA(1);
186 187
    PUTRGB48(dst_2, py_2, 1);
    PUTRGB48(dst_1, py_1, 1);
188 189

    LOADCHROMA(2);
190 191
    PUTRGB48(dst_1, py_1, 2);
    PUTRGB48(dst_2, py_2, 2);
192 193

    LOADCHROMA(3);
194 195
    PUTRGB48(dst_2, py_2, 3);
    PUTRGB48(dst_1, py_1, 3);
196
ENDYUV2RGBLINE(48, 0)
197
    LOADCHROMA(0);
198 199
    PUTRGB48(dst_1, py_1, 0);
    PUTRGB48(dst_2, py_2, 0);
200 201

    LOADCHROMA(1);
202 203
    PUTRGB48(dst_2, py_2, 1);
    PUTRGB48(dst_1, py_1, 1);
204 205 206 207
ENDYUV2RGBLINE(48, 1)
    LOADCHROMA(0);
    PUTRGB48(dst_1, py_1, 0);
    PUTRGB48(dst_2, py_2, 0);
208 209
ENDYUV2RGBFUNC()

210 211
YUV2RGBFUNC(yuv2rgb_c_bgr48, uint8_t, 0)
    LOADCHROMA(0);
212 213
    PUTBGR48(dst_1, py_1, 0);
    PUTBGR48(dst_2, py_2, 0);
214 215

    LOADCHROMA(1);
216 217
    PUTBGR48(dst_2, py_2, 1);
    PUTBGR48(dst_1, py_1, 1);
218 219

    LOADCHROMA(2);
220 221
    PUTBGR48(dst_1, py_1, 2);
    PUTBGR48(dst_2, py_2, 2);
222 223

    LOADCHROMA(3);
224 225
    PUTBGR48(dst_2, py_2, 3);
    PUTBGR48(dst_1, py_1, 3);
226
ENDYUV2RGBLINE(48, 0)
227
    LOADCHROMA(0);
228 229
    PUTBGR48(dst_1, py_1, 0);
    PUTBGR48(dst_2, py_2, 0);
230 231

    LOADCHROMA(1);
232 233
    PUTBGR48(dst_2, py_2, 1);
    PUTBGR48(dst_1, py_1, 1);
234 235 236 237
ENDYUV2RGBLINE(48, 1)
    LOADCHROMA(0);
    PUTBGR48(dst_1, py_1, 0);
    PUTBGR48(dst_2, py_2, 0);
238 239
ENDYUV2RGBFUNC()

240
YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
241
    LOADCHROMA(0);
242 243
    PUTRGB(dst_1, py_1, 0);
    PUTRGB(dst_2, py_2, 0);
244 245

    LOADCHROMA(1);
246 247
    PUTRGB(dst_2, py_2, 1);
    PUTRGB(dst_1, py_1, 1);
248 249

    LOADCHROMA(2);
250 251
    PUTRGB(dst_1, py_1, 2);
    PUTRGB(dst_2, py_2, 2);
252 253

    LOADCHROMA(3);
254 255
    PUTRGB(dst_2, py_2, 3);
    PUTRGB(dst_1, py_1, 3);
256
ENDYUV2RGBLINE(8, 0)
257
    LOADCHROMA(0);
258 259
    PUTRGB(dst_1, py_1, 0);
    PUTRGB(dst_2, py_2, 0);
260 261

    LOADCHROMA(1);
262 263
    PUTRGB(dst_2, py_2, 1);
    PUTRGB(dst_1, py_1, 1);
264 265 266 267
ENDYUV2RGBLINE(8, 1)
    LOADCHROMA(0);
    PUTRGB(dst_1, py_1, 0);
    PUTRGB(dst_2, py_2, 0);
268 269
ENDYUV2RGBFUNC()

270 271
YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
    LOADCHROMA(0);
272 273
    PUTRGBA(dst_1, py_1, pa_1, 0, 24);
    PUTRGBA(dst_2, py_2, pa_2, 0, 24);
274 275

    LOADCHROMA(1);
276 277
    PUTRGBA(dst_2, py_2, pa_2, 1, 24);
    PUTRGBA(dst_1, py_1, pa_1, 1, 24);
278 279

    LOADCHROMA(2);
280 281
    PUTRGBA(dst_1, py_1, pa_1, 2, 24);
    PUTRGBA(dst_2, py_2, pa_2, 2, 24);
282 283

    LOADCHROMA(3);
284 285
    PUTRGBA(dst_2, py_2, pa_2, 3, 24);
    PUTRGBA(dst_1, py_1, pa_1, 3, 24);
286 287
    pa_1 += 8;
    pa_2 += 8;
288
ENDYUV2RGBLINE(8, 0)
289
    LOADCHROMA(0);
290 291
    PUTRGBA(dst_1, py_1, pa_1, 0, 24);
    PUTRGBA(dst_2, py_2, pa_2, 0, 24);
292 293

    LOADCHROMA(1);
294 295
    PUTRGBA(dst_2, py_2, pa_2, 1, 24);
    PUTRGBA(dst_1, py_1, pa_1, 1, 24);
296 297
    pa_1 += 4;
    pa_2 += 4;
298 299 300 301
ENDYUV2RGBLINE(8, 1)
    LOADCHROMA(0);
    PUTRGBA(dst_1, py_1, pa_1, 0, 24);
    PUTRGBA(dst_2, py_2, pa_2, 0, 24);
302 303 304 305
ENDYUV2RGBFUNC()

YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
    LOADCHROMA(0);
306 307
    PUTRGBA(dst_1, py_1, pa_1, 0, 0);
    PUTRGBA(dst_2, py_2, pa_2, 0, 0);
308 309

    LOADCHROMA(1);
310 311
    PUTRGBA(dst_2, py_2, pa_2, 1, 0);
    PUTRGBA(dst_1, py_1, pa_1, 1, 0);
312 313

    LOADCHROMA(2);
314 315
    PUTRGBA(dst_1, py_1, pa_1, 2, 0);
    PUTRGBA(dst_2, py_2, pa_2, 2, 0);
316 317

    LOADCHROMA(3);
318 319
    PUTRGBA(dst_2, py_2, pa_2, 3, 0);
    PUTRGBA(dst_1, py_1, pa_1, 3, 0);
320 321
    pa_1 += 8;
    pa_2 += 8;
322
ENDYUV2RGBLINE(8, 0)
323
    LOADCHROMA(0);
324 325
    PUTRGBA(dst_1, py_1, pa_1, 0, 0);
    PUTRGBA(dst_2, py_2, pa_2, 0, 0);
326 327

    LOADCHROMA(1);
328 329
    PUTRGBA(dst_2, py_2, pa_2, 1, 0);
    PUTRGBA(dst_1, py_1, pa_1, 1, 0);
330 331
    pa_1 += 4;
    pa_2 += 4;
332 333 334 335
ENDYUV2RGBLINE(8, 1)
    LOADCHROMA(0);
    PUTRGBA(dst_1, py_1, pa_1, 0, 0);
    PUTRGBA(dst_2, py_2, pa_2, 0, 0);
336 337
ENDYUV2RGBFUNC()

338
YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0)
339
    LOADCHROMA(0);
340 341
    PUTRGB24(dst_1, py_1, 0);
    PUTRGB24(dst_2, py_2, 0);
342 343

    LOADCHROMA(1);
344 345
    PUTRGB24(dst_2, py_2, 1);
    PUTRGB24(dst_1, py_1, 1);
346 347

    LOADCHROMA(2);
348 349
    PUTRGB24(dst_1, py_1, 2);
    PUTRGB24(dst_2, py_2, 2);
350 351

    LOADCHROMA(3);
352 353
    PUTRGB24(dst_2, py_2, 3);
    PUTRGB24(dst_1, py_1, 3);
354
ENDYUV2RGBLINE(24, 0)
355
    LOADCHROMA(0);
356 357
    PUTRGB24(dst_1, py_1, 0);
    PUTRGB24(dst_2, py_2, 0);
358 359

    LOADCHROMA(1);
360 361
    PUTRGB24(dst_2, py_2, 1);
    PUTRGB24(dst_1, py_1, 1);
362 363 364 365
ENDYUV2RGBLINE(24, 1)
    LOADCHROMA(0);
    PUTRGB24(dst_1, py_1, 0);
    PUTRGB24(dst_2, py_2, 0);
366 367 368
ENDYUV2RGBFUNC()

// only trivial mods from yuv2rgb_c_24_rgb
369
YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0)
370
    LOADCHROMA(0);
371 372
    PUTBGR24(dst_1, py_1, 0);
    PUTBGR24(dst_2, py_2, 0);
373 374

    LOADCHROMA(1);
375 376
    PUTBGR24(dst_2, py_2, 1);
    PUTBGR24(dst_1, py_1, 1);
377 378

    LOADCHROMA(2);
379 380
    PUTBGR24(dst_1, py_1, 2);
    PUTBGR24(dst_2, py_2, 2);
381 382

    LOADCHROMA(3);
383 384
    PUTBGR24(dst_2, py_2, 3);
    PUTBGR24(dst_1, py_1, 3);
385
ENDYUV2RGBLINE(24, 0)
386
    LOADCHROMA(0);
387 388
    PUTBGR24(dst_1, py_1, 0);
    PUTBGR24(dst_2, py_2, 0);
389 390

    LOADCHROMA(1);
391 392
    PUTBGR24(dst_2, py_2, 1);
    PUTBGR24(dst_1, py_1, 1);
393 394 395 396
ENDYUV2RGBLINE(24, 1)
    LOADCHROMA(0);
    PUTBGR24(dst_1, py_1, 0);
    PUTBGR24(dst_2, py_2, 0);
397 398
ENDYUV2RGBFUNC()

399
YUV2RGBFUNC(yuv2rgb_c_16_ordered_dither, uint16_t, 0)
400 401 402
    const uint8_t *d16 = ff_dither_2x2_8[y & 1];
    const uint8_t *e16 = ff_dither_2x2_4[y & 1];
    const uint8_t *f16 = ff_dither_2x2_8[(y & 1)^1];
403 404 405 406 407 408 409 410 411 412

#define PUTRGB16(dst, src, i, o)                    \
    Y              = src[2 * i];                    \
    dst[2 * i]     = r[Y + d16[0 + o]] +            \
                     g[Y + e16[0 + o]] +            \
                     b[Y + f16[0 + o]];             \
    Y              = src[2 * i + 1];                \
    dst[2 * i + 1] = r[Y + d16[1 + o]] +            \
                     g[Y + e16[1 + o]] +            \
                     b[Y + f16[1 + o]];
413
    LOADCHROMA(0);
414 415
    PUTRGB16(dst_1, py_1, 0, 0);
    PUTRGB16(dst_2, py_2, 0, 0 + 8);
416 417

    LOADCHROMA(1);
418 419
    PUTRGB16(dst_2, py_2, 1, 2 + 8);
    PUTRGB16(dst_1, py_1, 1, 2);
420 421

    LOADCHROMA(2);
422 423
    PUTRGB16(dst_1, py_1, 2, 4);
    PUTRGB16(dst_2, py_2, 2, 4 + 8);
424 425

    LOADCHROMA(3);
426 427 428 429 430
    PUTRGB16(dst_2, py_2, 3, 6 + 8);
    PUTRGB16(dst_1, py_1, 3, 6);
CLOSEYUV2RGBFUNC(8)

YUV2RGBFUNC(yuv2rgb_c_15_ordered_dither, uint16_t, 0)
431 432
    const uint8_t *d16 = ff_dither_2x2_8[y & 1];
    const uint8_t *e16 = ff_dither_2x2_8[(y & 1)^1];
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457

#define PUTRGB15(dst, src, i, o)                    \
    Y              = src[2 * i];                    \
    dst[2 * i]     = r[Y + d16[0 + o]] +            \
                     g[Y + d16[1 + o]] +            \
                     b[Y + e16[0 + o]];             \
    Y              = src[2 * i + 1];                \
    dst[2 * i + 1] = r[Y + d16[1 + o]] +            \
                     g[Y + d16[0 + o]] +            \
                     b[Y + e16[1 + o]];
    LOADCHROMA(0);
    PUTRGB15(dst_1, py_1, 0, 0);
    PUTRGB15(dst_2, py_2, 0, 0 + 8);

    LOADCHROMA(1);
    PUTRGB15(dst_2, py_2, 1, 2 + 8);
    PUTRGB15(dst_1, py_1, 1, 2);

    LOADCHROMA(2);
    PUTRGB15(dst_1, py_1, 2, 4);
    PUTRGB15(dst_2, py_2, 2, 4 + 8);

    LOADCHROMA(3);
    PUTRGB15(dst_2, py_2, 3, 6 + 8);
    PUTRGB15(dst_1, py_1, 3, 6);
458 459
CLOSEYUV2RGBFUNC(8)

460 461
// r, g, b, dst_1, dst_2
YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
462
    const uint8_t *d16 = ff_dither_4x4_16[y & 3];
463 464 465 466 467 468 469 470 471 472

#define PUTRGB12(dst, src, i, o)                    \
    Y              = src[2 * i];                    \
    dst[2 * i]     = r[Y + d16[0 + o]] +            \
                     g[Y + d16[0 + o]] +            \
                     b[Y + d16[0 + o]];             \
    Y              = src[2 * i + 1];                \
    dst[2 * i + 1] = r[Y + d16[1 + o]] +            \
                     g[Y + d16[1 + o]] +            \
                     b[Y + d16[1 + o]];
473 474

    LOADCHROMA(0);
475 476
    PUTRGB12(dst_1, py_1, 0, 0);
    PUTRGB12(dst_2, py_2, 0, 0 + 8);
477 478

    LOADCHROMA(1);
479 480
    PUTRGB12(dst_2, py_2, 1, 2 + 8);
    PUTRGB12(dst_1, py_1, 1, 2);
481 482

    LOADCHROMA(2);
483 484
    PUTRGB12(dst_1, py_1, 2, 4);
    PUTRGB12(dst_2, py_2, 2, 4 + 8);
485 486

    LOADCHROMA(3);
487 488
    PUTRGB12(dst_2, py_2, 3, 6 + 8);
    PUTRGB12(dst_1, py_1, 3, 6);
489 490
CLOSEYUV2RGBFUNC(8)

491
// r, g, b, dst_1, dst_2
492
YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
493 494
    const uint8_t *d32 = ff_dither_8x8_32[y & 7];
    const uint8_t *d64 = ff_dither_8x8_73[y & 7];
495 496 497 498 499 500 501 502 503 504

#define PUTRGB8(dst, src, i, o)                     \
    Y              = src[2 * i];                    \
    dst[2 * i]     = r[Y + d32[0 + o]] +            \
                     g[Y + d32[0 + o]] +            \
                     b[Y + d64[0 + o]];             \
    Y              = src[2 * i + 1];                \
    dst[2 * i + 1] = r[Y + d32[1 + o]] +            \
                     g[Y + d32[1 + o]] +            \
                     b[Y + d64[1 + o]];
505 506

    LOADCHROMA(0);
507 508
    PUTRGB8(dst_1, py_1, 0, 0);
    PUTRGB8(dst_2, py_2, 0, 0 + 8);
509 510

    LOADCHROMA(1);
511 512
    PUTRGB8(dst_2, py_2, 1, 2 + 8);
    PUTRGB8(dst_1, py_1, 1, 2);
513 514

    LOADCHROMA(2);
515 516
    PUTRGB8(dst_1, py_1, 2, 4);
    PUTRGB8(dst_2, py_2, 2, 4 + 8);
517 518

    LOADCHROMA(3);
519 520
    PUTRGB8(dst_2, py_2, 3, 6 + 8);
    PUTRGB8(dst_1, py_1, 3, 6);
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541

ENDYUV2RGBLINE(8, 0)
    const uint8_t *d32 = ff_dither_8x8_32[y & 7];
    const uint8_t *d64 = ff_dither_8x8_73[y & 7];
    LOADCHROMA(0);
    PUTRGB8(dst_1, py_1, 0, 0);
    PUTRGB8(dst_2, py_2, 0, 0 + 8);

    LOADCHROMA(1);
    PUTRGB8(dst_2, py_2, 1, 2 + 8);
    PUTRGB8(dst_1, py_1, 1, 2);

ENDYUV2RGBLINE(8, 1)
    const uint8_t *d32 = ff_dither_8x8_32[y & 7];
    const uint8_t *d64 = ff_dither_8x8_73[y & 7];
    LOADCHROMA(0);
    PUTRGB8(dst_1, py_1, 0, 0);
    PUTRGB8(dst_2, py_2, 0, 0 + 8);

ENDYUV2RGBFUNC()

542

543
YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
544 545
    const uint8_t * d64 = ff_dither_8x8_73[y & 7];
    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
546 547
    int acc;

548 549 550 551 552 553 554 555 556 557
#define PUTRGB4D(dst, src, i, o)                    \
    Y      = src[2 * i];                            \
    acc    = r[Y + d128[0 + o]] +                   \
             g[Y +  d64[0 + o]] +                   \
             b[Y + d128[0 + o]];                    \
    Y      = src[2 * i + 1];                        \
    acc   |= (r[Y + d128[1 + o]] +                  \
              g[Y +  d64[1 + o]] +                  \
              b[Y + d128[1 + o]]) << 4;             \
    dst[i] = acc;
558 559

    LOADCHROMA(0);
560 561
    PUTRGB4D(dst_1, py_1, 0, 0);
    PUTRGB4D(dst_2, py_2, 0, 0 + 8);
562 563

    LOADCHROMA(1);
564 565
    PUTRGB4D(dst_2, py_2, 1, 2 + 8);
    PUTRGB4D(dst_1, py_1, 1, 2);
566 567

    LOADCHROMA(2);
568 569
    PUTRGB4D(dst_1, py_1, 2, 4);
    PUTRGB4D(dst_2, py_2, 2, 4 + 8);
570 571

    LOADCHROMA(3);
572 573
    PUTRGB4D(dst_2, py_2, 3, 6 + 8);
    PUTRGB4D(dst_1, py_1, 3, 6);
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594

ENDYUV2RGBLINE(4, 0)
    const uint8_t * d64 = ff_dither_8x8_73[y & 7];
    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
    int acc;
    LOADCHROMA(0);
    PUTRGB4D(dst_1, py_1, 0, 0);
    PUTRGB4D(dst_2, py_2, 0, 0 + 8);

    LOADCHROMA(1);
    PUTRGB4D(dst_2, py_2, 1, 2 + 8);
    PUTRGB4D(dst_1, py_1, 1, 2);

ENDYUV2RGBLINE(4, 1)
    const uint8_t * d64 = ff_dither_8x8_73[y & 7];
    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
    int acc;
    LOADCHROMA(0);
    PUTRGB4D(dst_1, py_1, 0, 0);
    PUTRGB4D(dst_2, py_2, 0, 0 + 8);
ENDYUV2RGBFUNC()
595

596
YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
597 598
    const uint8_t *d64  = ff_dither_8x8_73[y & 7];
    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
599 600 601 602 603 604 605 606 607 608

#define PUTRGB4DB(dst, src, i, o)                   \
    Y              = src[2 * i];                    \
    dst[2 * i]     = r[Y + d128[0 + o]] +           \
                     g[Y +  d64[0 + o]] +           \
                     b[Y + d128[0 + o]];            \
    Y              = src[2 * i + 1];                \
    dst[2 * i + 1] = r[Y + d128[1 + o]] +           \
                     g[Y +  d64[1 + o]] +           \
                     b[Y + d128[1 + o]];
609 610

    LOADCHROMA(0);
611 612
    PUTRGB4DB(dst_1, py_1, 0, 0);
    PUTRGB4DB(dst_2, py_2, 0, 0 + 8);
613 614

    LOADCHROMA(1);
615 616
    PUTRGB4DB(dst_2, py_2, 1, 2 + 8);
    PUTRGB4DB(dst_1, py_1, 1, 2);
617 618

    LOADCHROMA(2);
619 620
    PUTRGB4DB(dst_1, py_1, 2, 4);
    PUTRGB4DB(dst_2, py_2, 2, 4 + 8);
621 622

    LOADCHROMA(3);
623 624
    PUTRGB4DB(dst_2, py_2, 3, 6 + 8);
    PUTRGB4DB(dst_1, py_1, 3, 6);
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
ENDYUV2RGBLINE(8, 0)
    const uint8_t *d64  = ff_dither_8x8_73[y & 7];
    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
    LOADCHROMA(0);
    PUTRGB4DB(dst_1, py_1, 0, 0);
    PUTRGB4DB(dst_2, py_2, 0, 0 + 8);

    LOADCHROMA(1);
    PUTRGB4DB(dst_2, py_2, 1, 2 + 8);
    PUTRGB4DB(dst_1, py_1, 1, 2);
ENDYUV2RGBLINE(8, 1)
    const uint8_t *d64  = ff_dither_8x8_73[y & 7];
    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
    LOADCHROMA(0);
    PUTRGB4DB(dst_1, py_1, 0, 0);
    PUTRGB4DB(dst_2, py_2, 0, 0 + 8);
ENDYUV2RGBFUNC()
642

643
YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
644
    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
645
    char out_1 = 0, out_2 = 0;
646
    g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
647

648 649 650 651 652
#define PUTRGB1(out, src, i, o)                     \
    Y    = src[2 * i];                              \
    out += out + g[Y + d128[0 + o]];                \
    Y    = src[2 * i + 1];                          \
    out += out + g[Y + d128[1 + o]];
653

654 655
    PUTRGB1(out_1, py_1, 0, 0);
    PUTRGB1(out_2, py_2, 0, 0 + 8);
656

657 658
    PUTRGB1(out_2, py_2, 1, 2 + 8);
    PUTRGB1(out_1, py_1, 1, 2);
659

660 661
    PUTRGB1(out_1, py_1, 2, 4);
    PUTRGB1(out_2, py_2, 2, 4 + 8);
662

663 664
    PUTRGB1(out_2, py_2, 3, 6 + 8);
    PUTRGB1(out_1, py_1, 3, 6);
665

666 667
    dst_1[0] = out_1;
    dst_2[0] = out_2;
668 669
CLOSEYUV2RGBFUNC(1)

670
SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
671 672 673
{
    SwsFunc t = NULL;

674
    if (ARCH_PPC)
675
        t = ff_yuv2rgb_init_ppc(c);
676 677
    if (ARCH_X86)
        t = ff_yuv2rgb_init_x86(c);
678 679 680 681

    if (t)
        return t;

682 683
    av_log(c, AV_LOG_WARNING,
           "No accelerated colorspace conversion found from %s to %s.\n",
684
           av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
685 686

    switch (c->dstFormat) {
687 688
    case AV_PIX_FMT_BGR48BE:
    case AV_PIX_FMT_BGR48LE:
689
        return yuv2rgb_c_bgr48;
690 691
    case AV_PIX_FMT_RGB48BE:
    case AV_PIX_FMT_RGB48LE:
692
        return yuv2rgb_c_48;
693 694
    case AV_PIX_FMT_ARGB:
    case AV_PIX_FMT_ABGR:
695
        if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat))
696
            return yuva2argb_c;
697 698
    case AV_PIX_FMT_RGBA:
    case AV_PIX_FMT_BGRA:
699
        return (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) ? yuva2rgba_c : yuv2rgb_c_32;
700
    case AV_PIX_FMT_RGB24:
701
        return yuv2rgb_c_24_rgb;
702
    case AV_PIX_FMT_BGR24:
703
        return yuv2rgb_c_24_bgr;
704 705
    case AV_PIX_FMT_RGB565:
    case AV_PIX_FMT_BGR565:
706
        return yuv2rgb_c_16_ordered_dither;
707 708
    case AV_PIX_FMT_RGB555:
    case AV_PIX_FMT_BGR555:
709
        return yuv2rgb_c_15_ordered_dither;
710 711
    case AV_PIX_FMT_RGB444:
    case AV_PIX_FMT_BGR444:
712
        return yuv2rgb_c_12_ordered_dither;
713 714
    case AV_PIX_FMT_RGB8:
    case AV_PIX_FMT_BGR8:
715
        return yuv2rgb_c_8_ordered_dither;
716 717
    case AV_PIX_FMT_RGB4:
    case AV_PIX_FMT_BGR4:
718
        return yuv2rgb_c_4_ordered_dither;
719 720
    case AV_PIX_FMT_RGB4_BYTE:
    case AV_PIX_FMT_BGR4_BYTE:
721
        return yuv2rgb_c_4b_ordered_dither;
722
    case AV_PIX_FMT_MONOBLACK:
723
        return yuv2rgb_c_1_ordered_dither;
724 725 726 727
    }
    return NULL;
}

728
static void fill_table(uint8_t* table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize,
729
                       const int64_t inc, void *y_tab)
730 731
{
    int i;
732
    uint8_t *y_table = y_tab;
733 734 735

    y_table -= elemsize * (inc >> 9);

736
    for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
737
        int64_t cb = av_clip_uint8(i-YUVRGB_TABLE_HEADROOM)*inc;
738 739 740 741
        table[i] = y_table + elemsize * (cb >> 16);
    }
}

742
static void fill_gv_table(int table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize, const int64_t inc)
743 744
{
    int i;
745
    int off    = -(inc >> 9);
746

747
    for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
748
        int64_t cb = av_clip_uint8(i-YUVRGB_TABLE_HEADROOM)*inc;
749 750 751 752
        table[i] = elemsize * (off + (cb >> 16));
    }
}

753 754
static uint16_t roundToInt16(int64_t f)
{
755 756 757 758 759 760 761 762
    int r = (f + (1 << 15)) >> 16;

    if (r < -0x7FFF)
        return 0x8000;
    else if (r > 0x7FFF)
        return 0x7FFF;
    else
        return r;
763 764
}

765 766 767
av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4],
                                     int fullRange, int brightness,
                                     int contrast, int saturation)
768
{
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
    const int isRgb = c->dstFormat == AV_PIX_FMT_RGB32     ||
                      c->dstFormat == AV_PIX_FMT_RGB32_1   ||
                      c->dstFormat == AV_PIX_FMT_BGR24     ||
                      c->dstFormat == AV_PIX_FMT_RGB565BE  ||
                      c->dstFormat == AV_PIX_FMT_RGB565LE  ||
                      c->dstFormat == AV_PIX_FMT_RGB555BE  ||
                      c->dstFormat == AV_PIX_FMT_RGB555LE  ||
                      c->dstFormat == AV_PIX_FMT_RGB444BE  ||
                      c->dstFormat == AV_PIX_FMT_RGB444LE  ||
                      c->dstFormat == AV_PIX_FMT_RGB8      ||
                      c->dstFormat == AV_PIX_FMT_RGB4      ||
                      c->dstFormat == AV_PIX_FMT_RGB4_BYTE ||
                      c->dstFormat == AV_PIX_FMT_MONOBLACK;
    const int isNotNe = c->dstFormat == AV_PIX_FMT_NE(RGB565LE, RGB565BE) ||
                        c->dstFormat == AV_PIX_FMT_NE(RGB555LE, RGB555BE) ||
                        c->dstFormat == AV_PIX_FMT_NE(RGB444LE, RGB444BE) ||
                        c->dstFormat == AV_PIX_FMT_NE(BGR565LE, BGR565BE) ||
                        c->dstFormat == AV_PIX_FMT_NE(BGR555LE, BGR555BE) ||
                        c->dstFormat == AV_PIX_FMT_NE(BGR444LE, BGR444BE);
788
    const int bpp = c->dstFormatBpp;
789 790 791
    uint8_t *y_table;
    uint16_t *y_table16;
    uint32_t *y_table32;
792
    int i, base, rbase, gbase, bbase, av_uninit(abase), needAlpha;
793 794
    const int yoffs = (fullRange ? 384 : 326) + YUVRGB_TABLE_LUMA_HEADROOM;
    const int table_plane_size = 1024 + 2*YUVRGB_TABLE_LUMA_HEADROOM;
795 796 797 798 799

    int64_t crv =  inv_table[0];
    int64_t cbu =  inv_table[1];
    int64_t cgu = -inv_table[2];
    int64_t cgv = -inv_table[3];
800
    int64_t cy  = 1 << 16;
801
    int64_t oy  = 0;
802
    int64_t yb  = 0;
803 804

    if (!fullRange) {
805 806
        cy = (cy * 255) / 219;
        oy = 16 << 16;
807
    } else {
808 809 810 811
        crv = (crv * 224) / 255;
        cbu = (cbu * 224) / 255;
        cgu = (cgu * 224) / 255;
        cgv = (cgv * 224) / 255;
812 813
    }

814 815 816 817 818 819 820 821 822
    cy   = (cy  * contrast)              >> 16;
    crv  = (crv * contrast * saturation) >> 32;
    cbu  = (cbu * contrast * saturation) >> 32;
    cgu  = (cgu * contrast * saturation) >> 32;
    cgv  = (cgv * contrast * saturation) >> 32;
    oy  -= 256 * brightness;

    c->uOffset = 0x0400040004000400LL;
    c->vOffset = 0x0400040004000400LL;
823 824 825 826 827 828
    c->yCoeff  = roundToInt16(cy  * (1 << 13)) * 0x0001000100010001ULL;
    c->vrCoeff = roundToInt16(crv * (1 << 13)) * 0x0001000100010001ULL;
    c->ubCoeff = roundToInt16(cbu * (1 << 13)) * 0x0001000100010001ULL;
    c->vgCoeff = roundToInt16(cgv * (1 << 13)) * 0x0001000100010001ULL;
    c->ugCoeff = roundToInt16(cgu * (1 << 13)) * 0x0001000100010001ULL;
    c->yOffset = roundToInt16(oy  * (1 <<  3)) * 0x0001000100010001ULL;
829

830 831 832 833 834 835
    c->yuv2rgb_y_coeff   = (int16_t)roundToInt16(cy  * (1 << 13));
    c->yuv2rgb_y_offset  = (int16_t)roundToInt16(oy  * (1 <<  9));
    c->yuv2rgb_v2r_coeff = (int16_t)roundToInt16(crv * (1 << 13));
    c->yuv2rgb_v2g_coeff = (int16_t)roundToInt16(cgv * (1 << 13));
    c->yuv2rgb_u2g_coeff = (int16_t)roundToInt16(cgu * (1 << 13));
    c->yuv2rgb_u2b_coeff = (int16_t)roundToInt16(cbu * (1 << 13));
836

837
    //scale coefficients by cy
838 839 840 841
    crv = ((crv * (1 << 16)) + 0x8000) / FFMAX(cy, 1);
    cbu = ((cbu * (1 << 16)) + 0x8000) / FFMAX(cy, 1);
    cgu = ((cgu * (1 << 16)) + 0x8000) / FFMAX(cy, 1);
    cgv = ((cgv * (1 << 16)) + 0x8000) / FFMAX(cy, 1);
842

843
    av_freep(&c->yuvTable);
844

845 846 847 848
#define ALLOC_YUV_TABLE(x)          \
        c->yuvTable = av_malloc(x); \
        if (!c->yuvTable)           \
            return AVERROR(ENOMEM);
849 850
    switch (bpp) {
    case 1:
851
        ALLOC_YUV_TABLE(table_plane_size);
852
        y_table     = c->yuvTable;
853 854
        yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
        for (i = 0; i < table_plane_size - 110; i++) {
855 856
            y_table[i + 110]  = av_clip_uint8((yb + 0x8000) >> 16) >> 7;
            yb               += cy;
857 858 859 860 861
        }
        fill_table(c->table_gU, 1, cgu, y_table + yoffs);
        fill_gv_table(c->table_gV, 1, cgv);
        break;
    case 4:
862 863 864 865
    case 4 | 128:
        rbase       = isRgb ? 3 : 0;
        gbase       = 1;
        bbase       = isRgb ? 0 : 3;
866
        ALLOC_YUV_TABLE(table_plane_size * 3);
867
        y_table     = c->yuvTable;
868 869
        yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
        for (i = 0; i < table_plane_size - 110; i++) {
870 871
            int yval                = av_clip_uint8((yb + 0x8000) >> 16);
            y_table[i + 110]        = (yval >> 7)        << rbase;
872 873
            y_table[i +  37 +   table_plane_size] = ((yval + 43) / 85) << gbase;
            y_table[i + 110 + 2*table_plane_size] = (yval >> 7)        << bbase;
874 875 876
            yb += cy;
        }
        fill_table(c->table_rV, 1, crv, y_table + yoffs);
877 878
        fill_table(c->table_gU, 1, cgu, y_table + yoffs +   table_plane_size);
        fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2*table_plane_size);
879 880 881
        fill_gv_table(c->table_gV, 1, cgv);
        break;
    case 8:
882 883 884
        rbase       = isRgb ? 5 : 0;
        gbase       = isRgb ? 2 : 3;
        bbase       = isRgb ? 0 : 6;
885
        ALLOC_YUV_TABLE(table_plane_size * 3);
886
        y_table     = c->yuvTable;
887 888
        yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
        for (i = 0; i < table_plane_size - 38; i++) {
889 890
            int yval               = av_clip_uint8((yb + 0x8000) >> 16);
            y_table[i + 16]        = ((yval + 18) / 36) << rbase;
891 892
            y_table[i + 16 +   table_plane_size] = ((yval + 18) / 36) << gbase;
            y_table[i + 37 + 2*table_plane_size] = ((yval + 43) / 85) << bbase;
893 894 895
            yb += cy;
        }
        fill_table(c->table_rV, 1, crv, y_table + yoffs);
896 897
        fill_table(c->table_gU, 1, cgu, y_table + yoffs +   table_plane_size);
        fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2*table_plane_size);
898 899
        fill_gv_table(c->table_gV, 1, cgv);
        break;
900
    case 12:
901 902 903
        rbase       = isRgb ? 8 : 0;
        gbase       = 4;
        bbase       = isRgb ? 0 : 8;
904
        ALLOC_YUV_TABLE(table_plane_size * 3 * 2);
905
        y_table16   = c->yuvTable;
906 907
        yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
        for (i = 0; i < table_plane_size; i++) {
908 909
            uint8_t yval        = av_clip_uint8((yb + 0x8000) >> 16);
            y_table16[i]        = (yval >> 4) << rbase;
910 911
            y_table16[i +   table_plane_size] = (yval >> 4) << gbase;
            y_table16[i + 2*table_plane_size] = (yval >> 4) << bbase;
912 913
            yb += cy;
        }
914
        if (isNotNe)
915
            for (i = 0; i < table_plane_size * 3; i++)
916
                y_table16[i] = av_bswap16(y_table16[i]);
917
        fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
918 919
        fill_table(c->table_gU, 2, cgu, y_table16 + yoffs +   table_plane_size);
        fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2*table_plane_size);
920 921
        fill_gv_table(c->table_gV, 2, cgv);
        break;
922 923
    case 15:
    case 16:
924 925 926
        rbase       = isRgb ? bpp - 5 : 0;
        gbase       = 5;
        bbase       = isRgb ? 0 : (bpp - 5);
927
        ALLOC_YUV_TABLE(table_plane_size * 3 * 2);
928
        y_table16   = c->yuvTable;
929 930
        yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
        for (i = 0; i < table_plane_size; i++) {
931 932
            uint8_t yval        = av_clip_uint8((yb + 0x8000) >> 16);
            y_table16[i]        = (yval >> 3)          << rbase;
933 934
            y_table16[i +   table_plane_size] = (yval >> (18 - bpp)) << gbase;
            y_table16[i + 2*table_plane_size] = (yval >> 3)          << bbase;
935 936
            yb += cy;
        }
937
        if (isNotNe)
938
            for (i = 0; i < table_plane_size * 3; i++)
939
                y_table16[i] = av_bswap16(y_table16[i]);
940
        fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
941 942
        fill_table(c->table_gU, 2, cgu, y_table16 + yoffs +   table_plane_size);
        fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2*table_plane_size);
943 944 945
        fill_gv_table(c->table_gV, 2, cgv);
        break;
    case 24:
946
    case 48:
947
        ALLOC_YUV_TABLE(table_plane_size);
948
        y_table     = c->yuvTable;
949 950
        yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
        for (i = 0; i < table_plane_size; i++) {
951 952
            y_table[i]  = av_clip_uint8((yb + 0x8000) >> 16);
            yb         += cy;
953 954 955 956 957 958 959
        }
        fill_table(c->table_rV, 1, crv, y_table + yoffs);
        fill_table(c->table_gU, 1, cgu, y_table + yoffs);
        fill_table(c->table_bU, 1, cbu, y_table + yoffs);
        fill_gv_table(c->table_gV, 1, cgv);
        break;
    case 32:
Paul B Mahol's avatar
Paul B Mahol committed
960
    case 64:
961 962
        base      = (c->dstFormat == AV_PIX_FMT_RGB32_1 ||
                     c->dstFormat == AV_PIX_FMT_BGR32_1) ? 8 : 0;
963 964 965
        rbase     = base + (isRgb ? 16 : 0);
        gbase     = base + 8;
        bbase     = base + (isRgb ? 0 : 16);
966 967 968
        needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
        if (!needAlpha)
            abase = (base + 24) & 31;
969
        ALLOC_YUV_TABLE(table_plane_size * 3 * 4);
970
        y_table32   = c->yuvTable;
971 972
        yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy;
        for (i = 0; i < table_plane_size; i++) {
973 974 975
            unsigned yval       = av_clip_uint8((yb + 0x8000) >> 16);
            y_table32[i]        = (yval << rbase) +
                                  (needAlpha ? 0 : (255u << abase));
976 977
            y_table32[i +   table_plane_size] =  yval << gbase;
            y_table32[i + 2*table_plane_size] =  yval << bbase;
978 979 980
            yb += cy;
        }
        fill_table(c->table_rV, 4, crv, y_table32 + yoffs);
981 982
        fill_table(c->table_gU, 4, cgu, y_table32 + yoffs +   table_plane_size);
        fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2*table_plane_size);
983 984 985
        fill_gv_table(c->table_gV, 4, cgv);
        break;
    default:
986
        if(!isPlanar(c->dstFormat) || bpp <= 24)
987
            av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
988 989 990 991
        return -1;
    }
    return 0;
}