00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <inttypes.h>
00027
00028 #include "libavutil/attributes.h"
00029 #include "libavutil/bswap.h"
00030 #include "config.h"
00031 #include "rgb2rgb.h"
00032 #include "swscale.h"
00033 #include "swscale_internal.h"
00034
00035 void (*rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
00036 void (*rgb32tobgr16)(const uint8_t *src, uint8_t *dst, int src_size);
00037 void (*rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size);
00038 void (*rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size);
00039 void (*rgb24tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
00040 void (*rgb24tobgr16)(const uint8_t *src, uint8_t *dst, int src_size);
00041 void (*rgb24tobgr15)(const uint8_t *src, uint8_t *dst, int src_size);
00042 void (*rgb16tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
00043 void (*rgb15tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
00044
00045 void (*rgb32to16)(const uint8_t *src, uint8_t *dst, int src_size);
00046 void (*rgb32to15)(const uint8_t *src, uint8_t *dst, int src_size);
00047 void (*rgb24to16)(const uint8_t *src, uint8_t *dst, int src_size);
00048 void (*rgb24to15)(const uint8_t *src, uint8_t *dst, int src_size);
00049 void (*rgb16to32)(const uint8_t *src, uint8_t *dst, int src_size);
00050 void (*rgb16to15)(const uint8_t *src, uint8_t *dst, int src_size);
00051 void (*rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size);
00052 void (*rgb15to32)(const uint8_t *src, uint8_t *dst, int src_size);
00053
00054 void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size);
00055
00056 void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc,
00057 const uint8_t *vsrc, uint8_t *dst,
00058 int width, int height,
00059 int lumStride, int chromStride, int dstStride);
00060 void (*yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc,
00061 const uint8_t *vsrc, uint8_t *dst,
00062 int width, int height,
00063 int lumStride, int chromStride, int dstStride);
00064 void (*yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usrc,
00065 const uint8_t *vsrc, uint8_t *dst,
00066 int width, int height,
00067 int lumStride, int chromStride, int dstStride);
00068 void (*yuv422ptouyvy)(const uint8_t *ysrc, const uint8_t *usrc,
00069 const uint8_t *vsrc, uint8_t *dst,
00070 int width, int height,
00071 int lumStride, int chromStride, int dstStride);
00072 void (*yuy2toyv12)(const uint8_t *src, uint8_t *ydst,
00073 uint8_t *udst, uint8_t *vdst,
00074 int width, int height,
00075 int lumStride, int chromStride, int srcStride);
00076 void (*rgb24toyv12)(const uint8_t *src, uint8_t *ydst,
00077 uint8_t *udst, uint8_t *vdst,
00078 int width, int height,
00079 int lumStride, int chromStride, int srcStride);
00080 void (*planar2x)(const uint8_t *src, uint8_t *dst, int width, int height,
00081 int srcStride, int dstStride);
00082 void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst,
00083 int width, int height, int src1Stride,
00084 int src2Stride, int dstStride);
00085 void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
00086 uint8_t *dst1, uint8_t *dst2,
00087 int width, int height,
00088 int srcStride1, int srcStride2,
00089 int dstStride1, int dstStride2);
00090 void (*yvu9_to_yuy2)(const uint8_t *src1, const uint8_t *src2,
00091 const uint8_t *src3, uint8_t *dst,
00092 int width, int height,
00093 int srcStride1, int srcStride2,
00094 int srcStride3, int dstStride);
00095 void (*uyvytoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
00096 const uint8_t *src, int width, int height,
00097 int lumStride, int chromStride, int srcStride);
00098 void (*uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
00099 const uint8_t *src, int width, int height,
00100 int lumStride, int chromStride, int srcStride);
00101 void (*yuyvtoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
00102 const uint8_t *src, int width, int height,
00103 int lumStride, int chromStride, int srcStride);
00104 void (*yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
00105 const uint8_t *src, int width, int height,
00106 int lumStride, int chromStride, int srcStride);
00107
00108 #define RGB2YUV_SHIFT 8
00109 #define BY ((int)( 0.098 * (1 << RGB2YUV_SHIFT) + 0.5))
00110 #define BV ((int)(-0.071 * (1 << RGB2YUV_SHIFT) + 0.5))
00111 #define BU ((int)( 0.439 * (1 << RGB2YUV_SHIFT) + 0.5))
00112 #define GY ((int)( 0.504 * (1 << RGB2YUV_SHIFT) + 0.5))
00113 #define GV ((int)(-0.368 * (1 << RGB2YUV_SHIFT) + 0.5))
00114 #define GU ((int)(-0.291 * (1 << RGB2YUV_SHIFT) + 0.5))
00115 #define RY ((int)( 0.257 * (1 << RGB2YUV_SHIFT) + 0.5))
00116 #define RV ((int)( 0.439 * (1 << RGB2YUV_SHIFT) + 0.5))
00117 #define RU ((int)(-0.148 * (1 << RGB2YUV_SHIFT) + 0.5))
00118
00119
00120 #include "rgb2rgb_template.c"
00121
00122
00123
00124
00125
00126
00127
00128
00129 av_cold void sws_rgb2rgb_init(void)
00130 {
00131 rgb2rgb_init_c();
00132 if (HAVE_MMX)
00133 rgb2rgb_init_x86();
00134 }
00135
00136 void rgb32to24(const uint8_t *src, uint8_t *dst, int src_size)
00137 {
00138 int i, num_pixels = src_size >> 2;
00139
00140 for (i = 0; i < num_pixels; i++) {
00141 #if HAVE_BIGENDIAN
00142
00143 dst[3 * i + 0] = src[4 * i + 1];
00144 dst[3 * i + 1] = src[4 * i + 2];
00145 dst[3 * i + 2] = src[4 * i + 3];
00146 #else
00147 dst[3 * i + 0] = src[4 * i + 2];
00148 dst[3 * i + 1] = src[4 * i + 1];
00149 dst[3 * i + 2] = src[4 * i + 0];
00150 #endif
00151 }
00152 }
00153
00154 void rgb24to32(const uint8_t *src, uint8_t *dst, int src_size)
00155 {
00156 int i;
00157
00158 for (i = 0; 3 * i < src_size; i++) {
00159 #if HAVE_BIGENDIAN
00160
00161 dst[4 * i + 0] = 255;
00162 dst[4 * i + 1] = src[3 * i + 0];
00163 dst[4 * i + 2] = src[3 * i + 1];
00164 dst[4 * i + 3] = src[3 * i + 2];
00165 #else
00166 dst[4 * i + 0] = src[3 * i + 2];
00167 dst[4 * i + 1] = src[3 * i + 1];
00168 dst[4 * i + 2] = src[3 * i + 0];
00169 dst[4 * i + 3] = 255;
00170 #endif
00171 }
00172 }
00173
00174 void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
00175 {
00176 uint8_t *d = dst;
00177 const uint16_t *s = (const uint16_t *)src;
00178 const uint16_t *end = s + src_size / 2;
00179
00180 while (s < end) {
00181 register uint16_t bgr = *s++;
00182 #if HAVE_BIGENDIAN
00183 *d++ = 255;
00184 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
00185 *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
00186 *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
00187 #else
00188 *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
00189 *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
00190 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
00191 *d++ = 255;
00192 #endif
00193 }
00194 }
00195
00196 void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size)
00197 {
00198 uint16_t rgb, r, g, b;
00199 uint16_t *d = (uint16_t *)dst;
00200 const uint16_t *s = (const uint16_t *)src;
00201 const uint16_t *end = s + src_size / 2;
00202
00203 while (s < end) {
00204 rgb = *s++;
00205 r = rgb & 0xF00;
00206 g = rgb & 0x0F0;
00207 b = rgb & 0x00F;
00208 r = (r << 3) | ((r & 0x800) >> 1);
00209 g = (g << 2) | ((g & 0x080) >> 2);
00210 b = (b << 1) | ( b >> 3);
00211 *d++ = r | g | b;
00212 }
00213 }
00214
00215 void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size)
00216 {
00217 uint8_t *d = dst;
00218 const uint16_t *s = (const uint16_t *)src;
00219 const uint16_t *end = s + src_size / 2;
00220
00221 while (s < end) {
00222 register uint16_t bgr = *s++;
00223 *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
00224 *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
00225 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
00226 }
00227 }
00228
00229 void rgb16tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
00230 {
00231 int i, num_pixels = src_size >> 1;
00232
00233 for (i = 0; i < num_pixels; i++) {
00234 unsigned rgb = ((const uint16_t *)src)[i];
00235 ((uint16_t *)dst)[i] = (rgb >> 11) | (rgb & 0x7E0) | (rgb << 11);
00236 }
00237 }
00238
00239 void rgb16tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
00240 {
00241 int i, num_pixels = src_size >> 1;
00242
00243 for (i = 0; i < num_pixels; i++) {
00244 unsigned rgb = ((const uint16_t *)src)[i];
00245 ((uint16_t *)dst)[i] = (rgb >> 11) | ((rgb & 0x7C0) >> 1) | ((rgb & 0x1F) << 10);
00246 }
00247 }
00248
00249 void rgb15tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
00250 {
00251 uint8_t *d = dst;
00252 const uint16_t *s = (const uint16_t *)src;
00253 const uint16_t *end = s + src_size / 2;
00254
00255 while (s < end) {
00256 register uint16_t bgr = *s++;
00257 #if HAVE_BIGENDIAN
00258 *d++ = 255;
00259 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
00260 *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
00261 *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
00262 #else
00263 *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
00264 *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
00265 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
00266 *d++ = 255;
00267 #endif
00268 }
00269 }
00270
00271 void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size)
00272 {
00273 uint8_t *d = dst;
00274 const uint16_t *s = (const uint16_t *)src;
00275 const uint16_t *end = s + src_size / 2;
00276
00277 while (s < end) {
00278 register uint16_t bgr = *s++;
00279 *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
00280 *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
00281 *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
00282 }
00283 }
00284
00285 void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
00286 {
00287 int i, num_pixels = src_size >> 1;
00288
00289 for (i = 0; i < num_pixels; i++) {
00290 unsigned rgb = ((const uint16_t *)src)[i];
00291 ((uint16_t *)dst)[i] = ((rgb & 0x7C00) >> 10) | ((rgb & 0x3E0) << 1) | (rgb << 11);
00292 }
00293 }
00294
00295 void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
00296 {
00297 int i, num_pixels = src_size >> 1;
00298
00299 for (i = 0; i < num_pixels; i++) {
00300 unsigned rgb = ((const uint16_t *)src)[i];
00301 unsigned br = rgb & 0x7C1F;
00302 ((uint16_t *)dst)[i] = (br >> 10) | (rgb & 0x3E0) | (br << 10);
00303 }
00304 }
00305
00306 void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size)
00307 {
00308 uint16_t *d = (uint16_t *)dst;
00309 uint16_t *s = (uint16_t *)src;
00310 int i, num_pixels = src_size >> 1;
00311
00312 for (i = 0; i < num_pixels; i++) {
00313 unsigned rgb = s[i];
00314 d[i] = (rgb << 8 | rgb & 0xF0 | rgb >> 8) & 0xFFF;
00315 }
00316 }
00317
00318
00319 #define DEFINE_SHUFFLE_BYTES(a, b, c, d) \
00320 void shuffle_bytes_ ## a ## b ## c ## d(const uint8_t *src, \
00321 uint8_t *dst, int src_size) \
00322 { \
00323 int i; \
00324 \
00325 for (i = 0; i < src_size; i += 4) { \
00326 dst[i + 0] = src[i + a]; \
00327 dst[i + 1] = src[i + b]; \
00328 dst[i + 2] = src[i + c]; \
00329 dst[i + 3] = src[i + d]; \
00330 } \
00331 }
00332
00333 DEFINE_SHUFFLE_BYTES(0, 3, 2, 1)
00334 DEFINE_SHUFFLE_BYTES(1, 2, 3, 0)
00335 DEFINE_SHUFFLE_BYTES(3, 0, 1, 2)
00336 DEFINE_SHUFFLE_BYTES(3, 2, 1, 0)
00337
00338 #define DEFINE_RGB48TOBGR48(need_bswap, swap) \
00339 void rgb48tobgr48_ ## need_bswap(const uint8_t *src, \
00340 uint8_t *dst, int src_size) \
00341 { \
00342 uint16_t *d = (uint16_t *)dst; \
00343 uint16_t *s = (uint16_t *)src; \
00344 int i, num_pixels = src_size >> 1; \
00345 \
00346 for (i = 0; i < num_pixels; i += 3) { \
00347 d[i ] = swap ? av_bswap16(s[i + 2]) : s[i + 2]; \
00348 d[i + 1] = swap ? av_bswap16(s[i + 1]) : s[i + 1]; \
00349 d[i + 2] = swap ? av_bswap16(s[i ]) : s[i ]; \
00350 } \
00351 }
00352
00353 DEFINE_RGB48TOBGR48(nobswap, 0)
00354 DEFINE_RGB48TOBGR48(bswap, 1)
00355
00356 #define DEFINE_RGB64TOBGR48(need_bswap, swap) \
00357 void rgb64tobgr48_ ## need_bswap(const uint8_t *src, \
00358 uint8_t *dst, int src_size) \
00359 { \
00360 uint16_t *d = (uint16_t *)dst; \
00361 uint16_t *s = (uint16_t *)src; \
00362 int i, num_pixels = src_size >> 3; \
00363 \
00364 for (i = 0; i < num_pixels; i++) { \
00365 d[3 * i ] = swap ? av_bswap16(s[4 * i + 2]) : s[4 * i + 2]; \
00366 d[3 * i + 1] = swap ? av_bswap16(s[4 * i + 1]) : s[4 * i + 1]; \
00367 d[3 * i + 2] = swap ? av_bswap16(s[4 * i ]) : s[4 * i ]; \
00368 } \
00369 }
00370
00371 DEFINE_RGB64TOBGR48(nobswap, 0)
00372 DEFINE_RGB64TOBGR48(bswap, 1)
00373
00374 #define DEFINE_RGB64TO48(need_bswap, swap) \
00375 void rgb64to48_ ## need_bswap(const uint8_t *src, \
00376 uint8_t *dst, int src_size) \
00377 { \
00378 uint16_t *d = (uint16_t *)dst; \
00379 uint16_t *s = (uint16_t *)src; \
00380 int i, num_pixels = src_size >> 3; \
00381 \
00382 for (i = 0; i < num_pixels; i++) { \
00383 d[3 * i ] = swap ? av_bswap16(s[4 * i ]) : s[4 * i ]; \
00384 d[3 * i + 1] = swap ? av_bswap16(s[4 * i + 1]) : s[4 * i + 1]; \
00385 d[3 * i + 2] = swap ? av_bswap16(s[4 * i + 2]) : s[4 * i + 2]; \
00386 } \
00387 }
00388
00389 DEFINE_RGB64TO48(nobswap, 0)
00390 DEFINE_RGB64TO48(bswap, 1)