yuv2rgb.c 21.5 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 30 31 32 33 34
/*
 * 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>
#include <assert.h>

#include "config.h"
#include "rgb2rgb.h"
#include "swscale.h"
#include "swscale_internal.h"
35
#include "libavutil/x86_cpu.h"
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

extern const uint8_t dither_8x8_32[8][8];
extern const uint8_t dither_8x8_73[8][8];
extern const uint8_t dither_8x8_220[8][8];

const int32_t ff_yuv2rgb_coeffs[8][4] = {
    {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
    {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
    {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 */
    {117579, 136230, 16907, 35559}  /* SMPTE 240M (1987) */
};

#define LOADCHROMA(i)                               \
    U = pu[i];                                      \
    V = pv[i];                                      \
    r = (void *)c->table_rV[V];                     \
    g = (void *)(c->table_gU[U] + c->table_gV[V]);  \
    b = (void *)c->table_bU[U];

59 60
#define PUTRGB(dst,src,i)            \
    Y = src[2*i];                    \
61
    dst[2*i  ] = r[Y] + g[Y] + b[Y]; \
62
    Y = src[2*i+1];                  \
63 64 65 66 67 68 69 70 71 72 73 74 75 76
    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];

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

83 84 85 86 87 88 89 90 91 92
#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];

