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

Symbian

开发平台:

Visual C++

  1.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  2.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  3.         /* convert image: */
  4.         for (i = 0; i < dest_dy; i ++) {
  5.             /* convert a line: */
  6.             register int ddx = dest_dx;
  7.             while (ddx) {
  8.                 /* RGB -> 0BGR: */
  9.                 *(unsigned int *)d = (unsigned int)
  10.                     (s[0] << 16) | (s[1] << 8) | s[2];
  11.                 d += BPP4; s += BPP3;
  12.                 ddx --;
  13.             }
  14.             s += src_pitch - dest_dx * BPP3;
  15.             d += dest_pitch - dest_dx * BPP4;
  16.         }
  17.         return 0;
  18.     }
  19.     /* check if 2:1 scale: */
  20.     if (scale_x == 2 && scale_y == 2) {
  21.         /* local variables: */
  22.         unsigned char *s, *d;
  23.         register int i;
  24.         /* get pointers: */
  25.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  26.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  27.         /* convert & stretch image: */
  28.         for (i = 0; i < src_dy; i ++) {
  29.             /* convert & stretch a line: */
  30.             register int sdx = src_dx;
  31.             while (sdx) {
  32.                 /* RGB -> 0BGR: */
  33.                 register unsigned int a;
  34.                 a = (unsigned int)
  35.                     (s[0] << 16) | (s[1] << 8) | s[2];
  36.                 *(unsigned int *)d = a;
  37.                 *(unsigned int *)(d+BPP4) = a;
  38.                 d += 2*BPP4; s += BPP3;
  39.                 sdx --;
  40.             }
  41.             s -= src_dx * BPP3;
  42.             d -= src_dx * 2*BPP4;
  43.             /* replicate a line (vertical stretching): */
  44.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP4); /* Flawfinder: ignore */
  45.             /* bump pointers to the next row: */
  46.             s += src_pitch;
  47.             d += dest_pitch * 2;
  48.         }
  49.         return 0;
  50.     }
  51.     /* conversion is not supported */
  52.     return -1;
  53. }
  54. int RGB565toBGR32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  55.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  56.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  57.     int src_x, int src_y, int src_dx, int src_dy)
  58. {
  59.     /* scale factors: */
  60.     int scale_x, scale_y;
  61.     /* check arguments: */
  62.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  63.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  64.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  65.         return -1;
  66.     /* check if bottom-up bitmaps: */
  67.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  68.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  69.     /* check if 1:1 scale: */
  70.     if (scale_x == 1 && scale_y == 1) {
  71.         /* local variables: */
  72.         unsigned char *s, *d;
  73.         register int i;
  74.         /* get pointers: */
  75.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  76.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  77.         /* convert image: */
  78.         for (i = 0; i < dest_dy; i ++) {
  79.             /* convert a line: */
  80.             register int ddx = dest_dx;
  81.             while (ddx) {
  82.                 /* rrrr,rggg,gggb,bbbb -> 0BGR: */
  83.                 register unsigned short a;
  84.                 a = *(unsigned short *)s;
  85.                 *(unsigned int *)d = (unsigned int)
  86.                     ((a & 0x001F) << 19)|
  87.                     ((a & 0x07E0) << 5) |
  88.                     ((a & 0xF800) >> 8);
  89.                 d += BPP4; s += BPP2;
  90.                 ddx --;
  91.             }
  92.             s += src_pitch - dest_dx * BPP2;
  93.             d += dest_pitch - dest_dx * BPP4;
  94.         }
  95.         return 0;
  96.     }
  97.     /* check if 2:1 scale: */
  98.     if (scale_x == 2 && scale_y == 2) {
  99.         /* local variables: */
  100.         unsigned char *s, *d;
  101.         register int i;
  102.         /* get pointers: */
  103.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  104.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  105.         /* convert & stretch image: */
  106.         for (i = 0; i < src_dy; i ++) {
  107.             /* convert & stretch a line: */
  108.             register int sdx = src_dx;
  109.             while (sdx) {
  110.                 register unsigned short a;
  111.                 register unsigned int c;
  112.                 a = *(unsigned short *)s;
  113.                 c = ((a & 0x001F) << 19)|
  114.                     ((a & 0x07E0) << 5) |
  115.                     ((a & 0xF800) >> 8);
  116.                 *(unsigned int *)d = c;
  117.                 *(unsigned int *)(d+BPP4) = c;
  118.                 d += 2*BPP4; s += BPP2;
  119.                 sdx --;
  120.             }
  121.             s -= src_dx * BPP2;
  122.             d -= src_dx * 2*BPP4;
  123.             /* replicate a line (vertical stretching): */
  124.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP4); /* Flawfinder: ignore */
  125.             /* bump pointers to the next row: */
  126.             s += src_pitch;
  127.             d += dest_pitch * 2;
  128.         }
  129.         return 0;
  130.     }
  131.     /* conversion is not supported */
  132.     return -1;
  133. }
  134. int RGB555toBGR32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  135.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  136.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  137.     int src_x, int src_y, int src_dx, int src_dy)
  138. {
  139.     /* scale factors: */
  140.     int scale_x, scale_y;
  141.     /* check arguments: */
  142.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  143.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  144.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  145.         return -1;
  146.     /* check if bottom-up bitmaps: */
  147.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  148.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  149.     /* check if 1:1 scale: */
  150.     if (scale_x == 1 && scale_y == 1) {
  151.         /* local variables: */
  152.         unsigned char *s, *d;
  153.         register int i;
  154.         /* get pointers: */
  155.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  156.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  157.         /* convert image: */
  158.         for (i = 0; i < dest_dy; i ++) {
  159.             /* convert a line: */
  160.             register int ddx = dest_dx;
  161.             while (ddx) {
  162.                 /* 0rrrr,rgg,gggb,bbbb -> 0BGR: */
  163.                 register unsigned short a;
  164.                 a = *(unsigned short *)s;
  165.                 *(unsigned int *)d = (unsigned int)
  166.                     ((a & 0x001F) << 19)|
  167.                     ((a & 0x03E0) << 6) |
  168.                     ((a & 0x7C00) >> 7);
  169.                 d += BPP4; s += BPP2;
  170.                 ddx --;
  171.             }
  172.             s += src_pitch - dest_dx * BPP2;
  173.             d += dest_pitch - dest_dx * BPP4;
  174.         }
  175.         return 0;
  176.     }
  177.     /* check if 2:1 scale: */
  178.     if (scale_x == 2 && scale_y == 2) {
  179.         /* local variables: */
  180.         unsigned char *s, *d;
  181.         register int i;
  182.         /* get pointers: */
  183.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  184.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  185.         /* convert & stretch image: */
  186.         for (i = 0; i < src_dy; i ++) {
  187.             /* convert & stretch a line: */
  188.             register int sdx = src_dx;
  189.             while (sdx) {
  190.                 register unsigned short a;
  191.                 register unsigned int c;
  192.                 a = *(unsigned short *)s;
  193.                 c = ((a & 0x001F) << 19)|
  194.                     ((a & 0x03E0) << 6) |
  195.                     ((a & 0x7C00) >> 7);
  196.                 *(unsigned int *)d = c;
  197.                 *(unsigned int *)(d+BPP4) = c;
  198.                 d += 2*BPP4; s += BPP2;
  199.                 sdx --;
  200.             }
  201.             s -= src_dx * BPP2;
  202.             d -= src_dx * 2*BPP4;
  203.             /* replicate a line (vertical stretching): */
  204.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP4); /* Flawfinder: ignore */
  205.             /* bump pointers to the next row: */
  206.             s += src_pitch;
  207.             d += dest_pitch * 2;
  208.         }
  209.         return 0;
  210.     }
  211.     /* conversion is not supported */
  212.     return -1;
  213. }
  214. int RGB8toBGR32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  215.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  216.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  217.     int src_x, int src_y, int src_dx, int src_dy)
  218. {
  219.     return -1;   /* not implemented yet... */
  220. }
  221. /********************************
  222.  *
  223.  * "RGBx to RGBy" converters.
  224.  *
  225.  ********************************/
  226. /*
  227.  * RGB32toRGB32() converter:
  228.  *  1:1, 2:1
  229.  */
  230. int RGB32toRGB32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  231.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  232.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  233.     int src_x, int src_y, int src_dx, int src_dy)
  234. {
  235.     /* scale factors: */
  236.     int scale_x, scale_y;
  237.     /* check arguments: */
  238.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  239.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  240.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  241.         return -1;
  242.     /* check if bottom-up bitmaps: */
  243.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  244.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  245.     /* check if 1:1 scale: */
  246.     if (scale_x == 1 && scale_y == 1) {
  247.         /* local variables: */
  248.         unsigned char *s, *d;
  249.         register int i;
  250.         /* get pointers: */
  251.         s = src_ptr + src_x * BPP4 + src_y * src_pitch;
  252.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  253.         /* copy image: */
  254.         for (i = 0; i < dest_dy; i ++) {
  255.             memcpy (d, s, dest_dx * BPP4);  /* copy dest_dx pixels */ /* Flawfinder: ignore */
  256.             s += src_pitch;
  257.             d += dest_pitch;
  258.         }
  259.         return 0;
  260.     }
  261.     /* check if 2:1 scale: */
  262.     if (scale_x == 2 && scale_y == 2) {
  263.         /* local variables: */
  264.         unsigned char *s, *d;
  265.         register int i;
  266.         /* get pointers: */
  267.         s = src_ptr + src_x * BPP4 + src_y * src_pitch;
  268.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  269.         /* stretch image: */
  270.         for (i = 0; i < src_dy; i ++) {
  271.             /* stretch a line: */
  272.             register int sdx = src_dx;
  273.             while (sdx) {
  274.                 register unsigned int a;
  275.                 a = *(unsigned int *)s;
  276.                 *(unsigned int *)d = a;
  277.                 *(unsigned int *)(d+BPP4) = a;
  278.                 d += 2*BPP4; s += BPP4;
  279.                 sdx --;
  280.             }
  281.             s -= src_dx * BPP4;
  282.             d -= src_dx * 2*BPP4;
  283.             /* replicate a line (vertical stretching): */
  284.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP4); /* Flawfinder: ignore */
  285.             /* bump pointers to the next row: */
  286.             s += src_pitch;
  287.             d += dest_pitch * 2;
  288.         }
  289.         return 0;
  290.     }
  291.     /* conversion is not supported */
  292.     return -1;
  293. }
  294. int RGB32toRGB24 (unsigned char *dest_ptr, int dest_width, int dest_height,
  295.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  296.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  297.     int src_x, int src_y, int src_dx, int src_dy)
  298. {
  299.     return -1;   /* not implemented yet... */
  300. }
  301. int RGB32toRGB565 (unsigned char *dest_ptr, int dest_width, int dest_height,
  302.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  303.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  304.     int src_x, int src_y, int src_dx, int src_dy)
  305. {
  306.     return -1;   /* not implemented yet... */
  307. }
  308. int RGB32toRGB555 (unsigned char *dest_ptr, int dest_width, int dest_height,
  309.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  310.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  311.     int src_x, int src_y, int src_dx, int src_dy)
  312. {
  313.     return -1;   /* not implemented yet... */
  314. }
  315. /*
  316.  * No dithering yet.
  317.  */
  318. int RGB32toRGB8 (unsigned char *dest_ptr, int dest_width, int dest_height,
  319.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  320.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  321.     int src_x, int src_y, int src_dx, int src_dy)
  322. {
  323.     /* scale factors: */
  324.     int scale_x, scale_y;
  325.     /* check arguments: */
  326.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  327.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  328.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  329.         return -1;
  330.     /* check if bottom-up bitmaps: */
  331.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  332.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  333.     /* check if 1:1 scale: */
  334.     if (scale_x == 1 && scale_y == 1) {
  335.         /* local variables: */
  336.         unsigned char *s, *d;
  337.         register int i;
  338.         /* get pointers: */
  339.         s = src_ptr + src_x * BPP4 + src_y * src_pitch;
  340.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  341.         /* copy rows: */
  342.         for (i = 0; i < dest_dy; i ++) {
  343.             /* convert a line: */
  344.             register int ddx = dest_dx;
  345.             while (ddx) {
  346.                 register unsigned int a;
  347.                 a = *(unsigned int *)s;             /* BGR0 */
  348.                 *d = pmap[
  349.                     ((a & 0x000000f0) >>  4) |
  350.                     ((a & 0x0000f000) >>  8) |
  351.                     ((a & 0x00f00000) >> 12)];
  352.                 d += BPP1; s += BPP4;
  353.                 ddx --;
  354.             }
  355.             /* bump pointers to the next row: */
  356.             s += src_pitch - dest_dx * BPP4;
  357.             d += dest_pitch - dest_dx * BPP1;
  358.         }
  359.         return 0;
  360.     }
  361.     /* check if 2:1 scale: */
  362.     if (scale_x == 2 && scale_y == 2) {
  363.         /* local variables: */
  364.         unsigned char *s, *d;
  365.         register int i;
  366.         /* get pointers: */
  367.         s = src_ptr + src_x * BPP4 + src_y * src_pitch;
  368.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  369.         /* stretch image: */
  370.         for (i = 0; i < src_dy; i ++) {
  371.             /* stretch a line: */
  372.             register int sdx = src_dx;
  373.             while (sdx) {
  374.                 register unsigned int a;
  375.                 register unsigned char c;
  376.                 a = *(unsigned int *)s;             /* BRG0 */
  377.                 c = pmap[
  378.                     ((a & 0x000000f0) >>  4) |
  379.                     ((a & 0x0000f000) >>  8) |
  380.                     ((a & 0x00f00000) >> 12)];
  381.                 *(d+0) = c;
  382.                 *(d+BPP1) = c;
  383.                 d += 2*BPP1; s += BPP4;
  384.                 sdx --;
  385.             }
  386.             s -= src_dx * BPP4;
  387.             d -= src_dx * 2*BPP1;
  388.             /* replicate a line (vertical stretching): */
  389.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP1); /* Flawfinder: ignore */
  390.             /* bump pointers to the next row: */
  391.             s += src_pitch;
  392.             d += dest_pitch * 2;
  393.         }
  394.         return 0;
  395.     }
  396.     /* conversion is not supported */
  397.     return -1;
  398. }
  399. /*
  400.  * RGB24toRGB32() converter:
  401.  *  1:1, 2:1
  402.  */
  403. int RGB24toRGB32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  404.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  405.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  406.     int src_x, int src_y, int src_dx, int src_dy)
  407. {
  408.     /* scale factors: */
  409.     int scale_x, scale_y;
  410.     /* check arguments: */
  411.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  412.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  413.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  414.         return -1;
  415.     /* check if bottom-up bitmaps: */
  416.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  417.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  418.     /* check if 1:1 scale: */
  419.     if (scale_x == 1 && scale_y == 1) {
  420.         /* local variables: */
  421.         unsigned char *s, *d;
  422.         register int i;
  423.         /* get pointers: */
  424.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  425.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  426.         /* copy rows: */
  427.         for (i = 0; i < dest_dy; i ++) {
  428.             register int sx = src_x, ddx = dest_dx;
  429.             /* process misaligned pixels first: */
  430.             while ((sx & 3) && ddx) {
  431.                 /* BGR -> BGR0: */
  432.                 *(unsigned int *)d = (unsigned int)s[0] | (s[1] << 8) | (s[2] << 16);
  433.                 d += BPP4; s += BPP3;
  434.                 sx ++; ddx --;
  435.             }
  436.             /* main loop: process 4 pixels a time: */
  437.             while (ddx >= 4) {
  438.                 register unsigned int a, b;
  439.                 a = *(unsigned int *)s;             /* BGR.B */
  440.                 b = *(unsigned int *)(s+4);         /* GR.BG */
  441.                 *(unsigned int *)d      = a & 0x00FFFFFF;
  442.                 *(unsigned int *)(d+4)  = ((a >> 24) | (b << 8)) & 0x00FFFFFF;
  443.                 a = *(unsigned int *)(s+8);         /* R.BGR */
  444.                 *(unsigned int *)(d+8)  = ((b >> 16) | (a << 16)) & 0x00FFFFFF;
  445.                 *(unsigned int *)(d+12) = a >> 8;
  446.                 d += BPP4*4; s += BPP3*4;
  447.                 ddx -= 4;
  448.             }
  449.             /* process the remaining 1..3 pixels: */
  450.             while (ddx) {
  451.                 /* RGB -> RGB0: */
  452.                 *(unsigned int *)d = (unsigned int)s[0] | (s[1] << 8) | (s[2] << 16);
  453.                 d += BPP4; s += BPP3;
  454.                 ddx --;
  455.             }
  456.             /* bump pointers to the next row: */
  457.             s += src_pitch - dest_dx * BPP3;
  458.             d += dest_pitch - dest_dx * BPP4;
  459.         }
  460.         return 0;
  461.     }
  462.     /* check if 2:1 scale: */
  463.     if (scale_x == 2 && scale_y == 2) {
  464.         /* local variables: */
  465.         unsigned char *s, *d;
  466.         register int i;
  467.         /* get pointers: */
  468.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  469.         d = dest_ptr + dest_x * BPP4 + dest_y * dest_pitch;
  470.         /* stretch image: */
  471.         for (i = 0; i < src_dy; i ++) {
  472.             /* stretch a line: */
  473.             register int sx = src_x, sdx = src_dx;
  474.             /* misaligned pixels first: */
  475.             while ((sx & 3) && sdx) {
  476.                 /* BGR -> BGR0: */
  477.                 register unsigned int a;
  478.                 a = (unsigned int)s[0] | (s[1] << 8) | (s[2] << 16);
  479.                 *(unsigned int *)d = a;
  480.                 *(unsigned int *)(d+BPP4) = a;
  481.                 d += 2*BPP4; s += BPP3;
  482.                 sx ++; sdx --;
  483.             }
  484.             /* main bulk of data: */
  485.             while (sdx >= 4) {
  486.                 register unsigned int a, b, c;
  487.                 a = *(unsigned int *)s;             /* bgrB */
  488.                 b = *(unsigned int *)(s+4);         /* GRbg */
  489.                 c = a & 0x00FFFFFF;
  490.                 *(unsigned int *)(d) = c;
  491.                 *(unsigned int *)(d+BPP4) = c;
  492.                 c = ((a >> 24) | (b << 8)) & 0x00FFFFFF;
  493.                 *(unsigned int *)(d+2*BPP4) = c;
  494.                 *(unsigned int *)(d+3*BPP4) = c;
  495.                 a = *(unsigned int *)(s+8);         /* rBGR */
  496.                 c = ((b >> 16) | (a << 16)) & 0x00FFFFFF;
  497.                 *(unsigned int *)(d+4*BPP4) = c;
  498.                 *(unsigned int *)(d+5*BPP4) = c;
  499.                 c = a >> 8;
  500.                 *(unsigned int *)(d+6*BPP4) = c;
  501.                 *(unsigned int *)(d+7*BPP4) = c;
  502.                 d += 4*2*BPP4; s += 4*BPP3;
  503.                 sdx -= 4;
  504.             }
  505.             /* the remaining 1..3 pixels: */
  506.             while (sdx) {
  507.                 /* BGR -> BGR0: */
  508.                 register unsigned int a;
  509.                 a = (unsigned int)s[0] | (s[1] << 8) | (s[2] << 16);
  510.                 *(unsigned int *)d = a;
  511.                 *(unsigned int *)(d+BPP4) = a;
  512.                 d += 2*BPP4; s += BPP3;
  513.                 sdx --;
  514.             }
  515.             s -= src_dx * BPP3;
  516.             d -= src_dx * 2*BPP4;
  517.             /* replicate a line (vertical stretching): */
  518.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP4); /* Flawfinder: ignore */
  519.             /* bump pointers to the next row: */
  520.             s += src_pitch;
  521.             d += dest_pitch * 2;
  522.         }
  523.         return 0;
  524.     }
  525.     /* conversion is not supported */
  526.     return -1;
  527. }
  528. /*
  529.  * RGB24toRGB24() converter:
  530.  *  1:1, 2:1
  531.  */
  532. int RGB24toRGB24 (unsigned char *dest_ptr, int dest_width, int dest_height,
  533.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  534.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  535.     int src_x, int src_y, int src_dx, int src_dy)
  536. {
  537.     /* scale factors: */
  538.     int scale_x, scale_y;
  539.     /* check arguments: */
  540.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  541.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  542.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  543.         return -1;
  544.     /* check if bottom-up bitmaps: */
  545.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  546.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  547.     /* check if 1:1 scale: */
  548.     if (scale_x == 1 && scale_y == 1) {
  549.         /* local variables: */
  550.         unsigned char *s, *d;
  551.         register int i;
  552.         /* get pointers: */
  553.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  554.         d = dest_ptr + dest_x * BPP3 + dest_y * dest_pitch;
  555.         /* copy image: */
  556.         for (i = 0; i < dest_dy; i ++) {
  557.             memcpy (d, s, dest_dx * BPP3);  /* copy dest_dx pixels */ /* Flawfinder: ignore */
  558.             s += src_pitch;
  559.             d += dest_pitch;
  560.         }
  561.         return 0;
  562.     }
  563.     /* check if 2:1 scale: */
  564.     if (scale_x == 2 && scale_y == 2) {
  565.         /* local variables: */
  566.         unsigned char *s, *d;
  567.         register int i;
  568.         /* get pointers: */
  569.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  570.         d = dest_ptr + dest_x * BPP3 + dest_y * dest_pitch;
  571.         /* stretch image: */
  572.         for (i = 0; i < src_dy; i ++) {
  573.             /* stretch a line: */
  574.             register int sx = src_x, sdx = src_dx;
  575.             /* misaligned pixels first: */
  576.             while ((sx & 3) && sdx) {
  577.                 register unsigned char a;
  578.                 a = *s; *d = a; *(d+BPP3) = a;
  579.                 a = *(s+1); *(d+1) = a; *(d+1+BPP3) = a;
  580.                 a = *(s+2); *(d+2) = a; *(d+2+BPP3) = a;
  581.                 d += 2*BPP3; s += BPP3;
  582.                 sx ++; sdx --;
  583.             }
  584.             /* main bulk of data: */
  585.             while (sdx >= 4) {
  586.                 register unsigned int a, b;
  587.                 a = *(unsigned int *)s;             /* bgrB */
  588.                 b = *(unsigned int *)(s+4);         /* GRbg */
  589.                 *(unsigned int *)(d) = (a & 0x00FFFFFF) | (a << 24);    /* bgrb */
  590.                 *(unsigned int *)(d+4) = (a >> 8) | (b << 24);          /* grBG */
  591.                 *(unsigned int *)(d+2*4) = ((b & 0xFF00) >> 8) |        /* RBGR */
  592.                                            ((a & 0xFF000000) >> 16) | (b << 16);
  593.                 a = *(unsigned int *)(s+8);         /* rBGR */
  594.                 *(unsigned int *)(d+3*4) = (b >> 16) |                  /* bgrb */
  595.                                            ((a & 0xFF) << 16) | ((b & 0xFF0000) << 8);
  596.                 *(unsigned int *)(d+4*4) = (b >> 24) | (a << 8);        /* grBG */
  597.                 *(unsigned int *)(d+5*4) = (a >> 24) | (a & 0xFFFFFF00);/* RBGR */
  598.                 d += 4*2*BPP3; s += 4*BPP3;
  599.                 sdx -= 4;
  600.             }
  601.             /* the remaining 1..3 pixels: */
  602.             while (sdx) {
  603.                 register unsigned char a;
  604.                 a = *s; *d = a; *(d+BPP3) = a;
  605.                 a = *(s+1); *(d+1) = a; *(d+1+BPP3) = a;
  606.                 a = *(s+2); *(d+2) = a; *(d+2+BPP3) = a;
  607.                 d += 2*BPP3; s += BPP3;
  608.                 sdx --;
  609.             }
  610.             s -= src_dx * BPP3;
  611.             d -= src_dx * 2*BPP3;
  612.             /* replicate a line (vertical stretching): */
  613.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP3); /* Flawfinder: ignore */
  614.             /* bump pointers to the next row: */
  615.             s += src_pitch;
  616.             d += dest_pitch * 2;
  617.         }
  618.         return 0;
  619.     }
  620.     /* conversion is not supported */
  621.     return -1;
  622. }
  623. /*
  624.  * RGB24toRGB565() converter:
  625.  *  1:1, 2:1
  626.  */
  627. int RGB24toRGB565 (unsigned char *dest_ptr, int dest_width, int dest_height,
  628.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  629.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  630.     int src_x, int src_y, int src_dx, int src_dy)
  631. {
  632.     /* scale factors: */
  633.     int scale_x, scale_y;
  634.     /* check arguments: */
  635.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  636.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  637.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  638.         return -1;
  639.     /* check if bottom-up bitmaps: */
  640.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  641.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  642.     /* check if 1:1 scale: */
  643.     if (scale_x == 1 && scale_y == 1) {
  644.         /* local variables: */
  645.         unsigned char *s, *d;
  646.         register int i;
  647.         /* get pointers: */
  648.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  649.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  650.         /* copy rows: */
  651.         for (i = 0; i < dest_dy; i ++) {
  652.             register int sx = src_x, ddx = dest_dx;
  653.             /* process misaligned pixels first: */
  654.             while ((sx & 3) && ddx) {
  655.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.rrrrrggg: */
  656.                 *(unsigned short *)d =
  657.                     (s[0] >> 3) | ((s[1] & 0xFC) << 3) | ((s[2] & 0xF8) << 8);
  658.                 d += BPP2;  s += BPP3;
  659.                 sx ++; ddx --;
  660.             }
  661.             /* main loop: process 4 pixels a time: */
  662.             while (ddx >= 4) {
  663.                 register unsigned int a, b;
  664.                 a = *(unsigned int *)s;             /* BGR.B */
  665.                 b = *(unsigned int *)(s+4);         /* GR.BG */
  666.                 *(unsigned int *)d =
  667.                     ((a & 0xF8) >> 3) | ((a & 0xFC00) >> 5) | ((a & 0xF80000) >> 8) |
  668.                     ((a & 0xF8000000) >> 11) | ((b & 0xFC) << 19) | ((b & 0xF800) << 16);
  669.                 a = *(unsigned int *)(s+8);         /* R.BGR */
  670.                 *(unsigned int *)(d+4) =
  671.                     ((b & 0xF80000) >> 19) | ((b & 0xFC000000) >> 21) | ((a & 0xF8) << 8) |
  672.                     ((a & 0xF800) << 5) | ((a & 0xFC0000) << 3) | (a & 0xF8000000);
  673.                 d += BPP2*4; s += BPP3*4; ddx -= 4;
  674.             }
  675.             /* process the remaining 1..3 pixels: */
  676.             while (ddx) {
  677.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.rrrrrggg: */
  678.                 *(unsigned short *)d =
  679.                     (s[0] >> 3) | ((s[1] & 0xFC) << 3) | ((s[2] & 0xF8) << 8);
  680.                 d += BPP2;  s += BPP3;
  681.                 ddx --;
  682.             }
  683.             /* bump pointers to the next row: */
  684.             s += src_pitch - dest_dx * BPP3;
  685.             d += dest_pitch - dest_dx * BPP2;
  686.         }
  687.         return 0;
  688.     }
  689.     /* check if 2:1 scale: */
  690.     if (scale_x == 2 && scale_y == 2) {
  691.         /* local variables: */
  692.         unsigned char *s, *d;
  693.         register int i;
  694.         /* get pointers: */
  695.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  696.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  697.         /* stretch image: */
  698.         for (i = 0; i < src_dy; i ++) {
  699.             /* stretch a line: */
  700.             register int sx = src_x, sdx = src_dx;
  701.             /* misaligned pixels first: */
  702.             while ((sx & 3) && sdx) {
  703.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.0rrrrrgg: */
  704.                 register unsigned short a;
  705.                 a = (s[0] >> 3) | ((s[1] & 0xFC) << 3) | ((s[2] & 0xF8) << 8);
  706.                 *(unsigned short *)d = a;
  707.                 *(unsigned short *)(d+BPP2) = a;
  708.                 d += 2*BPP2;  s += BPP3;
  709.                 sx ++; sdx --;
  710.             }
  711.             /* main bulk of data: */
  712.             while (sdx >= 4) {
  713.                 register unsigned int a, b, c;
  714.                 a = *(unsigned int *)s;             /* bgrB */
  715.                 b = *(unsigned int *)(s+4);         /* GRbg */
  716.                 c = ((a & 0xF8) >> 3) | ((a & 0xFC00) >> 5) | ((a & 0xF80000) >> 8);
  717.                 *(unsigned int *)d = c | (c << 16);
  718.                 c = ((a & 0xF8000000) >> 11) | ((b & 0xFC) << 19) | ((b & 0xF800) << 16);
  719.                 *(unsigned int *)(d+2*BPP2) = c | (c >> 16);
  720.                 a = *(unsigned int *)(s+8);         /* rBGR */
  721.                 c = ((b & 0xF80000) >> 19) | ((b & 0xFC000000) >> 21) | ((a & 0xF8) << 8);
  722.                 *(unsigned int *)(d+2*2*BPP2) = c | (c << 16);
  723.                 c = ((a & 0xF800) << 5) | ((a & 0xFC0000) << 3) | (a & 0xF8000000);
  724.                 *(unsigned int *)(d+3*2*BPP2) = c | (c >> 16);
  725.                 d += 2*4*BPP2; s += 4*BPP3;
  726.                 sdx -= 4;
  727.             }
  728.             /* the remaining pixels: */
  729.             while (sdx) {
  730.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.0rrrrrgg: */
  731.                 register unsigned short a;
  732.                 a = (s[0] >> 3) | ((s[1] & 0xFC) << 3) | ((s[2] & 0xF8) << 8);
  733.                 *(unsigned short *)d = a;
  734.                 *(unsigned short *)(d+BPP2) = a;
  735.                 d += 2*BPP2;  s += BPP3;
  736.                 sdx --;
  737.             }
  738.             s -= src_dx * BPP3;
  739.             d -= src_dx * 2*BPP2;
  740.             /* replicate a line (vertical stretching): */
  741.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP2); /* Flawfinder: ignore */
  742.             /* bump pointers to the next row: */
  743.             s += src_pitch;
  744.             d += dest_pitch * 2;
  745.         }
  746.         return 0;
  747.     }
  748.     /* conversion is not supported */
  749.     return -1;
  750. }
  751. /*
  752.  * RGB24toRGB555() converter:
  753.  *  1:1, 2:1
  754.  */
  755. int RGB24toRGB555 (unsigned char *dest_ptr, int dest_width, int dest_height,
  756.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  757.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  758.     int src_x, int src_y, int src_dx, int src_dy)
  759. {
  760.     /* scale factors: */
  761.     int scale_x, scale_y;
  762.     /* check arguments: */
  763.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  764.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  765.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  766.         return -1;
  767.     /* check if bottom-up bitmaps: */
  768.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  769.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  770.     /* check if 1:1 scale: */
  771.     if (scale_x == 1 && scale_y == 1) {
  772.         /* local variables: */
  773.         unsigned char *s, *d;
  774.         register int i;
  775.         /* get pointers: */
  776.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  777.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  778.         /* copy rows: */
  779.         for (i = 0; i < dest_dy; i ++) {
  780.             register int sx = src_x, ddx = dest_dx;
  781.             /* process misaligned pixels first: */
  782.             while ((sx & 3) && ddx) {
  783.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.0rrrrrgg: */
  784.                 *(unsigned short *)d =
  785.                     (s[0] >> 3) | ((s[1] & 0xF8) << 2) | ((s[2] & 0xF8) << 7);
  786.                 d += BPP2;  s += BPP3;
  787.                 sx ++; ddx --;
  788.             }
  789.             /* main loop: process 4 pixels a time: */
  790.             while (ddx >= 4) {
  791.                 register unsigned int a, b;
  792.                 a = *(unsigned int *)s;             /* bgrB */
  793.                 b = *(unsigned int *)(s+4);         /* GRbg */
  794.                 *(unsigned int *)d =
  795.                     ((a & 0xF8) >> 3) | ((a & 0xF800) >> 6) | ((a & 0xF80000) >> 9) |
  796.                     ((a & 0xF8000000) >> 11) | ((b & 0xF8) << 18) | ((b & 0xF800) << 15);
  797.                 a = *(unsigned int *)(s+8);         /* rBGR */
  798.                 *(unsigned int *)(d+4) =
  799.                     ((b & 0xF80000) >> 19) | ((b & 0xF8000000) >> 22) | ((a & 0xF8) << 7) |
  800.                     ((a & 0xF800) << 5) | ((a & 0xF80000) << 2) | ((a & 0xF8000000) >> 1);
  801.                 d += BPP2*4; s += BPP3*4; ddx -= 4;
  802.             }
  803.             /* process the remaining 1..3 pixels: */
  804.             while (ddx) {
  805.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.rrrrrggg: */
  806.                 *(unsigned short *)d =
  807.                     (s[0] >> 3) | ((s[1] & 0xF8) << 2) | ((s[2] & 0xF8) << 7);
  808.                 d += BPP2;  s += BPP3;
  809.                 ddx --;
  810.             }
  811.             /* bump pointers to the next row: */
  812.             s += src_pitch - dest_dx * BPP3;
  813.             d += dest_pitch - dest_dx * BPP2;
  814.         }
  815.         return 0;
  816.     }
  817.     /* check if 2:1 scale: */
  818.     if (scale_x == 2 && scale_y == 2) {
  819.         /* local variables: */
  820.         unsigned char *s, *d;
  821.         register int i;
  822.         /* get pointers: */
  823.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  824.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  825.         /* stretch image: */
  826.         for (i = 0; i < src_dy; i ++) {
  827.             /* stretch a line: */
  828.             register int sx = src_x, sdx = src_dx;
  829.             /* misaligned pixels first: */
  830.             while ((sx & 3) && sdx) {
  831.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.0rrrrrgg: */
  832.                 register unsigned short a;
  833.                 a = (s[0] >> 3) | ((s[1] & 0xF8) << 2) | ((s[2] & 0xF8) << 7);
  834.                 *(unsigned short *)d = a;
  835.                 *(unsigned short *)(d+BPP2) = a;
  836.                 d += 2*BPP2;  s += BPP3;
  837.                 sx ++; sdx --;
  838.             }
  839.             /* main bulk of data: */
  840.             while (sdx >= 4) {
  841.                 register unsigned int a, b, c;
  842.                 a = *(unsigned int *)s;             /* bgrB */
  843.                 b = *(unsigned int *)(s+4);         /* GRbg */
  844.                 c = ((a & 0xF8) >> 3) | ((a & 0xF800) >> 6) | ((a & 0xF80000) >> 9);
  845.                 *(unsigned int *)d = c | (c << 16);
  846.                 c = ((a & 0xF8000000) >> 11) | ((b & 0xF8) << 18) | ((b & 0xF800) << 15);
  847.                 *(unsigned int *)(d+2*BPP2) = c | (c >> 16);
  848.                 a = *(unsigned int *)(s+8);         /* rBGR */
  849.                 c = ((b & 0xF80000) >> 19) | ((b & 0xF8000000) >> 22) | ((a & 0xF8) << 7);
  850.                 *(unsigned int *)(d+2*2*BPP2) = c | (c << 16);
  851.                 c = ((a & 0xF800) << 5) | ((a & 0xF80000) << 2) | ((a & 0xF8000000) >> 1);
  852.                 *(unsigned int *)(d+3*2*BPP2) = c | (c >> 16);
  853.                 d += 2*4*BPP2; s += 4*BPP3;
  854.                 sdx -= 4;
  855.             }
  856.             /* the remaining pixels: */
  857.             while (sdx) {
  858.                 /* bbbbbbbb.gggggggg.rrrrrrrr -> gggbbbbb.0rrrrrgg: */
  859.                 register unsigned short a;
  860.                 a = (s[0] >> 3) | ((s[1] & 0xF8) << 2) | ((s[2] & 0xF8) << 7);
  861.                 *(unsigned short *)d = a;
  862.                 *(unsigned short *)(d+BPP2) = a;
  863.                 d += 2*BPP2;  s += BPP3;
  864.                 sdx --;
  865.             }
  866.             s -= src_dx * BPP3;
  867.             d -= src_dx * 2*BPP2;
  868.             /* replicate a line (vertical stretching): */
  869.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP2); /* Flawfinder: ignore */
  870.             /* bump pointers to the next row: */
  871.             s += src_pitch;
  872.             d += dest_pitch * 2;
  873.         }
  874.         return 0;
  875.     }
  876.     /* conversion is not supported */
  877.     return -1;
  878. }
  879. /*
  880.  * No dithering yet.
  881.  */
  882. int RGB24toRGB8 (unsigned char *dest_ptr, int dest_width, int dest_height,
  883.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  884.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  885.     int src_x, int src_y, int src_dx, int src_dy)
  886. {
  887.     /* scale factors: */
  888.     int scale_x, scale_y;
  889.     /* check arguments: */
  890.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  891.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  892.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  893.         return -1;
  894.     /* check if bottom-up bitmaps: */
  895.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  896.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  897.     /* check if 1:1 scale: */
  898.     if (scale_x == 1 && scale_y == 1) {
  899.         /* local variables: */
  900.         unsigned char *s, *d;
  901.         register int i;
  902.         /* get pointers: */
  903.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  904.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  905.         /* copy rows: */
  906.         for (i = 0; i < dest_dy; i ++) {
  907.             register int sx = src_x, ddx = dest_dx;
  908.             /* process misaligned pixels first: */
  909.             while ((sx & 3) && ddx) {
  910.                 /* BGR -> palette index: */
  911.                 *d = pmap[(unsigned int)
  912.                     ((s[0] & 0xf0) >> 4) |
  913.                     ((s[1] & 0xf0)     ) |
  914.                     ((s[2] & 0xf0) << 4)];
  915.                 d += BPP1; s += BPP3;
  916.                 sx ++; ddx --;
  917.             }
  918.             /* main loop: process 4 pixels a time: */
  919.             while (ddx >= 4) {
  920.                 register unsigned int a, b;
  921.                 a = *(unsigned int *)s;             /* BGR.B */
  922.                 b = *(unsigned int *)(s+4);         /* GR.BG */
  923.                 *d = pmap[(unsigned int)
  924.                     ((a & 0x000000f0) >>  4) |
  925.                     ((a & 0x0000f000) >>  8) |
  926.                     ((a & 0x00f00000) >> 12)];
  927.                 *(d+BPP1) = pmap[(unsigned int)
  928.                     ((a & 0xf0000000) >> 28) |
  929.                     ((b & 0x000000f0)      ) |
  930.                     ((b & 0x0000f000) >>  4)];
  931.                 a = *(unsigned int *)(s+8);         /* R.BGR */
  932.                 *(d+2*BPP1) = pmap[(unsigned int)
  933.                     ((b & 0x00f00000) >> 20) |
  934.                     ((b & 0xf0000000) >> 24) |
  935.                     ((a & 0x000000f0) <<  4)];
  936.                 *(d+3*BPP1) = pmap[(unsigned int)
  937.                     ((a & 0x0000f000) >> 12) |
  938.                     ((a & 0x00f00000) >> 16) |
  939.                     ((a & 0xf0000000) >> 20)];
  940.                 d += BPP1*4; s += BPP3*4;
  941.                 ddx -= 4;
  942.             }
  943.             /* process the remaining 1..3 pixels: */
  944.             while (ddx) {
  945.                 /* RGB -> palette index: */
  946.                 *d = pmap[(unsigned int)
  947.                     ((s[0] & 0xf0) >> 4) |
  948.                     ((s[1] & 0xf0)     ) |
  949.                     ((s[2] & 0xf0) << 4)];
  950.                 d += BPP1; s += BPP3;
  951.                 ddx --;
  952.             }
  953.             /* bump pointers to the next row: */
  954.             s += src_pitch - dest_dx * BPP3;
  955.             d += dest_pitch - dest_dx * BPP1;
  956.         }
  957.         return 0;
  958.     }
  959.     /* check if 2:1 scale: */
  960.     if (scale_x == 2 && scale_y == 2) {
  961.         /* local variables: */
  962.         unsigned char *s, *d;
  963.         register int i;
  964.         /* get pointers: */
  965.         s = src_ptr + src_x * BPP3 + src_y * src_pitch;
  966.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  967.         /* stretch image: */
  968.         for (i = 0; i < src_dy; i ++) {
  969.             /* stretch a line: */
  970.             register int sx = src_x, sdx = src_dx;
  971.             /* misaligned pixels first: */
  972.             while ((sx & 3) && sdx) {
  973.                 /* BGR -> palette index: */
  974.                 register unsigned char c;
  975.                 c = pmap[(unsigned int)
  976.                     ((s[0] & 0xf0) >> 4) |
  977.                     ((s[1] & 0xf0)     ) |
  978.                     ((s[2] & 0xf0) << 4)];
  979.                 *d = c;
  980.                 *(d+BPP1) = c;
  981.                 d += 2*BPP1; s += BPP3;
  982.                 sx ++; sdx --;
  983.             }
  984.             /* main bulk of data: */
  985.             while (sdx >= 4) {
  986.                 register unsigned int a, b;
  987.                 register unsigned char c;
  988.                 a = *(unsigned int *)s;             /* bgrB */
  989.                 b = *(unsigned int *)(s+4);         /* GRbg */
  990.                 c = pmap[(unsigned int)
  991.                     ((a & 0x000000f0) >>  4) |
  992.                     ((a & 0x0000f000) >>  8) |
  993.                     ((a & 0x00f00000) >> 12)];
  994.                 *(d+0) = c;
  995.                 *(d+BPP1) = c;
  996.                 c = pmap[(unsigned int)
  997.                     ((a & 0xf0000000) >> 28) |
  998.                     ((b & 0x000000f0)      ) |
  999.                     ((b & 0x0000f000) >>  4)];
  1000.                 *(d+2*BPP1) = c;
  1001.                 *(d+3*BPP1) = c;
  1002.                 a = *(unsigned int *)(s+8);         /* rBGR */
  1003.                 c = pmap[(unsigned int)
  1004.                     ((b & 0x00f00000) >> 20) |
  1005.                     ((b & 0xf0000000) >> 24) |
  1006.                     ((a & 0x000000f0) <<  4)];
  1007.                 *(d+4*BPP1) = c;
  1008.                 *(d+5*BPP1) = c;
  1009.                 c = pmap[(unsigned int)
  1010.                     ((a & 0x0000f000) >> 12) |
  1011.                     ((a & 0x00f00000) >> 16) |
  1012.                     ((a & 0xf0000000) >> 20)];
  1013.                 *(d+6*BPP1) = c;
  1014.                 *(d+7*BPP1) = c;
  1015.                 d += 4*2*BPP1; s += 4*BPP3;
  1016.                 sdx -= 4;
  1017.             }
  1018.             /* the remaining 1..3 pixels: */
  1019.             while (sdx) {
  1020.                 /* BGR -> palette index: */
  1021.                 register unsigned char c;
  1022.                 c = pmap[(unsigned int)
  1023.                     ((s[0] & 0xf0) >> 4) |
  1024.                     ((s[1] & 0xf0)     ) |
  1025.                     ((s[2] & 0xf0) << 4)];
  1026.                 *d = c;
  1027.                 *(d+BPP1) = c;
  1028.                 d += 2*BPP1; s += BPP3;
  1029.                 sdx --;
  1030.             }
  1031.             s -= src_dx * BPP3;
  1032.             d -= src_dx * 2*BPP1;
  1033.             /* replicate a line (vertical stretching): */
  1034.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP1); /* Flawfinder: ignore */
  1035.             /* bump pointers to the next row: */
  1036.             s += src_pitch;
  1037.             d += dest_pitch * 2;
  1038.         }
  1039.         return 0;
  1040.     }
  1041.     /* conversion is not supported */
  1042.     return -1;
  1043. }
  1044. int RGB565toRGB32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1045.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1046.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1047.     int src_x, int src_y, int src_dx, int src_dy)
  1048. {
  1049.     return -1;   /* not implemented yet... */
  1050. }
  1051. int RGB565toRGB24 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1052.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1053.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1054.     int src_x, int src_y, int src_dx, int src_dy)
  1055. {
  1056.     return -1;   /* not implemented yet... */
  1057. }
  1058. /*
  1059.  * RGB565toRGB565() converter:
  1060.  *  1:1, 2:1
  1061.  */
  1062. int RGB565toRGB565 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1063.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1064.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1065.     int src_x, int src_y, int src_dx, int src_dy)
  1066. {
  1067.     /* scale factors: */
  1068.     int scale_x, scale_y;
  1069.     /* check arguments: */
  1070.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  1071.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  1072.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  1073.         return -1;
  1074.     /* check if bottom-up bitmaps: */
  1075.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  1076.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1077.     /* check if 1:1 scale: */
  1078.     if (scale_x == 1 && scale_y == 1) {
  1079.         /* local variables: */
  1080.         unsigned char *s, *d;
  1081.         register int i;
  1082.         /* get pointers: */
  1083.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1084.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  1085.         /* copy image: */
  1086.         for (i = 0; i < dest_dy; i ++) {
  1087.             memcpy (d, s, dest_dx * BPP2);  /* copy dest_dx pixels */ /* Flawfinder: ignore */
  1088.             s += src_pitch;
  1089.             d += dest_pitch;
  1090.         }
  1091.         return 0;
  1092.     }
  1093.     /* check if 2:1 scale: */
  1094.     if (scale_x == 2 && scale_y == 2) {
  1095.         /* local variables: */
  1096.         unsigned char *s, *d;
  1097.         register int i;
  1098.         /* get pointers: */
  1099.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1100.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  1101.         /* stretch image: */
  1102.         for (i = 0; i < src_dy; i ++) {
  1103.             /* stretch a line: */
  1104.             register int sdx = src_dx;
  1105.             /* misaligned pixel first: */
  1106.             if (src_x & 1) {
  1107.                 register unsigned short a;
  1108.                 a = *(unsigned short *)s;
  1109.                 *(unsigned short *)d = a;
  1110.                 *(unsigned short *)(d+BPP2) = a;
  1111.                 d += 2*BPP2; s += BPP2;
  1112.                 sdx --;
  1113.             }
  1114.             /* main bulk of data: */
  1115.             while (sdx >= 2) {
  1116.                 register unsigned int a;
  1117.                 a = *(unsigned int *)s;
  1118.                 *(unsigned int *)d = (a & 0xFFFF) | (a << 16);
  1119.                 *(unsigned int *)(d+2*BPP2) = (a & 0xFFFF0000) | (a >> 16);
  1120.                 d += 2*2*BPP2; s += 2*BPP2;
  1121.                 sdx -= 2;
  1122.             }
  1123.             /* the remaining odd pixel: */
  1124.             if (sdx) {
  1125.                 register unsigned short a;
  1126.                 a = *(unsigned short *)s;
  1127.                 *(unsigned short *)d = a;
  1128.                 *(unsigned short *)(d+BPP2) = a;
  1129.                 d += 2*BPP2; s += BPP2;
  1130.             }
  1131.             s -= src_dx * BPP2;
  1132.             d -= src_dx * 2*BPP2;
  1133.             /* replicate a line (vertical stretching): */
  1134.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP2); /* Flawfinder: ignore */
  1135.             /* bump pointers to the next row: */
  1136.             s += src_pitch;
  1137.             d += dest_pitch * 2;
  1138.         }
  1139.         return 0;
  1140.     }
  1141.     /* conversion is not supported */
  1142.     return -1;
  1143. }
  1144. int RGB565toRGB555 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1145.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1146.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1147.     int src_x, int src_y, int src_dx, int src_dy)
  1148. {
  1149.     return -1;   /* not implemented yet... */
  1150. }
  1151. /*
  1152.  * No dithering yet.
  1153.  */
  1154. int RGB565toRGB8 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1155.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1156.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1157.     int src_x, int src_y, int src_dx, int src_dy)
  1158. {
  1159.     /* scale factors: */
  1160.     int scale_x, scale_y;
  1161.     /* check arguments: */
  1162.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  1163.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  1164.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  1165.         return -1;
  1166.     /* check if bottom-up bitmaps: */
  1167.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  1168.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1169.     /* check if 1:1 scale: */
  1170.     if (scale_x == 1 && scale_y == 1) {
  1171.         /* local variables: */
  1172.         unsigned char *s, *d;
  1173.         register int i;
  1174.         /* get pointers: */
  1175.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1176.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  1177.         /* copy rows: */
  1178.         for (i = 0; i < dest_dy; i ++) {
  1179.             register int ddx = dest_dx;
  1180.             /* first odd pixel: */
  1181.             if (src_x & 1) {
  1182.                 /* gggbbbbb.rrrrrggg -> palette index: */
  1183.                 unsigned short a = *(unsigned short *)s;
  1184.                 *d = pmap[
  1185.                     ((a & 0x001E) >> 1) |
  1186.                     ((a & 0x0780) >> 3) |
  1187.                     ((a & 0xf000) >> 4)];
  1188.                 d += BPP1; s += BPP2;
  1189.                 ddx --;
  1190.             }
  1191.             /* main loop: process 2 pixels a time: */
  1192.             while (ddx >= 2) {
  1193.                 /* gggbbbbb.rrrrrggg.gggbbbbb.rrrrrggg -> 2 palette indices */
  1194.                 register unsigned int a;
  1195.                 a = *(unsigned int *)s;
  1196.                 *d = pmap[
  1197.                     ((a & 0x001e) >> 1) |
  1198.                     ((a & 0x0780) >> 3) |
  1199.                     ((a & 0xf000) >> 4)];
  1200.                 *(d+BPP1) = pmap[
  1201.                     ((a & 0x001e0000) >> 17) |
  1202.                     ((a & 0x07800000) >> 19) |
  1203.                     ((a & 0xf0000000) >> 20)];
  1204.                 d += BPP1*2; s += BPP2*2;
  1205.                 ddx -= 2;
  1206.             }
  1207.             /* the remaining odd pixel: */
  1208.             if (ddx) {
  1209.                 /* gggbbbbb.rrrrrggg -> palette index: */
  1210.                 unsigned short a = *(unsigned short *)s;
  1211.                 *d = pmap[
  1212.                     ((a & 0x001e) >> 1) |
  1213.                     ((a & 0x0780) >> 3) |
  1214.                     ((a & 0xf000) >> 4)];
  1215.                 d += BPP1; s += BPP2;
  1216.                 ddx --;
  1217.             }
  1218.             /* bump pointers to the next row: */
  1219.             s += src_pitch - dest_dx * BPP2;
  1220.             d += dest_pitch - dest_dx * BPP1;
  1221.         }
  1222.         return 0;
  1223.     }
  1224.     /* check if 2:1 scale: */
  1225.     if (scale_x == 2 && scale_y == 2) {
  1226.         /* local variables: */
  1227.         unsigned char *s, *d;
  1228.         register int i;
  1229.         /* get pointers: */
  1230.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1231.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  1232.         /* stretch image: */
  1233.         for (i = 0; i < src_dy; i ++) {
  1234.             /* stretch a line: */
  1235.             register int sdx = src_dx;
  1236.             /* first odd pixel: */
  1237.             if (src_x & 1) {
  1238.                 /* gggbbbbb.rrrrrggg -> palette index: */
  1239.                 unsigned short a = *(unsigned short *)s;
  1240.                 register unsigned char c;
  1241.                 c = pmap[
  1242.                     ((a & 0x001e) >> 1) |
  1243.                     ((a & 0x0780) >> 3) |
  1244.                     ((a & 0xf000) >> 4)];
  1245.                 *d = c;
  1246.                 *(d+BPP1) = c;
  1247.                 d += 2*BPP1; s += BPP2;
  1248.                 sdx --;
  1249.             }
  1250.             /* main bulk of data: */
  1251.             while (sdx >= 2) {
  1252.                 /* gggbbbbb.rrrrrggg.gggbbbbb.rrrrrggg -> 2 palette indices */
  1253.                 register unsigned int a;
  1254.                 register unsigned char c;
  1255.                 a = *(unsigned int *)s;
  1256.                 c = pmap[
  1257.                     ((a & 0x001e) >> 1) |
  1258.                     ((a & 0x0780) >> 3) |
  1259.                     ((a & 0xf000) >> 4)];
  1260.                 *(d+0) = c;
  1261.                 *(d+BPP1) = c;
  1262.                 c = pmap[
  1263.                     ((a & 0x001e0000) >> 17) |
  1264.                     ((a & 0x07800000) >> 19) |
  1265.                     ((a & 0xf0000000) >> 20)];
  1266.                 *(d+2*BPP1) = c;
  1267.                 *(d+3*BPP1) = c;
  1268.                 d += 2*2*BPP1; s += 2*BPP2;
  1269.                 sdx -= 2;
  1270.             }
  1271.             /* the remaining odd pixel: */
  1272.             if (sdx) {
  1273.                 /* gggbbbbb.rrrrrggg -> palette index: */
  1274.                 unsigned short a = *(unsigned short *)s;
  1275.                 register unsigned char c;
  1276.                 c = pmap[
  1277.                     ((a & 0x001e) >> 1) |
  1278.                     ((a & 0x0780) >> 3) |
  1279.                     ((a & 0xf000) >> 4)];
  1280.                 *d = c;
  1281.                 *(d+BPP1) = c;
  1282.                 d += 2*BPP1; s += BPP2;
  1283.             }
  1284.             s -= src_dx * BPP2;
  1285.             d -= src_dx * 2*BPP1;
  1286.             /* replicate a line (vertical stretching): */
  1287.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP1); /* Flawfinder: ignore */
  1288.             /* bump pointers to the next row: */
  1289.             s += src_pitch;
  1290.             d += dest_pitch * 2;
  1291.         }
  1292.         return 0;
  1293.     }
  1294.     /* conversion is not supported */
  1295.     return -1;
  1296. }
  1297. int RGB555toRGB32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1298.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1299.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1300.     int src_x, int src_y, int src_dx, int src_dy)
  1301. {
  1302.     return -1;   /* not implemented yet... */
  1303. }
  1304. int RGB555toRGB24 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1305.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1306.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1307.     int src_x, int src_y, int src_dx, int src_dy)
  1308. {
  1309.     return -1;   /* not implemented yet... */
  1310. }
  1311. /*
  1312.  * RGB555toRGB565() converter:
  1313.  *  1:1, 2:1
  1314.  */
  1315. int RGB555toRGB565 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1316.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1317.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1318.     int src_x, int src_y, int src_dx, int src_dy)
  1319. {
  1320.     /* scale factors: */
  1321.     int scale_x, scale_y;
  1322.     /* check arguments: */
  1323.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  1324.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  1325.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  1326.         return -1;
  1327.     /* check if bottom-up bitmaps: */
  1328.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  1329.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1330.     /* check if 1:1 scale: */
  1331.     if (scale_x == 1 && scale_y == 1) {
  1332.         /* local variables: */
  1333.         unsigned char *s, *d;
  1334.         register int i;
  1335.         /* get pointers: */
  1336.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1337.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  1338.         /* copy rows: */
  1339.         for (i = 0; i < dest_dy; i ++) {
  1340.             register int sx = src_x, ddx = dest_dx;
  1341.             /* process misaligned pixels first: */
  1342.             while ((sx & 3) && ddx) {
  1343.                 /* gggbbbbb.0rrrrrgg -> gg0bbbbb.rrrrrggg : */
  1344.                 register unsigned short c = *(unsigned short *)s;
  1345.                 *(unsigned short *)d = (c & 0x1F) | ((c & 0x7FE0) << 1);
  1346.                 d += BPP2;  s += BPP2;
  1347.                 sx ++; ddx --;
  1348.             }
  1349.             /* main loop: process 4 pixels a time: */
  1350.             while (ddx >= 4) {
  1351.                 register unsigned int a, b;
  1352.                 a = *(unsigned int *)s;     /* gggbbbbb.0rrrrrgg.gggbbbbb.0rrrrrgg */
  1353.                 b = *(unsigned int *)(s+4);
  1354.                 *(unsigned int *)d = (a & 0x1F001F) | ((a & 0x7FE07FE0) << 1);
  1355.                 *(unsigned int *)(d+4) = (b & 0x1F001F) | ((b & 0x7FE07FE0) << 1);
  1356.                 d += BPP2*4; s += BPP2*4; ddx -= 4;
  1357.             }
  1358.             /* process the remaining 1..3 pixels: */
  1359.             while (ddx) {
  1360.                 /* gggbbbbb.0rrrrrgg -> gg0bbbbb.rrrrrggg : */
  1361.                 register unsigned short c = *(unsigned short *)s;
  1362.                 *(unsigned short *)d = (c & 0x1F) | ((c & 0x7FE0) << 1);
  1363.                 d += BPP2;  s += BPP2;
  1364.                 ddx --;
  1365.             }
  1366.             /* bump pointers to the next row: */
  1367.             s += src_pitch - dest_dx * BPP2;
  1368.             d += dest_pitch - dest_dx * BPP2;
  1369.         }
  1370.         return 0;
  1371.     }
  1372.     /* check if 2:1 scale: */
  1373.     if (scale_x == 2 && scale_y == 2) {
  1374.         /* local variables: */
  1375.         unsigned char *s, *d;
  1376.         register int i;
  1377.         /* get pointers: */
  1378.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1379.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  1380.         /* stretch image: */
  1381.         for (i = 0; i < src_dy; i ++) {
  1382.             /* stretch a line: */
  1383.             register int sx = src_x, sdx = src_dx;
  1384.             /* misaligned pixels first: */
  1385.             while ((sx & 3) && sdx) {
  1386.                 /* gggbbbbb.0rrrrrgg -> gg0bbbbb.rrrrrggg : */
  1387.                 register unsigned short a, b;
  1388.                 a = *(unsigned short *)s;
  1389.                 b = (a & 0x1F) | ((a & 0x7FE0) << 1);
  1390.                 *(unsigned short *)d = b;
  1391.                 *(unsigned short *)(d+BPP2) = b;
  1392.                 d += 2*BPP2; s += BPP2;
  1393.                 sx ++; sdx --;
  1394.             }
  1395.             /* main bulk of data: */
  1396.             while (sdx >= 4) {
  1397.                 register unsigned int a, b;
  1398.                 a = *(unsigned int *)s;     /* gggbbbbb.0rrrrrgg.gggbbbbb.0rrrrrgg */
  1399.                 b = (a & 0x1F001F) | ((a & 0x7FE07FE0) << 1);
  1400.                 *(unsigned int *)d = (b & 0xFFFF) | (b << 16);
  1401.                 *(unsigned int *)(d+2*BPP2) = (b & 0xFFFF0000) | (b >> 16);
  1402.                 a = *(unsigned int *)(s+2*BPP2);
  1403.                 b = (a & 0x1F001F) | ((a & 0x7FE07FE0) << 1);
  1404.                 *(unsigned int *)(d+2*2*BPP2) = (b & 0xFFFF) | (b << 16);
  1405.                 *(unsigned int *)(d+3*2*BPP2) = (b & 0xFFFF0000) | (b >> 16);
  1406.                 d += 2*4*BPP2; s += 4*BPP2;
  1407.                 sdx -= 4;
  1408.             }
  1409.             /* the remaining pixels: */
  1410.             while (sdx) {
  1411.                 /* gggbbbbb.0rrrrrgg -> gg0bbbbb.rrrrrggg : */
  1412.                 register unsigned short a, b;
  1413.                 a = *(unsigned short *)s;
  1414.                 b = (a & 0x1F) | ((a & 0x7FE0) << 1);
  1415.                 *(unsigned short *)d = b;
  1416.                 *(unsigned short *)(d+BPP2) = b;
  1417.                 d += 2*BPP2; s += BPP2;
  1418.                 sdx --;
  1419.             }
  1420.             s -= src_dx * BPP2;
  1421.             d -= src_dx * 2*BPP2;
  1422.             /* replicate a line (vertical stretching): */
  1423.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP2); /* Flawfinder: ignore */
  1424.             /* bump pointers to the next row: */
  1425.             s += src_pitch;
  1426.             d += dest_pitch * 2;
  1427.         }
  1428.         return 0;
  1429.     }
  1430.     /* conversion is not supported */
  1431.     return -1;
  1432. }
  1433. /*
  1434.  * RGB555toRGB555() converter:
  1435.  *  1:1, 2:1
  1436.  */
  1437. int RGB555toRGB555 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1438.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1439.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1440.     int src_x, int src_y, int src_dx, int src_dy)
  1441. {
  1442.     /* scale factors: */
  1443.     int scale_x, scale_y;
  1444.     /* check arguments: */
  1445.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  1446.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  1447.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  1448.         return -1;
  1449.     /* check if bottom-up bitmaps: */
  1450.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  1451.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1452.     /* check if 1:1 scale: */
  1453.     if (scale_x == 1 && scale_y == 1) {
  1454.         /* local variables: */
  1455.         unsigned char *s, *d;
  1456.         register int i;
  1457.         /* get pointers: */
  1458.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1459.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  1460.         /* copy image: */
  1461.         for (i = 0; i < dest_dy; i ++) {
  1462.             memcpy (d, s, dest_dx * BPP2);  /* copy dest_dx pixels */ /* Flawfinder: ignore */
  1463.             s += src_pitch;
  1464.             d += dest_pitch;
  1465.         }
  1466.         return 0;
  1467.     }
  1468.     /* check if 2:1 scale: */
  1469.     if (scale_x == 2 && scale_y == 2) {
  1470.         /* local variables: */
  1471.         unsigned char *s, *d;
  1472.         register int i;
  1473.         /* get pointers: */
  1474.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1475.         d = dest_ptr + dest_x * BPP2 + dest_y * dest_pitch;
  1476.         /* stretch image: */
  1477.         for (i = 0; i < src_dy; i ++) {
  1478.             /* stretch a line: */
  1479.             register int sdx = src_dx;
  1480.             /* misaligned pixel first: */
  1481.             if (src_x & 1) {
  1482.                 register unsigned short a;
  1483.                 a = *(unsigned short *)s;
  1484.                 *(unsigned short *)d = a;
  1485.                 *(unsigned short *)(d+BPP2) = a;
  1486.                 d += 2*BPP2; s += BPP2;
  1487.                 sdx --;
  1488.             }
  1489.             /* main bulk of data: */
  1490.             while (sdx >= 2) {
  1491.                 register unsigned int a;
  1492.                 a = *(unsigned int *)s;
  1493.                 *(unsigned int *)d = (a & 0xFFFF) | (a << 16);
  1494.                 *(unsigned int *)(d+2*BPP2) = (a & 0xFFFF0000) | (a >> 16);
  1495.                 d += 2*2*BPP2; s += 2*BPP2;
  1496.                 sdx -= 2;
  1497.             }
  1498.             /* the remaining odd pixel: */
  1499.             if (sdx) {
  1500.                 register unsigned short a;
  1501.                 a = *(unsigned short *)s;
  1502.                 *(unsigned short *)d = a;
  1503.                 *(unsigned short *)(d+BPP2) = a;
  1504.                 d += 2*BPP2; s += BPP2;
  1505.             }
  1506.             s -= src_dx * BPP2;
  1507.             d -= src_dx * 2*BPP2;
  1508.             /* replicate a line (vertical stretching): */
  1509.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP2); /* Flawfinder: ignore */
  1510.             /* bump pointers to the next row: */
  1511.             s += src_pitch;
  1512.             d += dest_pitch * 2;
  1513.         }
  1514.         return 0;
  1515.     }
  1516.     /* conversion is not supported */
  1517.     return -1;
  1518. }
  1519. /*
  1520.  * No dithering yet.
  1521.  */
  1522. int RGB555toRGB8 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1523.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1524.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1525.     int src_x, int src_y, int src_dx, int src_dy)
  1526. {
  1527.     /* scale factors: */
  1528.     int scale_x, scale_y;
  1529.     /* check arguments: */
  1530.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  1531.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  1532.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  1533.         return -1;
  1534.     /* check if bottom-up bitmaps: */
  1535.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  1536.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1537.     /* check if 1:1 scale: */
  1538.     if (scale_x == 1 && scale_y == 1) {
  1539.         /* local variables: */
  1540.         unsigned char *s, *d;
  1541.         register int i;
  1542.         /* get pointers: */
  1543.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1544.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  1545.         /* copy rows: */
  1546.         for (i = 0; i < dest_dy; i ++) {
  1547.             register int ddx = dest_dx;
  1548.             /* first odd pixel: */
  1549.             if (src_x & 1) {
  1550.                 /* gggbbbbb.0rrrrrgg -> palette index: */
  1551.                 unsigned short a = *(unsigned short *)s;
  1552.                 *d = pmap[
  1553.                     ((a & 0x001e) >> 1) |
  1554.                     ((a & 0x03c0) >> 2) |
  1555.                     ((a & 0x7800) >> 3)];
  1556.                 d += BPP1; s += BPP2;
  1557.                 ddx --;
  1558.             }
  1559.             /* main loop: process 2 pixels a time: */
  1560.             while (ddx >= 2) {
  1561.                 /* gggbbbbb.0rrrrrgg.gggbbbbb.0rrrrrgg -> 2 palette indices */
  1562.                 register unsigned int a;
  1563.                 a = *(unsigned int *)s;
  1564.                 *d = pmap[
  1565.                     ((a & 0x001e) >> 1) |
  1566.                     ((a & 0x03c0) >> 2) |
  1567.                     ((a & 0x7800) >> 3)];
  1568.                 *(d+BPP1) = pmap[
  1569.                     ((a & 0x001e0000) >> 17) |
  1570.                     ((a & 0x03c00000) >> 18) |
  1571.                     ((a & 0x78000000) >> 19)];
  1572.                 d += BPP1*2; s += BPP2*2;
  1573.                 ddx -= 2;
  1574.             }
  1575.             /* the remaining odd pixel: */
  1576.             if (ddx) {
  1577.                 /* gggbbbbb.0rrrrrgg -> palette index: */
  1578.                 unsigned short a = *(unsigned short *)s;
  1579.                 *d = pmap[
  1580.                     ((a & 0x001e) >> 1) |
  1581.                     ((a & 0x03c0) >> 2) |
  1582.                     ((a & 0x7800) >> 3)];
  1583.                 d += BPP1; s += BPP2;
  1584.                 ddx --;
  1585.             }
  1586.             /* bump pointers to the next row: */
  1587.             s += src_pitch - dest_dx * BPP2;
  1588.             d += dest_pitch - dest_dx * BPP1;
  1589.         }
  1590.         return 0;
  1591.     }
  1592.     /* check if 2:1 scale: */
  1593.     if (scale_x == 2 && scale_y == 2) {
  1594.         /* local variables: */
  1595.         unsigned char *s, *d;
  1596.         register int i;
  1597.         /* get pointers: */
  1598.         s = src_ptr + src_x * BPP2 + src_y * src_pitch;
  1599.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  1600.         /* stretch image: */
  1601.         for (i = 0; i < src_dy; i ++) {
  1602.             /* stretch a line: */
  1603.             register int sdx = src_dx;
  1604.             /* first odd pixel: */
  1605.             if (src_x & 1) {
  1606.                 /* gggbbbbb.0rrrrrgg -> palette index: */
  1607.                 unsigned short a = *(unsigned short *)s;
  1608.                 register unsigned char c;
  1609.                 c = pmap[
  1610.                     ((a & 0x001e) >> 1) |
  1611.                     ((a & 0x03c0) >> 2) |
  1612.                     ((a & 0x7800) >> 3)];
  1613.                 *d = c;
  1614.                 *(d+BPP1) = c;
  1615.                 d += 2*BPP1; s += BPP2;
  1616.                 sdx --;
  1617.             }
  1618.             /* main bulk of data: */
  1619.             while (sdx >= 2) {
  1620.                 /* gggbbbbb.0rrrrrgg.gggbbbbb.0rrrrrgg -> 2 palette indices */
  1621.                 register unsigned int a;
  1622.                 register unsigned char c;
  1623.                 a = *(unsigned int *)s;
  1624.                 c = pmap[
  1625.                     ((a & 0x001e) >> 1) |
  1626.                     ((a & 0x03c0) >> 2) |
  1627.                     ((a & 0x7800) >> 3)];
  1628.                 *(d+0) = c;
  1629.                 *(d+BPP1) = c;
  1630.                 c = pmap[
  1631.                     ((a & 0x001e0000) >> 17) |
  1632.                     ((a & 0x03c00000) >> 18) |
  1633.                     ((a & 0x78000000) >> 19)];
  1634.                 *(d+2*BPP1) = c;
  1635.                 *(d+3*BPP1) = c;
  1636.                 d += 2*2*BPP1; s += 2*BPP2;
  1637.                 sdx -= 2;
  1638.             }
  1639.             /* the remaining odd pixel: */
  1640.             if (sdx) {
  1641.                 /* gggbbbbb.0rrrrrgg -> palette index: */
  1642.                 unsigned short a = *(unsigned short *)s;
  1643.                 register unsigned char c;
  1644.                 c = pmap[
  1645.                     ((a & 0x001e) >> 1) |
  1646.                     ((a & 0x03c0) >> 2) |
  1647.                     ((a & 0x7800) >> 3)];
  1648.                 *d = c;
  1649.                 *(d+BPP1) = c;
  1650.                 d += 2*BPP1; s += BPP2;
  1651.             }
  1652.             s -= src_dx * BPP2;
  1653.             d -= src_dx * 2*BPP1;
  1654.             /* replicate a line (vertical stretching): */
  1655.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP1); /* Flawfinder: ignore */
  1656.             /* bump pointers to the next row: */
  1657.             s += src_pitch;
  1658.             d += dest_pitch * 2;
  1659.         }
  1660.         return 0;
  1661.     }
  1662.     /* conversion is not supported */
  1663.     return -1;
  1664. }
  1665. int RGB8toRGB32 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1666.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1667.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1668.     int src_x, int src_y, int src_dx, int src_dy)
  1669. {
  1670.     return -1;   /* not implemented yet... */
  1671. }
  1672. int RGB8toRGB24 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1673.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1674.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1675.     int src_x, int src_y, int src_dx, int src_dy)
  1676. {
  1677.     return -1;   /* not implemented yet... */
  1678. }
  1679. int RGB8toRGB565 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1680.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1681.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1682.     int src_x, int src_y, int src_dx, int src_dy)
  1683. {
  1684.     return -1;   /* not implemented yet... */
  1685. }
  1686. int RGB8toRGB555 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1687.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1688.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1689.     int src_x, int src_y, int src_dx, int src_dy)
  1690. {
  1691.     return -1;   /* not implemented yet... */
  1692. }
  1693. /*
  1694.  * RGB8toRGB8() converter:
  1695.  *  1:1, 2:1
  1696.  */
  1697. int RGB8toRGB8 (unsigned char *dest_ptr, int dest_width, int dest_height,
  1698.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1699.     unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1700.     int src_x, int src_y, int src_dx, int src_dy)
  1701. {
  1702.     /* scale factors: */
  1703.     int scale_x, scale_y;
  1704.     /* check arguments: */
  1705.     if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
  1706.         dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
  1707.         src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
  1708.         return -1;
  1709.     /* check if bottom-up bitmaps: */
  1710.     if (src_pitch < 0)  src_ptr -= (src_height-1) * src_pitch;
  1711.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1712.     /* check if 1:1 scale: */
  1713.     if (scale_x == 1 && scale_y == 1) {
  1714.         /* local variables: */
  1715.         unsigned char *s, *d;
  1716.         register int i;
  1717.         /* get pointers: */
  1718.         s = src_ptr + src_x * BPP1 + src_y * src_pitch;
  1719.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  1720.         /* copy image: */
  1721.         for (i = 0; i < dest_dy; i ++) {
  1722.             memcpy (d, s, dest_dx * BPP1);  /* copy dest_dx pixels */ /* Flawfinder: ignore */
  1723.             s += src_pitch;
  1724.             d += dest_pitch;
  1725.         }
  1726.         return 0;
  1727.     }
  1728.     /* check if 2:1 scale: */
  1729.     if (scale_x == 2 && scale_y == 2) {
  1730.         /* local variables: */
  1731.         unsigned char *s, *d;
  1732.         register int i;
  1733.         /* get pointers: */
  1734.         s = src_ptr + src_x * BPP1 + src_y * src_pitch;
  1735.         d = dest_ptr + dest_x * BPP1 + dest_y * dest_pitch;
  1736.         /* stretch image: */
  1737.         for (i = 0; i < src_dy; i ++) {
  1738.             /* stretch a line: */
  1739.             register int sx = src_x, sdx = src_dx;
  1740.             /* misaligned pixels first: */
  1741.             while ((sx & 3) && sdx) {
  1742.                 register unsigned char a;
  1743.                 a = *s; *d = a; *(d+BPP1) = a;
  1744.                 d += 2*BPP1; s += BPP1;
  1745.                 sx ++; sdx --;
  1746.             }
  1747.             /* main bulk of data: */
  1748.             while (sdx >= 4) {
  1749.                 register unsigned int a;
  1750.                 a = *(unsigned int *)s;
  1751.                 *(unsigned int *)d = (a & 0xFF) | ((a & 0xFFFF) << 8) | ((a & 0xFF00) << 16);
  1752.                 *(unsigned int *)(d+4*BPP1) = (a & 0xFF000000) | ((a & 0xFFFF0000) >> 8) | ((a & 0xFF0000) >> 16);
  1753.                 d += 2*4*BPP1; s += 4*BPP1;
  1754.                 sdx -= 4;
  1755.             }
  1756.             /* the remaining 1..3 pixels: */
  1757.             while (sdx) {
  1758.                 register unsigned char a;
  1759.                 a = *s; *d = a; *(d+BPP1) = a;
  1760.                 d += 2*BPP1; s += BPP1;
  1761.                 sdx --;
  1762.             }
  1763.             s -= src_dx * BPP1;
  1764.             d -= src_dx * 2*BPP1;
  1765.             /* replicate a line (vertical stretching): */
  1766.             memcpy (d + dest_pitch, d, src_dx * 2 * BPP1); /* Flawfinder: ignore */
  1767.             /* bump pointers to the next row: */
  1768.             s += src_pitch;
  1769.             d += dest_pitch * 2;
  1770.         }
  1771.         return 0;
  1772.     }
  1773.     /* conversion is not supported */
  1774.     return -1;
  1775. }
  1776. /*
  1777.  * Old I420->RGB converters:
  1778.  * Use:
  1779.  *  void oldI420toRGBXXX (unsigned char *ysrc, unsigned char *usrc,
  1780.  *          unsigned char *vsrc, int pitchSrc, unsigned char *dst,
  1781.  *          int width, int height, int pitchDst);
  1782.  * Input:
  1783.  *  ysrc, usrc, vsrc - pointers to Y, Cr, and Cb components of the frame
  1784.  *  pitchSrc - pitch of the input frame (luminance)
  1785.  *  dst - pointer to an output buffer
  1786.  *  width, height - the size of frame to convert
  1787.  *  pitchDst - pitch of the output buffer (in RGB pixels!!!)
  1788.  * Returns:
  1789.  *  none.
  1790.  */
  1791. /* the driver function: */
  1792. static int oldI420toRGB (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  1793.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst, int bpp,
  1794.     void (* dbline) (unsigned char *d1, unsigned char *d2, int dest_x,
  1795.     unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
  1796.     int src_x, int dx))
  1797. {
  1798.     unsigned char *sy1, *sy2, *sv, *su, *d1, *d2;
  1799.     register int j, pitch = pitchDst * bpp;
  1800.     /* bump dest to other end, if bottom-up output: */
  1801.     if (pitch < 0)
  1802.         dst += -pitch * (height-1);                     /* start of last line */
  1803.     /* get pointers: */
  1804.     sy1 = ysrc;                                         /* luma offset */
  1805.     sy2 = sy1  + pitchSrc;
  1806.     su  = usrc;                                         /* chroma offset */
  1807.     sv  = vsrc;
  1808.     d1  = dst;                                          /* RGB offset */
  1809.     d2  = d1 + pitch;
  1810.     /* convert aligned portion of the image: */
  1811.     for (j = 0; j < height/2; j ++) {
  1812.         /* convert two lines a time: */
  1813.         (* dbline) (d1, d2, 0, sy1, sy2, su, sv, 0, width);
  1814.         sy1 += pitchSrc*2; sy2 += pitchSrc*2;
  1815.         su  += pitchSrc/2; sv  += pitchSrc/2;
  1816.         d1  += pitch*2; d2  += pitch*2;
  1817.     }
  1818.     return 0;
  1819. }
  1820. /* actual converters: */
  1821. void oldI420toRGB32 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  1822.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  1823. {
  1824.     oldI420toRGB (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 4,
  1825.         is_alpha? dblineI420toRGB32alpha: dblineI420toRGB32);
  1826. }
  1827. void oldI420toRGB24 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  1828.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  1829. {
  1830.     oldI420toRGB (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 3,
  1831.         is_alpha? dblineI420toRGB24alpha: dblineI420toRGB24);
  1832. }
  1833. void oldI420toRGB565 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  1834.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  1835. {
  1836.     oldI420toRGB (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 2,
  1837.         is_alpha? dblineI420toRGB565alpha: dblineI420toRGB565);
  1838. }
  1839. void oldI420toRGB555 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  1840.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  1841. {
  1842.     oldI420toRGB (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 2,
  1843.         is_alpha? dblineI420toRGB555alpha: dblineI420toRGB555);
  1844. }
  1845. /*
  1846.  * Convert two YUV lines into RGB linebufs.
  1847.  * Produces two RGB lines per call.
  1848.  * Output in padded RGB format, needed for SIMD interpolation.
  1849.  */
  1850. static void convertI420toXRGB (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  1851.     unsigned char *buf1, unsigned char *buf2, int width, int pitchSrc)
  1852. {
  1853.     unsigned char * ysrc2 = ysrc + pitchSrc;
  1854.     if (is_alpha) {
  1855.         /* use full matrix: */
  1856.         for (; width; width -= 2) {
  1857.             int ruv, guv, buv, y;
  1858.             buv = butab[usrc[0]] + bvtab[vsrc[0]];
  1859.             guv = gutab[usrc[0]] + gvtab[vsrc[0]];
  1860.             ruv = rutab[usrc[0]] + rvtab[vsrc[0]];
  1861.             /* store as |00 RRRRRRRR 000 GGGGGGGG 000 BBBBBBBB| */
  1862.             y = ytab[ysrc[0]];
  1863.             *(int *)(buf1+0) =
  1864.                 (CLIP8[y + buv] << 0) |
  1865.                 (CLIP8[y + guv] << 11) |
  1866.                 (CLIP8[y + ruv] << 22);
  1867.             y = ytab[ysrc[1]];
  1868.             *(int *)(buf1+4) =
  1869.                 (CLIP8[y + buv] << 0) |
  1870.                 (CLIP8[y + guv] << 11) |
  1871.                 (CLIP8[y + ruv] << 22);
  1872.             y = ytab[ysrc2[0]];
  1873.             *(int *)(buf2+0) =
  1874.                 (CLIP8[y + buv] << 0) |
  1875.                 (CLIP8[y + guv] << 11) |
  1876.                 (CLIP8[y + ruv] << 22);
  1877.             y = ytab[ysrc2[1]];
  1878.             *(int *)(buf2+4) =
  1879.                 (CLIP8[y + buv] << 0) |
  1880.                 (CLIP8[y + guv] << 11) |
  1881.                 (CLIP8[y + ruv] << 22);
  1882.             /* next 2x2 block */
  1883.             ysrc += 2; ysrc2 += 2;
  1884.             usrc += 1; vsrc += 1;
  1885.             buf1 += 8; buf2 += 8;
  1886.         }
  1887.     } else {
  1888.         /* no chroma rotation: */
  1889.         for (; width; width -= 2) {
  1890.             int rv, guv, bu, y;
  1891.             bu = butab[usrc[0]];
  1892.             guv = gutab[usrc[0]] + gvtab[vsrc[0]];
  1893.             rv = rvtab[vsrc[0]];
  1894.             /* store as |00 RRRRRRRR 000 GGGGGGGG 000 BBBBBBBB| */
  1895.             y = ytab[ysrc[0]];
  1896.             *(int *)(buf1+0) =
  1897.                 (CLIP8[y + bu] << 0) |
  1898.                 (CLIP8[y + guv] << 11) |
  1899.                 (CLIP8[y + rv] << 22);
  1900.             y = ytab[ysrc[1]];
  1901.             *(int *)(buf1+4) =
  1902.                 (CLIP8[y + bu] << 0) |
  1903.                 (CLIP8[y + guv] << 11) |
  1904.                 (CLIP8[y + rv] << 22);
  1905.             y = ytab[ysrc2[0]];
  1906.             *(int *)(buf2+0) =
  1907.                 (CLIP8[y + bu] << 0) |
  1908.                 (CLIP8[y + guv] << 11) |
  1909.                 (CLIP8[y + rv] << 22);
  1910.             y = ytab[ysrc2[1]];
  1911.             *(int *)(buf2+4) =
  1912.                 (CLIP8[y + bu] << 0) |
  1913.                 (CLIP8[y + guv] << 11) |
  1914.                 (CLIP8[y + rv] << 22);
  1915.             /* next 2x2 block */
  1916.             ysrc += 2; ysrc2 += 2;
  1917.             usrc += 1; vsrc += 1;
  1918.             buf1 += 8; buf2 += 8;
  1919.         }
  1920.     }
  1921. }
  1922. /*
  1923.  * Interpolate and pack RGB lines into final output
  1924.  * Produces two output lines per call.
  1925.  * Requires padded RGB for SIMD interpolation.
  1926.  */
  1927. #define ROUND888 0x00400801
  1928. /* RGB32 version: */
  1929. static void interpRGB32 (unsigned char *src1, unsigned char *src2,
  1930.     unsigned char *dst1, unsigned char *dst2, int width)
  1931. {
  1932.     unsigned int a, b, c, d, e, f;
  1933.     unsigned int w, x, y, z;
  1934.     width >>= 1;                /* two per pass */
  1935.     while (--width) {           /* do all but last pair */
  1936.     /*
  1937.      * Input pels       Output pels
  1938.      *  a b e           w  x  y  z
  1939.      *  c d f           w' x' y' z'
  1940.      *
  1941.      * Input stored as 00 RRRRRRRR 000 GGGGGGGG 000 BBBBBBBB
  1942.      */
  1943.         /* top line */
  1944.         a = *(unsigned int *)(src1+0);
  1945.         b = *(unsigned int *)(src1+4);
  1946.         e = *(unsigned int *)(src1+8);
  1947.         w = a;
  1948.         x = a + b + ROUND888;
  1949.         y = b;
  1950.         z = b + e + ROUND888;
  1951.         /* pack and store */
  1952.         *(unsigned int *)(dst1+0) =
  1953.             ((w & 0x000000ff) >> 0) |
  1954.             ((w & 0x0007f800) >> 3) |
  1955.             ((w & 0x3fc00000) >> 6);
  1956.         *(unsigned int *)(dst1+4) =
  1957.             ((x & 0x000001fe) >> 1) |
  1958.             ((x & 0x000ff000) >> 4) |
  1959.             ((x & 0x7f800000) >> 7);
  1960.         *(unsigned int *)(dst1+8) =
  1961.             ((y & 0x000000ff) >> 0) |
  1962.             ((y & 0x0007f800) >> 3) |
  1963.             ((y & 0x3fc00000) >> 6);
  1964.         *(unsigned int *)(dst1+12) =
  1965.             ((z & 0x000001fe) >> 1) |
  1966.             ((z & 0x000ff000) >> 4) |
  1967.             ((z & 0x7f800000) >> 7);
  1968.         /* bottom line */
  1969.         c = *(unsigned int *)(src2+0);
  1970.         d = *(unsigned int *)(src2+4);
  1971.         f = *(unsigned int *)(src2+8);
  1972.         w = a + c + ROUND888;
  1973.         x = a + b + c + d + (ROUND888<<1);
  1974.         y = b + d + ROUND888;
  1975.         z = b + e + d + f + (ROUND888<<1);
  1976.         /* pack and store */
  1977.         *(unsigned int *)(dst2+0) =
  1978.             ((w & 0x000001fe) >> 1) |
  1979.             ((w & 0x000ff000) >> 4) |
  1980.             ((w & 0x7f800000) >> 7);
  1981.         *(unsigned int *)(dst2+4) =
  1982.             ((x & 0x000003fc) >> 2) |
  1983.             ((x & 0x001fe000) >> 5) |
  1984.             ((x & 0xff000000) >> 8);
  1985.         *(unsigned int *)(dst2+8) =
  1986.             ((y & 0x000001fe) >> 1) |
  1987.             ((y & 0x000ff000) >> 4) |
  1988.             ((y & 0x7f800000) >> 7);
  1989.         *(unsigned int *)(dst2+12) =
  1990.             ((z & 0x000003fc) >> 2) |
  1991.             ((z & 0x001fe000) >> 5) |
  1992.             ((z & 0xff000000) >> 8);
  1993.         /* bump pointers to next 2x2 input */
  1994.         src1 += 8; src2 += 8;
  1995.         dst1 += 16; dst2 += 16;
  1996.     }
  1997.     /*
  1998.      * For last 4 output pels, repeat final input pel
  1999.      * for offscreen input.  Equivalent to pixel-doubling the
  2000.      * last output pel.
  2001.      */
  2002.     /* top line */
  2003.     a = *(unsigned int *)(src1+0);
  2004.     b = *(unsigned int *)(src1+4);
  2005.     e = b;      /* repeat last input pel */
  2006.     w = a;
  2007.     x = a + b + ROUND888;
  2008.     y = b;
  2009.     z = b + e + ROUND888;
  2010.     /* pack and store */
  2011.     *(unsigned int *)(dst1+0) =
  2012.         ((w & 0x000000ff) >> 0) |
  2013.         ((w & 0x0007f800) >> 3) |
  2014.         ((w & 0x3fc00000) >> 6);
  2015.     *(unsigned int *)(dst1+4) =
  2016.         ((x & 0x000001fe) >> 1) |
  2017.         ((x & 0x000ff000) >> 4) |
  2018.         ((x & 0x7f800000) >> 7);
  2019.     *(unsigned int *)(dst1+8) =
  2020.         ((y & 0x000000ff) >> 0) |
  2021.         ((y & 0x0007f800) >> 3) |
  2022.         ((y & 0x3fc00000) >> 6);
  2023.     *(unsigned int *)(dst1+12) =
  2024.         ((z & 0x000001fe) >> 1) |
  2025.         ((z & 0x000ff000) >> 4) |
  2026.         ((z & 0x7f800000) >> 7);
  2027.     /* bottom line */
  2028.     c = *(unsigned int *)(src2+0);
  2029.     d = *(unsigned int *)(src2+4);
  2030.     f = d;      /* repeat last input pel */
  2031.     w = a + c + ROUND888;
  2032.     x = a + b + c + d + (ROUND888<<1);
  2033.     y = b + d + ROUND888;
  2034.     z = b + e + d + f + (ROUND888<<1);
  2035.     /* pack and store */
  2036.     *(unsigned int *)(dst2+0) =
  2037.         ((w & 0x000001fe) >> 1) |
  2038.         ((w & 0x000ff000) >> 4) |
  2039.         ((w & 0x7f800000) >> 7);
  2040.     *(unsigned int *)(dst2+4) =
  2041.         ((x & 0x000003fc) >> 2) |
  2042.         ((x & 0x001fe000) >> 5) |
  2043.         ((x & 0xff000000) >> 8);
  2044.     *(unsigned int *)(dst2+8) =
  2045.         ((y & 0x000001fe) >> 1) |
  2046.         ((y & 0x000ff000) >> 4) |
  2047.         ((y & 0x7f800000) >> 7);
  2048.     *(unsigned int *)(dst2+12) =
  2049.         ((z & 0x000003fc) >> 2) |
  2050.         ((z & 0x001fe000) >> 5) |
  2051.         ((z & 0xff000000) >> 8);
  2052. }
  2053. /* RGB24 version: */
  2054. static void interpRGB24 (unsigned char *src1, unsigned char *src2,
  2055.     unsigned char *dst1, unsigned char *dst2, int width)
  2056. {
  2057.     unsigned int a, b, c, d, e, f;
  2058.     unsigned int w, x, y, z;
  2059.     width >>= 1;        /* two per pass */
  2060.     while (--width) {   /* do all but last pair */
  2061.     /*
  2062.      * Input pels       Output pels
  2063.      *  a b e           w  x  y  z
  2064.      *  c d f           w' x' y' z'
  2065.      *
  2066.      * Input stored as 00 RRRRRRRR 000 GGGGGGGG 000 BBBBBBBB
  2067.      */
  2068.         /* top line */
  2069.         a = *(unsigned int *)(src1+0);
  2070.         b = *(unsigned int *)(src1+4);
  2071.         e = *(unsigned int *)(src1+8);
  2072.         w = a;
  2073.         x = a + b + ROUND888;
  2074.         y = b;
  2075.         z = b + e + ROUND888;
  2076.         /* pack and store */
  2077.         *(unsigned int *)(dst1+0) =
  2078.             ((w & 0x000000ff) >> 0) |
  2079.             ((w & 0x0007f800) >> 3) |
  2080.             ((w & 0x3fc00000) >> 6) |
  2081.             ((x & 0x000001fe) << 23);
  2082.         *(unsigned int *)(dst1+4) =
  2083.             ((x & 0x000ff000) >> 12) |
  2084.             ((x & 0x7f800000) >> 15) |
  2085.             ((y & 0x000000ff) << 16) |
  2086.             ((y & 0x0007f800) << 13);
  2087.         *(unsigned int *)(dst1+8) =
  2088.             ((y & 0x3fc00000) >> 22) |
  2089.             ((z & 0x000001fe) << 7) |
  2090.             ((z & 0x000ff000) << 4) |
  2091.             ((z & 0x7f800000) << 1);
  2092.         /* bottom line */
  2093.         c = *(unsigned int *)(src2+0);
  2094.         d = *(unsigned int *)(src2+4);
  2095.         f = *(unsigned int *)(src2+8);
  2096.         w = a + c + ROUND888;
  2097.         x = a + b + c + d + (ROUND888<<1);
  2098.         y = b + d + ROUND888;
  2099.         z = b + e + d + f + (ROUND888<<1);
  2100.         /* pack and store */
  2101.         *(unsigned int *)(dst2+0) =
  2102.             ((w & 0x000001fe) >> 1) |
  2103.             ((w & 0x000ff000) >> 4) |
  2104.             ((w & 0x7f800000) >> 7) |
  2105.             ((x & 0x000003fc) << 22);
  2106.         *(unsigned int *)(dst2+4) =
  2107.             ((x & 0x001fe000) >> 13) |
  2108.             ((x & 0xff000000) >> 16) |
  2109.             ((y & 0x000001fe) << 15) |
  2110.             ((y & 0x000ff000) << 12);
  2111.         *(unsigned int *)(dst2+8) =
  2112.             ((y & 0x7f800000) >> 23) |
  2113.             ((z & 0x000003fc) << 6) |
  2114.             ((z & 0x001fe000) << 3) |
  2115.             ((z & 0xff000000) << 0);
  2116.         /* next 2x2 input block */
  2117.         src1 += 8; src2 += 8;
  2118.         dst1 += 12; dst2 += 12;
  2119.     }
  2120.     /*
  2121.      * For last 4 output pels, repeat the final input pel for
  2122.      * for missing input.  Equivalent to pixel-doubling the
  2123.      * last output pel.
  2124.      */
  2125.     /* top line */
  2126.     a = *(unsigned int *)(src1+0);
  2127.     b = *(unsigned int *)(src1+4);
  2128.     e = b;      /* repeat last input pel */
  2129.     w = a;
  2130.     x = a + b + ROUND888;
  2131.     y = b;
  2132.     z = b + e + ROUND888;
  2133.     /* pack and store */
  2134.     *(unsigned int *)(dst1+0) =
  2135.         ((w & 0x000000ff) >> 0) |
  2136.         ((w & 0x0007f800) >> 3) |
  2137.         ((w & 0x3fc00000) >> 6) |
  2138.         ((x & 0x000001fe) << 23);
  2139.     *(unsigned int *)(dst1+4) =
  2140.         ((x & 0x000ff000) >> 12) |
  2141.         ((x & 0x7f800000) >> 15) |
  2142.         ((y & 0x000000ff) << 16) |
  2143.         ((y & 0x0007f800) << 13);
  2144.     *(unsigned int *)(dst1+8) =
  2145.         ((y & 0x3fc00000) >> 22) |
  2146.         ((z & 0x000001fe) << 7) |
  2147.         ((z & 0x000ff000) << 4) |
  2148.         ((z & 0x7f800000) << 1);
  2149.     /* bottom line */
  2150.     c = *(unsigned int *)(src2+0);
  2151.     d = *(unsigned int *)(src2+4);
  2152.     f = d;      /* repeat last input pel */
  2153.     w = a + c + ROUND888;
  2154.     x = a + b + c + d + (ROUND888<<1);
  2155.     y = b + d + ROUND888;
  2156.     z = b + e + d + f + (ROUND888<<1);
  2157.     /* pack and store */
  2158.     *(unsigned int *)(dst2+0) =
  2159.         ((w & 0x000001fe) >> 1) |
  2160.         ((w & 0x000ff000) >> 4) |
  2161.         ((w & 0x7f800000) >> 7) |
  2162.         ((x & 0x000003fc) << 22);
  2163.     *(unsigned int *)(dst2+4) =
  2164.         ((x & 0x001fe000) >> 13) |
  2165.         ((x & 0xff000000) >> 16) |
  2166.         ((y & 0x000001fe) << 15) |
  2167.         ((y & 0x000ff000) << 12);
  2168.     *(unsigned int *)(dst2+8) =
  2169.         ((y & 0x7f800000) >> 23) |
  2170.         ((z & 0x000003fc) << 6) |
  2171.         ((z & 0x001fe000) << 3) |
  2172.         ((z & 0xff000000) << 0);
  2173. }
  2174. /* RGB565 version: */
  2175. static void interpRGB565 (unsigned char *src1, unsigned char *src2,
  2176.     unsigned char *dst1, unsigned char *dst2, int width)
  2177. {
  2178.     unsigned int a, b, c, d, e, f;
  2179.     unsigned int w, x, y, z;
  2180.     width >>= 1;        /* two per pass */
  2181.     while (--width) {   /* do all but last pair */
  2182.     /*
  2183.      * Input pels       Output pels
  2184.      *  a b e           w  x  y  z
  2185.      *  c d f           w' x' y' z'
  2186.      *
  2187.      * Input stored as 00 RRRRRRRR 000 GGGGGGGG 000 BBBBBBBB
  2188.      */
  2189.         /* top line */
  2190.         a = *(unsigned int *)(src1+0);
  2191.         b = *(unsigned int *)(src1+4);
  2192.         e = *(unsigned int *)(src1+8);
  2193.         w = a;
  2194.         x = a + b;
  2195.         y = b;
  2196.         z = b + e;
  2197.         /* pack and store */
  2198.         *(unsigned int *)(dst1+0) =
  2199.             ((w & 0x000000f8) >> 3) |
  2200.             ((w & 0x0007e000) >> 8) |
  2201.             ((w & 0x3e000000) >> 14) |
  2202.             ((x & 0x000001f0) << 12) |
  2203.             ((x & 0x000fc000) << 7) |
  2204.             ((x & 0x7c000000) << 1);
  2205.         *(unsigned int *)(dst1+4) =
  2206.             ((y & 0x000000f8) >> 3) |
  2207.             ((y & 0x0007e000) >> 8) |
  2208.             ((y & 0x3e000000) >> 14) |
  2209.             ((z & 0x000001f0) << 12) |
  2210.             ((z & 0x000fc000) << 7) |
  2211.             ((z & 0x7c000000) << 1);
  2212.         /* bottom line */
  2213.         c = *(unsigned int *)(src2+0);
  2214.         d = *(unsigned int *)(src2+4);
  2215.         f = *(unsigned int *)(src2+8);
  2216.         w = a + c;
  2217.         x = a + b + c + d;
  2218.         y = b + d;
  2219.         z = b + e + d + f;
  2220.         /* pack and store */
  2221.         *(unsigned int *)(dst2+0) =
  2222.             ((w & 0x000001f0) >> 4) |
  2223.             ((w & 0x000fc000) >> 9) |
  2224.             ((w & 0x7c000000) >> 15) |
  2225.             ((x & 0x000003e0) << 11) |
  2226.             ((x & 0x001f8000) << 6) |
  2227.             ((x & 0xf8000000) << 0);
  2228.         *(unsigned int *)(dst2+4) =
  2229.             ((y & 0x000001f0) >> 4) |
  2230.             ((y & 0x000fc000) >> 9) |
  2231.             ((y & 0x7c000000) >> 15) |
  2232.             ((z & 0x000003e0) << 11) |
  2233.             ((z & 0x001f8000) << 6) |
  2234.             ((z & 0xf8000000) << 0);
  2235.         /* next 2x2 input block */
  2236.         src1 += 8; src2 += 8;
  2237.         dst1 += 8; dst2 += 8;
  2238.     }
  2239.     /*
  2240.      * For last 4 output pels, repeat the final input pel for
  2241.      * for missing input.  Equivalent to pixel-doubling the
  2242.      * last output pel.
  2243.      */
  2244.     /* top line */
  2245.     a = *(unsigned int *)(src1+0);
  2246.     b = *(unsigned int *)(src1+4);
  2247.     e = b;      /* repeat last input pel */
  2248.     w = a;
  2249.     x = a + b;
  2250.     y = b;
  2251.     z = b + e;
  2252.     /* pack and store */
  2253.     *(unsigned int *)(dst1+0) =
  2254.         ((w & 0x000000f8) >> 3) |
  2255.         ((w & 0x0007e000) >> 8) |
  2256.         ((w & 0x3e000000) >> 14) |
  2257.         ((x & 0x000001f0) << 12) |
  2258.         ((x & 0x000fc000) << 7) |
  2259.         ((x & 0x7c000000) << 1);
  2260.     *(unsigned int *)(dst1+4) =
  2261.         ((y & 0x000000f8) >> 3) |
  2262.         ((y & 0x0007e000) >> 8) |
  2263.         ((y & 0x3e000000) >> 14) |
  2264.         ((z & 0x000001f0) << 12) |
  2265.         ((z & 0x000fc000) << 7) |
  2266.         ((z & 0x7c000000) << 1);
  2267.     /* bottom line */
  2268.     c = *(unsigned int *)(src2+0);
  2269.     d = *(unsigned int *)(src2+4);
  2270.     f = d;      /* repeat last input pel */
  2271.     w = a + c;
  2272.     x = a + b + c + d;
  2273.     y = b + d;
  2274.     z = b + e + d + f;
  2275.     /* pack and store */
  2276.     *(unsigned int *)(dst2+0) =
  2277.         ((w & 0x000001f0) >> 4) |
  2278.         ((w & 0x000fc000) >> 9) |
  2279.         ((w & 0x7c000000) >> 15) |
  2280.         ((x & 0x000003e0) << 11) |
  2281.         ((x & 0x001f8000) << 6) |
  2282.         ((x & 0xf8000000) << 0);
  2283.     *(unsigned int *)(dst2+4) =
  2284.         ((y & 0x000001f0) >> 4) |
  2285.         ((y & 0x000fc000) >> 9) |
  2286.         ((y & 0x7c000000) >> 15) |
  2287.         ((z & 0x000003e0) << 11) |
  2288.         ((z & 0x001f8000) << 6) |
  2289.         ((z & 0xf8000000) << 0);
  2290. }
  2291. /* RGB555 version: */
  2292. static void interpRGB555 (unsigned char *src1, unsigned char *src2,
  2293.     unsigned char *dst1, unsigned char *dst2, int width)
  2294. {
  2295.     unsigned int a, b, c, d, e, f;
  2296.     unsigned int w, x, y, z;
  2297.     width >>= 1;        /* two per pass */
  2298.     while (--width) {   /* do all but last pair */
  2299.     /*
  2300.      * Input pels       Output pels
  2301.      *  a b e           w  x  y  z
  2302.      *  c d f           w' x' y' z'
  2303.      *
  2304.      * Input stored as 00 RRRRRRRR 000 GGGGGGGG 000 BBBBBBBB
  2305.      */
  2306.         /* top line */
  2307.         a = *(unsigned int *)(src1+0);
  2308.         b = *(unsigned int *)(src1+4);
  2309.         e = *(unsigned int *)(src1+8);
  2310.         w = a;
  2311.         x = a + b;
  2312.         y = b;
  2313.         z = b + e;
  2314.         /* pack and store */
  2315.         *(unsigned int *)(dst1+0) =
  2316.             ((w & 0x000000f8) >> 3) |
  2317.             ((w & 0x0007c000) >> 9) |
  2318.             ((w & 0x3e000000) >> 15) |
  2319.             ((x & 0x000001f0) << 12) |
  2320.             ((x & 0x000f8000) << 6) |
  2321.             ((x & 0x7c000000) << 0);
  2322.         *(unsigned int *)(dst1+4) =
  2323.             ((y & 0x000000f8) >> 3) |
  2324.             ((y & 0x0007c000) >> 9) |
  2325.             ((y & 0x3e000000) >> 15) |
  2326.             ((z & 0x000001f0) << 12) |
  2327.             ((z & 0x000f8000) << 6) |
  2328.             ((z & 0x7c000000) << 0);
  2329.         /* bottom line */
  2330.         c = *(unsigned int *)(src2+0);
  2331.         d = *(unsigned int *)(src2+4);
  2332.         f = *(unsigned int *)(src2+8);
  2333.         w = a + c;
  2334.         x = a + b + c + d;
  2335.         y = b + d;
  2336.         z = b + e + d + f;
  2337.         /* pack and store */
  2338.         *(unsigned int *)(dst2+0) =
  2339.             ((w & 0x000001f0) >> 4) |
  2340.             ((w & 0x000f8000) >> 10) |
  2341.             ((w & 0x7c000000) >> 16) |
  2342.             ((x & 0x000003e0) << 11) |
  2343.             ((x & 0x001f0000) << 5) |
  2344.             ((x & 0xf8000000) >> 1);
  2345.         *(unsigned int *)(dst2+4) =
  2346.             ((y & 0x000001f0) >> 4) |
  2347.             ((y & 0x000f8000) >> 10) |
  2348.             ((y & 0x7c000000) >> 16) |
  2349.             ((z & 0x000003e0) << 11) |
  2350.             ((z & 0x001f0000) << 5) |
  2351.             ((z & 0xf8000000) >> 1);
  2352.         /* next 2x2 input block */
  2353.         src1 += 8; src2 += 8;
  2354.         dst1 += 8; dst2 += 8;
  2355.     }
  2356.     /*
  2357.      * For last 4 output pels, repeat the final input pel for
  2358.      * for missing input.  Equivalent to pixel-doubling the
  2359.      * last output pel.
  2360.      */
  2361.     /* top line */
  2362.     a = *(unsigned int *)(src1+0);
  2363.     b = *(unsigned int *)(src1+4);
  2364.     e = b;      /* repeat last input pel */
  2365.     w = a;
  2366.     x = a + b;
  2367.     y = b;
  2368.     z = b + e;
  2369.     /* pack and store */
  2370.     *(unsigned int *)(dst1+0) =
  2371.         ((w & 0x000000f8) >> 3) |
  2372.         ((w & 0x0007c000) >> 9) |
  2373.         ((w & 0x3e000000) >> 15) |
  2374.         ((x & 0x000001f0) << 12) |
  2375.         ((x & 0x000f8000) << 6) |
  2376.         ((x & 0x7c000000) << 0);
  2377.     *(unsigned int *)(dst1+4) =
  2378.         ((y & 0x000000f8) >> 3) |
  2379.         ((y & 0x0007c000) >> 9) |
  2380.         ((y & 0x3e000000) >> 15) |
  2381.         ((z & 0x000001f0) << 12) |
  2382.         ((z & 0x000f8000) << 6) |
  2383.         ((z & 0x7c000000) << 0);
  2384.     /* bottom line */
  2385.     c = *(unsigned int *)(src2+0);
  2386.     d = *(unsigned int *)(src2+4);
  2387.     f = d;      /* repeat last input pel */
  2388.     w = a + c;
  2389.     x = a + b + c + d;
  2390.     y = b + d;
  2391.     z = b + e + d + f;
  2392.     /* pack and store */
  2393.     *(unsigned int *)(dst2+0) =
  2394.         ((w & 0x000001f0) >> 4) |
  2395.         ((w & 0x000f8000) >> 10) |
  2396.         ((w & 0x7c000000) >> 16) |
  2397.         ((x & 0x000003e0) << 11) |
  2398.         ((x & 0x001f0000) << 5) |
  2399.         ((x & 0xf8000000) >> 1);
  2400.     *(unsigned int *)(dst2+4) =
  2401.         ((y & 0x000001f0) >> 4) |
  2402.         ((y & 0x000f8000) >> 10) |
  2403.         ((y & 0x7c000000) >> 16) |
  2404.         ((z & 0x000003e0) << 11) |
  2405.         ((z & 0x001f0000) << 5) |
  2406.         ((z & 0xf8000000) >> 1);
  2407. }
  2408. /* the driver function: */
  2409. void oldI420toRGBx2 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  2410.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst, int bpp,
  2411.     void (* interp) (unsigned char *, unsigned char *, unsigned char *, unsigned char *, int))
  2412. {
  2413.     /* Pointers to the three RGB linebuffers */
  2414.     unsigned char *buf[3]; /* Flawfinder: ignore */
  2415.     int ibuf = 0;                           /* circular buffer index */
  2416.     int dstinc = bpp * 2 * pitchDst;        /* offset to next output line */
  2417.     unsigned char *dst2 = dst + bpp * pitchDst;    /* second output line */
  2418.     buf[0] = linebuf;
  2419.     buf[1] = linebuf + 4 * width;
  2420.     buf[2] = linebuf + 8 * width;
  2421.     /* Bump dst to other end, if inverting ouput */
  2422.     if (pitchDst < 0) {
  2423.         dst += bpp * -pitchDst * (2*height - 1);
  2424.         dst2 += bpp * -pitchDst * (2*height - 1);
  2425.     }
  2426.     /* Special case for first 2 lines */
  2427.     convertI420toXRGB (ysrc, usrc, vsrc, buf[next[ibuf]], buf[next2[ibuf]], width, pitchSrc);
  2428.     ysrc += pitchSrc << 1;                  /* next 2 lines */
  2429.     usrc += pitchSrc >> 1;                  /* next line */
  2430.     vsrc += pitchSrc >> 1;                  /* next line */
  2431.     /* skip first interp */
  2432.     ibuf = next[ibuf];                      /* shift buffers */
  2433.     (* interp) (buf[ibuf], buf[next[ibuf]], dst, dst2, width);
  2434.     dst += dstinc;                          /* next 2 lines */
  2435.     dst2 += dstinc;
  2436.     ibuf = next[ibuf];                      /* shift buffers */
  2437.     height >>= 1;       /* two rows per pass */
  2438.     while (--height) {  /* do all but last pair */
  2439.         /* Convert 2 lines into bufs */
  2440.         convertI420toXRGB (ysrc, usrc, vsrc, buf[next[ibuf]], buf[next2[ibuf]], width, pitchSrc);
  2441.         ysrc += pitchSrc << 1;              /* next 2 lines */
  2442.         usrc += pitchSrc >> 1;              /* next line */
  2443.         vsrc += pitchSrc >> 1;              /* next line */
  2444.         /* Interp 2 lines into dst */
  2445.         (* interp) (buf[ibuf], buf[next[ibuf]], dst, dst2, width);
  2446.         dst += dstinc;                      /* next 2 lines */
  2447.         dst2 += dstinc;
  2448.         ibuf = next[ibuf];                  /* shift buffers */
  2449.         /* Interp 2 lines into dst */
  2450.         (* interp) (buf[ibuf], buf[next[ibuf]], dst, dst2, width);
  2451.         dst += dstinc;                      /* next 2 lines */
  2452.         dst2 += dstinc;
  2453.         ibuf = next[ibuf];                  /* shift buffers */
  2454.     }
  2455.     /* Last 2 lines, repeating last input line */
  2456.     (* interp) (buf[ibuf], buf[ibuf], dst, dst2, width);
  2457. }
  2458. /* actual converters: */
  2459. void oldI420toRGB32x2 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  2460.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  2461. {
  2462.     oldI420toRGBx2 (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 4, interpRGB32);
  2463. }
  2464. void oldI420toRGB24x2 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  2465.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  2466. {
  2467.     oldI420toRGBx2 (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 3, interpRGB24);
  2468. }
  2469. void oldI420toRGB565x2 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  2470.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  2471. {
  2472.     oldI420toRGBx2 (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 2, interpRGB565);
  2473. }
  2474. void oldI420toRGB555x2 (unsigned char *ysrc, unsigned char *usrc, unsigned char *vsrc,
  2475.     int pitchSrc, unsigned char *dst, int width, int height, int pitchDst)
  2476. {
  2477.     oldI420toRGBx2 (ysrc, usrc, vsrc, pitchSrc, dst, width, height, pitchDst, 2, interpRGB555);
  2478. }
  2479. #if defined (_MACINTOSH) && defined (_DEBUG)
  2480. #pragma global_optimizer off
  2481. #endif
  2482. /* colorcvt.c -- end of file */