LCOV - code coverage report
Current view: top level - libswscale - rgb2rgb_template.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 100 518 19.3 %
Date: 2017-10-24 00:14:43 Functions: 8 42 19.0 %

          Line data    Source code
       1             : /*
       2             :  * software RGB to RGB converter
       3             :  * pluralize by software PAL8 to RGB converter
       4             :  *              software YUV to YUV converter
       5             :  *              software YUV to RGB converter
       6             :  * Written by Nick Kurshev.
       7             :  * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
       8             :  * lot of big-endian byte order fixes by Alex Beregszaszi
       9             :  *
      10             :  * This file is part of FFmpeg.
      11             :  *
      12             :  * FFmpeg is free software; you can redistribute it and/or
      13             :  * modify it under the terms of the GNU Lesser General Public
      14             :  * License as published by the Free Software Foundation; either
      15             :  * version 2.1 of the License, or (at your option) any later version.
      16             :  *
      17             :  * FFmpeg is distributed in the hope that it will be useful,
      18             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      20             :  * Lesser General Public License for more details.
      21             :  *
      22             :  * You should have received a copy of the GNU Lesser General Public
      23             :  * License along with FFmpeg; if not, write to the Free Software
      24             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      25             :  */
      26             : 
      27             : #include <stddef.h>
      28             : 
      29             : #include "libavutil/attributes.h"
      30             : 
      31           1 : static inline void rgb24tobgr32_c(const uint8_t *src, uint8_t *dst,
      32             :                                   int src_size)
      33             : {
      34           1 :     uint8_t *dest      = dst;
      35           1 :     const uint8_t *s   = src;
      36           1 :     const uint8_t *end = s + src_size;
      37             : 
      38       65538 :     while (s < end) {
      39             : #if HAVE_BIGENDIAN
      40             :         /* RGB24 (= R, G, B) -> RGB32 (= A, B, G, R) */
      41             :         *dest++  = 255;
      42             :         *dest++  = s[2];
      43             :         *dest++  = s[1];
      44             :         *dest++  = s[0];
      45             :         s       += 3;
      46             : #else
      47       65536 :         *dest++  = *s++;
      48       65536 :         *dest++  = *s++;
      49       65536 :         *dest++  = *s++;
      50       65536 :         *dest++  = 255;
      51             : #endif
      52             :     }
      53           1 : }
      54             : 
      55           4 : static inline void rgb32tobgr24_c(const uint8_t *src, uint8_t *dst,
      56             :                                   int src_size)
      57             : {
      58           4 :     uint8_t *dest      = dst;
      59           4 :     const uint8_t *s   = src;
      60           4 :     const uint8_t *end = s + src_size;
      61             : 
      62       49158 :     while (s < end) {
      63             : #if HAVE_BIGENDIAN
      64             :         /* RGB32 (= A, B, G, R) -> RGB24 (= R, G, B) */
      65             :         s++;
      66             :         dest[2]  = *s++;
      67             :         dest[1]  = *s++;
      68             :         dest[0]  = *s++;
      69             :         dest    += 3;
      70             : #else
      71       49150 :         *dest++  = *s++;
      72       49150 :         *dest++  = *s++;
      73       49150 :         *dest++  = *s++;
      74       49150 :         s++;
      75             : #endif
      76             :     }
      77           4 : }
      78             : 
      79             : /*
      80             :  * original by Strepto/Astral
      81             :  * ported to gcc & bugfixed: A'rpi
      82             :  * MMXEXT, 3DNOW optimization by Nick Kurshev
      83             :  * 32-bit C version, and and&add trick by Michael Niedermayer
      84             :  */
      85           0 : static inline void rgb15to16_c(const uint8_t *src, uint8_t *dst, int src_size)
      86             : {
      87           0 :     register uint8_t *d         = dst;
      88           0 :     register const uint8_t *s   = src;
      89           0 :     register const uint8_t *end = s + src_size;
      90           0 :     const uint8_t *mm_end       = end - 3;
      91             : 
      92           0 :     while (s < mm_end) {
      93           0 :         register unsigned x = *((const uint32_t *)s);
      94           0 :         *((uint32_t *)d)    = (x & 0x7FFF7FFF) + (x & 0x7FE07FE0);
      95           0 :         d += 4;
      96           0 :         s += 4;
      97             :     }
      98           0 :     if (s < end) {
      99           0 :         register unsigned short x = *((const uint16_t *)s);
     100           0 :         *((uint16_t *)d)          = (x & 0x7FFF) + (x & 0x7FE0);
     101             :     }
     102           0 : }
     103             : 
     104           0 : static inline void rgb16to15_c(const uint8_t *src, uint8_t *dst, int src_size)
     105             : {
     106           0 :     register uint8_t *d         = dst;
     107           0 :     register const uint8_t *s   = src;
     108           0 :     register const uint8_t *end = s + src_size;
     109           0 :     const uint8_t *mm_end       = end - 3;
     110             : 
     111           0 :     while (s < mm_end) {
     112           0 :         register uint32_t x  = *((const uint32_t *)s);
     113           0 :         *((uint32_t *)d)     = ((x >> 1) & 0x7FE07FE0) | (x & 0x001F001F);
     114           0 :         s                   += 4;
     115           0 :         d                   += 4;
     116             :     }
     117           0 :     if (s < end) {
     118           0 :         register uint16_t x = *((const uint16_t *)s);
     119           0 :         *((uint16_t *)d)    = ((x >> 1) & 0x7FE0) | (x & 0x001F);
     120             :     }
     121           0 : }
     122             : 
     123           0 : static inline void rgb32to16_c(const uint8_t *src, uint8_t *dst, int src_size)
     124             : {
     125           0 :     uint16_t *d        = (uint16_t *)dst;
     126           0 :     const uint8_t *s   = src;
     127           0 :     const uint8_t *end = s + src_size;
     128             : 
     129           0 :     while (s < end) {
     130           0 :         register int rgb  = *(const uint32_t *)s;
     131           0 :         s                += 4;
     132           0 :         *d++              = ((rgb & 0xFF)     >> 3) +
     133           0 :                             ((rgb & 0xFC00)   >> 5) +
     134           0 :                             ((rgb & 0xF80000) >> 8);
     135             :     }
     136           0 : }
     137             : 
     138           0 : static inline void rgb32tobgr16_c(const uint8_t *src, uint8_t *dst,
     139             :                                   int src_size)
     140             : {
     141           0 :     uint16_t *d        = (uint16_t *)dst;
     142           0 :     const uint8_t *s   = src;
     143           0 :     const uint8_t *end = s + src_size;
     144             : 
     145           0 :     while (s < end) {
     146           0 :         register int rgb  = *(const uint32_t *)s;
     147           0 :         s                += 4;
     148           0 :         *d++              = ((rgb & 0xF8)     << 8) +
     149           0 :                             ((rgb & 0xFC00)   >> 5) +
     150           0 :                             ((rgb & 0xF80000) >> 19);
     151             :     }
     152           0 : }
     153             : 
     154           0 : static inline void rgb32to15_c(const uint8_t *src, uint8_t *dst, int src_size)
     155             : {
     156           0 :     uint16_t *d        = (uint16_t *)dst;
     157           0 :     const uint8_t *s   = src;
     158           0 :     const uint8_t *end = s + src_size;
     159             : 
     160           0 :     while (s < end) {
     161           0 :         register int rgb  = *(const uint32_t *)s;
     162           0 :         s                += 4;
     163           0 :         *d++              = ((rgb & 0xFF)     >> 3) +
     164           0 :                             ((rgb & 0xF800)   >> 6) +
     165           0 :                             ((rgb & 0xF80000) >> 9);
     166             :     }
     167           0 : }
     168             : 
     169           0 : static inline void rgb32tobgr15_c(const uint8_t *src, uint8_t *dst,
     170             :                                   int src_size)
     171             : {
     172           0 :     uint16_t *d        = (uint16_t *)dst;
     173           0 :     const uint8_t *s   = src;
     174           0 :     const uint8_t *end = s + src_size;
     175             : 
     176           0 :     while (s < end) {
     177           0 :         register int rgb  = *(const uint32_t *)s;
     178           0 :         s                += 4;
     179           0 :         *d++              = ((rgb & 0xF8)     <<  7) +
     180           0 :                             ((rgb & 0xF800)   >>  6) +
     181           0 :                             ((rgb & 0xF80000) >> 19);
     182             :     }
     183           0 : }
     184             : 
     185           0 : static inline void rgb24tobgr16_c(const uint8_t *src, uint8_t *dst,
     186             :                                   int src_size)
     187             : {
     188           0 :     uint16_t *d        = (uint16_t *)dst;
     189           0 :     const uint8_t *s   = src;
     190           0 :     const uint8_t *end = s + src_size;
     191             : 
     192           0 :     while (s < end) {
     193           0 :         const int b = *s++;
     194           0 :         const int g = *s++;
     195           0 :         const int r = *s++;
     196           0 :         *d++        = (b >> 3) | ((g & 0xFC) << 3) | ((r & 0xF8) << 8);
     197             :     }
     198           0 : }
     199             : 
     200           0 : static inline void rgb24to16_c(const uint8_t *src, uint8_t *dst, int src_size)
     201             : {
     202           0 :     uint16_t *d        = (uint16_t *)dst;
     203           0 :     const uint8_t *s   = src;
     204           0 :     const uint8_t *end = s + src_size;
     205             : 
     206           0 :     while (s < end) {
     207           0 :         const int r = *s++;
     208           0 :         const int g = *s++;
     209           0 :         const int b = *s++;
     210           0 :         *d++        = (b >> 3) | ((g & 0xFC) << 3) | ((r & 0xF8) << 8);
     211             :     }
     212           0 : }
     213             : 
     214           0 : static inline void rgb24tobgr15_c(const uint8_t *src, uint8_t *dst,
     215             :                                   int src_size)
     216             : {
     217           0 :     uint16_t *d        = (uint16_t *)dst;
     218           0 :     const uint8_t *s   = src;
     219           0 :     const uint8_t *end = s + src_size;
     220             : 
     221           0 :     while (s < end) {
     222           0 :         const int b = *s++;
     223           0 :         const int g = *s++;
     224           0 :         const int r = *s++;
     225           0 :         *d++        = (b >> 3) | ((g & 0xF8) << 2) | ((r & 0xF8) << 7);
     226             :     }
     227           0 : }
     228             : 
     229           0 : static inline void rgb24to15_c(const uint8_t *src, uint8_t *dst, int src_size)
     230             : {
     231           0 :     uint16_t *d        = (uint16_t *)dst;
     232           0 :     const uint8_t *s   = src;
     233           0 :     const uint8_t *end = s + src_size;
     234             : 
     235           0 :     while (s < end) {
     236           0 :         const int r = *s++;
     237           0 :         const int g = *s++;
     238           0 :         const int b = *s++;
     239           0 :         *d++        = (b >> 3) | ((g & 0xF8) << 2) | ((r & 0xF8) << 7);
     240             :     }
     241           0 : }
     242             : 
     243       19489 : static inline void rgb15tobgr24_c(const uint8_t *src, uint8_t *dst,
     244             :                                   int src_size)
     245             : {
     246       19489 :     uint8_t *d          = dst;
     247       19489 :     const uint16_t *s   = (const uint16_t *)src;
     248       19489 :     const uint16_t *end = s + src_size / 2;
     249             : 
     250     4847170 :     while (s < end) {
     251     4808192 :         register uint16_t bgr = *s++;
     252     4808192 :         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     253     4808192 :         *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
     254     4808192 :         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
     255             :     }
     256       19489 : }
     257             : 
     258           0 : static inline void rgb16tobgr24_c(const uint8_t *src, uint8_t *dst,
     259             :                                   int src_size)
     260             : {
     261           0 :     uint8_t *d          = (uint8_t *)dst;
     262           0 :     const uint16_t *s   = (const uint16_t *)src;
     263           0 :     const uint16_t *end = s + src_size / 2;
     264             : 
     265           0 :     while (s < end) {
     266           0 :         register uint16_t bgr = *s++;
     267           0 :         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     268           0 :         *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
     269           0 :         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
     270             :     }
     271           0 : }
     272             : 
     273           0 : static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, int src_size)
     274             : {
     275           0 :     uint8_t *d          = dst;
     276           0 :     const uint16_t *s   = (const uint16_t *)src;
     277           0 :     const uint16_t *end = s + src_size / 2;
     278             : 
     279           0 :     while (s < end) {
     280           0 :         register uint16_t bgr = *s++;
     281             : #if HAVE_BIGENDIAN
     282             :         *d++ = 255;
     283             :         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
     284             :         *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
     285             :         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     286             : #else
     287           0 :         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     288           0 :         *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
     289           0 :         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
     290           0 :         *d++ = 255;
     291             : #endif
     292             :     }
     293           0 : }
     294             : 
     295           0 : static inline void rgb16to32_c(const uint8_t *src, uint8_t *dst, int src_size)
     296             : {
     297           0 :     uint8_t *d          = dst;
     298           0 :     const uint16_t *s   = (const uint16_t *)src;
     299           0 :     const uint16_t *end = s + src_size / 2;
     300             : 
     301           0 :     while (s < end) {
     302           0 :         register uint16_t bgr = *s++;
     303             : #if HAVE_BIGENDIAN
     304             :         *d++ = 255;
     305             :         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
     306             :         *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
     307             :         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     308             : #else
     309           0 :         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     310           0 :         *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
     311           0 :         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
     312           0 :         *d++ = 255;
     313             : #endif
     314             :     }
     315           0 : }
     316             : 
     317           9 : static inline void shuffle_bytes_2103_c(const uint8_t *src, uint8_t *dst,
     318             :                                         int src_size)
     319             : {
     320           9 :     int idx          = 15  - src_size;
     321           9 :     const uint8_t *s = src - idx;
     322           9 :     uint8_t *d       = dst - idx;
     323             : 
     324      331395 :     for (; idx < 15; idx += 4) {
     325      331386 :         register unsigned v   = *(const uint32_t *)&s[idx], g = v & 0xff00ff00;
     326      331386 :         v                    &= 0xff00ff;
     327      331386 :         *(uint32_t *)&d[idx]  = (v >> 16) + g + (v << 16);
     328             :     }
     329           9 : }
     330             : 
     331           0 : static inline void shuffle_bytes_0321_c(const uint8_t *src, uint8_t *dst,
     332             :                                         int src_size)
     333             : {
     334           0 :     int idx          = 15  - src_size;
     335           0 :     const uint8_t *s = src - idx;
     336           0 :     uint8_t *d       = dst - idx;
     337             : 
     338           0 :     for (; idx < 15; idx += 4) {
     339           0 :         register unsigned v   = *(const uint32_t *)&s[idx], g = v & 0x00ff00ff;
     340           0 :         v                    &= 0xff00ff00;
     341           0 :         *(uint32_t *)&d[idx]  = (v >> 16) + g + (v << 16);
     342             :     }
     343           0 : }
     344             : 
     345          35 : static inline void rgb24tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size)
     346             : {
     347             :     unsigned i;
     348             : 
     349     2727875 :     for (i = 0; i < src_size; i += 3) {
     350     2727840 :         register uint8_t x = src[i + 2];
     351     2727840 :         dst[i + 1]         = src[i + 1];
     352     2727840 :         dst[i + 2]         = src[i + 0];
     353     2727840 :         dst[i + 0]         = x;
     354             :     }
     355          35 : }
     356             : 
     357           0 : static inline void yuvPlanartoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
     358             :                                      const uint8_t *vsrc, uint8_t *dst,
     359             :                                      int width, int height,
     360             :                                      int lumStride, int chromStride,
     361             :                                      int dstStride, int vertLumPerChroma)
     362             : {
     363             :     int y, i;
     364           0 :     const int chromWidth = width >> 1;
     365             : 
     366           0 :     for (y = 0; y < height; y++) {
     367             : #if HAVE_FAST_64BIT
     368           0 :         uint64_t *ldst = (uint64_t *)dst;
     369           0 :         const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
     370           0 :         for (i = 0; i < chromWidth; i += 2) {
     371           0 :             uint64_t k = yc[0] + (uc[0] << 8) +
     372           0 :                          (yc[1] << 16) + ((unsigned) vc[0] << 24);
     373           0 :             uint64_t l = yc[2] + (uc[1] << 8) +
     374           0 :                          (yc[3] << 16) + ((unsigned) vc[1] << 24);
     375           0 :             *ldst++ = k + (l << 32);
     376           0 :             yc     += 4;
     377           0 :             uc     += 2;
     378           0 :             vc     += 2;
     379             :         }
     380             : 
     381             : #else
     382             :         int *idst = (int32_t *)dst;
     383             :         const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
     384             : 
     385             :         for (i = 0; i < chromWidth; i++) {
     386             : #if HAVE_BIGENDIAN
     387             :             *idst++ = (yc[0] << 24) + (uc[0] << 16) +
     388             :                       (yc[1] <<  8) + (vc[0] <<  0);
     389             : #else
     390             :             *idst++ = yc[0] + (uc[0] << 8) +
     391             :                       (yc[1] << 16) + (vc[0] << 24);
     392             : #endif
     393             :             yc += 2;
     394             :             uc++;
     395             :             vc++;
     396             :         }
     397             : #endif
     398           0 :         if ((y & (vertLumPerChroma - 1)) == vertLumPerChroma - 1) {
     399           0 :             usrc += chromStride;
     400           0 :             vsrc += chromStride;
     401             :         }
     402           0 :         ysrc += lumStride;
     403           0 :         dst  += dstStride;
     404             :     }
     405           0 : }
     406             : 
     407             : /**
     408             :  * Height should be a multiple of 2 and width should be a multiple of 16.
     409             :  * (If this is a problem for anyone then tell me, and I will fix it.)
     410             :  */
     411           0 : static inline void yv12toyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
     412             :                                 const uint8_t *vsrc, uint8_t *dst,
     413             :                                 int width, int height, int lumStride,
     414             :                                 int chromStride, int dstStride)
     415             : {
     416             :     //FIXME interpolate chroma
     417           0 :     yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
     418             :                       chromStride, dstStride, 2);
     419           0 : }
     420             : 
     421           0 : static inline void yuvPlanartouyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
     422             :                                      const uint8_t *vsrc, uint8_t *dst,
     423             :                                      int width, int height,
     424             :                                      int lumStride, int chromStride,
     425             :                                      int dstStride, int vertLumPerChroma)
     426             : {
     427             :     int y, i;
     428           0 :     const int chromWidth = width >> 1;
     429             : 
     430           0 :     for (y = 0; y < height; y++) {
     431             : #if HAVE_FAST_64BIT
     432           0 :         uint64_t *ldst = (uint64_t *)dst;
     433           0 :         const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
     434           0 :         for (i = 0; i < chromWidth; i += 2) {
     435           0 :             uint64_t k = uc[0] + (yc[0] << 8) +
     436           0 :                          (vc[0] << 16) + ((unsigned) yc[1] << 24);
     437           0 :             uint64_t l = uc[1] + (yc[2] << 8) +
     438           0 :                          (vc[1] << 16) + ((unsigned) yc[3] << 24);
     439           0 :             *ldst++ = k + (l << 32);
     440           0 :             yc     += 4;
     441           0 :             uc     += 2;
     442           0 :             vc     += 2;
     443             :         }
     444             : 
     445             : #else
     446             :         int *idst = (int32_t *)dst;
     447             :         const uint8_t *yc = ysrc, *uc = usrc, *vc = vsrc;
     448             : 
     449             :         for (i = 0; i < chromWidth; i++) {
     450             : #if HAVE_BIGENDIAN
     451             :             *idst++ = (uc[0] << 24) + (yc[0] << 16) +
     452             :                       (vc[0] <<  8) + (yc[1] <<  0);
     453             : #else
     454             :             *idst++ = uc[0] + (yc[0] << 8) +
     455             :                       (vc[0] << 16) + (yc[1] << 24);
     456             : #endif
     457             :             yc += 2;
     458             :             uc++;
     459             :             vc++;
     460             :         }
     461             : #endif
     462           0 :         if ((y & (vertLumPerChroma - 1)) == vertLumPerChroma - 1) {
     463           0 :             usrc += chromStride;
     464           0 :             vsrc += chromStride;
     465             :         }
     466           0 :         ysrc += lumStride;
     467           0 :         dst  += dstStride;
     468             :     }
     469           0 : }
     470             : 
     471             : /**
     472             :  * Height should be a multiple of 2 and width should be a multiple of 16
     473             :  * (If this is a problem for anyone then tell me, and I will fix it.)
     474             :  */
     475           0 : static inline void yv12touyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
     476             :                                 const uint8_t *vsrc, uint8_t *dst,
     477             :                                 int width, int height, int lumStride,
     478             :                                 int chromStride, int dstStride)
     479             : {
     480             :     //FIXME interpolate chroma
     481           0 :     yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
     482             :                       chromStride, dstStride, 2);
     483           0 : }
     484             : 
     485             : /**
     486             :  * Width should be a multiple of 16.
     487             :  */
     488           0 : static inline void yuv422ptouyvy_c(const uint8_t *ysrc, const uint8_t *usrc,
     489             :                                    const uint8_t *vsrc, uint8_t *dst,
     490             :                                    int width, int height, int lumStride,
     491             :                                    int chromStride, int dstStride)
     492             : {
     493           0 :     yuvPlanartouyvy_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
     494             :                       chromStride, dstStride, 1);
     495           0 : }
     496             : 
     497             : /**
     498             :  * Width should be a multiple of 16.
     499             :  */
     500           0 : static inline void yuv422ptoyuy2_c(const uint8_t *ysrc, const uint8_t *usrc,
     501             :                                    const uint8_t *vsrc, uint8_t *dst,
     502             :                                    int width, int height, int lumStride,
     503             :                                    int chromStride, int dstStride)
     504             : {
     505           0 :     yuvPlanartoyuy2_c(ysrc, usrc, vsrc, dst, width, height, lumStride,
     506             :                       chromStride, dstStride, 1);
     507           0 : }
     508             : 
     509             : /**
     510             :  * Height should be a multiple of 2 and width should be a multiple of 16.
     511             :  * (If this is a problem for anyone then tell me, and I will fix it.)
     512             :  */
     513           0 : static inline void yuy2toyv12_c(const uint8_t *src, uint8_t *ydst,
     514             :                                 uint8_t *udst, uint8_t *vdst,
     515             :                                 int width, int height, int lumStride,
     516             :                                 int chromStride, int srcStride)
     517             : {
     518             :     int y;
     519           0 :     const int chromWidth = width >> 1;
     520             : 
     521           0 :     for (y = 0; y < height; y += 2) {
     522             :         int i;
     523           0 :         for (i = 0; i < chromWidth; i++) {
     524           0 :             ydst[2 * i + 0] = src[4 * i + 0];
     525           0 :             udst[i]         = src[4 * i + 1];
     526           0 :             ydst[2 * i + 1] = src[4 * i + 2];
     527           0 :             vdst[i]         = src[4 * i + 3];
     528             :         }
     529           0 :         ydst += lumStride;
     530           0 :         src  += srcStride;
     531             : 
     532           0 :         for (i = 0; i < chromWidth; i++) {
     533           0 :             ydst[2 * i + 0] = src[4 * i + 0];
     534           0 :             ydst[2 * i + 1] = src[4 * i + 2];
     535             :         }
     536           0 :         udst += chromStride;
     537           0 :         vdst += chromStride;
     538           0 :         ydst += lumStride;
     539           0 :         src  += srcStride;
     540             :     }
     541           0 : }
     542             : 
     543           0 : static inline void planar2x_c(const uint8_t *src, uint8_t *dst, int srcWidth,
     544             :                               int srcHeight, int srcStride, int dstStride)
     545             : {
     546             :     int x, y;
     547             : 
     548           0 :     dst[0] = src[0];
     549             : 
     550             :     // first line
     551           0 :     for (x = 0; x < srcWidth - 1; x++) {
     552           0 :         dst[2 * x + 1] = (3 * src[x] + src[x + 1]) >> 2;
     553           0 :         dst[2 * x + 2] = (src[x] + 3 * src[x + 1]) >> 2;
     554             :     }
     555           0 :     dst[2 * srcWidth - 1] = src[srcWidth - 1];
     556             : 
     557           0 :     dst += dstStride;
     558             : 
     559           0 :     for (y = 1; y < srcHeight; y++) {
     560           0 :         const int mmxSize = 1;
     561             : 
     562           0 :         dst[0]         = (src[0] * 3 + src[srcStride]) >> 2;
     563           0 :         dst[dstStride] = (src[0] + 3 * src[srcStride]) >> 2;
     564             : 
     565           0 :         for (x = mmxSize - 1; x < srcWidth - 1; x++) {
     566           0 :             dst[2 * x + 1]             = (src[x + 0] * 3 + src[x + srcStride + 1]) >> 2;
     567           0 :             dst[2 * x + dstStride + 2] = (src[x + 0] + 3 * src[x + srcStride + 1]) >> 2;
     568           0 :             dst[2 * x + dstStride + 1] = (src[x + 1] + 3 * src[x + srcStride])     >> 2;
     569           0 :             dst[2 * x + 2]             = (src[x + 1] * 3 + src[x + srcStride])     >> 2;
     570             :         }
     571           0 :         dst[srcWidth * 2 - 1]             = (src[srcWidth - 1] * 3 + src[srcWidth - 1 + srcStride]) >> 2;
     572           0 :         dst[srcWidth * 2 - 1 + dstStride] = (src[srcWidth - 1] + 3 * src[srcWidth - 1 + srcStride]) >> 2;
     573             : 
     574           0 :         dst += dstStride * 2;
     575           0 :         src += srcStride;
     576             :     }
     577             : 
     578             :     // last line
     579           0 :     dst[0] = src[0];
     580             : 
     581           0 :     for (x = 0; x < srcWidth - 1; x++) {
     582           0 :         dst[2 * x + 1] = (src[x] * 3 + src[x + 1]) >> 2;
     583           0 :         dst[2 * x + 2] = (src[x] + 3 * src[x + 1]) >> 2;
     584             :     }
     585           0 :     dst[2 * srcWidth - 1] = src[srcWidth - 1];
     586           0 : }
     587             : 
     588             : /**
     589             :  * Height should be a multiple of 2 and width should be a multiple of 16.
     590             :  * (If this is a problem for anyone then tell me, and I will fix it.)
     591             :  * Chrominance data is only taken from every second line, others are ignored.
     592             :  * FIXME: Write HQ version.
     593             :  */
     594             : static inline void uyvytoyv12_c(const uint8_t *src, uint8_t *ydst,
     595             :                                 uint8_t *udst, uint8_t *vdst,
     596             :                                 int width, int height, int lumStride,
     597             :                                 int chromStride, int srcStride)
     598             : {
     599             :     int y;
     600             :     const int chromWidth = width >> 1;
     601             : 
     602             :     for (y = 0; y < height; y += 2) {
     603             :         int i;
     604             :         for (i = 0; i < chromWidth; i++) {
     605             :             udst[i]         = src[4 * i + 0];
     606             :             ydst[2 * i + 0] = src[4 * i + 1];
     607             :             vdst[i]         = src[4 * i + 2];
     608             :             ydst[2 * i + 1] = src[4 * i + 3];
     609             :         }
     610             :         ydst += lumStride;
     611             :         src  += srcStride;
     612             : 
     613             :         for (i = 0; i < chromWidth; i++) {
     614             :             ydst[2 * i + 0] = src[4 * i + 1];
     615             :             ydst[2 * i + 1] = src[4 * i + 3];
     616             :         }
     617             :         udst += chromStride;
     618             :         vdst += chromStride;
     619             :         ydst += lumStride;
     620             :         src  += srcStride;
     621             :     }
     622             : }
     623             : 
     624             : /**
     625             :  * Height should be a multiple of 2 and width should be a multiple of 2.
     626             :  * (If this is a problem for anyone then tell me, and I will fix it.)
     627             :  * Chrominance data is only taken from every second line,
     628             :  * others are ignored in the C version.
     629             :  * FIXME: Write HQ version.
     630             :  */
     631           0 : void ff_rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst,
     632             :                    uint8_t *vdst, int width, int height, int lumStride,
     633             :                    int chromStride, int srcStride, int32_t *rgb2yuv)
     634             : {
     635           0 :     int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX];
     636           0 :     int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX];
     637           0 :     int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX];
     638             :     int y;
     639           0 :     const int chromWidth = width >> 1;
     640             : 
     641           0 :     for (y = 0; y < height; y += 2) {
     642             :         int i;
     643           0 :         for (i = 0; i < chromWidth; i++) {
     644           0 :             unsigned int b = src[6 * i + 0];
     645           0 :             unsigned int g = src[6 * i + 1];
     646           0 :             unsigned int r = src[6 * i + 2];
     647             : 
     648           0 :             unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) +  16;
     649           0 :             unsigned int V = ((rv * r + gv * g + bv * b) >> RGB2YUV_SHIFT) + 128;
     650           0 :             unsigned int U = ((ru * r + gu * g + bu * b) >> RGB2YUV_SHIFT) + 128;
     651             : 
     652           0 :             udst[i]     = U;
     653           0 :             vdst[i]     = V;
     654           0 :             ydst[2 * i] = Y;
     655             : 
     656           0 :             b = src[6 * i + 3];
     657           0 :             g = src[6 * i + 4];
     658           0 :             r = src[6 * i + 5];
     659             : 
     660           0 :             Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16;
     661           0 :             ydst[2 * i + 1] = Y;
     662             :         }
     663           0 :         ydst += lumStride;
     664           0 :         src  += srcStride;
     665             : 
     666           0 :         if (y+1 == height)
     667           0 :             break;
     668             : 
     669           0 :         for (i = 0; i < chromWidth; i++) {
     670           0 :             unsigned int b = src[6 * i + 0];
     671           0 :             unsigned int g = src[6 * i + 1];
     672           0 :             unsigned int r = src[6 * i + 2];
     673             : 
     674           0 :             unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16;
     675             : 
     676           0 :             ydst[2 * i] = Y;
     677             : 
     678           0 :             b = src[6 * i + 3];
     679           0 :             g = src[6 * i + 4];
     680           0 :             r = src[6 * i + 5];
     681             : 
     682           0 :             Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16;
     683           0 :             ydst[2 * i + 1] = Y;
     684             :         }
     685           0 :         udst += chromStride;
     686           0 :         vdst += chromStride;
     687           0 :         ydst += lumStride;
     688           0 :         src  += srcStride;
     689             :     }
     690           0 : }
     691             : 
     692         128 : static void interleaveBytes_c(const uint8_t *src1, const uint8_t *src2,
     693             :                               uint8_t *dest, int width, int height,
     694             :                               int src1Stride, int src2Stride, int dstStride)
     695             : {
     696             :     int h;
     697             : 
     698       18560 :     for (h = 0; h < height; h++) {
     699             :         int w;
     700     3262464 :         for (w = 0; w < width; w++) {
     701     3244032 :             dest[2 * w + 0] = src1[w];
     702     3244032 :             dest[2 * w + 1] = src2[w];
     703             :         }
     704       18432 :         dest += dstStride;
     705       18432 :         src1 += src1Stride;
     706       18432 :         src2 += src2Stride;
     707             :     }
     708         128 : }
     709             : 
     710         100 : static void deinterleaveBytes_c(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
     711             :                                 int width, int height, int srcStride,
     712             :                                 int dst1Stride, int dst2Stride)
     713             : {
     714             :     int h;
     715             : 
     716       14500 :     for (h = 0; h < height; h++) {
     717             :         int w;
     718     2548800 :         for (w = 0; w < width; w++) {
     719     2534400 :             dst1[w] = src[2 * w + 0];
     720     2534400 :             dst2[w] = src[2 * w + 1];
     721             :         }
     722       14400 :         src  += srcStride;
     723       14400 :         dst1 += dst1Stride;
     724       14400 :         dst2 += dst2Stride;
     725             :     }
     726         100 : }
     727             : 
     728           0 : static inline void vu9_to_vu12_c(const uint8_t *src1, const uint8_t *src2,
     729             :                                  uint8_t *dst1, uint8_t *dst2,
     730             :                                  int width, int height,
     731             :                                  int srcStride1, int srcStride2,
     732             :                                  int dstStride1, int dstStride2)
     733             : {
     734             :     int x, y;
     735           0 :     int w = width  / 2;
     736           0 :     int h = height / 2;
     737             : 
     738           0 :     for (y = 0; y < h; y++) {
     739           0 :         const uint8_t *s1 = src1 + srcStride1 * (y >> 1);
     740           0 :         uint8_t *d        = dst1 + dstStride1 *  y;
     741           0 :         for (x = 0; x < w; x++)
     742           0 :             d[2 * x] = d[2 * x + 1] = s1[x];
     743             :     }
     744           0 :     for (y = 0; y < h; y++) {
     745           0 :         const uint8_t *s2 = src2 + srcStride2 * (y >> 1);
     746           0 :         uint8_t *d        = dst2 + dstStride2 *  y;
     747           0 :         for (x = 0; x < w; x++)
     748           0 :             d[2 * x] = d[2 * x + 1] = s2[x];
     749             :     }
     750           0 : }
     751             : 
     752           0 : static inline void yvu9_to_yuy2_c(const uint8_t *src1, const uint8_t *src2,
     753             :                                   const uint8_t *src3, uint8_t *dst,
     754             :                                   int width, int height,
     755             :                                   int srcStride1, int srcStride2,
     756             :                                   int srcStride3, int dstStride)
     757             : {
     758             :     int x, y;
     759           0 :     int w = width / 2;
     760           0 :     int h = height;
     761             : 
     762           0 :     for (y = 0; y < h; y++) {
     763           0 :         const uint8_t *yp = src1 + srcStride1 *  y;
     764           0 :         const uint8_t *up = src2 + srcStride2 * (y >> 2);
     765           0 :         const uint8_t *vp = src3 + srcStride3 * (y >> 2);
     766           0 :         uint8_t *d        = dst  + dstStride  *  y;
     767           0 :         for (x = 0; x < w; x++) {
     768           0 :             const int x2 = x << 2;
     769           0 :             d[8 * x + 0] = yp[x2];
     770           0 :             d[8 * x + 1] = up[x];
     771           0 :             d[8 * x + 2] = yp[x2 + 1];
     772           0 :             d[8 * x + 3] = vp[x];
     773           0 :             d[8 * x + 4] = yp[x2 + 2];
     774           0 :             d[8 * x + 5] = up[x];
     775           0 :             d[8 * x + 6] = yp[x2 + 3];
     776           0 :             d[8 * x + 7] = vp[x];
     777             :         }
     778             :     }
     779           0 : }
     780             : 
     781           0 : static void extract_even_c(const uint8_t *src, uint8_t *dst, int count)
     782             : {
     783           0 :     dst   +=  count;
     784           0 :     src   +=  count * 2;
     785           0 :     count  = -count;
     786           0 :     while (count < 0) {
     787           0 :         dst[count] = src[2 * count];
     788           0 :         count++;
     789             :     }
     790           0 : }
     791             : 
     792           0 : static void extract_even2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1,
     793             :                             int count)
     794             : {
     795           0 :     dst0  +=  count;
     796           0 :     dst1  +=  count;
     797           0 :     src   +=  count * 4;
     798           0 :     count  = -count;
     799           0 :     while (count < 0) {
     800           0 :         dst0[count] = src[4 * count + 0];
     801           0 :         dst1[count] = src[4 * count + 2];
     802           0 :         count++;
     803             :     }
     804           0 : }
     805             : 
     806           0 : static void extract_even2avg_c(const uint8_t *src0, const uint8_t *src1,
     807             :                                uint8_t *dst0, uint8_t *dst1, int count)
     808             : {
     809           0 :     dst0  +=  count;
     810           0 :     dst1  +=  count;
     811           0 :     src0  +=  count * 4;
     812           0 :     src1  +=  count * 4;
     813           0 :     count  = -count;
     814           0 :     while (count < 0) {
     815           0 :         dst0[count] = (src0[4 * count + 0] + src1[4 * count + 0]) >> 1;
     816           0 :         dst1[count] = (src0[4 * count + 2] + src1[4 * count + 2]) >> 1;
     817           0 :         count++;
     818             :     }
     819           0 : }
     820             : 
     821           0 : static void extract_odd2_c(const uint8_t *src, uint8_t *dst0, uint8_t *dst1,
     822             :                            int count)
     823             : {
     824           0 :     dst0  +=  count;
     825           0 :     dst1  +=  count;
     826           0 :     src   +=  count * 4;
     827           0 :     count  = -count;
     828           0 :     src++;
     829           0 :     while (count < 0) {
     830           0 :         dst0[count] = src[4 * count + 0];
     831           0 :         dst1[count] = src[4 * count + 2];
     832           0 :         count++;
     833             :     }
     834           0 : }
     835             : 
     836           0 : static void extract_odd2avg_c(const uint8_t *src0, const uint8_t *src1,
     837             :                               uint8_t *dst0, uint8_t *dst1, int count)
     838             : {
     839           0 :     dst0  +=  count;
     840           0 :     dst1  +=  count;
     841           0 :     src0  +=  count * 4;
     842           0 :     src1  +=  count * 4;
     843           0 :     count  = -count;
     844           0 :     src0++;
     845           0 :     src1++;
     846           0 :     while (count < 0) {
     847           0 :         dst0[count] = (src0[4 * count + 0] + src1[4 * count + 0]) >> 1;
     848           0 :         dst1[count] = (src0[4 * count + 2] + src1[4 * count + 2]) >> 1;
     849           0 :         count++;
     850             :     }
     851           0 : }
     852             : 
     853           0 : static void yuyvtoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
     854             :                            const uint8_t *src, int width, int height,
     855             :                            int lumStride, int chromStride, int srcStride)
     856             : {
     857             :     int y;
     858           0 :     const int chromWidth = AV_CEIL_RSHIFT(width, 1);
     859             : 
     860           0 :     for (y = 0; y < height; y++) {
     861           0 :         extract_even_c(src, ydst, width);
     862           0 :         if (y & 1) {
     863           0 :             extract_odd2avg_c(src - srcStride, src, udst, vdst, chromWidth);
     864           0 :             udst += chromStride;
     865           0 :             vdst += chromStride;
     866             :         }
     867             : 
     868           0 :         src  += srcStride;
     869           0 :         ydst += lumStride;
     870             :     }
     871           0 : }
     872             : 
     873           0 : static void yuyvtoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
     874             :                            const uint8_t *src, int width, int height,
     875             :                            int lumStride, int chromStride, int srcStride)
     876             : {
     877             :     int y;
     878           0 :     const int chromWidth = AV_CEIL_RSHIFT(width, 1);
     879             : 
     880           0 :     for (y = 0; y < height; y++) {
     881           0 :         extract_even_c(src, ydst, width);
     882           0 :         extract_odd2_c(src, udst, vdst, chromWidth);
     883             : 
     884           0 :         src  += srcStride;
     885           0 :         ydst += lumStride;
     886           0 :         udst += chromStride;
     887           0 :         vdst += chromStride;
     888             :     }
     889           0 : }
     890             : 
     891           0 : static void uyvytoyuv420_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
     892             :                            const uint8_t *src, int width, int height,
     893             :                            int lumStride, int chromStride, int srcStride)
     894             : {
     895             :     int y;
     896           0 :     const int chromWidth = AV_CEIL_RSHIFT(width, 1);
     897             : 
     898           0 :     for (y = 0; y < height; y++) {
     899           0 :         extract_even_c(src + 1, ydst, width);
     900           0 :         if (y & 1) {
     901           0 :             extract_even2avg_c(src - srcStride, src, udst, vdst, chromWidth);
     902           0 :             udst += chromStride;
     903           0 :             vdst += chromStride;
     904             :         }
     905             : 
     906           0 :         src  += srcStride;
     907           0 :         ydst += lumStride;
     908             :     }
     909           0 : }
     910             : 
     911           0 : static void uyvytoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
     912             :                            const uint8_t *src, int width, int height,
     913             :                            int lumStride, int chromStride, int srcStride)
     914             : {
     915             :     int y;
     916           0 :     const int chromWidth = AV_CEIL_RSHIFT(width, 1);
     917             : 
     918           0 :     for (y = 0; y < height; y++) {
     919           0 :         extract_even_c(src + 1, ydst, width);
     920           0 :         extract_even2_c(src, udst, vdst, chromWidth);
     921             : 
     922           0 :         src  += srcStride;
     923           0 :         ydst += lumStride;
     924           0 :         udst += chromStride;
     925           0 :         vdst += chromStride;
     926             :     }
     927           0 : }
     928             : 
     929        2620 : static av_cold void rgb2rgb_init_c(void)
     930             : {
     931        2620 :     rgb15to16          = rgb15to16_c;
     932        2620 :     rgb15tobgr24       = rgb15tobgr24_c;
     933        2620 :     rgb15to32          = rgb15to32_c;
     934        2620 :     rgb16tobgr24       = rgb16tobgr24_c;
     935        2620 :     rgb16to32          = rgb16to32_c;
     936        2620 :     rgb16to15          = rgb16to15_c;
     937        2620 :     rgb24tobgr16       = rgb24tobgr16_c;
     938        2620 :     rgb24tobgr15       = rgb24tobgr15_c;
     939        2620 :     rgb24tobgr32       = rgb24tobgr32_c;
     940        2620 :     rgb32to16          = rgb32to16_c;
     941        2620 :     rgb32to15          = rgb32to15_c;
     942        2620 :     rgb32tobgr24       = rgb32tobgr24_c;
     943        2620 :     rgb24to15          = rgb24to15_c;
     944        2620 :     rgb24to16          = rgb24to16_c;
     945        2620 :     rgb24tobgr24       = rgb24tobgr24_c;
     946             : #if HAVE_BIGENDIAN
     947             :     shuffle_bytes_0321 = shuffle_bytes_2103_c;
     948             :     shuffle_bytes_2103 = shuffle_bytes_0321_c;
     949             : #else
     950        2620 :     shuffle_bytes_0321 = shuffle_bytes_0321_c;
     951        2620 :     shuffle_bytes_2103 = shuffle_bytes_2103_c;
     952             : #endif
     953        2620 :     rgb32tobgr16       = rgb32tobgr16_c;
     954        2620 :     rgb32tobgr15       = rgb32tobgr15_c;
     955        2620 :     yv12toyuy2         = yv12toyuy2_c;
     956        2620 :     yv12touyvy         = yv12touyvy_c;
     957        2620 :     yuv422ptoyuy2      = yuv422ptoyuy2_c;
     958        2620 :     yuv422ptouyvy      = yuv422ptouyvy_c;
     959        2620 :     yuy2toyv12         = yuy2toyv12_c;
     960        2620 :     planar2x           = planar2x_c;
     961        2620 :     ff_rgb24toyv12     = ff_rgb24toyv12_c;
     962        2620 :     interleaveBytes    = interleaveBytes_c;
     963        2620 :     deinterleaveBytes  = deinterleaveBytes_c;
     964        2620 :     vu9_to_vu12        = vu9_to_vu12_c;
     965        2620 :     yvu9_to_yuy2       = yvu9_to_yuy2_c;
     966             : 
     967        2620 :     uyvytoyuv420       = uyvytoyuv420_c;
     968        2620 :     uyvytoyuv422       = uyvytoyuv422_c;
     969        2620 :     yuyvtoyuv420       = yuyvtoyuv420_c;
     970        2620 :     yuyvtoyuv422       = yuyvtoyuv422_c;
     971        2620 : }

Generated by: LCOV version 1.13