00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <inttypes.h>
00029 #include <assert.h>
00030
00031 #include "config.h"
00032 #include "rgb2rgb.h"
00033 #include "swscale.h"
00034 #include "swscale_internal.h"
00035 #include "libavutil/cpu.h"
00036 #include "libavutil/bswap.h"
00037
00038 extern const uint8_t dither_4x4_16[4][8];
00039 extern const uint8_t dither_8x8_32[8][8];
00040 extern const uint8_t dither_8x8_73[8][8];
00041 extern const uint8_t dither_8x8_220[8][8];
00042
00043 const int32_t ff_yuv2rgb_coeffs[8][4] = {
00044 {117504, 138453, 13954, 34903},
00045 {117504, 138453, 13954, 34903},
00046 {104597, 132201, 25675, 53279},
00047 {104597, 132201, 25675, 53279},
00048 {104448, 132798, 24759, 53109},
00049 {104597, 132201, 25675, 53279},
00050 {104597, 132201, 25675, 53279},
00051 {117579, 136230, 16907, 35559}
00052 };
00053
00054 const int *sws_getCoefficients(int colorspace)
00055 {
00056 if (colorspace > 7 || colorspace < 0)
00057 colorspace = SWS_CS_DEFAULT;
00058 return ff_yuv2rgb_coeffs[colorspace];
00059 }
00060
00061 #define LOADCHROMA(i) \
00062 U = pu[i]; \
00063 V = pv[i]; \
00064 r = (void *)c->table_rV[V]; \
00065 g = (void *)(c->table_gU[U] + c->table_gV[V]); \
00066 b = (void *)c->table_bU[U];
00067
00068 #define PUTRGB(dst,src,i) \
00069 Y = src[2*i]; \
00070 dst[2*i ] = r[Y] + g[Y] + b[Y]; \
00071 Y = src[2*i+1]; \
00072 dst[2*i+1] = r[Y] + g[Y] + b[Y];
00073
00074 #define PUTRGB24(dst,src,i) \
00075 Y = src[2*i]; \
00076 dst[6*i+0] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y]; \
00077 Y = src[2*i+1]; \
00078 dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y];
00079
00080 #define PUTBGR24(dst,src,i) \
00081 Y = src[2*i]; \
00082 dst[6*i+0] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y]; \
00083 Y = src[2*i+1]; \
00084 dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y];
00085
00086 #define PUTRGBA(dst,ysrc,asrc,i,s) \
00087 Y = ysrc[2*i]; \
00088 dst[2*i ] = r[Y] + g[Y] + b[Y] + (asrc[2*i ]<<s); \
00089 Y = ysrc[2*i+1]; \
00090 dst[2*i+1] = r[Y] + g[Y] + b[Y] + (asrc[2*i+1]<<s);
00091
00092 #define PUTRGB48(dst,src,i) \
00093 Y = src[2*i]; \
00094 dst[12*i+ 0] = dst[12*i+ 1] = r[Y]; \
00095 dst[12*i+ 2] = dst[12*i+ 3] = g[Y]; \
00096 dst[12*i+ 4] = dst[12*i+ 5] = b[Y]; \
00097 Y = src[2*i+1]; \
00098 dst[12*i+ 6] = dst[12*i+ 7] = r[Y]; \
00099 dst[12*i+ 8] = dst[12*i+ 9] = g[Y]; \
00100 dst[12*i+10] = dst[12*i+11] = b[Y];
00101
00102 #define PUTBGR48(dst,src,i) \
00103 Y = src[2*i]; \
00104 dst[12*i+ 0] = dst[12*i+ 1] = b[Y]; \
00105 dst[12*i+ 2] = dst[12*i+ 3] = g[Y]; \
00106 dst[12*i+ 4] = dst[12*i+ 5] = r[Y]; \
00107 Y = src[2*i+1]; \
00108 dst[12*i+ 6] = dst[12*i+ 7] = b[Y]; \
00109 dst[12*i+ 8] = dst[12*i+ 9] = g[Y]; \
00110 dst[12*i+10] = dst[12*i+11] = r[Y];
00111
00112 #define YUV2RGBFUNC(func_name, dst_type, alpha) \
00113 static int func_name(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, \
00114 int srcSliceH, uint8_t* dst[], int dstStride[]) \
00115 {\
00116 int y;\
00117 \
00118 if (!alpha && c->srcFormat == PIX_FMT_YUV422P) {\
00119 srcStride[1] *= 2;\
00120 srcStride[2] *= 2;\
00121 }\
00122 for (y=0; y<srcSliceH; y+=2) {\
00123 dst_type *dst_1 = (dst_type*)(dst[0] + (y+srcSliceY )*dstStride[0]);\
00124 dst_type *dst_2 = (dst_type*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);\
00125 dst_type av_unused *r, *b;\
00126 dst_type *g;\
00127 const uint8_t *py_1 = src[0] + y*srcStride[0];\
00128 const uint8_t *py_2 = py_1 + srcStride[0];\
00129 const uint8_t *pu = src[1] + (y>>1)*srcStride[1];\
00130 const uint8_t *pv = src[2] + (y>>1)*srcStride[2];\
00131 const uint8_t av_unused *pa_1, *pa_2;\
00132 unsigned int h_size = c->dstW>>3;\
00133 if (alpha) {\
00134 pa_1 = src[3] + y*srcStride[3];\
00135 pa_2 = pa_1 + srcStride[3];\
00136 }\
00137 while (h_size--) {\
00138 int av_unused U, V;\
00139 int Y;\
00140
00141 #define ENDYUV2RGBLINE(dst_delta)\
00142 pu += 4;\
00143 pv += 4;\
00144 py_1 += 8;\
00145 py_2 += 8;\
00146 dst_1 += dst_delta;\
00147 dst_2 += dst_delta;\
00148 }\
00149 if (c->dstW & 4) {\
00150 int av_unused Y, U, V;\
00151
00152 #define ENDYUV2RGBFUNC()\
00153 }\
00154 }\
00155 return srcSliceH;\
00156 }
00157
00158 #define CLOSEYUV2RGBFUNC(dst_delta)\
00159 ENDYUV2RGBLINE(dst_delta)\
00160 ENDYUV2RGBFUNC()
00161
00162 YUV2RGBFUNC(yuv2rgb_c_48, uint8_t, 0)
00163 LOADCHROMA(0);
00164 PUTRGB48(dst_1,py_1,0);
00165 PUTRGB48(dst_2,py_2,0);
00166
00167 LOADCHROMA(1);
00168 PUTRGB48(dst_2,py_2,1);
00169 PUTRGB48(dst_1,py_1,1);
00170
00171 LOADCHROMA(2);
00172 PUTRGB48(dst_1,py_1,2);
00173 PUTRGB48(dst_2,py_2,2);
00174
00175 LOADCHROMA(3);
00176 PUTRGB48(dst_2,py_2,3);
00177 PUTRGB48(dst_1,py_1,3);
00178 ENDYUV2RGBLINE(48)
00179 LOADCHROMA(0);
00180 PUTRGB48(dst_1,py_1,0);
00181 PUTRGB48(dst_2,py_2,0);
00182
00183 LOADCHROMA(1);
00184 PUTRGB48(dst_2,py_2,1);
00185 PUTRGB48(dst_1,py_1,1);
00186 ENDYUV2RGBFUNC()
00187
00188 YUV2RGBFUNC(yuv2rgb_c_bgr48, uint8_t, 0)
00189 LOADCHROMA(0);
00190 PUTBGR48(dst_1,py_1,0);
00191 PUTBGR48(dst_2,py_2,0);
00192
00193 LOADCHROMA(1);
00194 PUTBGR48(dst_2,py_2,1);
00195 PUTBGR48(dst_1,py_1,1);
00196
00197 LOADCHROMA(2);
00198 PUTBGR48(dst_1,py_1,2);
00199 PUTBGR48(dst_2,py_2,2);
00200
00201 LOADCHROMA(3);
00202 PUTBGR48(dst_2,py_2,3);
00203 PUTBGR48(dst_1,py_1,3);
00204 ENDYUV2RGBLINE(48)
00205 LOADCHROMA(0);
00206 PUTBGR48(dst_1,py_1,0);
00207 PUTBGR48(dst_2,py_2,0);
00208
00209 LOADCHROMA(1);
00210 PUTBGR48(dst_2,py_2,1);
00211 PUTBGR48(dst_1,py_1,1);
00212 ENDYUV2RGBFUNC()
00213
00214 YUV2RGBFUNC(yuv2rgb_c_32, uint32_t, 0)
00215 LOADCHROMA(0);
00216 PUTRGB(dst_1,py_1,0);
00217 PUTRGB(dst_2,py_2,0);
00218
00219 LOADCHROMA(1);
00220 PUTRGB(dst_2,py_2,1);
00221 PUTRGB(dst_1,py_1,1);
00222
00223 LOADCHROMA(2);
00224 PUTRGB(dst_1,py_1,2);
00225 PUTRGB(dst_2,py_2,2);
00226
00227 LOADCHROMA(3);
00228 PUTRGB(dst_2,py_2,3);
00229 PUTRGB(dst_1,py_1,3);
00230 ENDYUV2RGBLINE(8)
00231 LOADCHROMA(0);
00232 PUTRGB(dst_1,py_1,0);
00233 PUTRGB(dst_2,py_2,0);
00234
00235 LOADCHROMA(1);
00236 PUTRGB(dst_2,py_2,1);
00237 PUTRGB(dst_1,py_1,1);
00238 ENDYUV2RGBFUNC()
00239
00240 YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
00241 LOADCHROMA(0);
00242 PUTRGBA(dst_1,py_1,pa_1,0,24);
00243 PUTRGBA(dst_2,py_2,pa_2,0,24);
00244
00245 LOADCHROMA(1);
00246 PUTRGBA(dst_2,py_2,pa_1,1,24);
00247 PUTRGBA(dst_1,py_1,pa_2,1,24);
00248
00249 LOADCHROMA(2);
00250 PUTRGBA(dst_1,py_1,pa_1,2,24);
00251 PUTRGBA(dst_2,py_2,pa_2,2,24);
00252
00253 LOADCHROMA(3);
00254 PUTRGBA(dst_2,py_2,pa_1,3,24);
00255 PUTRGBA(dst_1,py_1,pa_2,3,24);
00256 pa_1 += 8;\
00257 pa_2 += 8;\
00258 ENDYUV2RGBLINE(8)
00259 LOADCHROMA(0);
00260 PUTRGBA(dst_1,py_1,pa_1,0,24);
00261 PUTRGBA(dst_2,py_2,pa_2,0,24);
00262
00263 LOADCHROMA(1);
00264 PUTRGBA(dst_2,py_2,pa_1,1,24);
00265 PUTRGBA(dst_1,py_1,pa_2,1,24);
00266 ENDYUV2RGBFUNC()
00267
00268 YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
00269 LOADCHROMA(0);
00270 PUTRGBA(dst_1,py_1,pa_1,0,0);
00271 PUTRGBA(dst_2,py_2,pa_2,0,0);
00272
00273 LOADCHROMA(1);
00274 PUTRGBA(dst_2,py_2,pa_2,1,0);
00275 PUTRGBA(dst_1,py_1,pa_1,1,0);
00276
00277 LOADCHROMA(2);
00278 PUTRGBA(dst_1,py_1,pa_1,2,0);
00279 PUTRGBA(dst_2,py_2,pa_2,2,0);
00280
00281 LOADCHROMA(3);
00282 PUTRGBA(dst_2,py_2,pa_2,3,0);
00283 PUTRGBA(dst_1,py_1,pa_1,3,0);
00284 pa_1 += 8;\
00285 pa_2 += 8;\
00286 ENDYUV2RGBLINE(8)
00287 LOADCHROMA(0);
00288 PUTRGBA(dst_1,py_1,pa_1,0,0);
00289 PUTRGBA(dst_2,py_2,pa_2,0,0);
00290
00291 LOADCHROMA(1);
00292 PUTRGBA(dst_2,py_2,pa_2,1,0);
00293 PUTRGBA(dst_1,py_1,pa_1,1,0);
00294 ENDYUV2RGBFUNC()
00295
00296 YUV2RGBFUNC(yuv2rgb_c_24_rgb, uint8_t, 0)
00297 LOADCHROMA(0);
00298 PUTRGB24(dst_1,py_1,0);
00299 PUTRGB24(dst_2,py_2,0);
00300
00301 LOADCHROMA(1);
00302 PUTRGB24(dst_2,py_2,1);
00303 PUTRGB24(dst_1,py_1,1);
00304
00305 LOADCHROMA(2);
00306 PUTRGB24(dst_1,py_1,2);
00307 PUTRGB24(dst_2,py_2,2);
00308
00309 LOADCHROMA(3);
00310 PUTRGB24(dst_2,py_2,3);
00311 PUTRGB24(dst_1,py_1,3);
00312 ENDYUV2RGBLINE(24)
00313 LOADCHROMA(0);
00314 PUTRGB24(dst_1,py_1,0);
00315 PUTRGB24(dst_2,py_2,0);
00316
00317 LOADCHROMA(1);
00318 PUTRGB24(dst_2,py_2,1);
00319 PUTRGB24(dst_1,py_1,1);
00320 ENDYUV2RGBFUNC()
00321
00322
00323 YUV2RGBFUNC(yuv2rgb_c_24_bgr, uint8_t, 0)
00324 LOADCHROMA(0);
00325 PUTBGR24(dst_1,py_1,0);
00326 PUTBGR24(dst_2,py_2,0);
00327
00328 LOADCHROMA(1);
00329 PUTBGR24(dst_2,py_2,1);
00330 PUTBGR24(dst_1,py_1,1);
00331
00332 LOADCHROMA(2);
00333 PUTBGR24(dst_1,py_1,2);
00334 PUTBGR24(dst_2,py_2,2);
00335
00336 LOADCHROMA(3);
00337 PUTBGR24(dst_2,py_2,3);
00338 PUTBGR24(dst_1,py_1,3);
00339 ENDYUV2RGBLINE(24)
00340 LOADCHROMA(0);
00341 PUTBGR24(dst_1,py_1,0);
00342 PUTBGR24(dst_2,py_2,0);
00343
00344 LOADCHROMA(1);
00345 PUTBGR24(dst_2,py_2,1);
00346 PUTBGR24(dst_1,py_1,1);
00347 ENDYUV2RGBFUNC()
00348
00349
00350
00351 YUV2RGBFUNC(yuv2rgb_c_16, uint16_t, 0)
00352 LOADCHROMA(0);
00353 PUTRGB(dst_1,py_1,0);
00354 PUTRGB(dst_2,py_2,0);
00355
00356 LOADCHROMA(1);
00357 PUTRGB(dst_2,py_2,1);
00358 PUTRGB(dst_1,py_1,1);
00359
00360 LOADCHROMA(2);
00361 PUTRGB(dst_1,py_1,2);
00362 PUTRGB(dst_2,py_2,2);
00363
00364 LOADCHROMA(3);
00365 PUTRGB(dst_2,py_2,3);
00366 PUTRGB(dst_1,py_1,3);
00367 CLOSEYUV2RGBFUNC(8)
00368
00369
00370 YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
00371 const uint8_t *d16 = dither_4x4_16[y&3];
00372 #define PUTRGB12(dst,src,i,o) \
00373 Y = src[2*i]; \
00374 dst[2*i] = r[Y+d16[0+o]] + g[Y+d16[0+o]] + b[Y+d16[0+o]]; \
00375 Y = src[2*i+1]; \
00376 dst[2*i+1] = r[Y+d16[1+o]] + g[Y+d16[1+o]] + b[Y+d16[1+o]];
00377
00378 LOADCHROMA(0);
00379 PUTRGB12(dst_1,py_1,0,0);
00380 PUTRGB12(dst_2,py_2,0,0+8);
00381
00382 LOADCHROMA(1);
00383 PUTRGB12(dst_2,py_2,1,2+8);
00384 PUTRGB12(dst_1,py_1,1,2);
00385
00386 LOADCHROMA(2);
00387 PUTRGB12(dst_1,py_1,2,4);
00388 PUTRGB12(dst_2,py_2,2,4+8);
00389
00390 LOADCHROMA(3);
00391 PUTRGB12(dst_2,py_2,3,6+8);
00392 PUTRGB12(dst_1,py_1,3,6);
00393 CLOSEYUV2RGBFUNC(8)
00394
00395
00396 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
00397 const uint8_t *d32 = dither_8x8_32[y&7];
00398 const uint8_t *d64 = dither_8x8_73[y&7];
00399 #define PUTRGB8(dst,src,i,o) \
00400 Y = src[2*i]; \
00401 dst[2*i] = r[Y+d32[0+o]] + g[Y+d32[0+o]] + b[Y+d64[0+o]]; \
00402 Y = src[2*i+1]; \
00403 dst[2*i+1] = r[Y+d32[1+o]] + g[Y+d32[1+o]] + b[Y+d64[1+o]];
00404
00405 LOADCHROMA(0);
00406 PUTRGB8(dst_1,py_1,0,0);
00407 PUTRGB8(dst_2,py_2,0,0+8);
00408
00409 LOADCHROMA(1);
00410 PUTRGB8(dst_2,py_2,1,2+8);
00411 PUTRGB8(dst_1,py_1,1,2);
00412
00413 LOADCHROMA(2);
00414 PUTRGB8(dst_1,py_1,2,4);
00415 PUTRGB8(dst_2,py_2,2,4+8);
00416
00417 LOADCHROMA(3);
00418 PUTRGB8(dst_2,py_2,3,6+8);
00419 PUTRGB8(dst_1,py_1,3,6);
00420 CLOSEYUV2RGBFUNC(8)
00421
00422 YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
00423 const uint8_t *d64 = dither_8x8_73[y&7];
00424 const uint8_t *d128 = dither_8x8_220[y&7];
00425 int acc;
00426
00427 #define PUTRGB4D(dst,src,i,o) \
00428 Y = src[2*i]; \
00429 acc = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \
00430 Y = src[2*i+1]; \
00431 acc |= (r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]])<<4; \
00432 dst[i]= acc;
00433
00434 LOADCHROMA(0);
00435 PUTRGB4D(dst_1,py_1,0,0);
00436 PUTRGB4D(dst_2,py_2,0,0+8);
00437
00438 LOADCHROMA(1);
00439 PUTRGB4D(dst_2,py_2,1,2+8);
00440 PUTRGB4D(dst_1,py_1,1,2);
00441
00442 LOADCHROMA(2);
00443 PUTRGB4D(dst_1,py_1,2,4);
00444 PUTRGB4D(dst_2,py_2,2,4+8);
00445
00446 LOADCHROMA(3);
00447 PUTRGB4D(dst_2,py_2,3,6+8);
00448 PUTRGB4D(dst_1,py_1,3,6);
00449 CLOSEYUV2RGBFUNC(4)
00450
00451 YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
00452 const uint8_t *d64 = dither_8x8_73[y&7];
00453 const uint8_t *d128 = dither_8x8_220[y&7];
00454
00455 #define PUTRGB4DB(dst,src,i,o) \
00456 Y = src[2*i]; \
00457 dst[2*i] = r[Y+d128[0+o]] + g[Y+d64[0+o]] + b[Y+d128[0+o]]; \
00458 Y = src[2*i+1]; \
00459 dst[2*i+1] = r[Y+d128[1+o]] + g[Y+d64[1+o]] + b[Y+d128[1+o]];
00460
00461 LOADCHROMA(0);
00462 PUTRGB4DB(dst_1,py_1,0,0);
00463 PUTRGB4DB(dst_2,py_2,0,0+8);
00464
00465 LOADCHROMA(1);
00466 PUTRGB4DB(dst_2,py_2,1,2+8);
00467 PUTRGB4DB(dst_1,py_1,1,2);
00468
00469 LOADCHROMA(2);
00470 PUTRGB4DB(dst_1,py_1,2,4);
00471 PUTRGB4DB(dst_2,py_2,2,4+8);
00472
00473 LOADCHROMA(3);
00474 PUTRGB4DB(dst_2,py_2,3,6+8);
00475 PUTRGB4DB(dst_1,py_1,3,6);
00476 CLOSEYUV2RGBFUNC(8)
00477
00478 YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
00479 const uint8_t *d128 = dither_8x8_220[y&7];
00480 char out_1 = 0, out_2 = 0;
00481 g= c->table_gU[128] + c->table_gV[128];
00482
00483 #define PUTRGB1(out,src,i,o) \
00484 Y = src[2*i]; \
00485 out+= out + g[Y+d128[0+o]]; \
00486 Y = src[2*i+1]; \
00487 out+= out + g[Y+d128[1+o]];
00488
00489 PUTRGB1(out_1,py_1,0,0);
00490 PUTRGB1(out_2,py_2,0,0+8);
00491
00492 PUTRGB1(out_2,py_2,1,2+8);
00493 PUTRGB1(out_1,py_1,1,2);
00494
00495 PUTRGB1(out_1,py_1,2,4);
00496 PUTRGB1(out_2,py_2,2,4+8);
00497
00498 PUTRGB1(out_2,py_2,3,6+8);
00499 PUTRGB1(out_1,py_1,3,6);
00500
00501 dst_1[0]= out_1;
00502 dst_2[0]= out_2;
00503 CLOSEYUV2RGBFUNC(1)
00504
00505 SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
00506 {
00507 SwsFunc t = NULL;
00508
00509 if (HAVE_MMX) {
00510 t = ff_yuv2rgb_init_mmx(c);
00511 } else if (HAVE_VIS) {
00512 t = ff_yuv2rgb_init_vis(c);
00513 } else if (CONFIG_MLIB) {
00514 t = ff_yuv2rgb_init_mlib(c);
00515 } else if (HAVE_ALTIVEC) {
00516 t = ff_yuv2rgb_init_altivec(c);
00517 } else if (ARCH_BFIN) {
00518 t = ff_yuv2rgb_get_func_ptr_bfin(c);
00519 }
00520
00521 if (t)
00522 return t;
00523
00524 av_log(c, AV_LOG_WARNING, "No accelerated colorspace conversion found from %s to %s.\n", sws_format_name(c->srcFormat), sws_format_name(c->dstFormat));
00525
00526 switch (c->dstFormat) {
00527 case PIX_FMT_BGR48BE:
00528 case PIX_FMT_BGR48LE: return yuv2rgb_c_bgr48;
00529 case PIX_FMT_RGB48BE:
00530 case PIX_FMT_RGB48LE: return yuv2rgb_c_48;
00531 case PIX_FMT_ARGB:
00532 case PIX_FMT_ABGR: if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) return yuva2argb_c;
00533 case PIX_FMT_RGBA:
00534 case PIX_FMT_BGRA: return (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) ? yuva2rgba_c : yuv2rgb_c_32;
00535 case PIX_FMT_RGB24: return yuv2rgb_c_24_rgb;
00536 case PIX_FMT_BGR24: return yuv2rgb_c_24_bgr;
00537 case PIX_FMT_RGB565:
00538 case PIX_FMT_BGR565:
00539 case PIX_FMT_RGB555:
00540 case PIX_FMT_BGR555: return yuv2rgb_c_16;
00541 case PIX_FMT_RGB444:
00542 case PIX_FMT_BGR444: return yuv2rgb_c_12_ordered_dither;
00543 case PIX_FMT_RGB8:
00544 case PIX_FMT_BGR8: return yuv2rgb_c_8_ordered_dither;
00545 case PIX_FMT_RGB4:
00546 case PIX_FMT_BGR4: return yuv2rgb_c_4_ordered_dither;
00547 case PIX_FMT_RGB4_BYTE:
00548 case PIX_FMT_BGR4_BYTE: return yuv2rgb_c_4b_ordered_dither;
00549 case PIX_FMT_MONOBLACK: return yuv2rgb_c_1_ordered_dither;
00550 default:
00551 assert(0);
00552 }
00553 return NULL;
00554 }
00555
00556 static void fill_table(uint8_t* table[256], const int elemsize, const int inc, void *y_tab)
00557 {
00558 int i;
00559 int64_t cb = 0;
00560 uint8_t *y_table = y_tab;
00561
00562 y_table -= elemsize * (inc >> 9);
00563
00564 for (i = 0; i < 256; i++) {
00565 table[i] = y_table + elemsize * (cb >> 16);
00566 cb += inc;
00567 }
00568 }
00569
00570 static void fill_gv_table(int table[256], const int elemsize, const int inc)
00571 {
00572 int i;
00573 int64_t cb = 0;
00574 int off = -(inc >> 9);
00575
00576 for (i = 0; i < 256; i++) {
00577 table[i] = elemsize * (off + (cb >> 16));
00578 cb += inc;
00579 }
00580 }
00581
00582 static uint16_t roundToInt16(int64_t f)
00583 {
00584 int r= (f + (1<<15))>>16;
00585 if (r<-0x7FFF) return 0x8000;
00586 else if (r> 0x7FFF) return 0x7FFF;
00587 else return r;
00588 }
00589
00590 av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange,
00591 int brightness, int contrast, int saturation)
00592 {
00593 const int isRgb = c->dstFormat==PIX_FMT_RGB32
00594 || c->dstFormat==PIX_FMT_RGB32_1
00595 || c->dstFormat==PIX_FMT_BGR24
00596 || c->dstFormat==PIX_FMT_RGB565BE
00597 || c->dstFormat==PIX_FMT_RGB565LE
00598 || c->dstFormat==PIX_FMT_RGB555BE
00599 || c->dstFormat==PIX_FMT_RGB555LE
00600 || c->dstFormat==PIX_FMT_RGB444BE
00601 || c->dstFormat==PIX_FMT_RGB444LE
00602 || c->dstFormat==PIX_FMT_RGB8
00603 || c->dstFormat==PIX_FMT_RGB4
00604 || c->dstFormat==PIX_FMT_RGB4_BYTE
00605 || c->dstFormat==PIX_FMT_MONOBLACK;
00606 const int isNotNe = c->dstFormat==PIX_FMT_NE(RGB565LE,RGB565BE)
00607 || c->dstFormat==PIX_FMT_NE(RGB555LE,RGB555BE)
00608 || c->dstFormat==PIX_FMT_NE(RGB444LE,RGB444BE)
00609 || c->dstFormat==PIX_FMT_NE(BGR565LE,BGR565BE)
00610 || c->dstFormat==PIX_FMT_NE(BGR555LE,BGR555BE)
00611 || c->dstFormat==PIX_FMT_NE(BGR444LE,BGR444BE);
00612 const int bpp = c->dstFormatBpp;
00613 uint8_t *y_table;
00614 uint16_t *y_table16;
00615 uint32_t *y_table32;
00616 int i, base, rbase, gbase, bbase, abase, needAlpha;
00617 const int yoffs = fullRange ? 384 : 326;
00618
00619 int64_t crv = inv_table[0];
00620 int64_t cbu = inv_table[1];
00621 int64_t cgu = -inv_table[2];
00622 int64_t cgv = -inv_table[3];
00623 int64_t cy = 1<<16;
00624 int64_t oy = 0;
00625
00626 int64_t yb = 0;
00627
00628 if (!fullRange) {
00629 cy = (cy*255) / 219;
00630 oy = 16<<16;
00631 } else {
00632 crv = (crv*224) / 255;
00633 cbu = (cbu*224) / 255;
00634 cgu = (cgu*224) / 255;
00635 cgv = (cgv*224) / 255;
00636 }
00637
00638 cy = (cy *contrast ) >> 16;
00639 crv = (crv*contrast * saturation) >> 32;
00640 cbu = (cbu*contrast * saturation) >> 32;
00641 cgu = (cgu*contrast * saturation) >> 32;
00642 cgv = (cgv*contrast * saturation) >> 32;
00643 oy -= 256*brightness;
00644
00645 c->uOffset= 0x0400040004000400LL;
00646 c->vOffset= 0x0400040004000400LL;
00647 c->yCoeff= roundToInt16(cy *8192) * 0x0001000100010001ULL;
00648 c->vrCoeff= roundToInt16(crv*8192) * 0x0001000100010001ULL;
00649 c->ubCoeff= roundToInt16(cbu*8192) * 0x0001000100010001ULL;
00650 c->vgCoeff= roundToInt16(cgv*8192) * 0x0001000100010001ULL;
00651 c->ugCoeff= roundToInt16(cgu*8192) * 0x0001000100010001ULL;
00652 c->yOffset= roundToInt16(oy * 8) * 0x0001000100010001ULL;
00653
00654 c->yuv2rgb_y_coeff = (int16_t)roundToInt16(cy <<13);
00655 c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9);
00656 c->yuv2rgb_v2r_coeff= (int16_t)roundToInt16(crv<<13);
00657 c->yuv2rgb_v2g_coeff= (int16_t)roundToInt16(cgv<<13);
00658 c->yuv2rgb_u2g_coeff= (int16_t)roundToInt16(cgu<<13);
00659 c->yuv2rgb_u2b_coeff= (int16_t)roundToInt16(cbu<<13);
00660
00661
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 }