Libav 0.7.1
libswscale/rgb2rgb_template.c
Go to the documentation of this file.
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 }