93
#define YUV2RGBFUNC(func_name, dst_type, alpha) \
94
static int func_name(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, \
Ramiro Polla's avatar
Ramiro Polla committed
95 96
                     int srcSliceH, uint8_t* dst[], int dstStride[]) \
{\
97 98
    int y;\
\
99
    if (!alpha && c->srcFormat == PIX_FMT_YUV422P) {\
100 101 102 103 104 105 106 107 108 109 110 111
        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, *b;\
        dst_type *g;\
        uint8_t *py_1 = src[0] + y*srcStride[0];\
        uint8_t *py_2 = py_1 + srcStride[0];\
        uint8_t *pu = src[1] + (y>>1)*srcStride[1];\
        uint8_t *pv = src[2] + (y>>1)*srcStride[2];\
112
        uint8_t av_unused *pa_1, *pa_2;\
113
        unsigned int h_size = c->dstW>>3;\
Ramiro Polla's avatar
Ramiro Polla committed
114
        if (alpha) {\
115 116 117
            pa_1 = src[3] + y*srcStride[3];\
            pa_2 = pa_1 + srcStride[3];\
        }\
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
        while (h_size--) {\
            int av_unused U, V;\
            int Y;\

#define ENDYUV2RGBLINE(dst_delta)\
            pu += 4;\
            pv += 4;\
            py_1 += 8;\
            py_2 += 8;\
            dst_1 += dst_delta;\
            dst_2 += dst_delta;\
        }\
        if (c->dstW & 4) {\
            int av_unused Y, U, V;\

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

#define CLOSEYUV2RGBFUNC(dst_delta)\
    ENDYUV2RGBLINE(dst_delta)\
    ENDYUV2RGBFUNC()

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
    LOADCHROMA(0);
    PUTRGB48(dst_1,py_1,0);
    PUTRGB48(dst_2,py_2,0);

    LOADCHROMA(1);
    PUTRGB48(dst_2,py_2,1);
    PUTRGB48(dst_1,py_1,1);

    LOADCHROMA(2);
    PUTRGB48(dst_1,py_1,2);
    PUTRGB48(dst_2,py_2,2);

    LOADCHROMA(3);
    PUTRGB48(dst_2,py_2,3);
    PUTRGB48(dst_1,py_1,3);
ENDYUV2RGBLINE(48)
    LOADCHROMA(0);
    PUTRGB48(dst_1,py_1,0);
    PUTRGB48(dst_2,py_2,0);

    LOADCHROMA(1);
    PUTRGB48(dst_2,py_2,1);
    PUTRGB48(dst_1,py_1,1);
ENDYUV2RGBFUNC()

169
YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
170
    LOADCHROMA(0);
171 172
    PUTRGB(dst_1,py_1,0);
    PUTRGB(dst_2,py_2,0);
173 174

    LOADCHROMA(1);
175 176
    PUTRGB(dst_2,py_2,1);
    PUTRGB(dst_1,py_1,1);
177 178

    LOADCHROMA(2);
179 180
    PUTRGB(dst_1,py_1,2);
    PUTRGB(dst_2,py_2,2);
181 182

    LOADCHROMA(3);
183 184
    PUTRGB(dst_2,py_2,3);
    PUTRGB(dst_1,py_1,3);
185 186
ENDYUV2RGBLINE(8)
    LOADCHROMA(0);
187 188
    PUTRGB(dst_1,py_1,0);
    PUTRGB(dst_2,py_2,0);
189 190

    LOADCHROMA(1);
191 192
    PUTRGB(dst_2,py_2,1);
    PUTRGB(dst_1,py_1,1);
193 194
ENDYUV2RGBFUNC()

195 196
YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
    LOADCHROMA(0);
197 198
    PUTRGBA(dst_1,py_1,pa_1,0,24);
    PUTRGBA(dst_2,py_2,pa_2,0,24);
199 200

    LOADCHROMA(1);
201 202
    PUTRGBA(dst_2,py_2,pa_1,1,24);
    PUTRGBA(dst_1,py_1,pa_2,1,24);
203 204

    LOADCHROMA(2);
205 206
    PUTRGBA(dst_1,py_1,pa_1,2,24);
    PUTRGBA(dst_2,py_2,pa_2,2,24);
207 208

    LOADCHROMA(3);
209 210
    PUTRGBA(dst_2,py_2,pa_1,3,24);
    PUTRGBA(dst_1,py_1,pa_2,3,24);
211 212 213 214
    pa_1 += 8;\
    pa_2 += 8;\
ENDYUV2RGBLINE(8)
    LOADCHROMA(0);
215 216
    PUTRGBA(dst_1,py_1,pa_1,0,24);
    PUTRGBA(dst_2,py_2,pa_2,0,24);
217 218

    LOADCHROMA(1);
219 220
    PUTRGBA(dst_2,py_2,pa_1,1,24);
    PUTRGBA(dst_1,py_1,pa_2,1,24);
221 222 223 224
ENDYUV2RGBFUNC()

YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
    LOADCHROMA(0);
225 226
    PUTRGBA(dst_1,py_1,pa_1,0,0);
    PUTRGBA(dst_2,py_2,pa_2,0,0);
227 228

    LOADCHROMA(1);
229 230
    PUTRGBA(dst_2,py_2,pa_2,1,0);
    PUTRGBA(dst_1,py_1,pa_1,1,0);
231 232

    LOADCHROMA(2);
233 234
    PUTRGBA(dst_1,py_1,pa_1,2,0);
    PUTRGBA(dst_2,py_2,pa_2,2,0);
235 236

    LOADCHROMA(3);
237 238
    PUTRGBA(dst_2,py_2,pa_2,3,0);
    PUTRGBA(dst_1,py_1,pa_1,3,0);
239 240 241 242
    pa_1 += 8;\
    pa_2 += 8;\
ENDYUV2RGBLINE(8)
    LOADCHROMA(0);
243 244
    PUTRGBA(dst_1,py_1,pa_1,0,0);
    PUTRGBA(dst_2,py_2,pa_2,0,0);
245 246

    LOADCHROMA(1);
247 248
    PUTRGBA(dst_2,py_2,pa_2,1,0);
    PUTRGBA(dst_1,py_1,pa_1,1,0);
249 250
ENDYUV2RGBFUNC()

251
YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0)
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
    LOADCHROMA(0);
    PUTRGB24(dst_1,py_1,0);
    PUTRGB24(dst_2,py_2,0);

    LOADCHROMA(1);
    PUTRGB24(dst_2,py_2,1);
    PUTRGB24(dst_1,py_1,1);

    LOADCHROMA(2);
    PUTRGB24(dst_1,py_1,2);
    PUTRGB24(dst_2,py_2,2);

    LOADCHROMA(3);
    PUTRGB24(dst_2,py_2,3);
    PUTRGB24(dst_1,py_1,3);
ENDYUV2RGBLINE(24)
    LOADCHROMA(0);
    PUTRGB24(dst_1,py_1,0);
    PUTRGB24(dst_2,py_2,0);

    LOADCHROMA(1);
    PUTRGB24(dst_2,py_2,1);
    PUTRGB24(dst_1,py_1,1);
ENDYUV2RGBFUNC()

// only trivial mods from yuv2rgb_c_24_rgb
278
YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0)
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
    LOADCHROMA(0);
    PUTBGR24(dst_1,py_1,0);
    PUTBGR24(dst_2,py_2,0);

    LOADCHROMA(1);
    PUTBGR24(dst_2,py_2,1);
    PUTBGR24(dst_1,py_1,1);

    LOADCHROMA(2);
    PUTBGR24(dst_1,py_1,2);
    PUTBGR24(dst_2,py_2,2);

    LOADCHROMA(3);
    PUTBGR24(dst_2,py_2,3);
    PUTBGR24(dst_1,py_1,3);
ENDYUV2RGBLINE(24)
    LOADCHROMA(0);
    PUTBGR24(dst_1,py_1,0);
    PUTBGR24(dst_2,py_2,0);

    LOADCHROMA(1);
    PUTBGR24(dst_2,py_2,1);
    PUTBGR24(dst_1,py_1,1);
ENDYUV2RGBFUNC()

// This is exactly the same code as yuv2rgb_c_32 except for the types of
// r, g, b, dst_1, dst_2
306
YUV2RGBFUNC(yuv2rgb_c_16, uint16_t, 0)
307
    LOADCHROMA(0);
308 309
    PUTRGB(dst_1,py_1,0);
    PUTRGB(dst_2,py_2,0);
310 311

    LOADCHROMA(1);
312 313
    PUTRGB(dst_2,py_2,1);
    PUTRGB(dst_1,py_1,1);
314 315

    LOADCHROMA(2);
316 317
    PUTRGB(dst_1,py_1,2);
    PUTRGB(dst_2,py_2,2);
318 319

    LOADCHROMA(3);
320 321
    PUTRGB(dst_2,py_2,3);
    PUTRGB(dst_1,py_1,3);
322 323 324 325
CLOSEYUV2RGBFUNC(8)

// This is exactly the same code as yuv2rgb_c_32 except for the types of
// r, g, b, dst_1, dst_2
326
YUV2RGBFUNC(yuv2rgb_c_8, uint8_t, 0)
327
    LOADCHROMA(0);
328 329
    PUTRGB(dst_1,py_1,0);
    PUTRGB(dst_2,py_2,0);
330 331

    LOADCHROMA(1);
332 333
    PUTRGB(dst_2,py_2,1);
    PUTRGB(dst_1,py_1,1);
334 335

    LOADCHROMA(2);
336 337
    PUTRGB(dst_1,py_1,2);
    PUTRGB(dst_2,py_2,2);
338 339

    LOADCHROMA(3);
340 341
    PUTRGB(dst_2,py_2,3);
    PUTRGB(dst_1,py_1,3);
342 343 344
CLOSEYUV2RGBFUNC(8)

// r, g, b, dst_1, dst_2
345
YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
    const uint8_t *d32 = dither_8x8_32[y&7];
    const uint8_t *d64 = dither_8x8_73[y&7];
#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]];

    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);

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

    LOADCHROMA(3);
    PUTRGB8(dst_2,py_2,3,6+8);
    PUTRGB8(dst_1,py_1,3,6);
