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 * lot of big-endian byte order fixes by Alex Beregszaszi 00009 * 00010 * This file is part of Libav. 00011 * 00012 * Libav is free software; you can redistribute it and/or 00013 * modify it under the terms of the GNU Lesser General Public 00014 * License as published by the Free Software Foundation; either 00015 * version 2.1 of the License, or (at your option) any later version. 00016 * 00017 * Libav is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 * Lesser General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU Lesser General Public 00023 * License along with Libav; if not, write to the Free Software 00024 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00025 */ 00026 00027 #include <stddef.h> 00028 00029 static inline void rgb24tobgr32_c(const uint8_t *src, uint8_t *dst, int src_size) 00030 { 00031 uint8_t *dest = dst; 00032 const uint8_t *s = src; 00033 const uint8_t *end; 00034 end = s + src_size; 00035 00036 while (s < end) { 00037 #if HAVE_BIGENDIAN 00038 /* RGB24 (= R,G,B) -> RGB32 (= A,B,G,R) */ 00039 *dest++ = 255; 00040 *dest++ = s[2]; 00041 *dest++ = s[1]; 00042 *dest++ = s[0]; 00043 s+=3; 00044 #else 00045 *dest++ = *s++; 00046 *dest++ = *s++; 00047 *dest++ = *s++; 00048 *dest++ = 255; 00049 #endif 00050 } 00051 } 00052 00053 static inline void rgb32tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size) 00054 { 00055 uint8_t *dest = dst; 00056 const uint8_t *s = src; 00057 const uint8_t *end; 00058 00059 end = s + src_size; 00060 00061 while (s < end) { 00062 #if HAVE_BIGENDIAN 00063 /* RGB32 (= A,B,G,R) -> RGB24 (= R,G,B) */ 00064 s++; 00065 dest[2] = *s++; 00066 dest[1] = *s++; 00067 dest[0] = *s++; 00068 dest += 3; 00069 #else 00070 *dest++ = *s++; 00071 *dest++ = *s++; 00072 *dest++ = *s++; 00073 s++; 00074 #endif 00075 } 00076 } 00077 00078 /* 00079 original by Strepto/Astral 00080 ported to gcc & bugfixed: A'rpi 00081 MMX2, 3DNOW optimization by Nick Kurshev 00082 32-bit C version, and and&add trick by Michael Niedermayer 00083 */ 00084 static inline void rgb15to16_c(const uint8_t *src, uint8_t *dst, int src_size) 00085 { 00086 register const uint8_t* s=src; 00087 register uint8_t* d=dst; 00088 register const uint8_t *end; 00089 const uint8_t *mm_end; 00090 end = s + src_size; 00091 mm_end = end - 3; 00092 while (s < mm_end) { 00093 register unsigned x= *((const uint32_t *)s); 00094 *((uint32_t *)d) = (x&0x7FFF7FFF) + (x&0x7FE07FE0); 00095 d+=4; 00096 s+=4; 00097 } 00098 if (s < end) { 00099 register unsigned short x= *((const uint16_t *)s); 00100 *((uint16_t *)d) = (x&0x7FFF) + (x&0x7FE0); 00101 } 00102 } 00103 00104 static inline void rgb16to15_c(const uint8_t *src, uint8_t *dst, int src_size) 00105 { 00106 register const uint8_t* s=src; 00107 register uint8_t* d=dst; 00108 register const uint8_t *end; 00109 const uint8_t *mm_end; 00110 end = s + src_size; 00111 00112 mm_end = end - 3; 00113 while (s < mm_end) { 00114 register uint32_t x= *((const uint32_t*)s); 00115 *((uint32_t *)d) = ((x>>1)&0x7FE07FE0) | (x&0x001F001F); 00116 s+=4; 00117 d+=4; 00118 } 00119 if (s < end) { 00120 register uint16_t x= *((const uint16_t*)s); 00121 *((uint16_t *)d) = ((x>>1)&0x7FE0) | (x&0x001F); 00122 } 00123 } 00124 00125 static inline void rgb32to16_c(const uint8_t *src, uint8_t *dst, int src_size) 00126 { 00127 const uint8_t *s = src; 00128 const uint8_t *end; 00129 uint16_t *d = (uint16_t *)dst; 00130 end = s + src_size; 00131 00132 while (s < end) { 00133 register int rgb = *(const uint32_t*)s; s += 4; 00134 *d++ = ((rgb&0xFF)>>3) + ((rgb&0xFC00)>>5) + ((rgb&0xF80000)>>8); 00135 } 00136 } 00137 00138 static inline void rgb32tobgr16_c(const uint8_t *src, uint8_t *dst, int src_size) 00139 { 00140 const uint8_t *s = src; 00141 const uint8_t *end; 00142 uint16_t *d = (uint16_t *)dst; 00143 end = s + src_size; 00144 while (s < end) { 00145 register int rgb = *(const uint32_t*)s; s += 4; 00146 *d++ = ((rgb&0xF8)<<8) + ((rgb&0xFC00)>>5) + ((rgb&0xF80000)>>19); 00147 } 00148 } 00149 00150 static inline void rgb32to15_c(const uint8_t *src, uint8_t *dst, int src_size) 00151 { 00152 const uint8_t *s = src; 00153 const uint8_t *end; 00154 uint16_t *d = (uint16_t *)dst; 00155 end = s + src_size; 00156 while (s < end) { 00157 register int rgb = *(const uint32_t*)s; s += 4; 00158 *d++ = ((rgb&0xFF)>>3) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>9); 00159 } 00160 } 00161 00162 static inline void rgb32tobgr15_c(const uint8_t *src, uint8_t *dst, int src_size) 00163 { 00164 const uint8_t *s = src; 00165 const uint8_t *end; 00166 uint16_t *d = (uint16_t *)dst; 00167 end = s + src_size; 00168 while (s < end) { 00169 register int rgb = *(const uint32_t*)s; s += 4; 00170 *d++ = ((rgb&0xF8)<<7) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>19); 00171 } 00172 } 00173 00174 static inline void rgb24tobgr16_c(const uint8_t *src, uint8_t *dst, int src_size) 00175 { 00176 const uint8_t *s = src; 00177 const uint8_t *end; 00178 uint16_t *d = (uint16_t *)dst; 00179 end = s + src_size; 00180 while (s < end) { 00181 const int b = *s++; 00182 const int g = *s++; 00183 const int r = *s++; 00184 *d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8); 00185 } 00186 } 00187 00188 static inline void rgb24to16_c(const uint8_t *src, uint8_t *dst, int src_size) 00189 { 00190 const uint8_t *s = src; 00191 const uint8_t *end; 00192 uint16_t *d = (uint16_t *)dst; 00193 end = s + src_size; 00194 while (s < end) { 00195 const int r = *s++; 00196 const int g = *s++; 00197 const int b = *s++; 00198 *d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8); 00199 } 00200 } 00201 00202 static inline void rgb24tobgr15_c(const uint8_t *src, uint8_t *dst, int src_size) 00203 { 00204 const uint8_t *s = src; 00205 const uint8_t *end; 00206 uint16_t *d = (uint16_t *)dst; 00207 end = s + src_size; 00208 while (s < end) { 00209 const int b = *s++; 00210 const int g = *s++; 00211 const int r = *s++; 00212 *d++ = (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7); 00213 } 00214 } 00215 00216 static inline void rgb24to15_c(const uint8_t *src, uint8_t *dst, int src_size) 00217 { 00218 const uint8_t *s = src; 00219 const uint8_t *end; 00220 uint16_t *d = (uint16_t *)dst; 00221 end = s + src_size; 00222 while (s < end) { 00223 const int r = *s++; 00224 const int g = *s++; 00225 const int b = *s++; 00226 *d++ = (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7); 00227 } 00228 } 00229 00230 /* 00231 I use less accurate approximation here by simply left-shifting the input 00232 value and filling the low order bits with zeroes. This method improves PNG 00233 compression but this scheme cannot reproduce white exactly, since it does 00234 not generate an all-ones maximum value; the net effect is to darken the 00235 image slightly. 00236 00237 The better method should be "left bit replication": 00238 00239 4 3 2 1 0 00240 --------- 00241 1 1 0 1 1 00242 00243 7 6 5 4 3 2 1 0 00244 ---------------- 00245 1 1 0 1 1 1 1 0 00246 |=======| |===| 00247 | leftmost bits repeated to fill open bits 00248 | 00249 original bits 00250 */ 00251 static inline void rgb15tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size) 00252 { 00253 const uint16_t *end; 00254 uint8_t *d = dst; 00255 const uint16_t *s = (const uint16_t*)src; 00256 end = s + src_size/2; 00257 while (s < end) { 00258 register uint16_t bgr; 00259 bgr = *s++; 00260 *d++ = (bgr&0x1F)<<3; 00261 *d++ = (bgr&0x3E0)>>2; 00262 *d++ = (bgr&0x7C00)>>7; 00263 } 00264 } 00265 00266 static inline void rgb16tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size) 00267 { 00268 const uint16_t *end; 00269 uint8_t *d = (uint8_t *)dst; 00270 const uint16_t *s = (const uint16_t *)src; 00271 end = s + src_size/2; 00272 while (s < end) { 00273 register uint16_t bgr; 00274 bgr = *s++; 00275 *d++ = (bgr&0x1F)<<3; 00276 *d++ = (bgr&0x7E0)>>3; 00277 *d++ = (bgr&0xF800)>>8; 00278 } 00279 } 00280 00281 static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, int src_size) 00282 { 00283 const uint16_t *end; 00284 uint8_t *d = dst; 00285 const uint16_t *s = (const uint16_t *)src; 00286 end = s + src_size/2; 00287 while (s < end) { 00288 register uint16_t bgr; 00289 bgr = *s++; 00290 #if HAVE_BIGENDIAN 00291 *d++ = 255; 00292 *d++ = (bgr&0x7C00)>>7; 00293 *d++ = (bgr&0x3E0)>>2; 00294 *d++ = (bgr&0x1F)<<3; 00295 #else 00296 *d++ = (bgr&0x1F)<<3; 00297 *d++ = (bgr&0x3E0)>>2; 00298 *d++ = (bgr&0x7C00)>>7; 00299 *d++ = 255; 00300 #endif 00301 } 00302 } 00303 00304 static inline void rgb16to32_c(const uint8_t *src, uint8_t *dst, int src_size) 00305 { 00306 const uint16_t *end; 00307 uint8_t *d = dst; 00308 const uint16_t *s = (const uint16_t*)src; 00309 end = s + src_size/2; 00310 while (s < end) { 00311 register uint16_t bgr; 00312 bgr = *s++; 00313 #if HAVE_BIGENDIAN 00314 *d++ = 255; 00315 *d++ = (bgr&0xF800)>>8; 00316 *d++ = (bgr&0x7E0)>>3; 00317 *d++ = (bgr&0x1F)<<3; 00318 #else 00319 *d++ = (bgr&0x1F)<<3; 00320 *d++ = (bgr&0x7E0)>>3; 00321 *d++ = (bgr&0xF800)>>8; 00322 *d++ = 255; 00323 #endif 00324 } 00325 } 00326 00327 static inline void shuffle_bytes_2103_c(const uint8_t *src, uint8_t *dst, int src_size) 00328 { 00329 int idx = 15 - src_size; 00330 const uint8_t *s = src-idx; 00331 uint8_t *d = dst-idx; 00332 for (; idx<15; idx+=4) { 00333 register int v = *(const uint32_t *)&s[idx], g = v & 0xff00ff00; 00334 v &= 0xff00ff; 00335 *(uint32_t *)&d[idx] = (v>>16) + g + (v<<16); 00336 } 00337 } 00338 00339 static inline void rgb24tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size) 00340 { 00341 unsigned i; 00342 for (i=0; i<src_size; i+=3) { 00343 register uint8_t x; 00344 x = src[i + 2]; 00345 dst[i + 1] = src[i + 1]; 00346 dst[i + 2] = src[i + 0]; 00347 dst[i + 0] = x; 00348 } 00349 } 00350 00351 static inline void yuvPlanartoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc, 00352 const uint8_t *vsrc, uint8_t *dst, 00353 int width, int height, 00354 int lumStride, int chromStride, 00355 int dstStride, int vertLumPerChroma) 00356 { 00357 int y; 00358 const int chromWidth = width >> 1; 00359 for (y=0; y<height; y++) { 00360 #if HAVE_FAST_64BIT 00361 int i; 00362 uint64_t *ldst = (uint64_t *) dst; 00363 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc; 00364 for (i = 0; i < chromWidth; i += 2) { 00365 uint64_t k, l; 00366 k = yc[0] + (uc[0] << 8) + 00367 (yc[1] << 16) + (vc[0] << 24); 00368 l = yc[2] + (uc[1] << 8) + 00369 (yc[3] << 16) + (vc[1] << 24); 00370 *ldst++ = k + (l << 32); 00371 yc += 4; 00372 uc += 2; 00373 vc += 2; 00374 } 00375 00376 #else 00377 int i, *idst = (int32_t *) dst; 00378 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc; 00379 for (i = 0; i < chromWidth; i++) { 00380 #if HAVE_BIGENDIAN 00381 *idst++ = (yc[0] << 24)+ (uc[0] << 16) + 00382 (yc[1] << 8) + (vc[0] << 0); 00383 #else 00384 *idst++ = yc[0] + (uc[0] << 8) + 00385 (yc[1] << 16) + (vc[0] << 24); 00386 #endif 00387 yc += 2; 00388 uc++; 00389 vc++; 00390 } 00391 #endif 00392 if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) { 00393 usrc += chromStride; 00394 vsrc += chromStride; 00395 } 00396 ysrc += lumStride; 00397 dst += dstStride; 00398 } 00399 } 00400 00405 static inline void yv12toyuy2_c(const uint8_t *ysrc, const uint8_t *usrc, 00406 const uint8_t *vsrc, uint8_t *dst, 00407 int width, int height, 00408 int lumStride, int chromStride, 00409 int dstStride) 00410 { 00411 //FIXME interpolate chroma 00412 yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride, 00413 chromStride, dstStride, 2); 00414 } 00415 00416 static inline void yuvPlanartouyvy_c(const uint8_t *ysrc, const uint8_t *usrc, 00417 const uint8_t *vsrc, uint8_t *dst, 00418 int width, int height, 00419 int lumStride, int chromStride, 00420 int dstStride, int vertLumPerChroma) 00421 { 00422 int y; 00423 const int chromWidth = width >> 1; 00424 for (y=0; y<height; y++) { 00425 #if HAVE_FAST_64BIT 00426 int i; 00427 uint64_t *ldst = (uint64_t *) dst; 00428 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc; 00429 for (i = 0; i < chromWidth; i += 2) { 00430 uint64_t k, l; 00431 k = uc[0] + (yc[0] << 8) + 00432 (vc[0] << 16) + (yc[1] << 24); 00433 l = uc[1] + (yc[2] << 8) + 00434 (vc[1] << 16) + (yc[3] << 24); 00435 *ldst++ = k + (l << 32); 00436 yc += 4; 00437 uc += 2; 00438 vc += 2; 00439 } 00440 00441 #else 00442 int i, *idst = (int32_t *) dst; 00443 const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc; 00444 for (i = 0; i < chromWidth; i++) { 00445 #if HAVE_BIGENDIAN 00446 *idst++ = (uc[0] << 24)+ (yc[0] << 16) + 00447 (vc[0] << 8) + (yc[1] << 0); 00448 #else 00449 *idst++ = uc[0] + (yc[0] << 8) + 00450 (vc[0] << 16) + (yc[1] << 24); 00451 #endif 00452 yc += 2; 00453 uc++; 00454 vc++; 00455 } 00456 #endif 00457 if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) { 00458 usrc += chromStride; 00459 vsrc += chromStride; 00460 } 00461 ysrc += lumStride; 00462 dst += dstStride; 00463 } 00464 } 00465 00470 static inline void yv12touyvy_c(const uint8_t *ysrc, const uint8_t *usrc, 00471 const uint8_t *vsrc, uint8_t *dst, 00472 int width, int height, 00473 int lumStride, int chromStride, 00474 int dstStride) 00475 { 00476 //FIXME interpolate chroma 00477 yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride, 00478 chromStride, dstStride, 2); 00479 } 00480 00484 static inline void yuv422ptouyvy_c(const uint8_t *ysrc, const uint8_t *usrc, 00485 const uint8_t *vsrc, uint8_t *dst, 00486 int width, int height, 00487 int lumStride, int chromStride, 00488 int dstStride) 00489 { 00490 yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride, 00491 chromStride, dstStride, 1); 00492 } 00493 00497 static inline void yuv422ptoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc, 00498 const uint8_t *vsrc, uint8_t *dst, 00499 int width, int height, 00500 int lumStride, int chromStride, 00501 int dstStride) 00502 { 00503 yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride, 00504 chromStride, dstStride, 1); 00505 } 00506 00511 static inline void yuy2toyv12_c(const uint8_t *src, uint8_t *ydst, 00512 uint8_t *udst, uint8_t *vdst, 00513 int width, int height, 00514 int lumStride, int chromStride, 00515 int srcStride) 00516 { 00517 int y; 00518 const int chromWidth = width >> 1; 00519 for (y=0; y<height; y+=2) { 00520 int i; 00521 for (i=0; i<chromWidth; i++) { 00522 ydst[2*i+0] = src[4*i+0]; 00523 udst[i] = src[4*i+1]; 00524 ydst[2*i+1] = src[4*i+2]; 00525 vdst[i] = src[4*i+3]; 00526 } 00527 ydst += lumStride; 00528 src += srcStride; 00529 00530 for (i=0; i<chromWidth; i++) { 00531 ydst[2*i+0] = src[4*i+0]; 00532 ydst[2*i+1] = src[4*i+2]; 00533 } 00534 udst += chromStride; 00535 vdst += chromStride; 00536 ydst += lumStride; 00537 src += srcStride; 00538 } 00539 } 00540 00541 static inline void planar2x_c(const uint8_t *src, uint8_t *dst, int srcWidth, 00542 int srcHeight, int srcStride, int dstStride) 00543 { 00544 int x,y; 00545 00546 dst[0]= src[0]; 00547 00548 // first line 00549 for (x=0; x<srcWidth-1; x++) { 00550 dst[2*x+1]= (3*src[x] + src[x+1])>>2; 00551 dst[2*x+2]= ( src[x] + 3*src[x+1])>>2; 00552 } 00553 dst[2*srcWidth-1]= src[srcWidth-1]; 00554 00555 dst+= dstStride; 00556 00557 for (y=1; y<srcHeight; y++) { 00558 const int mmxSize = 1; 00559 00560 dst[0 ]= (3*src[0] + src[srcStride])>>2; 00561 dst[dstStride]= ( src[0] + 3*src[srcStride])>>2; 00562 00563 for (x=mmxSize-1; x<srcWidth-1; x++) { 00564 dst[2*x +1]= (3*src[x+0] + src[x+srcStride+1])>>2; 00565 dst[2*x+dstStride+2]= ( src[x+0] + 3*src[x+srcStride+1])>>2; 00566 dst[2*x+dstStride+1]= ( src[x+1] + 3*src[x+srcStride ])>>2; 00567 dst[2*x +2]= (3*src[x+1] + src[x+srcStride ])>>2; 00568 } 00569 dst[srcWidth*2 -1 ]= (3*src[srcWidth-1] + src[srcWidth-1 + srcStride])>>2; 00570 dst[srcWidth*2 -1 + dstStride]= ( src[srcWidth-1] + 3*src[srcWidth-1 + srcStride])>>2; 00571 00572 dst+=dstStride*2; 00573 src+=srcStride; 00574 } 00575 00576 // last line 00577 dst[0]= src[0]; 00578 00579 for (x=0; x<srcWidth-1; x++) { 00580 dst[2*x+1]= (3*src[x] + src[x+1])>>2; 00581 dst[2*x+2]= ( src[x] + 3*src[x+1])>>2; 00582 } 00583 dst[2*srcWidth-1]= src[srcWidth-1]; 00584 } 00585 00592 static inline void uyvytoyv12_c(const uint8_t *src, uint8_t *ydst, 00593 uint8_t *udst, uint8_t *vdst, 00594 int width, int height, 00595 int lumStride, int chromStride, 00596 int srcStride) 00597 { 00598 int y; 00599 const int chromWidth = width >> 1; 00600 for (y=0; y<height; y+=2) { 00601 int i; 00602 for (i=0; i<chromWidth; i++) { 00603 udst[i] = src[4*i+0]; 00604 ydst[2*i+0] = src[4*i+1]; 00605 vdst[i] = src[4*i+2]; 00606 ydst[2*i+1] = src[4*i+3]; 00607 } 00608 ydst += lumStride; 00609 src += srcStride; 00610 00611 for (i=0; i<chromWidth; i++) { 00612 ydst[2*i+0] = src[4*i+1]; 00613 ydst[2*i+1] = src[4*i+3]; 00614 } 00615 udst += chromStride; 00616 vdst += chromStride; 00617 ydst += lumStride; 00618 src += srcStride; 00619 } 00620 } 00621 00629 void rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst, 00630 uint8_t *vdst, int width, int height, int lumStride, 00631 int chromStride, int srcStride) 00632 { 00633 int y; 00634 const int chromWidth = width >> 1; 00635 y=0; 00636 for (; y<height; y+=2) { 00637 int i; 00638 for (i=0; i<chromWidth; i++) { 00639 unsigned int b = src[6*i+0]; 00640 unsigned int g = src[6*i+1]; 00641 unsigned int r = src[6*i+2]; 00642 00643 unsigned int Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16; 00644 unsigned int V = ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128; 00645 unsigned int U = ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128; 00646 00647 udst[i] = U; 00648 vdst[i] = V; 00649 ydst[2*i] = Y; 00650 00651 b = src[6*i+3]; 00652 g = src[6*i+4]; 00653 r = src[6*i+5]; 00654 00655 Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16; 00656 ydst[2*i+1] = Y; 00657 } 00658 ydst += lumStride; 00659 src += srcStride; 00660 00661 for (i=0; i<chromWidth; i++) { 00662 unsigned int b = src[6*i+0]; 00663 unsigned int g = src[6*i+1]; 00664 unsigned int r = src[6*i+2]; 00665 00666 unsigned int Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16; 00667 00668 ydst[2*i] = Y; 00669 00670 b = src[6*i+3]; 00671 g = src[6*i+4]; 00672 r = src[6*i+5]; 00673 00674 Y = ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16; 00675 ydst[2*i+1] = Y; 00676 } 00677 udst += chromStride; 00678 vdst += chromStride; 00679 ydst += lumStride; 00680 src += srcStride; 00681 } 00682 } 00683 00684 static void interleaveBytes_c(const uint8_t *src1, const uint8_t *src2, 00685 uint8_t *dest, int width, 00686 int height, int src1Stride, 00687 int src2Stride, int dstStride) 00688 { 00689 int h; 00690 00691 for (h=0; h < height; h++) { 00692 int w; 00693 for (w=0; w < width; w++) { 00694 dest[2*w+0] = src1[w]; 00695 dest[2*w+1] = src2[w]; 00696 } 00697 dest += dstStride; 00698 src1 += src1Stride; 00699 src2 += src2Stride; 00700 } 00701 } 00702 00703 static inline void vu9_to_vu12_c(const uint8_t *src1, const uint8_t *src2, 00704 uint8_t *dst1, uint8_t *dst2, 00705 int width, int height, 00706 int srcStride1, int srcStride2, 00707 int dstStride1, int dstStride2) 00708 { 00709 int y; 00710 int x,w,h; 00711 w=width/2; h=height/2; 00712 for (y=0;y<h;y++) { 00713 const uint8_t* s1=src1+srcStride1*(y>>1); 00714 uint8_t* d=dst1+dstStride1*y; 00715 x=0; 00716 for (;x<w;x++) d[2*x]=d[2*x+1]=s1[x]; 00717 } 00718 for (y=0;y<h;y++) { 00719 const uint8_t* s2=src2+srcStride2*(y>>1); 00720 uint8_t* d=dst2+dstStride2*y; 00721 x=0; 00722 for (;x<w;x++) d[2*x]=d[2*x+1]=s2[x]; 00723 } 00724 } 00725 00726 static inline void yvu9_to_yuy2_c(const uint8_t *src1, const uint8_t *src2, 00727 const uint8_t *src3, uint8_t *dst, 00728 int width, int height, 00729 int srcStride1, int srcStride2, 00730 int srcStride3, int dstStride) 00731 { 00732 int x; 00733 int y,w,h; 00734 w=width/2; h=height; 00735 for (y=0;y<h;y++) { 00736 const uint8_t* yp=src1+srcStride1*y; 00737 const uint8_t* up=src2+srcStride2*(y>>2); 00738 const uint8_t* vp=src3+srcStride3*(y>>2); 00739 uint8_t* d=dst+dstStride*y; 00740 x=0; 00741 for (; x<w; x++) { 00742 const int x2 = x<<2; 00743 d[8*x+0] = yp[x2]; 00744 d[8*x+1] = up[x]; 00745 d[8*x+2] = yp[x2+1]; 00746 d[8*x+3] = vp[x]; 00747 d[8*x+4] = yp[x2+2]; 00748 d[8*x+5] = up[x]; 00749 d[8*x+6] = yp[x2+3]; 00750 d[8*x+7] = vp[x]; 00751 } 00752 } 00753 } 00754 00755 static void extract_even_c(const uint8_t *src, uint8_t *dst, int count) 00756 { 00757 dst += count; 00758 src += 2*count; 00759 count= - count; 00760 00761 while(count<0) { 00762 dst[count]= src[2*count]; 00763 count++; 00764 } 00765 } 00766 00767 static void extract_even2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1, 00768 int count) 00769 { 00770 dst0+= count; 00771 dst1+= count; 00772 src += 4*count; 00773 count= - count; 00774 while(count<0) { 00775 dst0[count]= src[4*count+0]; 00776 dst1[count]= src[4*count+2]; 00777 count++; 00778 } 00779 } 00780 00781 static void extract_even2avg_c(const uint8_t *src0, const uint8_t *src1, 00782 uint8_t *dst0, uint8_t *dst1, int count) 00783 { 00784 dst0 += count; 00785 dst1 += count; 00786 src0 += 4*count; 00787 src1 += 4*count; 00788 count= - count; 00789 while(count<0) { 00790 dst0[count]= (src0[4*count+0]+src1[4*count+0])>>1; 00791 dst1[count]= (src0[4*count+2]+src1[4*count+2])>>1; 00792 count++; 00793 } 00794 } 00795 00796 static void extract_odd2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1, 00797 int count) 00798 { 00799 dst0+= count; 00800 dst1+= count; 00801 src += 4*count; 00802 count= - count; 00803 src++; 00804 while(count<0) { 00805 dst0[count]= src[4*count+0]; 00806 dst1[count]= src[4*count+2]; 00807 count++; 00808 } 00809 } 00810 00811 static void extract_odd2avg_c(const uint8_t *src0, const uint8_t *src1, 00812 uint8_t *dst0, uint8_t *dst1, int count) 00813 { 00814 dst0 += count; 00815 dst1 += count; 00816 src0 += 4*count; 00817 src1 += 4*count; 00818 count= - count; 00819 src0++; 00820 src1++; 00821 while(count<0) { 00822 dst0[count]= (src0[4*count+0]+src1[4*count+0])>>1; 00823 dst1[count]= (src0[4*count+2]+src1[4*count+2])>>1; 00824 count++; 00825 } 00826 } 00827 00828 static void yuyvtoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, 00829 const uint8_t *src, int width, int height, 00830 int lumStride, int chromStride, int srcStride) 00831 { 00832 int y; 00833 const int chromWidth= -((-width)>>1); 00834 00835 for (y=0; y<height; y++) { 00836 extract_even_c(src, ydst, width); 00837 if(y&1) { 00838 extract_odd2avg_c(src - srcStride, src, udst, vdst, chromWidth); 00839 udst+= chromStride; 00840 vdst+= chromStride; 00841 } 00842 00843 src += srcStride; 00844 ydst+= lumStride; 00845 } 00846 } 00847 00848 static void yuyvtoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, 00849 const uint8_t *src, int width, int height, 00850 int lumStride, int chromStride, int srcStride) 00851 { 00852 int y; 00853 const int chromWidth= -((-width)>>1); 00854 00855 for (y=0; y<height; y++) { 00856 extract_even_c(src, ydst, width); 00857 extract_odd2_c(src, udst, vdst, chromWidth); 00858 00859 src += srcStride; 00860 ydst+= lumStride; 00861 udst+= chromStride; 00862 vdst+= chromStride; 00863 } 00864 } 00865 00866 static void uyvytoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, 00867 const uint8_t *src, int width, int height, 00868 int lumStride, int chromStride, int srcStride) 00869 { 00870 int y; 00871 const int chromWidth= -((-width)>>1); 00872 00873 for (y=0; y<height; y++) { 00874 extract_even_c(src + 1, ydst, width); 00875 if(y&1) { 00876 extract_even2avg_c(src - srcStride, src, udst, vdst, chromWidth); 00877 udst+= chromStride; 00878 vdst+= chromStride; 00879 } 00880 00881 src += srcStride; 00882 ydst+= lumStride; 00883 } 00884 } 00885 00886 static void uyvytoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, 00887 const uint8_t *src, int width, int height, 00888 int lumStride, int chromStride, int srcStride) 00889 { 00890 int y; 00891 const int chromWidth= -((-width)>>1); 00892 00893 for (y=0; y<height; y++) { 00894 extract_even_c(src + 1, ydst, width); 00895 extract_even2_c(src, udst, vdst, chromWidth); 00896 00897 src += srcStride; 00898 ydst+= lumStride; 00899 udst+= chromStride; 00900 vdst+= chromStride; 00901 } 00902 } 00903 00904 static inline void rgb2rgb_init_c(void) 00905 { 00906 rgb15to16 = rgb15to16_c; 00907 rgb15tobgr24 = rgb15tobgr24_c; 00908 rgb15to32 = rgb15to32_c; 00909 rgb16tobgr24 = rgb16tobgr24_c; 00910 rgb16to32 = rgb16to32_c; 00911 rgb16to15 = rgb16to15_c; 00912 rgb24tobgr16 = rgb24tobgr16_c; 00913 rgb24tobgr15 = rgb24tobgr15_c; 00914 rgb24tobgr32 = rgb24tobgr32_c; 00915 rgb32to16 = rgb32to16_c; 00916 rgb32to15 = rgb32to15_c; 00917 rgb32tobgr24 = rgb32tobgr24_c; 00918 rgb24to15 = rgb24to15_c; 00919 rgb24to16 = rgb24to16_c; 00920 rgb24tobgr24 = rgb24tobgr24_c; 00921 shuffle_bytes_2103 = shuffle_bytes_2103_c; 00922 rgb32tobgr16 = rgb32tobgr16_c; 00923 rgb32tobgr15 = rgb32tobgr15_c; 00924 yv12toyuy2 = yv12toyuy2_c; 00925 yv12touyvy = yv12touyvy_c; 00926 yuv422ptoyuy2 = yuv422ptoyuy2_c; 00927 yuv422ptouyvy = yuv422ptouyvy_c; 00928 yuy2toyv12 = yuy2toyv12_c; 00929 planar2x = planar2x_c; 00930 rgb24toyv12 = rgb24toyv12_c; 00931 interleaveBytes = interleaveBytes_c; 00932 vu9_to_vu12 = vu9_to_vu12_c; 00933 yvu9_to_yuy2 = yvu9_to_yuy2_c; 00934 00935 uyvytoyuv420 = uyvytoyuv420_c; 00936 uyvytoyuv422 = uyvytoyuv422_c; 00937 yuyvtoyuv420 = yuyvtoyuv420_c; 00938 yuyvtoyuv422 = yuyvtoyuv422_c; 00939 }