Libav
|
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 }