CLOSEYUV2RGBFUNC(8)


// This is exactly the same code as yuv2rgb_c_32 except for the types of
// r, g, b, dst_1, dst_2
374
YUV2RGBFUNC(yuv2rgb_c_4, uint8_t, 0)
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
    int acc;
#define PUTRGB4(dst,src,i)          \
    Y = src[2*i];                   \
    acc = r[Y] + g[Y] + b[Y];       \
    Y = src[2*i+1];                 \
    acc |= (r[Y] + g[Y] + b[Y])<<4; \
    dst[i] = acc;

    LOADCHROMA(0);
    PUTRGB4(dst_1,py_1,0);
    PUTRGB4(dst_2,py_2,0);

    LOADCHROMA(1);
    PUTRGB4(dst_2,py_2,1);
    PUTRGB4(dst_1,py_1,1);

    LOADCHROMA(2);
    PUTRGB4(dst_1,py_1,2);
    PUTRGB4(dst_2,py_2,2);

    LOADCHROMA(3);
    PUTRGB4(dst_2,py_2,3);
    PUTRGB4(dst_1,py_1,3);
CLOSEYUV2RGBFUNC(4)

400
YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
    const uint8_t *d64 =  dither_8x8_73[y&7];
    const uint8_t *d128 = dither_8x8_220[y&7];
    int acc;

