Libav 0.7.1
libswscale/yuv2rgb.c
Go to the documentation of this file.
00001 /*
00002  * software YUV to RGB converter
00003  *
00004  * Copyright (C) 2009 Konstantin Shishkov
00005  *
00006  * 1,4,8bpp support and context / deglobalize stuff
00007  * by Michael Niedermayer (michaelni@gmx.at)
00008  *
00009  * This file is part of Libav.
00010  *
00011  * Libav is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU Lesser General Public
00013  * License as published by the Free Software Foundation; either
00014  * version 2.1 of the License, or (at your option) any later version.
00015  *
00016  * Libav is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with Libav; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00024  */
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <inttypes.h>
00029 #include <assert.h>
00030 
00031 #include "config.h"
00032 #include "rgb2rgb.h"
00033 #include "swscale.h"
00034 #include "swscale_internal.h"
00035 #include "libavutil/cpu.h"
00036 #include "libavutil/bswap.h"
00037 
00038 extern const uint8_t dither_4x4_16[4][8];
00039 extern const uint8_t dither_8x8_32[8][8];
00040 extern const uint8_t dither_8x8_73[8][8];
00041 extern const uint8_t dither_8x8_220[8][8];
00042 
00043 const int32_t ff_yuv2rgb_coeffs[8][4] = {
00044     {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
00045     {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
00046     {104597, 132201, 25675, 53279}, /* unspecified */
00047     {104597, 132201, 25675, 53279}, /* reserved */
00048     {104448, 132798, 24759, 53109}, /* FCC */
00049     {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
00050     {104597, 132201, 25675, 53279}, /* SMPTE 170M */
00051     {117579, 136230, 16907, 35559}  /* SMPTE 240M (1987) */
00052 };
00053 
00054 const int *sws_getCoefficients(int colorspace)
00055 {
00056     if (colorspace > 7 || colorspace < 0)
00057         colorspace = SWS_CS_DEFAULT;
00058     return ff_yuv2rgb_coeffs[colorspace];
00059 }
00060 
00061 #define LOADCHROMA(i)                               \
00062     U = pu[i];                                      \
00063     V = pv[i];                                      \
00064     r = (void *)c->table_rV[V];                     \
00065     g = (void *)(c->table_gU[U] + c->table_gV[V]);  \
00066     b = (void *)c->table_bU[U];
00067 
00068 #define PUTRGB(dst,src,i)            \
00069     Y = src[2*i];                    \
00070     dst[2*i  ] = r[Y] + g[Y] + b[Y]; \
00071     Y = src[2*i+1];                  \
00072     dst[2*i+1] = r[Y] + g[Y] + b[Y];
00073 
00074 #define PUTRGB24(dst,src,i)                                  \
00075     Y = src[2*i];                                            \
00076     dst[6*i+0] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y]; \
00077     Y = src[2*i+1];                                          \
00078     dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y];
00079 
00080 #define PUTBGR24(dst,src,i)                                  \
00081     Y = src[2*i];                                            \
00082     dst[6*i+0] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y]; \
00083     Y = src[2*i+1];                                          \
00084     dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y];
00085 
00086 #define PUTRGBA(dst,ysrc,asrc,i,s)                      \
00087     Y = ysrc[2*i];                                      \
00088     dst[2*i  ] = r[Y] + g[Y] + b[Y] + (asrc[2*i  ]<<s); \
00089     Y = ysrc[2*i+1];                                    \
00090     dst[2*i+1] = r[Y] + g[Y] + b[Y] + (asrc[2*i+1]<<s);
00091 
00092 #define PUTRGB48(dst,src,i)             \
00093     Y = src[2*i];                       \
00094     dst[12*i+ 0] = dst[12*i+ 1] = r[Y]; \
00095     dst[12*i+ 2] = dst[12*i+ 3] = g[Y]; \
00096     dst[12*i+ 4] = dst[12*i+ 5] = b[Y]; \
00097     Y = src[2*i+1];                     \
00098     dst[12*i+ 6] = dst[12*i+ 7] = r[Y]; \
00099     dst[12*i+ 8] = dst[12*i+ 9] = g[Y]; \
00100     dst[12*i+10] = dst[12*i+11] = b[Y];
00101 
00102 #define PUTBGR48(dst,src,i)             \
00103     Y = src[2*i];                       \
00104     dst[12*i+ 0] = dst[12*i+ 1] = b[Y]; \
00105     dst[12*i+ 2] = dst[12*i+ 3] = g[Y]; \
00106     dst[12*i+ 4] = dst[12*i+ 5] = r[Y]; \
00107     Y = src[2*i+1];                     \
00108     dst[12*i+ 6] = dst[12*i+ 7] = b[Y]; \
00109     dst[12*i+ 8] = dst[12*i+ 9] = g[Y]; \
00110     dst[12*i+10] = dst[12*i+11] = r[Y];
00111 
00112 #define YUV2RGBFUNC(func_name, dst_type, alpha) \
00113 static int func_name(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, \
00114                      int srcSliceH, uint8_t* dst[], int dstStride[]) \
00115 {\
00116     int y;\
00117 \
00118     if (!alpha && c->srcFormat == PIX_FMT_YUV422P) {\
00119         srcStride[1] *= 2;\
00120         srcStride[2] *= 2;\
00121     }\
00122     for (y=0; y<srcSliceH; y+=2) {\
00123         dst_type *dst_1 = (dst_type*)(dst[0] + (y+srcSliceY  )*dstStride[0]);\
00124         dst_type *dst_2 = (dst_type*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);\
00125         dst_type av_unused *r, *b;\
00126         dst_type *g;\
00127         const uint8_t *py_1 = src[0] + y*srcStride[0];\
00128         const uint8_t *py_2 = py_1 + srcStride[0];\
00129         const uint8_t *pu = src[1] + (y>>1)*srcStride[1];\
00130         const uint8_t *pv = src[2] + (y>>1)*srcStride[2];\
00131         const uint8_t av_unused *pa_1, *pa_2;\
00132         unsigned int h_size = c->dstW>>3;\
00133         if (alpha) {\
00134             pa_1 = src[3] + y*srcStride[3];\
00135             pa_2 = pa_1 + srcStride[3];\
00136         }\
00137         while (h_size--) {\
00138             int av_unused U, V;\
00139             int Y;\
00140 
00141 #define ENDYUV2RGBLINE(dst_delta)\
00142             pu += 4;\
00143             pv += 4;\
00144             py_1 += 8;\
00145             py_2 += 8;\
00146             dst_1 += dst_delta;\
00147             dst_2 += dst_delta;\
00148         }\
00149         if (c->dstW & 4) {\
00150             int av_unused Y, U, V;\
00151 
00152 #define ENDYUV2RGBFUNC()\
00153         }\
00154     }\
00155     return srcSliceH;\
00156 }
00157 
00158 #define CLOSEYUV2RGBFUNC(dst_delta)\
00159     ENDYUV2RGBLINE(dst_delta)\
00160     ENDYUV2RGBFUNC()
00161 
00162 YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
00163     LOADCHROMA(0);
00164     PUTRGB48(dst_1,py_1,0);
00165     PUTRGB48(dst_2,py_2,0);
00166 
00167     LOADCHROMA(1);
00168     PUTRGB48(dst_2,py_2,1);
00169     PUTRGB48(dst_1,py_1,1);
00170 
00171     LOADCHROMA(2);
00172     PUTRGB48(dst_1,py_1,2);
00173     PUTRGB48(dst_2,py_2,2);
00174 
00175     LOADCHROMA(3);
00176     PUTRGB48(dst_2,py_2,3);
00177     PUTRGB48(dst_1,py_1,3);
00178 ENDYUV2RGBLINE(48)
00179     LOADCHROMA(0);
00180     PUTRGB48(dst_1,py_1,0);
00181     PUTRGB48(dst_2,py_2,0);
00182 
00183     LOADCHROMA(1);
00184     PUTRGB48(dst_2,py_2,1);
00185     PUTRGB48(dst_1,py_1,1);
00186 ENDYUV2RGBFUNC()
00187 
00188 YUV2RGBFUNC(yuv2rgb_c_bgr48, uint8_t, 0)
00189     LOADCHROMA(0);
00190     PUTBGR48(dst_1,py_1,0);
00191     PUTBGR48(dst_2,py_2,0);
00192 
00193     LOADCHROMA(1);
00194     PUTBGR48(dst_2,py_2,1);
00195     PUTBGR48(dst_1,py_1,1);
00196 
00197     LOADCHROMA(2);
00198     PUTBGR48(dst_1,py_1,2);
00199     PUTBGR48(dst_2,py_2,2);
00200 
00201     LOADCHROMA(3);
00202     PUTBGR48(dst_2,py_2,3);
00203     PUTBGR48(dst_1,py_1,3);
00204 ENDYUV2RGBLINE(48)
00205     LOADCHROMA(0);
00206     PUTBGR48(dst_1,py_1,0);
00207     PUTBGR48(dst_2,py_2,0);
00208 
00209     LOADCHROMA(1);
00210     PUTBGR48(dst_2,py_2,1);
00211     PUTBGR48(dst_1,py_1,1);
00212 ENDYUV2RGBFUNC()
00213 
00214 YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
00215     LOADCHROMA(0);
00216     PUTRGB(dst_1,py_1,0);
00217     PUTRGB(dst_2,py_2,0);
00218 
00219     LOADCHROMA(1);
00220     PUTRGB(dst_2,py_2,1);
00221     PUTRGB(dst_1,py_1,1);
00222 
00223     LOADCHROMA(2);
00224     PUTRGB(dst_1,py_1,2);
00225     PUTRGB(dst_2,py_2,2);
00226 
00227     LOADCHROMA(3);
00228     PUTRGB(dst_2,py_2,3);
00229     PUTRGB(dst_1,py_1,3);
00230 ENDYUV2RGBLINE(8)
00231     LOADCHROMA(0);
00232     PUTRGB(dst_1,py_1,0);
00233     PUTRGB(dst_2,py_2,0);
00234 
00235     LOADCHROMA(1);
00236     PUTRGB(dst_2,py_2,1);
00237     PUTRGB(dst_1,py_1,1);
00238 ENDYUV2RGBFUNC()
00239 
00240 YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
00241     LOADCHROMA(0);
00242     PUTRGBA(dst_1,py_1,pa_1,0,24);
00243     PUTRGBA(dst_2,py_2,pa_2,0,24);
00244 
00245     LOADCHROMA(1);
00246     PUTRGBA(dst_2,py_2,pa_1,1,24);
00247     PUTRGBA(dst_1,py_1,pa_2,1,24);
00248 
00249     LOADCHROMA(2);
00250     PUTRGBA(dst_1,py_1,pa_1,2,24);
00251     PUTRGBA(dst_2,py_2,pa_2,2,24);
00252 
00253     LOADCHROMA(3);
00254     PUTRGBA(dst_2,py_2,pa_1,3,24);
00255     PUTRGBA(dst_1,py_1,pa_2,3,24);
00256     pa_1 += 8;\
00257     pa_2 += 8;\
00258 ENDYUV2RGBLINE(8)
00259     LOADCHROMA(0);
00260     PUTRGBA(dst_1,py_1,pa_1,0,24);
00261     PUTRGBA(dst_2,py_2,pa_2,0,24);
00262 
00263     LOADCHROMA(1);
00264     PUTRGBA(dst_2,py_2,pa_1,1,24);
00265     PUTRGBA(dst_1,py_1,pa_2,1,24);
00266 ENDYUV2RGBFUNC()
00267 
00268 YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
00269     LOADCHROMA(0);
00270     PUTRGBA(dst_1,py_1,pa_1,0,0);
00271     PUTRGBA(dst_2,py_2,pa_2,0,0);
00272 
00273     LOADCHROMA(1);
00274     PUTRGBA(dst_2,py_2,pa_2,1,0);
00275     PUTRGBA(dst_1,py_1,pa_1,1,0);
00276 
00277     LOADCHROMA(2);
00278     PUTRGBA(dst_1,py_1,pa_1,2,0);
00279     PUTRGBA(dst_2,py_2,pa_2,2,0);
00280 
00281     LOADCHROMA(3);
00282     PUTRGBA(dst_2,py_2,pa_2,3,0);
00283     PUTRGBA(dst_1,py_1,pa_1,3,0);
00284     pa_1 += 8;\
00285     pa_2 += 8;\
00286 ENDYUV2RGBLINE(8)
00287     LOADCHROMA(0);
00288     PUTRGBA(dst_1,py_1,pa_1,0,0);
00289     PUTRGBA(dst_2,py_2,pa_2,0,0);
00290 
00291     LOADCHROMA(1);
00292     PUTRGBA(dst_2,py_2,pa_2,1,0);
00293     PUTRGBA(dst_1,py_1,pa_1,1,0);
00294 ENDYUV2RGBFUNC()
00295 
00296 YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0)
00297     LOADCHROMA(0);
00298     PUTRGB24(dst_1,py_1,0);
00299     PUTRGB24(dst_2,py_2,0);
00300 
00301     LOADCHROMA(1);
00302     PUTRGB24(dst_2,py_2,1);
00303     PUTRGB24(dst_1,py_1,1);
00304 
00305     LOADCHROMA(2);
00306     PUTRGB24(dst_1,py_1,2);
00307     PUTRGB24(dst_2,py_2,2);
00308 
00309     LOADCHROMA(3);
00310     PUTRGB24(dst_2,py_2,3);
00311     PUTRGB24(dst_1,py_1,3);
00312 ENDYUV2RGBLINE(24)
00313     LOADCHROMA(0);
00314     PUTRGB24(dst_1,py_1,0);
00315     PUTRGB24(dst_2,py_2,0);
00316 
00317     LOADCHROMA(1);
00318     PUTRGB24(dst_2,py_2,1);
00319     PUTRGB24(dst_1,py_1,1);
00320 ENDYUV2RGBFUNC()
00321 
00322 // only trivial mods from yuv2rgb_c_24_rgb
00323 YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0)
00324     LOADCHROMA(0);
00325     PUTBGR24(dst_1,py_1,0);
00326     PUTBGR24(dst_2,py_2,0);
00327 
00328     LOADCHROMA(1);
00329     PUTBGR24(dst_2,py_2,1);
00330     PUTBGR24(dst_1,py_1,1);
00331 
00332     LOADCHROMA(2);
00333     PUTBGR24(dst_1,py_1,2);
00334     PUTBGR24(dst_2,py_2,2);
00335 
00336     LOADCHROMA(3);
00337     PUTBGR24(dst_2,py_2,3);
00338     PUTBGR24(dst_1,py_1,3);
00339 ENDYUV2RGBLINE(24)
00340     LOADCHROMA(0);
00341     PUTBGR24(dst_1,py_1,0);
00342     PUTBGR24(dst_2,py_2,0);
00343 
00344     LOADCHROMA(1);
00345     PUTBGR24(dst_2,py_2,1);
00346     PUTBGR24(dst_1,py_1,1);
00347 ENDYUV2RGBFUNC()
00348 
00349 // This is exactly the same code as yuv2rgb_c_32 except for the types of
00350 // r, g, b, dst_1, dst_2
00351 YUV2RGBFUNC(yuv2rgb_c_16, uint16_t, 0)
00352     LOADCHROMA(0);
00353     PUTRGB(dst_1,py_1,0);
00354     PUTRGB(dst_2,py_2,0);
00355 
00356     LOADCHROMA(1);
00357     PUTRGB(dst_2,py_2,1);
00358     PUTRGB(dst_1,py_1,1);
00359 
00360     LOADCHROMA(2);
00361     PUTRGB(dst_1,py_1,2);
00362     PUTRGB(dst_2,py_2,2);
00363 
00364     LOADCHROMA(3);
00365     PUTRGB(dst_2,py_2,3);
00366     PUTRGB(dst_1,py_1,3);
00367 CLOSEYUV2RGBFUNC(8)
00368 
00369 // r, g, b, dst_1, dst_2
00370 YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
00371     const uint8_t *d16 = dither_4x4_16[y&3];
00372 #define PUTRGB12(dst,src,i,o)                                   \
00373     Y = src[2*i];                                               \
00374     dst[2*i]   = r[Y+d16[0+o]] + g[Y+d16[0+o]] + b[Y+d16[0+o]]; \
00375     Y = src[2*i+1];                                             \
00376     dst[2*i+1] = r[Y+d16[1+o]] + g[Y+d16[1+o]] + b[Y+d16[1+o]];
00377 
00378     LOADCHROMA(0);
00379     PUTRGB12(dst_1,py_1,0,0);
00380     PUTRGB12(dst_2,py_2,0,0+8);
00381 
00382     LOADCHROMA(1);
00383     PUTRGB12(dst_2,py_2,1,2+8);
00384     PUTRGB12(dst_1,py_1,1,2);
00385 
00386     LOADCHROMA(2);
00387     PUTRGB12(dst_1,py_1,2,4);
00388     PUTRGB12(dst_2,py_2,2,4+8);
00389 
00390     LOADCHROMA(3);
00391     PUTRGB12(dst_2,py_2,3,6+8);
00392     PUTRGB12(dst_1,py_1,3,6);
00393 CLOSEYUV2RGBFUNC(8)
00394 
00395 // r, g, b, dst_1, dst_2
00396 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
00397     const uint8_t *d32 = dither_8x8_32[y&7];
00398     const uint8_t *d64 = dither_8x8_73[y&7];
00399 #define PUTRGB8(dst,src,i,o)                                    \
00400     Y = src[2*i];                                               \
00401     dst[2*i]   = r[Y+d32[0+o]] + g[Y+d32[0+o]] + b[Y+d64[0+o]]; \
00402     Y = src[2*i+1];                                             \
00403     dst[2*i+1] = r[Y+d32[1+o]] + g[Y+d32[1+o]] + b[Y+d64[1+o]];
00404 
00405     LOADCHROMA(0);
00406     PUTRGB8(dst_1,py_1,0,0);
00407     PUTRGB8(dst_2,py_2,0,0+8);
00408 
00409     LOADCHROMA(1);
00410     PUTRGB8(dst_2,py_2,1,2+8);
00411     PUTRGB8(dst_1,py_1,1,2);
00412 
00413     LOADCHROMA(2);
00414     PUTRGB8(dst_1,py_1,2,4);
00415     PUTRGB8(dst_2,py_2,2,4+8);
00416 
00417     LOADCHROMA(3);
00418     PUTRGB8(dst_2,py_2,3,6+8);
00419     PUTRGB8(dst_1,py_1,3,6);
00420 CLOSEYUV2RGBFUNC(8)
00421 
00422 YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
00423     const uint8_t *d64 =  dither_8x8_73[y&7];
00424     const uint8_t *d128 = dither_8x8_220[y&7];
00425     int acc;
00426 
00427 #define PUTRGB4D(dst,src,i,o)                                     \
00428     Y = src[2*i];                                                 \
00429     acc = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]];        \
00430     Y = src[2*i+1];                                               \
00431     acc |= (r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]])<<4;  \
00432     dst[i]= acc;
00433 
00434     LOADCHROMA(0);
00435     PUTRGB4D(dst_1,py_1,0,0);
00436     PUTRGB4D(dst_2,py_2,0,0+8);
00437 
00438     LOADCHROMA(1);
00439     PUTRGB4D(dst_2,py_2,1,2+8);
00440     PUTRGB4D(dst_1,py_1,1,2);
00441 
00442     LOADCHROMA(2);
00443     PUTRGB4D(dst_1,py_1,2,4);
00444     PUTRGB4D(dst_2,py_2,2,4+8);
00445 
00446     LOADCHROMA(3);
00447     PUTRGB4D(dst_2,py_2,3,6+8);
00448     PUTRGB4D(dst_1,py_1,3,6);
00449 CLOSEYUV2RGBFUNC(4)
00450 
00451 YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
00452     const uint8_t *d64 =  dither_8x8_73[y&7];
00453     const uint8_t *d128 = dither_8x8_220[y&7];
00454 
00455 #define PUTRGB4DB(dst,src,i,o)                                    \
00456     Y = src[2*i];                                                 \
00457     dst[2*i]   = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \
00458     Y = src[2*i+1];                                               \
00459     dst[2*i+1] = r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]];
00460 
00461     LOADCHROMA(0);
00462     PUTRGB4DB(dst_1,py_1,0,0);
00463     PUTRGB4DB(dst_2,py_2,0,0+8);
00464 
00465     LOADCHROMA(1);
00466     PUTRGB4DB(dst_2,py_2,1,2+8);
00467     PUTRGB4DB(dst_1,py_1,1,2);
00468 
00469     LOADCHROMA(2);
00470     PUTRGB4DB(dst_1,py_1,2,4);
00471     PUTRGB4DB(dst_2,py_2,2,4+8);
00472 
00473     LOADCHROMA(3);
00474     PUTRGB4DB(dst_2,py_2,3,6+8);
00475     PUTRGB4DB(dst_1,py_1,3,6);
00476 CLOSEYUV2RGBFUNC(8)
00477 
00478 YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
00479         const uint8_t *d128 = dither_8x8_220[y&7];
00480         char out_1 = 0, out_2 = 0;
00481         g= c->table_gU[128] + c->table_gV[128];
00482 
00483 #define PUTRGB1(out,src,i,o)    \
00484     Y = src[2*i];               \
00485     out+= out + g[Y+d128[0+o]]; \
00486     Y = src[2*i+1];             \
00487     out+= out + g[Y+d128[1+o]];
00488 
00489     PUTRGB1(out_1,py_1,0,0);
00490     PUTRGB1(out_2,py_2,0,0+8);
00491 
00492     PUTRGB1(out_2,py_2,1,2+8);
00493     PUTRGB1(out_1,py_1,1,2);
00494 
00495     PUTRGB1(out_1,py_1,2,4);
00496     PUTRGB1(out_2,py_2,2,4+8);
00497 
00498     PUTRGB1(out_2,py_2,3,6+8);
00499     PUTRGB1(out_1,py_1,3,6);
00500 
00501     dst_1[0]= out_1;
00502     dst_2[0]= out_2;
00503 CLOSEYUV2RGBFUNC(1)
00504 
00505 SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
00506 {
00507     SwsFunc t = NULL;
00508 
00509     if (HAVE_MMX) {
00510         t = ff_yuv2rgb_init_mmx(c);
00511     } else if (HAVE_VIS) {
00512         t = ff_yuv2rgb_init_vis(c);
00513     } else if (CONFIG_MLIB) {
00514         t = ff_yuv2rgb_init_mlib(c);
00515     } else if (HAVE_ALTIVEC) {
00516         t = ff_yuv2rgb_init_altivec(c);
00517     } else if (ARCH_BFIN) {
00518         t = ff_yuv2rgb_get_func_ptr_bfin(c);
00519     }
00520 
00521     if (t)
00522         return t;
00523 
00524     av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found from %s to %s.\n", sws_format_name(c->srcFormat), sws_format_name(c->dstFormat));
00525 
00526     switch (c->dstFormat) {
00527     case PIX_FMT_BGR48BE:
00528     case PIX_FMT_BGR48LE:    return yuv2rgb_c_bgr48;
00529     case PIX_FMT_RGB48BE:
00530     case PIX_FMT_RGB48LE:    return yuv2rgb_c_48;
00531     case PIX_FMT_ARGB:
00532     case PIX_FMT_ABGR:       if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) return yuva2argb_c;
00533     case PIX_FMT_RGBA:
00534     case PIX_FMT_BGRA:       return (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) ? yuva2rgba_c : yuv2rgb_c_32;
00535     case PIX_FMT_RGB24:      return yuv2rgb_c_24_rgb;
00536     case PIX_FMT_BGR24:      return yuv2rgb_c_24_bgr;
00537     case PIX_FMT_RGB565:
00538     case PIX_FMT_BGR565:
00539     case PIX_FMT_RGB555:
00540     case PIX_FMT_BGR555:     return yuv2rgb_c_16;
00541     case PIX_FMT_RGB444:
00542     case PIX_FMT_BGR444:     return yuv2rgb_c_12_ordered_dither;
00543     case PIX_FMT_RGB8:
00544     case PIX_FMT_BGR8:       return yuv2rgb_c_8_ordered_dither;
00545     case PIX_FMT_RGB4:
00546     case PIX_FMT_BGR4:       return yuv2rgb_c_4_ordered_dither;
00547     case PIX_FMT_RGB4_BYTE:
00548     case PIX_FMT_BGR4_BYTE:  return yuv2rgb_c_4b_ordered_dither;
00549     case PIX_FMT_MONOBLACK:  return yuv2rgb_c_1_ordered_dither;
00550     default:
00551         assert(0);
00552     }
00553     return NULL;
00554 }
00555 
00556 static void fill_table(uint8_t* table[256], const int elemsize, const int inc, void *y_tab)
00557 {
00558     int i;
00559     int64_t cb = 0;
00560     uint8_t *y_table = y_tab;
00561 
00562     y_table -= elemsize * (inc >> 9);
00563 
00564     for (i = 0; i < 256; i++) {
00565         table[i] = y_table + elemsize * (cb >> 16);
00566         cb += inc;
00567     }
00568 }
00569 
00570 static void fill_gv_table(int table[256], const int elemsize, const int inc)
00571 {
00572     int i;
00573     int64_t cb = 0;
00574     int off = -(inc >> 9);
00575 
00576     for (i = 0; i < 256; i++) {
00577         table[i] = elemsize * (off + (cb >> 16));
00578         cb += inc;
00579     }
00580 }
00581 
00582 static uint16_t roundToInt16(int64_t f)
00583 {
00584     int r= (f + (1<<15))>>16;
00585          if (r<-0x7FFF) return 0x8000;
00586     else if (r> 0x7FFF) return 0x7FFF;
00587     else                return r;
00588 }
00589 
00590 av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange,
00591                                      int brightness, int contrast, int saturation)
00592 {
00593     const int isRgb =      c->dstFormat==PIX_FMT_RGB32
00594                         || c->dstFormat==PIX_FMT_RGB32_1
00595                         || c->dstFormat==PIX_FMT_BGR24
00596                         || c->dstFormat==PIX_FMT_RGB565BE
00597                         || c->dstFormat==PIX_FMT_RGB565LE
00598                         || c->dstFormat==PIX_FMT_RGB555BE
00599                         || c->dstFormat==PIX_FMT_RGB555LE
00600                         || c->dstFormat==PIX_FMT_RGB444BE
00601                         || c->dstFormat==PIX_FMT_RGB444LE
00602                         || c->dstFormat==PIX_FMT_RGB8
00603                         || c->dstFormat==PIX_FMT_RGB4
00604                         || c->dstFormat==PIX_FMT_RGB4_BYTE
00605                         || c->dstFormat==PIX_FMT_MONOBLACK;
00606     const int isNotNe =    c->dstFormat==PIX_FMT_NE(RGB565LE,RGB565BE)
00607                         || c->dstFormat==PIX_FMT_NE(RGB555LE,RGB555BE)
00608                         || c->dstFormat==PIX_FMT_NE(RGB444LE,RGB444BE)
00609                         || c->dstFormat==PIX_FMT_NE(BGR565LE,BGR565BE)
00610                         || c->dstFormat==PIX_FMT_NE(BGR555LE,BGR555BE)
00611                         || c->dstFormat==PIX_FMT_NE(BGR444LE,BGR444BE);
00612     const int bpp = c->dstFormatBpp;
00613     uint8_t *y_table;
00614     uint16_t *y_table16;
00615     uint32_t *y_table32;
00616     int i, base, rbase, gbase, bbase, abase, needAlpha;
00617     const int yoffs = fullRange ? 384 : 326;
00618 
00619     int64_t crv =  inv_table[0];
00620     int64_t cbu =  inv_table[1];
00621     int64_t cgu = -inv_table[2];
00622     int64_t cgv = -inv_table[3];
00623     int64_t cy  = 1<<16;
00624     int64_t oy  = 0;
00625 
00626     int64_t yb = 0;
00627 
00628     if (!fullRange) {
00629         cy = (cy*255) / 219;
00630         oy = 16<<16;
00631     } else {
00632         crv = (crv*224) / 255;
00633         cbu = (cbu*224) / 255;
00634         cgu = (cgu*224) / 255;
00635         cgv = (cgv*224) / 255;
00636     }
00637 
00638     cy  = (cy *contrast             ) >> 16;
00639     crv = (crv*contrast * saturation) >> 32;
00640     cbu = (cbu*contrast * saturation) >> 32;
00641     cgu = (cgu*contrast * saturation) >> 32;
00642     cgv = (cgv*contrast * saturation) >> 32;
00643     oy -= 256*brightness;
00644 
00645     c->uOffset=   0x0400040004000400LL;
00646     c->vOffset=   0x0400040004000400LL;
00647     c->yCoeff=    roundToInt16(cy *8192) * 0x0001000100010001ULL;
00648     c->vrCoeff=   roundToInt16(crv*8192) * 0x0001000100010001ULL;
00649     c->ubCoeff=   roundToInt16(cbu*8192) * 0x0001000100010001ULL;
00650     c->vgCoeff=   roundToInt16(cgv*8192) * 0x0001000100010001ULL;
00651     c->ugCoeff=   roundToInt16(cgu*8192) * 0x0001000100010001ULL;
00652     c->yOffset=   roundToInt16(oy *   8) * 0x0001000100010001ULL;
00653 
00654     c->yuv2rgb_y_coeff  = (int16_t)roundToInt16(cy <<13);
00655     c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9);
00656     c->yuv2rgb_v2r_coeff= (int16_t)roundToInt16(crv<<13);
00657     c->yuv2rgb_v2g_coeff= (int16_t)roundToInt16(cgv<<13);
00658     c->yuv2rgb_u2g_coeff= (int16_t)roundToInt16(cgu<<13);
00659     c->yuv2rgb_u2b_coeff= (int16_t)roundToInt16(cbu<<13);
00660 
00661     //scale coefficients by cy
00662     crv = ((crv << 16) + 0x8000) / cy;
00663     cbu = ((cbu << 16) + 0x8000) / cy;
00664     cgu = ((cgu << 16) + 0x8000) / cy;
00665     cgv = ((cgv << 16) + 0x8000) / cy;
00666 
00667     av_free(c->yuvTable);
00668 
00669     switch (bpp) {
00670     case 1:
00671         c->yuvTable = av_malloc(1024);
00672         y_table = c->yuvTable;
00673         yb = -(384<<16) - oy;
00674         for (i = 0; i < 1024-110; i++) {
00675             y_table[i+110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7;
00676             yb += cy;
00677         }
00678         fill_table(c->table_gU, 1, cgu, y_table + yoffs);
00679         fill_gv_table(c->table_gV, 1, cgv);
00680         break;
00681     case 4:
00682     case 4|128:
00683         rbase = isRgb ? 3 : 0;
00684         gbase = 1;
00685         bbase = isRgb ? 0 : 3;
00686         c->yuvTable = av_malloc(1024*3);
00687         y_table = c->yuvTable;
00688         yb = -(384<<16) - oy;
00689         for (i = 0; i < 1024-110; i++) {
00690             int yval = av_clip_uint8((yb + 0x8000) >> 16);
00691             y_table[i+110     ] =  (yval >> 7)       << rbase;
00692             y_table[i+ 37+1024] = ((yval + 43) / 85) << gbase;
00693             y_table[i+110+2048] =  (yval >> 7)       << bbase;
00694             yb += cy;
00695         }
00696         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00697         fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
00698         fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
00699         fill_gv_table(c->table_gV, 1, cgv);
00700         break;
00701     case 8:
00702         rbase = isRgb ? 5 : 0;
00703         gbase = isRgb ? 2 : 3;
00704         bbase = isRgb ? 0 : 6;
00705         c->yuvTable = av_malloc(1024*3);
00706         y_table = c->yuvTable;
00707         yb = -(384<<16) - oy;
00708         for (i = 0; i < 1024-38; i++) {
00709             int yval = av_clip_uint8((yb + 0x8000) >> 16);
00710             y_table[i+16     ] = ((yval + 18) / 36) << rbase;
00711             y_table[i+16+1024] = ((yval + 18) / 36) << gbase;
00712             y_table[i+37+2048] = ((yval + 43) / 85) << bbase;
00713             yb += cy;
00714         }
00715         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00716         fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
00717         fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
00718         fill_gv_table(c->table_gV, 1, cgv);
00719         break;
00720     case 12:
00721         rbase = isRgb ? 8 : 0;
00722         gbase = 4;
00723         bbase = isRgb ? 0 : 8;
00724         c->yuvTable = av_malloc(1024*3*2);
00725         y_table16 = c->yuvTable;
00726         yb = -(384<<16) - oy;
00727         for (i = 0; i < 1024; i++) {
00728             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00729             y_table16[i     ] = (yval >> 4) << rbase;
00730             y_table16[i+1024] = (yval >> 4) << gbase;
00731             y_table16[i+2048] = (yval >> 4) << bbase;
00732             yb += cy;
00733         }
00734         if (isNotNe)
00735             for (i = 0; i < 1024*3; i++)
00736                 y_table16[i] = av_bswap16(y_table16[i]);
00737         fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
00738         fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
00739         fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
00740         fill_gv_table(c->table_gV, 2, cgv);
00741         break;
00742     case 15:
00743     case 16:
00744         rbase = isRgb ? bpp - 5 : 0;
00745         gbase = 5;
00746         bbase = isRgb ? 0 : (bpp - 5);
00747         c->yuvTable = av_malloc(1024*3*2);
00748         y_table16 = c->yuvTable;
00749         yb = -(384<<16) - oy;
00750         for (i = 0; i < 1024; i++) {
00751             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00752             y_table16[i     ] = (yval >> 3)          << rbase;
00753             y_table16[i+1024] = (yval >> (18 - bpp)) << gbase;
00754             y_table16[i+2048] = (yval >> 3)          << bbase;
00755             yb += cy;
00756         }
00757         if(isNotNe)
00758             for (i = 0; i < 1024*3; i++)
00759                 y_table16[i] = av_bswap16(y_table16[i]);
00760         fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
00761         fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
00762         fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
00763         fill_gv_table(c->table_gV, 2, cgv);
00764         break;
00765     case 24:
00766     case 48:
00767         c->yuvTable = av_malloc(1024);
00768         y_table = c->yuvTable;
00769         yb = -(384<<16) - oy;
00770         for (i = 0; i < 1024; i++) {
00771             y_table[i] = av_clip_uint8((yb + 0x8000) >> 16);
00772             yb += cy;
00773         }
00774         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00775         fill_table(c->table_gU, 1, cgu, y_table + yoffs);
00776         fill_table(c->table_bU, 1, cbu, y_table + yoffs);
00777         fill_gv_table(c->table_gV, 1, cgv);
00778         break;
00779     case 32:
00780         base = (c->dstFormat == PIX_FMT_RGB32_1 || c->dstFormat == PIX_FMT_BGR32_1) ? 8 : 0;
00781         rbase = base + (isRgb ? 16 : 0);
00782         gbase = base + 8;
00783         bbase = base + (isRgb ? 0 : 16);
00784         needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
00785         if (!needAlpha)
00786             abase = (base + 24) & 31;
00787         c->yuvTable = av_malloc(1024*3*4);
00788         y_table32 = c->yuvTable;
00789         yb = -(384<<16) - oy;
00790         for (i = 0; i < 1024; i++) {
00791             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00792             y_table32[i     ] = (yval << rbase) + (needAlpha ? 0 : (255 << abase));
00793             y_table32[i+1024] = yval << gbase;
00794             y_table32[i+2048] = yval << bbase;
00795             yb += cy;
00796         }
00797         fill_table(c->table_rV, 4, crv, y_table32 + yoffs);
00798         fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + 1024);
00799         fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2048);
00800         fill_gv_table(c->table_gV, 4, cgv);
00801         break;
00802     default:
00803         c->yuvTable = NULL;
00804         av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
00805         return -1;
00806     }
00807     return 0;
00808 }