Libav 0.7.1
|
00001 /* 00002 * software RGB to RGB converter 00003 * pluralize by software PAL8 to RGB converter 00004 * software YUV to YUV converter 00005 * software YUV to RGB converter 00006 * Written by Nick Kurshev. 00007 * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at) 00008 * 00009 * This file is part of Libav. 00010 * 00011 * Libav is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU Lesser General Public 00013 * License as published by the Free Software Foundation; either 00014 * version 2.1 of the License, or (at your option) any later version. 00015 * 00016 * Libav is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with Libav; if not, write to the Free Software 00023 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00024 */ 00025 #include <inttypes.h> 00026 #include "config.h" 00027 #include "libavutil/bswap.h" 00028 #include "rgb2rgb.h" 00029 #include "swscale.h" 00030 #include "swscale_internal.h" 00031 00032 void (*rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size); 00033 void (*rgb24tobgr16)(const uint8_t *src, uint8_t *dst, int src_size); 00034 void (*rgb24tobgr15)(const uint8_t *src, uint8_t *dst, int src_size); 00035 void (*rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size); 00036 void (*rgb32to16)(const uint8_t *src, uint8_t *dst, int src_size); 00037 void (*rgb32to15)(const uint8_t *src, uint8_t *dst, int src_size); 00038 void (*rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size); 00039 void (*rgb15tobgr24)(const uint8_t *src, uint8_t *dst, int src_size); 00040 void (*rgb15to32)(const uint8_t *src, uint8_t *dst, int src_size); 00041 void (*rgb16to15)(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 (*rgb16to32)(const uint8_t *src, uint8_t *dst, int src_size); 00044 void (*rgb24tobgr24)(const uint8_t *src, uint8_t *dst, int src_size); 00045 void (*rgb24to16)(const uint8_t *src, uint8_t *dst, int src_size); 00046 void (*rgb24to15)(const uint8_t *src, uint8_t *dst, int src_size); 00047 void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size); 00048 void (*rgb32tobgr16)(const uint8_t *src, uint8_t *dst, int src_size); 00049 void (*rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size); 00050 00051 void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, 00052 int width, int height, 00053 int lumStride, int chromStride, int dstStride); 00054 void (*yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, 00055 int width, int height, 00056 int lumStride, int chromStride, int dstStride); 00057 void (*yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, 00058 int width, int height, 00059 int lumStride, int chromStride, int dstStride); 00060 void (*yuv422ptouyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst, 00061 int width, int height, 00062 int lumStride, int chromStride, int dstStride); 00063 void (*yuy2toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, 00064 int width, int height, 00065 int lumStride, int chromStride, int srcStride); 00066 void (*rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst, 00067 int width, int height, 00068 int lumStride, int chromStride, int srcStride); 00069 void (*planar2x)(const uint8_t *src, uint8_t *dst, int width, int height, 00070 int srcStride, int dstStride); 00071 void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst, 00072 int width, int height, int src1Stride, 00073 int src2Stride, int dstStride); 00074 void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2, 00075 uint8_t *dst1, uint8_t *dst2, 00076 int width, int height, 00077 int srcStride1, int srcStride2, 00078 int dstStride1, int dstStride2); 00079 void (*yvu9_to_yuy2)(const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, 00080 uint8_t *dst, 00081 int width, int height, 00082 int srcStride1, int srcStride2, 00083 int srcStride3, int dstStride); 00084 void (*uyvytoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, 00085 int width, int height, 00086 int lumStride, int chromStride, int srcStride); 00087 void (*uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, 00088 int width, int height, 00089 int lumStride, int chromStride, int srcStride); 00090 void (*yuyvtoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, 00091 int width, int height, 00092 int lumStride, int chromStride, int srcStride); 00093 void (*yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src, 00094 int width, int height, 00095 int lumStride, int chromStride, int srcStride); 00096 00097 #define RGB2YUV_SHIFT 8 00098 #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5)) 00099 #define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5)) 00100 #define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) 00101 #define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5)) 00102 #define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5)) 00103 #define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5)) 00104 #define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5)) 00105 #define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) 00106 #define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5)) 00107 00108 //plain C versions 00109 #include "rgb2rgb_template.c" 00110 00111 00112 /* 00113 RGB15->RGB16 original by Strepto/Astral 00114 ported to gcc & bugfixed : A'rpi 00115 MMX2, 3DNOW optimization by Nick Kurshev 00116 32-bit C version, and and&add trick by Michael Niedermayer 00117 */ 00118 00119 void sws_rgb2rgb_init(void) 00120 { 00121 rgb2rgb_init_c(); 00122 if (HAVE_MMX) 00123 rgb2rgb_init_x86(); 00124 } 00125 00126 void rgb32to24(const uint8_t *src, uint8_t *dst, int src_size) 00127 { 00128 int i; 00129 int num_pixels = src_size >> 2; 00130 for (i=0; i<num_pixels; i++) { 00131 #if HAVE_BIGENDIAN 00132 /* RGB32 (= A,B,G,R) -> BGR24 (= B,G,R) */ 00133 dst[3*i + 0] = src[4*i + 1]; 00134 dst[3*i + 1] = src[4*i + 2]; 00135 dst[3*i + 2] = src[4*i + 3]; 00136 #else 00137 dst[3*i + 0] = src[4*i + 2]; 00138 dst[3*i + 1] = src[4*i + 1]; 00139 dst[3*i + 2] = src[4*i + 0]; 00140 #endif 00141 } 00142 } 00143 00144 void rgb24to32(const uint8_t *src, uint8_t *dst, int src_size) 00145 { 00146 int i; 00147 for (i=0; 3*i<src_size; i++) { 00148 #if HAVE_BIGENDIAN 00149 /* RGB24 (= R,G,B) -> BGR32 (= A,R,G,B) */ 00150 dst[4*i + 0] = 255; 00151 dst[4*i + 1] = src[3*i + 0]; 00152 dst[4*i + 2] = src[3*i + 1]; 00153 dst[4*i + 3] = src[3*i + 2]; 00154 #else 00155 dst[4*i + 0] = src[3*i + 2]; 00156 dst[4*i + 1] = src[3*i + 1]; 00157 dst[4*i + 2] = src[3*i + 0]; 00158 dst[4*i + 3] = 255; 00159 #endif 00160 } 00161 } 00162 00163 void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size) 00164 { 00165 const uint16_t *end; 00166 uint8_t *d = dst; 00167 const uint16_t *s = (const uint16_t *)src; 00168 end = s + src_size/2; 00169 while (s < end) { 00170 register uint16_t bgr; 00171 bgr = *s++; 00172 #if HAVE_BIGENDIAN 00173 *d++ = 255; 00174 *d++ = (bgr&0x1F)<<3; 00175 *d++ = (bgr&0x7E0)>>3; 00176 *d++ = (bgr&0xF800)>>8; 00177 #else 00178 *d++ = (bgr&0xF800)>>8; 00179 *d++ = (bgr&0x7E0)>>3; 00180 *d++ = (bgr&0x1F)<<3; 00181 *d++ = 255; 00182 #endif 00183 } 00184 } 00185 00186 void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size) 00187 { 00188 const uint16_t *end; 00189 uint8_t *d = dst; 00190 const uint16_t *s = (const uint16_t *)src; 00191 end = s + src_size/2; 00192 while (s < end) { 00193 register uint16_t bgr; 00194 bgr = *s++; 00195 *d++ = (bgr&0xF800)>>8; 00196 *d++ = (bgr&0x7E0)>>3; 00197 *d++ = (bgr&0x1F)<<3; 00198 } 00199 } 00200 00201 void rgb16tobgr16(const uint8_t *src, uint8_t *dst, int src_size) 00202 { 00203 int i; 00204 int num_pixels = src_size >> 1; 00205 00206 for (i=0; i<num_pixels; i++) { 00207 unsigned rgb = ((const uint16_t*)src)[i]; 00208 ((uint16_t*)dst)[i] = (rgb>>11) | (rgb&0x7E0) | (rgb<<11); 00209 } 00210 } 00211 00212 void rgb16tobgr15(const uint8_t *src, uint8_t *dst, int src_size) 00213 { 00214 int i; 00215 int num_pixels = src_size >> 1; 00216 00217 for (i=0; i<num_pixels; i++) { 00218 unsigned rgb = ((const uint16_t*)src)[i]; 00219 ((uint16_t*)dst)[i] = (rgb>>11) | ((rgb&0x7C0)>>1) | ((rgb&0x1F)<<10); 00220 } 00221 } 00222 00223 void rgb15tobgr32(const uint8_t *src, uint8_t *dst, int src_size) 00224 { 00225 const uint16_t *end; 00226 uint8_t *d = dst; 00227 const uint16_t *s = (const uint16_t *)src; 00228 end = s + src_size/2; 00229 while (s < end) { 00230 register uint16_t bgr; 00231 bgr = *s++; 00232 #if HAVE_BIGENDIAN 00233 *d++ = 255; 00234 *d++ = (bgr&0x1F)<<3; 00235 *d++ = (bgr&0x3E0)>>2; 00236 *d++ = (bgr&0x7C00)>>7; 00237 #else 00238 *d++ = (bgr&0x7C00)>>7; 00239 *d++ = (bgr&0x3E0)>>2; 00240 *d++ = (bgr&0x1F)<<3; 00241 *d++ = 255; 00242 #endif 00243 } 00244 } 00245 00246 void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size) 00247 { 00248 const uint16_t *end; 00249 uint8_t *d = dst; 00250 const uint16_t *s = (const uint16_t *)src; 00251 end = s + src_size/2; 00252 while (s < end) { 00253 register uint16_t bgr; 00254 bgr = *s++; 00255 *d++ = (bgr&0x7C00)>>7; 00256 *d++ = (bgr&0x3E0)>>2; 00257 *d++ = (bgr&0x1F)<<3; 00258 } 00259 } 00260 00261 void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size) 00262 { 00263 int i; 00264 int num_pixels = src_size >> 1; 00265 00266 for (i=0; i<num_pixels; i++) { 00267 unsigned rgb = ((const uint16_t*)src)[i]; 00268 ((uint16_t*)dst)[i] = ((rgb&0x7C00)>>10) | ((rgb&0x3E0)<<1) | (rgb<<11); 00269 } 00270 } 00271 00272 void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size) 00273 { 00274 int i; 00275 int num_pixels = src_size >> 1; 00276 00277 for (i=0; i<num_pixels; i++) { 00278 unsigned br; 00279 unsigned rgb = ((const uint16_t*)src)[i]; 00280 br = rgb&0x7c1F; 00281 ((uint16_t*)dst)[i] = (br>>10) | (rgb&0x3E0) | (br<<10); 00282 } 00283 } 00284 00285 void bgr8torgb8(const uint8_t *src, uint8_t *dst, int src_size) 00286 { 00287 int i; 00288 int num_pixels = src_size; 00289 for (i=0; i<num_pixels; i++) { 00290 unsigned b,g,r; 00291 register uint8_t rgb; 00292 rgb = src[i]; 00293 r = (rgb&0x07); 00294 g = (rgb&0x38)>>3; 00295 b = (rgb&0xC0)>>6; 00296 dst[i] = ((b<<1)&0x07) | ((g&0x07)<<3) | ((r&0x03)<<6); 00297 } 00298 } 00299 00300 #define DEFINE_SHUFFLE_BYTES(a, b, c, d) \ 00301 void shuffle_bytes_##a##b##c##d(const uint8_t *src, uint8_t *dst, int src_size) \ 00302 { \ 00303 int i; \ 00304 \ 00305 for (i = 0; i < src_size; i+=4) { \ 00306 dst[i + 0] = src[i + a]; \ 00307 dst[i + 1] = src[i + b]; \ 00308 dst[i + 2] = src[i + c]; \ 00309 dst[i + 3] = src[i + d]; \ 00310 } \ 00311 } 00312 00313 DEFINE_SHUFFLE_BYTES(0, 3, 2, 1); 00314 DEFINE_SHUFFLE_BYTES(1, 2, 3, 0); 00315 DEFINE_SHUFFLE_BYTES(3, 0, 1, 2); 00316 DEFINE_SHUFFLE_BYTES(3, 2, 1, 0); 00317