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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <inttypes.h>
00055 #include <string.h>
00056 #include <math.h>
00057 #include <stdio.h>
00058 #include "config.h"
00059 #include <assert.h>
00060 #include "swscale.h"
00061 #include "swscale_internal.h"
00062 #include "rgb2rgb.h"
00063 #include "libavutil/intreadwrite.h"
00064 #include "libavutil/x86_cpu.h"
00065 #include "libavutil/avutil.h"
00066 #include "libavutil/mathematics.h"
00067 #include "libavutil/bswap.h"
00068 #include "libavutil/pixdesc.h"
00069
00070 #undef MOVNTQ
00071 #undef PAVGB
00072
00073
00074
00075
00076
00077 #define DITHER1XBPP
00078
00079 #define FAST_BGR2YV12 // use 7 bit coefficients instead of 15 bit
00080
00081 #define isPacked(x) ( \
00082 (x)==PIX_FMT_PAL8 \
00083 || (x)==PIX_FMT_YUYV422 \
00084 || (x)==PIX_FMT_UYVY422 \
00085 || (x)==PIX_FMT_Y400A \
00086 || isAnyRGB(x) \
00087 )
00088
00089 #define RGB2YUV_SHIFT 15
00090 #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
00091 #define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00092 #define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00093 #define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
00094 #define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00095 #define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00096 #define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
00097 #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00098 #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00099
00100 static const double rgb2yuv_table[8][9]={
00101 {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5},
00102 {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5},
00103 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00104 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00105 {0.59 , 0.11 , 0.30 , -0.331, 0.5, -0.169, -0.421, -0.079, 0.5},
00106 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00107 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00108 {0.701 , 0.087 , 0.212 , -0.384, 0.5, -0.116, -0.445, -0.055, 0.5},
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 #if ARCH_X86
00127 DECLARE_ASM_CONST(8, uint64_t, bF8)= 0xF8F8F8F8F8F8F8F8LL;
00128 DECLARE_ASM_CONST(8, uint64_t, bFC)= 0xFCFCFCFCFCFCFCFCLL;
00129 DECLARE_ASM_CONST(8, uint64_t, w10)= 0x0010001000100010LL;
00130 DECLARE_ASM_CONST(8, uint64_t, w02)= 0x0002000200020002LL;
00131 DECLARE_ASM_CONST(8, uint64_t, bm00001111)=0x00000000FFFFFFFFLL;
00132 DECLARE_ASM_CONST(8, uint64_t, bm00000111)=0x0000000000FFFFFFLL;
00133 DECLARE_ASM_CONST(8, uint64_t, bm11111000)=0xFFFFFFFFFF000000LL;
00134 DECLARE_ASM_CONST(8, uint64_t, bm01010101)=0x00FF00FF00FF00FFLL;
00135
00136 const DECLARE_ALIGNED(8, uint64_t, ff_dither4)[2] = {
00137 0x0103010301030103LL,
00138 0x0200020002000200LL,};
00139
00140 const DECLARE_ALIGNED(8, uint64_t, ff_dither8)[2] = {
00141 0x0602060206020602LL,
00142 0x0004000400040004LL,};
00143
00144 DECLARE_ASM_CONST(8, uint64_t, b16Mask)= 0x001F001F001F001FLL;
00145 DECLARE_ASM_CONST(8, uint64_t, g16Mask)= 0x07E007E007E007E0LL;
00146 DECLARE_ASM_CONST(8, uint64_t, r16Mask)= 0xF800F800F800F800LL;
00147 DECLARE_ASM_CONST(8, uint64_t, b15Mask)= 0x001F001F001F001FLL;
00148 DECLARE_ASM_CONST(8, uint64_t, g15Mask)= 0x03E003E003E003E0LL;
00149 DECLARE_ASM_CONST(8, uint64_t, r15Mask)= 0x7C007C007C007C00LL;
00150
00151 DECLARE_ALIGNED(8, const uint64_t, ff_M24A) = 0x00FF0000FF0000FFLL;
00152 DECLARE_ALIGNED(8, const uint64_t, ff_M24B) = 0xFF0000FF0000FF00LL;
00153 DECLARE_ALIGNED(8, const uint64_t, ff_M24C) = 0x0000FF0000FF0000LL;
00154
00155 #ifdef FAST_BGR2YV12
00156 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000000210041000DULL;
00157 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000FFEEFFDC0038ULL;
00158 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00000038FFD2FFF8ULL;
00159 #else
00160 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000020E540830C8BULL;
00161 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000ED0FDAC23831ULL;
00162 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00003831D0E6F6EAULL;
00163 #endif
00164 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YOffset) = 0x1010101010101010ULL;
00165 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UVOffset) = 0x8080808080808080ULL;
00166 DECLARE_ALIGNED(8, const uint64_t, ff_w1111) = 0x0001000100010001ULL;
00167
00168 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY1Coeff) = 0x0C88000040870C88ULL;
00169 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY2Coeff) = 0x20DE4087000020DEULL;
00170 DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY1Coeff) = 0x20DE0000408720DEULL;
00171 DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY2Coeff) = 0x0C88408700000C88ULL;
00172 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toYOffset) = 0x0008400000084000ULL;
00173
00174 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUV)[2][4] = {
00175 {0x38380000DAC83838ULL, 0xECFFDAC80000ECFFULL, 0xF6E40000D0E3F6E4ULL, 0x3838D0E300003838ULL},
00176 {0xECFF0000DAC8ECFFULL, 0x3838DAC800003838ULL, 0x38380000D0E33838ULL, 0xF6E4D0E30000F6E4ULL},
00177 };
00178
00179 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUVOffset)= 0x0040400000404000ULL;
00180
00181 #endif
00182
00183 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_4)[2][8]={
00184 { 1, 3, 1, 3, 1, 3, 1, 3, },
00185 { 2, 0, 2, 0, 2, 0, 2, 0, },
00186 };
00187
00188 DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
00189 { 6, 2, 6, 2, 6, 2, 6, 2, },
00190 { 0, 4, 0, 4, 0, 4, 0, 4, },
00191 };
00192
00193 DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
00194 { 8, 4, 11, 7, 8, 4, 11, 7, },
00195 { 2, 14, 1, 13, 2, 14, 1, 13, },
00196 { 10, 6, 9, 5, 10, 6, 9, 5, },
00197 { 0, 12, 3, 15, 0, 12, 3, 15, },
00198 };
00199
00200 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
00201 { 17, 9, 23, 15, 16, 8, 22, 14, },
00202 { 5, 29, 3, 27, 4, 28, 2, 26, },
00203 { 21, 13, 19, 11, 20, 12, 18, 10, },
00204 { 0, 24, 6, 30, 1, 25, 7, 31, },
00205 { 16, 8, 22, 14, 17, 9, 23, 15, },
00206 { 4, 28, 2, 26, 5, 29, 3, 27, },
00207 { 20, 12, 18, 10, 21, 13, 19, 11, },
00208 { 1, 25, 7, 31, 0, 24, 6, 30, },
00209 };
00210
00211 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
00212 { 0, 55, 14, 68, 3, 58, 17, 72, },
00213 { 37, 18, 50, 32, 40, 22, 54, 35, },
00214 { 9, 64, 5, 59, 13, 67, 8, 63, },
00215 { 46, 27, 41, 23, 49, 31, 44, 26, },
00216 { 2, 57, 16, 71, 1, 56, 15, 70, },
00217 { 39, 21, 52, 34, 38, 19, 51, 33, },
00218 { 11, 66, 7, 62, 10, 65, 6, 60, },
00219 { 48, 30, 43, 25, 47, 29, 42, 24, },
00220 };
00221
00222 #if 1
00223 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
00224 {117, 62, 158, 103, 113, 58, 155, 100, },
00225 { 34, 199, 21, 186, 31, 196, 17, 182, },
00226 {144, 89, 131, 76, 141, 86, 127, 72, },
00227 { 0, 165, 41, 206, 10, 175, 52, 217, },
00228 {110, 55, 151, 96, 120, 65, 162, 107, },
00229 { 28, 193, 14, 179, 38, 203, 24, 189, },
00230 {138, 83, 124, 69, 148, 93, 134, 79, },
00231 { 7, 172, 48, 213, 3, 168, 45, 210, },
00232 };
00233 #elif 1
00234
00235 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
00236 { 0, 143, 18, 200, 2, 156, 25, 215, },
00237 { 78, 28, 125, 64, 89, 36, 138, 74, },
00238 { 10, 180, 3, 161, 16, 195, 8, 175, },
00239 {109, 51, 93, 38, 121, 60, 105, 47, },
00240 { 1, 152, 23, 210, 0, 147, 20, 205, },
00241 { 85, 33, 134, 71, 81, 30, 130, 67, },
00242 { 14, 190, 6, 171, 12, 185, 5, 166, },
00243 {117, 57, 101, 44, 113, 54, 97, 41, },
00244 };
00245 #elif 1
00246
00247 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
00248 { 0, 124, 8, 193, 0, 140, 12, 213, },
00249 { 55, 14, 104, 42, 66, 19, 119, 52, },
00250 { 3, 168, 1, 145, 6, 187, 3, 162, },
00251 { 86, 31, 70, 21, 99, 39, 82, 28, },
00252 { 0, 134, 11, 206, 0, 129, 9, 200, },
00253 { 62, 17, 114, 48, 58, 16, 109, 45, },
00254 { 5, 181, 2, 157, 4, 175, 1, 151, },
00255 { 95, 36, 78, 26, 90, 34, 74, 24, },
00256 };
00257 #else
00258
00259 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
00260 { 0, 107, 3, 187, 0, 125, 6, 212, },
00261 { 39, 7, 86, 28, 49, 11, 102, 36, },
00262 { 1, 158, 0, 131, 3, 180, 1, 151, },
00263 { 68, 19, 52, 12, 81, 25, 64, 17, },
00264 { 0, 119, 5, 203, 0, 113, 4, 195, },
00265 { 45, 9, 96, 33, 42, 8, 91, 30, },
00266 { 2, 172, 1, 144, 2, 165, 0, 137, },
00267 { 77, 23, 60, 15, 72, 21, 56, 14, },
00268 };
00269 #endif
00270
00271 static av_always_inline void yuv2yuvX16inC_template(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
00272 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
00273 const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest,
00274 int dstW, int chrDstW, int big_endian)
00275 {
00276
00277 int i;
00278
00279 for (i = 0; i < dstW; i++) {
00280 int val = 1 << 10;
00281 int j;
00282
00283 for (j = 0; j < lumFilterSize; j++)
00284 val += lumSrc[j][i] * lumFilter[j];
00285
00286 if (big_endian) {
00287 AV_WB16(&dest[i], av_clip_uint16(val >> 11));
00288 } else {
00289 AV_WL16(&dest[i], av_clip_uint16(val >> 11));
00290 }
00291 }
00292
00293 if (uDest) {
00294 for (i = 0; i < chrDstW; i++) {
00295 int u = 1 << 10;
00296 int v = 1 << 10;
00297 int j;
00298
00299 for (j = 0; j < chrFilterSize; j++) {
00300 u += chrSrc[j][i ] * chrFilter[j];
00301 v += chrSrc[j][i + VOFW] * chrFilter[j];
00302 }
00303
00304 if (big_endian) {
00305 AV_WB16(&uDest[i], av_clip_uint16(u >> 11));
00306 AV_WB16(&vDest[i], av_clip_uint16(v >> 11));
00307 } else {
00308 AV_WL16(&uDest[i], av_clip_uint16(u >> 11));
00309 AV_WL16(&vDest[i], av_clip_uint16(v >> 11));
00310 }
00311 }
00312 }
00313
00314 if (CONFIG_SWSCALE_ALPHA && aDest) {
00315 for (i = 0; i < dstW; i++) {
00316 int val = 1 << 10;
00317 int j;
00318
00319 for (j = 0; j < lumFilterSize; j++)
00320 val += alpSrc[j][i] * lumFilter[j];
00321
00322 if (big_endian) {
00323 AV_WB16(&aDest[i], av_clip_uint16(val >> 11));
00324 } else {
00325 AV_WL16(&aDest[i], av_clip_uint16(val >> 11));
00326 }
00327 }
00328 }
00329 }
00330
00331 static inline void yuv2yuvX16inC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
00332 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
00333 const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest, int dstW, int chrDstW,
00334 enum PixelFormat dstFormat)
00335 {
00336 if (isBE(dstFormat)) {
00337 yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize,
00338 chrFilter, chrSrc, chrFilterSize,
00339 alpSrc,
00340 dest, uDest, vDest, aDest,
00341 dstW, chrDstW, 1);
00342 } else {
00343 yuv2yuvX16inC_template(lumFilter, lumSrc, lumFilterSize,
00344 chrFilter, chrSrc, chrFilterSize,
00345 alpSrc,
00346 dest, uDest, vDest, aDest,
00347 dstW, chrDstW, 0);
00348 }
00349 }
00350
00351 static inline void yuv2yuvXinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
00352 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
00353 const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, int dstW, int chrDstW)
00354 {
00355
00356 int i;
00357 for (i=0; i<dstW; i++) {
00358 int val=1<<18;
00359 int j;
00360 for (j=0; j<lumFilterSize; j++)
00361 val += lumSrc[j][i] * lumFilter[j];
00362
00363 dest[i]= av_clip_uint8(val>>19);
00364 }
00365
00366 if (uDest)
00367 for (i=0; i<chrDstW; i++) {
00368 int u=1<<18;
00369 int v=1<<18;
00370 int j;
00371 for (j=0; j<chrFilterSize; j++) {
00372 u += chrSrc[j][i] * chrFilter[j];
00373 v += chrSrc[j][i + VOFW] * chrFilter[j];
00374 }
00375
00376 uDest[i]= av_clip_uint8(u>>19);
00377 vDest[i]= av_clip_uint8(v>>19);
00378 }
00379
00380 if (CONFIG_SWSCALE_ALPHA && aDest)
00381 for (i=0; i<dstW; i++) {
00382 int val=1<<18;
00383 int j;
00384 for (j=0; j<lumFilterSize; j++)
00385 val += alpSrc[j][i] * lumFilter[j];
00386
00387 aDest[i]= av_clip_uint8(val>>19);
00388 }
00389
00390 }
00391
00392 static inline void yuv2nv12XinC(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
00393 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
00394 uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
00395 {
00396
00397 int i;
00398 for (i=0; i<dstW; i++) {
00399 int val=1<<18;
00400 int j;
00401 for (j=0; j<lumFilterSize; j++)
00402 val += lumSrc[j][i] * lumFilter[j];
00403
00404 dest[i]= av_clip_uint8(val>>19);
00405 }
00406
00407 if (!uDest)
00408 return;
00409
00410 if (dstFormat == PIX_FMT_NV12)
00411 for (i=0; i<chrDstW; i++) {
00412 int u=1<<18;
00413 int v=1<<18;
00414 int j;
00415 for (j=0; j<chrFilterSize; j++) {
00416 u += chrSrc[j][i] * chrFilter[j];
00417 v += chrSrc[j][i + VOFW] * chrFilter[j];
00418 }
00419
00420 uDest[2*i]= av_clip_uint8(u>>19);
00421 uDest[2*i+1]= av_clip_uint8(v>>19);
00422 }
00423 else
00424 for (i=0; i<chrDstW; i++) {
00425 int u=1<<18;
00426 int v=1<<18;
00427 int j;
00428 for (j=0; j<chrFilterSize; j++) {
00429 u += chrSrc[j][i] * chrFilter[j];
00430 v += chrSrc[j][i + VOFW] * chrFilter[j];
00431 }
00432
00433 uDest[2*i]= av_clip_uint8(v>>19);
00434 uDest[2*i+1]= av_clip_uint8(u>>19);
00435 }
00436 }
00437
00438 #define YSCALE_YUV_2_PACKEDX_NOCLIP_C(type,alpha) \
00439 for (i=0; i<(dstW>>1); i++) {\
00440 int j;\
00441 int Y1 = 1<<18;\
00442 int Y2 = 1<<18;\
00443 int U = 1<<18;\
00444 int V = 1<<18;\
00445 int av_unused A1, A2;\
00446 type av_unused *r, *b, *g;\
00447 const int i2= 2*i;\
00448 \
00449 for (j=0; j<lumFilterSize; j++) {\
00450 Y1 += lumSrc[j][i2] * lumFilter[j];\
00451 Y2 += lumSrc[j][i2+1] * lumFilter[j];\
00452 }\
00453 for (j=0; j<chrFilterSize; j++) {\
00454 U += chrSrc[j][i] * chrFilter[j];\
00455 V += chrSrc[j][i+VOFW] * chrFilter[j];\
00456 }\
00457 Y1>>=19;\
00458 Y2>>=19;\
00459 U >>=19;\
00460 V >>=19;\
00461 if (alpha) {\
00462 A1 = 1<<18;\
00463 A2 = 1<<18;\
00464 for (j=0; j<lumFilterSize; j++) {\
00465 A1 += alpSrc[j][i2 ] * lumFilter[j];\
00466 A2 += alpSrc[j][i2+1] * lumFilter[j];\
00467 }\
00468 A1>>=19;\
00469 A2>>=19;\
00470 }
00471
00472 #define YSCALE_YUV_2_PACKEDX_C(type,alpha) \
00473 YSCALE_YUV_2_PACKEDX_NOCLIP_C(type,alpha)\
00474 if ((Y1|Y2|U|V)&256) {\
00475 if (Y1>255) Y1=255; \
00476 else if (Y1<0)Y1=0; \
00477 if (Y2>255) Y2=255; \
00478 else if (Y2<0)Y2=0; \
00479 if (U>255) U=255; \
00480 else if (U<0) U=0; \
00481 if (V>255) V=255; \
00482 else if (V<0) V=0; \
00483 }\
00484 if (alpha && ((A1|A2)&256)) {\
00485 A1=av_clip_uint8(A1);\
00486 A2=av_clip_uint8(A2);\
00487 }
00488
00489 #define YSCALE_YUV_2_PACKEDX_FULL_C(rnd,alpha) \
00490 for (i=0; i<dstW; i++) {\
00491 int j;\
00492 int Y = 0;\
00493 int U = -128<<19;\
00494 int V = -128<<19;\
00495 int av_unused A;\
00496 int R,G,B;\
00497 \
00498 for (j=0; j<lumFilterSize; j++) {\
00499 Y += lumSrc[j][i ] * lumFilter[j];\
00500 }\
00501 for (j=0; j<chrFilterSize; j++) {\
00502 U += chrSrc[j][i ] * chrFilter[j];\
00503 V += chrSrc[j][i+VOFW] * chrFilter[j];\
00504 }\
00505 Y >>=10;\
00506 U >>=10;\
00507 V >>=10;\
00508 if (alpha) {\
00509 A = rnd;\
00510 for (j=0; j<lumFilterSize; j++)\
00511 A += alpSrc[j][i ] * lumFilter[j];\
00512 A >>=19;\
00513 if (A&256)\
00514 A = av_clip_uint8(A);\
00515 }
00516
00517 #define YSCALE_YUV_2_RGBX_FULL_C(rnd,alpha) \
00518 YSCALE_YUV_2_PACKEDX_FULL_C(rnd>>3,alpha)\
00519 Y-= c->yuv2rgb_y_offset;\
00520 Y*= c->yuv2rgb_y_coeff;\
00521 Y+= rnd;\
00522 R= Y + V*c->yuv2rgb_v2r_coeff;\
00523 G= Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;\
00524 B= Y + U*c->yuv2rgb_u2b_coeff;\
00525 if ((R|G|B)&(0xC0000000)) {\
00526 if (R>=(256<<22)) R=(256<<22)-1; \
00527 else if (R<0)R=0; \
00528 if (G>=(256<<22)) G=(256<<22)-1; \
00529 else if (G<0)G=0; \
00530 if (B>=(256<<22)) B=(256<<22)-1; \
00531 else if (B<0)B=0; \
00532 }
00533
00534 #define YSCALE_YUV_2_GRAY16_C \
00535 for (i=0; i<(dstW>>1); i++) {\
00536 int j;\
00537 int Y1 = 1<<18;\
00538 int Y2 = 1<<18;\
00539 int U = 1<<18;\
00540 int V = 1<<18;\
00541 \
00542 const int i2= 2*i;\
00543 \
00544 for (j=0; j<lumFilterSize; j++) {\
00545 Y1 += lumSrc[j][i2] * lumFilter[j];\
00546 Y2 += lumSrc[j][i2+1] * lumFilter[j];\
00547 }\
00548 Y1>>=11;\
00549 Y2>>=11;\
00550 if ((Y1|Y2|U|V)&65536) {\
00551 if (Y1>65535) Y1=65535; \
00552 else if (Y1<0)Y1=0; \
00553 if (Y2>65535) Y2=65535; \
00554 else if (Y2<0)Y2=0; \
00555 }
00556
00557 #define YSCALE_YUV_2_RGBX_C(type,alpha) \
00558 YSCALE_YUV_2_PACKEDX_C(type,alpha) \
00559 r = (type *)c->table_rV[V]; \
00560 g = (type *)(c->table_gU[U] + c->table_gV[V]); \
00561 b = (type *)c->table_bU[U];
00562
00563 #define YSCALE_YUV_2_PACKED2_C(type,alpha) \
00564 for (i=0; i<(dstW>>1); i++) { \
00565 const int i2= 2*i; \
00566 int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \
00567 int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19; \
00568 int U= (uvbuf0[i ]*uvalpha1+uvbuf1[i ]*uvalpha)>>19; \
00569 int V= (uvbuf0[i+VOFW]*uvalpha1+uvbuf1[i+VOFW]*uvalpha)>>19; \
00570 type av_unused *r, *b, *g; \
00571 int av_unused A1, A2; \
00572 if (alpha) {\
00573 A1= (abuf0[i2 ]*yalpha1+abuf1[i2 ]*yalpha)>>19; \
00574 A2= (abuf0[i2+1]*yalpha1+abuf1[i2+1]*yalpha)>>19; \
00575 }
00576
00577 #define YSCALE_YUV_2_GRAY16_2_C \
00578 for (i=0; i<(dstW>>1); i++) { \
00579 const int i2= 2*i; \
00580 int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>11; \
00581 int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>11;
00582
00583 #define YSCALE_YUV_2_RGB2_C(type,alpha) \
00584 YSCALE_YUV_2_PACKED2_C(type,alpha)\
00585 r = (type *)c->table_rV[V];\
00586 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
00587 b = (type *)c->table_bU[U];
00588
00589 #define YSCALE_YUV_2_PACKED1_C(type,alpha) \
00590 for (i=0; i<(dstW>>1); i++) {\
00591 const int i2= 2*i;\
00592 int Y1= buf0[i2 ]>>7;\
00593 int Y2= buf0[i2+1]>>7;\
00594 int U= (uvbuf1[i ])>>7;\
00595 int V= (uvbuf1[i+VOFW])>>7;\
00596 type av_unused *r, *b, *g;\
00597 int av_unused A1, A2;\
00598 if (alpha) {\
00599 A1= abuf0[i2 ]>>7;\
00600 A2= abuf0[i2+1]>>7;\
00601 }
00602
00603 #define YSCALE_YUV_2_GRAY16_1_C \
00604 for (i=0; i<(dstW>>1); i++) {\
00605 const int i2= 2*i;\
00606 int Y1= buf0[i2 ]<<1;\
00607 int Y2= buf0[i2+1]<<1;
00608
00609 #define YSCALE_YUV_2_RGB1_C(type,alpha) \
00610 YSCALE_YUV_2_PACKED1_C(type,alpha)\
00611 r = (type *)c->table_rV[V];\
00612 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
00613 b = (type *)c->table_bU[U];
00614
00615 #define YSCALE_YUV_2_PACKED1B_C(type,alpha) \
00616 for (i=0; i<(dstW>>1); i++) {\
00617 const int i2= 2*i;\
00618 int Y1= buf0[i2 ]>>7;\
00619 int Y2= buf0[i2+1]>>7;\
00620 int U= (uvbuf0[i ] + uvbuf1[i ])>>8;\
00621 int V= (uvbuf0[i+VOFW] + uvbuf1[i+VOFW])>>8;\
00622 type av_unused *r, *b, *g;\
00623 int av_unused A1, A2;\
00624 if (alpha) {\
00625 A1= abuf0[i2 ]>>7;\
00626 A2= abuf0[i2+1]>>7;\
00627 }
00628
00629 #define YSCALE_YUV_2_RGB1B_C(type,alpha) \
00630 YSCALE_YUV_2_PACKED1B_C(type,alpha)\
00631 r = (type *)c->table_rV[V];\
00632 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
00633 b = (type *)c->table_bU[U];
00634
00635 #define YSCALE_YUV_2_MONO2_C \
00636 const uint8_t * const d128=dither_8x8_220[y&7];\
00637 uint8_t *g= c->table_gU[128] + c->table_gV[128];\
00638 for (i=0; i<dstW-7; i+=8) {\
00639 int acc;\
00640 acc = g[((buf0[i ]*yalpha1+buf1[i ]*yalpha)>>19) + d128[0]];\
00641 acc+= acc + g[((buf0[i+1]*yalpha1+buf1[i+1]*yalpha)>>19) + d128[1]];\
00642 acc+= acc + g[((buf0[i+2]*yalpha1+buf1[i+2]*yalpha)>>19) + d128[2]];\
00643 acc+= acc + g[((buf0[i+3]*yalpha1+buf1[i+3]*yalpha)>>19) + d128[3]];\
00644 acc+= acc + g[((buf0[i+4]*yalpha1+buf1[i+4]*yalpha)>>19) + d128[4]];\
00645 acc+= acc + g[((buf0[i+5]*yalpha1+buf1[i+5]*yalpha)>>19) + d128[5]];\
00646 acc+= acc + g[((buf0[i+6]*yalpha1+buf1[i+6]*yalpha)>>19) + d128[6]];\
00647 acc+= acc + g[((buf0[i+7]*yalpha1+buf1[i+7]*yalpha)>>19) + d128[7]];\
00648 ((uint8_t*)dest)[0]= c->dstFormat == PIX_FMT_MONOBLACK ? acc : ~acc;\
00649 dest++;\
00650 }
00651
00652 #define YSCALE_YUV_2_MONOX_C \
00653 const uint8_t * const d128=dither_8x8_220[y&7];\
00654 uint8_t *g= c->table_gU[128] + c->table_gV[128];\
00655 int acc=0;\
00656 for (i=0; i<dstW-1; i+=2) {\
00657 int j;\
00658 int Y1=1<<18;\
00659 int Y2=1<<18;\
00660 \
00661 for (j=0; j<lumFilterSize; j++) {\
00662 Y1 += lumSrc[j][i] * lumFilter[j];\
00663 Y2 += lumSrc[j][i+1] * lumFilter[j];\
00664 }\
00665 Y1>>=19;\
00666 Y2>>=19;\
00667 if ((Y1|Y2)&256) {\
00668 if (Y1>255) Y1=255;\
00669 else if (Y1<0)Y1=0;\
00670 if (Y2>255) Y2=255;\
00671 else if (Y2<0)Y2=0;\
00672 }\
00673 acc+= acc + g[Y1+d128[(i+0)&7]];\
00674 acc+= acc + g[Y2+d128[(i+1)&7]];\
00675 if ((i&7)==6) {\
00676 ((uint8_t*)dest)[0]= c->dstFormat == PIX_FMT_MONOBLACK ? acc : ~acc;\
00677 dest++;\
00678 }\
00679 }
00680
00681 #define YSCALE_YUV_2_ANYRGB_C(func, func2, func_g16, func_monoblack)\
00682 switch(c->dstFormat) {\
00683 case PIX_FMT_RGB48BE:\
00684 case PIX_FMT_RGB48LE:\
00685 func(uint8_t,0)\
00686 ((uint8_t*)dest)[ 0]= r[Y1];\
00687 ((uint8_t*)dest)[ 1]= r[Y1];\
00688 ((uint8_t*)dest)[ 2]= g[Y1];\
00689 ((uint8_t*)dest)[ 3]= g[Y1];\
00690 ((uint8_t*)dest)[ 4]= b[Y1];\
00691 ((uint8_t*)dest)[ 5]= b[Y1];\
00692 ((uint8_t*)dest)[ 6]= r[Y2];\
00693 ((uint8_t*)dest)[ 7]= r[Y2];\
00694 ((uint8_t*)dest)[ 8]= g[Y2];\
00695 ((uint8_t*)dest)[ 9]= g[Y2];\
00696 ((uint8_t*)dest)[10]= b[Y2];\
00697 ((uint8_t*)dest)[11]= b[Y2];\
00698 dest+=12;\
00699 }\
00700 break;\
00701 case PIX_FMT_RGBA:\
00702 case PIX_FMT_BGRA:\
00703 if (CONFIG_SMALL) {\
00704 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
00705 func(uint32_t,needAlpha)\
00706 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? (A1<<24) : 0);\
00707 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? (A2<<24) : 0);\
00708 }\
00709 } else {\
00710 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
00711 func(uint32_t,1)\
00712 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (A1<<24);\
00713 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (A2<<24);\
00714 }\
00715 } else {\
00716 func(uint32_t,0)\
00717 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
00718 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
00719 }\
00720 }\
00721 }\
00722 break;\
00723 case PIX_FMT_ARGB:\
00724 case PIX_FMT_ABGR:\
00725 if (CONFIG_SMALL) {\
00726 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;\
00727 func(uint32_t,needAlpha)\
00728 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + (needAlpha ? A1 : 0);\
00729 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + (needAlpha ? A2 : 0);\
00730 }\
00731 } else {\
00732 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {\
00733 func(uint32_t,1)\
00734 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1] + A1;\
00735 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2] + A2;\
00736 }\
00737 } else {\
00738 func(uint32_t,0)\
00739 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
00740 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
00741 }\
00742 }\
00743 } \
00744 break;\
00745 case PIX_FMT_RGB24:\
00746 func(uint8_t,0)\
00747 ((uint8_t*)dest)[0]= r[Y1];\
00748 ((uint8_t*)dest)[1]= g[Y1];\
00749 ((uint8_t*)dest)[2]= b[Y1];\
00750 ((uint8_t*)dest)[3]= r[Y2];\
00751 ((uint8_t*)dest)[4]= g[Y2];\
00752 ((uint8_t*)dest)[5]= b[Y2];\
00753 dest+=6;\
00754 }\
00755 break;\
00756 case PIX_FMT_BGR24:\
00757 func(uint8_t,0)\
00758 ((uint8_t*)dest)[0]= b[Y1];\
00759 ((uint8_t*)dest)[1]= g[Y1];\
00760 ((uint8_t*)dest)[2]= r[Y1];\
00761 ((uint8_t*)dest)[3]= b[Y2];\
00762 ((uint8_t*)dest)[4]= g[Y2];\
00763 ((uint8_t*)dest)[5]= r[Y2];\
00764 dest+=6;\
00765 }\
00766 break;\
00767 case PIX_FMT_RGB565BE:\
00768 case PIX_FMT_RGB565LE:\
00769 case PIX_FMT_BGR565BE:\
00770 case PIX_FMT_BGR565LE:\
00771 {\
00772 const int dr1= dither_2x2_8[y&1 ][0];\
00773 const int dg1= dither_2x2_4[y&1 ][0];\
00774 const int db1= dither_2x2_8[(y&1)^1][0];\
00775 const int dr2= dither_2x2_8[y&1 ][1];\
00776 const int dg2= dither_2x2_4[y&1 ][1];\
00777 const int db2= dither_2x2_8[(y&1)^1][1];\
00778 func(uint16_t,0)\
00779 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
00780 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
00781 }\
00782 }\
00783 break;\
00784 case PIX_FMT_RGB555BE:\
00785 case PIX_FMT_RGB555LE:\
00786 case PIX_FMT_BGR555BE:\
00787 case PIX_FMT_BGR555LE:\
00788 {\
00789 const int dr1= dither_2x2_8[y&1 ][0];\
00790 const int dg1= dither_2x2_8[y&1 ][1];\
00791 const int db1= dither_2x2_8[(y&1)^1][0];\
00792 const int dr2= dither_2x2_8[y&1 ][1];\
00793 const int dg2= dither_2x2_8[y&1 ][0];\
00794 const int db2= dither_2x2_8[(y&1)^1][1];\
00795 func(uint16_t,0)\
00796 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
00797 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
00798 }\
00799 }\
00800 break;\
00801 case PIX_FMT_RGB444BE:\
00802 case PIX_FMT_RGB444LE:\
00803 case PIX_FMT_BGR444BE:\
00804 case PIX_FMT_BGR444LE:\
00805 {\
00806 const int dr1= dither_4x4_16[y&3 ][0];\
00807 const int dg1= dither_4x4_16[y&3 ][1];\
00808 const int db1= dither_4x4_16[(y&3)^3][0];\
00809 const int dr2= dither_4x4_16[y&3 ][1];\
00810 const int dg2= dither_4x4_16[y&3 ][0];\
00811 const int db2= dither_4x4_16[(y&3)^3][1];\
00812 func(uint16_t,0)\
00813 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
00814 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
00815 }\
00816 }\
00817 break;\
00818 case PIX_FMT_RGB8:\
00819 case PIX_FMT_BGR8:\
00820 {\
00821 const uint8_t * const d64= dither_8x8_73[y&7];\
00822 const uint8_t * const d32= dither_8x8_32[y&7];\
00823 func(uint8_t,0)\
00824 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
00825 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
00826 }\
00827 }\
00828 break;\
00829 case PIX_FMT_RGB4:\
00830 case PIX_FMT_BGR4:\
00831 {\
00832 const uint8_t * const d64= dither_8x8_73 [y&7];\
00833 const uint8_t * const d128=dither_8x8_220[y&7];\
00834 func(uint8_t,0)\
00835 ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\
00836 + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\
00837 }\
00838 }\
00839 break;\
00840 case PIX_FMT_RGB4_BYTE:\
00841 case PIX_FMT_BGR4_BYTE:\
00842 {\
00843 const uint8_t * const d64= dither_8x8_73 [y&7];\
00844 const uint8_t * const d128=dither_8x8_220[y&7];\
00845 func(uint8_t,0)\
00846 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
00847 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
00848 }\
00849 }\
00850 break;\
00851 case PIX_FMT_MONOBLACK:\
00852 case PIX_FMT_MONOWHITE:\
00853 {\
00854 func_monoblack\
00855 }\
00856 break;\
00857 case PIX_FMT_YUYV422:\
00858 func2\
00859 ((uint8_t*)dest)[2*i2+0]= Y1;\
00860 ((uint8_t*)dest)[2*i2+1]= U;\
00861 ((uint8_t*)dest)[2*i2+2]= Y2;\
00862 ((uint8_t*)dest)[2*i2+3]= V;\
00863 } \
00864 break;\
00865 case PIX_FMT_UYVY422:\
00866 func2\
00867 ((uint8_t*)dest)[2*i2+0]= U;\
00868 ((uint8_t*)dest)[2*i2+1]= Y1;\
00869 ((uint8_t*)dest)[2*i2+2]= V;\
00870 ((uint8_t*)dest)[2*i2+3]= Y2;\
00871 } \
00872 break;\
00873 case PIX_FMT_GRAY16BE:\
00874 func_g16\
00875 ((uint8_t*)dest)[2*i2+0]= Y1>>8;\
00876 ((uint8_t*)dest)[2*i2+1]= Y1;\
00877 ((uint8_t*)dest)[2*i2+2]= Y2>>8;\
00878 ((uint8_t*)dest)[2*i2+3]= Y2;\
00879 } \
00880 break;\
00881 case PIX_FMT_GRAY16LE:\
00882 func_g16\
00883 ((uint8_t*)dest)[2*i2+0]= Y1;\
00884 ((uint8_t*)dest)[2*i2+1]= Y1>>8;\
00885 ((uint8_t*)dest)[2*i2+2]= Y2;\
00886 ((uint8_t*)dest)[2*i2+3]= Y2>>8;\
00887 } \
00888 break;\
00889 }
00890
00891 static inline void yuv2packedXinC(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
00892 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
00893 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
00894 {
00895 int i;
00896 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C, YSCALE_YUV_2_PACKEDX_C(void,0), YSCALE_YUV_2_GRAY16_C, YSCALE_YUV_2_MONOX_C)
00897 }
00898
00899 static inline void yuv2rgbXinC_full(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
00900 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
00901 const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
00902 {
00903 int i;
00904 int step= c->dstFormatBpp/8;
00905 int aidx= 3;
00906
00907 switch(c->dstFormat) {
00908 case PIX_FMT_ARGB:
00909 dest++;
00910 aidx= 0;
00911 case PIX_FMT_RGB24:
00912 aidx--;
00913 case PIX_FMT_RGBA:
00914 if (CONFIG_SMALL) {
00915 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
00916 YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
00917 dest[aidx]= needAlpha ? A : 255;
00918 dest[0]= R>>22;
00919 dest[1]= G>>22;
00920 dest[2]= B>>22;
00921 dest+= step;
00922 }
00923 } else {
00924 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
00925 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
00926 dest[aidx]= A;
00927 dest[0]= R>>22;
00928 dest[1]= G>>22;
00929 dest[2]= B>>22;
00930 dest+= step;
00931 }
00932 } else {
00933 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
00934 dest[aidx]= 255;
00935 dest[0]= R>>22;
00936 dest[1]= G>>22;
00937 dest[2]= B>>22;
00938 dest+= step;
00939 }
00940 }
00941 }
00942 break;
00943 case PIX_FMT_ABGR:
00944 dest++;
00945 aidx= 0;
00946 case PIX_FMT_BGR24:
00947 aidx--;
00948 case PIX_FMT_BGRA:
00949 if (CONFIG_SMALL) {
00950 int needAlpha = CONFIG_SWSCALE_ALPHA && c->alpPixBuf;
00951 YSCALE_YUV_2_RGBX_FULL_C(1<<21, needAlpha)
00952 dest[aidx]= needAlpha ? A : 255;
00953 dest[0]= B>>22;
00954 dest[1]= G>>22;
00955 dest[2]= R>>22;
00956 dest+= step;
00957 }
00958 } else {
00959 if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
00960 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 1)
00961 dest[aidx]= A;
00962 dest[0]= B>>22;
00963 dest[1]= G>>22;
00964 dest[2]= R>>22;
00965 dest+= step;
00966 }
00967 } else {
00968 YSCALE_YUV_2_RGBX_FULL_C(1<<21, 0)
00969 dest[aidx]= 255;
00970 dest[0]= B>>22;
00971 dest[1]= G>>22;
00972 dest[2]= R>>22;
00973 dest+= step;
00974 }
00975 }
00976 }
00977 break;
00978 default:
00979 assert(0);
00980 }
00981 }
00982
00983 static void fillPlane(uint8_t* plane, int stride, int width, int height, int y, uint8_t val)
00984 {
00985 int i;
00986 uint8_t *ptr = plane + stride*y;
00987 for (i=0; i<height; i++) {
00988 memset(ptr, val, width);
00989 ptr += stride;
00990 }
00991 }
00992
00993 static inline void rgb48ToY(uint8_t *dst, const uint8_t *src, long width,
00994 uint32_t *unused)
00995 {
00996 int i;
00997 for (i = 0; i < width; i++) {
00998 int r = src[i*6+0];
00999 int g = src[i*6+2];
01000 int b = src[i*6+4];
01001
01002 dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
01003 }
01004 }
01005
01006 static inline void rgb48ToUV(uint8_t *dstU, uint8_t *dstV,
01007 const uint8_t *src1, const uint8_t *src2,
01008 long width, uint32_t *unused)
01009 {
01010 int i;
01011 assert(src1==src2);
01012 for (i = 0; i < width; i++) {
01013 int r = src1[6*i + 0];
01014 int g = src1[6*i + 2];
01015 int b = src1[6*i + 4];
01016
01017 dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
01018 dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
01019 }
01020 }
01021
01022 static inline void rgb48ToUV_half(uint8_t *dstU, uint8_t *dstV,
01023 const uint8_t *src1, const uint8_t *src2,
01024 long width, uint32_t *unused)
01025 {
01026 int i;
01027 assert(src1==src2);
01028 for (i = 0; i < width; i++) {
01029 int r= src1[12*i + 0] + src1[12*i + 6];
01030 int g= src1[12*i + 2] + src1[12*i + 8];
01031 int b= src1[12*i + 4] + src1[12*i + 10];
01032
01033 dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
01034 dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
01035 }
01036 }
01037
01038 #define BGR2Y(type, name, shr, shg, shb, maskr, maskg, maskb, RY, GY, BY, S)\
01039 static inline void name(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)\
01040 {\
01041 int i;\
01042 for (i=0; i<width; i++) {\
01043 int b= (((const type*)src)[i]>>shb)&maskb;\
01044 int g= (((const type*)src)[i]>>shg)&maskg;\
01045 int r= (((const type*)src)[i]>>shr)&maskr;\
01046 \
01047 dst[i]= (((RY)*r + (GY)*g + (BY)*b + (33<<((S)-1)))>>(S));\
01048 }\
01049 }
01050
01051 BGR2Y(uint32_t, bgr32ToY,16, 0, 0, 0x00FF, 0xFF00, 0x00FF, RY<< 8, GY , BY<< 8, RGB2YUV_SHIFT+8)
01052 BGR2Y(uint32_t,bgr321ToY,16,16, 0, 0xFF00, 0x00FF, 0xFF00, RY , GY<<8, BY , RGB2YUV_SHIFT+8)
01053 BGR2Y(uint32_t, rgb32ToY, 0, 0,16, 0x00FF, 0xFF00, 0x00FF, RY<< 8, GY , BY<< 8, RGB2YUV_SHIFT+8)
01054 BGR2Y(uint32_t,rgb321ToY, 0,16,16, 0xFF00, 0x00FF, 0xFF00, RY , GY<<8, BY , RGB2YUV_SHIFT+8)
01055 BGR2Y(uint16_t, bgr16ToY, 0, 0, 0, 0x001F, 0x07E0, 0xF800, RY<<11, GY<<5, BY , RGB2YUV_SHIFT+8)
01056 BGR2Y(uint16_t, bgr15ToY, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, RY<<10, GY<<5, BY , RGB2YUV_SHIFT+7)
01057 BGR2Y(uint16_t, rgb16ToY, 0, 0, 0, 0xF800, 0x07E0, 0x001F, RY , GY<<5, BY<<11, RGB2YUV_SHIFT+8)
01058 BGR2Y(uint16_t, rgb15ToY, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, RY , GY<<5, BY<<10, RGB2YUV_SHIFT+7)
01059
01060 static inline void abgrToA(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
01061 {
01062 int i;
01063 for (i=0; i<width; i++) {
01064 dst[i]= src[4*i];
01065 }
01066 }
01067
01068 #define BGR2UV(type, name, shr, shg, shb, shp, maskr, maskg, maskb, RU, GU, BU, RV, GV, BV, S) \
01069 static inline void name(uint8_t *dstU, uint8_t *dstV, const uint8_t *src, const uint8_t *dummy, long width, uint32_t *unused)\
01070 {\
01071 int i;\
01072 for (i=0; i<width; i++) {\
01073 int b= ((((const type*)src)[i]>>shp)&maskb)>>shb;\
01074 int g= ((((const type*)src)[i]>>shp)&maskg)>>shg;\
01075 int r= ((((const type*)src)[i]>>shp)&maskr)>>shr;\
01076 \
01077 dstU[i]= ((RU)*r + (GU)*g + (BU)*b + (257<<((S)-1)))>>(S);\
01078 dstV[i]= ((RV)*r + (GV)*g + (BV)*b + (257<<((S)-1)))>>(S);\
01079 }\
01080 }\
01081 static inline void name ## _half(uint8_t *dstU, uint8_t *dstV, const uint8_t *src, const uint8_t *dummy, long width, uint32_t *unused)\
01082 {\
01083 int i;\
01084 for (i=0; i<width; i++) {\
01085 int pix0= ((const type*)src)[2*i+0]>>shp;\
01086 int pix1= ((const type*)src)[2*i+1]>>shp;\
01087 int g= (pix0&~(maskr|maskb))+(pix1&~(maskr|maskb));\
01088 int b= ((pix0+pix1-g)&(maskb|(2*maskb)))>>shb;\
01089 int r= ((pix0+pix1-g)&(maskr|(2*maskr)))>>shr;\
01090 g&= maskg|(2*maskg);\
01091 \
01092 g>>=shg;\
01093 \
01094 dstU[i]= ((RU)*r + (GU)*g + (BU)*b + (257<<(S)))>>((S)+1);\
01095 dstV[i]= ((RV)*r + (GV)*g + (BV)*b + (257<<(S)))>>((S)+1);\
01096 }\
01097 }
01098
01099 BGR2UV(uint32_t, bgr32ToUV,16, 0, 0, 0, 0xFF0000, 0xFF00, 0x00FF, RU<< 8, GU , BU<< 8, RV<< 8, GV , BV<< 8, RGB2YUV_SHIFT+8)
01100 BGR2UV(uint32_t,bgr321ToUV,16, 0, 0, 8, 0xFF0000, 0xFF00, 0x00FF, RU<< 8, GU , BU<< 8, RV<< 8, GV , BV<< 8, RGB2YUV_SHIFT+8)
01101 BGR2UV(uint32_t, rgb32ToUV, 0, 0,16, 0, 0x00FF, 0xFF00, 0xFF0000, RU<< 8, GU , BU<< 8, RV<< 8, GV , BV<< 8, RGB2YUV_SHIFT+8)
01102 BGR2UV(uint32_t,rgb321ToUV, 0, 0,16, 8, 0x00FF, 0xFF00, 0xFF0000, RU<< 8, GU , BU<< 8, RV<< 8, GV , BV<< 8, RGB2YUV_SHIFT+8)
01103 BGR2UV(uint16_t, bgr16ToUV, 0, 0, 0, 0, 0x001F, 0x07E0, 0xF800, RU<<11, GU<<5, BU , RV<<11, GV<<5, BV , RGB2YUV_SHIFT+8)
01104 BGR2UV(uint16_t, bgr15ToUV, 0, 0, 0, 0, 0x001F, 0x03E0, 0x7C00, RU<<10, GU<<5, BU , RV<<10, GV<<5, BV , RGB2YUV_SHIFT+7)
01105 BGR2UV(uint16_t, rgb16ToUV, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, RU , GU<<5, BU<<11, RV , GV<<5, BV<<11, RGB2YUV_SHIFT+8)
01106 BGR2UV(uint16_t, rgb15ToUV, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, RU , GU<<5, BU<<10, RV , GV<<5, BV<<10, RGB2YUV_SHIFT+7)
01107
01108 static inline void palToY(uint8_t *dst, const uint8_t *src, long width, uint32_t *pal)
01109 {
01110 int i;
01111 for (i=0; i<width; i++) {
01112 int d= src[i];
01113
01114 dst[i]= pal[d] & 0xFF;
01115 }
01116 }
01117
01118 static inline void palToUV(uint8_t *dstU, uint8_t *dstV,
01119 const uint8_t *src1, const uint8_t *src2,
01120 long width, uint32_t *pal)
01121 {
01122 int i;
01123 assert(src1 == src2);
01124 for (i=0; i<width; i++) {
01125 int p= pal[src1[i]];
01126
01127 dstU[i]= p>>8;
01128 dstV[i]= p>>16;
01129 }
01130 }
01131
01132 static inline void monowhite2Y(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
01133 {
01134 int i, j;
01135 for (i=0; i<width/8; i++) {
01136 int d= ~src[i];
01137 for(j=0; j<8; j++)
01138 dst[8*i+j]= ((d>>(7-j))&1)*255;
01139 }
01140 }
01141
01142 static inline void monoblack2Y(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
01143 {
01144 int i, j;
01145 for (i=0; i<width/8; i++) {
01146 int d= src[i];
01147 for(j=0; j<8; j++)
01148 dst[8*i+j]= ((d>>(7-j))&1)*255;
01149 }
01150 }
01151
01152
01153
01154 #if CONFIG_RUNTIME_CPUDETECT
01155 # define COMPILE_C 1
01156 # if ARCH_X86
01157 # define COMPILE_MMX HAVE_MMX
01158 # define COMPILE_MMX2 HAVE_MMX2
01159 # define COMPILE_3DNOW HAVE_AMD3DNOW
01160 # elif ARCH_PPC
01161 # define COMPILE_ALTIVEC HAVE_ALTIVEC
01162 # endif
01163 #else
01164 # if ARCH_X86
01165 # if HAVE_MMX2
01166 # define COMPILE_MMX2 1
01167 # elif HAVE_AMD3DNOW
01168 # define COMPILE_3DNOW 1
01169 # elif HAVE_MMX
01170 # define COMPILE_MMX 1
01171 # else
01172 # define COMPILE_C 1
01173 # endif
01174 # elif ARCH_PPC && HAVE_ALTIVEC
01175 # define COMPILE_ALTIVEC 1
01176 # else
01177 # define COMPILE_C 1
01178 # endif
01179 #endif
01180
01181 #ifndef COMPILE_C
01182 # define COMPILE_C 0
01183 #endif
01184 #ifndef COMPILE_MMX
01185 # define COMPILE_MMX 0
01186 #endif
01187 #ifndef COMPILE_MMX2
01188 # define COMPILE_MMX2 0
01189 #endif
01190 #ifndef COMPILE_3DNOW
01191 # define COMPILE_3DNOW 0
01192 #endif
01193 #ifndef COMPILE_ALTIVEC
01194 # define COMPILE_ALTIVEC 0
01195 #endif
01196
01197 #define COMPILE_TEMPLATE_MMX 0
01198 #define COMPILE_TEMPLATE_MMX2 0
01199 #define COMPILE_TEMPLATE_AMD3DNOW 0
01200 #define COMPILE_TEMPLATE_ALTIVEC 0
01201
01202 #if COMPILE_C
01203 #define RENAME(a) a ## _C
01204 #include "swscale_template.c"
01205 #endif
01206
01207 #if COMPILE_ALTIVEC
01208 #undef RENAME
01209 #undef COMPILE_TEMPLATE_ALTIVEC
01210 #define COMPILE_TEMPLATE_ALTIVEC 1
01211 #define RENAME(a) a ## _altivec
01212 #include "swscale_template.c"
01213 #endif
01214
01215 #if ARCH_X86
01216
01217
01218 #if COMPILE_MMX
01219 #undef RENAME
01220 #undef COMPILE_TEMPLATE_MMX
01221 #undef COMPILE_TEMPLATE_MMX2
01222 #undef COMPILE_TEMPLATE_AMD3DNOW
01223 #define COMPILE_TEMPLATE_MMX 1
01224 #define COMPILE_TEMPLATE_MMX2 0
01225 #define COMPILE_TEMPLATE_AMD3DNOW 0
01226 #define RENAME(a) a ## _MMX
01227 #include "swscale_template.c"
01228 #endif
01229
01230
01231 #if COMPILE_MMX2
01232 #undef RENAME
01233 #undef COMPILE_TEMPLATE_MMX
01234 #undef COMPILE_TEMPLATE_MMX2
01235 #undef COMPILE_TEMPLATE_AMD3DNOW
01236 #define COMPILE_TEMPLATE_MMX 1
01237 #define COMPILE_TEMPLATE_MMX2 1
01238 #define COMPILE_TEMPLATE_AMD3DNOW 0
01239 #define RENAME(a) a ## _MMX2
01240 #include "swscale_template.c"
01241 #endif
01242
01243
01244 #if COMPILE_3DNOW
01245 #undef RENAME
01246 #undef COMPILE_TEMPLATE_MMX
01247 #undef COMPILE_TEMPLATE_MMX2
01248 #undef COMPILE_TEMPLATE_AMD3DNOW
01249 #define COMPILE_TEMPLATE_MMX 1
01250 #define COMPILE_TEMPLATE_MMX2 0
01251 #define COMPILE_TEMPLATE_AMD3DNOW 1
01252 #define RENAME(a) a ## _3DNow
01253 #include "swscale_template.c"
01254 #endif
01255
01256 #endif //ARCH_X86
01257
01258 SwsFunc ff_getSwsFunc(SwsContext *c)
01259 {
01260 #if CONFIG_RUNTIME_CPUDETECT
01261 int flags = c->flags;
01262
01263 #if ARCH_X86
01264
01265 if (flags & SWS_CPU_CAPS_MMX2) {
01266 sws_init_swScale_MMX2(c);
01267 return swScale_MMX2;
01268 } else if (flags & SWS_CPU_CAPS_3DNOW) {
01269 sws_init_swScale_3DNow(c);
01270 return swScale_3DNow;
01271 } else if (flags & SWS_CPU_CAPS_MMX) {
01272 sws_init_swScale_MMX(c);
01273 return swScale_MMX;
01274 } else {
01275 sws_init_swScale_C(c);
01276 return swScale_C;
01277 }
01278
01279 #else
01280 #if COMPILE_ALTIVEC
01281 if (flags & SWS_CPU_CAPS_ALTIVEC) {
01282 sws_init_swScale_altivec(c);
01283 return swScale_altivec;
01284 } else {
01285 sws_init_swScale_C(c);
01286 return swScale_C;
01287 }
01288 #endif
01289 sws_init_swScale_C(c);
01290 return swScale_C;
01291 #endif
01292 #else //CONFIG_RUNTIME_CPUDETECT
01293 #if COMPILE_TEMPLATE_MMX2
01294 sws_init_swScale_MMX2(c);
01295 return swScale_MMX2;
01296 #elif COMPILE_TEMPLATE_AMD3DNOW
01297 sws_init_swScale_3DNow(c);
01298 return swScale_3DNow;
01299 #elif COMPILE_TEMPLATE_MMX
01300 sws_init_swScale_MMX(c);
01301 return swScale_MMX;
01302 #elif COMPILE_TEMPLATE_ALTIVEC
01303 sws_init_swScale_altivec(c);
01304 return swScale_altivec;
01305 #else
01306 sws_init_swScale_C(c);
01307 return swScale_C;
01308 #endif
01309 #endif
01310 }
01311
01312 static void copyPlane(const uint8_t *src, int srcStride,
01313 int srcSliceY, int srcSliceH, int width,
01314 uint8_t *dst, int dstStride)
01315 {
01316 dst += dstStride * srcSliceY;
01317 if (dstStride == srcStride && srcStride > 0) {
01318 memcpy(dst, src, srcSliceH * dstStride);
01319 } else {
01320 int i;
01321 for (i=0; i<srcSliceH; i++) {
01322 memcpy(dst, src, width);
01323 src += srcStride;
01324 dst += dstStride;
01325 }
01326 }
01327 }
01328
01329 static int planarToNv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01330 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01331 {
01332 uint8_t *dst = dstParam[1] + dstStride[1]*srcSliceY/2;
01333
01334 copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
01335 dstParam[0], dstStride[0]);
01336
01337 if (c->dstFormat == PIX_FMT_NV12)
01338 interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]);
01339 else
01340 interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]);
01341
01342 return srcSliceH;
01343 }
01344
01345 static int planarToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01346 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01347 {
01348 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01349
01350 yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
01351
01352 return srcSliceH;
01353 }
01354
01355 static int planarToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01356 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01357 {
01358 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01359
01360 yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
01361
01362 return srcSliceH;
01363 }
01364
01365 static int yuv422pToYuy2Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01366 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01367 {
01368 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01369
01370 yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
01371
01372 return srcSliceH;
01373 }
01374
01375 static int yuv422pToUyvyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01376 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01377 {
01378 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01379
01380 yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
01381
01382 return srcSliceH;
01383 }
01384
01385 static int yuyvToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01386 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01387 {
01388 uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
01389 uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
01390 uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
01391
01392 yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
01393
01394 if (dstParam[3])
01395 fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
01396
01397 return srcSliceH;
01398 }
01399
01400 static int yuyvToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01401 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01402 {
01403 uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
01404 uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
01405 uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
01406
01407 yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
01408
01409 return srcSliceH;
01410 }
01411
01412 static int uyvyToYuv420Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01413 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01414 {
01415 uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
01416 uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY/2;
01417 uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY/2;
01418
01419 uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
01420
01421 if (dstParam[3])
01422 fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
01423
01424 return srcSliceH;
01425 }
01426
01427 static int uyvyToYuv422Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01428 int srcSliceH, uint8_t* dstParam[], int dstStride[])
01429 {
01430 uint8_t *ydst=dstParam[0] + dstStride[0]*srcSliceY;
01431 uint8_t *udst=dstParam[1] + dstStride[1]*srcSliceY;
01432 uint8_t *vdst=dstParam[2] + dstStride[2]*srcSliceY;
01433
01434 uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0], dstStride[1], srcStride[0]);
01435
01436 return srcSliceH;
01437 }
01438
01439 static void gray8aToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
01440 {
01441 long i;
01442 for (i=0; i<num_pixels; i++)
01443 ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | (src[(i<<1)+1] << 24);
01444 }
01445
01446 static void gray8aToPacked32_1(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
01447 {
01448 long i;
01449
01450 for (i=0; i<num_pixels; i++)
01451 ((uint32_t *) dst)[i] = ((const uint32_t *)palette)[src[i<<1]] | src[(i<<1)+1];
01452 }
01453
01454 static void gray8aToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
01455 {
01456 long i;
01457
01458 for (i=0; i<num_pixels; i++) {
01459
01460 dst[0]= palette[src[i<<1]*4+0];
01461 dst[1]= palette[src[i<<1]*4+1];
01462 dst[2]= palette[src[i<<1]*4+2];
01463 dst+= 3;
01464 }
01465 }
01466
01467 static int palToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01468 int srcSliceH, uint8_t* dst[], int dstStride[])
01469 {
01470 const enum PixelFormat srcFormat= c->srcFormat;
01471 const enum PixelFormat dstFormat= c->dstFormat;
01472 void (*conv)(const uint8_t *src, uint8_t *dst, long num_pixels,
01473 const uint8_t *palette)=NULL;
01474 int i;
01475 uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
01476 const uint8_t *srcPtr= src[0];
01477
01478 if (srcFormat == PIX_FMT_Y400A) {
01479 switch (dstFormat) {
01480 case PIX_FMT_RGB32 : conv = gray8aToPacked32; break;
01481 case PIX_FMT_BGR32 : conv = gray8aToPacked32; break;
01482 case PIX_FMT_BGR32_1: conv = gray8aToPacked32_1; break;
01483 case PIX_FMT_RGB32_1: conv = gray8aToPacked32_1; break;
01484 case PIX_FMT_RGB24 : conv = gray8aToPacked24; break;
01485 case PIX_FMT_BGR24 : conv = gray8aToPacked24; break;
01486 }
01487 } else if (usePal(srcFormat)) {
01488 switch (dstFormat) {
01489 case PIX_FMT_RGB32 : conv = sws_convertPalette8ToPacked32; break;
01490 case PIX_FMT_BGR32 : conv = sws_convertPalette8ToPacked32; break;
01491 case PIX_FMT_BGR32_1: conv = sws_convertPalette8ToPacked32; break;
01492 case PIX_FMT_RGB32_1: conv = sws_convertPalette8ToPacked32; break;
01493 case PIX_FMT_RGB24 : conv = sws_convertPalette8ToPacked24; break;
01494 case PIX_FMT_BGR24 : conv = sws_convertPalette8ToPacked24; break;
01495 }
01496 }
01497
01498 if (!conv)
01499 av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
01500 sws_format_name(srcFormat), sws_format_name(dstFormat));
01501 else {
01502 for (i=0; i<srcSliceH; i++) {
01503 conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
01504 srcPtr+= srcStride[0];
01505 dstPtr+= dstStride[0];
01506 }
01507 }
01508
01509 return srcSliceH;
01510 }
01511
01512 #define isRGBA32(x) ( \
01513 (x) == PIX_FMT_ARGB \
01514 || (x) == PIX_FMT_RGBA \
01515 || (x) == PIX_FMT_BGRA \
01516 || (x) == PIX_FMT_ABGR \
01517 )
01518
01519
01520 static int rgbToRgbWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01521 int srcSliceH, uint8_t* dst[], int dstStride[])
01522 {
01523 const enum PixelFormat srcFormat= c->srcFormat;
01524 const enum PixelFormat dstFormat= c->dstFormat;
01525 const int srcBpp= (c->srcFormatBpp + 7) >> 3;
01526 const int dstBpp= (c->dstFormatBpp + 7) >> 3;
01527 const int srcId= c->srcFormatBpp >> 2;
01528 const int dstId= c->dstFormatBpp >> 2;
01529 void (*conv)(const uint8_t *src, uint8_t *dst, long src_size)=NULL;
01530
01531 #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst)
01532
01533 if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
01534 if ( CONV_IS(ABGR, RGBA)
01535 || CONV_IS(ARGB, BGRA)
01536 || CONV_IS(BGRA, ARGB)
01537 || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
01538 else if (CONV_IS(ABGR, ARGB)
01539 || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
01540 else if (CONV_IS(ABGR, BGRA)
01541 || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
01542 else if (CONV_IS(BGRA, RGBA)
01543 || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
01544 else if (CONV_IS(BGRA, ABGR)
01545 || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
01546 } else
01547
01548 if ( (isBGRinInt(srcFormat) && isBGRinInt(dstFormat))
01549 || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
01550 switch(srcId | (dstId<<4)) {
01551 case 0x34: conv= rgb16to15; break;
01552 case 0x36: conv= rgb24to15; break;
01553 case 0x38: conv= rgb32to15; break;
01554 case 0x43: conv= rgb15to16; break;
01555 case 0x46: conv= rgb24to16; break;
01556 case 0x48: conv= rgb32to16; break;
01557 case 0x63: conv= rgb15to24; break;
01558 case 0x64: conv= rgb16to24; break;
01559 case 0x68: conv= rgb32to24; break;
01560 case 0x83: conv= rgb15to32; break;
01561 case 0x84: conv= rgb16to32; break;
01562 case 0x86: conv= rgb24to32; break;
01563 }
01564 } else if ( (isBGRinInt(srcFormat) && isRGBinInt(dstFormat))
01565 || (isRGBinInt(srcFormat) && isBGRinInt(dstFormat))) {
01566 switch(srcId | (dstId<<4)) {
01567 case 0x33: conv= rgb15tobgr15; break;
01568 case 0x34: conv= rgb16tobgr15; break;
01569 case 0x36: conv= rgb24tobgr15; break;
01570 case 0x38: conv= rgb32tobgr15; break;
01571 case 0x43: conv= rgb15tobgr16; break;
01572 case 0x44: conv= rgb16tobgr16; break;
01573 case 0x46: conv= rgb24tobgr16; break;
01574 case 0x48: conv= rgb32tobgr16; break;
01575 case 0x63: conv= rgb15tobgr24; break;
01576 case 0x64: conv= rgb16tobgr24; break;
01577 case 0x66: conv= rgb24tobgr24; break;
01578 case 0x68: conv= rgb32tobgr24; break;
01579 case 0x83: conv= rgb15tobgr32; break;
01580 case 0x84: conv= rgb16tobgr32; break;
01581 case 0x86: conv= rgb24tobgr32; break;
01582 }
01583 }
01584
01585 if (!conv) {
01586 av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
01587 sws_format_name(srcFormat), sws_format_name(dstFormat));
01588 } else {
01589 const uint8_t *srcPtr= src[0];
01590 uint8_t *dstPtr= dst[0];
01591 if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat))
01592 srcPtr += ALT32_CORR;
01593
01594 if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat))
01595 dstPtr += ALT32_CORR;
01596
01597 if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0)
01598 conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]);
01599 else {
01600 int i;
01601 dstPtr += dstStride[0]*srcSliceY;
01602
01603 for (i=0; i<srcSliceH; i++) {
01604 conv(srcPtr, dstPtr, c->srcW*srcBpp);
01605 srcPtr+= srcStride[0];
01606 dstPtr+= dstStride[0];
01607 }
01608 }
01609 }
01610 return srcSliceH;
01611 }
01612
01613 static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01614 int srcSliceH, uint8_t* dst[], int dstStride[])
01615 {
01616 rgb24toyv12(
01617 src[0],
01618 dst[0]+ srcSliceY *dstStride[0],
01619 dst[1]+(srcSliceY>>1)*dstStride[1],
01620 dst[2]+(srcSliceY>>1)*dstStride[2],
01621 c->srcW, srcSliceH,
01622 dstStride[0], dstStride[1], srcStride[0]);
01623 if (dst[3])
01624 fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
01625 return srcSliceH;
01626 }
01627
01628 static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01629 int srcSliceH, uint8_t* dst[], int dstStride[])
01630 {
01631 copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
01632 dst[0], dstStride[0]);
01633
01634 planar2x(src[1], dst[1] + dstStride[1]*(srcSliceY >> 1), c->chrSrcW,
01635 srcSliceH >> 2, srcStride[1], dstStride[1]);
01636 planar2x(src[2], dst[2] + dstStride[2]*(srcSliceY >> 1), c->chrSrcW,
01637 srcSliceH >> 2, srcStride[2], dstStride[2]);
01638 if (dst[3])
01639 fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
01640 return srcSliceH;
01641 }
01642
01643
01644 static int packedCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01645 int srcSliceH, uint8_t* dst[], int dstStride[])
01646 {
01647 if (dstStride[0]==srcStride[0] && srcStride[0] > 0)
01648 memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]);
01649 else {
01650 int i;
01651 const uint8_t *srcPtr= src[0];
01652 uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
01653 int length=0;
01654
01655
01656 while(length+c->srcW <= FFABS(dstStride[0])
01657 && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW;
01658 assert(length!=0);
01659
01660 for (i=0; i<srcSliceH; i++) {
01661 memcpy(dstPtr, srcPtr, length);
01662 srcPtr+= srcStride[0];
01663 dstPtr+= dstStride[0];
01664 }
01665 }
01666 return srcSliceH;
01667 }
01668
01669 static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
01670 int srcSliceH, uint8_t* dst[], int dstStride[])
01671 {
01672 int plane, i, j;
01673 for (plane=0; plane<4; plane++) {
01674 int length= (plane==0 || plane==3) ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample);
01675 int y= (plane==0 || plane==3) ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample);
01676 int height= (plane==0 || plane==3) ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample);
01677 const uint8_t *srcPtr= src[plane];
01678 uint8_t *dstPtr= dst[plane] + dstStride[plane]*y;
01679
01680 if (!dst[plane]) continue;
01681
01682 if (plane == 1 && !dst[2]) continue;
01683 if (!src[plane] || (plane == 1 && !src[2])) {
01684 if(is16BPS(c->dstFormat))
01685 length*=2;
01686 fillPlane(dst[plane], dstStride[plane], length, height, y, (plane==3) ? 255 : 128);
01687 } else {
01688 if(is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
01689 if (!isBE(c->srcFormat)) srcPtr++;
01690 for (i=0; i<height; i++) {
01691 for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
01692 srcPtr+= srcStride[plane];
01693 dstPtr+= dstStride[plane];
01694 }
01695 } else if(!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
01696 for (i=0; i<height; i++) {
01697 for (j=0; j<length; j++) {
01698 dstPtr[ j<<1 ] = srcPtr[j];
01699 dstPtr[(j<<1)+1] = srcPtr[j];
01700 }
01701 srcPtr+= srcStride[plane];
01702 dstPtr+= dstStride[plane];
01703 }
01704 } else if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat)
01705 && isBE(c->srcFormat) != isBE(c->dstFormat)) {
01706
01707 for (i=0; i<height; i++) {
01708 for (j=0; j<length; j++)
01709 ((uint16_t*)dstPtr)[j] = av_bswap16(((const uint16_t*)srcPtr)[j]);
01710 srcPtr+= srcStride[plane];
01711 dstPtr+= dstStride[plane];
01712 }
01713 } else if (dstStride[plane] == srcStride[plane] &&
01714 srcStride[plane] > 0 && srcStride[plane] == length) {
01715 memcpy(dst[plane] + dstStride[plane]*y, src[plane],
01716 height*dstStride[plane]);
01717 } else {
01718 if(is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
01719 length*=2;
01720 for (i=0; i<height; i++) {
01721 memcpy(dstPtr, srcPtr, length);
01722 srcPtr+= srcStride[plane];
01723 dstPtr+= dstStride[plane];
01724 }
01725 }
01726 }
01727 }
01728 return srcSliceH;
01729 }
01730
01731 int ff_hardcodedcpuflags(void)
01732 {
01733 int flags = 0;
01734 #if COMPILE_TEMPLATE_MMX2
01735 flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2;
01736 #elif COMPILE_TEMPLATE_AMD3DNOW
01737 flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_3DNOW;
01738 #elif COMPILE_TEMPLATE_MMX
01739 flags |= SWS_CPU_CAPS_MMX;
01740 #elif COMPILE_TEMPLATE_ALTIVEC
01741 flags |= SWS_CPU_CAPS_ALTIVEC;
01742 #elif ARCH_BFIN
01743 flags |= SWS_CPU_CAPS_BFIN;
01744 #endif
01745 return flags;
01746 }
01747
01748 void ff_get_unscaled_swscale(SwsContext *c)
01749 {
01750 const enum PixelFormat srcFormat = c->srcFormat;
01751 const enum PixelFormat dstFormat = c->dstFormat;
01752 const int flags = c->flags;
01753 const int dstH = c->dstH;
01754 int needsDither;
01755
01756 needsDither= isAnyRGB(dstFormat)
01757 && c->dstFormatBpp < 24
01758 && (c->dstFormatBpp < c->srcFormatBpp || (!isAnyRGB(srcFormat)));
01759
01760
01761 if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21)) {
01762 c->swScale= planarToNv12Wrapper;
01763 }
01764
01765 if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && isAnyRGB(dstFormat)
01766 && !(flags & SWS_ACCURATE_RND) && !(dstH&1)) {
01767 c->swScale= ff_yuv2rgb_get_func_ptr(c);
01768 }
01769
01770 if (srcFormat==PIX_FMT_YUV410P && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) {
01771 c->swScale= yvu9ToYv12Wrapper;
01772 }
01773
01774
01775 if (srcFormat==PIX_FMT_BGR24 && (dstFormat==PIX_FMT_YUV420P || dstFormat==PIX_FMT_YUVA420P) && !(flags & SWS_ACCURATE_RND))
01776 c->swScale= bgr24ToYv12Wrapper;
01777
01778
01779 if ( isAnyRGB(srcFormat)
01780 && isAnyRGB(dstFormat)
01781 && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8
01782 && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8
01783 && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4
01784 && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4
01785 && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE
01786 && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE
01787 && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK
01788 && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE
01789 && srcFormat != PIX_FMT_RGB48LE && dstFormat != PIX_FMT_RGB48LE
01790 && srcFormat != PIX_FMT_RGB48BE && dstFormat != PIX_FMT_RGB48BE
01791 && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
01792 c->swScale= rgbToRgbWrapper;
01793
01794 if ((usePal(srcFormat) && (
01795 dstFormat == PIX_FMT_RGB32 ||
01796 dstFormat == PIX_FMT_RGB32_1 ||
01797 dstFormat == PIX_FMT_RGB24 ||
01798 dstFormat == PIX_FMT_BGR32 ||
01799 dstFormat == PIX_FMT_BGR32_1 ||
01800 dstFormat == PIX_FMT_BGR24)))
01801 c->swScale= palToRgbWrapper;
01802
01803 if (srcFormat == PIX_FMT_YUV422P) {
01804 if (dstFormat == PIX_FMT_YUYV422)
01805 c->swScale= yuv422pToYuy2Wrapper;
01806 else if (dstFormat == PIX_FMT_UYVY422)
01807 c->swScale= yuv422pToUyvyWrapper;
01808 }
01809
01810
01811 if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
01812
01813 if (srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) {
01814 if (dstFormat == PIX_FMT_YUYV422)
01815 c->swScale= planarToYuy2Wrapper;
01816 else if (dstFormat == PIX_FMT_UYVY422)
01817 c->swScale= planarToUyvyWrapper;
01818 }
01819 }
01820 if(srcFormat == PIX_FMT_YUYV422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
01821 c->swScale= yuyvToYuv420Wrapper;
01822 if(srcFormat == PIX_FMT_UYVY422 && (dstFormat == PIX_FMT_YUV420P || dstFormat == PIX_FMT_YUVA420P))
01823 c->swScale= uyvyToYuv420Wrapper;
01824 if(srcFormat == PIX_FMT_YUYV422 && dstFormat == PIX_FMT_YUV422P)
01825 c->swScale= yuyvToYuv422Wrapper;
01826 if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P)
01827 c->swScale= uyvyToYuv422Wrapper;
01828
01829 #if COMPILE_ALTIVEC
01830 if ((c->flags & SWS_CPU_CAPS_ALTIVEC) &&
01831 !(c->flags & SWS_BITEXACT) &&
01832 srcFormat == PIX_FMT_YUV420P) {
01833
01834 if (dstFormat == PIX_FMT_YUYV422)
01835 c->swScale= yv12toyuy2_unscaled_altivec;
01836 else if (dstFormat == PIX_FMT_UYVY422)
01837 c->swScale= yv12touyvy_unscaled_altivec;
01838 }
01839 #endif
01840
01841
01842 if ( srcFormat == dstFormat
01843 || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P)
01844 || (srcFormat == PIX_FMT_YUV420P && dstFormat == PIX_FMT_YUVA420P)
01845 || (isPlanarYUV(srcFormat) && isGray(dstFormat))
01846 || (isPlanarYUV(dstFormat) && isGray(srcFormat))
01847 || (isGray(dstFormat) && isGray(srcFormat))
01848 || (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat)
01849 && c->chrDstHSubSample == c->chrSrcHSubSample
01850 && c->chrDstVSubSample == c->chrSrcVSubSample
01851 && dstFormat != PIX_FMT_NV12 && dstFormat != PIX_FMT_NV21
01852 && srcFormat != PIX_FMT_NV12 && srcFormat != PIX_FMT_NV21))
01853 {
01854 if (isPacked(c->srcFormat))
01855 c->swScale= packedCopyWrapper;
01856 else
01857 c->swScale= planarCopyWrapper;
01858 }
01859 #if ARCH_BFIN
01860 if (flags & SWS_CPU_CAPS_BFIN)
01861 ff_bfin_get_unscaled_swscale (c);
01862 #endif
01863 }
01864
01865 static void reset_ptr(const uint8_t* src[], int format)
01866 {
01867 if(!isALPHA(format))
01868 src[3]=NULL;
01869 if(!isPlanarYUV(format)) {
01870 src[3]=src[2]=NULL;
01871
01872 if (!usePal(format))
01873 src[1]= NULL;
01874 }
01875 }
01876
01877 static int check_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt,
01878 const int linesizes[4])
01879 {
01880 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
01881 int i;
01882
01883 for (i = 0; i < 4; i++) {
01884 int plane = desc->comp[i].plane;
01885 if (!data[plane] || !linesizes[plane])
01886 return 0;
01887 }
01888
01889 return 1;
01890 }
01891
01896 int sws_scale(SwsContext *c, const uint8_t* const src[], const int srcStride[], int srcSliceY,
01897 int srcSliceH, uint8_t* const dst[], const int dstStride[])
01898 {
01899 int i;
01900 const uint8_t* src2[4]= {src[0], src[1], src[2], src[3]};
01901 uint8_t* dst2[4]= {dst[0], dst[1], dst[2], dst[3]};
01902
01903
01904 if (srcSliceH == 0)
01905 return 0;
01906
01907 if (!check_image_pointers(src, c->srcFormat, srcStride)) {
01908 av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
01909 return 0;
01910 }
01911 if (!check_image_pointers(dst, c->dstFormat, dstStride)) {
01912 av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
01913 return 0;
01914 }
01915
01916 if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
01917 av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
01918 return 0;
01919 }
01920 if (c->sliceDir == 0) {
01921 if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
01922 }
01923
01924 if (usePal(c->srcFormat)) {
01925 for (i=0; i<256; i++) {
01926 int p, r, g, b,y,u,v;
01927 if(c->srcFormat == PIX_FMT_PAL8) {
01928 p=((const uint32_t*)(src[1]))[i];
01929 r= (p>>16)&0xFF;
01930 g= (p>> 8)&0xFF;
01931 b= p &0xFF;
01932 } else if(c->srcFormat == PIX_FMT_RGB8) {
01933 r= (i>>5 )*36;
01934 g= ((i>>2)&7)*36;
01935 b= (i&3 )*85;
01936 } else if(c->srcFormat == PIX_FMT_BGR8) {
01937 b= (i>>6 )*85;
01938 g= ((i>>3)&7)*36;
01939 r= (i&7 )*36;
01940 } else if(c->srcFormat == PIX_FMT_RGB4_BYTE) {
01941 r= (i>>3 )*255;
01942 g= ((i>>1)&3)*85;
01943 b= (i&1 )*255;
01944 } else if(c->srcFormat == PIX_FMT_GRAY8 || c->srcFormat == PIX_FMT_Y400A) {
01945 r = g = b = i;
01946 } else {
01947 assert(c->srcFormat == PIX_FMT_BGR4_BYTE);
01948 b= (i>>3 )*255;
01949 g= ((i>>1)&3)*85;
01950 r= (i&1 )*255;
01951 }
01952 y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
01953 u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
01954 v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
01955 c->pal_yuv[i]= y + (u<<8) + (v<<16);
01956
01957 switch(c->dstFormat) {
01958 case PIX_FMT_BGR32:
01959 #if !HAVE_BIGENDIAN
01960 case PIX_FMT_RGB24:
01961 #endif
01962 c->pal_rgb[i]= r + (g<<8) + (b<<16);
01963 break;
01964 case PIX_FMT_BGR32_1:
01965 #if HAVE_BIGENDIAN
01966 case PIX_FMT_BGR24:
01967 #endif
01968 c->pal_rgb[i]= (r + (g<<8) + (b<<16)) << 8;
01969 break;
01970 case PIX_FMT_RGB32_1:
01971 #if HAVE_BIGENDIAN
01972 case PIX_FMT_RGB24:
01973 #endif
01974 c->pal_rgb[i]= (b + (g<<8) + (r<<16)) << 8;
01975 break;
01976 case PIX_FMT_RGB32:
01977 #if !HAVE_BIGENDIAN
01978 case PIX_FMT_BGR24:
01979 #endif
01980 default:
01981 c->pal_rgb[i]= b + (g<<8) + (r<<16);
01982 }
01983 }
01984 }
01985
01986
01987 if (c->sliceDir == 1) {
01988
01989 int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2], srcStride[3]};
01990 int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2], dstStride[3]};
01991
01992 reset_ptr(src2, c->srcFormat);
01993 reset_ptr((const uint8_t**)dst2, c->dstFormat);
01994
01995
01996 if (srcSliceY + srcSliceH == c->srcH)
01997 c->sliceDir = 0;
01998
01999 return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2);
02000 } else {
02001
02002 int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2], -srcStride[3]};
02003 int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2], -dstStride[3]};
02004
02005 src2[0] += (srcSliceH-1)*srcStride[0];
02006 if (!usePal(c->srcFormat))
02007 src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1];
02008 src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2];
02009 src2[3] += (srcSliceH-1)*srcStride[3];
02010 dst2[0] += ( c->dstH -1)*dstStride[0];
02011 dst2[1] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1];
02012 dst2[2] += ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2];
02013 dst2[3] += ( c->dstH -1)*dstStride[3];
02014
02015 reset_ptr(src2, c->srcFormat);
02016 reset_ptr((const uint8_t**)dst2, c->dstFormat);
02017
02018
02019 if (!srcSliceY)
02020 c->sliceDir = 0;
02021
02022 return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2);
02023 }
02024 }
02025
02026 #if LIBSWSCALE_VERSION_MAJOR < 1
02027 int sws_scale_ordered(SwsContext *c, const uint8_t* const src[], int srcStride[], int srcSliceY,
02028 int srcSliceH, uint8_t* dst[], int dstStride[])
02029 {
02030 return sws_scale(c, src, srcStride, srcSliceY, srcSliceH, dst, dstStride);
02031 }
02032 #endif
02033
02034
02035 void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
02036 {
02037 long i;
02038
02039 for (i=0; i<num_pixels; i++)
02040 ((uint32_t *) dst)[i] = ((const uint32_t *) palette)[src[i]];
02041 }
02042
02043
02044 void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
02045 {
02046 long i;
02047
02048 for (i=0; i<num_pixels; i++) {
02049
02050 dst[0]= palette[src[i]*4+0];
02051 dst[1]= palette[src[i]*4+1];
02052 dst[2]= palette[src[i]*4+2];
02053 dst+= 3;
02054 }
02055 }