#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;

    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);

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

    LOADCHROMA(3);
    PUTRGB4D(dst_2,py_2,3,6+8);
    PUTRGB4D(dst_1,py_1,3,6);
CLOSEYUV2RGBFUNC(4)

// This is exactly the same code as yuv2rgb_c_32 except for the types of
// r, g, b, dst_1, dst_2
431
YUV2RGBFUNC(yuv2rgb_c_4b, uint8_t, 0)
432
    LOADCHROMA(0);
433 434
    PUTRGB(dst_1,py_1,0);
    PUTRGB(dst_2,py_2,0);
435 436

    LOADCHROMA(1);
437 438
    PUTRGB(dst_2,py_2,1);
    PUTRGB(dst_1,py_1,1);
439 440

    LOADCHROMA(2);
441 442
    PUTRGB(dst_1,py_1,2);
    PUTRGB(dst_2,py_2,2);
443 444

    LOADCHROMA(3);
445 446
    PUTRGB(dst_2,py_2,3);
    PUTRGB(dst_1,py_1,3);
447 448
CLOSEYUV2RGBFUNC(8)

449
YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
    const uint8_t *d64 =  dither_8x8_73[y&7];
    const uint8_t *d128 = dither_8x8_220[y&7];

#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]];

    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);

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

    LOADCHROMA(3);
    PUTRGB4DB(dst_2,py_2,3,6+8);
    PUTRGB4DB(dst_1,py_1,3,6);
CLOSEYUV2RGBFUNC(8)

476
YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
        const uint8_t *d128 = dither_8x8_220[y&7];
        char out_1 = 0, out_2 = 0;
        g= c->table_gU[128] + c->table_gV[128];

#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]];

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

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

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

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

    dst_1[0]= out_1;
    dst_2[0]= out_2;
CLOSEYUV2RGBFUNC(1)

