Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (C) 2001-2012 Michael Niedermayer <michaelni@gmx.at>
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. #include <math.h>
  22. #include <stdint.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25.  
  26. #include "libavutil/attributes.h"
  27. #include "libavutil/avutil.h"
  28. #include "libavutil/avassert.h"
  29. #include "libavutil/bswap.h"
  30. #include "libavutil/cpu.h"
  31. #include "libavutil/intreadwrite.h"
  32. #include "libavutil/mathematics.h"
  33. #include "libavutil/pixdesc.h"
  34. #include "config.h"
  35. #include "rgb2rgb.h"
  36. #include "swscale.h"
  37. #include "swscale_internal.h"
  38.  
  39. DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_4)[][8] = {
  40. {  1,   3,   1,   3,   1,   3,   1,   3, },
  41. {  2,   0,   2,   0,   2,   0,   2,   0, },
  42. {  1,   3,   1,   3,   1,   3,   1,   3, },
  43. };
  44.  
  45. DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_8)[][8] = {
  46. {  6,   2,   6,   2,   6,   2,   6,   2, },
  47. {  0,   4,   0,   4,   0,   4,   0,   4, },
  48. {  6,   2,   6,   2,   6,   2,   6,   2, },
  49. };
  50.  
  51. DECLARE_ALIGNED(8, const uint8_t, ff_dither_4x4_16)[][8] = {
  52. {  8,   4,  11,   7,   8,   4,  11,   7, },
  53. {  2,  14,   1,  13,   2,  14,   1,  13, },
  54. { 10,   6,   9,   5,  10,   6,   9,   5, },
  55. {  0,  12,   3,  15,   0,  12,   3,  15, },
  56. {  8,   4,  11,   7,   8,   4,  11,   7, },
  57. };
  58.  
  59. DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_32)[][8] = {
  60. { 17,   9,  23,  15,  16,   8,  22,  14, },
  61. {  5,  29,   3,  27,   4,  28,   2,  26, },
  62. { 21,  13,  19,  11,  20,  12,  18,  10, },
  63. {  0,  24,   6,  30,   1,  25,   7,  31, },
  64. { 16,   8,  22,  14,  17,   9,  23,  15, },
  65. {  4,  28,   2,  26,   5,  29,   3,  27, },
  66. { 20,  12,  18,  10,  21,  13,  19,  11, },
  67. {  1,  25,   7,  31,   0,  24,   6,  30, },
  68. { 17,   9,  23,  15,  16,   8,  22,  14, },
  69. };
  70.  
  71. DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_73)[][8] = {
  72. {  0,  55,  14,  68,   3,  58,  17,  72, },
  73. { 37,  18,  50,  32,  40,  22,  54,  35, },
  74. {  9,  64,   5,  59,  13,  67,   8,  63, },
  75. { 46,  27,  41,  23,  49,  31,  44,  26, },
  76. {  2,  57,  16,  71,   1,  56,  15,  70, },
  77. { 39,  21,  52,  34,  38,  19,  51,  33, },
  78. { 11,  66,   7,  62,  10,  65,   6,  60, },
  79. { 48,  30,  43,  25,  47,  29,  42,  24, },
  80. {  0,  55,  14,  68,   3,  58,  17,  72, },
  81. };
  82.  
  83. #if 1
  84. DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
  85. {117,  62, 158, 103, 113,  58, 155, 100, },
  86. { 34, 199,  21, 186,  31, 196,  17, 182, },
  87. {144,  89, 131,  76, 141,  86, 127,  72, },
  88. {  0, 165,  41, 206,  10, 175,  52, 217, },
  89. {110,  55, 151,  96, 120,  65, 162, 107, },
  90. { 28, 193,  14, 179,  38, 203,  24, 189, },
  91. {138,  83, 124,  69, 148,  93, 134,  79, },
  92. {  7, 172,  48, 213,   3, 168,  45, 210, },
  93. {117,  62, 158, 103, 113,  58, 155, 100, },
  94. };
  95. #elif 1
  96. // tries to correct a gamma of 1.5
  97. DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
  98. {  0, 143,  18, 200,   2, 156,  25, 215, },
  99. { 78,  28, 125,  64,  89,  36, 138,  74, },
  100. { 10, 180,   3, 161,  16, 195,   8, 175, },
  101. {109,  51,  93,  38, 121,  60, 105,  47, },
  102. {  1, 152,  23, 210,   0, 147,  20, 205, },
  103. { 85,  33, 134,  71,  81,  30, 130,  67, },
  104. { 14, 190,   6, 171,  12, 185,   5, 166, },
  105. {117,  57, 101,  44, 113,  54,  97,  41, },
  106. {  0, 143,  18, 200,   2, 156,  25, 215, },
  107. };
  108. #elif 1
  109. // tries to correct a gamma of 2.0
  110. DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
  111. {  0, 124,   8, 193,   0, 140,  12, 213, },
  112. { 55,  14, 104,  42,  66,  19, 119,  52, },
  113. {  3, 168,   1, 145,   6, 187,   3, 162, },
  114. { 86,  31,  70,  21,  99,  39,  82,  28, },
  115. {  0, 134,  11, 206,   0, 129,   9, 200, },
  116. { 62,  17, 114,  48,  58,  16, 109,  45, },
  117. {  5, 181,   2, 157,   4, 175,   1, 151, },
  118. { 95,  36,  78,  26,  90,  34,  74,  24, },
  119. {  0, 124,   8, 193,   0, 140,  12, 213, },
  120. };
  121. #else
  122. // tries to correct a gamma of 2.5
  123. DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[][8] = {
  124. {  0, 107,   3, 187,   0, 125,   6, 212, },
  125. { 39,   7,  86,  28,  49,  11, 102,  36, },
  126. {  1, 158,   0, 131,   3, 180,   1, 151, },
  127. { 68,  19,  52,  12,  81,  25,  64,  17, },
  128. {  0, 119,   5, 203,   0, 113,   4, 195, },
  129. { 45,   9,  96,  33,  42,   8,  91,  30, },
  130. {  2, 172,   1, 144,   2, 165,   0, 137, },
  131. { 77,  23,  60,  15,  72,  21,  56,  14, },
  132. {  0, 107,   3, 187,   0, 125,   6, 212, },
  133. };
  134. #endif
  135.  
  136. #define output_pixel(pos, val, bias, signedness) \
  137.     if (big_endian) { \
  138.         AV_WB16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
  139.     } else { \
  140.         AV_WL16(pos, bias + av_clip_ ## signedness ## 16(val >> shift)); \
  141.     }
  142.  
  143. static av_always_inline void
  144. yuv2plane1_16_c_template(const int32_t *src, uint16_t *dest, int dstW,
  145.                          int big_endian, int output_bits)
  146. {
  147.     int i;
  148.     int shift = 3;
  149.     av_assert0(output_bits == 16);
  150.  
  151.     for (i = 0; i < dstW; i++) {
  152.         int val = src[i] + (1 << (shift - 1));
  153.         output_pixel(&dest[i], val, 0, uint);
  154.     }
  155. }
  156.  
  157. static av_always_inline void
  158. yuv2planeX_16_c_template(const int16_t *filter, int filterSize,
  159.                          const int32_t **src, uint16_t *dest, int dstW,
  160.                          int big_endian, int output_bits)
  161. {
  162.     int i;
  163.     int shift = 15;
  164.     av_assert0(output_bits == 16);
  165.  
  166.     for (i = 0; i < dstW; i++) {
  167.         int val = 1 << (shift - 1);
  168.         int j;
  169.  
  170.         /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline
  171.          * filters (or anything with negative coeffs, the range can be slightly
  172.          * wider in both directions. To account for this overflow, we subtract
  173.          * a constant so it always fits in the signed range (assuming a
  174.          * reasonable filterSize), and re-add that at the end. */
  175.         val -= 0x40000000;
  176.         for (j = 0; j < filterSize; j++)
  177.             val += src[j][i] * (unsigned)filter[j];
  178.  
  179.         output_pixel(&dest[i], val, 0x8000, int);
  180.     }
  181. }
  182.  
  183. #undef output_pixel
  184.  
  185. #define output_pixel(pos, val) \
  186.     if (big_endian) { \
  187.         AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
  188.     } else { \
  189.         AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
  190.     }
  191.  
  192. static av_always_inline void
  193. yuv2plane1_10_c_template(const int16_t *src, uint16_t *dest, int dstW,
  194.                          int big_endian, int output_bits)
  195. {
  196.     int i;
  197.     int shift = 15 - output_bits;
  198.  
  199.     for (i = 0; i < dstW; i++) {
  200.         int val = src[i] + (1 << (shift - 1));
  201.         output_pixel(&dest[i], val);
  202.     }
  203. }
  204.  
  205. static av_always_inline void
  206. yuv2planeX_10_c_template(const int16_t *filter, int filterSize,
  207.                          const int16_t **src, uint16_t *dest, int dstW,
  208.                          int big_endian, int output_bits)
  209. {
  210.     int i;
  211.     int shift = 11 + 16 - output_bits;
  212.  
  213.     for (i = 0; i < dstW; i++) {
  214.         int val = 1 << (shift - 1);
  215.         int j;
  216.  
  217.         for (j = 0; j < filterSize; j++)
  218.             val += src[j][i] * filter[j];
  219.  
  220.         output_pixel(&dest[i], val);
  221.     }
  222. }
  223.  
  224. #undef output_pixel
  225.  
  226. #define yuv2NBPS(bits, BE_LE, is_be, template_size, typeX_t) \
  227. static void yuv2plane1_ ## bits ## BE_LE ## _c(const int16_t *src, \
  228.                               uint8_t *dest, int dstW, \
  229.                               const uint8_t *dither, int offset)\
  230. { \
  231.     yuv2plane1_ ## template_size ## _c_template((const typeX_t *) src, \
  232.                          (uint16_t *) dest, dstW, is_be, bits); \
  233. }\
  234. static void yuv2planeX_ ## bits ## BE_LE ## _c(const int16_t *filter, int filterSize, \
  235.                               const int16_t **src, uint8_t *dest, int dstW, \
  236.                               const uint8_t *dither, int offset)\
  237. { \
  238.     yuv2planeX_## template_size ## _c_template(filter, \
  239.                          filterSize, (const typeX_t **) src, \
  240.                          (uint16_t *) dest, dstW, is_be, bits); \
  241. }
  242. yuv2NBPS( 9, BE, 1, 10, int16_t)
  243. yuv2NBPS( 9, LE, 0, 10, int16_t)
  244. yuv2NBPS(10, BE, 1, 10, int16_t)
  245. yuv2NBPS(10, LE, 0, 10, int16_t)
  246. yuv2NBPS(12, BE, 1, 10, int16_t)
  247. yuv2NBPS(12, LE, 0, 10, int16_t)
  248. yuv2NBPS(14, BE, 1, 10, int16_t)
  249. yuv2NBPS(14, LE, 0, 10, int16_t)
  250. yuv2NBPS(16, BE, 1, 16, int32_t)
  251. yuv2NBPS(16, LE, 0, 16, int32_t)
  252.  
  253. static void yuv2planeX_8_c(const int16_t *filter, int filterSize,
  254.                            const int16_t **src, uint8_t *dest, int dstW,
  255.                            const uint8_t *dither, int offset)
  256. {
  257.     int i;
  258.     for (i=0; i<dstW; i++) {
  259.         int val = dither[(i + offset) & 7] << 12;
  260.         int j;
  261.         for (j=0; j<filterSize; j++)
  262.             val += src[j][i] * filter[j];
  263.  
  264.         dest[i]= av_clip_uint8(val>>19);
  265.     }
  266. }
  267.  
  268. static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW,
  269.                            const uint8_t *dither, int offset)
  270. {
  271.     int i;
  272.     for (i=0; i<dstW; i++) {
  273.         int val = (src[i] + dither[(i + offset) & 7]) >> 7;
  274.         dest[i]= av_clip_uint8(val);
  275.     }
  276. }
  277.  
  278. static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
  279.                         const int16_t **chrUSrc, const int16_t **chrVSrc,
  280.                         uint8_t *dest, int chrDstW)
  281. {
  282.     enum AVPixelFormat dstFormat = c->dstFormat;
  283.     const uint8_t *chrDither = c->chrDither8;
  284.     int i;
  285.  
  286.     if (dstFormat == AV_PIX_FMT_NV12)
  287.         for (i=0; i<chrDstW; i++) {
  288.             int u = chrDither[i & 7] << 12;
  289.             int v = chrDither[(i + 3) & 7] << 12;
  290.             int j;
  291.             for (j=0; j<chrFilterSize; j++) {
  292.                 u += chrUSrc[j][i] * chrFilter[j];
  293.                 v += chrVSrc[j][i] * chrFilter[j];
  294.             }
  295.  
  296.             dest[2*i]= av_clip_uint8(u>>19);
  297.             dest[2*i+1]= av_clip_uint8(v>>19);
  298.         }
  299.     else
  300.         for (i=0; i<chrDstW; i++) {
  301.             int u = chrDither[i & 7] << 12;
  302.             int v = chrDither[(i + 3) & 7] << 12;
  303.             int j;
  304.             for (j=0; j<chrFilterSize; j++) {
  305.                 u += chrUSrc[j][i] * chrFilter[j];
  306.                 v += chrVSrc[j][i] * chrFilter[j];
  307.             }
  308.  
  309.             dest[2*i]= av_clip_uint8(v>>19);
  310.             dest[2*i+1]= av_clip_uint8(u>>19);
  311.         }
  312. }
  313.  
  314. #define accumulate_bit(acc, val) \
  315.     acc <<= 1; \
  316.     acc |= (val) >= (128 + 110)
  317. #define output_pixel(pos, acc) \
  318.     if (target == AV_PIX_FMT_MONOBLACK) { \
  319.         pos = acc; \
  320.     } else { \
  321.         pos = ~acc; \
  322.     }
  323.  
  324. static av_always_inline void
  325. yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
  326.                       const int16_t **lumSrc, int lumFilterSize,
  327.                       const int16_t *chrFilter, const int16_t **chrUSrc,
  328.                       const int16_t **chrVSrc, int chrFilterSize,
  329.                       const int16_t **alpSrc, uint8_t *dest, int dstW,
  330.                       int y, enum AVPixelFormat target)
  331. {
  332.     const uint8_t * const d128 = ff_dither_8x8_220[y&7];
  333.     int i;
  334.     unsigned acc = 0;
  335.     int err = 0;
  336.  
  337.     for (i = 0; i < dstW; i += 2) {
  338.         int j;
  339.         int Y1 = 1 << 18;
  340.         int Y2 = 1 << 18;
  341.  
  342.         for (j = 0; j < lumFilterSize; j++) {
  343.             Y1 += lumSrc[j][i]   * lumFilter[j];
  344.             Y2 += lumSrc[j][i+1] * lumFilter[j];
  345.         }
  346.         Y1 >>= 19;
  347.         Y2 >>= 19;
  348.         if ((Y1 | Y2) & 0x100) {
  349.             Y1 = av_clip_uint8(Y1);
  350.             Y2 = av_clip_uint8(Y2);
  351.         }
  352.         if (c->dither == SWS_DITHER_ED) {
  353.             Y1 += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
  354.             c->dither_error[0][i] = err;
  355.             acc = 2*acc + (Y1 >= 128);
  356.             Y1 -= 220*(acc&1);
  357.  
  358.             err = Y2 + ((7*Y1 + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4);
  359.             c->dither_error[0][i+1] = Y1;
  360.             acc = 2*acc + (err >= 128);
  361.             err -= 220*(acc&1);
  362.         } else {
  363.             accumulate_bit(acc, Y1 + d128[(i + 0) & 7]);
  364.             accumulate_bit(acc, Y2 + d128[(i + 1) & 7]);
  365.         }
  366.         if ((i & 7) == 6) {
  367.             output_pixel(*dest++, acc);
  368.         }
  369.     }
  370.     c->dither_error[0][i] = err;
  371.  
  372.     if (i & 6) {
  373.         output_pixel(*dest, acc);
  374.     }
  375. }
  376.  
  377. static av_always_inline void
  378. yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
  379.                       const int16_t *ubuf[2], const int16_t *vbuf[2],
  380.                       const int16_t *abuf[2], uint8_t *dest, int dstW,
  381.                       int yalpha, int uvalpha, int y,
  382.                       enum AVPixelFormat target)
  383. {
  384.     const int16_t *buf0  = buf[0],  *buf1  = buf[1];
  385.     const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
  386.     int  yalpha1 = 4096 - yalpha;
  387.     int i;
  388.  
  389.     if (c->dither == SWS_DITHER_ED) {
  390.         int err = 0;
  391.         int acc = 0;
  392.         for (i = 0; i < dstW; i +=2) {
  393.             int Y;
  394.  
  395.             Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19;
  396.             Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
  397.             c->dither_error[0][i] = err;
  398.             acc = 2*acc + (Y >= 128);
  399.             Y -= 220*(acc&1);
  400.  
  401.             err = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19;
  402.             err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
  403.             c->dither_error[0][i+1] = Y;
  404.             acc = 2*acc + (err >= 128);
  405.             err -= 220*(acc&1);
  406.  
  407.             if ((i & 7) == 6)
  408.                 output_pixel(*dest++, acc);
  409.         }
  410.         c->dither_error[0][i] = err;
  411.     } else {
  412.     for (i = 0; i < dstW; i += 8) {
  413.         int Y, acc = 0;
  414.  
  415.         Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19;
  416.         accumulate_bit(acc, Y + d128[0]);
  417.         Y = (buf0[i + 1] * yalpha1 + buf1[i + 1] * yalpha) >> 19;
  418.         accumulate_bit(acc, Y + d128[1]);
  419.         Y = (buf0[i + 2] * yalpha1 + buf1[i + 2] * yalpha) >> 19;
  420.         accumulate_bit(acc, Y + d128[2]);
  421.         Y = (buf0[i + 3] * yalpha1 + buf1[i + 3] * yalpha) >> 19;
  422.         accumulate_bit(acc, Y + d128[3]);
  423.         Y = (buf0[i + 4] * yalpha1 + buf1[i + 4] * yalpha) >> 19;
  424.         accumulate_bit(acc, Y + d128[4]);
  425.         Y = (buf0[i + 5] * yalpha1 + buf1[i + 5] * yalpha) >> 19;
  426.         accumulate_bit(acc, Y + d128[5]);
  427.         Y = (buf0[i + 6] * yalpha1 + buf1[i + 6] * yalpha) >> 19;
  428.         accumulate_bit(acc, Y + d128[6]);
  429.         Y = (buf0[i + 7] * yalpha1 + buf1[i + 7] * yalpha) >> 19;
  430.         accumulate_bit(acc, Y + d128[7]);
  431.  
  432.         output_pixel(*dest++, acc);
  433.     }
  434.     }
  435. }
  436.  
  437. static av_always_inline void
  438. yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
  439.                       const int16_t *ubuf[2], const int16_t *vbuf[2],
  440.                       const int16_t *abuf0, uint8_t *dest, int dstW,
  441.                       int uvalpha, int y, enum AVPixelFormat target)
  442. {
  443.     const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
  444.     int i;
  445.  
  446.     if (c->dither == SWS_DITHER_ED) {
  447.         int err = 0;
  448.         int acc = 0;
  449.         for (i = 0; i < dstW; i +=2) {
  450.             int Y;
  451.  
  452.             Y = ((buf0[i + 0] + 64) >> 7);
  453.             Y += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
  454.             c->dither_error[0][i] = err;
  455.             acc = 2*acc + (Y >= 128);
  456.             Y -= 220*(acc&1);
  457.  
  458.             err = ((buf0[i + 1] + 64) >> 7);
  459.             err += (7*Y + 1*c->dither_error[0][i+1] + 5*c->dither_error[0][i+2] + 3*c->dither_error[0][i+3] + 8 - 256)>>4;
  460.             c->dither_error[0][i+1] = Y;
  461.             acc = 2*acc + (err >= 128);
  462.             err -= 220*(acc&1);
  463.  
  464.             if ((i & 7) == 6)
  465.                 output_pixel(*dest++, acc);
  466.         }
  467.         c->dither_error[0][i] = err;
  468.     } else {
  469.     for (i = 0; i < dstW; i += 8) {
  470.         int acc = 0;
  471.         accumulate_bit(acc, ((buf0[i + 0] + 64) >> 7) + d128[0]);
  472.         accumulate_bit(acc, ((buf0[i + 1] + 64) >> 7) + d128[1]);
  473.         accumulate_bit(acc, ((buf0[i + 2] + 64) >> 7) + d128[2]);
  474.         accumulate_bit(acc, ((buf0[i + 3] + 64) >> 7) + d128[3]);
  475.         accumulate_bit(acc, ((buf0[i + 4] + 64) >> 7) + d128[4]);
  476.         accumulate_bit(acc, ((buf0[i + 5] + 64) >> 7) + d128[5]);
  477.         accumulate_bit(acc, ((buf0[i + 6] + 64) >> 7) + d128[6]);
  478.         accumulate_bit(acc, ((buf0[i + 7] + 64) >> 7) + d128[7]);
  479.  
  480.         output_pixel(*dest++, acc);
  481.     }
  482.     }
  483. }
  484.  
  485. #undef output_pixel
  486. #undef accumulate_bit
  487.  
  488. #define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
  489. static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
  490.                                 const int16_t **lumSrc, int lumFilterSize, \
  491.                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
  492.                                 const int16_t **chrVSrc, int chrFilterSize, \
  493.                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
  494.                                 int y) \
  495. { \
  496.     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
  497.                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
  498.                                   alpSrc, dest, dstW, y, fmt); \
  499. } \
  500.  \
  501. static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
  502.                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
  503.                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
  504.                                 int yalpha, int uvalpha, int y) \
  505. { \
  506.     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
  507.                                   dest, dstW, yalpha, uvalpha, y, fmt); \
  508. } \
  509.  \
  510. static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
  511.                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
  512.                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
  513.                                 int uvalpha, int y) \
  514. { \
  515.     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, \
  516.                                   abuf0, dest, dstW, uvalpha, \
  517.                                   y, fmt); \
  518. }
  519.  
  520. YUV2PACKEDWRAPPER(yuv2mono,, white, AV_PIX_FMT_MONOWHITE)
  521. YUV2PACKEDWRAPPER(yuv2mono,, black, AV_PIX_FMT_MONOBLACK)
  522.  
  523. #define output_pixels(pos, Y1, U, Y2, V) \
  524.     if (target == AV_PIX_FMT_YUYV422) { \
  525.         dest[pos + 0] = Y1; \
  526.         dest[pos + 1] = U;  \
  527.         dest[pos + 2] = Y2; \
  528.         dest[pos + 3] = V;  \
  529.     } else { \
  530.         dest[pos + 0] = U;  \
  531.         dest[pos + 1] = Y1; \
  532.         dest[pos + 2] = V;  \
  533.         dest[pos + 3] = Y2; \
  534.     }
  535.  
  536. static av_always_inline void
  537. yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
  538.                      const int16_t **lumSrc, int lumFilterSize,
  539.                      const int16_t *chrFilter, const int16_t **chrUSrc,
  540.                      const int16_t **chrVSrc, int chrFilterSize,
  541.                      const int16_t **alpSrc, uint8_t *dest, int dstW,
  542.                      int y, enum AVPixelFormat target)
  543. {
  544.     int i;
  545.  
  546.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  547.         int j;
  548.         int Y1 = 1 << 18;
  549.         int Y2 = 1 << 18;
  550.         int U  = 1 << 18;
  551.         int V  = 1 << 18;
  552.  
  553.         for (j = 0; j < lumFilterSize; j++) {
  554.             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
  555.             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
  556.         }
  557.         for (j = 0; j < chrFilterSize; j++) {
  558.             U += chrUSrc[j][i] * chrFilter[j];
  559.             V += chrVSrc[j][i] * chrFilter[j];
  560.         }
  561.         Y1 >>= 19;
  562.         Y2 >>= 19;
  563.         U  >>= 19;
  564.         V  >>= 19;
  565.         if ((Y1 | Y2 | U | V) & 0x100) {
  566.             Y1 = av_clip_uint8(Y1);
  567.             Y2 = av_clip_uint8(Y2);
  568.             U  = av_clip_uint8(U);
  569.             V  = av_clip_uint8(V);
  570.         }
  571.         output_pixels(4*i, Y1, U, Y2, V);
  572.     }
  573. }
  574.  
  575. static av_always_inline void
  576. yuv2422_2_c_template(SwsContext *c, const int16_t *buf[2],
  577.                      const int16_t *ubuf[2], const int16_t *vbuf[2],
  578.                      const int16_t *abuf[2], uint8_t *dest, int dstW,
  579.                      int yalpha, int uvalpha, int y,
  580.                      enum AVPixelFormat target)
  581. {
  582.     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
  583.                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
  584.                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
  585.     int  yalpha1 = 4096 - yalpha;
  586.     int uvalpha1 = 4096 - uvalpha;
  587.     int i;
  588.  
  589.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  590.         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
  591.         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
  592.         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
  593.         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
  594.  
  595.         if ((Y1 | Y2 | U | V) & 0x100) {
  596.             Y1 = av_clip_uint8(Y1);
  597.             Y2 = av_clip_uint8(Y2);
  598.             U  = av_clip_uint8(U);
  599.             V  = av_clip_uint8(V);
  600.         }
  601.  
  602.         output_pixels(i * 4, Y1, U, Y2, V);
  603.     }
  604. }
  605.  
  606. static av_always_inline void
  607. yuv2422_1_c_template(SwsContext *c, const int16_t *buf0,
  608.                      const int16_t *ubuf[2], const int16_t *vbuf[2],
  609.                      const int16_t *abuf0, uint8_t *dest, int dstW,
  610.                      int uvalpha, int y, enum AVPixelFormat target)
  611. {
  612.     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
  613.     int i;
  614.  
  615.     if (uvalpha < 2048) {
  616.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  617.             int Y1 = (buf0[i * 2    ]+64) >> 7;
  618.             int Y2 = (buf0[i * 2 + 1]+64) >> 7;
  619.             int U  = (ubuf0[i]       +64) >> 7;
  620.             int V  = (vbuf0[i]       +64) >> 7;
  621.  
  622.             if ((Y1 | Y2 | U | V) & 0x100) {
  623.                 Y1 = av_clip_uint8(Y1);
  624.                 Y2 = av_clip_uint8(Y2);
  625.                 U  = av_clip_uint8(U);
  626.                 V  = av_clip_uint8(V);
  627.             }
  628.  
  629.             Y1 = av_clip_uint8(Y1);
  630.             Y2 = av_clip_uint8(Y2);
  631.             U  = av_clip_uint8(U);
  632.             V  = av_clip_uint8(V);
  633.  
  634.             output_pixels(i * 4, Y1, U, Y2, V);
  635.         }
  636.     } else {
  637.         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
  638.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  639.             int Y1 = (buf0[i * 2    ]    + 64) >> 7;
  640.             int Y2 = (buf0[i * 2 + 1]    + 64) >> 7;
  641.             int U  = (ubuf0[i] + ubuf1[i]+128) >> 8;
  642.             int V  = (vbuf0[i] + vbuf1[i]+128) >> 8;
  643.  
  644.             if ((Y1 | Y2 | U | V) & 0x100) {
  645.                 Y1 = av_clip_uint8(Y1);
  646.                 Y2 = av_clip_uint8(Y2);
  647.                 U  = av_clip_uint8(U);
  648.                 V  = av_clip_uint8(V);
  649.             }
  650.  
  651.             Y1 = av_clip_uint8(Y1);
  652.             Y2 = av_clip_uint8(Y2);
  653.             U  = av_clip_uint8(U);
  654.             V  = av_clip_uint8(V);
  655.  
  656.             output_pixels(i * 4, Y1, U, Y2, V);
  657.         }
  658.     }
  659. }
  660.  
  661. #undef output_pixels
  662.  
  663. YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, AV_PIX_FMT_YUYV422)
  664. YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, AV_PIX_FMT_UYVY422)
  665.  
  666. #define R_B ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE) ? R : B)
  667. #define B_R ((target == AV_PIX_FMT_RGB48LE || target == AV_PIX_FMT_RGB48BE) ? B : R)
  668. #define output_pixel(pos, val) \
  669.     if (isBE(target)) { \
  670.         AV_WB16(pos, val); \
  671.     } else { \
  672.         AV_WL16(pos, val); \
  673.     }
  674.  
  675. static av_always_inline void
  676. yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter,
  677.                        const int32_t **lumSrc, int lumFilterSize,
  678.                        const int16_t *chrFilter, const int32_t **chrUSrc,
  679.                        const int32_t **chrVSrc, int chrFilterSize,
  680.                        const int32_t **alpSrc, uint16_t *dest, int dstW,
  681.                        int y, enum AVPixelFormat target, int hasAlpha)
  682. {
  683.     int i;
  684.     int A1 = 0xffff<<14, A2 = 0xffff<<14;
  685.  
  686.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  687.         int j;
  688.         int Y1 = -0x40000000;
  689.         int Y2 = -0x40000000;
  690.         int U  = -128 << 23; // 19
  691.         int V  = -128 << 23;
  692.         int R, G, B;
  693.  
  694.         for (j = 0; j < lumFilterSize; j++) {
  695.             Y1 += lumSrc[j][i * 2]     * (unsigned)lumFilter[j];
  696.             Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
  697.         }
  698.         for (j = 0; j < chrFilterSize; j++) {;
  699.             U += chrUSrc[j][i] * (unsigned)chrFilter[j];
  700.             V += chrVSrc[j][i] * (unsigned)chrFilter[j];
  701.         }
  702.  
  703.         if (hasAlpha) {
  704.             A1 = -0x40000000;
  705.             A2 = -0x40000000;
  706.             for (j = 0; j < lumFilterSize; j++) {
  707.                 A1 += alpSrc[j][i * 2]     * (unsigned)lumFilter[j];
  708.                 A2 += alpSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
  709.             }
  710.             A1 >>= 1;
  711.             A1 += 0x20002000;
  712.             A2 >>= 1;
  713.             A2 += 0x20002000;
  714.         }
  715.  
  716.         // 8bit: 12+15=27; 16-bit: 12+19=31
  717.         Y1 >>= 14; // 10
  718.         Y1 += 0x10000;
  719.         Y2 >>= 14;
  720.         Y2 += 0x10000;
  721.         U  >>= 14;
  722.         V  >>= 14;
  723.  
  724.         // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
  725.         Y1 -= c->yuv2rgb_y_offset;
  726.         Y2 -= c->yuv2rgb_y_offset;
  727.         Y1 *= c->yuv2rgb_y_coeff;
  728.         Y2 *= c->yuv2rgb_y_coeff;
  729.         Y1 += 1 << 13; // 21
  730.         Y2 += 1 << 13;
  731.         // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
  732.  
  733.         R = V * c->yuv2rgb_v2r_coeff;
  734.         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  735.         B =                            U * c->yuv2rgb_u2b_coeff;
  736.  
  737.         // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
  738.         output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
  739.         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  740.         output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
  741.         output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
  742.         output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
  743.         output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
  744.         output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
  745.         output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
  746.         dest += 8;
  747.     }
  748. }
  749.  
  750. static av_always_inline void
  751. yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2],
  752.                        const int32_t *ubuf[2], const int32_t *vbuf[2],
  753.                        const int32_t *abuf[2], uint16_t *dest, int dstW,
  754.                        int yalpha, int uvalpha, int y,
  755.                        enum AVPixelFormat target, int hasAlpha)
  756. {
  757.     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
  758.                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
  759.                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
  760.                   *abuf0 = hasAlpha ? abuf[0] : NULL,
  761.                   *abuf1 = hasAlpha ? abuf[1] : NULL;
  762.     int  yalpha1 = 4096 - yalpha;
  763.     int uvalpha1 = 4096 - uvalpha;
  764.     int i;
  765.     int A1 = 0xffff<<14, A2 = 0xffff<<14;
  766.  
  767.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  768.         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;
  769.         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;
  770.         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;
  771.         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;
  772.         int R, G, B;
  773.  
  774.         Y1 -= c->yuv2rgb_y_offset;
  775.         Y2 -= c->yuv2rgb_y_offset;
  776.         Y1 *= c->yuv2rgb_y_coeff;
  777.         Y2 *= c->yuv2rgb_y_coeff;
  778.         Y1 += 1 << 13;
  779.         Y2 += 1 << 13;
  780.  
  781.         R = V * c->yuv2rgb_v2r_coeff;
  782.         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  783.         B =                            U * c->yuv2rgb_u2b_coeff;
  784.  
  785.         if (hasAlpha) {
  786.             A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 1;
  787.             A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 1;
  788.  
  789.             A1 += 1 << 13;
  790.             A2 += 1 << 13;
  791.         }
  792.  
  793.         output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
  794.         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  795.         output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
  796.         output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
  797.         output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
  798.         output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
  799.         output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
  800.         output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
  801.         dest += 8;
  802.     }
  803. }
  804.  
  805. static av_always_inline void
  806. yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0,
  807.                        const int32_t *ubuf[2], const int32_t *vbuf[2],
  808.                        const int32_t *abuf0, uint16_t *dest, int dstW,
  809.                        int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
  810. {
  811.     const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
  812.     int i;
  813.     int A1 = 0xffff<<14, A2= 0xffff<<14;
  814.  
  815.     if (uvalpha < 2048) {
  816.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  817.             int Y1 = (buf0[i * 2]    ) >> 2;
  818.             int Y2 = (buf0[i * 2 + 1]) >> 2;
  819.             int U  = (ubuf0[i] + (-128 << 11)) >> 2;
  820.             int V  = (vbuf0[i] + (-128 << 11)) >> 2;
  821.             int R, G, B;
  822.  
  823.             Y1 -= c->yuv2rgb_y_offset;
  824.             Y2 -= c->yuv2rgb_y_offset;
  825.             Y1 *= c->yuv2rgb_y_coeff;
  826.             Y2 *= c->yuv2rgb_y_coeff;
  827.             Y1 += 1 << 13;
  828.             Y2 += 1 << 13;
  829.  
  830.             if (hasAlpha) {
  831.                 A1 = abuf0[i * 2    ] << 11;
  832.                 A2 = abuf0[i * 2 + 1] << 11;
  833.  
  834.                 A1 += 1 << 13;
  835.                 A2 += 1 << 13;
  836.             }
  837.  
  838.             R = V * c->yuv2rgb_v2r_coeff;
  839.             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  840.             B =                            U * c->yuv2rgb_u2b_coeff;
  841.  
  842.             output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
  843.             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  844.             output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
  845.             output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
  846.             output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
  847.             output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
  848.             output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
  849.             output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
  850.             dest += 8;
  851.         }
  852.     } else {
  853.         const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
  854.         int A1 = 0xffff<<14, A2 = 0xffff<<14;
  855.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  856.             int Y1 = (buf0[i * 2]    ) >> 2;
  857.             int Y2 = (buf0[i * 2 + 1]) >> 2;
  858.             int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
  859.             int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
  860.             int R, G, B;
  861.  
  862.             Y1 -= c->yuv2rgb_y_offset;
  863.             Y2 -= c->yuv2rgb_y_offset;
  864.             Y1 *= c->yuv2rgb_y_coeff;
  865.             Y2 *= c->yuv2rgb_y_coeff;
  866.             Y1 += 1 << 13;
  867.             Y2 += 1 << 13;
  868.  
  869.             if (hasAlpha) {
  870.                 A1 = abuf0[i * 2    ] << 11;
  871.                 A2 = abuf0[i * 2 + 1] << 11;
  872.  
  873.                 A1 += 1 << 13;
  874.                 A2 += 1 << 13;
  875.             }
  876.  
  877.             R = V * c->yuv2rgb_v2r_coeff;
  878.             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  879.             B =                            U * c->yuv2rgb_u2b_coeff;
  880.  
  881.             output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);
  882.             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  883.             output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);
  884.             output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);
  885.             output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);
  886.             output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);
  887.             output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);
  888.             output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);
  889.             dest += 8;
  890.         }
  891.     }
  892. }
  893.  
  894. static av_always_inline void
  895. yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
  896.                        const int32_t **lumSrc, int lumFilterSize,
  897.                        const int16_t *chrFilter, const int32_t **chrUSrc,
  898.                        const int32_t **chrVSrc, int chrFilterSize,
  899.                        const int32_t **alpSrc, uint16_t *dest, int dstW,
  900.                        int y, enum AVPixelFormat target, int hasAlpha)
  901. {
  902.     int i;
  903.  
  904.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  905.         int j;
  906.         int Y1 = -0x40000000;
  907.         int Y2 = -0x40000000;
  908.         int U  = -128 << 23; // 19
  909.         int V  = -128 << 23;
  910.         int R, G, B;
  911.  
  912.         for (j = 0; j < lumFilterSize; j++) {
  913.             Y1 += lumSrc[j][i * 2]     * (unsigned)lumFilter[j];
  914.             Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
  915.         }
  916.         for (j = 0; j < chrFilterSize; j++) {;
  917.             U += chrUSrc[j][i] * (unsigned)chrFilter[j];
  918.             V += chrVSrc[j][i] * (unsigned)chrFilter[j];
  919.         }
  920.  
  921.         // 8bit: 12+15=27; 16-bit: 12+19=31
  922.         Y1 >>= 14; // 10
  923.         Y1 += 0x10000;
  924.         Y2 >>= 14;
  925.         Y2 += 0x10000;
  926.         U  >>= 14;
  927.         V  >>= 14;
  928.  
  929.         // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit
  930.         Y1 -= c->yuv2rgb_y_offset;
  931.         Y2 -= c->yuv2rgb_y_offset;
  932.         Y1 *= c->yuv2rgb_y_coeff;
  933.         Y2 *= c->yuv2rgb_y_coeff;
  934.         Y1 += 1 << 13; // 21
  935.         Y2 += 1 << 13;
  936.         // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit
  937.  
  938.         R = V * c->yuv2rgb_v2r_coeff;
  939.         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  940.         B =                            U * c->yuv2rgb_u2b_coeff;
  941.  
  942.         // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit
  943.         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
  944.         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  945.         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
  946.         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
  947.         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
  948.         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
  949.         dest += 6;
  950.     }
  951. }
  952.  
  953. static av_always_inline void
  954. yuv2rgb48_2_c_template(SwsContext *c, const int32_t *buf[2],
  955.                        const int32_t *ubuf[2], const int32_t *vbuf[2],
  956.                        const int32_t *abuf[2], uint16_t *dest, int dstW,
  957.                        int yalpha, int uvalpha, int y,
  958.                        enum AVPixelFormat target, int hasAlpha)
  959. {
  960.     const int32_t *buf0  = buf[0],  *buf1  = buf[1],
  961.                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
  962.                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1];
  963.     int  yalpha1 = 4096 - yalpha;
  964.     int uvalpha1 = 4096 - uvalpha;
  965.     int i;
  966.  
  967.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  968.         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;
  969.         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;
  970.         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;
  971.         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;
  972.         int R, G, B;
  973.  
  974.         Y1 -= c->yuv2rgb_y_offset;
  975.         Y2 -= c->yuv2rgb_y_offset;
  976.         Y1 *= c->yuv2rgb_y_coeff;
  977.         Y2 *= c->yuv2rgb_y_coeff;
  978.         Y1 += 1 << 13;
  979.         Y2 += 1 << 13;
  980.  
  981.         R = V * c->yuv2rgb_v2r_coeff;
  982.         G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  983.         B =                            U * c->yuv2rgb_u2b_coeff;
  984.  
  985.         output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
  986.         output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  987.         output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
  988.         output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
  989.         output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
  990.         output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
  991.         dest += 6;
  992.     }
  993. }
  994.  
  995. static av_always_inline void
  996. yuv2rgb48_1_c_template(SwsContext *c, const int32_t *buf0,
  997.                        const int32_t *ubuf[2], const int32_t *vbuf[2],
  998.                        const int32_t *abuf0, uint16_t *dest, int dstW,
  999.                        int uvalpha, int y, enum AVPixelFormat target, int hasAlpha)
  1000. {
  1001.     const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
  1002.     int i;
  1003.  
  1004.     if (uvalpha < 2048) {
  1005.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  1006.             int Y1 = (buf0[i * 2]    ) >> 2;
  1007.             int Y2 = (buf0[i * 2 + 1]) >> 2;
  1008.             int U  = (ubuf0[i] + (-128 << 11)) >> 2;
  1009.             int V  = (vbuf0[i] + (-128 << 11)) >> 2;
  1010.             int R, G, B;
  1011.  
  1012.             Y1 -= c->yuv2rgb_y_offset;
  1013.             Y2 -= c->yuv2rgb_y_offset;
  1014.             Y1 *= c->yuv2rgb_y_coeff;
  1015.             Y2 *= c->yuv2rgb_y_coeff;
  1016.             Y1 += 1 << 13;
  1017.             Y2 += 1 << 13;
  1018.  
  1019.             R = V * c->yuv2rgb_v2r_coeff;
  1020.             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  1021.             B =                            U * c->yuv2rgb_u2b_coeff;
  1022.  
  1023.             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
  1024.             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  1025.             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
  1026.             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
  1027.             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
  1028.             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
  1029.             dest += 6;
  1030.         }
  1031.     } else {
  1032.         const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
  1033.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  1034.             int Y1 = (buf0[i * 2]    ) >> 2;
  1035.             int Y2 = (buf0[i * 2 + 1]) >> 2;
  1036.             int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
  1037.             int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
  1038.             int R, G, B;
  1039.  
  1040.             Y1 -= c->yuv2rgb_y_offset;
  1041.             Y2 -= c->yuv2rgb_y_offset;
  1042.             Y1 *= c->yuv2rgb_y_coeff;
  1043.             Y2 *= c->yuv2rgb_y_coeff;
  1044.             Y1 += 1 << 13;
  1045.             Y2 += 1 << 13;
  1046.  
  1047.             R = V * c->yuv2rgb_v2r_coeff;
  1048.             G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  1049.             B =                            U * c->yuv2rgb_u2b_coeff;
  1050.  
  1051.             output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14);
  1052.             output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);
  1053.             output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14);
  1054.             output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14);
  1055.             output_pixel(&dest[4], av_clip_uintp2(  G + Y2, 30) >> 14);
  1056.             output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14);
  1057.             dest += 6;
  1058.         }
  1059.     }
  1060. }
  1061.  
  1062. #undef output_pixel
  1063. #undef r_b
  1064. #undef b_r
  1065.  
  1066. #define YUV2PACKED16WRAPPER(name, base, ext, fmt, hasAlpha) \
  1067. static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
  1068.                         const int16_t **_lumSrc, int lumFilterSize, \
  1069.                         const int16_t *chrFilter, const int16_t **_chrUSrc, \
  1070.                         const int16_t **_chrVSrc, int chrFilterSize, \
  1071.                         const int16_t **_alpSrc, uint8_t *_dest, int dstW, \
  1072.                         int y) \
  1073. { \
  1074.     const int32_t **lumSrc  = (const int32_t **) _lumSrc, \
  1075.                   **chrUSrc = (const int32_t **) _chrUSrc, \
  1076.                   **chrVSrc = (const int32_t **) _chrVSrc, \
  1077.                   **alpSrc  = (const int32_t **) _alpSrc; \
  1078.     uint16_t *dest = (uint16_t *) _dest; \
  1079.     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
  1080.                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
  1081.                           alpSrc, dest, dstW, y, fmt, hasAlpha); \
  1082. } \
  1083.  \
  1084. static void name ## ext ## _2_c(SwsContext *c, const int16_t *_buf[2], \
  1085.                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
  1086.                         const int16_t *_abuf[2], uint8_t *_dest, int dstW, \
  1087.                         int yalpha, int uvalpha, int y) \
  1088. { \
  1089.     const int32_t **buf  = (const int32_t **) _buf, \
  1090.                   **ubuf = (const int32_t **) _ubuf, \
  1091.                   **vbuf = (const int32_t **) _vbuf, \
  1092.                   **abuf = (const int32_t **) _abuf; \
  1093.     uint16_t *dest = (uint16_t *) _dest; \
  1094.     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
  1095.                           dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
  1096. } \
  1097.  \
  1098. static void name ## ext ## _1_c(SwsContext *c, const int16_t *_buf0, \
  1099.                         const int16_t *_ubuf[2], const int16_t *_vbuf[2], \
  1100.                         const int16_t *_abuf0, uint8_t *_dest, int dstW, \
  1101.                         int uvalpha, int y) \
  1102. { \
  1103.     const int32_t *buf0  = (const int32_t *)  _buf0, \
  1104.                  **ubuf  = (const int32_t **) _ubuf, \
  1105.                  **vbuf  = (const int32_t **) _vbuf, \
  1106.                   *abuf0 = (const int32_t *)  _abuf0; \
  1107.     uint16_t *dest = (uint16_t *) _dest; \
  1108.     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
  1109.                                   dstW, uvalpha, y, fmt, hasAlpha); \
  1110. }
  1111.  
  1112. YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48be, AV_PIX_FMT_RGB48BE, 0)
  1113. YUV2PACKED16WRAPPER(yuv2, rgb48, rgb48le, AV_PIX_FMT_RGB48LE, 0)
  1114. YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48be, AV_PIX_FMT_BGR48BE, 0)
  1115. YUV2PACKED16WRAPPER(yuv2, rgb48, bgr48le, AV_PIX_FMT_BGR48LE, 0)
  1116. YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64be, AV_PIX_FMT_RGBA64BE, 1)
  1117. YUV2PACKED16WRAPPER(yuv2, rgba64, rgba64le, AV_PIX_FMT_RGBA64LE, 1)
  1118. YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64be, AV_PIX_FMT_RGBA64BE, 0)
  1119. YUV2PACKED16WRAPPER(yuv2, rgba64, rgbx64le, AV_PIX_FMT_RGBA64LE, 0)
  1120.  
  1121. /*
  1122.  * Write out 2 RGB pixels in the target pixel format. This function takes a
  1123.  * R/G/B LUT as generated by ff_yuv2rgb_c_init_tables(), which takes care of
  1124.  * things like endianness conversion and shifting. The caller takes care of
  1125.  * setting the correct offset in these tables from the chroma (U/V) values.
  1126.  * This function then uses the luminance (Y1/Y2) values to write out the
  1127.  * correct RGB values into the destination buffer.
  1128.  */
  1129. static av_always_inline void
  1130. yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
  1131.               unsigned A1, unsigned A2,
  1132.               const void *_r, const void *_g, const void *_b, int y,
  1133.               enum AVPixelFormat target, int hasAlpha)
  1134. {
  1135.     if (target == AV_PIX_FMT_ARGB || target == AV_PIX_FMT_RGBA ||
  1136.         target == AV_PIX_FMT_ABGR || target == AV_PIX_FMT_BGRA) {
  1137.         uint32_t *dest = (uint32_t *) _dest;
  1138.         const uint32_t *r = (const uint32_t *) _r;
  1139.         const uint32_t *g = (const uint32_t *) _g;
  1140.         const uint32_t *b = (const uint32_t *) _b;
  1141.  
  1142. #if CONFIG_SMALL
  1143.         int sh = hasAlpha ? ((target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24) : 0;
  1144.  
  1145.         dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (hasAlpha ? A1 << sh : 0);
  1146.         dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (hasAlpha ? A2 << sh : 0);
  1147. #else
  1148.         if (hasAlpha) {
  1149.             int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24;
  1150.  
  1151.             av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0);
  1152.             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1] + (A1 << sh);
  1153.             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2] + (A2 << sh);
  1154.         } else {
  1155. #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1
  1156.             int sh = (target == AV_PIX_FMT_RGB32_1 || target == AV_PIX_FMT_BGR32_1) ? 0 : 24;
  1157.  
  1158.             av_assert2((((r[Y1] + g[Y1] + b[Y1]) >> sh) & 0xFF) == 0xFF);
  1159. #endif
  1160.             dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1];
  1161.             dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2];
  1162.         }
  1163. #endif
  1164.     } else if (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) {
  1165.         uint8_t *dest = (uint8_t *) _dest;
  1166.         const uint8_t *r = (const uint8_t *) _r;
  1167.         const uint8_t *g = (const uint8_t *) _g;
  1168.         const uint8_t *b = (const uint8_t *) _b;
  1169.  
  1170. #define r_b ((target == AV_PIX_FMT_RGB24) ? r : b)
  1171. #define b_r ((target == AV_PIX_FMT_RGB24) ? b : r)
  1172.  
  1173.         dest[i * 6 + 0] = r_b[Y1];
  1174.         dest[i * 6 + 1] =   g[Y1];
  1175.         dest[i * 6 + 2] = b_r[Y1];
  1176.         dest[i * 6 + 3] = r_b[Y2];
  1177.         dest[i * 6 + 4] =   g[Y2];
  1178.         dest[i * 6 + 5] = b_r[Y2];
  1179. #undef r_b
  1180. #undef b_r
  1181.     } else if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565 ||
  1182.                target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555 ||
  1183.                target == AV_PIX_FMT_RGB444 || target == AV_PIX_FMT_BGR444) {
  1184.         uint16_t *dest = (uint16_t *) _dest;
  1185.         const uint16_t *r = (const uint16_t *) _r;
  1186.         const uint16_t *g = (const uint16_t *) _g;
  1187.         const uint16_t *b = (const uint16_t *) _b;
  1188.         int dr1, dg1, db1, dr2, dg2, db2;
  1189.  
  1190.         if (target == AV_PIX_FMT_RGB565 || target == AV_PIX_FMT_BGR565) {
  1191.             dr1 = ff_dither_2x2_8[ y & 1     ][0];
  1192.             dg1 = ff_dither_2x2_4[ y & 1     ][0];
  1193.             db1 = ff_dither_2x2_8[(y & 1) ^ 1][0];
  1194.             dr2 = ff_dither_2x2_8[ y & 1     ][1];
  1195.             dg2 = ff_dither_2x2_4[ y & 1     ][1];
  1196.             db2 = ff_dither_2x2_8[(y & 1) ^ 1][1];
  1197.         } else if (target == AV_PIX_FMT_RGB555 || target == AV_PIX_FMT_BGR555) {
  1198.             dr1 = ff_dither_2x2_8[ y & 1     ][0];
  1199.             dg1 = ff_dither_2x2_8[ y & 1     ][1];
  1200.             db1 = ff_dither_2x2_8[(y & 1) ^ 1][0];
  1201.             dr2 = ff_dither_2x2_8[ y & 1     ][1];
  1202.             dg2 = ff_dither_2x2_8[ y & 1     ][0];
  1203.             db2 = ff_dither_2x2_8[(y & 1) ^ 1][1];
  1204.         } else {
  1205.             dr1 = ff_dither_4x4_16[ y & 3     ][0];
  1206.             dg1 = ff_dither_4x4_16[ y & 3     ][1];
  1207.             db1 = ff_dither_4x4_16[(y & 3) ^ 3][0];
  1208.             dr2 = ff_dither_4x4_16[ y & 3     ][1];
  1209.             dg2 = ff_dither_4x4_16[ y & 3     ][0];
  1210.             db2 = ff_dither_4x4_16[(y & 3) ^ 3][1];
  1211.         }
  1212.  
  1213.         dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
  1214.         dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
  1215.     } else /* 8/4-bit */ {
  1216.         uint8_t *dest = (uint8_t *) _dest;
  1217.         const uint8_t *r = (const uint8_t *) _r;
  1218.         const uint8_t *g = (const uint8_t *) _g;
  1219.         const uint8_t *b = (const uint8_t *) _b;
  1220.         int dr1, dg1, db1, dr2, dg2, db2;
  1221.  
  1222.         if (target == AV_PIX_FMT_RGB8 || target == AV_PIX_FMT_BGR8) {
  1223.             const uint8_t * const d64 = ff_dither_8x8_73[y & 7];
  1224.             const uint8_t * const d32 = ff_dither_8x8_32[y & 7];
  1225.             dr1 = dg1 = d32[(i * 2 + 0) & 7];
  1226.             db1 =       d64[(i * 2 + 0) & 7];
  1227.             dr2 = dg2 = d32[(i * 2 + 1) & 7];
  1228.             db2 =       d64[(i * 2 + 1) & 7];
  1229.         } else {
  1230.             const uint8_t * const d64  = ff_dither_8x8_73 [y & 7];
  1231.             const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
  1232.             dr1 = db1 = d128[(i * 2 + 0) & 7];
  1233.             dg1 =        d64[(i * 2 + 0) & 7];
  1234.             dr2 = db2 = d128[(i * 2 + 1) & 7];
  1235.             dg2 =        d64[(i * 2 + 1) & 7];
  1236.         }
  1237.  
  1238.         if (target == AV_PIX_FMT_RGB4 || target == AV_PIX_FMT_BGR4) {
  1239.             dest[i] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1] +
  1240.                     ((r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]) << 4);
  1241.         } else {
  1242.             dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
  1243.             dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2];
  1244.         }
  1245.     }
  1246. }
  1247.  
  1248. static av_always_inline void
  1249. yuv2rgb_X_c_template(SwsContext *c, const int16_t *lumFilter,
  1250.                      const int16_t **lumSrc, int lumFilterSize,
  1251.                      const int16_t *chrFilter, const int16_t **chrUSrc,
  1252.                      const int16_t **chrVSrc, int chrFilterSize,
  1253.                      const int16_t **alpSrc, uint8_t *dest, int dstW,
  1254.                      int y, enum AVPixelFormat target, int hasAlpha)
  1255. {
  1256.     int i;
  1257.  
  1258.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  1259.         int j, A1, A2;
  1260.         int Y1 = 1 << 18;
  1261.         int Y2 = 1 << 18;
  1262.         int U  = 1 << 18;
  1263.         int V  = 1 << 18;
  1264.         const void *r, *g, *b;
  1265.  
  1266.         for (j = 0; j < lumFilterSize; j++) {
  1267.             Y1 += lumSrc[j][i * 2]     * lumFilter[j];
  1268.             Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
  1269.         }
  1270.         for (j = 0; j < chrFilterSize; j++) {
  1271.             U += chrUSrc[j][i] * chrFilter[j];
  1272.             V += chrVSrc[j][i] * chrFilter[j];
  1273.         }
  1274.         Y1 >>= 19;
  1275.         Y2 >>= 19;
  1276.         U  >>= 19;
  1277.         V  >>= 19;
  1278.         if (hasAlpha) {
  1279.             A1 = 1 << 18;
  1280.             A2 = 1 << 18;
  1281.             for (j = 0; j < lumFilterSize; j++) {
  1282.                 A1 += alpSrc[j][i * 2    ] * lumFilter[j];
  1283.                 A2 += alpSrc[j][i * 2 + 1] * lumFilter[j];
  1284.             }
  1285.             A1 >>= 19;
  1286.             A2 >>= 19;
  1287.             if ((A1 | A2) & 0x100) {
  1288.                 A1 = av_clip_uint8(A1);
  1289.                 A2 = av_clip_uint8(A2);
  1290.             }
  1291.         }
  1292.  
  1293.         r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM];
  1294.         g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]);
  1295.         b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
  1296.  
  1297.         yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
  1298.                       r, g, b, y, target, hasAlpha);
  1299.     }
  1300. }
  1301.  
  1302. static av_always_inline void
  1303. yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
  1304.                      const int16_t *ubuf[2], const int16_t *vbuf[2],
  1305.                      const int16_t *abuf[2], uint8_t *dest, int dstW,
  1306.                      int yalpha, int uvalpha, int y,
  1307.                      enum AVPixelFormat target, int hasAlpha)
  1308. {
  1309.     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
  1310.                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
  1311.                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
  1312.                   *abuf0 = hasAlpha ? abuf[0] : NULL,
  1313.                   *abuf1 = hasAlpha ? abuf[1] : NULL;
  1314.     int  yalpha1 = 4096 - yalpha;
  1315.     int uvalpha1 = 4096 - uvalpha;
  1316.     int i;
  1317.  
  1318.     for (i = 0; i < ((dstW + 1) >> 1); i++) {
  1319.         int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
  1320.         int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
  1321.         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
  1322.         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
  1323.         int A1, A2;
  1324.         const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
  1325.                    *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
  1326.                    *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
  1327.  
  1328.         if (hasAlpha) {
  1329.             A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 19;
  1330.             A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
  1331.             A1 = av_clip_uint8(A1);
  1332.             A2 = av_clip_uint8(A2);
  1333.         }
  1334.  
  1335.         yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
  1336.                       r, g, b, y, target, hasAlpha);
  1337.     }
  1338. }
  1339.  
  1340. static av_always_inline void
  1341. yuv2rgb_1_c_template(SwsContext *c, const int16_t *buf0,
  1342.                      const int16_t *ubuf[2], const int16_t *vbuf[2],
  1343.                      const int16_t *abuf0, uint8_t *dest, int dstW,
  1344.                      int uvalpha, int y, enum AVPixelFormat target,
  1345.                      int hasAlpha)
  1346. {
  1347.     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
  1348.     int i;
  1349.  
  1350.     if (uvalpha < 2048) {
  1351.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  1352.             int Y1 = (buf0[i * 2    ] + 64) >> 7;
  1353.             int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
  1354.             int U  = (ubuf0[i]        + 64) >> 7;
  1355.             int V  = (vbuf0[i]        + 64) >> 7;
  1356.             int A1, A2;
  1357.             const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
  1358.                        *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
  1359.                        *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
  1360.  
  1361.             if (hasAlpha) {
  1362.                 A1 = abuf0[i * 2    ] * 255 + 16384 >> 15;
  1363.                 A2 = abuf0[i * 2 + 1] * 255 + 16384 >> 15;
  1364.                 A1 = av_clip_uint8(A1);
  1365.                 A2 = av_clip_uint8(A2);
  1366.             }
  1367.  
  1368.             yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
  1369.                           r, g, b, y, target, hasAlpha);
  1370.         }
  1371.     } else {
  1372.         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
  1373.         for (i = 0; i < ((dstW + 1) >> 1); i++) {
  1374.             int Y1 = (buf0[i * 2    ]     +  64) >> 7;
  1375.             int Y2 = (buf0[i * 2 + 1]     +  64) >> 7;
  1376.             int U  = (ubuf0[i] + ubuf1[i] + 128) >> 8;
  1377.             int V  = (vbuf0[i] + vbuf1[i] + 128) >> 8;
  1378.             int A1, A2;
  1379.             const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
  1380.                        *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
  1381.                        *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
  1382.  
  1383.             if (hasAlpha) {
  1384.                 A1 = (abuf0[i * 2    ] + 64) >> 7;
  1385.                 A2 = (abuf0[i * 2 + 1] + 64) >> 7;
  1386.                 A1 = av_clip_uint8(A1);
  1387.                 A2 = av_clip_uint8(A2);
  1388.             }
  1389.  
  1390.             yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
  1391.                           r, g, b, y, target, hasAlpha);
  1392.         }
  1393.     }
  1394. }
  1395.  
  1396. #define YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
  1397. static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
  1398.                                 const int16_t **lumSrc, int lumFilterSize, \
  1399.                                 const int16_t *chrFilter, const int16_t **chrUSrc, \
  1400.                                 const int16_t **chrVSrc, int chrFilterSize, \
  1401.                                 const int16_t **alpSrc, uint8_t *dest, int dstW, \
  1402.                                 int y) \
  1403. { \
  1404.     name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
  1405.                                   chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
  1406.                                   alpSrc, dest, dstW, y, fmt, hasAlpha); \
  1407. }
  1408.  
  1409. #define YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \
  1410. YUV2RGBWRAPPERX(name, base, ext, fmt, hasAlpha) \
  1411. static void name ## ext ## _2_c(SwsContext *c, const int16_t *buf[2], \
  1412.                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
  1413.                                 const int16_t *abuf[2], uint8_t *dest, int dstW, \
  1414.                                 int yalpha, int uvalpha, int y) \
  1415. { \
  1416.     name ## base ## _2_c_template(c, buf, ubuf, vbuf, abuf, \
  1417.                                   dest, dstW, yalpha, uvalpha, y, fmt, hasAlpha); \
  1418. }
  1419.  
  1420. #define YUV2RGBWRAPPER(name, base, ext, fmt, hasAlpha) \
  1421. YUV2RGBWRAPPERX2(name, base, ext, fmt, hasAlpha) \
  1422. static void name ## ext ## _1_c(SwsContext *c, const int16_t *buf0, \
  1423.                                 const int16_t *ubuf[2], const int16_t *vbuf[2], \
  1424.                                 const int16_t *abuf0, uint8_t *dest, int dstW, \
  1425.                                 int uvalpha, int y) \
  1426. { \
  1427.     name ## base ## _1_c_template(c, buf0, ubuf, vbuf, abuf0, dest, \
  1428.                                   dstW, uvalpha, y, fmt, hasAlpha); \
  1429. }
  1430.  
  1431. #if CONFIG_SMALL
  1432. YUV2RGBWRAPPER(yuv2rgb,,  32_1,  AV_PIX_FMT_RGB32_1,   CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
  1433. YUV2RGBWRAPPER(yuv2rgb,,  32,    AV_PIX_FMT_RGB32,     CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
  1434. #else
  1435. #if CONFIG_SWSCALE_ALPHA
  1436. YUV2RGBWRAPPER(yuv2rgb,, a32_1,  AV_PIX_FMT_RGB32_1,   1)
  1437. YUV2RGBWRAPPER(yuv2rgb,, a32,    AV_PIX_FMT_RGB32,     1)
  1438. #endif
  1439. YUV2RGBWRAPPER(yuv2rgb,, x32_1,  AV_PIX_FMT_RGB32_1,   0)
  1440. YUV2RGBWRAPPER(yuv2rgb,, x32,    AV_PIX_FMT_RGB32,     0)
  1441. #endif
  1442. YUV2RGBWRAPPER(yuv2, rgb, rgb24, AV_PIX_FMT_RGB24,   0)
  1443. YUV2RGBWRAPPER(yuv2, rgb, bgr24, AV_PIX_FMT_BGR24,   0)
  1444. YUV2RGBWRAPPER(yuv2rgb,,  16,    AV_PIX_FMT_RGB565,    0)
  1445. YUV2RGBWRAPPER(yuv2rgb,,  15,    AV_PIX_FMT_RGB555,    0)
  1446. YUV2RGBWRAPPER(yuv2rgb,,  12,    AV_PIX_FMT_RGB444,    0)
  1447. YUV2RGBWRAPPER(yuv2rgb,,   8,    AV_PIX_FMT_RGB8,      0)
  1448. YUV2RGBWRAPPER(yuv2rgb,,   4,    AV_PIX_FMT_RGB4,      0)
  1449. YUV2RGBWRAPPER(yuv2rgb,,   4b,   AV_PIX_FMT_RGB4_BYTE, 0)
  1450.  
  1451. static av_always_inline void yuv2rgb_write_full(SwsContext *c,
  1452.     uint8_t *dest, int i, int Y, int A, int U, int V,
  1453.     int y, enum AVPixelFormat target, int hasAlpha, int err[4])
  1454. {
  1455.     int R, G, B;
  1456.     int isrgb8 = target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8;
  1457.  
  1458.     Y -= c->yuv2rgb_y_offset;
  1459.     Y *= c->yuv2rgb_y_coeff;
  1460.     Y += 1 << 21;
  1461.     R = Y + V*c->yuv2rgb_v2r_coeff;
  1462.     G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
  1463.     B = Y +                          U*c->yuv2rgb_u2b_coeff;
  1464.     if ((R | G | B) & 0xC0000000) {
  1465.         R = av_clip_uintp2(R, 30);
  1466.         G = av_clip_uintp2(G, 30);
  1467.         B = av_clip_uintp2(B, 30);
  1468.     }
  1469.  
  1470.     switch(target) {
  1471.     case AV_PIX_FMT_ARGB:
  1472.         dest[0] = hasAlpha ? A : 255;
  1473.         dest[1] = R >> 22;
  1474.         dest[2] = G >> 22;
  1475.         dest[3] = B >> 22;
  1476.         break;
  1477.     case AV_PIX_FMT_RGB24:
  1478.         dest[0] = R >> 22;
  1479.         dest[1] = G >> 22;
  1480.         dest[2] = B >> 22;
  1481.         break;
  1482.     case AV_PIX_FMT_RGBA:
  1483.         dest[0] = R >> 22;
  1484.         dest[1] = G >> 22;
  1485.         dest[2] = B >> 22;
  1486.         dest[3] = hasAlpha ? A : 255;
  1487.         break;
  1488.     case AV_PIX_FMT_ABGR:
  1489.         dest[0] = hasAlpha ? A : 255;
  1490.         dest[1] = B >> 22;
  1491.         dest[2] = G >> 22;
  1492.         dest[3] = R >> 22;
  1493.         break;
  1494.     case AV_PIX_FMT_BGR24:
  1495.         dest[0] = B >> 22;
  1496.         dest[1] = G >> 22;
  1497.         dest[2] = R >> 22;
  1498.         break;
  1499.     case AV_PIX_FMT_BGRA:
  1500.         dest[0] = B >> 22;
  1501.         dest[1] = G >> 22;
  1502.         dest[2] = R >> 22;
  1503.         dest[3] = hasAlpha ? A : 255;
  1504.         break;
  1505.     case AV_PIX_FMT_BGR4_BYTE:
  1506.     case AV_PIX_FMT_RGB4_BYTE:
  1507.     case AV_PIX_FMT_BGR8:
  1508.     case AV_PIX_FMT_RGB8:
  1509.     {
  1510.         int r,g,b;
  1511.         R >>= 22;
  1512.         G >>= 22;
  1513.         B >>= 22;
  1514.         R += (7*err[0] + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2])>>4;
  1515.         G += (7*err[1] + 1*c->dither_error[1][i] + 5*c->dither_error[1][i+1] + 3*c->dither_error[1][i+2])>>4;
  1516.         B += (7*err[2] + 1*c->dither_error[2][i] + 5*c->dither_error[2][i+1] + 3*c->dither_error[2][i+2])>>4;
  1517.         c->dither_error[0][i] = err[0];
  1518.         c->dither_error[1][i] = err[1];
  1519.         c->dither_error[2][i] = err[2];
  1520.         r = R >> (isrgb8 ? 5 : 7);
  1521.         g = G >> (isrgb8 ? 5 : 6);
  1522.         b = B >> (isrgb8 ? 6 : 7);
  1523.         r = av_clip(r, 0, isrgb8 ? 7 : 1);
  1524.         g = av_clip(g, 0, isrgb8 ? 7 : 3);
  1525.         b = av_clip(b, 0, isrgb8 ? 3 : 1);
  1526.         err[0] = R - r*(isrgb8 ? 36 : 255);
  1527.         err[1] = G - g*(isrgb8 ? 36 : 85);
  1528.         err[2] = B - b*(isrgb8 ? 85 : 255);
  1529.         if(target == AV_PIX_FMT_BGR4_BYTE) {
  1530.             dest[0] = r + 2*g + 8*b;
  1531.         } else if(target == AV_PIX_FMT_RGB4_BYTE) {
  1532.             dest[0] = b + 2*g + 8*r;
  1533.         } else if(target == AV_PIX_FMT_BGR8) {
  1534.             dest[0] = r + 8*g + 64*b;
  1535.         } else if(target == AV_PIX_FMT_RGB8) {
  1536.             dest[0] = b + 4*g + 32*r;
  1537.         } else
  1538.             av_assert2(0);
  1539.         break;}
  1540.     }
  1541. }
  1542.  
  1543. static av_always_inline void
  1544. yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
  1545.                           const int16_t **lumSrc, int lumFilterSize,
  1546.                           const int16_t *chrFilter, const int16_t **chrUSrc,
  1547.                           const int16_t **chrVSrc, int chrFilterSize,
  1548.                           const int16_t **alpSrc, uint8_t *dest,
  1549.                           int dstW, int y, enum AVPixelFormat target, int hasAlpha)
  1550. {
  1551.     int i;
  1552.     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
  1553.     int err[4] = {0};
  1554.     int A = 0; //init to silence warning
  1555.  
  1556.     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
  1557.        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
  1558.         step = 1;
  1559.  
  1560.     for (i = 0; i < dstW; i++) {
  1561.         int j;
  1562.         int Y = 1<<9;
  1563.         int U = (1<<9)-(128 << 19);
  1564.         int V = (1<<9)-(128 << 19);
  1565.  
  1566.         for (j = 0; j < lumFilterSize; j++) {
  1567.             Y += lumSrc[j][i] * lumFilter[j];
  1568.         }
  1569.         for (j = 0; j < chrFilterSize; j++) {
  1570.             U += chrUSrc[j][i] * chrFilter[j];
  1571.             V += chrVSrc[j][i] * chrFilter[j];
  1572.         }
  1573.         Y >>= 10;
  1574.         U >>= 10;
  1575.         V >>= 10;
  1576.         if (hasAlpha) {
  1577.             A = 1 << 18;
  1578.             for (j = 0; j < lumFilterSize; j++) {
  1579.                 A += alpSrc[j][i] * lumFilter[j];
  1580.             }
  1581.             A >>= 19;
  1582.             if (A & 0x100)
  1583.                 A = av_clip_uint8(A);
  1584.         }
  1585.         yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
  1586.         dest += step;
  1587.     }
  1588.     c->dither_error[0][i] = err[0];
  1589.     c->dither_error[1][i] = err[1];
  1590.     c->dither_error[2][i] = err[2];
  1591. }
  1592.  
  1593. static av_always_inline void
  1594. yuv2rgb_full_2_c_template(SwsContext *c, const int16_t *buf[2],
  1595.                      const int16_t *ubuf[2], const int16_t *vbuf[2],
  1596.                      const int16_t *abuf[2], uint8_t *dest, int dstW,
  1597.                      int yalpha, int uvalpha, int y,
  1598.                      enum AVPixelFormat target, int hasAlpha)
  1599. {
  1600.     const int16_t *buf0  = buf[0],  *buf1  = buf[1],
  1601.                   *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
  1602.                   *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
  1603.                   *abuf0 = hasAlpha ? abuf[0] : NULL,
  1604.                   *abuf1 = hasAlpha ? abuf[1] : NULL;
  1605.     int  yalpha1 = 4096 - yalpha;
  1606.     int uvalpha1 = 4096 - uvalpha;
  1607.     int i;
  1608.     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
  1609.     int err[4] = {0};
  1610.     int A = 0; // init to silcene warning
  1611.  
  1612.     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
  1613.        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
  1614.         step = 1;
  1615.  
  1616.     for (i = 0; i < dstW; i++) {
  1617.         int Y = ( buf0[i] * yalpha1  +  buf1[i] * yalpha             ) >> 10; //FIXME rounding
  1618.         int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha-(128 << 19)) >> 10;
  1619.         int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha-(128 << 19)) >> 10;
  1620.  
  1621.         if (hasAlpha) {
  1622.             A = (abuf0[i] * yalpha1 + abuf1[i] * yalpha + (1<<18)) >> 19;
  1623.             if (A & 0x100)
  1624.                 A = av_clip_uint8(A);
  1625.         }
  1626.  
  1627.         yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
  1628.         dest += step;
  1629.     }
  1630.     c->dither_error[0][i] = err[0];
  1631.     c->dither_error[1][i] = err[1];
  1632.     c->dither_error[2][i] = err[2];
  1633. }
  1634.  
  1635. static av_always_inline void
  1636. yuv2rgb_full_1_c_template(SwsContext *c, const int16_t *buf0,
  1637.                      const int16_t *ubuf[2], const int16_t *vbuf[2],
  1638.                      const int16_t *abuf0, uint8_t *dest, int dstW,
  1639.                      int uvalpha, int y, enum AVPixelFormat target,
  1640.                      int hasAlpha)
  1641. {
  1642.     const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];
  1643.     int i;
  1644.     int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
  1645.     int err[4] = {0};
  1646.  
  1647.     if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
  1648.        || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)
  1649.         step = 1;
  1650.  
  1651.     if (uvalpha < 2048) {
  1652.         int A = 0; //init to silence warning
  1653.         for (i = 0; i < dstW; i++) {
  1654.             int Y = buf0[i] << 2;
  1655.             int U = (ubuf0[i] - (128<<7)) << 2;
  1656.             int V = (vbuf0[i] - (128<<7)) << 2;
  1657.  
  1658.             if (hasAlpha) {
  1659.                 A = (abuf0[i] + 64) >> 7;
  1660.                 if (A & 0x100)
  1661.                     A = av_clip_uint8(A);
  1662.             }
  1663.  
  1664.             yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
  1665.             dest += step;
  1666.         }
  1667.     } else {
  1668.         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
  1669.         int A = 0; //init to silence warning
  1670.         for (i = 0; i < dstW; i++) {
  1671.             int Y = buf0[i] << 2;
  1672.             int U = (ubuf0[i] + ubuf1[i] - (128<<8)) << 1;
  1673.             int V = (vbuf0[i] + vbuf1[i] - (128<<8)) << 1;
  1674.  
  1675.             if (hasAlpha) {
  1676.                 A = (abuf0[i] + 64) >> 7;
  1677.                 if (A & 0x100)
  1678.                     A = av_clip_uint8(A);
  1679.             }
  1680.  
  1681.             yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
  1682.             dest += step;
  1683.         }
  1684.     }
  1685.  
  1686.     c->dither_error[0][i] = err[0];
  1687.     c->dither_error[1][i] = err[1];
  1688.     c->dither_error[2][i] = err[2];
  1689. }
  1690.  
  1691. #if CONFIG_SMALL
  1692. YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
  1693. YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
  1694. YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
  1695. YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB,  CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
  1696. #else
  1697. #if CONFIG_SWSCALE_ALPHA
  1698. YUV2RGBWRAPPER(yuv2, rgb_full, bgra32_full, AV_PIX_FMT_BGRA,  1)
  1699. YUV2RGBWRAPPER(yuv2, rgb_full, abgr32_full, AV_PIX_FMT_ABGR,  1)
  1700. YUV2RGBWRAPPER(yuv2, rgb_full, rgba32_full, AV_PIX_FMT_RGBA,  1)
  1701. YUV2RGBWRAPPER(yuv2, rgb_full, argb32_full, AV_PIX_FMT_ARGB,  1)
  1702. #endif
  1703. YUV2RGBWRAPPER(yuv2, rgb_full, bgrx32_full, AV_PIX_FMT_BGRA,  0)
  1704. YUV2RGBWRAPPER(yuv2, rgb_full, xbgr32_full, AV_PIX_FMT_ABGR,  0)
  1705. YUV2RGBWRAPPER(yuv2, rgb_full, rgbx32_full, AV_PIX_FMT_RGBA,  0)
  1706. YUV2RGBWRAPPER(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB,  0)
  1707. #endif
  1708. YUV2RGBWRAPPER(yuv2, rgb_full, bgr24_full,  AV_PIX_FMT_BGR24, 0)
  1709. YUV2RGBWRAPPER(yuv2, rgb_full, rgb24_full,  AV_PIX_FMT_RGB24, 0)
  1710.  
  1711. YUV2RGBWRAPPER(yuv2, rgb_full, bgr4_byte_full,  AV_PIX_FMT_BGR4_BYTE, 0)
  1712. YUV2RGBWRAPPER(yuv2, rgb_full, rgb4_byte_full,  AV_PIX_FMT_RGB4_BYTE, 0)
  1713. YUV2RGBWRAPPER(yuv2, rgb_full, bgr8_full,   AV_PIX_FMT_BGR8,  0)
  1714. YUV2RGBWRAPPER(yuv2, rgb_full, rgb8_full,   AV_PIX_FMT_RGB8,  0)
  1715.  
  1716. static void
  1717. yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter,
  1718.                   const int16_t **lumSrc, int lumFilterSize,
  1719.                   const int16_t *chrFilter, const int16_t **chrUSrc,
  1720.                   const int16_t **chrVSrc, int chrFilterSize,
  1721.                   const int16_t **alpSrc, uint8_t **dest,
  1722.                   int dstW, int y)
  1723. {
  1724.     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
  1725.     int i;
  1726.     int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrc;
  1727.     uint16_t **dest16 = (uint16_t**)dest;
  1728.     int SH = 22 + 7 - desc->comp[0].depth_minus1;
  1729.     int A = 0; // init to silence warning
  1730.  
  1731.     for (i = 0; i < dstW; i++) {
  1732.         int j;
  1733.         int Y = 1 << 9;
  1734.         int U = (1 << 9) - (128 << 19);
  1735.         int V = (1 << 9) - (128 << 19);
  1736.         int R, G, B;
  1737.  
  1738.         for (j = 0; j < lumFilterSize; j++)
  1739.             Y += lumSrc[j][i] * lumFilter[j];
  1740.  
  1741.         for (j = 0; j < chrFilterSize; j++) {
  1742.             U += chrUSrc[j][i] * chrFilter[j];
  1743.             V += chrVSrc[j][i] * chrFilter[j];
  1744.         }
  1745.  
  1746.         Y >>= 10;
  1747.         U >>= 10;
  1748.         V >>= 10;
  1749.  
  1750.         if (hasAlpha) {
  1751.             A = 1 << 18;
  1752.  
  1753.             for (j = 0; j < lumFilterSize; j++)
  1754.                 A += alpSrc[j][i] * lumFilter[j];
  1755.  
  1756.             A >>= 19;
  1757.  
  1758.             if (A & 0x100)
  1759.                 A = av_clip_uint8(A);
  1760.         }
  1761.  
  1762.         Y -= c->yuv2rgb_y_offset;
  1763.         Y *= c->yuv2rgb_y_coeff;
  1764.         Y += 1 << 21;
  1765.         R = Y + V * c->yuv2rgb_v2r_coeff;
  1766.         G = Y + V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
  1767.         B = Y +                            U * c->yuv2rgb_u2b_coeff;
  1768.  
  1769.         if ((R | G | B) & 0xC0000000) {
  1770.             R = av_clip_uintp2(R, 30);
  1771.             G = av_clip_uintp2(G, 30);
  1772.             B = av_clip_uintp2(B, 30);
  1773.         }
  1774.  
  1775.         if (SH != 22) {
  1776.             dest16[0][i] = G >> SH;
  1777.             dest16[1][i] = B >> SH;
  1778.             dest16[2][i] = R >> SH;
  1779.             if (hasAlpha)
  1780.                 dest16[3][i] = A;
  1781.         } else {
  1782.             dest[0][i] = G >> 22;
  1783.             dest[1][i] = B >> 22;
  1784.             dest[2][i] = R >> 22;
  1785.             if (hasAlpha)
  1786.                 dest[3][i] = A;
  1787.         }
  1788.     }
  1789.     if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
  1790.         for (i = 0; i < dstW; i++) {
  1791.             dest16[0][i] = av_bswap16(dest16[0][i]);
  1792.             dest16[1][i] = av_bswap16(dest16[1][i]);
  1793.             dest16[2][i] = av_bswap16(dest16[2][i]);
  1794.             if (hasAlpha)
  1795.                 dest16[3][i] = av_bswap16(dest16[3][i]);
  1796.         }
  1797.     }
  1798. }
  1799.  
  1800. av_cold void ff_sws_init_output_funcs(SwsContext *c,
  1801.                                       yuv2planar1_fn *yuv2plane1,
  1802.                                       yuv2planarX_fn *yuv2planeX,
  1803.                                       yuv2interleavedX_fn *yuv2nv12cX,
  1804.                                       yuv2packed1_fn *yuv2packed1,
  1805.                                       yuv2packed2_fn *yuv2packed2,
  1806.                                       yuv2packedX_fn *yuv2packedX,
  1807.                                       yuv2anyX_fn *yuv2anyX)
  1808. {
  1809.     enum AVPixelFormat dstFormat = c->dstFormat;
  1810.     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
  1811.  
  1812.     if (is16BPS(dstFormat)) {
  1813.         *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c  : yuv2planeX_16LE_c;
  1814.         *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c  : yuv2plane1_16LE_c;
  1815.     } else if (is9_OR_10BPS(dstFormat)) {
  1816.         if (desc->comp[0].depth_minus1 == 8) {
  1817.             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c  : yuv2planeX_9LE_c;
  1818.             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_9BE_c  : yuv2plane1_9LE_c;
  1819.         } else if (desc->comp[0].depth_minus1 == 9) {
  1820.             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_10BE_c  : yuv2planeX_10LE_c;
  1821.             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_10BE_c  : yuv2plane1_10LE_c;
  1822.         } else if (desc->comp[0].depth_minus1 == 11) {
  1823.             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_12BE_c  : yuv2planeX_12LE_c;
  1824.             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_12BE_c  : yuv2plane1_12LE_c;
  1825.         } else if (desc->comp[0].depth_minus1 == 13) {
  1826.             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_14BE_c  : yuv2planeX_14LE_c;
  1827.             *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_14BE_c  : yuv2plane1_14LE_c;
  1828.         } else
  1829.             av_assert0(0);
  1830.     } else {
  1831.         *yuv2plane1 = yuv2plane1_8_c;
  1832.         *yuv2planeX = yuv2planeX_8_c;
  1833.         if (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)
  1834.             *yuv2nv12cX = yuv2nv12cX_c;
  1835.     }
  1836.  
  1837.     if(c->flags & SWS_FULL_CHR_H_INT) {
  1838.         switch (dstFormat) {
  1839.             case AV_PIX_FMT_RGBA:
  1840. #if CONFIG_SMALL
  1841.                 *yuv2packedX = yuv2rgba32_full_X_c;
  1842.                 *yuv2packed2 = yuv2rgba32_full_2_c;
  1843.                 *yuv2packed1 = yuv2rgba32_full_1_c;
  1844. #else
  1845. #if CONFIG_SWSCALE_ALPHA
  1846.                 if (c->alpPixBuf) {
  1847.                     *yuv2packedX = yuv2rgba32_full_X_c;
  1848.                     *yuv2packed2 = yuv2rgba32_full_2_c;
  1849.                     *yuv2packed1 = yuv2rgba32_full_1_c;
  1850.                 } else
  1851. #endif /* CONFIG_SWSCALE_ALPHA */
  1852.                 {
  1853.                     *yuv2packedX = yuv2rgbx32_full_X_c;
  1854.                     *yuv2packed2 = yuv2rgbx32_full_2_c;
  1855.                     *yuv2packed1 = yuv2rgbx32_full_1_c;
  1856.                 }
  1857. #endif /* !CONFIG_SMALL */
  1858.                 break;
  1859.             case AV_PIX_FMT_ARGB:
  1860. #if CONFIG_SMALL
  1861.                 *yuv2packedX = yuv2argb32_full_X_c;
  1862.                 *yuv2packed2 = yuv2argb32_full_2_c;
  1863.                 *yuv2packed1 = yuv2argb32_full_1_c;
  1864. #else
  1865. #if CONFIG_SWSCALE_ALPHA
  1866.                 if (c->alpPixBuf) {
  1867.                     *yuv2packedX = yuv2argb32_full_X_c;
  1868.                     *yuv2packed2 = yuv2argb32_full_2_c;
  1869.                     *yuv2packed1 = yuv2argb32_full_1_c;
  1870.                 } else
  1871. #endif /* CONFIG_SWSCALE_ALPHA */
  1872.                 {
  1873.                     *yuv2packedX = yuv2xrgb32_full_X_c;
  1874.                     *yuv2packed2 = yuv2xrgb32_full_2_c;
  1875.                     *yuv2packed1 = yuv2xrgb32_full_1_c;
  1876.                 }
  1877. #endif /* !CONFIG_SMALL */
  1878.                 break;
  1879.             case AV_PIX_FMT_BGRA:
  1880. #if CONFIG_SMALL
  1881.                 *yuv2packedX = yuv2bgra32_full_X_c;
  1882.                 *yuv2packed2 = yuv2bgra32_full_2_c;
  1883.                 *yuv2packed1 = yuv2bgra32_full_1_c;
  1884. #else
  1885. #if CONFIG_SWSCALE_ALPHA
  1886.                 if (c->alpPixBuf) {
  1887.                     *yuv2packedX = yuv2bgra32_full_X_c;
  1888.                     *yuv2packed2 = yuv2bgra32_full_2_c;
  1889.                     *yuv2packed1 = yuv2bgra32_full_1_c;
  1890.                 } else
  1891. #endif /* CONFIG_SWSCALE_ALPHA */
  1892.                 {
  1893.                     *yuv2packedX = yuv2bgrx32_full_X_c;
  1894.                     *yuv2packed2 = yuv2bgrx32_full_2_c;
  1895.                     *yuv2packed1 = yuv2bgrx32_full_1_c;
  1896.                 }
  1897. #endif /* !CONFIG_SMALL */
  1898.                 break;
  1899.             case AV_PIX_FMT_ABGR:
  1900. #if CONFIG_SMALL
  1901.                 *yuv2packedX = yuv2abgr32_full_X_c;
  1902.                 *yuv2packed2 = yuv2abgr32_full_2_c;
  1903.                 *yuv2packed1 = yuv2abgr32_full_1_c;
  1904. #else
  1905. #if CONFIG_SWSCALE_ALPHA
  1906.                 if (c->alpPixBuf) {
  1907.                     *yuv2packedX = yuv2abgr32_full_X_c;
  1908.                     *yuv2packed2 = yuv2abgr32_full_2_c;
  1909.                     *yuv2packed1 = yuv2abgr32_full_1_c;
  1910.                 } else
  1911. #endif /* CONFIG_SWSCALE_ALPHA */
  1912.                 {
  1913.                     *yuv2packedX = yuv2xbgr32_full_X_c;
  1914.                     *yuv2packed2 = yuv2xbgr32_full_2_c;
  1915.                     *yuv2packed1 = yuv2xbgr32_full_1_c;
  1916.                 }
  1917. #endif /* !CONFIG_SMALL */
  1918.                 break;
  1919.             case AV_PIX_FMT_RGB24:
  1920.             *yuv2packedX = yuv2rgb24_full_X_c;
  1921.             *yuv2packed2 = yuv2rgb24_full_2_c;
  1922.             *yuv2packed1 = yuv2rgb24_full_1_c;
  1923.             break;
  1924.         case AV_PIX_FMT_BGR24:
  1925.             *yuv2packedX = yuv2bgr24_full_X_c;
  1926.             *yuv2packed2 = yuv2bgr24_full_2_c;
  1927.             *yuv2packed1 = yuv2bgr24_full_1_c;
  1928.             break;
  1929.         case AV_PIX_FMT_BGR4_BYTE:
  1930.             *yuv2packedX = yuv2bgr4_byte_full_X_c;
  1931.             *yuv2packed2 = yuv2bgr4_byte_full_2_c;
  1932.             *yuv2packed1 = yuv2bgr4_byte_full_1_c;
  1933.             break;
  1934.         case AV_PIX_FMT_RGB4_BYTE:
  1935.             *yuv2packedX = yuv2rgb4_byte_full_X_c;
  1936.             *yuv2packed2 = yuv2rgb4_byte_full_2_c;
  1937.             *yuv2packed1 = yuv2rgb4_byte_full_1_c;
  1938.             break;
  1939.         case AV_PIX_FMT_BGR8:
  1940.             *yuv2packedX = yuv2bgr8_full_X_c;
  1941.             *yuv2packed2 = yuv2bgr8_full_2_c;
  1942.             *yuv2packed1 = yuv2bgr8_full_1_c;
  1943.             break;
  1944.         case AV_PIX_FMT_RGB8:
  1945.             *yuv2packedX = yuv2rgb8_full_X_c;
  1946.             *yuv2packed2 = yuv2rgb8_full_2_c;
  1947.             *yuv2packed1 = yuv2rgb8_full_1_c;
  1948.             break;
  1949.         case AV_PIX_FMT_GBRP:
  1950.         case AV_PIX_FMT_GBRP9BE:
  1951.         case AV_PIX_FMT_GBRP9LE:
  1952.         case AV_PIX_FMT_GBRP10BE:
  1953.         case AV_PIX_FMT_GBRP10LE:
  1954.         case AV_PIX_FMT_GBRP12BE:
  1955.         case AV_PIX_FMT_GBRP12LE:
  1956.         case AV_PIX_FMT_GBRP14BE:
  1957.         case AV_PIX_FMT_GBRP14LE:
  1958.         case AV_PIX_FMT_GBRP16BE:
  1959.         case AV_PIX_FMT_GBRP16LE:
  1960.         case AV_PIX_FMT_GBRAP:
  1961.             *yuv2anyX = yuv2gbrp_full_X_c;
  1962.             break;
  1963.         }
  1964.         if (!*yuv2packedX && !*yuv2anyX)
  1965.             goto YUV_PACKED;
  1966.     } else {
  1967.         YUV_PACKED:
  1968.         switch (dstFormat) {
  1969.         case AV_PIX_FMT_RGBA64LE:
  1970. #if CONFIG_SWSCALE_ALPHA
  1971.             if (c->alpPixBuf) {
  1972.                 *yuv2packed1 = yuv2rgba64le_1_c;
  1973.                 *yuv2packed2 = yuv2rgba64le_2_c;
  1974.                 *yuv2packedX = yuv2rgba64le_X_c;
  1975.             } else
  1976. #endif /* CONFIG_SWSCALE_ALPHA */
  1977.             {
  1978.                 *yuv2packed1 = yuv2rgbx64le_1_c;
  1979.                 *yuv2packed2 = yuv2rgbx64le_2_c;
  1980.                 *yuv2packedX = yuv2rgbx64le_X_c;
  1981.             }
  1982.             break;
  1983.         case AV_PIX_FMT_RGBA64BE:
  1984. #if CONFIG_SWSCALE_ALPHA
  1985.             if (c->alpPixBuf) {
  1986.                 *yuv2packed1 = yuv2rgba64be_1_c;
  1987.                 *yuv2packed2 = yuv2rgba64be_2_c;
  1988.                 *yuv2packedX = yuv2rgba64be_X_c;
  1989.             } else
  1990. #endif /* CONFIG_SWSCALE_ALPHA */
  1991.             {
  1992.                 *yuv2packed1 = yuv2rgbx64be_1_c;
  1993.                 *yuv2packed2 = yuv2rgbx64be_2_c;
  1994.                 *yuv2packedX = yuv2rgbx64be_X_c;
  1995.             }
  1996.             break;
  1997.         case AV_PIX_FMT_RGB48LE:
  1998.             *yuv2packed1 = yuv2rgb48le_1_c;
  1999.             *yuv2packed2 = yuv2rgb48le_2_c;
  2000.             *yuv2packedX = yuv2rgb48le_X_c;
  2001.             break;
  2002.         case AV_PIX_FMT_RGB48BE:
  2003.             *yuv2packed1 = yuv2rgb48be_1_c;
  2004.             *yuv2packed2 = yuv2rgb48be_2_c;
  2005.             *yuv2packedX = yuv2rgb48be_X_c;
  2006.             break;
  2007.         case AV_PIX_FMT_BGR48LE:
  2008.             *yuv2packed1 = yuv2bgr48le_1_c;
  2009.             *yuv2packed2 = yuv2bgr48le_2_c;
  2010.             *yuv2packedX = yuv2bgr48le_X_c;
  2011.             break;
  2012.         case AV_PIX_FMT_BGR48BE:
  2013.             *yuv2packed1 = yuv2bgr48be_1_c;
  2014.             *yuv2packed2 = yuv2bgr48be_2_c;
  2015.             *yuv2packedX = yuv2bgr48be_X_c;
  2016.             break;
  2017.         case AV_PIX_FMT_RGB32:
  2018.         case AV_PIX_FMT_BGR32:
  2019. #if CONFIG_SMALL
  2020.             *yuv2packed1 = yuv2rgb32_1_c;
  2021.             *yuv2packed2 = yuv2rgb32_2_c;
  2022.             *yuv2packedX = yuv2rgb32_X_c;
  2023. #else
  2024. #if CONFIG_SWSCALE_ALPHA
  2025.                 if (c->alpPixBuf) {
  2026.                     *yuv2packed1 = yuv2rgba32_1_c;
  2027.                     *yuv2packed2 = yuv2rgba32_2_c;
  2028.                     *yuv2packedX = yuv2rgba32_X_c;
  2029.                 } else
  2030. #endif /* CONFIG_SWSCALE_ALPHA */
  2031.                 {
  2032.                     *yuv2packed1 = yuv2rgbx32_1_c;
  2033.                     *yuv2packed2 = yuv2rgbx32_2_c;
  2034.                     *yuv2packedX = yuv2rgbx32_X_c;
  2035.                 }
  2036. #endif /* !CONFIG_SMALL */
  2037.             break;
  2038.         case AV_PIX_FMT_RGB32_1:
  2039.         case AV_PIX_FMT_BGR32_1:
  2040. #if CONFIG_SMALL
  2041.                 *yuv2packed1 = yuv2rgb32_1_1_c;
  2042.                 *yuv2packed2 = yuv2rgb32_1_2_c;
  2043.                 *yuv2packedX = yuv2rgb32_1_X_c;
  2044. #else
  2045. #if CONFIG_SWSCALE_ALPHA
  2046.                 if (c->alpPixBuf) {
  2047.                     *yuv2packed1 = yuv2rgba32_1_1_c;
  2048.                     *yuv2packed2 = yuv2rgba32_1_2_c;
  2049.                     *yuv2packedX = yuv2rgba32_1_X_c;
  2050.                 } else
  2051. #endif /* CONFIG_SWSCALE_ALPHA */
  2052.                 {
  2053.                     *yuv2packed1 = yuv2rgbx32_1_1_c;
  2054.                     *yuv2packed2 = yuv2rgbx32_1_2_c;
  2055.                     *yuv2packedX = yuv2rgbx32_1_X_c;
  2056.                 }
  2057. #endif /* !CONFIG_SMALL */
  2058.                 break;
  2059.         case AV_PIX_FMT_RGB24:
  2060.             *yuv2packed1 = yuv2rgb24_1_c;
  2061.             *yuv2packed2 = yuv2rgb24_2_c;
  2062.             *yuv2packedX = yuv2rgb24_X_c;
  2063.             break;
  2064.         case AV_PIX_FMT_BGR24:
  2065.             *yuv2packed1 = yuv2bgr24_1_c;
  2066.             *yuv2packed2 = yuv2bgr24_2_c;
  2067.             *yuv2packedX = yuv2bgr24_X_c;
  2068.             break;
  2069.         case AV_PIX_FMT_RGB565LE:
  2070.         case AV_PIX_FMT_RGB565BE:
  2071.         case AV_PIX_FMT_BGR565LE:
  2072.         case AV_PIX_FMT_BGR565BE:
  2073.             *yuv2packed1 = yuv2rgb16_1_c;
  2074.             *yuv2packed2 = yuv2rgb16_2_c;
  2075.             *yuv2packedX = yuv2rgb16_X_c;
  2076.             break;
  2077.         case AV_PIX_FMT_RGB555LE:
  2078.         case AV_PIX_FMT_RGB555BE:
  2079.         case AV_PIX_FMT_BGR555LE:
  2080.         case AV_PIX_FMT_BGR555BE:
  2081.             *yuv2packed1 = yuv2rgb15_1_c;
  2082.             *yuv2packed2 = yuv2rgb15_2_c;
  2083.             *yuv2packedX = yuv2rgb15_X_c;
  2084.             break;
  2085.         case AV_PIX_FMT_RGB444LE:
  2086.         case AV_PIX_FMT_RGB444BE:
  2087.         case AV_PIX_FMT_BGR444LE:
  2088.         case AV_PIX_FMT_BGR444BE:
  2089.             *yuv2packed1 = yuv2rgb12_1_c;
  2090.             *yuv2packed2 = yuv2rgb12_2_c;
  2091.             *yuv2packedX = yuv2rgb12_X_c;
  2092.             break;
  2093.         case AV_PIX_FMT_RGB8:
  2094.         case AV_PIX_FMT_BGR8:
  2095.             *yuv2packed1 = yuv2rgb8_1_c;
  2096.             *yuv2packed2 = yuv2rgb8_2_c;
  2097.             *yuv2packedX = yuv2rgb8_X_c;
  2098.             break;
  2099.         case AV_PIX_FMT_RGB4:
  2100.         case AV_PIX_FMT_BGR4:
  2101.             *yuv2packed1 = yuv2rgb4_1_c;
  2102.             *yuv2packed2 = yuv2rgb4_2_c;
  2103.             *yuv2packedX = yuv2rgb4_X_c;
  2104.             break;
  2105.         case AV_PIX_FMT_RGB4_BYTE:
  2106.         case AV_PIX_FMT_BGR4_BYTE:
  2107.             *yuv2packed1 = yuv2rgb4b_1_c;
  2108.             *yuv2packed2 = yuv2rgb4b_2_c;
  2109.             *yuv2packedX = yuv2rgb4b_X_c;
  2110.             break;
  2111.         }
  2112.     }
  2113.     switch (dstFormat) {
  2114.     case AV_PIX_FMT_MONOWHITE:
  2115.         *yuv2packed1 = yuv2monowhite_1_c;
  2116.         *yuv2packed2 = yuv2monowhite_2_c;
  2117.         *yuv2packedX = yuv2monowhite_X_c;
  2118.         break;
  2119.     case AV_PIX_FMT_MONOBLACK:
  2120.         *yuv2packed1 = yuv2monoblack_1_c;
  2121.         *yuv2packed2 = yuv2monoblack_2_c;
  2122.         *yuv2packedX = yuv2monoblack_X_c;
  2123.         break;
  2124.     case AV_PIX_FMT_YUYV422:
  2125.         *yuv2packed1 = yuv2yuyv422_1_c;
  2126.         *yuv2packed2 = yuv2yuyv422_2_c;
  2127.         *yuv2packedX = yuv2yuyv422_X_c;
  2128.         break;
  2129.     case AV_PIX_FMT_UYVY422:
  2130.         *yuv2packed1 = yuv2uyvy422_1_c;
  2131.         *yuv2packed2 = yuv2uyvy422_2_c;
  2132.         *yuv2packedX = yuv2uyvy422_X_c;
  2133.         break;
  2134.     }
  2135. }
  2136.