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