Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.  *
  9.  * This file is part of FFmpeg.
  10.  *
  11.  * FFmpeg is free software; you can redistribute it and/or
  12.  * modify it under the terms of the GNU Lesser General Public
  13.  * License as published by the Free Software Foundation; either
  14.  * version 2.1 of the License, or (at your option) any later version.
  15.  *
  16.  * FFmpeg is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19.  * Lesser General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU Lesser General Public
  22.  * License along with FFmpeg; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24.  */
  25.  
  26. #include <inttypes.h>
  27.  
  28. #include "libavutil/attributes.h"
  29. #include "libavutil/bswap.h"
  30. #include "config.h"
  31. #include "rgb2rgb.h"
  32. #include "swscale.h"
  33. #include "swscale_internal.h"
  34.  
  35. void (*rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
  36. void (*rgb32tobgr16)(const uint8_t *src, uint8_t *dst, int src_size);
  37. void (*rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size);
  38. void (*rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size);
  39. void (*rgb24tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
  40. void (*rgb24tobgr16)(const uint8_t *src, uint8_t *dst, int src_size);
  41. void (*rgb24tobgr15)(const uint8_t *src, uint8_t *dst, int src_size);
  42. void (*rgb16tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
  43. void (*rgb15tobgr24)(const uint8_t *src, uint8_t *dst, int src_size);
  44.  
  45. void (*rgb32to16)(const uint8_t *src, uint8_t *dst, int src_size);
  46. void (*rgb32to15)(const uint8_t *src, uint8_t *dst, int src_size);
  47. void (*rgb24to16)(const uint8_t *src, uint8_t *dst, int src_size);
  48. void (*rgb24to15)(const uint8_t *src, uint8_t *dst, int src_size);
  49. void (*rgb16to32)(const uint8_t *src, uint8_t *dst, int src_size);
  50. void (*rgb16to15)(const uint8_t *src, uint8_t *dst, int src_size);
  51. void (*rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size);
  52. void (*rgb15to32)(const uint8_t *src, uint8_t *dst, int src_size);
  53.  
  54. void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size);
  55.  
  56. void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc,
  57.                    const uint8_t *vsrc, uint8_t *dst,
  58.                    int width, int height,
  59.                    int lumStride, int chromStride, int dstStride);
  60. void (*yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc,
  61.                    const uint8_t *vsrc, uint8_t *dst,
  62.                    int width, int height,
  63.                    int lumStride, int chromStride, int dstStride);
  64. void (*yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usrc,
  65.                       const uint8_t *vsrc, uint8_t *dst,
  66.                       int width, int height,
  67.                       int lumStride, int chromStride, int dstStride);
  68. void (*yuv422ptouyvy)(const uint8_t *ysrc, const uint8_t *usrc,
  69.                       const uint8_t *vsrc, uint8_t *dst,
  70.                       int width, int height,
  71.                       int lumStride, int chromStride, int dstStride);
  72. void (*yuy2toyv12)(const uint8_t *src, uint8_t *ydst,
  73.                    uint8_t *udst, uint8_t *vdst,
  74.                    int width, int height,
  75.                    int lumStride, int chromStride, int srcStride);
  76. void (*ff_rgb24toyv12)(const uint8_t *src, uint8_t *ydst,
  77.                        uint8_t *udst, uint8_t *vdst,
  78.                        int width, int height,
  79.                        int lumStride, int chromStride, int srcStride,
  80.                        int32_t *rgb2yuv);
  81. void (*planar2x)(const uint8_t *src, uint8_t *dst, int width, int height,
  82.                  int srcStride, int dstStride);
  83. void (*interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst,
  84.                         int width, int height, int src1Stride,
  85.                         int src2Stride, int dstStride);
  86. void (*vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
  87.                     uint8_t *dst1, uint8_t *dst2,
  88.                     int width, int height,
  89.                     int srcStride1, int srcStride2,
  90.                     int dstStride1, int dstStride2);
  91. void (*yvu9_to_yuy2)(const uint8_t *src1, const uint8_t *src2,
  92.                      const uint8_t *src3, uint8_t *dst,
  93.                      int width, int height,
  94.                      int srcStride1, int srcStride2,
  95.                      int srcStride3, int dstStride);
  96. void (*uyvytoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  97.                      const uint8_t *src, int width, int height,
  98.                      int lumStride, int chromStride, int srcStride);
  99. void (*uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  100.                      const uint8_t *src, int width, int height,
  101.                      int lumStride, int chromStride, int srcStride);
  102. void (*yuyvtoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  103.                      const uint8_t *src, int width, int height,
  104.                      int lumStride, int chromStride, int srcStride);
  105. void (*yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  106.                      const uint8_t *src, int width, int height,
  107.                      int lumStride, int chromStride, int srcStride);
  108.  
  109. #define BY ((int)( 0.098 * (1 << RGB2YUV_SHIFT) + 0.5))
  110. #define BV ((int)(-0.071 * (1 << RGB2YUV_SHIFT) + 0.5))
  111. #define BU ((int)( 0.439 * (1 << RGB2YUV_SHIFT) + 0.5))
  112. #define GY ((int)( 0.504 * (1 << RGB2YUV_SHIFT) + 0.5))
  113. #define GV ((int)(-0.368 * (1 << RGB2YUV_SHIFT) + 0.5))
  114. #define GU ((int)(-0.291 * (1 << RGB2YUV_SHIFT) + 0.5))
  115. #define RY ((int)( 0.257 * (1 << RGB2YUV_SHIFT) + 0.5))
  116. #define RV ((int)( 0.439 * (1 << RGB2YUV_SHIFT) + 0.5))
  117. #define RU ((int)(-0.148 * (1 << RGB2YUV_SHIFT) + 0.5))
  118.  
  119. //plain C versions
  120. #include "rgb2rgb_template.c"
  121.  
  122. /*
  123.  * RGB15->RGB16 original by Strepto/Astral
  124.  * ported to gcc & bugfixed : A'rpi
  125.  * MMXEXT, 3DNOW optimization by Nick Kurshev
  126.  * 32-bit C version, and and&add trick by Michael Niedermayer
  127.  */
  128.  
  129. av_cold void sws_rgb2rgb_init(void)
  130. {
  131.     rgb2rgb_init_c();
  132.     if (ARCH_X86)
  133.         rgb2rgb_init_x86();
  134. }
  135.  
  136. void rgb32to24(const uint8_t *src, uint8_t *dst, int src_size)
  137. {
  138.     int i, num_pixels = src_size >> 2;
  139.  
  140.     for (i = 0; i < num_pixels; i++) {
  141. #if HAVE_BIGENDIAN
  142.         /* RGB32 (= A,B,G,R) -> BGR24 (= B,G,R) */
  143.         dst[3 * i + 0] = src[4 * i + 1];
  144.         dst[3 * i + 1] = src[4 * i + 2];
  145.         dst[3 * i + 2] = src[4 * i + 3];
  146. #else
  147.         dst[3 * i + 0] = src[4 * i + 2];
  148.         dst[3 * i + 1] = src[4 * i + 1];
  149.         dst[3 * i + 2] = src[4 * i + 0];
  150. #endif
  151.     }
  152. }
  153.  
  154. void rgb24to32(const uint8_t *src, uint8_t *dst, int src_size)
  155. {
  156.     int i;
  157.  
  158.     for (i = 0; 3 * i < src_size; i++) {
  159. #if HAVE_BIGENDIAN
  160.         /* RGB24 (= R, G, B) -> BGR32 (= A, R, G, B) */
  161.         dst[4 * i + 0] = 255;
  162.         dst[4 * i + 1] = src[3 * i + 0];
  163.         dst[4 * i + 2] = src[3 * i + 1];
  164.         dst[4 * i + 3] = src[3 * i + 2];
  165. #else
  166.         dst[4 * i + 0] = src[3 * i + 2];
  167.         dst[4 * i + 1] = src[3 * i + 1];
  168.         dst[4 * i + 2] = src[3 * i + 0];
  169.         dst[4 * i + 3] = 255;
  170. #endif
  171.     }
  172. }
  173.  
  174. void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
  175. {
  176.     uint8_t *d          = dst;
  177.     const uint16_t *s   = (const uint16_t *)src;
  178.     const uint16_t *end = s + src_size / 2;
  179.  
  180.     while (s < end) {
  181.         register uint16_t bgr = *s++;
  182. #if HAVE_BIGENDIAN
  183.         *d++ = 255;
  184.         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
  185.         *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
  186.         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  187. #else
  188.         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  189.         *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
  190.         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
  191.         *d++ = 255;
  192. #endif
  193.     }
  194. }
  195.  
  196. void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size)
  197. {
  198.     uint16_t rgb, r, g, b;
  199.     uint16_t *d         = (uint16_t *)dst;
  200.     const uint16_t *s   = (const uint16_t *)src;
  201.     const uint16_t *end = s + src_size / 2;
  202.  
  203.     while (s < end) {
  204.         rgb  = *s++;
  205.         r    = rgb & 0xF00;
  206.         g    = rgb & 0x0F0;
  207.         b    = rgb & 0x00F;
  208.         r    = (r << 3) | ((r & 0x800) >> 1);
  209.         g    = (g << 2) | ((g & 0x080) >> 2);
  210.         b    = (b << 1) | ( b          >> 3);
  211.         *d++ = r | g | b;
  212.     }
  213. }
  214.  
  215. void rgb16to24(const uint8_t *src, uint8_t *dst, int src_size)
  216. {
  217.     uint8_t *d          = dst;
  218.     const uint16_t *s   = (const uint16_t *)src;
  219.     const uint16_t *end = s + src_size / 2;
  220.  
  221.     while (s < end) {
  222.         register uint16_t bgr = *s++;
  223.         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  224.         *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
  225.         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
  226.     }
  227. }
  228.  
  229. void rgb16tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
  230. {
  231.     int i, num_pixels = src_size >> 1;
  232.  
  233.     for (i = 0; i < num_pixels; i++) {
  234.         unsigned rgb         = ((const uint16_t *)src)[i];
  235.         ((uint16_t *)dst)[i] = (rgb >> 11) | (rgb & 0x7E0) | (rgb << 11);
  236.     }
  237. }
  238.  
  239. void rgb16tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
  240. {
  241.     int i, num_pixels = src_size >> 1;
  242.  
  243.     for (i = 0; i < num_pixels; i++) {
  244.         unsigned rgb         = ((const uint16_t *)src)[i];
  245.         ((uint16_t *)dst)[i] = (rgb >> 11) | ((rgb & 0x7C0) >> 1) | ((rgb & 0x1F) << 10);
  246.     }
  247. }
  248.  
  249. void rgb15tobgr32(const uint8_t *src, uint8_t *dst, int src_size)
  250. {
  251.     uint8_t *d          = dst;
  252.     const uint16_t *s   = (const uint16_t *)src;
  253.     const uint16_t *end = s + src_size / 2;
  254.  
  255.     while (s < end) {
  256.         register uint16_t bgr = *s++;
  257. #if HAVE_BIGENDIAN
  258.         *d++ = 255;
  259.         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
  260.         *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
  261.         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  262. #else
  263.         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  264.         *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
  265.         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
  266.         *d++ = 255;
  267. #endif
  268.     }
  269. }
  270.  
  271. void rgb15to24(const uint8_t *src, uint8_t *dst, int src_size)
  272. {
  273.     uint8_t *d          = dst;
  274.     const uint16_t *s   = (const uint16_t *)src;
  275.     const uint16_t *end = s + src_size / 2;
  276.  
  277.     while (s < end) {
  278.         register uint16_t bgr = *s++;
  279.         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  280.         *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
  281.         *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
  282.     }
  283. }
  284.  
  285. void rgb15tobgr16(const uint8_t *src, uint8_t *dst, int src_size)
  286. {
  287.     int i, num_pixels = src_size >> 1;
  288.  
  289.     for (i = 0; i < num_pixels; i++) {
  290.         unsigned rgb         = ((const uint16_t *)src)[i];
  291.         ((uint16_t *)dst)[i] = ((rgb & 0x7C00) >> 10) | ((rgb & 0x3E0) << 1) | (rgb << 11);
  292.     }
  293. }
  294.  
  295. void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size)
  296. {
  297.     int i, num_pixels = src_size >> 1;
  298.  
  299.     for (i = 0; i < num_pixels; i++) {
  300.         unsigned rgb         = ((const uint16_t *)src)[i];
  301.         unsigned br          = rgb & 0x7C1F;
  302.         ((uint16_t *)dst)[i] = (br >> 10) | (rgb & 0x3E0) | (br << 10);
  303.     }
  304. }
  305.  
  306. void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size)
  307. {
  308.     uint16_t *d = (uint16_t *)dst;
  309.     uint16_t *s = (uint16_t *)src;
  310.     int i, num_pixels = src_size >> 1;
  311.  
  312.     for (i = 0; i < num_pixels; i++) {
  313.         unsigned rgb = s[i];
  314.         d[i]         = (rgb << 8 | rgb & 0xF0 | rgb >> 8) & 0xFFF;
  315.     }
  316. }
  317.  
  318.  
  319. #define DEFINE_SHUFFLE_BYTES(a, b, c, d)                                \
  320. void shuffle_bytes_ ## a ## b ## c ## d(const uint8_t *src,             \
  321.                                         uint8_t *dst, int src_size)     \
  322. {                                                                       \
  323.     int i;                                                              \
  324.                                                                         \
  325.     for (i = 0; i < src_size; i += 4) {                                 \
  326.         dst[i + 0] = src[i + a];                                        \
  327.         dst[i + 1] = src[i + b];                                        \
  328.         dst[i + 2] = src[i + c];                                        \
  329.         dst[i + 3] = src[i + d];                                        \
  330.     }                                                                   \
  331. }
  332.  
  333. DEFINE_SHUFFLE_BYTES(0, 3, 2, 1)
  334. DEFINE_SHUFFLE_BYTES(1, 2, 3, 0)
  335. DEFINE_SHUFFLE_BYTES(3, 0, 1, 2)
  336. DEFINE_SHUFFLE_BYTES(3, 2, 1, 0)
  337.  
  338. #define DEFINE_RGB48TOBGR48(need_bswap, swap)                           \
  339. void rgb48tobgr48_ ## need_bswap(const uint8_t *src,                    \
  340.                                  uint8_t *dst, int src_size)            \
  341. {                                                                       \
  342.     uint16_t *d = (uint16_t *)dst;                                      \
  343.     uint16_t *s = (uint16_t *)src;                                      \
  344.     int i, num_pixels = src_size >> 1;                                  \
  345.                                                                         \
  346.     for (i = 0; i < num_pixels; i += 3) {                               \
  347.         d[i    ] = swap ? av_bswap16(s[i + 2]) : s[i + 2];              \
  348.         d[i + 1] = swap ? av_bswap16(s[i + 1]) : s[i + 1];              \
  349.         d[i + 2] = swap ? av_bswap16(s[i    ]) : s[i    ];              \
  350.     }                                                                   \
  351. }
  352.  
  353. DEFINE_RGB48TOBGR48(nobswap, 0)
  354. DEFINE_RGB48TOBGR48(bswap, 1)
  355.  
  356. #define DEFINE_RGB64TOBGR48(need_bswap, swap)                           \
  357. void rgb64tobgr48_ ## need_bswap(const uint8_t *src,                    \
  358.                                  uint8_t *dst, int src_size)            \
  359. {                                                                       \
  360.     uint16_t *d = (uint16_t *)dst;                                      \
  361.     uint16_t *s = (uint16_t *)src;                                      \
  362.     int i, num_pixels = src_size >> 3;                                  \
  363.                                                                         \
  364.     for (i = 0; i < num_pixels; i++) {                                  \
  365.         d[3 * i    ] = swap ? av_bswap16(s[4 * i + 2]) : s[4 * i + 2];  \
  366.         d[3 * i + 1] = swap ? av_bswap16(s[4 * i + 1]) : s[4 * i + 1];  \
  367.         d[3 * i + 2] = swap ? av_bswap16(s[4 * i    ]) : s[4 * i    ];  \
  368.     }                                                                   \
  369. }
  370.  
  371. DEFINE_RGB64TOBGR48(nobswap, 0)
  372. DEFINE_RGB64TOBGR48(bswap, 1)
  373.  
  374. #define DEFINE_RGB64TO48(need_bswap, swap)                              \
  375. void rgb64to48_ ## need_bswap(const uint8_t *src,                       \
  376.                               uint8_t *dst, int src_size)               \
  377. {                                                                       \
  378.     uint16_t *d = (uint16_t *)dst;                                      \
  379.     uint16_t *s = (uint16_t *)src;                                      \
  380.     int i, num_pixels = src_size >> 3;                                  \
  381.                                                                         \
  382.     for (i = 0; i < num_pixels; i++) {                                  \
  383.         d[3 * i    ] = swap ? av_bswap16(s[4 * i    ]) : s[4 * i    ];  \
  384.         d[3 * i + 1] = swap ? av_bswap16(s[4 * i + 1]) : s[4 * i + 1];  \
  385.         d[3 * i + 2] = swap ? av_bswap16(s[4 * i + 2]) : s[4 * i + 2];  \
  386.     }                                                                   \
  387. }
  388.  
  389. DEFINE_RGB64TO48(nobswap, 0)
  390. DEFINE_RGB64TO48(bswap, 1)
  391.