503
SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
504 505 506
{
    SwsFunc t = NULL;
#if (HAVE_MMX2 || HAVE_MMX) && CONFIG_GPL
507
     t = ff_yuv2rgb_init_mmx(c);
508 509
#endif
#if HAVE_VIS
510
    t = ff_yuv2rgb_init_vis(c);
511 512
#endif
#if CONFIG_MLIB
513
    t = ff_yuv2rgb_init_mlib(c);
514
#endif
515
#if HAVE_ALTIVEC
516
    if (c->flags & SWS_CPU_CAPS_ALTIVEC)
517
        t = ff_yuv2rgb_init_altivec(c);
518 519 520 521
#endif

#if ARCH_BFIN
    if (c->flags & SWS_CPU_CAPS_BFIN)
522
        t = ff_yuv2rgb_get_func_ptr_bfin(c);
523 524 525 526 527 528 529 530
#endif

    if (t)
        return t;

    av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found.\n");

    switch (c->dstFormat) {
531 532
    case PIX_FMT_RGB48BE:
    case PIX_FMT_RGB48LE:    return yuv2rgb_c_48;
533 534 535 536
    case PIX_FMT_ARGB:
    case PIX_FMT_ABGR:       if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) return yuva2argb_c;
    case PIX_FMT_RGBA:
    case PIX_FMT_BGRA:       return (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) ? yuva2rgba_c : yuv2rgb_c_32;
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
    case PIX_FMT_RGB24:      return yuv2rgb_c_24_rgb;
    case PIX_FMT_BGR24:      return yuv2rgb_c_24_bgr;
    case PIX_FMT_RGB565:
    case PIX_FMT_BGR565:
    case PIX_FMT_RGB555:
    case PIX_FMT_BGR555:     return yuv2rgb_c_16;
    case PIX_FMT_RGB8:
    case PIX_FMT_BGR8:       return yuv2rgb_c_8_ordered_dither;
    case PIX_FMT_RGB4:
    case PIX_FMT_BGR4:       return yuv2rgb_c_4_ordered_dither;
    case PIX_FMT_RGB4_BYTE:
    case PIX_FMT_BGR4_BYTE:  return yuv2rgb_c_4b_ordered_dither;
    case PIX_FMT_MONOBLACK:  return yuv2rgb_c_1_ordered_dither;
    default:
        assert(0);
    }
    return NULL;
}

static void fill_table(uint8_t* table[256], const int elemsize, const int inc, uint8_t *y_table)
{
    int i;
    int64_t cb = 0;

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

    for (i = 0; i < 256; i++) {
        table[i] = y_table + elemsize * (cb >> 16);
        cb += inc;
    }
}

static void fill_gv_table(int table[256], const int elemsize, const int inc)
{
    int i;
    int64_t cb = 0;
    int off = -(inc >> 9);

    for (i = 0; i < 256; i++) {
        table[i] = elemsize * (off + (cb >> 16));
        cb += inc;
    }
}

581 582
av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange,
                                     int brightness, int contrast, int saturation)
