• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

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];                     \
00066     g = (void *)(c->table_gU[U] + c->table_gV[V]);  \
00067     b = (void *)c->table_bU[U];
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] + c->table_gV[128];
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], const int elemsize, const int inc, void *y_tab)
00559 {
00560     int i;
00561     int64_t cb = 0;
00562     uint8_t *y_table = y_tab;
00563 
00564     y_table -= elemsize * (inc >> 9);
00565 
00566     for (i = 0; i < 256; i++) {
00567         table[i] = y_table + elemsize * (cb >> 16);
00568         cb += inc;
00569     }
00570 }
00571 
00572 static void fill_gv_table(int table[256], const int elemsize, const int inc)
00573 {
00574     int i;
00575     int64_t cb = 0;
00576     int off = -(inc >> 9);
00577 
00578     for (i = 0; i < 256; i++) {
00579         table[i] = elemsize * (off + (cb >> 16));
00580         cb += inc;
00581     }
00582 }
00583 
00584 static uint16_t roundToInt16(int64_t f)
00585 {
00586     int r= (f + (1<<15))>>16;
00587          if (r<-0x7FFF) return 0x8000;
00588     else if (r> 0x7FFF) return 0x7FFF;
00589     else                return r;
00590 }
00591 
00592 av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange,
00593                                      int brightness, int contrast, int saturation)
00594 {
00595     const int isRgb =      c->dstFormat==PIX_FMT_RGB32
00596                         || c->dstFormat==PIX_FMT_RGB32_1
00597                         || c->dstFormat==PIX_FMT_BGR24
00598                         || c->dstFormat==PIX_FMT_RGB565BE
00599                         || c->dstFormat==PIX_FMT_RGB565LE
00600                         || c->dstFormat==PIX_FMT_RGB555BE
00601                         || c->dstFormat==PIX_FMT_RGB555LE
00602                         || c->dstFormat==PIX_FMT_RGB444BE
00603                         || c->dstFormat==PIX_FMT_RGB444LE
00604                         || c->dstFormat==PIX_FMT_RGB8
00605                         || c->dstFormat==PIX_FMT_RGB4
00606                         || c->dstFormat==PIX_FMT_RGB4_BYTE
00607                         || c->dstFormat==PIX_FMT_MONOBLACK;
00608     const int isNotNe =    c->dstFormat==PIX_FMT_NE(RGB565LE,RGB565BE)
00609                         || c->dstFormat==PIX_FMT_NE(RGB555LE,RGB555BE)
00610                         || c->dstFormat==PIX_FMT_NE(RGB444LE,RGB444BE)
00611                         || c->dstFormat==PIX_FMT_NE(BGR565LE,BGR565BE)
00612                         || c->dstFormat==PIX_FMT_NE(BGR555LE,BGR555BE)
00613                         || c->dstFormat==PIX_FMT_NE(BGR444LE,BGR444BE);
00614     const int bpp = c->dstFormatBpp;
00615     uint8_t *y_table;
00616     uint16_t *y_table16;
00617     uint32_t *y_table32;
00618     int i, base, rbase, gbase, bbase, abase, needAlpha;
00619     const int yoffs = fullRange ? 384 : 326;
00620 
00621     int64_t crv =  inv_table[0];
00622     int64_t cbu =  inv_table[1];
00623     int64_t cgu = -inv_table[2];
00624     int64_t cgv = -inv_table[3];
00625     int64_t cy  = 1<<16;
00626     int64_t oy  = 0;
00627 
00628     int64_t yb = 0;
00629 
00630     if (!fullRange) {
00631         cy = (cy*255) / 219;
00632         oy = 16<<16;
00633     } else {
00634         crv = (crv*224) / 255;
00635         cbu = (cbu*224) / 255;
00636         cgu = (cgu*224) / 255;
00637         cgv = (cgv*224) / 255;
00638     }
00639 
00640     cy  = (cy *contrast             ) >> 16;
00641     crv = (crv*contrast * saturation) >> 32;
00642     cbu = (cbu*contrast * saturation) >> 32;
00643     cgu = (cgu*contrast * saturation) >> 32;
00644     cgv = (cgv*contrast * saturation) >> 32;
00645     oy -= 256*brightness;
00646 
00647     c->uOffset=   0x0400040004000400LL;
00648     c->vOffset=   0x0400040004000400LL;
00649     c->yCoeff=    roundToInt16(cy *8192) * 0x0001000100010001ULL;
00650     c->vrCoeff=   roundToInt16(crv*8192) * 0x0001000100010001ULL;
00651     c->ubCoeff=   roundToInt16(cbu*8192) * 0x0001000100010001ULL;
00652     c->vgCoeff=   roundToInt16(cgv*8192) * 0x0001000100010001ULL;
00653     c->ugCoeff=   roundToInt16(cgu*8192) * 0x0001000100010001ULL;
00654     c->yOffset=   roundToInt16(oy *   8) * 0x0001000100010001ULL;
00655 
00656     c->yuv2rgb_y_coeff  = (int16_t)roundToInt16(cy <<13);
00657     c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9);
00658     c->yuv2rgb_v2r_coeff= (int16_t)roundToInt16(crv<<13);
00659     c->yuv2rgb_v2g_coeff= (int16_t)roundToInt16(cgv<<13);
00660     c->yuv2rgb_u2g_coeff= (int16_t)roundToInt16(cgu<<13);
00661     c->yuv2rgb_u2b_coeff= (int16_t)roundToInt16(cbu<<13);
00662 
00663     //scale coefficients by cy
00664     crv = ((crv << 16) + 0x8000) / cy;
00665     cbu = ((cbu << 16) + 0x8000) / cy;
00666     cgu = ((cgu << 16) + 0x8000) / cy;
00667     cgv = ((cgv << 16) + 0x8000) / cy;
00668 
00669     av_free(c->yuvTable);
00670 
00671     switch (bpp) {
00672     case 1:
00673         c->yuvTable = av_malloc(1024);
00674         y_table = c->yuvTable;
00675         yb = -(384<<16) - oy;
00676         for (i = 0; i < 1024-110; i++) {
00677             y_table[i+110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7;
00678             yb += cy;
00679         }
00680         fill_table(c->table_gU, 1, cgu, y_table + yoffs);
00681         fill_gv_table(c->table_gV, 1, cgv);
00682         break;
00683     case 4:
00684     case 4|128:
00685         rbase = isRgb ? 3 : 0;
00686         gbase = 1;
00687         bbase = isRgb ? 0 : 3;
00688         c->yuvTable = av_malloc(1024*3);
00689         y_table = c->yuvTable;
00690         yb = -(384<<16) - oy;
00691         for (i = 0; i < 1024-110; i++) {
00692             int yval = av_clip_uint8((yb + 0x8000) >> 16);
00693             y_table[i+110     ] =  (yval >> 7)       << rbase;
00694             y_table[i+ 37+1024] = ((yval + 43) / 85) << gbase;
00695             y_table[i+110+2048] =  (yval >> 7)       << bbase;
00696             yb += cy;
00697         }
00698         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00699         fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
00700         fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
00701         fill_gv_table(c->table_gV, 1, cgv);
00702         break;
00703     case 8:
00704         rbase = isRgb ? 5 : 0;
00705         gbase = isRgb ? 2 : 3;
00706         bbase = isRgb ? 0 : 6;
00707         c->yuvTable = av_malloc(1024*3);
00708         y_table = c->yuvTable;
00709         yb = -(384<<16) - oy;
00710         for (i = 0; i < 1024-38; i++) {
00711             int yval = av_clip_uint8((yb + 0x8000) >> 16);
00712             y_table[i+16     ] = ((yval + 18) / 36) << rbase;
00713             y_table[i+16+1024] = ((yval + 18) / 36) << gbase;
00714             y_table[i+37+2048] = ((yval + 43) / 85) << bbase;
00715             yb += cy;
00716         }
00717         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00718         fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
00719         fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
00720         fill_gv_table(c->table_gV, 1, cgv);
00721         break;
00722     case 12:
00723         rbase = isRgb ? 8 : 0;
00724         gbase = 4;
00725         bbase = isRgb ? 0 : 8;
00726         c->yuvTable = av_malloc(1024*3*2);
00727         y_table16 = c->yuvTable;
00728         yb = -(384<<16) - oy;
00729         for (i = 0; i < 1024; i++) {
00730             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00731             y_table16[i     ] = (yval >> 4) << rbase;
00732             y_table16[i+1024] = (yval >> 4) << gbase;
00733             y_table16[i+2048] = (yval >> 4) << bbase;
00734             yb += cy;
00735         }
00736         if (isNotNe)
00737             for (i = 0; i < 1024*3; i++)
00738                 y_table16[i] = av_bswap16(y_table16[i]);
00739         fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
00740         fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
00741         fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
00742         fill_gv_table(c->table_gV, 2, cgv);
00743         break;
00744     case 15:
00745     case 16:
00746         rbase = isRgb ? bpp - 5 : 0;
00747         gbase = 5;
00748         bbase = isRgb ? 0 : (bpp - 5);
00749         c->yuvTable = av_malloc(1024*3*2);
00750         y_table16 = c->yuvTable;
00751         yb = -(384<<16) - oy;
00752         for (i = 0; i < 1024; i++) {
00753             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00754             y_table16[i     ] = (yval >> 3)          << rbase;
00755             y_table16[i+1024] = (yval >> (18 - bpp)) << gbase;
00756             y_table16[i+2048] = (yval >> 3)          << bbase;
00757             yb += cy;
00758         }
00759         if(isNotNe)
00760             for (i = 0; i < 1024*3; i++)
00761                 y_table16[i] = av_bswap16(y_table16[i]);
00762         fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
00763         fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
00764         fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
00765         fill_gv_table(c->table_gV, 2, cgv);
00766         break;
00767     case 24:
00768     case 48:
00769         c->yuvTable = av_malloc(1024);
00770         y_table = c->yuvTable;
00771         yb = -(384<<16) - oy;
00772         for (i = 0; i < 1024; i++) {
00773             y_table[i] = av_clip_uint8((yb + 0x8000) >> 16);
00774             yb += cy;
00775         }
00776         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00777         fill_table(c->table_gU, 1, cgu, y_table + yoffs);
00778         fill_table(c->table_bU, 1, cbu, y_table + yoffs);
00779         fill_gv_table(c->table_gV, 1, cgv);
00780         break;
00781     case 32:
00782         base = (c->dstFormat == PIX_FMT_RGB32_1 || c->dstFormat == PIX_FMT_BGR32_1) ? 8 : 0;
00783         rbase = base + (isRgb ? 16 : 0);
00784         gbase = base + 8;
00785         bbase = base + (isRgb ? 0 : 16);
00786         needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
00787         if (!needAlpha)
00788             abase = (base + 24) & 31;
00789         c->yuvTable = av_malloc(1024*3*4);
00790         y_table32 = c->yuvTable;
00791         yb = -(384<<16) - oy;
00792         for (i = 0; i < 1024; i++) {
00793             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00794             y_table32[i     ] = (yval << rbase) + (needAlpha ? 0 : (255 << abase));
00795             y_table32[i+1024] = yval << gbase;
00796             y_table32[i+2048] = yval << bbase;
00797             yb += cy;
00798         }
00799         fill_table(c->table_rV, 4, crv, y_table32 + yoffs);
00800         fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + 1024);
00801         fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2048);
00802         fill_gv_table(c->table_gV, 4, cgv);
00803         break;
00804     default:
00805         c->yuvTable = NULL;
00806         av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
00807         return -1;
00808     }
00809     return 0;
00810 }

Generated on Wed Apr 11 2012 07:31:37 for FFmpeg by  doxygen 1.7.1