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

Symbian

开发平台:

Visual C++

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