colorcvt.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:289k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: colorcvt.c,v 1.2.42.1 2004/07/09 02:00:18 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. /* standard libraries to use: */
  50. #include <string.h>
  51. #include <math.h>
  52. #include "hxtypes.h"
  53. /* some math. constants: */
  54. #ifndef M_PI
  55. #define M_PI      3.14159265358979323846
  56. #endif
  57. #ifndef M_SQRT2
  58. #define M_SQRT2   1.41421356237309504880
  59. #endif
  60. /* fast rounding to a nearest integer: */
  61. #if _M_IX86
  62. static __inline int INT(double a)
  63. {
  64.     int ia;
  65.     __asm   fld     a
  66.     __asm   fistp   ia
  67.     return ia;
  68. }
  69. #elif defined(__i386) && defined(_LINUX) 
  70. static inline int INT(double a)
  71. {
  72.     int ia;
  73.     __asm__ (
  74.         " fldl %1; "
  75.         " fistpl %0; "
  76.         : "=m"(ia)
  77.         : "m"(a)
  78.         : "memory", "st"
  79.         );
  80.        
  81.     return ia;
  82. }
  83. #else
  84. #define INT(a) ((int) (((a)<0)? ((a)-0.5): ((a)+0.5)))
  85. #endif
  86. /* macros to check big/little endiannes of the system: */
  87. #ifdef _MACINTOSH
  88. const static union {char c[4]; UINT32 l;} _1234 = {'01020304'}; /* Flawfinder: ignore */
  89. #else
  90. const static union {char c[4]; UINT32 l;} _1234 = {"01020304"}; /* Flawfinder: ignore */
  91. #endif
  92. #define BIG_ENDIAN      (_1234.l == 0x01020304)
  93. #define LITTLE_ENDIAN   (_1234.l == 0x04030201)
  94. /* get our interface: */
  95. #include "colorcvt.h"
  96. /*
  97.  * CCIR Rec. 601-2 definition of YCrCb color space.
  98.  *
  99.  * Given a primary analogue RGB signal (R,G,and B components are in the
  100.  * range of 0..1 volt), the luminance signal is defined as:
  101.  *      Y = 0.299 R + 0.587 G + 0.114 B.
  102.  * Signals of color-defferences, are therefore:
  103.  *      (R-Y) = 0.701 R - 0.587 G - 0.114 B, and
  104.  *      (B-Y) = -0.299 R - 0.587 G + 0.886 B.
  105.  * Using normalization (we want (R-Y) and (B-Y) to be in the range of
  106.  * -0.5..0.5 volt), we will obtain:
  107.  *      Cr = 0.5/0.701 (R-Y), and
  108.  *      Cb = 0.5/0.886 (B-Y).
  109.  * Finally, the quantized versions of Y,Cr,and Cb are defined as:
  110.  *      Y'  = 219 Y + 16,
  111.  *      Cr' = 224 Cr + 128, and
  112.  *      Cb' = 224 Cb + 128.
  113.  *
  114.  * For convenience, we will use the following names for these constants
  115.  * (here and below: V = Cr, and U = Cb):
  116.  */
  117. #define CCIR601_YRCOEF  0.299
  118. #define CCIR601_YGCOEF  0.587
  119. #define CCIR601_YBCOEF  0.114
  120. #define CCIR601_YMAX    219
  121. #define CCIR601_YMED    ((double)CCIR601_YMAX/2.)
  122. #define CCIR601_YOFFSET 16
  123. #define CCIR601_VMAX    224
  124. #define CCIR601_VOFFSET 128
  125. #define CCIR601_UMAX    224
  126. #define CCIR601_UOFFSET 128
  127. /*
  128.  * Also, we typically will deal with quantized R'G'B' signal, represented
  129.  * by 8-bit quantities for R', G' and B' components:
  130.  */
  131. #define RGB_MAX 255
  132. /*
  133.  * Forward R'G'B'->Y'Cr'Cb' conversion:
  134.  *  a) calculate Y":
  135.  *      Y" = 0.299 R' + 0.587 G' + 0.114 B'; => 3 muls/lookups
  136.  *  b) calculate Y',Cr',Cb' values:
  137.  *      Y'  = 219/255 Y" + 16;     => 1 mul/lookup
  138.  *      Cr' = 224/255 * 0.5/0.701 (R'-Y") + 128; => 1 mul/lookup
  139.  *      Cb' = 224/255 * 0.5/0.886 (B'-Y") + 128; => 1 mul/lookup
  140.  */
  141. #define YSCALE  ((double)CCIR601_YMAX/RGB_MAX)
  142. #define VSCALE  ((double)CCIR601_VMAX/RGB_MAX * 0.5/(1.-CCIR601_YRCOEF))
  143. #define USCALE  ((double)CCIR601_UMAX/RGB_MAX * 0.5/(1.-CCIR601_YBCOEF))
  144. #define YMAX    (RGB_MAX + 3)       /* include max. rounding error */
  145. #define VMAX    (int)((double)(1.-CCIR601_YRCOEF) * RGB_MAX + 1)
  146. #define VMIN    VMAX
  147. #define UMAX    (int)((double)(1.-CCIR601_YBCOEF) * RGB_MAX + 1)
  148. #define UMIN    UMAX
  149. /* R'G'B' -> Y'Cr'Cb' conversion tables: */
  150. static int yrtab [RGB_MAX+1], ygtab [RGB_MAX+1], ybtab [RGB_MAX+1];
  151. static int yytab [YMAX+1], vrytab [VMIN+VMAX+1], ubytab [UMIN+UMAX+1];
  152. /*
  153.  * Backward Y'Cr'Cb'->R'G'B' conversion:
  154.  *  a) calculate Y":
  155.  *      Y"  = 1/(219/255) (Y'-16);     => 1 mul/lookup
  156.  *  b) calculate R'B':
  157.  *      R'  = Y" + 1/(224/255 * 0.5/0.701) (Cr'-128); => 1 mul/lookup
  158.  *      B'  = Y" + 1/(224/255 * 0.5/0.886) (Cb'-128);  => 1 mul/lookup
  159.  *  c) calculate G':
  160.  *      G'  = 1/0.587 (Y" - 0.299 R' - 0.114 B') =
  161.  *          = Y" - 0.299/0.587/(224/255 * 0.5/0.701) (Cr'-128)
  162.  *               - 0.114/0.587/(224/255 * 0.5/0.886) (Cb'-128); => 2 muls/luts
  163.  */
  164. #define YCOEF   (1/YSCALE)
  165. #define RVCOEF  (1/VSCALE)
  166. #define GVCOEF  (-CCIR601_YRCOEF/CCIR601_YGCOEF/VSCALE)
  167. #define GUCOEF  (-CCIR601_YBCOEF/CCIR601_YGCOEF/USCALE)
  168. #define BUCOEF  (1/USCALE)
  169. /* Y'Cr'Cb'->R'G'B' conversion tables: */
  170. static int ytab  [RGB_MAX+1], rvtab [RGB_MAX+1], gvtab [RGB_MAX+1];
  171. static int gutab [RGB_MAX+1], butab [RGB_MAX+1];
  172. static int rutab [RGB_MAX+1], bvtab [RGB_MAX+1]; /* alpha != 0 */
  173. /*
  174.  * Color adjustments.
  175.  *  a) hue: in NTSC YUV color space, the hue adjustment is equivalent
  176.  *    to the UV axes rotation:
  177.  *      V' = V cos(alpha) - U sin(alpha);
  178.  *      U' = V sin(alpha) + U cos(alpha);
  179.  *    where:
  180.  *      V = (R-Y)/1.14;
  181.  *      U = (B-Y)/2.03;
  182.  *    In YCrCb color space, this will be equivalent to:
  183.  *      Cr' - 128 = (Cr - 128) cos(alpha) - zeta (Cb - 128) sin(alpha));.
  184.  *      Cb' - 128 = xi (Cr - 128) sin(alpha) + (Cb - 128) cos(alpha);
  185.  *    where:
  186.  *      xi   = (1./(0.5/0.701)/1.14)/(1./(0.5/0.886)/2.03);
  187.  *      zeta = 1/xi;
  188.  *  b) saturation:
  189.  *      Cr' - 128 = beta (Cr - 128);
  190.  *      Cb' - 128 = beta (Cb - 128);
  191.  *  c) brightness:
  192.  *      Y' - 16 = gamma (Y - 16);
  193.  *      Cr' - 128 = gamma (Cr - 128);
  194.  *      Cb' - 128 = gamma (Cb - 128);
  195.  *  d) contrast:
  196.  *      Y' - 16 = lambda + kappa (Y - 16);
  197.  *  e) all together:
  198.  *      Y' - 16   = gamma (lambda + kappa (Y - 16));
  199.  *      Cr' - 128 = gamma beta ((Cr - 128) cos(alpha) - zeta (Cb - 128) sin(alpha));
  200.  *      Cb' - 128 = gamma beta (xi (Cr - 128) sin(alpha) + (Cb - 128) cos(alpha));
  201.  */
  202. #define XI      (((1.-CCIR601_YRCOEF)/0.5/1.14)/((1.-CCIR601_YBCOEF)/0.5/2.03))
  203. #define ZETA    (1./XI)
  204. /* empirically choosen limits for color adjustments: */
  205. #define ALPHA_MAX   (M_PI*3/4)
  206. #define ALPHA_MED   0.              /* hue */
  207. #define ALPHA_MIN   (-M_PI*3/4)
  208. #define BETA_MAX    M_SQRT2
  209. #define BETA_MED    1.              /* saturation */
  210. #define BETA_MIN    (M_SQRT2/4)
  211. #define GAMMA_MAX   M_SQRT2
  212. #define GAMMA_MED   1.              /* brightness */
  213. #define GAMMA_MIN   0.5
  214. #define KAPPA_MIN   0.5
  215. #define KAPPA_MED   1.              /* contrast */
  216. #define KAPPA_MAX   2.
  217. #define LAMBDA(kappa)   (CCIR601_YMED * (1. - kappa))
  218. /* current color adjustment parameters: */
  219. static float cur_brightness, cur_contrast, cur_saturation, cur_hue;
  220. static int is_alpha, is_beta, is_gamma, is_kappa;
  221. static int color_conversion_tables_inited = 0;
  222. /* Y'Cr'Cb'->Y'Cr'Cb' conversion tables: */
  223. static int _yytab [RGB_MAX+1], _uutab [RGB_MAX+1], _vvtab [RGB_MAX+1];
  224. static int _uvtab [RGB_MAX+1], _vutab [RGB_MAX+1]; /* alpha != 0: */
  225. /*
  226.  * Clipping & dithering:
  227.  *
  228.  * Note: the CLIPNEG/CLIPPOS numbers are somewhat rounded values
  229.  *  that correspond to current GAMMA_MAX,KAPPA_MAX, and BETA_MAX
  230.  *  parameters. If you are planning to modify any of these, the
  231.  *  ranges of the clip tables shall be adjusted as well.
  232.  */
  233. #define CLIPRNG 256                 /* unclipped range */
  234. #define CLIPNEG (288 * 4)           /* rounded max neg. value */
  235. #define CLIPPOS (288 * 4)           /* rounded max shot over 256 */
  236. #define CLIP4 (clip4+CLIPNEG)       /* offset into clip4 */
  237. #define CLIP5 (clip5+CLIPNEG)       /* offset into clip5 */
  238. #define CLIP6 (clip6+CLIPNEG)       /* offset into clip6 */
  239. #define CLIP8 (clip8+CLIPNEG)       /* offset into clip8 */
  240. /* actual clip tables */
  241. static unsigned char clip4 [CLIPNEG+CLIPRNG+CLIPPOS]; /* clip/round to 4 bits */ /* Flawfinder: ignore */
  242. static unsigned char clip5 [CLIPNEG+CLIPRNG+CLIPPOS]; /* clip/round to 5 bits */ /* Flawfinder: ignore */
  243. static unsigned char clip6 [CLIPNEG+CLIPRNG+CLIPPOS]; /* clip/round to 6 bits */ /* Flawfinder: ignore */
  244. static unsigned char clip8 [CLIPNEG+CLIPRNG+CLIPPOS]; /* clip to 8 bits */ /* Flawfinder: ignore */
  245. /* 2-level, 2x2 dither noise, added before rounding to 333/555/565.
  246.  * Define NO_DITHER to disable. */
  247. #ifndef NO_DITHER
  248. #define DITH3L  8   /* 16 - 8 */
  249. #define DITH3H  24  /* 16 + 8 */
  250. #define DITH4L  4   /* 8 - 4 */
  251. #define DITH4H  12  /* 8 + 4 */
  252. #define DITH5L  2   /* 4 - 2 */
  253. #define DITH5H  6   /* 4 + 2 */
  254. #define DITH6L  1   /* 2 - 1 */
  255. #define DITH6H  3   /* 2 + 1 */
  256. #else /* disabled */
  257. #define DITH3L  16  /* does (i+16)>>5 for proper rounding */
  258. #define DITH3H  16
  259. #define DITH4L  8   /* does (i+8)>>4 for proper rounding */
  260. #define DITH4H  8
  261. #define DITH5L  4   /* does (i+4)>>3 for proper rounding */
  262. #define DITH5H  4
  263. #define DITH6L  2   /* does (i+2)>>2 for proper rounding */
  264. #define DITH6H  2
  265. #endif
  266. /* speeds-up calculation of distance between pixels: */
  267. #define SQ  (sq+RGB_MAX+1)
  268. static unsigned int sq [RGB_MAX+1+RGB_MAX];
  269. /* palette color maps: */
  270. extern unsigned char pmap [1U << (4+4+4)];  /* 4-bits per channel */ /* Flawfinder: ignore */
  271. /* default palette to use: */
  272. static unsigned int default_palette [RGB_MAX+1] = {
  273.     0x000000, 0x000080, 0x008000, 0x008080, 0x800000, 0x800080, 0x808000, 0xC0C0C0,
  274.     0xC0DCC0, 0xF0CAA6, 0x040404, 0x080808, 0x0C0C0C, 0x111111, 0x161616, 0x1C1C1C,
  275.     0x222222, 0x292929, 0x555555, 0x4D4D4D, 0x424242, 0x393939, 0x818181, 0x000081,
  276.     0x008100, 0x008181, 0x810000, 0x810081, 0x818100, 0x000033, 0x000066, 0x000099,
  277.     0x0000CC, 0x003300, 0x003333, 0x003366, 0x003399, 0x0033CC, 0x0033FF, 0x006600,
  278.     0x006633, 0x006666, 0x006699, 0x0066CC, 0x0066FF, 0x009900, 0x009933, 0x009966,
  279.     0x009999, 0x0099CC, 0x0099FF, 0x00CC00, 0x00CC33, 0x00CC66, 0x00CC99, 0x00CCCC,
  280.     0x00CCFF, 0x00FF66, 0x00FF99, 0x00FFCC, 0x330000, 0x330033, 0x330066, 0x330099,
  281.     0x3300CC, 0x3300FF, 0x333300, 0x333333, 0x333366, 0x333399, 0x3333CC, 0x3333FF,
  282.     0x336600, 0x336633, 0x336666, 0x336699, 0x3366CC, 0x3366FF, 0x339900, 0x339933,
  283.     0x339966, 0x339999, 0x3399CC, 0x3399FF, 0x33CC00, 0x33CC33, 0x33CC66, 0x33CC99,
  284.     0x33CCCC, 0x33CCFF, 0x33FF33, 0x33FF66, 0x33FF99, 0x33FFCC, 0x33FFFF, 0x660000,
  285.     0x660033, 0x660066, 0x660099, 0x6600CC, 0x6600FF, 0x663300, 0x663333, 0x663366,
  286.     0x663399, 0x6633CC, 0x6633FF, 0x666600, 0x666633, 0x666666, 0x666699, 0x6666CC,
  287.     0x669900, 0x669933, 0x669966, 0x669999, 0x6699CC, 0x6699FF, 0x66CC00, 0x66CC33,
  288.     0x66CC99, 0x66CCCC, 0x66CCFF, 0x66FF00, 0x66FF33, 0x66FF99, 0x66FFCC, 0xCC00FF,
  289.     0xFF00CC, 0x999900, 0x993399, 0x990099, 0x9900CC, 0x990000, 0x993333, 0x990066,
  290.     0x9933CC, 0x9900FF, 0x996600, 0x996633, 0x993366, 0x996699, 0x9966CC, 0x9933FF,
  291.     0x999933, 0x999966, 0x999999, 0x9999CC, 0x9999FF, 0x99CC00, 0x99CC33, 0x66CC66,
  292.     0x99CC99, 0x99CCCC, 0x99CCFF, 0x99FF00, 0x99FF33, 0x99CC66, 0x99FF99, 0x99FFCC,
  293.     0x99FFFF, 0xCC0000, 0x990033, 0xCC0066, 0xCC0099, 0xCC00CC, 0x993300, 0xCC3333,
  294.     0xCC3366, 0xCC3399, 0xCC33CC, 0xCC33FF, 0xCC6600, 0xCC6633, 0x996666, 0xCC6699,
  295.     0xCC66CC, 0x9966FF, 0xCC9900, 0xCC9933, 0xCC9966, 0xCC9999, 0xCC99CC, 0xCC99FF,
  296.     0xCCCC00, 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCCC, 0xCCCCFF, 0xCCFF00, 0xCCFF33,
  297.     0x99FF66, 0xCCFF99, 0xCCFFCC, 0xCCFFFF, 0xCC0033, 0xFF0066, 0xFF0099, 0xCC3300,
  298.     0xFF3333, 0xFF3366, 0xFF3399, 0xFF33CC, 0xFF33FF, 0xFF6600, 0xFF6633, 0xCC6666,
  299.     0xFF6699, 0xFF66CC, 0xCC66FF, 0xFF9900, 0xFF9933, 0xFF9966, 0xFF9999, 0xFF99CC,
  300.     0xFF99FF, 0xFFCC00, 0xFFCC33, 0xFFCC66, 0xFFCC99, 0xFFCCCC, 0xFFCCFF, 0xFFFF33,
  301.     0xCCFF66, 0xFFFF99, 0xFFFFCC, 0x6666FF, 0x66FF66, 0x66FFFF, 0xFF6666, 0xFF66FF,
  302.     0xFFFF66, 0xC1C1C1, 0x5F5F5F, 0x777777, 0x868686, 0x969696, 0xCBCBCB, 0xB2B2B2,
  303.     0xD7D7D7, 0xDDDDDD, 0xE3E3E3, 0xEAEAEA, 0xF1F1F1, 0xF8F8F8, 0xF0FBFF, 0xA4A0A0,
  304.     0x808080, 0x0000FF, 0x00FF00, 0x00FFFF, 0xFF0000, 0xFF00FF, 0xFFFF00, 0xFFFFFF
  305. };
  306. int default_palette_idx [RGB_MAX+1] = {
  307.     0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,
  308.     16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
  309.     32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
  310.     48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,
  311.     64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
  312.     80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
  313.     96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  314.     112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
  315.     128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
  316.     144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
  317.     160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
  318.     176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
  319.     192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
  320.     208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
  321.     224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
  322.     240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
  323. };
  324. /*
  325.  * Bytes-per-pixel, for readability:
  326.  */
  327. #define BPP1    1
  328. #define BPP2    2
  329. #define BPP3    3
  330. #define BPP4    4
  331. #if defined (_MACINTOSH) && defined (_DEBUG)
  332. #pragma global_optimizer on
  333. #endif
  334. /*
  335.  * Convert a value in the range of [-1,1],
  336.  * to a new range [l,h]; with a middle value equal to m.
  337.  */
  338. static double chrange (double x, double l, double m, double h)
  339. {
  340.     if (x >= 0.) {
  341.         if (x > 1.) x = 1.;
  342.         x = m + (h - m) * x;
  343.     } else {
  344.         if (x < -1.) x = -1.;
  345.         x = m + (m - l) * x;
  346.     }
  347.     return x;
  348. }
  349. /*
  350.  * Checks if variable is signicantly different from zero.
  351.  */
  352. static int is (double val)
  353. {
  354.     return fabs(val) > 0.01;    /* < 1% is not considered a change */
  355. }
  356. /*
  357.  * Returns current state of "from/to I420" converters.
  358.  * Use:
  359.  *  void GetSrcI420Colors (float *brightness, float *contrast, float *saturation, float *hue);
  360.  * Output:
  361.  *  brightness - brightness adjustment [-1,1], 0 - default;
  362.  *  contrast   - contrast adjustment   [-1,1], 0 - default;
  363.  *  saturation - saturation adjustment [-1,1], 0 - default;
  364.  *  hue        - hue adjustment        [-1,1], 0 - default;
  365.  * Returns:
  366.  *  none.
  367.  */
  368. void GetSrcI420Colors (float *brightness, float *contrast, float *saturation, float *hue)
  369. {
  370.     if (brightness && contrast && saturation && hue)
  371.     {
  372. *brightness = cur_brightness;
  373. *contrast   = cur_contrast;
  374. *saturation = cur_saturation;
  375. *hue     = cur_hue;
  376.     }
  377. }
  378. /*
  379.  * Initializes "from/to I420" converters.
  380.  * Use:
  381.  *  void SetSrcI420Colors (float brightness, float contrast, float saturation, float hue);
  382.  *  void SetDestI420Colors (float brightness, float contrast, float saturation, float hue);
  383.  * Input:
  384.  *  brightness - brightness adjustment [-1,1], 0 - default;
  385.  *  contrast   - contrast adjustment   [-1,1], 0 - default;
  386.  *  saturation - saturation adjustment [-1,1], 0 - default;
  387.  *  hue        - hue adjustment        [-1,1], 0 - default;
  388.  * Returns:
  389.  *  none.
  390.  */
  391. void SetSrcI420Colors (float brightness, float contrast, float saturation, float hue)
  392. {
  393.     /* check if we need to generate new color conversion tables: */
  394.     if (!color_conversion_tables_inited  ||
  395.         is (cur_brightness - brightness) ||
  396.         is (cur_contrast - contrast)     ||
  397.         is (cur_saturation - saturation) ||
  398.         is (cur_hue - hue)) {
  399.         double alpha, beta, gamma, kappa, lambda;
  400.         double cos_alpha, xi_sin_alpha, minus_zeta_sin_alpha;
  401.         register int i;
  402.         /* hue: */
  403.         alpha = chrange (hue, ALPHA_MIN, ALPHA_MED, ALPHA_MAX);
  404.         cos_alpha = cos (alpha);
  405.         xi_sin_alpha = XI * sin (alpha);
  406.         minus_zeta_sin_alpha = -ZETA * sin (alpha);
  407.         is_alpha = is (cur_hue = hue);
  408.         /* saturation: */
  409.         beta = chrange (saturation, BETA_MIN, BETA_MED, BETA_MAX);
  410.         is_beta = is (cur_saturation = saturation);
  411.         /* brightness: */
  412.         gamma = chrange (brightness, GAMMA_MIN, GAMMA_MED, GAMMA_MAX);
  413.         is_gamma = is (cur_brightness = brightness);
  414.         /* contrast: */
  415.         kappa = chrange (contrast, KAPPA_MIN, KAPPA_MED, KAPPA_MAX);
  416.         lambda = LAMBDA (kappa);
  417.         is_kappa = is (cur_contrast = contrast);
  418.         /*
  419.          * Check if we need to generate clip tables & default palette:
  420.          */
  421.         if (!color_conversion_tables_inited) {
  422.             /* Init clip tables. CLIP4/5/6 includes chop to 3/5/6 bits */
  423.             for (i = -CLIPNEG; i < CLIPRNG + CLIPPOS; i++) {
  424.                 if (i < 0) {
  425.                     CLIP4[i] = 0;
  426.                     CLIP5[i] = 0;
  427.                     CLIP6[i] = 0;           /* clip */
  428.                     CLIP8[i] = 0;
  429.                 } else if (i > 255) {
  430.                     CLIP4[i] = 255 >> 4;
  431.                     CLIP5[i] = 255 >> 3;
  432.                     CLIP6[i] = 255 >> 2;    /* clip */
  433.                     CLIP8[i] = 255;
  434.                 } else {
  435.                     CLIP4[i] = i >> 4;      /* chop to 4 bits */
  436.                     CLIP5[i] = i >> 3;      /* chop to 5 bits */
  437.                     CLIP6[i] = i >> 2;      /* chop to 6 bits */
  438.                     CLIP8[i] = i;           /* leave at 8 bits */
  439.                 }
  440.             }
  441.             /* square values: */
  442.             for (i = -RGB_MAX; i <= RGB_MAX; i ++)
  443.                 SQ[i] = i * i;
  444.             /* set default palette: */
  445.             SetDestRGB8Palette (256, default_palette, default_palette_idx);
  446.             /* set indicator: */
  447.             color_conversion_tables_inited ++;
  448.         }
  449.         /*
  450.          * Initialize color conversion tables.
  451.          */
  452.         for (i = 0; i < 256; i++) {
  453.             /* Y'Cr'Cb'->R'G'B' conversion tables: */
  454.             double y = lambda + (i - CCIR601_YOFFSET) * kappa; /* adjust contrast */
  455.             if (y < 0) y = 0; else if (y > CCIR601_YMAX) y = CCIR601_YMAX;
  456.             ytab  [i] = INT(y * YCOEF * gamma);
  457.             rvtab [i] = INT((i-CCIR601_VOFFSET) * cos_alpha * RVCOEF * beta * gamma);
  458.             gvtab [i] = INT((i-CCIR601_VOFFSET) * GVCOEF * beta * gamma);
  459.             bvtab [i] = INT((i-CCIR601_VOFFSET) * xi_sin_alpha * BUCOEF * beta * gamma);
  460.             rutab [i] = INT((i-CCIR601_UOFFSET) * minus_zeta_sin_alpha * RVCOEF * beta * gamma);
  461.             gutab [i] = INT((i-CCIR601_UOFFSET) * GUCOEF * beta * gamma);
  462.             butab [i] = INT((i-CCIR601_UOFFSET) * cos_alpha * BUCOEF * beta * gamma);
  463.             /* Y'Cr'Cb'->Y'Cr'Cb' conversion tables: */
  464.             y = lambda + (i - CCIR601_YOFFSET) * kappa;
  465.             _yytab [i] = CLIP8 [CCIR601_YOFFSET + INT(y * gamma)];
  466.             _vvtab [i] = CCIR601_VOFFSET + INT((i-CCIR601_VOFFSET) * cos_alpha * beta * gamma);
  467.             _uutab [i] = CCIR601_UOFFSET + INT((i-CCIR601_UOFFSET) * cos_alpha * beta * gamma);
  468.             _vutab [i] = INT((i-CCIR601_UOFFSET) * minus_zeta_sin_alpha * beta * gamma);
  469.             _uvtab [i] = INT((i-CCIR601_VOFFSET) * xi_sin_alpha * beta * gamma);
  470.             if (!is_alpha) {
  471.                 _vvtab [i] = CLIP8 [_vvtab [i]];
  472.                 _uutab [i] = CLIP8 [_uutab [i]];
  473.             }
  474.         }
  475.     }
  476. }
  477. void SetDestI420Colors (float brightness, float contrast, float saturation, float hue)
  478. {
  479.     /* Currently, all color adjustment parameters are ignored,
  480.      * and tables will always be initialized for CCIR 601-2 - compliant
  481.      * color conversion. */
  482.     register int i, j;
  483.     /* initialize y*tab[] tables: */
  484.     for (i = 0; i <= RGB_MAX; i++) {
  485.         yrtab [i] = INT((double)i * CCIR601_YRCOEF);
  486.         ygtab [i] = INT((double)i * CCIR601_YGCOEF);
  487.         ybtab [i] = INT((double)i * CCIR601_YBCOEF);
  488.     }
  489.     /* initialize yytab[]: */
  490.     for (i = 0; i <= YMAX; i++) {
  491.         j = INT((double)i * YSCALE);
  492.         if (j > CCIR601_YMAX) j = CCIR601_YMAX;
  493.         yytab [i] = j + CCIR601_YOFFSET;
  494.     }
  495.     /* initialize vrytab[]: */
  496.     for (i = -VMIN; i <= VMAX; i++) {
  497.         j = INT((double)i * VSCALE);
  498.         if (j < -CCIR601_VMAX/2) j = -CCIR601_VMAX/2;
  499.         if (j >  CCIR601_VMAX/2) j =  CCIR601_VMAX/2;
  500.         vrytab [VMIN+i] = j + CCIR601_VOFFSET;
  501.     }
  502.     /* initialize ubytab[]: */
  503.     for (i = -UMIN; i <= UMAX; i++) {
  504.         j = INT((double)i * USCALE);
  505.         if (j < -CCIR601_UMAX/2) j = -CCIR601_UMAX/2;
  506.         if (j >  CCIR601_UMAX/2) j =  CCIR601_UMAX/2;
  507.         ubytab [UMIN+i] = j + CCIR601_UOFFSET;
  508.     }
  509. }
  510. /*
  511.  * Suggest palettes to use for 8-bit RGB formats.
  512.  * Use:
  513.  *  int SuggestSrcRGB8Palette (int nColors, unsigned int *lpRGBVals);
  514.  *  int SuggestDestRGB8Palette (int nColors, unsigned int *lpRGBVals);
  515.  * Input:
  516.  *  nColors - the number of existing colors in palette
  517.  *  lpRGBVals - RGB values for each palette entry
  518.  *  lpIndices - pixel values (palette indices)
  519.  * Returns:
  520.  *  >0, the total number of colors to be used, if success
  521.  *  -1, if error
  522.  */
  523. int SuggestSrcRGB8Palette (int nColors, unsigned int *lpRGBVals)
  524. {
  525.     return -1;    /* not implemented yet... */
  526. }
  527. int SuggestDestRGB8Palette (int nColors, unsigned int *lpRGBVals)
  528. {
  529.     unsigned int rgb;
  530.     int r, g, b, i, j, delta;
  531.     /* determine the quanization step size: */
  532.     if      (256 - nColors >= 6*6*6)    delta = 0x33;   /* 6x6x6 = 216 */
  533.     else if (256 - nColors >= 5*5*5)    delta = 0x40;   /* 5x5x5 = 125 */
  534.     else if (256 - nColors >= 4*4*4)    delta = 0x55;   /* 4x4x4 = 64  */
  535.     else return nColors;
  536.     /* complement the set of palette entries with ours: */
  537.     i = nColors;
  538.     for (r = 0; r <= 256; r += delta) { if (r == 256) r = 255;
  539.     for (g = 0; g <= 256; g += delta) { if (g == 256) g = 255;
  540.     for (b = 0; b <= 256; b += delta) { if (b == 256) b = 255;
  541.         /* form palette entry: */
  542.         rgb = b | (g << 8) | (r << 16);
  543.         /* check if we had this color before: */
  544.         for (j = 0; j < nColors; j ++)  if (lpRGBVals[j] == rgb) goto skip;
  545.         /* add color: */
  546.         lpRGBVals[i] = rgb;
  547.         i ++;
  548. skip:   ;
  549.     }}}
  550.     /* return total # of entries used: */
  551.     return i;
  552. }
  553. /*
  554.  * Set palettes to use for 8-bit RGB formats.
  555.  * Use:
  556.  *  int SetSrcRGB8Palette (int nColors, unsigned int *lpRGBVals, int *lpIndices);
  557.  *  int SetDestRGB8Palette (int nColors, unsigned int *lpRGBVals, int *lpIndices);
  558.  * Input:
  559.  *  nColors - the number of colors in palette
  560.  *  lpRGBVals - RGB values for each palette entry
  561.  *  lpIndices - pixel values (palette indices)
  562.  * Returns:
  563.  *  >0, the total number of colors set, if success
  564.  *  -1, if error
  565.  */
  566. int SetSrcRGB8Palette (int nColors, unsigned int *lpRGBVals, int *lpIndices)
  567. {
  568.     return -1;    /* not implemented yet... */
  569. }
  570. int SetDestRGB8Palette (int nColors, unsigned int *lpRGBVals, int *lpIndices)
  571. {
  572.     register unsigned int r, g, b, delta = 1U << 4;
  573.     /* perform the minimum energy mismatch mapping: */
  574.     for (r = 0; r < 256; r += delta) {
  575.     for (g = 0; g < 256; g += delta) {
  576.     for (b = 0; b < 256; b += delta) {
  577.         /* initialize search: */
  578.         int idx, match_idx = 0;
  579.         unsigned int j, diff, match_diff;
  580.         j = lpRGBVals[0];
  581.         match_diff =
  582.             SQ[(int)(r - ((j >> 0)  & 0xFF))] +
  583.             SQ[(int)(g - ((j >> 8)  & 0xFF))] +
  584.             SQ[(int)(b - ((j >> 16) & 0xFF))];
  585.         /* find minimum: */
  586.         for (idx = 1; idx < nColors; idx ++) {
  587.             j = lpRGBVals[idx];
  588.             diff =
  589.                 SQ[(int)(r - ((j >> 0)  & 0xFF))] +
  590.                 SQ[(int)(g - ((j >> 8)  & 0xFF))] +
  591.                 SQ[(int)(b - ((j >> 16) & 0xFF))];
  592.             if (diff < match_diff) {
  593.                 match_idx = idx;
  594.                 match_diff = diff;
  595.             }
  596.         }
  597.         /* store the result: */
  598.         pmap[(b >> 4) | g | (r << 4)] = lpIndices[match_idx];
  599.     }}}
  600.     return nColors;
  601. }
  602. /*
  603.  * Checks format conversion parameters.
  604.  * Use:
  605.  *  int chk_args (unsigned char *dest_ptr, int dest_width, int dest_height,
  606.  *      int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  607.  *      unsigned char *src_ptr, int src_width, int src_height,
  608.  *      int src_pitch, int src_x, int src_y, int src_dx, int src_dy,
  609.  *      int *p_scale_x, int *p_scale_y);
  610.  * Input:
  611.  *  dest_ptr - pointer to a destination buffer
  612.  *  dest_width, dest_height - width/height of the destination image (pixels)
  613.  *  dest_pitch - pitch of the dest. buffer (in bytes; <0 - if bottom up image)
  614.  *  dest_x, dest_y, dest_dx, dest_dy - destination rectangle (pixels)
  615.  *  src_ptr - pointer to an input image
  616.  *  src_width, src_height - width/height of the input image (pixels)
  617.  *  src_pitch - pitch of the source buffer (in bytes; <0 - if bottom up image)
  618.  *  src_x, src_y, src_dx, src_dy - source rectangle (pixels)
  619.  * Output:
  620.  *  p_scale_x, p_scale_y - scale factors for x,y axes
  621.  *      (currently only 1:1, and 2:1 scale factors are allowed)
  622.  * Returns:
  623.  *  0 - if success; -1 if failure.
  624.  */
  625. static int
  626. chk_args (unsigned char *dest_ptr, int dest_width, int dest_height,
  627.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  628.     unsigned char *src_ptr, int src_width, int src_height,
  629.     int src_pitch, int src_x, int src_y, int src_dx, int src_dy,
  630.     int *p_scale_x, int *p_scale_y)
  631. {
  632.     /* alignments: */
  633.     if (((unsigned)dest_ptr & 3) || (dest_pitch & 3) ||
  634.         ((unsigned)src_ptr  & 3) || (src_pitch  & 3) ||
  635.     /* image sizes: */
  636.         dest_width <= 0 || dest_height <= 0 ||
  637.         src_width  <= 0 || src_height  <= 0 ||
  638.     /* rectangles: */
  639.         dest_x < 0 || dest_y < 0 || dest_dx <= 0 || dest_dy <= 0 ||
  640.         src_x  < 0 || src_y  < 0 || src_dx  <= 0 || src_dy  <= 0 ||
  641.     /* overlaps: */
  642.         dest_width < dest_x + dest_dx || dest_height < dest_y + dest_dy ||
  643.         src_width  < src_x  + src_dx  || src_height  < src_y  + src_dy)
  644.         goto fail;
  645.     /* scale factors: */
  646.     if (dest_dx == src_dx)          *p_scale_x = 1;
  647.     else if (dest_dx == 2 * src_dx) *p_scale_x = 2;
  648.     else goto fail;
  649.     if (dest_dy == src_dy)          *p_scale_y = 1;
  650.     else if (dest_dy == 2 * src_dy) *p_scale_y = 2;
  651.     else goto fail;
  652.     /* success: */
  653.     return 1;
  654.     /* failure: */
  655. fail:
  656.     return 0;
  657. }
  658. static int adjust_range (int *z1, int *dz1, int *z2, int *dz2, int inc2)
  659. {
  660.     /* skip odd start pixel: */
  661.     if (*z1 & 1) {
  662.         *z1 += 1;
  663.         *dz1 -= 1;
  664.         *z2 += inc2;
  665.         *dz2 -= inc2;
  666.     }
  667.     /* clip the range: */
  668.     if (*dz1 & 1) {
  669.         *dz1 -= 1;
  670.         *dz2 -= inc2;
  671.     }
  672.     return (*dz1 > 0 && *dz2 > 0);
  673. }
  674. /*
  675.  * Format-conversion routines.
  676.  * Use:
  677.  *  int XXXXtoYYYYEx (unsigned char *dest_ptr, int dest_width, int dest_height,
  678.  *      int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  679.  *      unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  680.  *      int src_x, int src_y, int src_dx, int src_dy);
  681.  * Input:
  682.  *  dest_ptr - pointer to a destination buffer
  683.  *  dest_width, dest_height - width/height of the destination image (pixels)
  684.  *  dest_pitch - pitch of the dest. buffer (in bytes; <0 - if bottom up image)
  685.  *  dest_x, dest_y, dest_dx, dest_dy - destination rectangle (pixels)
  686.  *  src_ptr - pointer to an input image
  687.  *  src_width, src_height - width/height of the input image (pixels)
  688.  *  src_pitch - pitch of the source buffer (in bytes; <0 - if bottom up image)
  689.  *  src_x, src_y, src_dx, src_dy - source rectangle (pixels)
  690.  * Returns:
  691.  *  0 - if success; -1 if failure.
  692.  * Notes:
  693.  *  a) In all cases, pointers to the source and destination buffers must be
  694.  *     DWORD aligned, and both pitch parameters must be multiple of 4!!!
  695.  *  b) Converters that deal with YUV 4:2:2, or 4:2:0 formats may also require
  696.  *     rectangle parameters (x,y,dx,dy) to be multiple of 2. Failure to provide
  697.  *     aligned rectangles will result in partially converted image.
  698.  *  c) Currently only scale factors of 1:1 and 2:1 are supported; if the rates
  699.  *     dest_dx/src_dx & dest_dy/src_dy are neither 1, or 2, the converters
  700.  *     will fail.
  701.  */
  702. /*
  703.  * I420toI420() converter:
  704.  */
  705. int I420toI420 (unsigned char *dest_ptr, int dest_width, int dest_height,
  706.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  707.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  708.     int src_x, int src_y, int src_dx, int src_dy)
  709. {
  710.     /* scale factors: */
  711.     int scale_x, scale_y;
  712.     /* check arguments: */
  713.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  714.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  715.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  716.         return -1;
  717.     /* remove odd destination pixels: */
  718.     if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x) ||
  719.         !adjust_range (&dest_y, &dest_dy, &src_y, &src_dy, scale_y))
  720.         return 0;
  721.     /* check if we have matching chroma components: */
  722.     if ((src_x & 1) || (src_y & 1))
  723.         return -1;                          /* can't shift chromas */
  724.     /* check if bottop-up images: */
  725.     if (dest_pitch <= 0 || src_pitch <= 0)
  726.         return -1;                          /* not supported for this format */
  727.     /* check if 1:1 scale: */
  728.     if (scale_x == 1 && scale_y == 1) {
  729.         /* check if no color adjustmenst: */
  730.         if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
  731.             /* no color adjustments: */
  732.             unsigned char *s, *d;
  733.             int src_uv_offs, dest_uv_offs;
  734.             register int i;
  735.             /* copy Y plane: */
  736.             s = src_ptr + src_x + src_y * src_pitch;
  737.             d = dest_ptr + dest_x + dest_y * dest_pitch;
  738.             for (i = 0; i < dest_dy; i ++) {
  739.                 memcpy (d, s, dest_dx); /* Flawfinder: ignore */
  740.                 s += src_pitch;
  741.                 d += dest_pitch;
  742.             }
  743.             /* get Cr/Cb offsets: */
  744.             src_uv_offs = src_height * src_pitch / 4;
  745.             dest_uv_offs = dest_height * dest_pitch / 4;
  746.             /* copy Cr/Cb planes: */
  747.             s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
  748.             d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
  749.             for (i = 0; i < dest_dy/2; i ++) {
  750.                 memcpy (d, s, dest_dx/2); /* Flawfinder: ignore */
  751.                 memcpy (d + dest_uv_offs, s + src_uv_offs, dest_dx/2); /* Flawfinder: ignore */
  752.                 s += src_pitch/2;
  753.                 d += dest_pitch/2;
  754.             }
  755.         } else {
  756.             /* adjust colors: */
  757.             unsigned char *s, *d;
  758.             int src_uv_offs, dest_uv_offs;
  759.             register int i, j;
  760.             /* convert Y plane: */
  761.             s = src_ptr + src_x + src_y * src_pitch;
  762.             d = dest_ptr + dest_x + dest_y * dest_pitch;
  763.             for (i = 0; i < dest_dy; i ++) {
  764.                 /* convert pixels: */
  765.                 for (j = 0; j < dest_dx; j ++)
  766.                     d[j] = _yytab[s[j]];
  767.                 s += src_pitch;
  768.                 d += dest_pitch;
  769.             }
  770.             /* get Cr/Cb offsets: */
  771.             src_uv_offs = src_height * src_pitch / 4;
  772.             dest_uv_offs = dest_height * dest_pitch / 4;
  773.             /* get chroma pointers: */
  774.             s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
  775.             d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
  776.             /* check if no hue adjustment: */
  777.             if (!is_alpha) {
  778.                 /* no chroma rotation: */
  779.                 for (i = 0; i < dest_dy/2; i ++) {
  780.                     /* convert pixels: */
  781.                     for (j = 0; j < dest_dx/2; j ++) {
  782.                         d[j] = _vvtab[s[j]];
  783.                         d[j + dest_uv_offs] = _uutab[s[j + src_uv_offs]];
  784.                     }
  785.                     s += src_pitch/2;
  786.                     d += dest_pitch/2;
  787.                 }
  788.             } else {
  789.                 /* adjust hue: */
  790.                 for (i = 0; i < dest_dy/2; i ++) {
  791.                     /* convert pixels: */
  792.                     for (j = 0; j < dest_dx/2; j ++) {
  793.                         register unsigned v = s[j], u = s[j + src_uv_offs];
  794.                         d[j] = CLIP8[_vvtab[v] + _vutab[u]];
  795.                         d[j + dest_uv_offs] = CLIP8[_uutab[u] + _uvtab[v]];
  796.                     }
  797.                     s += src_pitch/2;
  798.                     d += dest_pitch/2;
  799.                 }
  800.             }
  801.         }
  802.         return 0;
  803.     }
  804.     /* conversion is not supported */
  805.     return -1;
  806. }
  807. /*
  808.  * I420toYV12() converter:
  809.  */
  810. int I420toYV12 (unsigned char *dest_ptr, int dest_width, int dest_height,
  811.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  812.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  813.     int src_x, int src_y, int src_dx, int src_dy)
  814. {
  815.     /* scale factors: */
  816.     int scale_x, scale_y;
  817.     /* check arguments: */
  818.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  819.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  820.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  821.         return -1;
  822.     /* remove odd destination pixels: */
  823.     if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x) ||
  824.         !adjust_range (&dest_y, &dest_dy, &src_y, &src_dy, scale_y))
  825.         return 0;
  826.     /* check if we have matching chroma components: */
  827.     if ((src_x & 1) || (src_y & 1))
  828.         return -1;                          /* can't shift chromas */
  829.     /* check if bottop-up images: */
  830.     if (dest_pitch <= 0 || src_pitch <= 0)
  831.         return -1;                          /* not supported for this format */
  832.     /* check if 1:1 scale: */
  833.     if (scale_x == 1 && scale_y == 1) {
  834.         /* check if no color adjustments: */
  835.         if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
  836.             /* no color adjustments: */
  837.             unsigned char *s, *d;
  838.             int src_uv_offs, dest_uv_offs;
  839.             register int i;
  840.             /* copy Y plane: */
  841.             s = src_ptr + src_x + src_y * src_pitch;
  842.             d = dest_ptr + dest_x + dest_y * dest_pitch;
  843.             for (i = 0; i < dest_dy; i ++) {
  844.                 memcpy (d, s, dest_dx); /* Flawfinder: ignore */
  845.                 s += src_pitch;
  846.                 d += dest_pitch;
  847.             }
  848.             /* get Cr/Cb offsets: */
  849.             src_uv_offs = src_height * src_pitch / 4;
  850.             dest_uv_offs = dest_height * dest_pitch / 4;
  851.             /* copy Cr/Cb planes: */
  852.             s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
  853.             d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
  854.             for (i = 0; i < dest_dy/2; i ++) {
  855.                 memcpy (d, s + src_uv_offs, dest_dx/2); /* Flawfinder: ignore */
  856.                 memcpy (d + dest_uv_offs, s, dest_dx/2); /* Flawfinder: ignore */
  857.                 s += src_pitch/2;
  858.                 d += dest_pitch/2;
  859.             }
  860.         } else {
  861.             /* adjust colors: */
  862.             unsigned char *s, *d;
  863.             int src_uv_offs, dest_uv_offs;
  864.             register int i, j;
  865.             /* convert Y plane: */
  866.             s = src_ptr + src_x + src_y * src_pitch;
  867.             d = dest_ptr + dest_x + dest_y * dest_pitch;
  868.             for (i = 0; i < dest_dy; i ++) {
  869.                 /* convert pixels: */
  870.                 for (j = 0; j < dest_dx; j ++)
  871.                     d[j] = _yytab[s[j]];
  872.                 s += src_pitch;
  873.                 d += dest_pitch;
  874.             }
  875.             /* get Cr/Cb offsets: */
  876.             src_uv_offs = src_height * src_pitch / 4;
  877.             dest_uv_offs = dest_height * dest_pitch / 4;
  878.             /* get chroma pointers: */
  879.             s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
  880.             d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
  881.             /* check if no hue adjustment: */
  882.             if (!is_alpha) {
  883.                 /* no chroma rotation: */
  884.                 for (i = 0; i < dest_dy/2; i ++) {
  885.                     /* convert pixels: */
  886.                     for (j = 0; j < dest_dx/2; j ++) {
  887.                         d[j] = _vvtab[s[j + src_uv_offs]];
  888.                         d[j + dest_uv_offs] = _uutab[s[j]];
  889.                     }
  890.                     s += src_pitch/2;
  891.                     d += dest_pitch/2;
  892.                 }
  893.             } else {
  894.                 /* adjust hue: */
  895.                 for (i = 0; i < dest_dy/2; i ++) {
  896.                     /* convert pixels: */
  897.                     for (j = 0; j < dest_dx/2; j ++) {
  898.                         register unsigned v = s[j + src_uv_offs], u = s[j];
  899.                         d[j] = CLIP8[_vvtab[v] + _vutab[u]];
  900.                         d[j + dest_uv_offs] = CLIP8[_uutab[u] + _uvtab[v]];
  901.                     }
  902.                     s += src_pitch/2;
  903.                     d += dest_pitch/2;
  904.                 }
  905.             }
  906.         }
  907.         return 0;
  908.     }
  909.     /* conversion is not supported */
  910.     return -1;
  911. }
  912. /*
  913.  * I420toYUY2() converter:
  914.  */
  915. int I420toYUY2 (unsigned char *dest_ptr, int dest_width, int dest_height,
  916.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  917.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  918.     int src_x, int src_y, int src_dx, int src_dy)
  919. {
  920.     /* scale factors: */
  921.     int scale_x, scale_y;
  922.     /* check arguments: */
  923.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  924.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  925.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  926.         return -1;
  927.     /* remove odd destination columns: */
  928.     if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x))
  929.         return 0;
  930.     /* check if we have misaligned input: */
  931.     if (src_x & 1)
  932.         return -1;                          /* can't shift chromas */
  933.     /* check if bottop-up images: */
  934.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  935.     if (src_pitch <= 0) return -1;          /* not supported */
  936.     /* check if 1:1 scale: */
  937.     if (scale_x == 1 && scale_y == 1) {
  938.         /* check if no color adjustments: */
  939.         if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
  940.             /* no color adjustments: */
  941.             unsigned char *sy, *sv, *su, *d;
  942.             register int i, j;
  943.             /* get pointers: */
  944.             sy = src_ptr + src_x + src_y * src_pitch;           /* luma offset */
  945.             su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
  946.             sv = su + src_height * src_pitch / 4;
  947.             d  = dest_ptr + dest_x * 2 + dest_y * dest_pitch;   /* 2 bytes/pixel */
  948.             /* process top line (if chroma is not pairable): */
  949.             if (dest_y & 1) {
  950.                 for (j = 0; j < dest_dx/2; j ++)
  951.                     *(unsigned int *)(d + j*4) = sy[j*2] | (su[j] << 8) | (sy[j*2+1] << 16) | (sv[j] << 24);
  952.                 sy += src_pitch;
  953.                 su += src_pitch/2;
  954.                 sv += src_pitch/2;
  955.                 d  += dest_pitch;
  956.                 dest_dy --;
  957.             }
  958.             /* the main loop (processes two lines a time): */
  959.             for (i = 0; i < dest_dy/2; i ++) {
  960.                 for (j = 0; j < dest_dx/2; j ++)
  961.                     *(unsigned int *)(d + j*4) = sy[j*2] | (su[j] << 8) | (sy[j*2+1] << 16) | (sv[j] << 24);
  962.                 sy += src_pitch;
  963.                 d  += dest_pitch;
  964.                 for (j = 0; j < dest_dx/2; j ++)
  965.                     *(unsigned int *)(d + j*4) = sy[j*2] | (su[j] << 8) | (sy[j*2+1] << 16) | (sv[j] << 24);
  966.                 sy += src_pitch;
  967.                 su += src_pitch/2;
  968.                 sv += src_pitch/2;
  969.                 d  += dest_pitch;
  970.             }
  971.             /* process the last line (if dy is odd): */
  972.             if (dest_dy & 1) {
  973.                 for (j = 0; j < dest_dx/2; j ++)
  974.                     *(unsigned int *)(d + j*4) = sy[j*2] | (su[j] << 8) | (sy[j*2+1] << 16) | (sv[j] << 24);
  975.             }
  976.         } else
  977.         /* check if no hue adjustment: */
  978.         if (!is_alpha) {
  979.             /* no chroma rotation: */
  980.             unsigned char *sy, *sv, *su, *d;
  981.             register int i, j;
  982.             /* get pointers: */
  983.             sy = src_ptr + src_x + src_y * src_pitch;           /* luma offset */
  984.             su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
  985.             sv = su + src_height * src_pitch / 4;
  986.             d  = dest_ptr + dest_x * 2 + dest_y * dest_pitch;   /* 2 bytes/pixel */
  987.             /* process top line (if chroma is not pairable): */
  988.             if (dest_y & 1) {
  989.                 for (j = 0; j < dest_dx/2; j ++)
  990.                     *(unsigned int *)(d + j*4) = _yytab[sy[j*2]] | (_uutab[su[j]] << 8) | (_yytab[sy[j*2+1]] << 16) | (_vvtab[sv[j]] << 24);
  991.                 sy += src_pitch;
  992.                 su += src_pitch/2;
  993.                 sv += src_pitch/2;
  994.                 d  += dest_pitch;
  995.                 dest_dy --;
  996.             }
  997.             /* the main loop (processes two lines a time): */
  998.             for (i = 0; i < dest_dy/2; i ++) {
  999.                 for (j = 0; j < dest_dx/2; j ++)
  1000.                     *(unsigned int *)(d + j*4) = _yytab[sy[j*2]] | (_uutab[su[j]] << 8) | (_yytab[sy[j*2+1]] << 16) | (_vvtab[sv[j]] << 24);
  1001.                 sy += src_pitch;
  1002.                 d  += dest_pitch;
  1003.                 for (j = 0; j < dest_dx/2; j ++)
  1004.                     *(unsigned int *)(d + j*4) = _yytab[sy[j*2]] | (_uutab[su[j]] << 8) | (_yytab[sy[j*2+1]] << 16) | (_vvtab[sv[j]] << 24);
  1005.                 sy += src_pitch;
  1006.                 su += src_pitch/2;
  1007.                 sv += src_pitch/2;
  1008.                 d  += dest_pitch;
  1009.             }
  1010.             /* process the last line (if dy is odd): */
  1011.             if (dest_dy & 1) {
  1012.                 for (j = 0; j < dest_dx/2; j ++)
  1013.                     *(unsigned int *)(d + j*4) = _yytab[sy[j*2]] | (_uutab[su[j]] << 8) | (_yytab[sy[j*2+1]] << 16) | (_vvtab[sv[j]] << 24);
  1014.             }
  1015.         } else {
  1016.             /* the most complex case (w. hue adjustment): */
  1017.             unsigned char *sy, *sv, *su, *d;
  1018.             register int i, j, u, v;
  1019.             /* get pointers: */
  1020.             sy = src_ptr + src_x + src_y * src_pitch;           /* luma offset */
  1021.             su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch/2);
  1022.             sv = su + src_height * src_pitch / 4;
  1023.             d  = dest_ptr + dest_x * 2 + dest_y * dest_pitch;   /* 2 bytes/pixel */
  1024.             /* process top line (if chroma is not pairable): */
  1025.             if (dest_y & 1) {
  1026.                 for (j = 0; j < dest_dx/2; j ++) {
  1027.                     v = CLIP8[_vvtab[sv[j]] + _vutab[su[j]]];
  1028.                     u = CLIP8[_uutab[su[j]] + _uvtab[sv[j]]];
  1029.                     *(unsigned int *)(d + j*4) = _yytab[sy[j*2]] | (u << 8) | (_yytab[sy[j*2+1]] << 16) | (v << 24);
  1030.                 }
  1031.                 sy += src_pitch;
  1032.                 su += src_pitch/2;
  1033.                 sv += src_pitch/2;
  1034.                 d  += dest_pitch;
  1035.                 dest_dy --;
  1036.             }
  1037.             /* the main loop (processes two lines a time): */
  1038.             for (i = 0; i < dest_dy/2; i ++) {
  1039.                 for (j = 0; j < dest_dx/2; j ++) {
  1040.                     v = CLIP8[_vvtab[sv[j]] + _vutab[su[j]]];
  1041.                     u = CLIP8[_uutab[su[j]] + _uvtab[sv[j]]];
  1042.                     *(unsigned int *)(d + j*4) = _yytab[sy[j*2]] | (u << 8) | (_yytab[sy[j*2+1]] << 16) | (v << 24);
  1043.                     *(unsigned int *)(d + j*4 + dest_pitch) = _yytab[sy[j*2 + src_pitch]] | (u << 8) | (_yytab[sy[j*2+1+src_pitch]] << 16) | (v << 24);
  1044.                 }
  1045.                 sy += src_pitch*2;
  1046.                 su += src_pitch/2;
  1047.                 sv += src_pitch/2;
  1048.                 d  += dest_pitch*2;
  1049.             }
  1050.             /* process the last line (if dy is odd): */
  1051.             if (dest_dy & 1) {
  1052.                 for (j = 0; j < dest_dx/2; j ++) {
  1053.                     v = CLIP8[_vvtab[sv[j]] + _vutab[su[j]]];
  1054.                     u = CLIP8[_uutab[su[j]] + _uvtab[sv[j]]];
  1055.                     *(unsigned int *)(d + j*4) = _yytab[sy[j*2]] | (u << 8) | (_yytab[sy[j*2+1]] << 16) | (v << 24);
  1056.                 }
  1057.             }
  1058.         }
  1059.         return 0;
  1060.     }
  1061.     /* conversion is not supported */
  1062.     return -1;
  1063. }
  1064. /*
  1065.  * I420toUYVY() converter:
  1066.  */
  1067. int I420toUYVY (unsigned char *dest_ptr, int dest_width, int dest_height,
  1068.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1069.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1070.     int src_x, int src_y, int src_dx, int src_dy)
  1071. {
  1072.     /* scale factors: */
  1073.     int scale_x, scale_y;
  1074.     /* check arguments: */
  1075.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  1076.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  1077.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  1078.         return -1;
  1079.     /* remove odd destination columns: */
  1080.     if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x))
  1081.         return 0;
  1082.     /* check if we have misaligned input: */
  1083.     if (src_x & 1)
  1084.         return -1;                          /* can't shift chromas */
  1085.     /* check if bottop-up images: */
  1086.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1087.     if (src_pitch <= 0) return -1;          /* not supported */
  1088.     /* check if 1:1 scale: */
  1089.     if (scale_x == 1 && scale_y == 1) {
  1090.         /* check if no color adjustments: */
  1091.         if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
  1092.             /* no color adjustments: */
  1093.             unsigned char *sy, *sv, *su, *d;
  1094.             register int i, j;
  1095.             /* get pointers: */
  1096.             sy = src_ptr + src_x + src_y * src_pitch;           /* luma offset */
  1097.             su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
  1098.             sv = su + src_height * src_pitch / 4;
  1099.             d  = dest_ptr + dest_x * 2 + dest_y * dest_pitch;   /* 2 bytes/pixel */
  1100.             /* process top line (if chroma is not pairable): */
  1101.             if (dest_y & 1) {
  1102.                 for (j = 0; j < dest_dx/2; j ++)
  1103.                     *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
  1104.                 sy += src_pitch;
  1105.                 su += src_pitch/2;
  1106.                 sv += src_pitch/2;
  1107.                 d  += dest_pitch;
  1108.                 dest_dy --;
  1109.             }
  1110.             /* the main loop (processes two lines a time): */
  1111.             for (i = 0; i < dest_dy/2; i ++) {
  1112.                 for (j = 0; j < dest_dx/2; j ++)
  1113.                     *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
  1114.                 sy += src_pitch;
  1115.                 d  += dest_pitch;
  1116.                 for (j = 0; j < dest_dx/2; j ++)
  1117.                     *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
  1118.                 sy += src_pitch;
  1119.                 su += src_pitch/2;
  1120.                 sv += src_pitch/2;
  1121.                 d  += dest_pitch;
  1122.             }
  1123.             /* process the last line (if dy is odd): */
  1124.             if (dest_dy & 1) {
  1125.                 for (j = 0; j < dest_dx/2; j ++)
  1126.                     *(unsigned int *)(d + j*4) = su[j] | (sy[j*2] << 8) | (sv[j] << 16) | (sy[j*2+1] << 24);
  1127.             }
  1128.         } else
  1129.         /* check if no hue adjustment: */
  1130.         if (!is_alpha) {
  1131.             /* no chroma rotation: */
  1132.             unsigned char *sy, *sv, *su, *d;
  1133.             register int i, j;
  1134.             /* get pointers: */
  1135.             sy = src_ptr + src_x + src_y * src_pitch;           /* luma offset */
  1136.             su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
  1137.             sv = su + src_height * src_pitch / 4;
  1138.             d  = dest_ptr + dest_x * 2 + dest_y * dest_pitch;   /* 2 bytes/pixel */
  1139.             /* process top line (if chroma is not pairable): */
  1140.             if (dest_y & 1) {
  1141.                 for (j = 0; j < dest_dx/2; j ++)
  1142.                     *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
  1143.                 sy += src_pitch;
  1144.                 su += src_pitch/2;
  1145.                 sv += src_pitch/2;
  1146.                 d  += dest_pitch;
  1147.                 dest_dy --;
  1148.             }
  1149.             /* the main loop (processes two lines a time): */
  1150.             for (i = 0; i < dest_dy/2; i ++) {
  1151.                 for (j = 0; j < dest_dx/2; j ++)
  1152.                     *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
  1153.                 sy += src_pitch;
  1154.                 d  += dest_pitch;
  1155.                 for (j = 0; j < dest_dx/2; j ++)
  1156.                     *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
  1157.                 sy += src_pitch;
  1158.                 su += src_pitch/2;
  1159.                 sv += src_pitch/2;
  1160.                 d  += dest_pitch;
  1161.             }
  1162.             /* process the last line (if dy is odd): */
  1163.             if (dest_dy & 1) {
  1164.                 for (j = 0; j < dest_dx/2; j ++)
  1165.                     *(unsigned int *)(d + j*4) = _uutab[su[j]] | (_yytab[sy[j*2]] << 8) | (_vvtab[sv[j]] << 16) | (_yytab[sy[j*2+1]] << 24);
  1166.             }
  1167.         } else {
  1168.             /* the most complex case (w. hue adjustement): */
  1169.             unsigned char *sy, *sv, *su, *d;
  1170.             register int i, j, u, v;
  1171.             /* get pointers: */
  1172.             sy = src_ptr + src_x + src_y * src_pitch;           /* luma offset */
  1173.             su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch/2);
  1174.             sv = su + src_height * src_pitch / 4;
  1175.             d  = dest_ptr + dest_x * 2 + dest_y * dest_pitch;   /* 2 bytes/pixel */
  1176.             /* process top line (if chroma is not pairable): */
  1177.             if (dest_y & 1) {
  1178.                 for (j = 0; j < dest_dx/2; j ++) {
  1179.                     v = CLIP8[_vvtab[sv[j]] + _vutab[su[j]]];
  1180.                     u = CLIP8[_uutab[su[j]] + _uvtab[sv[j]]];
  1181.                     *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
  1182.                 }
  1183.                 sy += src_pitch;
  1184.                 su += src_pitch/2;
  1185.                 sv += src_pitch/2;
  1186.                 d  += dest_pitch;
  1187.                 dest_dy --;
  1188.             }
  1189.             /* the main loop (processes two lines a time): */
  1190.             for (i = 0; i < dest_dy/2; i ++) {
  1191.                 for (j = 0; j < dest_dx/2; j ++) {
  1192.                     v = CLIP8[_vvtab[sv[j]] + _vutab[su[j]]];
  1193.                     u = CLIP8[_uutab[su[j]] + _uvtab[sv[j]]];
  1194.                     *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
  1195.                     *(unsigned int *)(d + j*4 + dest_pitch) = u | (_yytab[sy[j*2 + src_pitch]] << 8) | (v << 16) | (_yytab[sy[j*2+1 + src_pitch]] << 24);
  1196.                 }
  1197.                 sy += src_pitch*2;
  1198.                 su += src_pitch/2;
  1199.                 sv += src_pitch/2;
  1200.                 d  += dest_pitch*2;
  1201.             }
  1202.             /* process the last line (if dy is odd): */
  1203.             if (dest_dy & 1) {
  1204.                 for (j = 0; j < dest_dx/2; j ++) {
  1205.                     v = CLIP8[_vvtab[sv[j]] + _vutab[su[j]]];
  1206.                     u = CLIP8[_uutab[su[j]] + _uvtab[sv[j]]];
  1207.                     *(unsigned int *)(d + j*4) = u | (_yytab[sy[j*2]] << 8) | (v << 16) | (_yytab[sy[j*2+1]] << 24);
  1208.                 }
  1209.             }
  1210.         }
  1211.         return 0;
  1212.     }
  1213.     /* conversion is not supported */
  1214.     return -1;
  1215. }
  1216. /*
  1217.  * I420->RGB* double-line converters:
  1218.  */
  1219. static void dblineI420toRGB32 (unsigned char *d1, unsigned char *d2, int dest_x,
  1220.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  1221.     int src_x, int dx)
  1222. {
  1223.     register int y1, y2, rv, guv, bu;
  1224.     register int i;
  1225.     /* convert first 2x1 block: */
  1226.     if (src_x & 1) {
  1227.         bu = butab[su[0]];
  1228.         guv = gutab[su[0]] + gvtab[sv[0]];
  1229.         rv = rvtab[sv[0]];
  1230.         y1 = ytab[sy1[0]];
  1231.         y2 = ytab[sy2[0]];
  1232.         /* first line BGR0 */
  1233.         *(unsigned int *)(d1+0) =
  1234.             (CLIP8[y1 + bu])       |
  1235.             (CLIP8[y1 + guv] << 8) |
  1236.             (CLIP8[y1 + rv]  << 16);
  1237.         /* second line BGR0 */
  1238.         *(unsigned int *)(d2+0) =
  1239.             (CLIP8[y2 + bu])       |
  1240.             (CLIP8[y2 + guv] << 8) |
  1241.             (CLIP8[y2 + rv]  << 16);
  1242.         sy1 += 1; sy2 += 1;
  1243.         su += 1; sv += 1;           /* shift luma !!! */
  1244.         d1 += BPP4; d2 += BPP4;
  1245.         dx --;
  1246.     }
  1247.     /* convert all integral 2x2 blocks: */
  1248.     for (i = 0; i < dx/2; i ++) {
  1249.         bu = butab[su[0]];
  1250.         guv = gutab[su[0]] + gvtab[sv[0]];
  1251.         rv = rvtab[sv[0]];
  1252.         y1 = ytab[sy1[0]];
  1253.         y2 = ytab[sy2[0]];
  1254.         /* first line BGR0 */
  1255.         *(unsigned int *)(d1+0) =
  1256.             (CLIP8[y1 + bu])       |
  1257.             (CLIP8[y1 + guv] << 8) |
  1258.             (CLIP8[y1 + rv]  << 16);
  1259.         /* second line BGR0 */
  1260.         *(unsigned int *)(d2+0) =
  1261.             (CLIP8[y2 + bu])       |
  1262.             (CLIP8[y2 + guv] << 8) |
  1263.             (CLIP8[y2 + rv]  << 16);
  1264.         /* 2nd row: */
  1265.         y1 = ytab[sy1[1]];
  1266.         y2 = ytab[sy2[1]];
  1267.         /* first line BGR0 */
  1268.         *(unsigned int *)(d1+BPP4) =
  1269.             (CLIP8[y1 + bu])       |
  1270.             (CLIP8[y1 + guv] << 8) |
  1271.             (CLIP8[y1 + rv]  << 16);
  1272.         /* second line BGR0 */
  1273.         *(unsigned int *)(d2+BPP4) =
  1274.             (CLIP8[y2 + bu])       |
  1275.             (CLIP8[y2 + guv] << 8) |
  1276.             (CLIP8[y2 + rv]  << 16);
  1277.         /* next 2x2 block */
  1278.         sy1 += 2; sy2 += 2;
  1279.         su += 1; sv += 1;
  1280.         d1 += 2*BPP4; d2 += 2*BPP4;
  1281.     }
  1282.     /* convert the last 2x1 block: */
  1283.     if (dx & 1) {
  1284.         bu = butab[su[0]];
  1285.         guv = gutab[su[0]] + gvtab[sv[0]];
  1286.         rv = rvtab[sv[0]];
  1287.         y1 = ytab[sy1[0]];
  1288.         y2 = ytab[sy2[0]];
  1289.         /* first line BGR0 */
  1290.         *(unsigned int *)(d1+0) =
  1291.             (CLIP8[y1 + bu])       |
  1292.             (CLIP8[y1 + guv] << 8) |
  1293.             (CLIP8[y1 + rv]  << 16);
  1294.         /* second line BGR0 */
  1295.         *(unsigned int *)(d2+0) =
  1296.             (CLIP8[y2 + bu])       |
  1297.             (CLIP8[y2 + guv] << 8) |
  1298.             (CLIP8[y2 + rv]  << 16);
  1299.     }
  1300. }
  1301. static void dblineI420toRGB32alpha (unsigned char *d1, unsigned char *d2, int dest_x,
  1302.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  1303.     int src_x, int dx)
  1304. {
  1305.     register int y1, y2, ruv, guv, buv;
  1306.     register int i;
  1307.     /* convert first 2x1 block: */
  1308.     if (src_x & 1) {
  1309.         buv = butab[su[0]] + bvtab[sv[0]];
  1310.         guv = gutab[su[0]] + gvtab[sv[0]];
  1311.         ruv = rutab[su[0]] + rvtab[sv[0]];
  1312.         y1 = ytab[sy1[0]];
  1313.         y2 = ytab[sy2[0]];
  1314.         /* first line BGR0 */
  1315.         *(unsigned int *)(d1+0) =
  1316.             (CLIP8[y1 + buv])      |
  1317.             (CLIP8[y1 + guv] << 8) |
  1318.             (CLIP8[y1 + ruv] << 16);
  1319.         /* second line BGR0 */
  1320.         *(unsigned int *)(d2+0) =
  1321.             (CLIP8[y2 + buv])      |
  1322.             (CLIP8[y2 + guv] << 8) |
  1323.             (CLIP8[y2 + ruv] << 16);
  1324.         sy1 += 1; sy2 += 1;
  1325.         su += 1; sv += 1;           /* shift luma !!! */
  1326.         d1 += BPP4; d2 += BPP4;
  1327.         dx --;
  1328.     }
  1329.     /* convert all integral 2x2 blocks: */
  1330.     for (i = 0; i < dx/2; i ++) {
  1331.         buv = butab[su[0]] + bvtab[sv[0]];
  1332.         guv = gutab[su[0]] + gvtab[sv[0]];
  1333.         ruv = rutab[su[0]] + rvtab[sv[0]];
  1334.         y1 = ytab[sy1[0]];
  1335.         y2 = ytab[sy2[0]];
  1336.         /* first line BGR0 */
  1337.         *(unsigned int *)(d1+0) =
  1338.             (CLIP8[y1 + buv])      |
  1339.             (CLIP8[y1 + guv] << 8) |
  1340.             (CLIP8[y1 + ruv] << 16);
  1341.         /* second line BGR0 */
  1342.         *(unsigned int *)(d2+0) =
  1343.             (CLIP8[y2 + buv])      |
  1344.             (CLIP8[y2 + guv] << 8) |
  1345.             (CLIP8[y2 + ruv] << 16);
  1346.         y1 = ytab[sy1[1]];
  1347.         y2 = ytab[sy2[1]];
  1348.         /* first line BGR0 */
  1349.         *(unsigned int *)(d1+BPP4) =
  1350.             (CLIP8[y1 + buv])      |
  1351.             (CLIP8[y1 + guv] << 8) |
  1352.             (CLIP8[y1 + ruv] << 16);
  1353.         /* second line BGR0 */
  1354.         *(unsigned int *)(d2+BPP4) =
  1355.             (CLIP8[y2 + buv])      |
  1356.             (CLIP8[y2 + guv] << 8) |
  1357.             (CLIP8[y2 + ruv] << 16);
  1358.         /* next 2x2 block */
  1359.         sy1 += 2; sy2 += 2;
  1360.         su += 1; sv += 1;
  1361.         d1 += 2*BPP4; d2 += 2*BPP4;
  1362.     }
  1363.     /* convert last 2x1 block: */
  1364.     if (dx & 1) {
  1365.         buv = butab[su[0]] + bvtab[sv[0]];
  1366.         guv = gutab[su[0]] + gvtab[sv[0]];
  1367.         ruv = rutab[su[0]] + rvtab[sv[0]];
  1368.         y1 = ytab[sy1[0]];
  1369.         y2 = ytab[sy2[0]];
  1370.         /* first line BGR0 */
  1371.         *(unsigned int *)(d1+0) =
  1372.             (CLIP8[y1 + buv])      |
  1373.             (CLIP8[y1 + guv] << 8) |
  1374.             (CLIP8[y1 + ruv] << 16);
  1375.         /* second line BGR0 */
  1376.         *(unsigned int *)(d2+0) =
  1377.             (CLIP8[y2 + buv])      |
  1378.             (CLIP8[y2 + guv] << 8) |
  1379.             (CLIP8[y2 + ruv] << 16);
  1380.     }
  1381. }
  1382. static void dblineI420toBGR32 (unsigned char *d1, unsigned char *d2, int dest_x,
  1383.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  1384.     int src_x, int dx)
  1385. {
  1386.     register int y1, y2, rv, guv, bu;
  1387.     register int i;
  1388.     /* convert first 2x1 block: */
  1389.     if (src_x & 1) {
  1390.         bu = butab[su[0]];
  1391.         guv = gutab[su[0]] + gvtab[sv[0]];
  1392.         rv = rvtab[sv[0]];
  1393.         y1 = ytab[sy1[0]];
  1394.         y2 = ytab[sy2[0]];
  1395.         /* first line BGR0 */
  1396.         *(unsigned int *)(d1+0) =
  1397.             (CLIP8[y1 + bu]  << 16)|
  1398.             (CLIP8[y1 + guv] << 8) |
  1399.             (CLIP8[y1 + rv]  << 0);
  1400.         /* second line BGR0 */
  1401.         *(unsigned int *)(d2+0) =
  1402.             (CLIP8[y2 + bu]  << 16)|
  1403.             (CLIP8[y2 + guv] << 8) |
  1404.             (CLIP8[y2 + rv]  << 0);
  1405.         sy1 += 1; sy2 += 1;
  1406.         su += 1; sv += 1;           /* shift luma !!! */
  1407.         d1 += BPP4; d2 += BPP4;
  1408.         dx --;
  1409.     }
  1410.     /* convert all integral 2x2 blocks: */
  1411.     for (i = 0; i < dx/2; i ++) {
  1412.         bu = butab[su[0]];
  1413.         guv = gutab[su[0]] + gvtab[sv[0]];
  1414.         rv = rvtab[sv[0]];
  1415.         y1 = ytab[sy1[0]];
  1416.         y2 = ytab[sy2[0]];
  1417.         /* first line BGR0 */
  1418.         *(unsigned int *)(d1+0) =
  1419.             (CLIP8[y1 + bu]  << 16)|
  1420.             (CLIP8[y1 + guv] << 8) |
  1421.             (CLIP8[y1 + rv]  << 0);
  1422.         /* second line BGR0 */
  1423.         *(unsigned int *)(d2+0) =
  1424.             (CLIP8[y2 + bu]  << 16)|
  1425.             (CLIP8[y2 + guv] << 8) |
  1426.             (CLIP8[y2 + rv]  << 0);
  1427.         /* 2nd row: */
  1428.         y1 = ytab[sy1[1]];
  1429.         y2 = ytab[sy2[1]];
  1430.         /* first line BGR0 */
  1431.         *(unsigned int *)(d1+BPP4) =
  1432.             (CLIP8[y1 + bu]  << 16)|
  1433.             (CLIP8[y1 + guv] << 8) |
  1434.             (CLIP8[y1 + rv]  << 0);
  1435.         /* second line BGR0 */
  1436.         *(unsigned int *)(d2+BPP4) =
  1437.             (CLIP8[y2 + bu]  << 16)|
  1438.             (CLIP8[y2 + guv] << 8) |
  1439.             (CLIP8[y2 + rv]  << 0);
  1440.         /* next 2x2 block */
  1441.         sy1 += 2; sy2 += 2;
  1442.         su += 1; sv += 1;
  1443.         d1 += 2*BPP4; d2 += 2*BPP4;
  1444.     }
  1445.     /* convert the last 2x1 block: */
  1446.     if (dx & 1) {
  1447.         bu = butab[su[0]];
  1448.         guv = gutab[su[0]] + gvtab[sv[0]];
  1449.         rv = rvtab[sv[0]];
  1450.         y1 = ytab[sy1[0]];
  1451.         y2 = ytab[sy2[0]];
  1452.         /* first line BGR0 */
  1453.         *(unsigned int *)(d1+0) =
  1454.             (CLIP8[y1 + bu]  << 16)|
  1455.             (CLIP8[y1 + guv] << 8) |
  1456.             (CLIP8[y1 + rv]  << 0);
  1457.         /* second line BGR0 */
  1458.         *(unsigned int *)(d2+0) =
  1459.             (CLIP8[y2 + bu]  << 16)|
  1460.             (CLIP8[y2 + guv] << 8) |
  1461.             (CLIP8[y2 + rv]  << 0);
  1462.     }
  1463. }
  1464. static void dblineI420toBGR32alpha (unsigned char *d1, unsigned char *d2, int dest_x,
  1465.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  1466.     int src_x, int dx)
  1467. {
  1468.     register int y1, y2, ruv, guv, buv;
  1469.     register int i;
  1470.     /* convert first 2x1 block: */
  1471.     if (src_x & 1) {
  1472.         buv = butab[su[0]] + bvtab[sv[0]];
  1473.         guv = gutab[su[0]] + gvtab[sv[0]];
  1474.         ruv = rutab[su[0]] + rvtab[sv[0]];
  1475.         y1 = ytab[sy1[0]];
  1476.         y2 = ytab[sy2[0]];
  1477.         /* first line BGR0 */
  1478.         *(unsigned int *)(d1+0) =
  1479.             (CLIP8[y1 + buv] << 16)|
  1480.             (CLIP8[y1 + guv] << 8) |
  1481.             (CLIP8[y1 + ruv] << 0);
  1482.         /* second line BGR0 */
  1483.         *(unsigned int *)(d2+0) =
  1484.             (CLIP8[y2 + buv] << 16)|
  1485.             (CLIP8[y2 + guv] << 8) |
  1486.             (CLIP8[y2 + ruv] << 0);
  1487.         sy1 += 1; sy2 += 1;
  1488.         su += 1; sv += 1;           /* shift luma !!! */
  1489.         d1 += BPP4; d2 += BPP4;
  1490.         dx --;
  1491.     }
  1492.     /* convert all integral 2x2 blocks: */
  1493.     for (i = 0; i < dx/2; i ++) {
  1494.         buv = butab[su[0]] + bvtab[sv[0]];
  1495.         guv = gutab[su[0]] + gvtab[sv[0]];
  1496.         ruv = rutab[su[0]] + rvtab[sv[0]];
  1497.         y1 = ytab[sy1[0]];
  1498.         y2 = ytab[sy2[0]];
  1499.         /* first line BGR0 */
  1500.         *(unsigned int *)(d1+0) =
  1501.             (CLIP8[y1 + buv] << 16)|
  1502.             (CLIP8[y1 + guv] << 8) |
  1503.             (CLIP8[y1 + ruv] << 0);
  1504.         /* second line BGR0 */
  1505.         *(unsigned int *)(d2+0) =
  1506.             (CLIP8[y2 + buv] << 16)|
  1507.             (CLIP8[y2 + guv] << 8) |
  1508.             (CLIP8[y2 + ruv] << 0);
  1509.         y1 = ytab[sy1[1]];
  1510.         y2 = ytab[sy2[1]];
  1511.         /* first line BGR0 */
  1512.         *(unsigned int *)(d1+BPP4) =
  1513.             (CLIP8[y1 + buv] << 16)|
  1514.             (CLIP8[y1 + guv] << 8) |
  1515.             (CLIP8[y1 + ruv] << 0);
  1516.         /* second line BGR0 */
  1517.         *(unsigned int *)(d2+BPP4) =
  1518.             (CLIP8[y2 + buv] << 16)|
  1519.             (CLIP8[y2 + guv] << 8) |
  1520.             (CLIP8[y2 + ruv] << 0);
  1521.         /* next 2x2 block */
  1522.         sy1 += 2; sy2 += 2;
  1523.         su += 1; sv += 1;
  1524.         d1 += 2*BPP4; d2 += 2*BPP4;
  1525.     }
  1526.     /* convert last 2x1 block: */
  1527.     if (dx & 1) {
  1528.         buv = butab[su[0]] + bvtab[sv[0]];
  1529.         guv = gutab[su[0]] + gvtab[sv[0]];
  1530.         ruv = rutab[su[0]] + rvtab[sv[0]];
  1531.         y1 = ytab[sy1[0]];
  1532.         y2 = ytab[sy2[0]];
  1533.         /* first line BGR0 */
  1534.         *(unsigned int *)(d1+0) =
  1535.             (CLIP8[y1 + buv] << 16)|
  1536.             (CLIP8[y1 + guv] << 8) |
  1537.             (CLIP8[y1 + ruv] << 0);
  1538.         /* second line BGR0 */
  1539.         *(unsigned int *)(d2+0) =
  1540.             (CLIP8[y2 + buv] << 16)|
  1541.             (CLIP8[y2 + guv] << 8) |
  1542.             (CLIP8[y2 + ruv] << 0);
  1543.     }
  1544. }
  1545. static void dblineI420toRGB24 (unsigned char *d1, unsigned char *d2, int dest_x,
  1546.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  1547.     int src_x, int dx)
  1548. {
  1549.     /* check if we can use a fast 32-bit code: */
  1550.     if (LITTLE_ENDIAN && !((src_x ^ dest_x) & 1)) {
  1551.         /* aligned input/output on little-endian machine: */
  1552.         register int y11, y12, y13, y14, y21, y22, y23, y24;
  1553.         register int rv, rv2, guv, guv2, bu, bu2;
  1554.         register int i;
  1555.         /* convert first 2x1 block: */
  1556.         if (dest_x & 1) {
  1557.             bu = butab[su[0]];
  1558.             guv = gutab[su[0]] + gvtab[sv[0]];
  1559.             rv = rvtab[sv[0]];
  1560.             y11 = ytab[sy1[0]];
  1561.             y21 = ytab[sy2[0]];
  1562.             /* first line BGR: */
  1563.             d1[0] = CLIP8[y11 + bu];
  1564.             d1[1] = CLIP8[y11 + guv];
  1565.             d1[2] = CLIP8[y11 + rv];
  1566.             /* second line BGR: */
  1567.             d2[0] = CLIP8[y21 + bu];
  1568.             d2[1] = CLIP8[y21 + guv];
  1569.             d2[2] = CLIP8[y21 + rv];
  1570.             sy1 += 1; sy2 += 1;
  1571.             su += 1; sv += 1;
  1572.             d1 += BPP3; d2 += BPP3;
  1573.             dest_x ++; dx --;
  1574.         }
  1575.         /* convert first 2x2 block: */
  1576.         if (dest_x & 2) {
  1577.             bu = butab[su[0]];
  1578.             guv = gutab[su[0]] + gvtab[sv[0]];
  1579.             rv = rvtab[sv[0]];
  1580.             y11 = ytab[sy1[0]];
  1581.             y21 = ytab[sy2[0]];
  1582.             /* first line BGR: */
  1583.             d1[0] = CLIP8[y11 + bu];
  1584.             d1[1] = CLIP8[y11 + guv];
  1585.             d1[2] = CLIP8[y11 + rv];
  1586.             /* second line BGR: */
  1587.             d2[0] = CLIP8[y21 + bu];
  1588.             d2[1] = CLIP8[y21 + guv];
  1589.             d2[2] = CLIP8[y21 + rv];
  1590.             y12 = ytab[sy1[1]];
  1591.             y22 = ytab[sy2[1]];
  1592.             /* first line BGR: */
  1593.             d1[0+BPP3] = CLIP8[y12 + bu];
  1594.             d1[1+BPP3] = CLIP8[y12 + guv];
  1595.             d1[2+BPP3] = CLIP8[y12 + rv];
  1596.             /* second line BGR: */
  1597.             d2[0+BPP3] = CLIP8[y22 + bu];
  1598.             d2[1+BPP3] = CLIP8[y22 + guv];
  1599.             d2[2+BPP3] = CLIP8[y22 + rv];
  1600.             sy1 += 2; sy2 += 2;
  1601.             su += 1; sv += 1;
  1602.             d1 += 2*BPP3; d2 += 2*BPP3;
  1603.             dest_x += 2; dx -= 2;
  1604.         }
  1605.         /* convert all integral 2x4 blocks: */
  1606.         for (i = 0; i < dx/4; i ++) {
  1607.             bu = butab[su[0]];
  1608.             guv = gutab[su[0]] + gvtab[sv[0]];
  1609.             rv = rvtab[sv[0]];
  1610.             y11 = ytab[sy1[0]];
  1611.             y12 = ytab[sy1[1]];
  1612.             /* first line BGRB */
  1613.             *(unsigned int *)(d1+0) =
  1614.                 (CLIP8[y11 + bu])        |
  1615.                 (CLIP8[y11 + guv] << 8)  |
  1616.                 (CLIP8[y11 + rv]  << 16) |
  1617.                 (CLIP8[y12 + bu]  << 24) ;
  1618.             y21 = ytab[sy2[0]];
  1619.             y22 = ytab[sy2[1]];
  1620.             /* second line BGRB */
  1621.             *(unsigned int *)(d2+0) =
  1622.                 (CLIP8[y21 + bu])        |
  1623.                 (CLIP8[y21 + guv] << 8)  |
  1624.                 (CLIP8[y21 + rv]  << 16) |
  1625.                 (CLIP8[y22 + bu]  << 24) ;
  1626.             bu2 = butab[su[1]];
  1627.             guv2 = gutab[su[1]] + gvtab[sv[1]];
  1628.             y13 = ytab[sy1[2]];
  1629.             /* first line GRBG */
  1630.             *(unsigned int *)(d1+4) =
  1631.                 (CLIP8[y12 + guv])        |
  1632.                 (CLIP8[y12 + rv]   << 8)  |
  1633.                 (CLIP8[y13 + bu2]  << 16) |
  1634.                 (CLIP8[y13 + guv2] << 24) ;
  1635.             y23 = ytab[sy2[2]];
  1636.             /* second line GRBG */
  1637.             *(unsigned int *)(d2+4) =
  1638.                 (CLIP8[y22 + guv])        |
  1639.                 (CLIP8[y22 + rv]   << 8)  |
  1640.                 (CLIP8[y23 + bu2]  << 16) |
  1641.                 (CLIP8[y23 + guv2] << 24) ;
  1642.             y14 = ytab[sy1[3]];
  1643.             rv2 = rvtab[sv[1]];
  1644.             /* first line RBGR */
  1645.             *(unsigned int *)(d1+8) =
  1646.                 (CLIP8[y13 + rv2])        |
  1647.                 (CLIP8[y14 + bu2]  << 8)  |
  1648.                 (CLIP8[y14 + guv2] << 16) |
  1649.                 (CLIP8[y14 + rv2]  << 24) ;
  1650.             y24 = ytab[sy2[3]];
  1651.             /* second line RBGR */
  1652.             *(unsigned int *)(d2+8) =
  1653.                 (CLIP8[y23 + rv2])        |
  1654.                 (CLIP8[y24 + bu2]  << 8)  |
  1655.                 (CLIP8[y24 + guv2] << 16) |
  1656.                 (CLIP8[y24 + rv2]  << 24) ;
  1657.             /* next 4x2 block */
  1658.             sy1 += 4; sy2 += 4;
  1659.             su += 2; sv += 2;
  1660.             d1 += 4*BPP3; d2 += 4*BPP3;
  1661.         }
  1662.         /* convert last 2x2 block: */
  1663.         if (dx & 2) {
  1664.             bu = butab[su[0]];
  1665.             guv = gutab[su[0]] + gvtab[sv[0]];
  1666.             rv = rvtab[sv[0]];
  1667.             y11 = ytab[sy1[0]];
  1668.             y21 = ytab[sy2[0]];
  1669.             /* first line BGR: */
  1670.             d1[0] = CLIP8[y11 + bu];
  1671.             d1[1] = CLIP8[y11 + guv];
  1672.             d1[2] = CLIP8[y11 + rv];
  1673.             /* second line BGR: */
  1674.             d2[0] = CLIP8[y21 + bu];
  1675.             d2[1] = CLIP8[y21 + guv];
  1676.             d2[2] = CLIP8[y21 + rv];
  1677.             y12 = ytab[sy1[1]];
  1678.             y22 = ytab[sy2[1]];
  1679.             /* first line BGR: */
  1680.             d1[0+BPP3] = CLIP8[y12 + bu];
  1681.             d1[1+BPP3] = CLIP8[y12 + guv];
  1682.             d1[2+BPP3] = CLIP8[y12 + rv];
  1683.             /* second line BGR: */
  1684.             d2[0+BPP3] = CLIP8[y22 + bu];
  1685.             d2[1+BPP3] = CLIP8[y22 + guv];
  1686.             d2[2+BPP3] = CLIP8[y22 + rv];
  1687.             sy1 += 2; sy2 += 2;
  1688.             su += 1; sv += 1;
  1689.             d1 += 2*BPP3; d2 += 2*BPP3;
  1690.             dx -= 2;
  1691.         }
  1692.         /* convert last 2x1 block: */
  1693.         if (dx & 1) {
  1694.             bu = butab[su[0]];
  1695.             guv = gutab[su[0]] + gvtab[sv[0]];
  1696.             rv = rvtab[sv[0]];
  1697.             y11 = ytab[sy1[0]];
  1698.             y21 = ytab[sy2[0]];
  1699.             /* first line BGR: */
  1700.             d1[0] = CLIP8[y11 + bu];
  1701.             d1[1] = CLIP8[y11 + guv];
  1702.             d1[2] = CLIP8[y11 + rv];
  1703.             /* second line BGR: */
  1704.             d2[0] = CLIP8[y21 + bu];
  1705.             d2[1] = CLIP8[y21 + guv];
  1706.             d2[2] = CLIP8[y21 + rv];
  1707.         }
  1708.     } else {
  1709.         /* more generic implementation: */
  1710.         register int y11, y12, y21, y22;
  1711.         register int bu, rv, guv;
  1712.         register int i;
  1713.         /* convert first 2x1 block: */
  1714.         if (dest_x & 1) {
  1715.             bu = butab[su[0]];
  1716.             guv = gutab[su[0]] + gvtab[sv[0]];
  1717.             rv = rvtab[sv[0]];
  1718.             y11 = ytab[sy1[0]];
  1719.             y21 = ytab[sy2[0]];
  1720.             /* first line BGR: */
  1721.             d1[0] = CLIP8[y11 + bu];
  1722.             d1[1] = CLIP8[y11 + guv];
  1723.             d1[2] = CLIP8[y11 + rv];
  1724.             /* second line BGR: */
  1725.             d2[0] = CLIP8[y21 + bu];
  1726.             d2[1] = CLIP8[y21 + guv];
  1727.             d2[2] = CLIP8[y21 + rv];
  1728.             sy1 += 1; sy2 += 1;
  1729.             su += 1; sv += 1;
  1730.             d1 += BPP3; d2 += BPP3;
  1731.             dest_x ++; dx --;
  1732.         }
  1733.         /* convert all integral 2x2 blocks: */
  1734.         for (i = 0; i < dx/2; i ++) {
  1735.             bu = butab[su[0]];
  1736.             guv = gutab[su[0]] + gvtab[sv[0]];
  1737.             rv = rvtab[sv[0]];
  1738.             y11 = ytab[sy1[0]];
  1739.             y12 = ytab[sy1[1]];
  1740.             /* first line BGR,BGR: */
  1741.             d1[0] = CLIP8[y11 + bu];
  1742.             d1[1] = CLIP8[y11 + guv];
  1743.             d1[2] = CLIP8[y11 + rv];
  1744.             d1[3] = CLIP8[y12 + bu];
  1745.             d1[4] = CLIP8[y12 + guv];
  1746.             d1[5] = CLIP8[y12 + rv];
  1747.             y21 = ytab[sy2[0]];
  1748.             y22 = ytab[sy2[1]];
  1749.             /* second line BGR,BGR: */
  1750.             d2[0] = CLIP8[y21 + bu];
  1751.             d2[1] = CLIP8[y21 + guv];
  1752.             d2[2] = CLIP8[y21 + rv];
  1753.             d2[3] = CLIP8[y22 + bu];
  1754.             d2[4] = CLIP8[y22 + guv];
  1755.             d2[5] = CLIP8[y22 + rv];
  1756.             /* next 2x2 block */
  1757.             sy1 += 2; sy2 += 2;
  1758.             su += 1; sv += 1;
  1759.             d1 += 2*BPP3; d2 += 2*BPP3;
  1760.         }
  1761.         /* convert last 2x1 block: */
  1762.         if (dx & 1) {
  1763.             bu = butab[su[0]];
  1764.             guv = gutab[su[0]] + gvtab[sv[0]];
  1765.             rv = rvtab[sv[0]];
  1766.             y11 = ytab[sy1[0]];
  1767.             y21 = ytab[sy2[0]];
  1768.             /* first line BGR: */
  1769.             d1[0] = CLIP8[y11 + bu];
  1770.             d1[1] = CLIP8[y11 + guv];
  1771.             d1[2] = CLIP8[y11 + rv];
  1772.             /* second line BGR: */
  1773.             d2[0] = CLIP8[y21 + bu];
  1774.             d2[1] = CLIP8[y21 + guv];
  1775.             d2[2] = CLIP8[y21 + rv];
  1776.         }
  1777.     }
  1778. }
  1779. static void dblineI420toRGB24alpha (unsigned char *d1, unsigned char *d2, int dest_x,
  1780.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  1781.     int src_x, int dx)
  1782. {
  1783.     /* check if we can use a fast 32-bit code: */
  1784.     if (LITTLE_ENDIAN && !((src_x ^ dest_x) & 1)) {
  1785.         /* aligned input/output on little-endian machine: */
  1786.         register int y11, y12, y13, y14, y21, y22, y23, y24;
  1787.         register int ruv, ruv2, guv, guv2, buv, buv2;
  1788.         register int i;
  1789.         /* convert first 2x1 block: */
  1790.         if (dest_x & 1) {
  1791.             buv = butab[su[0]] + bvtab[sv[0]];
  1792.             guv = gutab[su[0]] + gvtab[sv[0]];
  1793.             ruv = rutab[su[0]] + rvtab[sv[0]];
  1794.             y11 = ytab[sy1[0]];
  1795.             y21 = ytab[sy2[0]];
  1796.             /* first line BGR */
  1797.             d1[0] = CLIP8[y11 + buv];
  1798.             d1[1] = CLIP8[y11 + guv];
  1799.             d1[2] = CLIP8[y11 + ruv];
  1800.             /* second line BGR */
  1801.             d2[0] = CLIP8[y21 + buv];
  1802.             d2[1] = CLIP8[y21 + guv];
  1803.             d2[2] = CLIP8[y21 + ruv];
  1804.             sy1 += 1; sy2 += 1;
  1805.             su += 1; sv += 1;
  1806.             d1 += BPP3; d2 += BPP3;
  1807.             dest_x ++; dx --;
  1808.         }
  1809.         /* convert first 2x2 block: */
  1810.         if (dest_x & 2) {
  1811.             buv = butab[su[0]] + bvtab[sv[0]];
  1812.             guv = gutab[su[0]] + gvtab[sv[0]];
  1813.             ruv = rutab[su[0]] + rvtab[sv[0]];
  1814.             y11 = ytab[sy1[0]];
  1815.             y21 = ytab[sy2[0]];
  1816.             /* first line BGR */
  1817.             d1[0] = CLIP8[y11 + buv];
  1818.             d1[1] = CLIP8[y11 + guv];
  1819.             d1[2] = CLIP8[y11 + ruv];
  1820.             /* second line BGR */
  1821.             d2[0] = CLIP8[y21 + buv];
  1822.             d2[1] = CLIP8[y21 + guv];
  1823.             d2[2] = CLIP8[y21 + ruv];
  1824.             y12 = ytab[sy1[1]];
  1825.             y22 = ytab[sy2[1]];
  1826.             /* first line BGR */
  1827.             d1[0+BPP3] = CLIP8[y12 + buv];
  1828.             d1[1+BPP3] = CLIP8[y12 + guv];
  1829.             d1[2+BPP3] = CLIP8[y12 + ruv];
  1830.             /* second line BGR */
  1831.             d2[0+BPP3] = CLIP8[y22 + buv];
  1832.             d2[1+BPP3] = CLIP8[y22 + guv];
  1833.             d2[2+BPP3] = CLIP8[y22 + ruv];
  1834.             sy1 += 2; sy2 += 2;
  1835.             su += 1; sv += 1;
  1836.             d1 += 2*BPP3; d2 += 2*BPP3;
  1837.             dest_x += 2; dx -= 2;
  1838.         }
  1839.         /* convert all integral 2x4 blocks: */
  1840.         for (i = 0; i < dx/4; i ++) {
  1841.             buv = butab[su[0]] + bvtab[sv[0]];
  1842.             guv = gutab[su[0]] + gvtab[sv[0]];
  1843.             ruv = rutab[su[0]] + rvtab[sv[0]];
  1844.             y11 = ytab[sy1[0]];
  1845.             y12 = ytab[sy1[1]];
  1846.             /* first line BGRB */
  1847.             *(unsigned int *)(d1+0) =
  1848.                 (CLIP8[y11 + buv])       |
  1849.                 (CLIP8[y11 + guv] << 8)  |
  1850.                 (CLIP8[y11 + ruv] << 16) |
  1851.                 (CLIP8[y12 + buv] << 24) ;
  1852.             y21 = ytab[sy2[0]];
  1853.             y22 = ytab[sy2[1]];
  1854.             /* second line BGRB */
  1855.             *(unsigned int *)(d2+0) =
  1856.                 (CLIP8[y21 + buv])       |
  1857.                 (CLIP8[y21 + guv] << 8)  |
  1858.                 (CLIP8[y21 + ruv] << 16) |
  1859.                 (CLIP8[y22 + buv] << 24) ;
  1860.             buv2 = butab[su[1]] + bvtab[sv[1]];
  1861.             guv2 = gutab[su[1]] + gvtab[sv[1]];
  1862.             y13 = ytab[sy1[2]];
  1863.             /* first line GRBG */
  1864.             *(unsigned int *)(d1+4) =
  1865.                 (CLIP8[y12 + guv])        |
  1866.                 (CLIP8[y12 + ruv]  << 8)  |
  1867.                 (CLIP8[y13 + buv2] << 16) |
  1868.                 (CLIP8[y13 + guv2] << 24) ;
  1869.             y23 = ytab[sy2[2]];
  1870.             /* second line GRBG */
  1871.             *(unsigned int *)(d2+4) =
  1872.                 (CLIP8[y22 + guv])        |
  1873.                 (CLIP8[y22 + ruv]  << 8)  |
  1874.                 (CLIP8[y23 + buv2] << 16) |
  1875.                 (CLIP8[y23 + guv2] << 24) ;
  1876.             y14 = ytab[sy1[3]];
  1877.             ruv2 = rutab[su[1]]+rvtab[sv[1]];
  1878.             /* first line RBGR */
  1879.             *(unsigned int *)(d1+8) =
  1880.                 (CLIP8[y13 + ruv2])       |
  1881.                 (CLIP8[y14 + buv2] << 8)  |
  1882.                 (CLIP8[y14 + guv2] << 16) |
  1883.                 (CLIP8[y14 + ruv2] << 24) ;
  1884.             y24 = ytab[sy2[3]];
  1885.             /* second line RBGR */
  1886.             *(unsigned int *)(d2+8) =
  1887.                 (CLIP8[y23 + ruv2])       |
  1888.                 (CLIP8[y24 + buv2] << 8)  |
  1889.                 (CLIP8[y24 + guv2] << 16) |
  1890.                 (CLIP8[y24 + ruv2] << 24) ;
  1891.             /* next 4x2 block */
  1892.             sy1 += 4; sy2 += 4;
  1893.             su += 2; sv += 2;
  1894.             d1 += 4*BPP3; d2 += 4*BPP3;
  1895.         }
  1896.         /* convert last 2x2 block: */
  1897.         if (dx & 2) {
  1898.             buv = butab[su[0]] + bvtab[sv[0]];
  1899.             guv = gutab[su[0]] + gvtab[sv[0]];
  1900.             ruv = rutab[su[0]] + rvtab[sv[0]];
  1901.             y11 = ytab[sy1[0]];
  1902.             y21 = ytab[sy2[0]];
  1903.             /* first line BGR */
  1904.             d1[0] = CLIP8[y11 + buv];
  1905.             d1[1] = CLIP8[y11 + guv];
  1906.             d1[2] = CLIP8[y11 + ruv];
  1907.             /* second line BGR */
  1908.             d2[0] = CLIP8[y21 + buv];
  1909.             d2[1] = CLIP8[y21 + guv];
  1910.             d2[2] = CLIP8[y21 + ruv];
  1911.             y12 = ytab[sy1[1]];
  1912.             y22 = ytab[sy2[1]];
  1913.             /* first line BGR */
  1914.             d1[0+BPP3] = CLIP8[y12 + buv];
  1915.             d1[1+BPP3] = CLIP8[y12 + guv];
  1916.             d1[2+BPP3] = CLIP8[y12 + ruv];
  1917.             /* second line BGR */
  1918.             d2[0+BPP3] = CLIP8[y22 + buv];
  1919.             d2[1+BPP3] = CLIP8[y22 + guv];
  1920.             d2[2+BPP3] = CLIP8[y22 + ruv];
  1921.             sy1 += 2; sy2 += 2;
  1922.             su += 1; sv += 1;
  1923.             d1 += 2*BPP3; d2 += 2*BPP3;
  1924.             dx -= 2;
  1925.         }
  1926.         /* convert last 2x1 block: */
  1927.         if (dx & 1) {
  1928.             buv = butab[su[0]] + bvtab[sv[0]];
  1929.             guv = gutab[su[0]] + gvtab[sv[0]];
  1930.             ruv = rutab[su[0]] + rvtab[sv[0]];
  1931.             y11 = ytab[sy1[0]];
  1932.             y21 = ytab[sy2[0]];
  1933.             /* first line BGR */
  1934.             d1[0] = CLIP8[y11 + buv];
  1935.             d1[1] = CLIP8[y11 + guv];
  1936.             d1[2] = CLIP8[y11 + ruv];
  1937.             /* second line BGR */
  1938.             d2[0] = CLIP8[y21 + buv];
  1939.             d2[1] = CLIP8[y21 + guv];
  1940.             d2[2] = CLIP8[y21 + ruv];
  1941.         }
  1942.     } else {
  1943.         /* a more generic implentation */
  1944.         register int y11, y12, y21, y22;
  1945.         register int ruv, guv, buv;
  1946.         register int i;
  1947.         /* convert first 2x1 block: */
  1948.         if (dest_x & 1) {
  1949.             buv = butab[su[0]] + bvtab[sv[0]];
  1950.             guv = gutab[su[0]] + gvtab[sv[0]];
  1951.             ruv = rutab[su[0]] + rvtab[sv[0]];
  1952.             y11 = ytab[sy1[0]];
  1953.             y21 = ytab[sy2[0]];
  1954.             /* first line BGR */
  1955.             d1[0] = CLIP8[y11 + buv];
  1956.             d1[1] = CLIP8[y11 + guv];
  1957.             d1[2] = CLIP8[y11 + ruv];
  1958.             /* second line BGR */
  1959.             d2[0] = CLIP8[y21 + buv];
  1960.             d2[1] = CLIP8[y21 + guv];
  1961.             d2[2] = CLIP8[y21 + ruv];
  1962.             sy1 += 1; sy2 += 1;
  1963.             su += 1; sv += 1;
  1964.             d1 += BPP3; d2 += BPP3;
  1965.             dest_x ++; dx --;
  1966.         }
  1967.         /* convert all integral 2x4 blocks: */
  1968.         for (i = 0; i < dx/2; i ++) {
  1969.             buv = butab[su[0]] + bvtab[sv[0]];
  1970.             guv = gutab[su[0]] + gvtab[sv[0]];
  1971.             ruv = rutab[su[0]] + rvtab[sv[0]];
  1972.             y11 = ytab[sy1[0]];
  1973.             y12 = ytab[sy1[1]];
  1974.             /* first line BGR,BGR: */
  1975.             d1[0] = CLIP8[y11 + buv];
  1976.             d1[1] = CLIP8[y11 + guv];
  1977.             d1[2] = CLIP8[y11 + ruv];
  1978.             d1[3] = CLIP8[y12 + buv];
  1979.             d1[4] = CLIP8[y12 + guv];
  1980.             d1[5] = CLIP8[y12 + ruv];
  1981.             y21 = ytab[sy2[0]];
  1982.             y22 = ytab[sy2[1]];
  1983.             /* second line BGR,BGR: */
  1984.             d2[0] = CLIP8[y21 + buv];
  1985.             d2[1] = CLIP8[y21 + guv];
  1986.             d2[2] = CLIP8[y21 + ruv];
  1987.             d2[3] = CLIP8[y22 + buv];
  1988.             d2[4] = CLIP8[y22 + guv];
  1989.             d2[5] = CLIP8[y22 + ruv];
  1990.             /* next 2x2 block */
  1991.             sy1 += 2; sy2 += 2;
  1992.             su += 1; sv += 1;
  1993.             d1 += 2*BPP3; d2 += 2*BPP3;
  1994.         }
  1995.         /* convert last 2x1 block: */
  1996.         if (dx & 1) {
  1997.             buv = butab[su[0]] + bvtab[sv[0]];
  1998.             guv = gutab[su[0]] + gvtab[sv[0]];
  1999.             ruv = rutab[su[0]] + rvtab[sv[0]];
  2000.             y11 = ytab[sy1[0]];
  2001.             y21 = ytab[sy2[0]];
  2002.             /* first line BGR */
  2003.             d1[0] = CLIP8[y11 + buv];
  2004.             d1[1] = CLIP8[y11 + guv];
  2005.             d1[2] = CLIP8[y11 + ruv];
  2006.             /* second line BGR */
  2007.             d2[0] = CLIP8[y21 + buv];
  2008.             d2[1] = CLIP8[y21 + guv];
  2009.             d2[2] = CLIP8[y21 + ruv];
  2010.         }
  2011.     }
  2012. }
  2013. static void dblineI420toRGB565 (unsigned char *d1, unsigned char *d2, int dest_x,
  2014.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  2015.     int src_x, int dx)
  2016. {
  2017.     /* check if we have misaligned input/output: */
  2018.     if ((src_x ^ dest_x) & 1) {
  2019.         ; /* not implemented yet */
  2020.     } else {
  2021.         /* aligned input/output: */
  2022.         register int y11, y12, y21, y22;
  2023.         register int rv, guv, bu;
  2024.         register int i;
  2025.         /* convert first 2x1 block: */
  2026.         if (dest_x & 1) {
  2027.             rv  = rvtab[sv[0]];
  2028.             guv = gutab[su[0]] + gvtab[sv[0]];
  2029.             bu  = butab[su[0]];
  2030.             y11 = ytab[sy1[0]];
  2031.             y21 = ytab[sy2[0]];
  2032.             /* output 2 bytes at a time */
  2033.             *(unsigned short *)(d1+0) =
  2034.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2035.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2036.                 (CLIP5[y11 + rv  + DITH5L] << 11) ;
  2037.             *(unsigned short *)(d2+0) =
  2038.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2039.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2040.                 (CLIP5[y21 + rv  + DITH5H] << 11) ;
  2041.             sy1 += 1; sy2 += 1;
  2042.             su += 1; sv += 1;
  2043.             d1 += BPP2; d2 += BPP2;
  2044.             dest_x ++; dx --;
  2045.         }
  2046.         /* convert first 2x2 block: */
  2047.         if (dest_x & 2) {
  2048.             rv  = rvtab[sv[0]];
  2049.             guv = gutab[su[0]] + gvtab[sv[0]];
  2050.             bu  = butab[su[0]];
  2051.             y11 = ytab[sy1[0]];
  2052.             y12 = ytab[sy1[1]];
  2053.             /* output 4 bytes at a time */
  2054.             *(unsigned int *)(d1+0) =
  2055.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2056.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2057.                 (CLIP5[y11 + rv  + DITH5L] << 11) |
  2058.                 (CLIP5[y12 + bu  + DITH5H] << 16) |
  2059.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2060.                 (CLIP5[y12 + rv  + DITH5H] << 27) ;
  2061.             y21 = ytab[sy2[0]];
  2062.             y22 = ytab[sy2[1]];
  2063.             *(unsigned int *)(d2+0) =
  2064.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2065.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2066.                 (CLIP5[y21 + rv  + DITH5H] << 11) |
  2067.                 (CLIP5[y22 + bu  + DITH5L] << 16) |
  2068.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2069.                 (CLIP5[y22 + rv  + DITH5L] << 27) ;
  2070.             sy1 += 2; sy2 += 2;
  2071.             su += 1; sv += 1;
  2072.             d1 += 2*BPP2; d2 += 2*BPP2;
  2073.             dest_x += 2; dx -= 2;
  2074.         }
  2075.         /* convert all integral 2x4 blocks: */
  2076.         for (i = 0; i < dx/4; i ++) {
  2077.             /* first 2x2 block */
  2078.             rv = rvtab[sv[0]];
  2079.             guv = gutab[su[0]] + gvtab[sv[0]];
  2080.             bu = butab[su[0]];
  2081.             y11 = ytab[sy1[0]];
  2082.             y12 = ytab[sy1[1]];
  2083.             /* output 4 bytes at a time */
  2084.             *(unsigned int *)(d1+0) =
  2085.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2086.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2087.                 (CLIP5[y11 + rv  + DITH5L] << 11) |
  2088.                 (CLIP5[y12 + bu  + DITH5H] << 16) |
  2089.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2090.                 (CLIP5[y12 + rv  + DITH5H] << 27) ;
  2091.             y21 = ytab[sy2[0]];
  2092.             y22 = ytab[sy2[1]];
  2093.             *(unsigned int *)(d2+0) =
  2094.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2095.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2096.                 (CLIP5[y21 + rv  + DITH5H] << 11) |
  2097.                 (CLIP5[y22 + bu  + DITH5L] << 16) |
  2098.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2099.                 (CLIP5[y22 + rv  + DITH5L] << 27) ;
  2100.             /* second 2x2 block */
  2101.             rv  = rvtab[sv[1]];
  2102.             guv = gutab[su[1]] + gvtab[sv[1]];
  2103.             bu  = butab[su[1]];
  2104.             y11 = ytab[sy1[2]];
  2105.             y12 = ytab[sy1[3]];
  2106.             *(unsigned int *)(d1+2*BPP2) =
  2107.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2108.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2109.                 (CLIP5[y11 + rv  + DITH5L] << 11) |
  2110.                 (CLIP5[y12 + bu  + DITH5H] << 16) |
  2111.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2112.                 (CLIP5[y12 + rv  + DITH5H] << 27) ;
  2113.             y21 = ytab[sy2[2]];
  2114.             y22 = ytab[sy2[3]];
  2115.             *(unsigned int *)(d2+2*BPP2) =
  2116.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2117.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2118.                 (CLIP5[y21 + rv  + DITH5H] << 11) |
  2119.                 (CLIP5[y22 + bu  + DITH5L] << 16) |
  2120.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2121.                 (CLIP5[y22 + rv  + DITH5L] << 27) ;
  2122.             /* next 4x2 block */
  2123.             sy1 += 4; sy2 += 4;
  2124.             su += 2; sv += 2;
  2125.             d1 += 4*BPP2; d2 += 4*BPP2;
  2126.         }
  2127.         /* convert last 2x2 block: */
  2128.         if (dx & 2) {
  2129.             rv = rvtab[sv[0]];
  2130.             guv = gutab[su[0]] + gvtab[sv[0]];
  2131.             bu = butab[su[0]];
  2132.             y11 = ytab[sy1[0]];
  2133.             y12 = ytab[sy1[1]];
  2134.             /* output 4 bytes at a time */
  2135.             *(unsigned int *)(d1+0) =
  2136.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2137.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2138.                 (CLIP5[y11 + rv  + DITH5L] << 11) |
  2139.                 (CLIP5[y12 + bu  + DITH5H] << 16) |
  2140.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2141.                 (CLIP5[y12 + rv  + DITH5H] << 27) ;
  2142.             y21 = ytab[sy2[0]];
  2143.             y22 = ytab[sy2[1]];
  2144.             *(unsigned int *)(d2+0) =
  2145.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2146.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2147.                 (CLIP5[y21 + rv  + DITH5H] << 11) |
  2148.                 (CLIP5[y22 + bu  + DITH5L] << 16) |
  2149.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2150.                 (CLIP5[y22 + rv  + DITH5L] << 27) ;
  2151.             sy1 += 2; sy2 += 2;
  2152.             su += 1; sv += 1;
  2153.             d1 += 2*BPP2; d2 += 2*BPP2;
  2154.             dx -= 2;
  2155.         }
  2156.         /* convert last 2x1 block: */
  2157.         if (dx & 1) {
  2158.             rv  = rvtab[sv[0]];
  2159.             guv = gutab[su[0]] + gvtab[sv[0]];
  2160.             bu  = butab[su[0]];
  2161.             y11 = ytab[sy1[0]];
  2162.             y21 = ytab[sy2[0]];
  2163.             /* output 2 bytes at a time */
  2164.             *(unsigned short *)(d1+0) =
  2165.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2166.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2167.                 (CLIP5[y11 + rv  + DITH5L] << 11) ;
  2168.             *(unsigned short *)(d2+0) =
  2169.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2170.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2171.                 (CLIP5[y21 + rv  + DITH5H] << 11) ;
  2172.         }
  2173.     }
  2174. }
  2175. static void dblineI420toRGB565alpha (unsigned char *d1, unsigned char *d2, int dest_x,
  2176.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  2177.     int src_x, int dx)
  2178. {
  2179.     /* check if we have misaligned input/output: */
  2180.     if ((src_x ^ dest_x) & 1) {
  2181.         ; /* not implemented yet */
  2182.     } else {
  2183.         /* aligned input/output: */
  2184.         register int y11, y12, y21, y22;
  2185.         register int ruv, guv, buv;
  2186.         register int i;
  2187.         /* convert first 2x1 block: */
  2188.         if (dest_x & 1) {
  2189.             ruv = rutab[su[0]] + rvtab[sv[0]];
  2190.             guv = gutab[su[0]] + gvtab[sv[0]];
  2191.             buv = butab[su[0]] + bvtab[sv[0]];
  2192.             y11 = ytab[sy1[0]];
  2193.             y21 = ytab[sy2[0]];
  2194.             /* output 2 bytes at a time */
  2195.             *(unsigned short *)(d1+0) =
  2196.                 (CLIP5[y11 + buv + DITH5L] << 0)  |
  2197.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2198.                 (CLIP5[y11 + ruv + DITH5L] << 11) ;
  2199.             *(unsigned short *)(d2+0) =
  2200.                 (CLIP5[y21 + buv + DITH5H] << 0)  |
  2201.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2202.                 (CLIP5[y21 + ruv + DITH5H] << 11) ;
  2203.             sy1 += 1; sy2 += 1;
  2204.             su += 1; sv += 1;
  2205.             d1 += BPP2; d2 += BPP2;
  2206.             dest_x ++; dx --;
  2207.         }
  2208.         /* convert first 2x2 block: */
  2209.         if (dest_x & 2) {
  2210.             ruv = rutab[su[0]] + rvtab[sv[0]];
  2211.             guv = gutab[su[0]] + gvtab[sv[0]];
  2212.             buv = butab[su[0]] + bvtab[sv[0]];
  2213.             y11 = ytab[sy1[0]];
  2214.             y12 = ytab[sy1[1]];
  2215.             /* output 4 bytes at a time */
  2216.             *(unsigned int *)(d1+0) =
  2217.                 (CLIP5[y11 + buv + DITH5L] << 0)  |
  2218.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2219.                 (CLIP5[y11 + ruv + DITH5L] << 11) |
  2220.                 (CLIP5[y12 + buv + DITH5H] << 16) |
  2221.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2222.                 (CLIP5[y12 + ruv + DITH5H] << 27) ;
  2223.             y21 = ytab[sy2[0]];
  2224.             y22 = ytab[sy2[1]];
  2225.             *(unsigned int *)(d2+0) =
  2226.                 (CLIP5[y21 + buv + DITH5H] << 0)  |
  2227.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2228.                 (CLIP5[y21 + ruv + DITH5H] << 11) |
  2229.                 (CLIP5[y22 + buv + DITH5L] << 16) |
  2230.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2231.                 (CLIP5[y22 + ruv + DITH5L] << 27) ;
  2232.             sy1 += 2; sy2 += 2;
  2233.             su += 1; sv += 1;
  2234.             d1 += 2*BPP2; d2 += 2*BPP2;
  2235.             dest_x += 2; dx -= 2;
  2236.         }
  2237.         /* convert all integral 2x4 blocks: */
  2238.         for (i = 0; i < dx/4; i ++) {
  2239.             /* first 2x2 block */
  2240.             ruv = rutab[su[0]] + rvtab[sv[0]];
  2241.             guv = gutab[su[0]] + gvtab[sv[0]];
  2242.             buv = butab[su[0]] + bvtab[sv[0]];
  2243.             y11 = ytab[sy1[0]];
  2244.             y12 = ytab[sy1[1]];
  2245.             /* output 4 bytes at a time */
  2246.             *(unsigned int *)(d1+0) =
  2247.                 (CLIP5[y11 + buv + DITH5L] << 0)  |
  2248.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2249.                 (CLIP5[y11 + ruv + DITH5L] << 11) |
  2250.                 (CLIP5[y12 + buv + DITH5H] << 16) |
  2251.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2252.                 (CLIP5[y12 + ruv + DITH5H] << 27) ;
  2253.             y21 = ytab[sy2[0]];
  2254.             y22 = ytab[sy2[1]];
  2255.             *(unsigned int *)(d2+0) =
  2256.                 (CLIP5[y21 + buv + DITH5H] << 0)  |
  2257.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2258.                 (CLIP5[y21 + ruv + DITH5H] << 11) |
  2259.                 (CLIP5[y22 + buv + DITH5L] << 16) |
  2260.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2261.                 (CLIP5[y22 + ruv + DITH5L] << 27) ;
  2262.             /* second 2x2 block */
  2263.             ruv = rutab[su[1]] + rvtab[sv[1]];
  2264.             guv = gutab[su[1]] + gvtab[sv[1]];
  2265.             buv = butab[su[1]] + bvtab[sv[1]];
  2266.             y11 = ytab[sy1[2]];
  2267.             y12 = ytab[sy1[3]];
  2268.             *(unsigned int *)(d1+2*BPP2) =
  2269.                 (CLIP5[y11 + buv + DITH5L] << 0)  |
  2270.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2271.                 (CLIP5[y11 + ruv + DITH5L] << 11) |
  2272.                 (CLIP5[y12 + buv + DITH5H] << 16) |
  2273.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2274.                 (CLIP5[y12 + ruv + DITH5H] << 27) ;
  2275.             y21 = ytab[sy2[2]];
  2276.             y22 = ytab[sy2[3]];
  2277.             *(unsigned int *)(d2+2*BPP2) =
  2278.                 (CLIP5[y21 + buv + DITH5H] << 0)  |
  2279.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2280.                 (CLIP5[y21 + ruv + DITH5H] << 11) |
  2281.                 (CLIP5[y22 + buv + DITH5L] << 16) |
  2282.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2283.                 (CLIP5[y22 + ruv + DITH5L] << 27) ;
  2284.             /* next 4x2 block */
  2285.             sy1 += 4; sy2 += 4;
  2286.             su += 2; sv += 2;
  2287.             d1 += 4*BPP2; d2 += 4*BPP2;
  2288.         }
  2289.         /* convert last 2x2 block: */
  2290.         if (dx & 2) {
  2291.             ruv = rutab[su[0]] + rvtab[sv[0]];
  2292.             guv = gutab[su[0]] + gvtab[sv[0]];
  2293.             buv = butab[su[0]] + bvtab[sv[0]];
  2294.             y11 = ytab[sy1[0]];
  2295.             y12 = ytab[sy1[1]];
  2296.             /* output 4 bytes at a time */
  2297.             *(unsigned int *)(d1+0) =
  2298.                 (CLIP5[y11 + buv + DITH5L] << 0)  |
  2299.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2300.                 (CLIP5[y11 + ruv + DITH5L] << 11) |
  2301.                 (CLIP5[y12 + buv + DITH5H] << 16) |
  2302.                 (CLIP6[y12 + guv + DITH6H] << 21) |
  2303.                 (CLIP5[y12 + ruv + DITH5H] << 27) ;
  2304.             y21 = ytab[sy2[0]];
  2305.             y22 = ytab[sy2[1]];
  2306.             *(unsigned int *)(d2+0) =
  2307.                 (CLIP5[y21 + buv + DITH5H] << 0)  |
  2308.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2309.                 (CLIP5[y21 + ruv + DITH5H] << 11) |
  2310.                 (CLIP5[y22 + buv + DITH5L] << 16) |
  2311.                 (CLIP6[y22 + guv + DITH6L] << 21) |
  2312.                 (CLIP5[y22 + ruv + DITH5L] << 27) ;
  2313.             sy1 += 2; sy2 += 2;
  2314.             su += 1; sv += 1;
  2315.             d1 += 2*BPP2; d2 += 2*BPP2;
  2316.             dx -= 2;
  2317.         }
  2318.         /* convert last 2x1 block: */
  2319.         if (dx & 1) {
  2320.             ruv = rutab[su[0]] + rvtab[sv[0]];
  2321.             guv = gutab[su[0]] + gvtab[sv[0]];
  2322.             buv = butab[su[0]] + bvtab[sv[0]];
  2323.             y11 = ytab[sy1[0]];
  2324.             y21 = ytab[sy2[0]];
  2325.             /* output 2 bytes at a time */
  2326.             *(unsigned short *)(d1+0) =
  2327.                 (CLIP5[y11 + buv + DITH5L] << 0)  |
  2328.                 (CLIP6[y11 + guv + DITH6L] << 5)  |
  2329.                 (CLIP5[y11 + ruv + DITH5L] << 11) ;
  2330.             *(unsigned short *)(d2+0) =
  2331.                 (CLIP5[y21 + buv + DITH5H] << 0)  |
  2332.                 (CLIP6[y21 + guv + DITH6H] << 5)  |
  2333.                 (CLIP5[y21 + ruv + DITH5H] << 11) ;
  2334.         }
  2335.     }
  2336. }
  2337. static void dblineI420toRGB555 (unsigned char *d1, unsigned char *d2, int dest_x,
  2338.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  2339.     int src_x, int dx)
  2340. {
  2341.     /* check if we have misaligned input/output: */
  2342.     if ((src_x ^ dest_x) & 1) {
  2343.         ; /* not implemented yet */
  2344.     } else {
  2345.         /* aligned input/output: */
  2346.         register int y11, y12, y21, y22;
  2347.         register int rv, guv, bu;
  2348.         register int i;
  2349.         /* convert first 2x1 block: */
  2350.         if (dest_x & 1) {
  2351.             rv  = rvtab[sv[0]];
  2352.             guv = gutab[su[0]] + gvtab[sv[0]];
  2353.             bu  = butab[su[0]];
  2354.             y11 = ytab[sy1[0]];
  2355.             y21 = ytab[sy2[0]];
  2356.             /* output 2 bytes at a time */
  2357.             *(unsigned short *)(d1+0) =
  2358.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2359.                 (CLIP5[y11 + guv + DITH5L] << 5)  |
  2360.                 (CLIP5[y11 + rv  + DITH5L] << 10) ;
  2361.             *(unsigned short *)(d2+0) =
  2362.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2363.                 (CLIP5[y21 + guv + DITH5H] << 5)  |
  2364.                 (CLIP5[y21 + rv  + DITH5H] << 10) ;
  2365.             sy1 += 1; sy2 += 1;
  2366.             su += 1; sv += 1;
  2367.             d1 += BPP2; d2 += BPP2;
  2368.             dest_x ++; dx --;
  2369.         }
  2370.         /* convert first 2x2 block: */
  2371.         if (dest_x & 2) {
  2372.             rv  = rvtab[sv[0]];
  2373.             guv = gutab[su[0]] + gvtab[sv[0]];
  2374.             bu  = butab[su[0]];
  2375.             y11 = ytab[sy1[0]];
  2376.             y12 = ytab[sy1[1]];
  2377.             /* output 4 bytes at a time */
  2378.             *(unsigned int *)(d1+0) =
  2379.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2380.                 (CLIP5[y11 + guv + DITH5L] << 5)  |
  2381.                 (CLIP5[y11 + rv  + DITH5L] << 10) |
  2382.                 (CLIP5[y12 + bu  + DITH5H] << 16) |
  2383.                 (CLIP5[y12 + guv + DITH5H] << 21) |
  2384.                 (CLIP5[y12 + rv  + DITH5H] << 26) ;
  2385.             y21 = ytab[sy2[0]];
  2386.             y22 = ytab[sy2[1]];
  2387.             *(unsigned int *)(d2+0) =
  2388.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2389.                 (CLIP5[y21 + guv + DITH5H] << 5)  |
  2390.                 (CLIP5[y21 + rv  + DITH5H] << 10) |
  2391.                 (CLIP5[y22 + bu  + DITH5L] << 16) |
  2392.                 (CLIP5[y22 + guv + DITH5L] << 21) |
  2393.                 (CLIP5[y22 + rv  + DITH5L] << 26) ;
  2394.             sy1 += 2; sy2 += 2;
  2395.             su += 1; sv += 1;
  2396.             d1 += 2*BPP2; d2 += 2*BPP2;
  2397.             dest_x += 2; dx -= 2;
  2398.         }
  2399.         /* convert all integral 2x4 blocks: */
  2400.         for (i = 0; i < dx/4; i ++) {
  2401.             /* first 2x2 block */
  2402.             rv = rvtab[sv[0]];
  2403.             guv = gutab[su[0]] + gvtab[sv[0]];
  2404.             bu = butab[su[0]];
  2405.             y11 = ytab[sy1[0]];
  2406.             y12 = ytab[sy1[1]];
  2407.             /* output 4 bytes at a time */
  2408.             *(unsigned int *)(d1+0) =
  2409.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2410.                 (CLIP5[y11 + guv + DITH5L] << 5)  |
  2411.                 (CLIP5[y11 + rv  + DITH5L] << 10) |
  2412.                 (CLIP5[y12 + bu  + DITH5H] << 16) |
  2413.                 (CLIP5[y12 + guv + DITH5H] << 21) |
  2414.                 (CLIP5[y12 + rv  + DITH5H] << 26) ;
  2415.             y21 = ytab[sy2[0]];
  2416.             y22 = ytab[sy2[1]];
  2417.             *(unsigned int *)(d2+0) =
  2418.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2419.                 (CLIP5[y21 + guv + DITH5H] << 5)  |
  2420.                 (CLIP5[y21 + rv  + DITH5H] << 10) |
  2421.                 (CLIP5[y22 + bu  + DITH5L] << 16) |
  2422.                 (CLIP5[y22 + guv + DITH5L] << 21) |
  2423.                 (CLIP5[y22 + rv  + DITH5L] << 26) ;
  2424.             /* second 2x2 block */
  2425.             rv  = rvtab[sv[1]];
  2426.             guv = gutab[su[1]] + gvtab[sv[1]];
  2427.             bu  = butab[su[1]];
  2428.             y11 = ytab[sy1[2]];
  2429.             y12 = ytab[sy1[3]];
  2430.             *(unsigned int *)(d1+2*BPP2) =
  2431.                 (CLIP5[y11 + bu  + DITH5L] << 0)  |
  2432.                 (CLIP5[y11 + guv + DITH5L] << 5)  |
  2433.                 (CLIP5[y11 + rv  + DITH5L] << 10) |
  2434.                 (CLIP5[y12 + bu  + DITH5H] << 16) |
  2435.                 (CLIP5[y12 + guv + DITH5H] << 21) |
  2436.                 (CLIP5[y12 + rv  + DITH5H] << 26) ;
  2437.             y21 = ytab[sy2[2]];
  2438.             y22 = ytab[sy2[3]];
  2439.             *(unsigned int *)(d2+2*BPP2) =
  2440.                 (CLIP5[y21 + bu  + DITH5H] << 0)  |
  2441.                 (CLIP5[y21 + guv + DITH5H] << 5)  |
  2442.                 (CLIP5[y21 + rv  + DITH5H] << 10) |
  2443.                 (CLIP5[y22 + bu  + DITH5L] << 16) |
  2444.                 (CLIP5[y22 + guv + DITH5L] << 21) |
  2445.                 (CLIP5[y22 + rv  + DITH5L] << 26) ;
  2446.             /* next 4x2 block */
  2447.             sy1 += 4; sy2 += 4;
  2448.             su += 2; sv += 2;
  2449.             d1 += 4*BPP2; d2 += 4*BPP2;
  2450.         }
  2451.         /* convert last 2x2 block: */
  2452.         if (dx & 2) {