583 584 585 586 587 588 589 590 591 592 593 594 595 596
{
    const int isRgb =      c->dstFormat==PIX_FMT_RGB32
                        || c->dstFormat==PIX_FMT_RGB32_1
                        || c->dstFormat==PIX_FMT_BGR24
                        || c->dstFormat==PIX_FMT_RGB565
                        || c->dstFormat==PIX_FMT_RGB555
                        || c->dstFormat==PIX_FMT_RGB8
                        || c->dstFormat==PIX_FMT_RGB4
                        || c->dstFormat==PIX_FMT_RGB4_BYTE
                        || c->dstFormat==PIX_FMT_MONOBLACK;
    const int bpp = fmt_depth(c->dstFormat);
    uint8_t *y_table;
    uint16_t *y_table16;
    uint32_t *y_table32;
597
    int i, base, rbase, gbase, bbase, abase, needAlpha;
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
    const int yoffs = fullRange ? 384 : 326;

    int64_t crv =  inv_table[0];
    int64_t cbu =  inv_table[1];
    int64_t cgu = -inv_table[2];
    int64_t cgv = -inv_table[3];
    int64_t cy  = 1<<16;
    int64_t oy  = 0;

    int64_t yb = 0;

    if (!fullRange) {
        cy = (cy*255) / 219;
        oy = 16<<16;
    } else {
        crv = (crv*224) / 255;
        cbu = (cbu*224) / 255;
        cgu = (cgu*224) / 255;
        cgv = (cgv*224) / 255;
    }

    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;

    //scale coefficients by cy
    crv = ((crv << 16) + 0x8000) / cy;
    cbu = ((cbu << 16) + 0x8000) / cy;
    cgu = ((cgu << 16) + 0x8000) / cy;
    cgv = ((cgv << 16) + 0x8000) / cy;

    av_free(c->yuvTable);

    switch (bpp) {
    case 1:
        c->yuvTable = av_malloc(1024);
        y_table = c->yuvTable;
        yb = -(384<<16) - oy;
        for (i = 0; i < 1024-110; i++) {
            y_table[i+110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7;
            yb += cy;
        }
        fill_table(c->table_gU, 1, cgu, y_table + yoffs);
        fill_gv_table(c->table_gV, 1, cgv);
        break;
    case 4:
    case 4|128:
        rbase = isRgb ? 3 : 0;
        gbase = 1;
        bbase = isRgb ? 0 : 3;
        c->yuvTable = av_malloc(1024*3);
        y_table = c->yuvTable;
        yb = -(384<<16) - oy;
        for (i = 0; i < 1024-110; i++) {
            int yval = av_clip_uint8((yb + 0x8000) >> 16);
            y_table[i+110     ] =  (yval >> 7)       << rbase;
            y_table[i+ 37+1024] = ((yval + 43) / 85) << gbase;
            y_table[i+110+2048] =  (yval >> 7)       << bbase;
            yb += cy;
        }
        fill_table(c->table_rV, 1, crv, y_table + yoffs);
        fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
        fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
        fill_gv_table(c->table_gV, 1, cgv);
        break;
    case 8:
        rbase = isRgb ? 5 : 0;
        gbase = isRgb ? 2 : 3;
        bbase = isRgb ? 0 : 6;
        c->yuvTable = av_malloc(1024*3);
        y_table = c->yuvTable;
        yb = -(384<<16) - oy;
        for (i = 0; i < 1024-38; i++) {
            int yval = av_clip_uint8((yb + 0x8000) >> 16);
            y_table[i+16     ] = ((yval + 18) / 36) << rbase;
            y_table[i+16+1024] = ((yval + 18) / 36) << gbase;
            y_table[i+37+2048] = ((yval + 43) / 85) << bbase;
            yb += cy;
        }
        fill_table(c->table_rV, 1, crv, y_table + yoffs);
        fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
        fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
        fill_gv_table(c->table_gV, 1, cgv);
        break;
    case 15:
    case 16:
        rbase = isRgb ? bpp - 5 : 0;
        gbase = 5;
        bbase = isRgb ? 0 : (bpp - 5);
        c->yuvTable = av_malloc(1024*3*2);
        y_table16 = c->yuvTable;
        yb = -(384<<16) - oy;
        for (i = 0; i < 1024; i++) {
            uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
            y_table16[i     ] = (yval >> 3)          << rbase;
            y_table16[i+1024] = (yval >> (18 - bpp)) << gbase;
            y_table16[i+2048] = (yval >> 3)          << bbase;
            yb += cy;
        }
        fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
        fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
        fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
        fill_gv_table(c->table_gV, 2, cgv);
        break;
    case 24:
706
    case 48:
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
        c->yuvTable = av_malloc(1024);
        y_table = c->yuvTable;
        yb = -(384<<16) - oy;
        for (i = 0; i < 1024; i++) {
            y_table[i] = av_clip_uint8((yb + 0x8000) >> 16);
            yb += cy;
        }
        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:
        base = (c->dstFormat == PIX_FMT_RGB32_1 || c->dstFormat == PIX_FMT_BGR32_1) ? 8 : 0;
        rbase = base + (isRgb ? 16 : 0);
        gbase = base + 8;
        bbase = base + (isRgb ? 0 : 16);
724 725 726
        needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
        if (!needAlpha)
            abase = (base + 24) & 31;
727 728 729 730 731
        c->yuvTable = av_malloc(1024*3*4);
        y_table32 = c->yuvTable;
        yb = -(384<<16) - oy;
        for (i = 0; i < 1024; i++) {
            uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
732
            y_table32[i     ] = (yval << rbase) + (needAlpha ? 0 : (255 << abase));
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
            y_table32[i+1024] = yval << gbase;
            y_table32[i+2048] = yval << bbase;
            yb += cy;
        }
        fill_table(c->table_rV, 4, crv, y_table32 + yoffs);
        fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + 1024);
        fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2048);
        fill_gv_table(c->table_gV, 4, cgv);
        break;
    default:
        c->yuvTable = NULL;
        av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
        return -1;
    }
    return 0;
}