• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • 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/x86_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 YUV2RGBFUNC(func_name, dst_type, alpha) \
00103 static int func_name(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, \
00104                      int srcSliceH, uint8_t* dst[], int dstStride[]) \
00105 {\
00106     int y;\
00107 \
00108     if (!alpha && c->srcFormat == PIX_FMT_YUV422P) {\
00109         srcStride[1] *= 2;\
00110         srcStride[2] *= 2;\
00111     }\
00112     for (y=0; y<srcSliceH; y+=2) {\
00113         dst_type *dst_1 = (dst_type*)(dst[0] + (y+srcSliceY  )*dstStride[0]);\
00114         dst_type *dst_2 = (dst_type*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);\
00115         dst_type av_unused *r, *b;\
00116         dst_type *g;\
00117         const uint8_t *py_1 = src[0] + y*srcStride[0];\
00118         const uint8_t *py_2 = py_1 + srcStride[0];\
00119         const uint8_t *pu = src[1] + (y>>1)*srcStride[1];\
00120         const uint8_t *pv = src[2] + (y>>1)*srcStride[2];\
00121         const uint8_t av_unused *pa_1, *pa_2;\
00122         unsigned int h_size = c->dstW>>3;\
00123         if (alpha) {\
00124             pa_1 = src[3] + y*srcStride[3];\
00125             pa_2 = pa_1 + srcStride[3];\
00126         }\
00127         while (h_size--) {\
00128             int av_unused U, V;\
00129             int Y;\
00130 
00131 #define ENDYUV2RGBLINE(dst_delta)\
00132             pu += 4;\
00133             pv += 4;\
00134             py_1 += 8;\
00135             py_2 += 8;\
00136             dst_1 += dst_delta;\
00137             dst_2 += dst_delta;\
00138         }\
00139         if (c->dstW & 4) {\
00140             int av_unused Y, U, V;\
00141 
00142 #define ENDYUV2RGBFUNC()\
00143         }\
00144     }\
00145     return srcSliceH;\
00146 }
00147 
00148 #define CLOSEYUV2RGBFUNC(dst_delta)\
00149     ENDYUV2RGBLINE(dst_delta)\
00150     ENDYUV2RGBFUNC()
00151 
00152 YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
00153     LOADCHROMA(0);
00154     PUTRGB48(dst_1,py_1,0);
00155     PUTRGB48(dst_2,py_2,0);
00156 
00157     LOADCHROMA(1);
00158     PUTRGB48(dst_2,py_2,1);
00159     PUTRGB48(dst_1,py_1,1);
00160 
00161     LOADCHROMA(2);
00162     PUTRGB48(dst_1,py_1,2);
00163     PUTRGB48(dst_2,py_2,2);
00164 
00165     LOADCHROMA(3);
00166     PUTRGB48(dst_2,py_2,3);
00167     PUTRGB48(dst_1,py_1,3);
00168 ENDYUV2RGBLINE(48)
00169     LOADCHROMA(0);
00170     PUTRGB48(dst_1,py_1,0);
00171     PUTRGB48(dst_2,py_2,0);
00172 
00173     LOADCHROMA(1);
00174     PUTRGB48(dst_2,py_2,1);
00175     PUTRGB48(dst_1,py_1,1);
00176 ENDYUV2RGBFUNC()
00177 
00178 YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
00179     LOADCHROMA(0);
00180     PUTRGB(dst_1,py_1,0);
00181     PUTRGB(dst_2,py_2,0);
00182 
00183     LOADCHROMA(1);
00184     PUTRGB(dst_2,py_2,1);
00185     PUTRGB(dst_1,py_1,1);
00186 
00187     LOADCHROMA(2);
00188     PUTRGB(dst_1,py_1,2);
00189     PUTRGB(dst_2,py_2,2);
00190 
00191     LOADCHROMA(3);
00192     PUTRGB(dst_2,py_2,3);
00193     PUTRGB(dst_1,py_1,3);
00194 ENDYUV2RGBLINE(8)
00195     LOADCHROMA(0);
00196     PUTRGB(dst_1,py_1,0);
00197     PUTRGB(dst_2,py_2,0);
00198 
00199     LOADCHROMA(1);
00200     PUTRGB(dst_2,py_2,1);
00201     PUTRGB(dst_1,py_1,1);
00202 ENDYUV2RGBFUNC()
00203 
00204 YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
00205     LOADCHROMA(0);
00206     PUTRGBA(dst_1,py_1,pa_1,0,24);
00207     PUTRGBA(dst_2,py_2,pa_2,0,24);
00208 
00209     LOADCHROMA(1);
00210     PUTRGBA(dst_2,py_2,pa_1,1,24);
00211     PUTRGBA(dst_1,py_1,pa_2,1,24);
00212 
00213     LOADCHROMA(2);
00214     PUTRGBA(dst_1,py_1,pa_1,2,24);
00215     PUTRGBA(dst_2,py_2,pa_2,2,24);
00216 
00217     LOADCHROMA(3);
00218     PUTRGBA(dst_2,py_2,pa_1,3,24);
00219     PUTRGBA(dst_1,py_1,pa_2,3,24);
00220     pa_1 += 8;\
00221     pa_2 += 8;\
00222 ENDYUV2RGBLINE(8)
00223     LOADCHROMA(0);
00224     PUTRGBA(dst_1,py_1,pa_1,0,24);
00225     PUTRGBA(dst_2,py_2,pa_2,0,24);
00226 
00227     LOADCHROMA(1);
00228     PUTRGBA(dst_2,py_2,pa_1,1,24);
00229     PUTRGBA(dst_1,py_1,pa_2,1,24);
00230 ENDYUV2RGBFUNC()
00231 
00232 YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
00233     LOADCHROMA(0);
00234     PUTRGBA(dst_1,py_1,pa_1,0,0);
00235     PUTRGBA(dst_2,py_2,pa_2,0,0);
00236 
00237     LOADCHROMA(1);
00238     PUTRGBA(dst_2,py_2,pa_2,1,0);
00239     PUTRGBA(dst_1,py_1,pa_1,1,0);
00240 
00241     LOADCHROMA(2);
00242     PUTRGBA(dst_1,py_1,pa_1,2,0);
00243     PUTRGBA(dst_2,py_2,pa_2,2,0);
00244 
00245     LOADCHROMA(3);
00246     PUTRGBA(dst_2,py_2,pa_2,3,0);
00247     PUTRGBA(dst_1,py_1,pa_1,3,0);
00248     pa_1 += 8;\
00249     pa_2 += 8;\
00250 ENDYUV2RGBLINE(8)
00251     LOADCHROMA(0);
00252     PUTRGBA(dst_1,py_1,pa_1,0,0);
00253     PUTRGBA(dst_2,py_2,pa_2,0,0);
00254 
00255     LOADCHROMA(1);
00256     PUTRGBA(dst_2,py_2,pa_2,1,0);
00257     PUTRGBA(dst_1,py_1,pa_1,1,0);
00258 ENDYUV2RGBFUNC()
00259 
00260 YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0)
00261     LOADCHROMA(0);
00262     PUTRGB24(dst_1,py_1,0);
00263     PUTRGB24(dst_2,py_2,0);
00264 
00265     LOADCHROMA(1);
00266     PUTRGB24(dst_2,py_2,1);
00267     PUTRGB24(dst_1,py_1,1);
00268 
00269     LOADCHROMA(2);
00270     PUTRGB24(dst_1,py_1,2);
00271     PUTRGB24(dst_2,py_2,2);
00272 
00273     LOADCHROMA(3);
00274     PUTRGB24(dst_2,py_2,3);
00275     PUTRGB24(dst_1,py_1,3);
00276 ENDYUV2RGBLINE(24)
00277     LOADCHROMA(0);
00278     PUTRGB24(dst_1,py_1,0);
00279     PUTRGB24(dst_2,py_2,0);
00280 
00281     LOADCHROMA(1);
00282     PUTRGB24(dst_2,py_2,1);
00283     PUTRGB24(dst_1,py_1,1);
00284 ENDYUV2RGBFUNC()
00285 
00286 // only trivial mods from yuv2rgb_c_24_rgb
00287 YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0)
00288     LOADCHROMA(0);
00289     PUTBGR24(dst_1,py_1,0);
00290     PUTBGR24(dst_2,py_2,0);
00291 
00292     LOADCHROMA(1);
00293     PUTBGR24(dst_2,py_2,1);
00294     PUTBGR24(dst_1,py_1,1);
00295 
00296     LOADCHROMA(2);
00297     PUTBGR24(dst_1,py_1,2);
00298     PUTBGR24(dst_2,py_2,2);
00299 
00300     LOADCHROMA(3);
00301     PUTBGR24(dst_2,py_2,3);
00302     PUTBGR24(dst_1,py_1,3);
00303 ENDYUV2RGBLINE(24)
00304     LOADCHROMA(0);
00305     PUTBGR24(dst_1,py_1,0);
00306     PUTBGR24(dst_2,py_2,0);
00307 
00308     LOADCHROMA(1);
00309     PUTBGR24(dst_2,py_2,1);
00310     PUTBGR24(dst_1,py_1,1);
00311 ENDYUV2RGBFUNC()
00312 
00313 // This is exactly the same code as yuv2rgb_c_32 except for the types of
00314 // r, g, b, dst_1, dst_2
00315 YUV2RGBFUNC(yuv2rgb_c_16, uint16_t, 0)
00316     LOADCHROMA(0);
00317     PUTRGB(dst_1,py_1,0);
00318     PUTRGB(dst_2,py_2,0);
00319 
00320     LOADCHROMA(1);
00321     PUTRGB(dst_2,py_2,1);
00322     PUTRGB(dst_1,py_1,1);
00323 
00324     LOADCHROMA(2);
00325     PUTRGB(dst_1,py_1,2);
00326     PUTRGB(dst_2,py_2,2);
00327 
00328     LOADCHROMA(3);
00329     PUTRGB(dst_2,py_2,3);
00330     PUTRGB(dst_1,py_1,3);
00331 CLOSEYUV2RGBFUNC(8)
00332 
00333 #if 0 // Currently unused
00334 // This is exactly the same code as yuv2rgb_c_32 except for the types of
00335 // r, g, b, dst_1, dst_2
00336 YUV2RGBFUNC(yuv2rgb_c_8, uint8_t, 0)
00337     LOADCHROMA(0);
00338     PUTRGB(dst_1,py_1,0);
00339     PUTRGB(dst_2,py_2,0);
00340 
00341     LOADCHROMA(1);
00342     PUTRGB(dst_2,py_2,1);
00343     PUTRGB(dst_1,py_1,1);
00344 
00345     LOADCHROMA(2);
00346     PUTRGB(dst_1,py_1,2);
00347     PUTRGB(dst_2,py_2,2);
00348 
00349     LOADCHROMA(3);
00350     PUTRGB(dst_2,py_2,3);
00351     PUTRGB(dst_1,py_1,3);
00352 CLOSEYUV2RGBFUNC(8)
00353 #endif
00354 
00355 // r, g, b, dst_1, dst_2
00356 YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
00357     const uint8_t *d16 = dither_4x4_16[y&3];
00358 #define PUTRGB12(dst,src,i,o)                                   \
00359     Y = src[2*i];                                               \
00360     dst[2*i]   = r[Y+d16[0+o]] + g[Y+d16[0+o]] + b[Y+d16[0+o]]; \
00361     Y = src[2*i+1];                                             \
00362     dst[2*i+1] = r[Y+d16[1+o]] + g[Y+d16[1+o]] + b[Y+d16[1+o]];
00363 
00364     LOADCHROMA(0);
00365     PUTRGB12(dst_1,py_1,0,0);
00366     PUTRGB12(dst_2,py_2,0,0+8);
00367 
00368     LOADCHROMA(1);
00369     PUTRGB12(dst_2,py_2,1,2+8);
00370     PUTRGB12(dst_1,py_1,1,2);
00371 
00372     LOADCHROMA(2);
00373     PUTRGB12(dst_1,py_1,2,4);
00374     PUTRGB12(dst_2,py_2,2,4+8);
00375 
00376     LOADCHROMA(3);
00377     PUTRGB12(dst_2,py_2,3,6+8);
00378     PUTRGB12(dst_1,py_1,3,6);
00379 CLOSEYUV2RGBFUNC(8)
00380 
00381 // r, g, b, dst_1, dst_2
00382 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
00383     const uint8_t *d32 = dither_8x8_32[y&7];
00384     const uint8_t *d64 = dither_8x8_73[y&7];
00385 #define PUTRGB8(dst,src,i,o)                                    \
00386     Y = src[2*i];                                               \
00387     dst[2*i]   = r[Y+d32[0+o]] + g[Y+d32[0+o]] + b[Y+d64[0+o]]; \
00388     Y = src[2*i+1];                                             \
00389     dst[2*i+1] = r[Y+d32[1+o]] + g[Y+d32[1+o]] + b[Y+d64[1+o]];
00390 
00391     LOADCHROMA(0);
00392     PUTRGB8(dst_1,py_1,0,0);
00393     PUTRGB8(dst_2,py_2,0,0+8);
00394 
00395     LOADCHROMA(1);
00396     PUTRGB8(dst_2,py_2,1,2+8);
00397     PUTRGB8(dst_1,py_1,1,2);
00398 
00399     LOADCHROMA(2);
00400     PUTRGB8(dst_1,py_1,2,4);
00401     PUTRGB8(dst_2,py_2,2,4+8);
00402 
00403     LOADCHROMA(3);
00404     PUTRGB8(dst_2,py_2,3,6+8);
00405     PUTRGB8(dst_1,py_1,3,6);
00406 CLOSEYUV2RGBFUNC(8)
00407 
00408 #if 0 // Currently unused
00409 // This is exactly the same code as yuv2rgb_c_32 except for the types of
00410 // r, g, b, dst_1, dst_2
00411 YUV2RGBFUNC(yuv2rgb_c_4, uint8_t, 0)
00412     int acc;
00413 #define PUTRGB4(dst,src,i)          \
00414     Y = src[2*i];                   \
00415     acc = r[Y] + g[Y] + b[Y];       \
00416     Y = src[2*i+1];                 \
00417     acc |= (r[Y] + g[Y] + b[Y])<<4; \
00418     dst[i] = acc;
00419 
00420     LOADCHROMA(0);
00421     PUTRGB4(dst_1,py_1,0);
00422     PUTRGB4(dst_2,py_2,0);
00423 
00424     LOADCHROMA(1);
00425     PUTRGB4(dst_2,py_2,1);
00426     PUTRGB4(dst_1,py_1,1);
00427 
00428     LOADCHROMA(2);
00429     PUTRGB4(dst_1,py_1,2);
00430     PUTRGB4(dst_2,py_2,2);
00431 
00432     LOADCHROMA(3);
00433     PUTRGB4(dst_2,py_2,3);
00434     PUTRGB4(dst_1,py_1,3);
00435 CLOSEYUV2RGBFUNC(4)
00436 #endif
00437 
00438 YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
00439     const uint8_t *d64 =  dither_8x8_73[y&7];
00440     const uint8_t *d128 = dither_8x8_220[y&7];
00441     int acc;
00442 
00443 #define PUTRGB4D(dst,src,i,o)                                     \
00444     Y = src[2*i];                                                 \
00445     acc = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]];        \
00446     Y = src[2*i+1];                                               \
00447     acc |= (r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]])<<4;  \
00448     dst[i]= acc;
00449 
00450     LOADCHROMA(0);
00451     PUTRGB4D(dst_1,py_1,0,0);
00452     PUTRGB4D(dst_2,py_2,0,0+8);
00453 
00454     LOADCHROMA(1);
00455     PUTRGB4D(dst_2,py_2,1,2+8);
00456     PUTRGB4D(dst_1,py_1,1,2);
00457 
00458     LOADCHROMA(2);
00459     PUTRGB4D(dst_1,py_1,2,4);
00460     PUTRGB4D(dst_2,py_2,2,4+8);
00461 
00462     LOADCHROMA(3);
00463     PUTRGB4D(dst_2,py_2,3,6+8);
00464     PUTRGB4D(dst_1,py_1,3,6);
00465 CLOSEYUV2RGBFUNC(4)
00466 
00467 #if 0 // Currently unused
00468 // This is exactly the same code as yuv2rgb_c_32 except for the types of
00469 // r, g, b, dst_1, dst_2
00470 YUV2RGBFUNC(yuv2rgb_c_4b, uint8_t, 0)
00471     LOADCHROMA(0);
00472     PUTRGB(dst_1,py_1,0);
00473     PUTRGB(dst_2,py_2,0);
00474 
00475     LOADCHROMA(1);
00476     PUTRGB(dst_2,py_2,1);
00477     PUTRGB(dst_1,py_1,1);
00478 
00479     LOADCHROMA(2);
00480     PUTRGB(dst_1,py_1,2);
00481     PUTRGB(dst_2,py_2,2);
00482 
00483     LOADCHROMA(3);
00484     PUTRGB(dst_2,py_2,3);
00485     PUTRGB(dst_1,py_1,3);
00486 CLOSEYUV2RGBFUNC(8)
00487 #endif
00488 
00489 YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
00490     const uint8_t *d64 =  dither_8x8_73[y&7];
00491     const uint8_t *d128 = dither_8x8_220[y&7];
00492 
00493 #define PUTRGB4DB(dst,src,i,o)                                    \
00494     Y = src[2*i];                                                 \
00495     dst[2*i]   = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \
00496     Y = src[2*i+1];                                               \
00497     dst[2*i+1] = r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]];
00498 
00499     LOADCHROMA(0);
00500     PUTRGB4DB(dst_1,py_1,0,0);
00501     PUTRGB4DB(dst_2,py_2,0,0+8);
00502 
00503     LOADCHROMA(1);
00504     PUTRGB4DB(dst_2,py_2,1,2+8);
00505     PUTRGB4DB(dst_1,py_1,1,2);
00506 
00507     LOADCHROMA(2);
00508     PUTRGB4DB(dst_1,py_1,2,4);
00509     PUTRGB4DB(dst_2,py_2,2,4+8);
00510 
00511     LOADCHROMA(3);
00512     PUTRGB4DB(dst_2,py_2,3,6+8);
00513     PUTRGB4DB(dst_1,py_1,3,6);
00514 CLOSEYUV2RGBFUNC(8)
00515 
00516 YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
00517         const uint8_t *d128 = dither_8x8_220[y&7];
00518         char out_1 = 0, out_2 = 0;
00519         g= c->table_gU[128] + c->table_gV[128];
00520 
00521 #define PUTRGB1(out,src,i,o)    \
00522     Y = src[2*i];               \
00523     out+= out + g[Y+d128[0+o]]; \
00524     Y = src[2*i+1];             \
00525     out+= out + g[Y+d128[1+o]];
00526 
00527     PUTRGB1(out_1,py_1,0,0);
00528     PUTRGB1(out_2,py_2,0,0+8);
00529 
00530     PUTRGB1(out_2,py_2,1,2+8);
00531     PUTRGB1(out_1,py_1,1,2);
00532 
00533     PUTRGB1(out_1,py_1,2,4);
00534     PUTRGB1(out_2,py_2,2,4+8);
00535 
00536     PUTRGB1(out_2,py_2,3,6+8);
00537     PUTRGB1(out_1,py_1,3,6);
00538 
00539     dst_1[0]= out_1;
00540     dst_2[0]= out_2;
00541 CLOSEYUV2RGBFUNC(1)
00542 
00543 SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
00544 {
00545     SwsFunc t = NULL;
00546 #if HAVE_MMX
00547      t = ff_yuv2rgb_init_mmx(c);
00548 #endif
00549 #if HAVE_VIS
00550     t = ff_yuv2rgb_init_vis(c);
00551 #endif
00552 #if CONFIG_MLIB
00553     t = ff_yuv2rgb_init_mlib(c);
00554 #endif
00555 #if HAVE_ALTIVEC
00556     if (c->flags & SWS_CPU_CAPS_ALTIVEC)
00557         t = ff_yuv2rgb_init_altivec(c);
00558 #endif
00559 
00560 #if ARCH_BFIN
00561     if (c->flags & SWS_CPU_CAPS_BFIN)
00562         t = ff_yuv2rgb_get_func_ptr_bfin(c);
00563 #endif
00564 
00565     if (t)
00566         return t;
00567 
00568     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));
00569 
00570     switch (c->dstFormat) {
00571     case PIX_FMT_RGB48BE:
00572     case PIX_FMT_RGB48LE:    return yuv2rgb_c_48;
00573     case PIX_FMT_ARGB:
00574     case PIX_FMT_ABGR:       if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) return yuva2argb_c;
00575     case PIX_FMT_RGBA:
00576     case PIX_FMT_BGRA:       return (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) ? yuva2rgba_c : yuv2rgb_c_32;
00577     case PIX_FMT_RGB24:      return yuv2rgb_c_24_rgb;
00578     case PIX_FMT_BGR24:      return yuv2rgb_c_24_bgr;
00579     case PIX_FMT_RGB565:
00580     case PIX_FMT_BGR565:
00581     case PIX_FMT_RGB555:
00582     case PIX_FMT_BGR555:     return yuv2rgb_c_16;
00583     case PIX_FMT_RGB444:
00584     case PIX_FMT_BGR444:     return yuv2rgb_c_12_ordered_dither;
00585     case PIX_FMT_RGB8:
00586     case PIX_FMT_BGR8:       return yuv2rgb_c_8_ordered_dither;
00587     case PIX_FMT_RGB4:
00588     case PIX_FMT_BGR4:       return yuv2rgb_c_4_ordered_dither;
00589     case PIX_FMT_RGB4_BYTE:
00590     case PIX_FMT_BGR4_BYTE:  return yuv2rgb_c_4b_ordered_dither;
00591     case PIX_FMT_MONOBLACK:  return yuv2rgb_c_1_ordered_dither;
00592     default:
00593         assert(0);
00594     }
00595     return NULL;
00596 }
00597 
00598 static void fill_table(uint8_t* table[256], const int elemsize, const int inc, uint8_t *y_table)
00599 {
00600     int i;
00601     int64_t cb = 0;
00602 
00603     y_table -= elemsize * (inc >> 9);
00604 
00605     for (i = 0; i < 256; i++) {
00606         table[i] = y_table + elemsize * (cb >> 16);
00607         cb += inc;
00608     }
00609 }
00610 
00611 static void fill_gv_table(int table[256], const int elemsize, const int inc)
00612 {
00613     int i;
00614     int64_t cb = 0;
00615     int off = -(inc >> 9);
00616 
00617     for (i = 0; i < 256; i++) {
00618         table[i] = elemsize * (off + (cb >> 16));
00619         cb += inc;
00620     }
00621 }
00622 
00623 av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange,
00624                                      int brightness, int contrast, int saturation)
00625 {
00626     const int isRgb =      c->dstFormat==PIX_FMT_RGB32
00627                         || c->dstFormat==PIX_FMT_RGB32_1
00628                         || c->dstFormat==PIX_FMT_BGR24
00629                         || c->dstFormat==PIX_FMT_RGB565BE
00630                         || c->dstFormat==PIX_FMT_RGB565LE
00631                         || c->dstFormat==PIX_FMT_RGB555BE
00632                         || c->dstFormat==PIX_FMT_RGB555LE
00633                         || c->dstFormat==PIX_FMT_RGB444BE
00634                         || c->dstFormat==PIX_FMT_RGB444LE
00635                         || c->dstFormat==PIX_FMT_RGB8
00636                         || c->dstFormat==PIX_FMT_RGB4
00637                         || c->dstFormat==PIX_FMT_RGB4_BYTE
00638                         || c->dstFormat==PIX_FMT_MONOBLACK;
00639     const int isNotNe =    c->dstFormat==PIX_FMT_NE(RGB565LE,RGB565BE)
00640                         || c->dstFormat==PIX_FMT_NE(RGB555LE,RGB555BE)
00641                         || c->dstFormat==PIX_FMT_NE(RGB444LE,RGB444BE)
00642                         || c->dstFormat==PIX_FMT_NE(BGR565LE,BGR565BE)
00643                         || c->dstFormat==PIX_FMT_NE(BGR555LE,BGR555BE)
00644                         || c->dstFormat==PIX_FMT_NE(BGR444LE,BGR444BE);
00645     const int bpp = c->dstFormatBpp;
00646     uint8_t *y_table;
00647     uint16_t *y_table16;
00648     uint32_t *y_table32;
00649     int i, base, rbase, gbase, bbase, abase, needAlpha;
00650     const int yoffs = fullRange ? 384 : 326;
00651 
00652     int64_t crv =  inv_table[0];
00653     int64_t cbu =  inv_table[1];
00654     int64_t cgu = -inv_table[2];
00655     int64_t cgv = -inv_table[3];
00656     int64_t cy  = 1<<16;
00657     int64_t oy  = 0;
00658 
00659     int64_t yb = 0;
00660 
00661     if (!fullRange) {
00662         cy = (cy*255) / 219;
00663         oy = 16<<16;
00664     } else {
00665         crv = (crv*224) / 255;
00666         cbu = (cbu*224) / 255;
00667         cgu = (cgu*224) / 255;
00668         cgv = (cgv*224) / 255;
00669     }
00670 
00671     cy  = (cy *contrast             ) >> 16;
00672     crv = (crv*contrast * saturation) >> 32;
00673     cbu = (cbu*contrast * saturation) >> 32;
00674     cgu = (cgu*contrast * saturation) >> 32;
00675     cgv = (cgv*contrast * saturation) >> 32;
00676     oy -= 256*brightness;
00677 
00678     //scale coefficients by cy
00679     crv = ((crv << 16) + 0x8000) / cy;
00680     cbu = ((cbu << 16) + 0x8000) / cy;
00681     cgu = ((cgu << 16) + 0x8000) / cy;
00682     cgv = ((cgv << 16) + 0x8000) / cy;
00683 
00684     av_free(c->yuvTable);
00685 
00686     switch (bpp) {
00687     case 1:
00688         c->yuvTable = av_malloc(1024);
00689         y_table = c->yuvTable;
00690         yb = -(384<<16) - oy;
00691         for (i = 0; i < 1024-110; i++) {
00692             y_table[i+110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7;
00693             yb += cy;
00694         }
00695         fill_table(c->table_gU, 1, cgu, y_table + yoffs);
00696         fill_gv_table(c->table_gV, 1, cgv);
00697         break;
00698     case 4:
00699     case 4|128:
00700         rbase = isRgb ? 3 : 0;
00701         gbase = 1;
00702         bbase = isRgb ? 0 : 3;
00703         c->yuvTable = av_malloc(1024*3);
00704         y_table = c->yuvTable;
00705         yb = -(384<<16) - oy;
00706         for (i = 0; i < 1024-110; i++) {
00707             int yval = av_clip_uint8((yb + 0x8000) >> 16);
00708             y_table[i+110     ] =  (yval >> 7)       << rbase;
00709             y_table[i+ 37+1024] = ((yval + 43) / 85) << gbase;
00710             y_table[i+110+2048] =  (yval >> 7)       << bbase;
00711             yb += cy;
00712         }
00713         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00714         fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
00715         fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
00716         fill_gv_table(c->table_gV, 1, cgv);
00717         break;
00718     case 8:
00719         rbase = isRgb ? 5 : 0;
00720         gbase = isRgb ? 2 : 3;
00721         bbase = isRgb ? 0 : 6;
00722         c->yuvTable = av_malloc(1024*3);
00723         y_table = c->yuvTable;
00724         yb = -(384<<16) - oy;
00725         for (i = 0; i < 1024-38; i++) {
00726             int yval = av_clip_uint8((yb + 0x8000) >> 16);
00727             y_table[i+16     ] = ((yval + 18) / 36) << rbase;
00728             y_table[i+16+1024] = ((yval + 18) / 36) << gbase;
00729             y_table[i+37+2048] = ((yval + 43) / 85) << bbase;
00730             yb += cy;
00731         }
00732         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00733         fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024);
00734         fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
00735         fill_gv_table(c->table_gV, 1, cgv);
00736         break;
00737     case 12:
00738         rbase = isRgb ? 8 : 0;
00739         gbase = 4;
00740         bbase = isRgb ? 0 : 8;
00741         c->yuvTable = av_malloc(1024*3*2);
00742         y_table16 = c->yuvTable;
00743         yb = -(384<<16) - oy;
00744         for (i = 0; i < 1024; i++) {
00745             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00746             y_table16[i     ] = (yval >> 4) << rbase;
00747             y_table16[i+1024] = (yval >> 4) << gbase;
00748             y_table16[i+2048] = (yval >> 4) << bbase;
00749             yb += cy;
00750         }
00751         if (isNotNe)
00752             for (i = 0; i < 1024*3; i++)
00753                 y_table16[i] = bswap_16(y_table16[i]);
00754         fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
00755         fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
00756         fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
00757         fill_gv_table(c->table_gV, 2, cgv);
00758         break;
00759     case 15:
00760     case 16:
00761         rbase = isRgb ? bpp - 5 : 0;
00762         gbase = 5;
00763         bbase = isRgb ? 0 : (bpp - 5);
00764         c->yuvTable = av_malloc(1024*3*2);
00765         y_table16 = c->yuvTable;
00766         yb = -(384<<16) - oy;
00767         for (i = 0; i < 1024; i++) {
00768             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00769             y_table16[i     ] = (yval >> 3)          << rbase;
00770             y_table16[i+1024] = (yval >> (18 - bpp)) << gbase;
00771             y_table16[i+2048] = (yval >> 3)          << bbase;
00772             yb += cy;
00773         }
00774         if(isNotNe)
00775             for (i = 0; i < 1024*3; i++)
00776                 y_table16[i] = bswap_16(y_table16[i]);
00777         fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
00778         fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
00779         fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
00780         fill_gv_table(c->table_gV, 2, cgv);
00781         break;
00782     case 24:
00783     case 48:
00784         c->yuvTable = av_malloc(1024);
00785         y_table = c->yuvTable;
00786         yb = -(384<<16) - oy;
00787         for (i = 0; i < 1024; i++) {
00788             y_table[i] = av_clip_uint8((yb + 0x8000) >> 16);
00789             yb += cy;
00790         }
00791         fill_table(c->table_rV, 1, crv, y_table + yoffs);
00792         fill_table(c->table_gU, 1, cgu, y_table + yoffs);
00793         fill_table(c->table_bU, 1, cbu, y_table + yoffs);
00794         fill_gv_table(c->table_gV, 1, cgv);
00795         break;
00796     case 32:
00797         base = (c->dstFormat == PIX_FMT_RGB32_1 || c->dstFormat == PIX_FMT_BGR32_1) ? 8 : 0;
00798         rbase = base + (isRgb ? 16 : 0);
00799         gbase = base + 8;
00800         bbase = base + (isRgb ? 0 : 16);
00801         needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
00802         if (!needAlpha)
00803             abase = (base + 24) & 31;
00804         c->yuvTable = av_malloc(1024*3*4);
00805         y_table32 = c->yuvTable;
00806         yb = -(384<<16) - oy;
00807         for (i = 0; i < 1024; i++) {
00808             uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
00809             y_table32[i     ] = (yval << rbase) + (needAlpha ? 0 : (255 << abase));
00810             y_table32[i+1024] = yval << gbase;
00811             y_table32[i+2048] = yval << bbase;
00812             yb += cy;
00813         }
00814         fill_table(c->table_rV, 4, crv, y_table32 + yoffs);
00815         fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + 1024);
00816         fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2048);
00817         fill_gv_table(c->table_gV, 4, cgv);
00818         break;
00819     default:
00820         c->yuvTable = NULL;
00821         av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
00822         return -1;
00823     }
00824     return 0;
00825 }

Generated on Fri Sep 16 2011 17:17:52 for FFmpeg by  doxygen 1.7.1