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 FFmpeg.
00010  *
00011  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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 #include "libavutil/pixdesc.h"
00038 
00039 extern const uint8_t dither_4x4_16[4][8];
00040 extern const uint8_t dither_8x8_32[8][8];
00041 extern const uint8_t dither_8x8_73[8][8];
00042 extern const uint8_t dither_8x8_220[8][8];
00043 
00044 const int32_t ff_yuv2rgb_coeffs[8][4] = {
00045     {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
00046     {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
00047     {104597, 132201, 25675, 53279}, /* unspecified */
00048     {104597, 132201, 25675, 53279}, /* reserved */
00049     {104448, 132798, 24759, 53109}, /* FCC */
00050     {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
00051     {104597, 132201, 25675, 53279}, /* SMPTE 170M */
00052     {117579, 136230, 16907, 35559}  /* SMPTE 240M (1987) */
00053 };
00054 
00055 const int *sws_getCoefficients(int colorspace)
00056 {
00057     if (colorspace > 7 || colorspace < 0)
00058         colorspace = SWS_CS_DEFAULT;
00059     return ff_yuv2rgb_coeffs[colorspace];
00060 }
00061 
00062 #define LOADCHROMA(i)                               \
00063     U = pu[i];                                      \
00064     V = pv[i];                                      \
00065     r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM];                     \
00066     g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] + c->table_gV[V+YUVRGB_TABLE_HEADROOM]);  \
00067     b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM];
00068 
00069 #define PUTRGB(dst,src,i)            \
00070     Y = src[2*i];                    \
00071     dst[2*i  ] = r[Y] + g[Y] + b[Y]; \
00072     Y = src[2*i+1];                  \
00073     dst[2*i+1] = r[Y] + g[Y] + b[Y];
00074 
00075 #define PUTRGB24(dst,src,i)                                  \
00076     Y = src[2*i];                                            \
00077     dst[6*i+0] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y]; \
00078     Y = src[2*i+1];                                          \
00079     dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y];
00080 
00081 #define PUTBGR24(dst,src,i)                                  \
00082     Y = src[2*i];                                            \
00083     dst[6*i+0] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y]; \
00084     Y = src[2*i+1];                                          \
00085     dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y];
00086 
00087 #define PUTRGBA(dst,ysrc,asrc,i,s)                      \
00088     Y = ysrc[2*i];                                      \
00089     dst[2*i  ] = r[Y] + g[Y] + b[Y] + (asrc[2*i  ]<<s); \
00090     Y = ysrc[2*i+1];                                    \
00091     dst[2*i+1] = r[Y] + g[Y] + b[Y] + (asrc[2*i+1]<<s);
00092 
00093 #define PUTRGB48(dst,src,i)             \
00094     Y = src[2*i];                       \
00095     dst[12*i+ 0] = dst[12*i+ 1] = r[Y]; \
00096     dst[12*i+ 2] = dst[12*i+ 3] = g[Y]; \
00097     dst[12*i+ 4] = dst[12*i+ 5] = b[Y]; \
00098     Y = src[2*i+1];                     \
00099     dst[12*i+ 6] = dst[12*i+ 7] = r[Y]; \
00100     dst[12*i+ 8] = dst[12*i+ 9] = g[Y]; \
00101     dst[12*i+10] = dst[12*i+11] = b[Y];
00102 
00103 #define PUTBGR48(dst,src,i)             \
00104     Y = src[2*i];                       \
00105     dst[12*i+ 0] = dst[12*i+ 1] = b[Y]; \
00106     dst[12*i+ 2] = dst[12*i+ 3] = g[Y]; \
00107     dst[12*i+ 4] = dst[12*i+ 5] = r[Y]; \
00108     Y = src[2*i+1];                     \
00109     dst[12*i+ 6] = dst[12*i+ 7] = b[Y]; \
00110     dst[12*i+ 8] = dst[12*i+ 9] = g[Y]; \
00111     dst[12*i+10] = dst[12*i+11] = r[Y];
00112 
00113 #define YUV2RGBFUNC(func_name, dst_type, alpha) \
00114 static int func_name(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, \
00115                      int srcSliceH, uint8_t* dst[], int dstStride[]) \
00116 {\
00117     int y;\
00118 \
00119     if (!alpha && c->srcFormat == PIX_FMT_YUV422P) {\
00120         srcStride[1] *= 2;\
00121         srcStride[2] *= 2;\
00122     }\
00123     for (y=0; y<srcSliceH; y+=2) {\
00124         dst_type *dst_1 = (dst_type*)(dst[0] + (y+srcSliceY  )*dstStride[0]);\
00125         dst_type *dst_2 = (dst_type*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);\
00126         dst_type av_unused *r, *b;\
00127         dst_type *g;\
00128         const uint8_t *py_1 = src[0] + y*srcStride[0];\
00129         const uint8_t *py_2 = py_1 + srcStride[0];\
00130         const uint8_t *pu = src[1] + (y>>1)*srcStride[1];\
00131         const uint8_t *pv = src[2] + (y>>1)*srcStride[2];\
00132         const uint8_t av_unused *pa_1, *pa_2;\
00133         unsigned int h_size = c->dstW>>3;\
00134         if (alpha) {\
00135             pa_1 = src[3] + y*srcStride[3];\
00136             pa_2 = pa_1 + srcStride[3];\
00137         }\
00138         while (h_size--) {\
00139             int av_unused U, V;\
00140             int Y;\
00141 
00142 #define ENDYUV2RGBLINE(dst_delta)\
00143             pu += 4;\
00144             pv += 4;\
00145             py_1 += 8;\
00146             py_2 += 8;\
00147             dst_1 += dst_delta;\
00148             dst_2 += dst_delta;\
00149         }\
00150         if (c->dstW & 4) {\
00151             int av_unused Y, U, V;\
00152 
00153 #define ENDYUV2RGBFUNC()\
00154         }\
00155     }\
00156     return srcSliceH;\
00157 }
00158 
00159 #define CLOSEYUV2RGBFUNC(dst_delta)\
00160     ENDYUV2RGBLINE(dst_delta)\
00161     ENDYUV2RGBFUNC()
00162 
00163 YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
00164     LOADCHROMA(0);
00165     PUTRGB48(dst_1,py_1,0);
00166     PUTRGB48(dst_2,py_2,0);
00167 
00168     LOADCHROMA(1);
00169     PUTRGB48(dst_2,py_2,1);
00170     PUTRGB48(dst_1,py_1,1);
00171 
00172     LOADCHROMA(2);
00173     PUTRGB48(dst_1,py_1,2);
00174     PUTRGB48(dst_2,py_2,2);
00175 
00176     LOADCHROMA(3);
00177     PUTRGB48(dst_2,py_2,3);
00178     PUTRGB48(dst_1,py_1,3);
00179 ENDYUV2RGBLINE(48)
00180     LOADCHROMA(0);
00181     PUTRGB48(dst_1,py_1,0);
00182     PUTRGB48(dst_2,py_2,0);
00183 
00184     LOADCHROMA(1);
00185     PUTRGB48(dst_2,py_2,1);
00186     PUTRGB48(dst_1,py_1,1);
00187 ENDYUV2RGBFUNC()
00188 
00189 YUV2RGBFUNC(yuv2rgb_c_bgr48, uint8_t, 0)
00190     LOADCHROMA(0);
00191     PUTBGR48(dst_1,py_1,0);
00192     PUTBGR48(dst_2,py_2,0);
00193 
00194     LOADCHROMA(1);
00195     PUTBGR48(dst_2,py_2,1);
00196     PUTBGR48(dst_1,py_1,1);
00197 
00198     LOADCHROMA(2);
00199     PUTBGR48(dst_1,py_1,2);
00200     PUTBGR48(dst_2,py_2,2);
00201 
00202     LOADCHROMA(3);
00203     PUTBGR48(dst_2,py_2,3);
00204     PUTBGR48(dst_1,py_1,3);
00205 ENDYUV2RGBLINE(48)
00206     LOADCHROMA(0);
00207     PUTBGR48(dst_1,py_1,0);
00208     PUTBGR48(dst_2,py_2,0);
00209 
00210     LOADCHROMA(1);
00211     PUTBGR48(dst_2,py_2,1);
00212     PUTBGR48(dst_1,py_1,1);
00213 ENDYUV2RGBFUNC()
00214 
00215 YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
00216     LOADCHROMA(0);
00217     PUTRGB(dst_1,py_1,0);
00218     PUTRGB(dst_2,py_2,0);
00219 
00220     LOADCHROMA(1);
00221     PUTRGB(dst_2,py_2,1);
00222     PUTRGB(dst_1,py_1,1);
00223 
00224     LOADCHROMA(2);
00225     PUTRGB(dst_1,py_1,2);
00226     PUTRGB(dst_2,py_2,2);
00227 
00228     LOADCHROMA(3);
00229     PUTRGB(dst_2,py_2,3);
00230     PUTRGB(dst_1,py_1,3);
00231 ENDYUV2RGBLINE(8)
00232     LOADCHROMA(0);
00233     PUTRGB(dst_1,py_1,0);
00234     PUTRGB(dst_2,py_2,0);
00235 
00236     LOADCHROMA(1);
00237     PUTRGB(dst_2,py_2,1);
00238     PUTRGB(dst_1,py_1,1);
00239 ENDYUV2RGBFUNC()
00240 
00241 YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
00242     LOADCHROMA(0);
00243     PUTRGBA(dst_1,py_1,pa_1,0,24);
00244     PUTRGBA(dst_2,py_2,pa_2,0,24);
00245 
00246     LOADCHROMA(1);
00247     PUTRGBA(dst_2,py_2,pa_1,1,24);
00248     PUTRGBA(dst_1,py_1,pa_2,1,24);
00249 
00250     LOADCHROMA(2);
00251     PUTRGBA(dst_1,py_1,pa_1,2,24);
00252     PUTRGBA(dst_2,py_2,pa_2,2,24);
00253 
00254     LOADCHROMA(3);
00255     PUTRGBA(dst_2,py_2,pa_1,3,24);
00256     PUTRGBA(dst_1,py_1,pa_2,3,24);
00257     pa_1 += 8;\
00258     pa_2 += 8;\
00259 ENDYUV2RGBLINE(8)
00260     LOADCHROMA(0);
00261     PUTRGBA(dst_1,py_1,pa_1,0,24);
00262     PUTRGBA(dst_2,py_2,pa_2,0,24);
00263 
00264     LOADCHROMA(1);
00265     PUTRGBA(dst_2,py_2,pa_1,1,24);
00266     PUTRGBA(dst_1,py_1,pa_2,1,24);
00267 ENDYUV2RGBFUNC()
00268 
00269 YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
00270     LOADCHROMA(0);
00271     PUTRGBA(dst_1,py_1,pa_1,0,0);
00272     PUTRGBA(dst_2,py_2,pa_2,0,0);
00273 
00274     LOADCHROMA(1);
00275     PUTRGBA(dst_2,py_2,pa_2,1,0);
00276     PUTRGBA(dst_1,py_1,pa_1,1,0);
00277 
00278     LOADCHROMA(2);
00279     PUTRGBA(dst_1,py_1,pa_1,2,0);
00280     PUTRGBA(dst_2,py_2,pa_2,2,0);
00281 
00282     LOADCHROMA(3);
00283     PUTRGBA(dst_2,py_2,pa_2,3,0);
00284     PUTRGBA(dst_1,py_1,pa_1,3,0);
00285     pa_1 += 8;\
00286     pa_2 += 8;\
00287 ENDYUV2RGBLINE(8)
00288     LOADCHROMA(0);
00289     PUTRGBA(dst_1,py_1,pa_1,0,0);
00290     PUTRGBA(dst_2,py_2,pa_2,0,0);
00291 
00292     LOADCHROMA(1);
00293     PUTRGBA(dst_2,py_2,pa_2,1,0);
00294     PUTRGBA(dst_1,py_1,pa_1,1,0);
00295 ENDYUV2RGBFUNC()
00296 
00297 YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0)
00298     LOADCHROMA(0);
00299     PUTRGB24(dst_1,py_1,0);
00300     PUTRGB24(dst_2,py_2,0);
00301 
00302     LOADCHROMA(1);
00303     PUTRGB24(dst_2,py_2,1);
00304     PUTRGB24(dst_1,py_1,1);
00305 
00306     LOADCHROMA(2);
00307     PUTRGB24(dst_1,py_1,2);
00308     PUTRGB24(dst_2,py_2,2);
00309 
00310     LOADCHROMA(3);
00311     PUTRGB24(dst_2,py_2,3);
00312     PUTRGB24(dst_1,py_1,3);
00313 ENDYUV2RGBLINE(24)
00314     LOADCHROMA(0);
00315     PUTRGB24(dst_1,py_1,0);
00316     PUTRGB24(dst_2,py_2,0);
00317 
00318     LOADCHROMA(1);
00319     PUTRGB24(dst_2,py_2,1);
00320     PUTRGB24(dst_1,py_1,1);
00321 ENDYUV2RGBFUNC()
00322 
00323 // only trivial mods from yuv2rgb_c_24_rgb
00324 YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0)
00325     LOADCHROMA(0);
00326     PUTBGR24(dst_1,py_1,0);
00327     PUTBGR24(dst_2,py_2,0);
00328 
00329     LOADCHROMA(1);
00330     PUTBGR24(dst_2,py_2,1);
00331     PUTBGR24(dst_1,py_1,1);
00332 
00333     LOADCHROMA(2);
00334     PUTBGR24(dst_1,py_1,2);
00335     PUTBGR24(dst_2,py_2,2);
00336 
00337     LOADCHROMA(3);
00338     PUTBGR24(dst_2,py_2,3);
00339     PUTBGR24(dst_1,py_1,3);
00340 ENDYUV2RGBLINE(24)
00341     LOADCHROMA(0);
00342     PUTBGR24(dst_1,py_1,0);
00343     PUTBGR24(dst_2,py_2,0);
00344 
00345     LOADCHROMA(1);
00346     PUTBGR24(dst_2,py_2,1);
00347     PUTBGR24(dst_1,py_1,1);
00348 ENDYUV2RGBFUNC()
00349 
00350 // This is exactly the same code as yuv2rgb_c_32 except for the types of
00351 // r, g, b, dst_1, dst_2
00352 YUV2RGBFUNC(yuv2rgb_c_16, uint16_t, 0)
00353     LOADCHROMA(0);
00354     PUTRGB(dst_1,py_1,0);
00355     PUTRGB(dst_2,py_2,0);
00356 
00357     LOADCHROMA(1);
00358     PUTRGB(dst_2,py_2,1);
00359     PUTRGB(dst_1,py_1,1);
00360 
00361     LOADCHROMA(2);
00362     PUTRGB(dst_1,py_1,2);
00363     PUTRGB(dst_2,py_2,2);
00364 
00365     LOADCHROMA(3);
00366     PUTRGB(dst_2,py_2,3);
00367     PUTRGB(dst_1,py_1,3);
00368 CLOSEYUV2RGBFUNC(8)
00369 
00370 // r, g, b, dst_1, dst_2
00371 YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
00372     const uint8_t *d16 = dither_4x4_16[y&3];
00373 #define PUTRGB12(dst,src,i,o)                                   \
00374     Y = src[2*i];                                               \
00375     dst[2*i]   = r[Y+d16[0+o]] + g[Y+d16[0+o]] + b[Y+d16[0+o]]; \
00376     Y = src[2*i+1];                                             \
00377     dst[2*i+1] = r[Y+d16[1+o]] + g[Y+d16[1+o]] + b[Y+d16[1+o]];
00378 
00379     LOADCHROMA(0);
00380     PUTRGB12(dst_1,py_1,0,0);
00381     PUTRGB12(dst_2,py_2,0,0+8);
00382 
00383     LOADCHROMA(1);
00384     PUTRGB12(dst_2,py_2,1,2+8);
00385     PUTRGB12(dst_1,py_1,1,2);
00386 
00387     LOADCHROMA(2);
00388     PUTRGB12(dst_1,py_1,2,4);
00389     PUTRGB12(dst_2,py_2,2,4+8);
00390 
00391     LOADCHROMA(3);
00392     PUTRGB12(dst_2,py_2,3,6+8);
00393     PUTRGB12(dst_1,py_1,3,6);
00394 CLOSEYUV2RGBFUNC(8)
00395 
00396 // r, g, b, dst_1, dst_2
00397 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
00398     const uint8_t *d32 = dither_8x8_32[y&7];
00399     const uint8_t *d64 = dither_8x8_73[y&7];
00400 #define PUTRGB8(dst,src,i,o)                                    \
00401     Y = src[2*i];                                               \
00402     dst[2*i]   = r[Y+d32[0+o]] + g[Y+d32[0+o]] + b[Y+d64[0+o]]; \
00403     Y = src[2*i+1];                                             \
00404     dst[2*i+1] = r[Y+d32[1+o]] + g[Y+d32[1+o]] + b[Y+d64[1+o]];
00405 
00406     LOADCHROMA(0);
00407     PUTRGB8(dst_1,py_1,0,0);
00408     PUTRGB8(dst_2,py_2,0,0+8);
00409 
00410     LOADCHROMA(1);
00411     PUTRGB8(dst_2,py_2,1,2+8);
00412     PUTRGB8(dst_1,py_1,1,2);
00413 
00414     LOADCHROMA(2);
00415     PUTRGB8(dst_1,py_1,2,4);
00416     PUTRGB8(dst_2,py_2,2,4+8);
00417 
00418     LOADCHROMA(3);
00419     PUTRGB8(dst_2,py_2,3,6+8);
00420     PUTRGB8(dst_1,py_1,3,6);
00421 CLOSEYUV2RGBFUNC(8)
00422 
00423 YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
00424     const uint8_t *d64 =  dither_8x8_73[y&7];
00425     const uint8_t *d128 = dither_8x8_220[y&7];
00426     int acc;
00427 
00428 #define PUTRGB4D(dst,src,i,o)                                     \
00429     Y = src[2*i];                                                 \
00430     acc = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]];        \
00431     Y = src[2*i+1];                                               \
00432     acc |= (r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]])<<4;  \
00433     dst[i]= acc;
00434 
00435     LOADCHROMA(0);
00436     PUTRGB4D(dst_1,py_1,0,0);
00437     PUTRGB4D(dst_2,py_2,0,0+8);
00438 
00439     LOADCHROMA(1);
00440     PUTRGB4D(dst_2,py_2,1,2+8);
00441     PUTRGB4D(dst_1,py_1,1,2);
00442 
00443     LOADCHROMA(2);
00444     PUTRGB4D(dst_1,py_1,2,4);
00445     PUTRGB4D(dst_2,py_2,2,4+8);
00446 
00447     LOADCHROMA(3);
00448     PUTRGB4D(dst_2,py_2,3,6+8);
00449     PUTRGB4D(dst_1,py_1,3,6);
00450 CLOSEYUV2RGBFUNC(4)
00451 
00452 YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
00453     const uint8_t *d64 =  dither_8x8_73[y&7];
00454     const uint8_t *d128 = dither_8x8_220[y&7];
00455 
00456 #define PUTRGB4DB(dst,src,i,o)                                    \
00457     Y = src[2*i];                                                 \
00458     dst[2*i]   = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \
00459     Y = src[2*i+1];                                               \
00460     dst[2*i+1] = r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]];
00461 
00462     LOADCHROMA(0);
00463     PUTRGB4DB(dst_1,py_1,0,0);
00464     PUTRGB4DB(dst_2,py_2,0,0+8);
00465 
00466     LOADCHROMA(1);
00467     PUTRGB4DB(dst_2,py_2,1,2+8);
00468     PUTRGB4DB(dst_1,py_1,1,2);
00469 
00470     LOADCHROMA(2);
00471     PUTRGB4DB(dst_1,py_1,2,4);
00472     PUTRGB4DB(dst_2,py_2,2,4+8);
00473 
00474     LOADCHROMA(3);
00475     PUTRGB4DB(dst_2,py_2,3,6+8);
00476     PUTRGB4DB(dst_1,py_1,3,6);
00477 CLOSEYUV2RGBFUNC(8)
00478 
00479 YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
00480         const uint8_t *d128 = dither_8x8_220[y&7];
00481         char out_1 = 0, out_2 = 0;
00482         g= c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
00483 
00484 #define PUTRGB1(out,src,i,o)    \
00485     Y = src[2*i];               \
00486     out+= out + g[Y+d128[0+o]]; \
00487     Y = src[2*i+1];             \
00488     out+= out + g[Y+d128[1+o]];
00489 
00490     PUTRGB1(out_1,py_1,0,0);
00491     PUTRGB1(out_2,py_2,0,0+8);
00492 
00493     PUTRGB1(out_2,py_2,1,2+8);
00494     PUTRGB1(out_1,py_1,1,2);
00495 
00496     PUTRGB1(out_1,py_1,2,4);
00497     PUTRGB1(out_2,py_2,2,4+8);
00498 
00499     PUTRGB1(out_2,py_2,3,6+8);
00500     PUTRGB1(out_1,py_1,3,6);
00501 
00502     dst_1[0]= out_1;
00503     dst_2[0]= out_2;
00504 CLOSEYUV2RGBFUNC(1)
00505 
00506 SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
00507 {
00508     SwsFunc t = NULL;
00509 
00510     if (HAVE_MMX) {
00511         t = ff_yuv2rgb_init_mmx(c);
00512     } else if (HAVE_VIS) {
00513         t = ff_yuv2rgb_init_vis(c);
00514     } else if (CONFIG_MLIB) {
00515         t = ff_yuv2rgb_init_mlib(c);
00516     } else if (HAVE_ALTIVEC) {
00517         t = ff_yuv2rgb_init_altivec(c);
00518     } else if (ARCH_BFIN) {
00519         t = ff_yuv2rgb_get_func_ptr_bfin(c);
00520     }
00521 
00522     if (t)
00523         return t;
00524 
00525     av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found from %s to %s.\n",
00526            av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
00527 
00528     switch (c->dstFormat) {
00529     case PIX_FMT_BGR48BE:
00530     case PIX_FMT_BGR48LE:    return yuv2rgb_c_bgr48;
00531     case PIX_FMT_RGB48BE:
00532     case PIX_FMT_RGB48LE:    return yuv2rgb_c_48;
00533     case PIX_FMT_ARGB:
00534     case PIX_FMT_ABGR:       if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) return yuva2argb_c;
00535     case PIX_FMT_RGBA:
00536     case PIX_FMT_BGRA:       return (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) ? yuva2rgba_c : yuv2rgb_c_32;
00537     case PIX_FMT_RGB24:      return yuv2rgb_c_24_rgb;
00538     case PIX_FMT_BGR24:      return yuv2rgb_c_24_bgr;
00539     case PIX_FMT_RGB565:
00540     case PIX_FMT_BGR565:
00541     case PIX_FMT_RGB555:
00542     case PIX_FMT_BGR555:     return yuv2rgb_c_16;
00543     case PIX_FMT_RGB444:
00544     case PIX_FMT_BGR444:     return yuv2rgb_c_12_ordered_dither;
00545     case PIX_FMT_RGB8:
00546     case PIX_FMT_BGR8:       return yuv2rgb_c_8_ordered_dither;
00547     case PIX_FMT_RGB4:
00548     case PIX_FMT_BGR4:       return yuv2rgb_c_4_ordered_dither;
00549     case PIX_FMT_RGB4_BYTE:
00550     case PIX_FMT_BGR4_BYTE:  return yuv2rgb_c_4b_ordered_dither;
00551     case PIX_FMT_MONOBLACK:  return yuv2rgb_c_1_ordered_dither;
00552     default:
00553         assert(0);
00554     }
00555     return NULL;
00556 }
00557 
00558 static void fill_table(uint8_t* table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize, const int inc, void *y_tab)
00559 {
00560     int i;
00561     uint8_t *y_table = y_tab;
00562 
00563     y_table -= elemsize * (inc >> 9);
00564 
00565     for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
00566         int64_t cb = av_clip(i-YUVRGB_TABLE_HEADROOM, 0, 255)*inc;
00567         table[i] = y_table + elemsize * (cb >> 16);
00568     }
00569 }
00570 
00571 static void fill_gv_table(int table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize, const int inc)
00572 {
00573     int i;
00574     int off = -(inc >> 9);
00575 
00576     for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
00577         int64_t cb = av_clip(i-YUVRGB_TABLE_HEADROOM, 0, 255)*inc;
00578         table[i] = elemsize * (off + (cb >> 16));
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, av_uninit(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             unsigned yval = av_clip_uint8((yb + 0x8000) >> 16);
00792             y_table32[i     ] = (yval << rbase) + (needAlpha ? 0 : (255u << 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 }