colorcvt.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:288k
源码类别:

Symbian

开发平台:

C/C++

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