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

Symbian

开发平台:

C/C++

  1.             DBLROW_FN(RGB565,I420 ,FULL, STRETCH2XPLUS)
  2.     #else
  3.             0
  4.     #endif //HXCOLOR_STRETCH2XPLUS
  5.             
  6. #else
  7.     0,
  8.     0,
  9.     0,
  10.     0,
  11.     0
  12. #endif
  13.         },{
  14. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB555out)
  15.     #if defined (HXCOLOR_SHRINK)
  16.             DBLROW_FN(RGB555,I420 ,FULL, SHRINK),
  17.     #else
  18.             0,
  19.     #endif //HXCOLOR_SHRINK
  20.             DBLROW_FN(RGB555,I420 ,FULL, COPY),
  21.     #if defined (HXCOLOR_STRETCH)
  22.             DBLROW_FN(RGB555,I420 ,FULL, STRETCH),
  23.     #else
  24.             0,
  25.     #endif //HXCOLOR_STRETCH
  26.     #if defined (HXCOLOR_STRETCH2X)
  27.             DBLROW_FN(RGB555,I420 ,FULL, STRETCH2X),
  28.     #else
  29.             0,
  30.     #endif //HXCOLOR_STRETCH2X
  31.             
  32.     #if defined (HXCOLOR_STRETCH2XPLUS)
  33.             DBLROW_FN(RGB555,I420 ,FULL, STRETCH2XPLUS)
  34.     #else
  35.             0
  36.     #endif //HXCOLOR_STRETCH2XPLUS
  37. #else
  38.     0,
  39.     0,
  40.     0,
  41.     0,
  42.     0
  43. #endif
  44.         },{
  45. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB444out)
  46.     #if defined (HXCOLOR_SHRINK)
  47.             DBLROW_FN(RGB444,I420 ,FULL, SHRINK),
  48.     #else
  49.             0,
  50.     #endif //HXCOLOR_SHRINK
  51.             DBLROW_FN(RGB444,I420 ,FULL, COPY),
  52.     #if defined (HXCOLOR_STRETCH)
  53.             DBLROW_FN(RGB444,I420 ,FULL, STRETCH),
  54.     #else
  55.             0,
  56.     #endif //HXCOLOR_STRETCH
  57.     #if defined (HXCOLOR_STRETCH2X)
  58.             DBLROW_FN(RGB444,I420 ,FULL, STRETCH2X),
  59.     #else
  60.             0,
  61.     #endif //HXCOLOR_STRETCH2X
  62.             
  63.     #if defined (HXCOLOR_STRETCH2XPLUS)
  64.             DBLROW_FN(RGB444,I420 ,FULL, STRETCH2XPLUS)
  65.     #else
  66.             0
  67.     #endif //HXCOLOR_STRETCH2XPLUS
  68. #else
  69.     0,
  70.     0,
  71.     0,
  72.     0,
  73.     0
  74. #endif
  75.         },{
  76. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB8out)
  77.     #if defined (HXCOLOR_SHRINK)
  78.             DBLROW_FN(RGB8  ,I420 ,FULL, SHRINK),
  79.     #else
  80.             0,
  81.     #endif //HXCOLOR_SHRINK
  82.             DBLROW_FN(RGB8  ,I420 ,FULL, COPY),
  83.     #if defined (HXCOLOR_STRETCH)
  84.             DBLROW_FN(RGB8  ,I420 ,FULL, STRETCH),
  85.     #else
  86.             0,
  87.     #endif //HXCOLOR_STRETCH
  88.     #if defined (HXCOLOR_STRETCH2X)
  89.             DBLROW_FN(RGB8  ,I420 ,FULL, STRETCH2X),
  90.     #else
  91.             0,
  92.     #endif //HXCOLOR_STRETCH2X
  93.             
  94.     #if defined (HXCOLOR_STRETCH2XPLUS)
  95.             DBLROW_FN(RGB8  ,I420 ,FULL, STRETCH2XPLUS)
  96.     #else
  97.             0
  98.     #endif //HXCOLOR_STRETCH2XPLUS
  99.             
  100.             
  101. #else
  102.     0,
  103.     0,
  104.     0,
  105.     0,
  106.     0
  107. #endif
  108.         }
  109.     }
  110. };
  111. /*
  112.  * Double-row scale function selection tables:
  113.  *  [conversion type][source format][row scale type]
  114.  */
  115. static void (* DblRow2xFuncs [2][RGB_FORMATS][SCALE_FUNCS]) (
  116.     unsigned char *d0, unsigned char *d01, unsigned char *d1,
  117.     unsigned char *d12, unsigned char *d2, int dest_x, int dest_dx,
  118.     unsigned char *sy1, unsigned char *sy2,
  119.     unsigned char *su, unsigned char *sv, int src_x, int src_dx) =
  120. {
  121.     {   {
  122. #if defined (HELIX_FEATURE_CC_RGB32out)
  123.     #if defined (HXCOLOR_SHRINK)
  124.             DBLROW2X_FN(RGB32 ,I420 ,FAST, SHRINK),
  125.     #else
  126.             0,
  127.     #endif //HXCOLOR_SHRINK
  128.             
  129.             DBLROW2X_FN(RGB32 ,I420 ,FAST, COPY),
  130.     #if defined (HXCOLOR_STRETCH)
  131.             DBLROW2X_FN(RGB32 ,I420 ,FAST, STRETCH),
  132.     #else
  133.             0,
  134.     #endif //HXCOLOR_STRETCH
  135.     #if defined (HXCOLOR_STRETCH2X)
  136.             DBLROW2X_FN(RGB32 ,I420 ,FAST, STRETCH2X),
  137.     #else
  138.             0,
  139.     #endif //HXCOLOR_STRETCH2X
  140.             
  141.     #if defined (HXCOLOR_STRETCH2XPLUS)
  142.             DBLROW2X_FN(RGB32 ,I420 ,FAST, STRETCH2XPLUS)
  143.     #else
  144.             0
  145.     #endif //HXCOLOR_STRETCH2XPLUS
  146. #else
  147.     0,
  148.     0,
  149.     0,
  150.     0,
  151.     0
  152. #endif //HELIX_FEATURE_CC_RGB32out
  153.         },{
  154. #if defined (HELIX_FEATURE_CC_BGR32out)
  155.     #if defined (HXCOLOR_SHRINK)
  156.             DBLROW2X_FN(BGR32 ,I420 ,FAST, SHRINK),
  157.     #else
  158.             0,
  159.     #endif //HXCOLOR_SHRINK
  160.             
  161.             DBLROW2X_FN(BGR32 ,I420 ,FAST, COPY),
  162.     #if defined (HXCOLOR_STRETCH)
  163.             DBLROW2X_FN(BGR32 ,I420 ,FAST, STRETCH),
  164.     #else
  165.             0,
  166.     #endif //HXCOLOR_STRETCH
  167.             
  168.     #if defined (HXCOLOR_STRETCH2X)
  169.             DBLROW2X_FN(BGR32 ,I420 ,FAST, STRETCH2X),
  170.     #else
  171.             0,
  172.     #endif //HXCOLOR_STRETCH2X
  173.             
  174.     #if defined (HXCOLOR_STRETCH2XPLUS)
  175.             DBLROW2X_FN(BGR32 ,I420 ,FAST, STRETCH2XPLUS)
  176.     #else
  177.             0
  178.     #endif //HXCOLOR_STRETCH2XPLUS
  179.             
  180. #else
  181.     0,
  182.     0,
  183.     0,
  184.     0,
  185.     0
  186. #endif //HELIX_FEATURE_CC_BGR32out
  187.         },{
  188. #if defined (HELIX_FEATURE_CC_RGB24out)
  189.     #if defined (HXCOLOR_SHRINK)
  190.             DBLROW2X_FN(RGB24 ,I420 ,FAST, SHRINK),
  191.     #else
  192.             0,
  193.     #endif // HXCOLOR_SHRINK
  194.             
  195.             DBLROW2X_FN(RGB24 ,I420 ,FAST, COPY),
  196.     #if defined (HXCOLOR_STRETCH)
  197.             DBLROW2X_FN(RGB24 ,I420 ,FAST, STRETCH),
  198.     #else
  199.             0,
  200.     #endif // HXCOLOR_STRETCH
  201.             
  202.     #if defined (HXCOLOR_STRETCH2X)
  203.             DBLROW2X_FN(RGB24 ,I420 ,FAST, STRETCH2X),
  204.     #else
  205.             0,
  206.     #endif // HXCOLOR_STRETCH2X
  207.             
  208.     #if defined (HXCOLOR_STRETCH2XPLUS)
  209.             DBLROW2X_FN(RGB24 ,I420 ,FAST, STRETCH2XPLUS)
  210.     #else
  211.             0
  212.     #endif // HXCOLOR_STRETCH2XPLUS
  213.             
  214. #else
  215.     0,
  216.     0,
  217.     0,
  218.     0,
  219.     0
  220. #endif //HELIX_FEATURE_CC_RGB24out
  221.         },{
  222. #if defined (HELIX_FEATURE_CC_RGB565out)
  223.             
  224.     #if defined (HXCOLOR_SHRINK)
  225.             DBLROW2X_FN(RGB565,I420 ,FAST, SHRINK),
  226.     #else
  227.             0,
  228.     #endif // HXCOLOR_SHRINK
  229.             
  230.             DBLROW2X_FN(RGB565,I420 ,FAST, COPY),
  231.     #if defined (HXCOLOR_STRETCH)
  232.             DBLROW2X_FN(RGB565,I420 ,FAST, STRETCH),
  233.     #else
  234.             0,
  235.     #endif // HXCOLOR_STRETCH
  236.             
  237.     #if defined (HXCOLOR_STRETCH2X)
  238.             DBLROW2X_FN(RGB565,I420 ,FAST, STRETCH2X),
  239.     #else
  240.             0,
  241.     #endif // HXCOLOR_STRETCH2X
  242.             
  243.     #if defined (HXCOLOR_STRETCH2XPLUS)
  244.             DBLROW2X_FN(RGB565,I420 ,FAST, STRETCH2XPLUS)
  245.     #else
  246.             0
  247.     #endif // HXCOLOR_STRETCH2XPLUS
  248.             
  249. #else
  250.     0,
  251.     0,
  252.     0,
  253.     0,
  254.     0
  255. #endif //HELIX_FEATURE_CC_RGB565out
  256.         },{
  257. #if defined (HELIX_FEATURE_CC_RGB555out)
  258.     #if defined (HXCOLOR_SHRINK)
  259.             DBLROW2X_FN(RGB555,I420 ,FAST, SHRINK),
  260.     #else
  261.             0,
  262.     #endif // HXCOLOR_SHRINK
  263.             
  264.             DBLROW2X_FN(RGB555,I420 ,FAST, COPY),
  265.     #if defined (HXCOLOR_STRETCH)
  266.             DBLROW2X_FN(RGB555,I420 ,FAST, STRETCH),
  267.     #else
  268.             0,
  269.     #endif // HXCOLOR_STRETCH
  270.             
  271.     #if defined (HXCOLOR_STRETCH2X)
  272.             DBLROW2X_FN(RGB555,I420 ,FAST, STRETCH2X),
  273.     #else
  274.             0,
  275.     #endif // HXCOLOR_STRETCH2X
  276.             
  277.     #if defined (HXCOLOR_STRETCH2XPLUS)
  278.             DBLROW2X_FN(RGB555,I420 ,FAST, STRETCH2XPLUS)
  279.     #else
  280.             0
  281.     #endif // STRETCH2XPLUS
  282.             
  283. #else
  284.     0,
  285.     0,
  286.     0,
  287.     0,
  288.     0
  289. #endif //HELIX_FEATURE_CC_RGB555out
  290.         },{
  291. #if defined (HELIX_FEATURE_CC_RGB444out)
  292.     #if defined (HXCOLOR_SHRINK)
  293.             DBLROW2X_FN(RGB444,I420 ,FAST, SHRINK),
  294.     #else
  295.             0,
  296.     #endif // HXCOLOR_SHRINK
  297.             
  298.             DBLROW2X_FN(RGB444,I420 ,FAST, COPY),
  299.     #if defined (HXCOLOR_STRETCH)
  300.             DBLROW2X_FN(RGB444,I420 ,FAST, STRETCH),
  301.     #else
  302.             0,
  303.     #endif // HXCOLOR_STRETCH
  304.             
  305.     #if defined (HXCOLOR_STRETCH2X)
  306.             DBLROW2X_FN(RGB444,I420 ,FAST, STRETCH2X),
  307.     #else
  308.             0,
  309.     #endif // HXCOLOR_STRETCH2X
  310.             
  311.     #if defined (HXCOLOR_STRETCH2XPLUS)
  312.             DBLROW2X_FN(RGB444,I420 ,FAST, STRETCH2XPLUS)
  313.     #else
  314.             0
  315.     #endif // STRETCH2XPLUS
  316.             
  317. #else
  318.     0,
  319.     0,
  320.     0,
  321.     0,
  322.     0
  323. #endif //HELIX_FEATURE_CC_RGB444out
  324.         },{
  325. #if defined (HELIX_FEATURE_CC_RGB8out)
  326.     #if defined (HXCOLOR_SHRINK)
  327.             DBLROW2X_FN(RGB8  ,I420 ,FAST, SHRINK),
  328.     #else
  329.             0,
  330.     #endif // HXCOLOR_SHRINK
  331.             
  332.             DBLROW2X_FN(RGB8  ,I420 ,FAST, COPY),
  333.     #if defined (HXCOLOR_SHRINK)
  334.             DBLROW2X_FN(RGB8  ,I420 ,FAST, SHRINK),
  335.     #else
  336.             0,
  337.     #endif // HXCOLOR_SHRINK
  338.             
  339.     #if defined (HXCOLOR_SHRINK2X)
  340.             DBLROW2X_FN(RGB8  ,I420 ,FAST, STRETCH2X),
  341.     #else
  342.             0,
  343.     #endif // HXCOLOR_SHRINK2X
  344.             
  345.     #if defined (HXCOLOR_STRETCH2XPLUS)
  346.             DBLROW2X_FN(RGB8  ,I420 ,FAST, STRETCH2XPLUS)
  347.     #else
  348.             0
  349.     #endif // HXCOLOR_STRETCH2XPLUS
  350.             
  351. #else
  352.     0,
  353.     0,
  354.     0,
  355.     0,
  356.     0
  357. #endif //HELIX_FEATURE_CC_RGB8out
  358.         }
  359.     },{ {
  360. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB32out)
  361.     #if defined (HXCOLOR_SHRINK)
  362.             DBLROW2X_FN(RGB32 ,I420 ,FULL, SHRINK),
  363.     #else
  364.             0,
  365.     #endif // HXCOLOR_SHRINK
  366.             
  367.             DBLROW2X_FN(RGB32 ,I420 ,FULL, COPY),
  368.     #if defined (HXCOLOR_STRETCH)
  369.             DBLROW2X_FN(RGB32 ,I420 ,FULL, STRETCH),
  370.     #else
  371.             0,
  372.     #endif // HXCOLOR_STRETCH
  373.             
  374.     #if defined (HXCOLOR_STRETCH2X)
  375.             DBLROW2X_FN(RGB32 ,I420 ,FULL, STRETCH2X),
  376.     #else
  377.             0,
  378.     #endif // HXCOLOR_STRETCH2X
  379.             
  380.     #if defined (HXCOLOR_STRETCH2XPLUS)
  381.             DBLROW2X_FN(RGB32 ,I420 ,FULL, STRETCH2XPLUS)
  382.     #else
  383.             0
  384.     #endif // HXCOLOR_STRETCH2XPLUS
  385.             
  386. #else
  387.     0,
  388.     0,
  389.     0,
  390.     0,
  391.     0
  392. #endif
  393.         },{
  394. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_BGR32out)
  395.     #if defined (HXCOLOR_SHRINK)
  396.             DBLROW2X_FN(BGR32 ,I420 ,FULL, SHRINK),
  397.     #else
  398.             0,
  399.     #endif // HXCOLOR_SHRINK
  400.             
  401.             DBLROW2X_FN(BGR32 ,I420 ,FULL, COPY),
  402.     #if defined (HXCOLOR_STRETCH)
  403.             DBLROW2X_FN(BGR32 ,I420 ,FULL, STRETCH),
  404.     #else
  405.             0,
  406.     #endif // HXCOLOR_STRETCH
  407.             
  408.     #if defined (HXCOLOR_STRETCH2X)
  409.             DBLROW2X_FN(BGR32 ,I420 ,FULL, STRETCH2X),
  410.     #else
  411.             0,
  412.     #endif // HXCOLOR_STRETCH2X
  413.             
  414.     #if defined (HXCOLOR_STRETCH2XPLUS)
  415.             DBLROW2X_FN(BGR32 ,I420 ,FULL, STRETCH2XPLUS)
  416.     #else
  417.             0
  418.     #endif // HXCOLOR_STRETCH2XPLUS
  419.             
  420. #else
  421.     0,
  422.     0,
  423.     0,
  424.     0,
  425.     0
  426. #endif
  427.         },{
  428. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB24out)
  429.     #if defined (HXCOLOR_SHRINK)
  430.             DBLROW2X_FN(RGB24 ,I420 ,FULL, SHRINK),
  431.     #else
  432.             0,
  433.     #endif // HXCOLOR_SHRINK
  434.             
  435.             DBLROW2X_FN(RGB24 ,I420 ,FULL, COPY),
  436.     #if defined (HXCOLOR_STRETCH)
  437.             DBLROW2X_FN(RGB24 ,I420 ,FULL, STRETCH),
  438.     #else
  439.             0,
  440.     #endif // HXCOLOR_STRETCH
  441.             
  442.     #if defined (HXCOLOR_STRETCH2X)
  443.             DBLROW2X_FN(RGB24 ,I420 ,FULL, STRETCH2X),
  444.     #else
  445.             0,
  446.     #endif // HXCOLOR_STRETCH2X
  447.             
  448.     #if defined (HXCOLOR_STRETCH2XPLUS)
  449.             DBLROW2X_FN(RGB24 ,I420 ,FULL, STRETCH2XPLUS)
  450.     #else
  451.             0
  452.     #endif // HXCOLOR_STRETCH2XPLUS
  453.             
  454. #else
  455.     0,
  456.     0,
  457.     0,
  458.     0,
  459.     0
  460. #endif
  461.         },{
  462. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB565out)
  463.     #if defined (HXCOLOR_SHRINK)
  464.             DBLROW2X_FN(RGB565,I420 ,FULL, SHRINK),
  465.     #else
  466.             0,
  467.     #endif // HXCOLOR_SHRINK
  468.             
  469.             DBLROW2X_FN(RGB565,I420 ,FULL, COPY),
  470.     #if defined (HXCOLOR_STRETCH)
  471.             DBLROW2X_FN(RGB565,I420 ,FULL, STRETCH),
  472.     #else
  473.             0,
  474.     #endif // HXCOLOR_STRETCH
  475.             
  476.     #if defined (HXCOLOR_STRETCH2X)
  477.             DBLROW2X_FN(RGB565,I420 ,FULL, STRETCH2X),
  478.     #else
  479.             0,
  480.     #endif // HXCOLOR_STRETCH2X
  481.             
  482.     #if defined (HXCOLOR_STRETCH2XPLUS)
  483.             DBLROW2X_FN(RGB565,I420 ,FULL, STRETCH2XPLUS)
  484.     #else
  485.             0
  486.     #endif // HXCOLOR_STRETCH2XPLUS
  487.             
  488. #else
  489.     0,
  490.     0,
  491.     0,
  492.     0,
  493.     0
  494. #endif
  495.         },{
  496. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB555out)
  497.     #if defined (HXCOLOR_SHRINK)
  498.             DBLROW2X_FN(RGB555,I420 ,FULL, SHRINK),
  499.     #else
  500.             0,
  501.     #endif // HXCOLOR_SHRINK
  502.             
  503.             DBLROW2X_FN(RGB555,I420 ,FULL, COPY),
  504.     #if defined (HXCOLOR_STRETCH)
  505.             DBLROW2X_FN(RGB555,I420 ,FULL, STRETCH),
  506.     #else
  507.             0,
  508.     #endif // HXCOLOR_STRETCH
  509.             
  510.     #if defined (HXCOLOR_STRETCH2X)
  511.             DBLROW2X_FN(RGB555,I420 ,FULL, STRETCH2X),
  512.     #else
  513.             0,
  514.     #endif // HXCOLOR_STRETCH2X
  515.             
  516.     #if defined (HXCOLOR_STRETCH2XPLUS)
  517.             DBLROW2X_FN(RGB555,I420 ,FULL, STRETCH2XPLUS)
  518.     #else
  519.             0
  520.     #endif // HXCOLOR_STRETCH2XPLUS
  521.             
  522. #else
  523.     0,
  524.     0,
  525.     0,
  526.     0,
  527.     0
  528. #endif
  529.         },{
  530. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB444out)
  531.     #if defined (HXCOLOR_SHRINK)
  532.             DBLROW2X_FN(RGB444,I420 ,FULL, SHRINK),
  533.     #else
  534.             0,
  535.     #endif // HXCOLOR_SHRINK
  536.             
  537.             DBLROW2X_FN(RGB444,I420 ,FULL, COPY),
  538.     #if defined (HXCOLOR_STRETCH)
  539.             DBLROW2X_FN(RGB444,I420 ,FULL, STRETCH),
  540.     #else
  541.             0,
  542.     #endif // HXCOLOR_STRETCH
  543.             
  544.     #if defined (HXCOLOR_STRETCH2X)
  545.             DBLROW2X_FN(RGB444,I420 ,FULL, STRETCH2X),
  546.     #else
  547.             0,
  548.     #endif // HXCOLOR_STRETCH2X
  549.             
  550.     #if defined (HXCOLOR_STRETCH2XPLUS)
  551.             DBLROW2X_FN(RGB444,I420 ,FULL, STRETCH2XPLUS)
  552.     #else
  553.             0
  554.     #endif // HXCOLOR_STRETCH2XPLUS
  555.             
  556. #else
  557.     0,
  558.     0,
  559.     0,
  560.     0,
  561.     0
  562. #endif
  563.         },{
  564. #if defined _PLUS_HXCOLOR && defined (HELIX_FEATURE_CC_RGB8out)
  565.     #if defined (HXCOLOR_SHRINK)
  566.             DBLROW2X_FN(RGB8  ,I420 ,FULL, SHRINK),
  567.     #else
  568.             0,
  569.     #endif // HXCOLOR_SHRINK
  570.             
  571.             DBLROW2X_FN(RGB8  ,I420 ,FULL, COPY),
  572.     #if defined (HXCOLOR_STRETCH)
  573.             DBLROW2X_FN(RGB8  ,I420 ,FULL, STRETCH),
  574.     #else
  575.             0,
  576.     #endif // HXCOLOR_STRETCH
  577.             
  578.     #if defined (HXCOLOR_STRETCH2X)
  579.             DBLROW2X_FN(RGB8  ,I420 ,FULL, STRETCH2X),
  580.     #else
  581.             0,
  582.     #endif // HXCOLOR_STRETCH2X
  583.             
  584.     #if defined (HXCOLOR_STRETCH2XPLUS)
  585.             DBLROW2X_FN(RGB8  ,I420 ,FULL, STRETCH2XPLUS)
  586.     #else
  587.             0
  588.     #endif // HXCOLOR_STRETCH2XPLUS
  589.             
  590. #else
  591.     0,
  592.     0,
  593.     0,
  594.     0,
  595.     0
  596. #endif
  597.         }
  598.     }
  599. };
  600. /*** YUV image converters: *********************************/
  601. /*
  602.  * Temporary RGB row buffers:
  603.  */
  604. #define MAXWIDTH 2048   /* should be larger that max.hor.res. of a monitor */
  605. static unsigned char tmp1 [MAXWIDTH * BPP(RGB32)]; /* Flawfinder: ignore */
  606. static unsigned char tmp2 [MAXWIDTH * BPP(RGB32)]; /* Flawfinder: ignore */
  607. /*
  608.  * Image shrink converter:
  609.  *  (uses readahead optimization to process all aligned
  610.  *  pairs of rows simultaneously (in a single dblrow_func() call))
  611.  */
  612. static void IMAGE_SHRINK (unsigned char *dest_ptr,
  613.     int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  614.     unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  615.     int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  616.     void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  617.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  618.     void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  619.         unsigned char *, unsigned char *, int, int, unsigned char *,
  620.         unsigned char *, unsigned char *, unsigned char *, int, int))
  621. {
  622.     /* initialize local variables: */
  623.     register unsigned char *d1  = dest_ptr;
  624.     register unsigned char *d2  = d1 + dest_pitch;
  625.     register unsigned char *sy1 = src_y_ptr;
  626.     register unsigned char *sy2 = sy1 + src_pitch;
  627.     register unsigned char *su  = src_u_ptr;
  628.     register unsigned char *sv  = src_v_ptr;
  629.     register int count = dest_dy;
  630.     register int limit = src_dy >> 1; /* -1 */
  631.     register int step = dest_dy;
  632.     /* check image height: */
  633.     if (count) {
  634.         /* check if top row is misaligned: */
  635.         if (src_y & 1)
  636.             goto start_odd;
  637.         /* process even rows: */
  638.         do {
  639.             /* make one Bresenham step ahead: */
  640.             if ((limit -= step) < 0) {
  641.                 limit += src_dy;
  642.                 /* can we process 2 rows? */
  643.                 if (!--count)
  644.                     goto last_pixel;
  645.                 /* process two rows: */
  646.                 (* dblrow_func) (d1, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  647.                 d1  += dest_pitch*2; d2  += dest_pitch*2;
  648.                 sy1 += src_pitch*2;  sy2 += src_pitch*2;
  649.                 su  += src_pitch_2;  sv  += src_pitch_2;
  650.             } else {
  651.                 /* proc. first row & skip next: */
  652.                 (* dblrow_func) (d1, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  653.                 d1  += dest_pitch;   d2  += dest_pitch;
  654.                 sy1 += src_pitch*2;  sy2 += src_pitch*2;
  655.                 su  += src_pitch_2;  sv  += src_pitch_2;
  656.             }
  657.             /* inverted Bresenham stepping: */
  658.             while ((limit -= step) >= 0) {
  659.                 /* skip next even source row: */
  660.                 sy1 += src_pitch;    sy2 += src_pitch;
  661.                 if ((limit -= step) < 0)
  662.                     goto cont_odd;
  663.                 /* skip odd source row: */
  664.                 sy1 += src_pitch;    sy2 += src_pitch;
  665.                 su  += src_pitch_2;  sv  += src_pitch_2; /* next chroma */
  666.             }
  667.             /* continue loop with next even row: */
  668. cont_even:
  669.             limit += src_dy;
  670.         } while (--count);
  671.         goto done;
  672.         /* use this branch to process last row as well:*/
  673. last_pixel:
  674.         count++;
  675.         /* process odd rows: */
  676. start_odd:
  677.         do {
  678.             /* convert a single row: */
  679.             (* dblrow_func) (d1, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  680.             d1  += dest_pitch;   d2  += dest_pitch;
  681.             /* inverted Bresenham stepping: */
  682.             do {
  683.                 /* skip odd source row: */
  684.                 sy1 += src_pitch;    sy2 += src_pitch;
  685.                 su  += src_pitch_2;  sv  += src_pitch_2; /* next chroma */
  686.                 if ((limit -= step) < 0)
  687.                     goto cont_even;
  688.                 /* skip even source row: */
  689.                 sy1 += src_pitch;    sy2 += src_pitch;
  690.             } while ((limit -= step) >= 0);
  691. cont_odd:
  692.             limit += src_dy;
  693.         } while (--count);
  694. done:   ;
  695.     }
  696. }
  697. /*
  698.  * Image copy converter:
  699.  */
  700. static void IMAGE_COPY (
  701.     unsigned char *dest_ptr,
  702.     int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  703.     unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  704.     int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  705.     void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  706.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  707.     void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  708.         unsigned char *, unsigned char *, int, int, unsigned char *,
  709.         unsigned char *, unsigned char *, unsigned char *, int, int))
  710. {
  711.     /* initialize local variables: */
  712.     register unsigned char *d1  = dest_ptr;
  713.     register unsigned char *d2  = d1 + dest_pitch;
  714.     register unsigned char *sy1 = src_y_ptr;
  715.     register unsigned char *sy2 = sy1 + src_pitch;
  716.     register unsigned char *su  = src_u_ptr;
  717.     register unsigned char *sv  = src_v_ptr;
  718.     register int count = dest_dy;
  719.     /* check if top row is misaligned: */
  720.     if ((src_y & 1) && count) {
  721.         /* convert a single row: */
  722.         (* dblrow_func) (d1, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  723.         /* shift pointers: */
  724.         d1  += dest_pitch;  d2  += dest_pitch;
  725.         sy1 += src_pitch;   sy2 += src_pitch;
  726.         su  += src_pitch_2; sv  += src_pitch_2;
  727.         count --;
  728.     }
  729.     /* convert the 2-row-aligned portion of the image: */
  730.     while (count >= 2) {
  731.         /* convert two rows: : */
  732.         (* dblrow_func) (d1, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  733.         /* shift pointers: */
  734.         d1  += dest_pitch*2; d2  += dest_pitch*2;
  735.         sy1 += src_pitch*2;  sy2 += src_pitch*2;
  736.         su  += src_pitch_2;  sv  += src_pitch_2;
  737.         count -= 2;
  738.     }
  739.     /* convert the bottom row (if # of rows is odd): */
  740.     if (count) {
  741.         /* convert a single row: */
  742.         (* dblrow_func) (d1, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  743.     }
  744. }
  745. /*
  746.  * Image stretching converter:
  747.  *  (uses readahead optimization to perform in-place 2 rows conversion:)
  748.  */
  749. static void IMAGE_STRETCH (unsigned char *dest_ptr,
  750.     int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  751.     unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  752.     int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  753.     void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  754.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  755.     void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  756.         unsigned char *, unsigned char *, int, int, unsigned char *,
  757.         unsigned char *, unsigned char *, unsigned char *, int, int))
  758. {
  759.     /* load image pointers: */
  760.     register unsigned char *d1  = dest_ptr;
  761.     register unsigned char *d2  = dest_ptr; /* !!! */
  762.     register unsigned char *sy1 = src_y_ptr;
  763.     register unsigned char *sy2 = sy1 + src_pitch;
  764.     register unsigned char *su  = src_u_ptr;
  765.     register unsigned char *sv  = src_v_ptr;
  766.     /* initialize other variables: */
  767.     register int dest_dx_bytes = dest_dx * dest_bpp;
  768.     register int count = dest_dy;
  769.     register int limit = dest_dy >> 1; /* !!! */
  770.     register int step = src_dy;
  771.     /* # of rows to be processed separately: */
  772.     int remainder = dest_dy - limit;
  773.     if ((src_y + src_dy) & 1) remainder += dest_dy;
  774.     remainder /= step;
  775.     /* check image height: */
  776.     if (count) {
  777.         /* update count: */
  778.         if ((count -= remainder) <= 0)
  779.             goto convert_last;
  780.         /* check if we have an odd first row: */
  781.         if (src_x & 1) {
  782.             /* convert first row: */
  783.             (* dblrow_func) (d2, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  784.             sy1 += src_pitch;   sy2 += src_pitch;
  785.             su  += src_pitch_2; sv  += src_pitch_2;
  786.             goto rep_odd;
  787.         }
  788.         /* the main loop: */
  789.         while (1) {
  790.             /* find second destination row: */
  791.             do {
  792.                 /* just shift a pointer: */
  793.                 d2 += dest_pitch;
  794.                 /* check if all rows are filled up: */
  795.                 if (!(--count))
  796.                     goto convert_last_2;    /* !!! */
  797.             } while ((limit -= step) >= 0);
  798.             limit += dest_dy;
  799.             /* convert two rows: */
  800.             (* dblrow_func) (d1, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  801.             sy1 += src_pitch*2;  sy2 += src_pitch*2;
  802.             su  += src_pitch_2;  sv  += src_pitch_2;
  803.             /* replicate first (even) row: */
  804.             while (d1 + dest_pitch != d2) { /* can't use < pitch can be negative !!! */
  805.                 memcpy(d1 + dest_pitch, d1, dest_dx_bytes); /* Flawfinder: ignore */
  806.                 d1 += dest_pitch;
  807.             }
  808.             /* replicate second (odd) row: */
  809.             goto rep_odd;
  810.             do {
  811.                 /* replicate a row: */
  812.                 memcpy(d2 + dest_pitch, d2, dest_dx_bytes); /* Flawfinder: ignore */
  813.                 d2 += dest_pitch;
  814. rep_odd:
  815.                 /* check if all rows are filled up: */
  816.                 if (!(--count))
  817.                     goto check_last;
  818.             } while ((limit -= step) >= 0);
  819.             limit += dest_dy;
  820.             d1 = d2 += dest_pitch;
  821.         }
  822.         /* convert last two rows: */
  823. convert_last_2:
  824.         d2 += dest_pitch;
  825.         count --;
  826.         (* dblrow_func) (d1, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  827.         /* replicate even row: */
  828.         while (d1 + dest_pitch != d2) { /* can't use < pitch can be negative !!! */
  829.             memcpy(d1 + dest_pitch, d1, dest_dx_bytes); /* Flawfinder: ignore */
  830.             d1 += dest_pitch;
  831.         }
  832.         goto rep_last;
  833.         /* check if we need to convert one more row: */
  834. check_last:
  835.         if ((src_y + src_dy) & 1) {
  836.             /* convert the last row: */
  837.             d2 += dest_pitch;
  838. convert_last:
  839.             count --;
  840.             (* dblrow_func) (d2, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  841.         }
  842.         /* restore the number of remaining row: */
  843. rep_last:
  844.         count += remainder;
  845.         while (count --) {
  846.             /* replicate a row: */
  847.             memcpy(d2 + dest_pitch, d2, dest_dx_bytes); /* Flawfinder: ignore */
  848.             d2 += dest_pitch;
  849.         }
  850.     }
  851. }
  852. /*
  853.  * Image 2x-stretching converter:
  854.  */
  855. static void IMAGE_STRETCH2X (unsigned char *dest_ptr,
  856.     int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  857.     unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  858.     int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  859.     void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  860.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  861.     void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  862.         unsigned char *, unsigned char *, int, int, unsigned char *,
  863.         unsigned char *, unsigned char *, unsigned char *, int, int))
  864. {
  865.     /* load image pointers: */
  866.     register unsigned char *d0, *d01;
  867.     register unsigned char *d1  = dest_ptr;
  868.     register unsigned char *d12 = d1 + dest_pitch;
  869.     register unsigned char *d2  = d12 + dest_pitch;
  870.     register unsigned char *sy1 = src_y_ptr;
  871.     register unsigned char *sy2 = sy1 + src_pitch;
  872.     register unsigned char *su  = src_u_ptr;
  873.     register unsigned char *sv  = src_v_ptr;
  874.     /* initialize other variables: */
  875.     register int count = src_dy;                /* !!! */
  876.     /* check image height: */
  877.     if (count) {
  878.         /* check if top row is misaligned or we have a single-line image: */
  879.         if ((src_y & 1) || count < 2) {
  880.             /* convert a single row: */
  881.             (* dblrow_func) (d1, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  882.             sy1 += src_pitch;    sy2 += src_pitch;
  883.             su  += src_pitch_2;  sv  += src_pitch_2;
  884.             d0  =  d1;           d01 = d12;
  885.             d1  += dest_pitch*2; d12 += dest_pitch*2;
  886.             d2  += dest_pitch*2;
  887.             count --;
  888.         } else {
  889.             /* convert & interpolate first two rows: */
  890.             (* dblrow2x_func) (tmp1, tmp2, d1, d12, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  891.             sy1 += src_pitch*2;  sy2 += src_pitch*2;
  892.             su  += src_pitch_2;  sv  += src_pitch_2;
  893.             d0  =  d2;           d01 =  d0 + dest_pitch;
  894.             d1  += dest_pitch*4; d12 += dest_pitch*4;
  895.             d2  += dest_pitch*4;
  896.             count -= 2;
  897.         }
  898.         /* convert the 2-row-aligned portion of the image: */
  899.         while (count >= 2) {
  900.             /* convert & interpolate two rows a time: */
  901.             (* dblrow2x_func) (d0, d01, d1, d12, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  902.             sy1 += src_pitch*2;  sy2 += src_pitch*2;
  903.             su  += src_pitch_2;  sv  += src_pitch_2;
  904.             d0  += dest_pitch*4; d01 += dest_pitch*4;
  905.             d1  += dest_pitch*4; d12 += dest_pitch*4;
  906.             d2  += dest_pitch*4;
  907.             count -= 2;
  908.         }
  909.         /* convert the bottom row (if # of rows is odd): */
  910.         if (count) {
  911.             /* convert & interpolate the last row: */
  912.             (* dblrow2x_func) (d0, d01, d1, tmp1, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  913.             d0  += dest_pitch*2; d01 += dest_pitch*2;
  914.         }
  915.         /* replicate the last converted row: */
  916.         memcpy(d01, d0, dest_dx * dest_bpp); /* Flawfinder: ignore */
  917.     }
  918. }
  919. /*
  920.  * Image 2x+ stretching converter:
  921.  */
  922. static void IMAGE_STRETCH2XPLUS (unsigned char *dest_ptr,
  923.     int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  924.     unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  925.     int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  926.     void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  927.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  928.     void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  929.         unsigned char *, unsigned char *, int, int, unsigned char *,
  930.         unsigned char *, unsigned char *, unsigned char *, int, int))
  931. {
  932.     /* load image pointers: */
  933.     register unsigned char *d0, *d01, *d1, *d12, *d2, *d;
  934.     register unsigned char *sy1 = src_y_ptr;
  935.     register unsigned char *sy2 = sy1 + src_pitch;
  936.     register unsigned char *su  = src_u_ptr;
  937.     register unsigned char *sv  = src_v_ptr;
  938.     /* initialize other variables: */
  939.     register int dest_dx_bytes = dest_dx * dest_bpp;
  940.     register int count = dest_dy;
  941.     register int limit = dest_dy >> 1;
  942.     register int step = src_dy << 1;
  943.     /* # of rows to be processed separately: */
  944.     int remainder = 3 * dest_dy - limit;
  945.     if ((src_y + src_dy) & 1) remainder += 2 * dest_dy;
  946.     remainder /= step;
  947.     /* check destination image height: */
  948.     if (count) {
  949.         /* check if top row is misaligned or we have a single-line image: */
  950.         if ((src_y & 1) || src_dy < 2) {
  951.             /* convert a single row: */
  952. convert_last_0:
  953.             d2 = dest_ptr;
  954.             (* dblrow_func) (d2, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  955.             sy1 += src_pitch;    sy2 += src_pitch;
  956.             su  += src_pitch_2;  sv  += src_pitch_2;
  957.             /* update count: */
  958.             if ((count -= remainder) <= 0)
  959.                 goto rep_last;
  960.         } else {
  961.             register int count2 = count;
  962.             /* set pointer to first integral-pixel row (d1): */
  963.             d1 = dest_ptr;
  964.             /* find half-pixel row (d12): */
  965.             d12 = d1;
  966.             do {
  967.                 d12 += dest_pitch;
  968.                 if (!(--count2))
  969.                     goto convert_last_0;            /* ??? */
  970.             } while ((limit -= step) >= 0);
  971.             limit += dest_dy;
  972.             /* find second integral-pixel row (d2): */
  973.             d2 = d12;
  974.             do {
  975.                 d2 += dest_pitch;
  976.                 if (!(--count2))
  977.                     goto convert_last_0;            /* ??? */
  978.             } while ((limit -= step) >= 0);
  979.             limit += dest_dy;
  980.             /* convert & interpolate first two rows: */
  981.             (* dblrow2x_func) (tmp1, tmp2, d1, d12, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  982.             sy1 += src_pitch*2;  sy2 += src_pitch*2;
  983.             su  += src_pitch_2;  sv  += src_pitch_2;
  984.             /* update count: */
  985.             count = count2;
  986.             if ((count -= remainder) <= 0)
  987.                 goto rep_d1_d12_d2;                 /* ??? */
  988.             goto rep_even;
  989.         }
  990.         /* the main loop: */
  991.         while (1) {
  992.             /* get last converted integral row (d0): */
  993.             d0 = d2;
  994.             /* find first half-pixel row (d01): */
  995.             d01 = d0;
  996.             do {
  997.                 d01 += dest_pitch;
  998.                 if (!(--count))
  999.                     goto rep_last;                  /* ??? */
  1000.             } while ((limit -= step) >= 0);
  1001.             limit += dest_dy;
  1002.             /* find first integral-pixel row (d1): */
  1003.             d1 = d01;
  1004.             do {
  1005.                 d1 += dest_pitch;
  1006.                 if (!(--count))
  1007.                     goto rep_last;                  /* ??? */
  1008.             } while ((limit -= step) >= 0);
  1009.             limit += dest_dy;
  1010.             /* find second half-pixel row (d12): */
  1011.             d12 = d1;
  1012.             do {
  1013.                 d12 += dest_pitch;
  1014.                 if (!(--count))
  1015.                     goto convert_last_2_rows;       /* !!! */
  1016.             } while ((limit -= step) >= 0);
  1017.             limit += dest_dy;
  1018.             /* find second integral-pixel row (d2): */
  1019.             d2 = d12;
  1020.             do {
  1021.                 d2 += dest_pitch;
  1022.                 if (!(--count))
  1023.                     goto convert_last_2_or_3_rows;  /* !!! */
  1024.             } while ((limit -= step) >= 0);
  1025.             limit += dest_dy;
  1026.             /* convert & interpolate next two rows: */
  1027.             (* dblrow2x_func) (d0, d01, d1, d12, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  1028.             sy1 += src_pitch*2;  sy2 += src_pitch*2;
  1029.             su  += src_pitch_2;  sv  += src_pitch_2;
  1030.             /* replicate a previous integral row (d0): */
  1031.             d = d0 + dest_pitch;
  1032.             while (d != d01) {
  1033.                 memcpy(d, d0, dest_dx_bytes); /* Flawfinder: ignore */
  1034.                 d += dest_pitch;
  1035.             }
  1036.             /* replicate the first half-pixel row (d01): */
  1037.             d = d01 + dest_pitch;
  1038.             while (d != d1) {
  1039.                 memcpy(d, d01, dest_dx_bytes); /* Flawfinder: ignore */
  1040.                 d += dest_pitch;
  1041.             }
  1042. rep_even:
  1043.             /* replicate the first integral row (d1): */
  1044.             d = d1 + dest_pitch;
  1045.             while (d != d12) {
  1046.                 memcpy(d, d1, dest_dx_bytes); /* Flawfinder: ignore */
  1047.                 d += dest_pitch;
  1048.             }
  1049.             /* replicate the second half-pixel row (d12): */
  1050.             d = d12 + dest_pitch;
  1051.             while (d != d2) {
  1052.                 memcpy(d, d12, dest_dx_bytes); /* Flawfinder: ignore */
  1053.                 d += dest_pitch;
  1054.             }
  1055.         }
  1056.         /* convert & replicate last two rows: */
  1057. convert_last_2_or_3_rows:
  1058.         /* convert & interpolate next two rows: */
  1059.         (* dblrow2x_func) (d0, d01, d1, d12, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  1060.         sy1 += src_pitch*2;  sy2 += src_pitch*2;
  1061.         su  += src_pitch_2;  sv  += src_pitch_2;
  1062.         /* replicate a previous integral row (d0): */
  1063.         d = d0 + dest_pitch;
  1064.         while (d != d01) {
  1065.             memcpy(d, d0, dest_dx_bytes); /* Flawfinder: ignore */
  1066.             d += dest_pitch;
  1067.         }
  1068.         /* replicate the first half-pixel row (d01): */
  1069.         d = d01 + dest_pitch;
  1070.         while (d != d1) {
  1071.             memcpy(d, d01, dest_dx_bytes); /* Flawfinder: ignore */
  1072.             d += dest_pitch;
  1073.         }
  1074.         /* replicate the first integral row (d1): */
  1075.         d = d1 + dest_pitch;
  1076.         while (d != d12) {
  1077.             memcpy(d, d1, dest_dx_bytes); /* Flawfinder: ignore */
  1078.             d += dest_pitch;
  1079.         }
  1080.         /* replicate the second half-pixel row (d12): */
  1081.         d = d12 + dest_pitch;
  1082.         while (d != d2) {
  1083.             memcpy(d, d12, dest_dx_bytes); /* Flawfinder: ignore */
  1084.             d += dest_pitch;
  1085.         }
  1086.         /* check if we need to convert one more row: */
  1087.         if ((src_y + src_dy) & 1) {
  1088.             /* update count & remainder: */
  1089.             register int r2 = remainder >> 1;
  1090.             count += r2; remainder -= r2;
  1091.             if (count <= 0)
  1092.                 goto rep_last;
  1093.             /* get last converted row (d1): */
  1094.             d1 = d2;
  1095.             /* find last half-pixel row (d01): */
  1096.             d12 = d1;
  1097.             do {
  1098.                 d12 += dest_pitch;
  1099.                 if (!(--count))
  1100.                     goto convert_last_row_1;  /* ??? */
  1101.             } while ((limit -= step) >= 0);
  1102.             limit += dest_dy;
  1103.             /* find last integral-pixel row (d2): */
  1104.             d2 = d12;
  1105.             do {
  1106.                 d2 += dest_pitch;
  1107.                 if (!(--count))
  1108.                     goto convert_last_row;    /* !!! */
  1109.             } while ((limit -= step) >= 0);
  1110.             limit += dest_dy;
  1111.             goto convert_last_row;
  1112.             /* set pointer to the last integral row: */
  1113. convert_last_row_1:
  1114.             d2 = d12 + dest_pitch;
  1115.             count --;
  1116.             /* convert & interpolate the last row: */
  1117. convert_last_row:
  1118.             (* dblrow2x_func) (d1, d12, d2, tmp1, tmp2, dest_x, dest_dx, sy1, sy1, su, sv, src_x, src_dx);
  1119.             goto rep_d1_d12_d2;
  1120.         }
  1121.         goto rep_last;
  1122.         /* convert & replicate the last two rows: */
  1123. convert_last_2_rows:
  1124.         /* convert & interpolate next two rows: */
  1125.         (* dblrow2x_func) (d0, d01, d1, d12, d2, dest_x, dest_dx, sy1, sy2, su, sv, src_x, src_dx);
  1126.         sy1 += src_pitch*2;  sy2 += src_pitch*2;
  1127.         su  += src_pitch_2;  sv  += src_pitch_2;
  1128.         /* replicate a previous integral row (d0): */
  1129.         d = d0 + dest_pitch;
  1130.         while (d != d01) {
  1131.             memcpy(d, d0, dest_dx_bytes); /* Flawfinder: ignore */
  1132.             d += dest_pitch;
  1133.         }
  1134.         /* replicate the first half-pixel row (d01): */
  1135.         d = d01 + dest_pitch;
  1136.         while (d != d1) {
  1137.             memcpy(d, d01, dest_dx_bytes); /* Flawfinder: ignore */
  1138.             d += dest_pitch;
  1139.         }
  1140. rep_d1_d12_d2:
  1141.         /* replicate the first integral row (d1): */
  1142.         d = d1 + dest_pitch;
  1143.         while (d != d12) {
  1144.             memcpy(d, d1, dest_dx_bytes); /* Flawfinder: ignore */
  1145.             d += dest_pitch;
  1146.         }
  1147.         /* replicate the second half-pixel row (d12): */
  1148.         d = d12 + dest_pitch;
  1149.         while (d != d2) {
  1150.             memcpy(d, d12, dest_dx_bytes); /* Flawfinder: ignore */
  1151.             d += dest_pitch;
  1152.         }
  1153.         /* restore the number of remaining rows: */
  1154. rep_last:
  1155.         count += remainder;
  1156.         /* replicate last converted row: */
  1157. if (count > 0) {
  1158. d = d2 + dest_pitch;
  1159. while (--count) {
  1160. memcpy(d, d2, dest_dx_bytes); /* Flawfinder: ignore */
  1161. d += dest_pitch;
  1162. }
  1163. }
  1164.     }
  1165. }
  1166. /*
  1167.  * Image scale functions table:
  1168.  *  [vertical scale type]
  1169.  */
  1170. static void (* ImageFuncs [SCALE_FUNCS]) (unsigned char *dest_ptr,
  1171.     int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  1172.     unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  1173.     int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  1174.     void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  1175.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  1176.     void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  1177.         unsigned char *, unsigned char *, int, int, unsigned char *,
  1178.         unsigned char *, unsigned char *, unsigned char *, int, int)) =
  1179. {
  1180.     IMAGE_SHRINK,
  1181.     IMAGE_COPY,
  1182.     IMAGE_STRETCH,
  1183.     IMAGE_STRETCH2X,
  1184.     IMAGE_STRETCH2XPLUS
  1185. };
  1186. /*
  1187.  * Bytes per pixel (bpp) table:
  1188.  */
  1189. static int bpp [RGB_FORMATS] =
  1190. {
  1191.     BPP(RGB32),
  1192.     BPP(BGR32),
  1193.     BPP(RGB24),
  1194.     BPP(RGB565),
  1195.     BPP(RGB555),
  1196.     BPP(RGB444),
  1197.     BPP(RGB8)
  1198. };
  1199. /*
  1200.  * The main YUVtoRGB converter:
  1201.  */
  1202. static int YUVtoRGB (
  1203.     /* destination format: */
  1204.     int dest_format,
  1205.     /* destination image parameters: */
  1206.     unsigned char *dest_ptr, int dest_width, int dest_height,
  1207.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1208.     /* source image parameters: */
  1209.     unsigned char *src_ptr, int src_width, int src_height,
  1210.     int src_pitch, int src_x, int src_y, int src_dx, int src_dy)
  1211. {
  1212. #if 1
  1213.     unsigned char *pU = src_ptr + src_height * src_pitch;
  1214.     unsigned char *pV = pU + src_height * src_pitch / 4;
  1215.     return YUVtoRGB2(dest_format, dest_ptr, dest_width, dest_height, dest_pitch,
  1216.                      dest_x, dest_y, dest_dx, dest_dy,
  1217.                      src_ptr, pU, pV, src_width, src_height,
  1218.                      src_pitch, src_pitch/2, src_pitch/2, src_x, src_y, src_dx, src_dy);
  1219. #else    
  1220.     /* pointers to low-level converters to use: */
  1221.     void (*dblrow_proc) (unsigned char *, unsigned char *, int, int,
  1222.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int);
  1223.     void (*dblrow2x_proc) (unsigned char *, unsigned char *, unsigned char *,
  1224.         unsigned char *, unsigned char *, int, int, unsigned char *,
  1225.         unsigned char *, unsigned char *, unsigned char *, int, int);
  1226.     void (*image_proc) (unsigned char *dest_ptr,
  1227.         int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  1228.         unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  1229.         int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  1230.         void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  1231.             unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  1232.         void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  1233.             unsigned char *, unsigned char *, int, int, unsigned char *,
  1234.             unsigned char *, unsigned char *, unsigned char *, int, int));
  1235.     /* scale types: */
  1236.     register int scale_x, scale_y;
  1237.     /* pointers and destination pixel depth: */
  1238.     register unsigned char *d, *sy, *su, *sv;
  1239.     register int dest_bpp;
  1240.     /* check arguments: */
  1241.     if (
  1242.         /* alignments: */
  1243.         ((unsigned)dest_ptr & 3) || (dest_pitch & 3) ||
  1244.         ((unsigned)src_ptr  & 3) || (src_pitch  & 3) ||
  1245.         /* image sizes: */
  1246.         dest_width <= 0 || dest_height <= 0 ||
  1247.         src_width  <= 0 || src_height  <= 0 ||
  1248.         /* rectangles: */
  1249.         dest_x < 0 || dest_y < 0 || dest_dx <= 0 || dest_dy <= 0 ||
  1250.         src_x  < 0 || src_y  < 0 || src_dx  <= 0 || src_dy  <= 0 ||
  1251.         /* overlaps: */
  1252.         dest_width < dest_x + dest_dx || dest_height < dest_y + dest_dy ||
  1253.         src_width  < src_x  + src_dx  || src_height  < src_y  + src_dy)
  1254.     {
  1255.         /* fail: */
  1256.         return -1;
  1257.     }
  1258.     /* get scale types: */
  1259.     GET_SCALE_TYPE(dest_dx, src_dx, scale_x);
  1260.     GET_SCALE_TYPE(dest_dy, src_dy, scale_y);
  1261.     /* select row and image converters: */
  1262. #ifdef _PLUS_HXCOLOR
  1263.     dblrow_proc   = DblRowFuncs [is_alpha][dest_format][scale_x];
  1264.     dblrow2x_proc = DblRow2xFuncs [is_alpha][dest_format][scale_x];
  1265. #else
  1266.     dblrow_proc   = DblRowFuncs [0][dest_format][scale_x];
  1267.     dblrow2x_proc = DblRow2xFuncs [0][dest_format][scale_x];
  1268. #endif
  1269.     image_proc    = ImageFuncs [scale_y];
  1270.     /* get destination pixel depth: */
  1271.     dest_bpp = bpp [dest_format];
  1272.     /* check if bottop-up images: */
  1273.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1274.     if (src_pitch <= 0) return -1;          /* not supported */
  1275.     /* get pointers: */
  1276.     d = dest_ptr + dest_x * dest_bpp + dest_y * dest_pitch;
  1277.     sy = src_ptr + (src_x + src_y * src_pitch); /* luminance */
  1278.     su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch/2); /* !!! */
  1279.     sv = su + src_height * src_pitch / 4;
  1280.     /* pass control to appropriate lower-level converters: */
  1281.     (* image_proc) (
  1282.         d, dest_x, dest_y, dest_dx, dest_dy, dest_pitch, dest_bpp,
  1283.         sy, su, sv, src_x, src_y, src_dx, src_dy, src_pitch, src_pitch/2,
  1284.         dblrow_proc, dblrow2x_proc);
  1285.     /* success: */
  1286.     return 0;
  1287. #endif
  1288. }
  1289. /*
  1290.  * Public format-conversion routines.
  1291.  * Use:
  1292.  *  int XXXXtoYYYY (unsigned char *dest_ptr, int dest_width, int dest_height,
  1293.  *      int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1294.  *      unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1295.  *      int src_x, int src_y, int src_dx, int src_dy);
  1296.  * Input:
  1297.  *  dest_ptr - pointer to a destination buffer
  1298.  *  dest_width, dest_height - width/height of the destination image (pixels)
  1299.  *  dest_pitch - pitch of the dest. buffer (in bytes; <0 - if bottom up image)
  1300.  *  dest_x, dest_y, dest_dx, dest_dy - destination rectangle (pixels)
  1301.  *  src_ptr - pointer to an input image
  1302.  *  src_width, src_height - width/height of the input image (pixels)
  1303.  *  src_pitch - pitch of the source buffer (in bytes; <0 - if bottom up image)
  1304.  *  src_x, src_y, src_dx, src_dy - source rectangle (pixels)
  1305.  * Returns:
  1306.  *  0 - if success; -1 if failure.
  1307.  * Note:
  1308.  *  Both source and destination buffers must be 4-bytes aligned,
  1309.  *  and their pitches (#of bytes in row) shall be multiple of 4!!!
  1310.  */
  1311. #if 1
  1312. #define YUVTORGB_FUNC(df, sf)                               
  1313.     int FN(df,sf) (unsigned char *dest_ptr,                 
  1314.         int dest_width, int dest_height, int dest_pitch,    
  1315.         int dest_x, int dest_y, int dest_dx, int dest_dy,   
  1316.         unsigned char *src_ptr,                             
  1317.         int src_width, int src_height, int src_pitch,       
  1318.         int src_x, int src_y, int src_dx, int src_dy)       
  1319.     {                                                       
  1320.     unsigned char *pU = src_ptr + src_height * src_pitch;   
  1321.     unsigned char *pV = pU + src_height * src_pitch / 4;    
  1322.                                                             
  1323.     if (ID(sf) == YV12_ID)                                  
  1324.     {                                                       
  1325.         unsigned char *pTemp = pU;                          
  1326.         pU = pV;                                            
  1327.         pV = pTemp;                                         
  1328.     }                                                       
  1329.                                                             
  1330.     return YUVtoRGB2(ID(df), dest_ptr, dest_width, dest_height, dest_pitch, 
  1331.                      dest_x, dest_y, dest_dx, dest_dy,      
  1332.                      src_ptr, pU, pV, src_width, src_height,
  1333.                      src_pitch, src_pitch/2, src_pitch/2, src_x, src_y, src_dx, src_dy); 
  1334.                                                             
  1335.                                                             
  1336.     }
  1337.     /*        return YUVtoRGB(                                    
  1338.             ID(df), dest_ptr, dest_width, dest_height,      
  1339.             dest_pitch, dest_x, dest_y, dest_dx, dest_dy,   
  1340.             src_ptr, src_width, src_height,                 
  1341.             src_pitch, src_x, src_y, src_dx, src_dy);       
  1342. */
  1343. YUVTORGB_FUNC(RGB32, I420)
  1344. YUVTORGB_FUNC(BGR32, I420)
  1345. YUVTORGB_FUNC(RGB24, I420)                     
  1346. YUVTORGB_FUNC(RGB565, I420)
  1347. YUVTORGB_FUNC(RGB555, I420)
  1348. YUVTORGB_FUNC(RGB444, I420)
  1349. YUVTORGB_FUNC(RGB8, I420)
  1350. YUVTORGB_FUNC(RGB32, YV12)
  1351. YUVTORGB_FUNC(BGR32, YV12)
  1352. YUVTORGB_FUNC(RGB24, YV12)
  1353. YUVTORGB_FUNC(RGB565, YV12)
  1354. YUVTORGB_FUNC(RGB555, YV12)
  1355. YUVTORGB_FUNC(RGB444, YV12)
  1356. YUVTORGB_FUNC(RGB8, YV12)
  1357. #else                  
  1358. #define YUVTORGB_FUNC(df)                                   
  1359.     int FN(df,I420) (unsigned char *dest_ptr,               
  1360.         int dest_width, int dest_height, int dest_pitch,    
  1361.         int dest_x, int dest_y, int dest_dx, int dest_dy,   
  1362.         unsigned char *src_ptr,                             
  1363.         int src_width, int src_height, int src_pitch,       
  1364.         int src_x, int src_y, int src_dx, int src_dy)       
  1365.     {                                                       
  1366.         return YUVtoRGB(                                    
  1367.             ID(df), dest_ptr, dest_width, dest_height,      
  1368.             dest_pitch, dest_x, dest_y, dest_dx, dest_dy,   
  1369.             src_ptr, src_width, src_height,                 
  1370.             src_pitch, src_x, src_y, src_dx, src_dy);       
  1371.     }
  1372. YUVTORGB_FUNC(RGB32 )
  1373. YUVTORGB_FUNC(BGR32 )
  1374. YUVTORGB_FUNC(RGB24 )
  1375. YUVTORGB_FUNC(RGB565)
  1376. YUVTORGB_FUNC(RGB555)
  1377. YUVTORGB_FUNC(RGB444)
  1378. YUVTORGB_FUNC(RGB8  )
  1379. #endif
  1380. /*
  1381.  * The main YUVtoRGB2 converter:
  1382.  */
  1383. static int YUVtoRGB2 (
  1384.     /* destination format: */
  1385.     int dest_format,
  1386.     unsigned char *dest_ptr, int dest_width, int dest_height,
  1387.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1388.     unsigned char *pY, unsigned char *pU, unsigned char *pV,
  1389.     int src_width, int src_height, int yPitch, int uPitch, int vPitch,
  1390.     int src_x, int src_y, int src_dx, int src_dy)
  1391. {
  1392.     /* pointers to low-level converters to use: */
  1393.     void (*dblrow_proc) (unsigned char *, unsigned char *, int, int,
  1394.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int);
  1395.     void (*dblrow2x_proc) (unsigned char *, unsigned char *, unsigned char *,
  1396.         unsigned char *, unsigned char *, int, int, unsigned char *,
  1397.         unsigned char *, unsigned char *, unsigned char *, int, int);
  1398.     void (*image_proc) (unsigned char *dest_ptr,
  1399.         int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  1400.         unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  1401.         int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  1402.         void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  1403.             unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  1404.         void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  1405.             unsigned char *, unsigned char *, int, int, unsigned char *,
  1406.             unsigned char *, unsigned char *, unsigned char *, int, int));
  1407.     /* scale types: */
  1408.     register int scale_x, scale_y;
  1409.     /* pointers and destination pixel depth: */
  1410.     register unsigned char *d, *sy, *su, *sv;
  1411.     register int dest_bpp;
  1412.     /* check arguments: */
  1413.     if (
  1414.         /* alignments: */
  1415.         ((unsigned)dest_ptr & 3) || (dest_pitch & 3) ||
  1416.         ((unsigned)pY  & 3) || (yPitch & 3) ||
  1417.         /* image sizes: */
  1418.         dest_width <= 0 || dest_height <= 0 ||
  1419.         src_width  <= 0 || src_height  <= 0 ||
  1420.         /* rectangles: */
  1421.         dest_x < 0 || dest_y < 0 || dest_dx <= 0 || dest_dy <= 0 ||
  1422.         src_x  < 0 || src_y  < 0 || src_dx  <= 0 || src_dy  <= 0 ||
  1423.         /* overlaps: */
  1424.         dest_width < dest_x + dest_dx || dest_height < dest_y + dest_dy ||
  1425.         src_width  < src_x  + src_dx  || src_height  < src_y  + src_dy)
  1426.     {
  1427.         /* fail: */
  1428.         return -1;
  1429.     }
  1430.     /* get scale types: */
  1431.     GET_SCALE_TYPE(dest_dx, src_dx, scale_x);
  1432.     GET_SCALE_TYPE(dest_dy, src_dy, scale_y);
  1433.     /* select row and image converters: */
  1434. #ifdef _PLUS_HXCOLOR
  1435.     dblrow_proc   = DblRowFuncs [is_alpha][dest_format][scale_x];
  1436.     dblrow2x_proc = DblRow2xFuncs [is_alpha][dest_format][scale_x];
  1437. #else
  1438.     dblrow_proc   = DblRowFuncs [0][dest_format][scale_x];
  1439.     dblrow2x_proc = DblRow2xFuncs [0][dest_format][scale_x];
  1440. #endif
  1441.     image_proc    = ImageFuncs [scale_y];
  1442.     /* get destination pixel depth: */
  1443.     dest_bpp = bpp [dest_format];
  1444.     /* check if bottop-up images: */
  1445.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1446.     if (yPitch <= 0 ||
  1447.         uPitch <= 0 ||
  1448.         vPitch <= 0)
  1449.         return -1;          /* not supported */
  1450.     /* get pointers: */
  1451.     d = dest_ptr + dest_x * dest_bpp + dest_y * dest_pitch;
  1452.     sy = pY + (src_x + src_y * yPitch); /* luminance */
  1453.     su = pU + (src_x/2 + src_y/2 * uPitch); /* !!! */
  1454.     sv = pV + (src_x/2 + src_y/2 * vPitch); /* !!! */
  1455.     /* pass control to appropriate lower-level converters: */
  1456.     (* image_proc) (
  1457.         d, dest_x, dest_y, dest_dx, dest_dy, dest_pitch, dest_bpp,
  1458.         sy, su, sv, src_x, src_y, src_dx, src_dy, yPitch, uPitch,
  1459.         dblrow_proc, dblrow2x_proc);
  1460.     /* success: */
  1461.     return 0;
  1462. }
  1463. /*
  1464.  * Public format-conversion routines.
  1465.  * Use:
  1466.  *  int XXXXtoYYYY (unsigned char *dest_ptr, int dest_width, int dest_height,
  1467.  *      int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1468.  *      unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
  1469.  *      int src_x, int src_y, int src_dx, int src_dy);
  1470.  * Input:
  1471.  *  dest_ptr - pointer to a destination buffer
  1472.  *  dest_width, dest_height - width/height of the destination image (pixels)
  1473.  *  dest_pitch - pitch of the dest. buffer (in bytes; <0 - if bottom up image)
  1474.  *  dest_x, dest_y, dest_dx, dest_dy - destination rectangle (pixels)
  1475.  *  pY - pointer to the y plane
  1476.  *  pU - pointer to the u plane
  1477.  *  pV - pointer to the v plane
  1478.  *  src_width, src_height - width/height of the input image (pixels)
  1479.  *  yPitch - pitch of the y buffer (in bytes; <0 - if bottom up image)
  1480.  *  uPitch - pitch of the u buffer (in bytes; <0 - if bottom up image)
  1481.  *  vPitch - pitch of the v buffer (in bytes; <0 - if bottom up image)
  1482.  *  src_x, src_y, src_dx, src_dy - source rectangle (pixels)
  1483.  * Returns:
  1484.  *  0 - if success; -1 if failure.
  1485.  * Note:
  1486.  *  Both source and destination buffers must be 4-bytes aligned,
  1487.  *  and their pitches (#of bytes in row) shall be multiple of 4!!!
  1488.  */
  1489. #if 1
  1490. #define YUVTORGB2_FUNC(df, sf)                                   
  1491.     int FN2(df, sf) (unsigned char *dest_ptr, int dest_width,   
  1492.     int dest_height, int dest_pitch, int dest_x, int dest_y,    
  1493.     int dest_dx, int dest_dy, unsigned char *pY,                
  1494.     unsigned char *pU, unsigned char *pV, int src_width,        
  1495.     int src_height, int yPitch, int uPitch, int vPitch,         
  1496.     int src_x, int src_y, int src_dx, int src_dy)               
  1497.     {                                                           
  1498.         return YUVtoRGB2(                                       
  1499.             ID(df), dest_ptr, dest_width, dest_height,          
  1500.             dest_pitch, dest_x, dest_y, dest_dx, dest_dy,       
  1501.             pY, pU, pV, src_width, src_height, yPitch,          
  1502.             uPitch, vPitch, src_x, src_y, src_dx, src_dy);      
  1503.     }
  1504. YUVTORGB2_FUNC(RGB32, I420)
  1505. YUVTORGB2_FUNC(BGR32, I420)
  1506. YUVTORGB2_FUNC(RGB24, I420)
  1507. YUVTORGB2_FUNC(RGB565, I420)
  1508. YUVTORGB2_FUNC(RGB555, I420)
  1509. YUVTORGB2_FUNC(RGB444, I420)
  1510. YUVTORGB2_FUNC(RGB8, I420)
  1511. YUVTORGB2_FUNC(RGB32, YV12)
  1512. YUVTORGB2_FUNC(BGR32, YV12)
  1513. YUVTORGB2_FUNC(RGB24, YV12)
  1514. YUVTORGB2_FUNC(RGB565, YV12)
  1515. YUVTORGB2_FUNC(RGB555, YV12)
  1516. YUVTORGB2_FUNC(RGB444, YV12)
  1517. YUVTORGB2_FUNC(RGB8, YV12)
  1518. #else
  1519. #define YUVTORGB2_FUNC(df)                                      
  1520.     int FN2(df,I420) (unsigned char *dest_ptr, int dest_width,  
  1521.     int dest_height, int dest_pitch, int dest_x, int dest_y,    
  1522.     int dest_dx, int dest_dy, unsigned char *pY,                
  1523.     unsigned char *pU, unsigned char *pV, int src_width,        
  1524.     int src_height, int yPitch, int uPitch, int vPitch,         
  1525.     int src_x, int src_y, int src_dx, int src_dy)               
  1526.     {                                                           
  1527.         return YUVtoRGB2(                                       
  1528.             ID(df), dest_ptr, dest_width, dest_height,          
  1529.             dest_pitch, dest_x, dest_y, dest_dx, dest_dy,       
  1530.             pY, pU, pV, src_width, src_height, yPitch,          
  1531.             uPitch, vPitch, src_x, src_y, src_dx, src_dy);      
  1532.     }
  1533. YUVTORGB2_FUNC(RGB32 )
  1534. YUVTORGB2_FUNC(BGR32 )
  1535. YUVTORGB2_FUNC(RGB24 )
  1536. YUVTORGB2_FUNC(RGB565)
  1537. YUVTORGB2_FUNC(RGB555)
  1538. YUVTORGB2_FUNC(RGB444)
  1539. YUVTORGB2_FUNC(RGB8  )
  1540. #endif
  1541. #if 0
  1542. /***********************************************************/
  1543. /*
  1544.  * New XINGtoRGB converter:
  1545.  */
  1546. static int XINGtoRGB (
  1547.     /* destination format: */
  1548.     int dest_format,
  1549.     /* destination image parameters: */
  1550.     unsigned char *dest_ptr, int dest_width, int dest_height,
  1551.     int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
  1552.     /* source image parameters: */
  1553.     unsigned char *src_ptr, int src_width, int src_height,
  1554.     int src_pitch, int src_x, int src_y, int src_dx, int src_dy)
  1555. {
  1556.     /* pointers to low-level converters to use: */
  1557.     void (*dblrow_proc) (unsigned char *, unsigned char *, int, int,
  1558.         unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int);
  1559.     void (*dblrow2x_proc) (unsigned char *, unsigned char *, unsigned char *,
  1560.         unsigned char *, unsigned char *, int, int, unsigned char *,
  1561.         unsigned char *, unsigned char *, unsigned char *, int, int);
  1562.     void (*image_proc) (unsigned char *dest_ptr,
  1563.         int dest_x, int dest_y, int dest_dx, int dest_dy, int dest_pitch, int dest_bpp,
  1564.         unsigned char *src_y_ptr, unsigned char *src_u_ptr, unsigned char *src_v_ptr,
  1565.         int src_x, int src_y, int src_dx, int src_dy, int src_pitch, int src_pitch_2,
  1566.         void (*dblrow_func) (unsigned char *, unsigned char *, int, int,
  1567.             unsigned char *, unsigned char *, unsigned char *, unsigned char *, int, int),
  1568.         void (*dblrow2x_func) (unsigned char *, unsigned char *, unsigned char *,
  1569.             unsigned char *, unsigned char *, int, int, unsigned char *,
  1570.             unsigned char *, unsigned char *, unsigned char *, int, int));
  1571.     /* scale types: */
  1572.     register int scale_x, scale_y;
  1573.     /* pointers and destination pixel depth: */
  1574.     register unsigned char *d, *sy, *su, *sv;
  1575.     register int dest_bpp;
  1576.     /* check arguments: */
  1577.     if (
  1578.         /* alignments: */
  1579.         ((unsigned)dest_ptr & 3) || (dest_pitch & 3) ||
  1580.         ((unsigned)src_ptr  & 3) || (src_pitch  & 3) ||
  1581.         /* image sizes: */
  1582.         dest_width <= 0 || dest_height <= 0 ||
  1583.         src_width  <= 0 || src_height  <= 0 ||
  1584.         /* rectangles: */
  1585.         dest_x < 0 || dest_y < 0 || dest_dx <= 0 || dest_dy <= 0 ||
  1586.         src_x  < 0 || src_y  < 0 || src_dx  <= 0 || src_dy  <= 0 ||
  1587.         /* overlaps: */
  1588.         dest_width < dest_x + dest_dx || dest_height < dest_y + dest_dy ||
  1589.         src_width  < src_x  + src_dx  || src_height  < src_y  + src_dy)
  1590.     {
  1591.         /* fail: */
  1592.         return -1;
  1593.     }
  1594.     /* get scale types: */
  1595.     GET_SCALE_TYPE(dest_dx, src_dx, scale_x);
  1596.     GET_SCALE_TYPE(dest_dy, src_dy, scale_y);
  1597.     /* select row and image converters: */
  1598. #ifdef _PLUS_HXCOLOR
  1599.     dblrow_proc   = DblRowFuncs [is_alpha][dest_format][scale_x];
  1600.     dblrow2x_proc = DblRow2xFuncs [is_alpha][dest_format][scale_x];
  1601. #else
  1602.     dblrow_proc   = DblRowFuncs [0][dest_format][scale_x];
  1603.     dblrow2x_proc = DblRow2xFuncs [0][dest_format][scale_x];
  1604. #endif
  1605.     image_proc    = ImageFuncs [scale_y];
  1606.     /* get destination pixel depth: */
  1607.     dest_bpp = bpp [dest_format];
  1608.     /* check if bottop-up images: */
  1609.     if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
  1610.     if (src_pitch <= 0) return -1;          /* not supported */
  1611.     /*
  1612.      * XING is essentially a planar YUV 4:2:0 format
  1613.      * with common pitch and interleaved UV planes:
  1614.      *
  1615.      *  +-------------+
  1616.      *  |      Y      |
  1617.      *  |             |  next_line = Y/U/V + pitch;
  1618.      *  +------+------+
  1619.      *  |  U   |  V   |  V = U + pitch / 2;
  1620.      *  +------+------+
  1621.      */
  1622.     /* get pointers: */
  1623.     d = dest_ptr + dest_x * dest_bpp + dest_y * dest_pitch;
  1624.     sy = src_ptr + (src_x + src_y * src_pitch); /* luminance */
  1625.     
  1626.     su = src_ptr + (src_height+15 & 0xFFF0) * src_pitch + (src_x/2 + src_y/2 * src_pitch);
  1627.     sv = su + src_pitch / 2;
  1628.     /* pass control to appropriate lower-level converters: */
  1629.     (* image_proc) (
  1630.         d, dest_x, dest_y, dest_dx, dest_dy, dest_pitch, dest_bpp,
  1631.         sy, su, sv, src_x, src_y, src_dx, src_dy, src_pitch, src_pitch,
  1632.         dblrow_proc, dblrow2x_proc);
  1633.     /* success: */
  1634.     return 0;
  1635. }
  1636. #endif //0
  1637. /*
  1638.  * Public format-conversion routines.
  1639.  */
  1640. #define XINGTORGB_FUNC(df)                                  
  1641.     int FN(df,XING) (unsigned char *dest_ptr,               
  1642.         int dest_width, int dest_height, int dest_pitch,    
  1643.         int dest_x, int dest_y, int dest_dx, int dest_dy,   
  1644.         unsigned char *src_ptr,                             
  1645.         int src_width, int src_height, int src_pitch,       
  1646.         int src_x, int src_y, int src_dx, int src_dy)       
  1647.     {                                                       
  1648.         unsigned char *pU = src_ptr + (src_height+15 & 0xFFF0) * src_pitch; 
  1649.         unsigned char *pV = pU + (src_pitch>>1);                    
  1650.                                                                     
  1651.         return YUVtoRGB2(                                           
  1652.             ID(df), dest_ptr, dest_width, dest_height,              
  1653.             dest_pitch, dest_x, dest_y, dest_dx, dest_dy,           
  1654.             src_ptr, pU, pV, src_width, src_height, src_pitch,      
  1655.             src_pitch, src_pitch, src_x, src_y, src_dx, src_dy);    
  1656.     } 
  1657.         //return XINGtoRGB(                                   
  1658.         //    ID(df), dest_ptr, dest_width, dest_height,      
  1659.         //    dest_pitch, dest_x, dest_y, dest_dx, dest_dy,   
  1660.         //    src_ptr, src_width, src_height,                 
  1661.         //    src_pitch, src_x, src_y, src_dx, src_dy);       
  1662.     //}
  1663. XINGTORGB_FUNC(RGB32 )
  1664. XINGTORGB_FUNC(BGR32 )
  1665. XINGTORGB_FUNC(RGB24 )
  1666. XINGTORGB_FUNC(RGB565)
  1667. XINGTORGB_FUNC(RGB555)
  1668. XINGTORGB_FUNC(RGB8  )
  1669. /***********************************************************/
  1670. /*
  1671.  * Obsolete I420->RGB converters:
  1672.  * Use:
  1673.  *  void oldI420toRGBXXX (unsigned char *ysrc, unsigned char *usrc,
  1674.  *          unsigned char *vsrc, int pitchSrc, unsigned char *dst,
  1675.  *          int width, int height, int pitchDst);
  1676.  * Input:
  1677.  *  ysrc, usrc, vsrc - pointers to Y, Cr, and Cb components of the frame
  1678.  *  pitchSrc - pitch of the input frame (luminance)
  1679.  *  dst - pointer to an output buffer
  1680.  *  width, height - the size of frame to convert
  1681.  *  pitchDst - pitch of the output buffer (in RGB pixels!!!)
  1682.  * Returns:
  1683.  *  none.
  1684.  */
  1685. #ifdef _PLUS_HXCOLOR
  1686. #define OLD_YUVTORGB_FUNC(df)                               
  1687.     void oldI420to##df (unsigned char *ysrc,                
  1688.         unsigned char *usrc, unsigned char *vsrc, int pitchSrc, 
  1689.         unsigned char *dst, int width, int height, int pitchDst)
  1690.     {                                                       
  1691.         /* correct pointer if bottom-up bitmap: */          
  1692.         if (pitchDst < 0)                                   
  1693.             dst += BPP(df) * -pitchDst * (height - 1);      
  1694.         /* invoke color converter: */                       
  1695.         IMAGE_COPY (dst, 0, 0, width, height,               
  1696.             pitchDst*BPP(df), BPP(df),                      
  1697.             ysrc, usrc, vsrc, 0, 0, width, height,          
  1698.             pitchSrc, pitchSrc / 2,                         
  1699.             is_alpha? DBLROW_FN(df,I420,FULL,COPY)          
  1700.                     : DBLROW_FN(df,I420,FAST,COPY),         
  1701.             is_alpha? DBLROW2X_FN(df,I420,FULL,COPY)        
  1702.                     : DBLROW2X_FN(df,I420,FAST,COPY));      
  1703.     }
  1704. #define OLD_YUVTORGB_X2_FUNC(df)                            
  1705.     void oldI420to##df##x2 (unsigned char *ysrc,            
  1706.         unsigned char *usrc, unsigned char *vsrc, int pitchSrc, 
  1707.         unsigned char *dst, int width, int height, int pitchDst)
  1708.     {                                                       
  1709.         /* correct pointer if bottom-up bitmap: */          
  1710.         if (pitchDst < 0)                                   
  1711.             dst += BPP(df) * -pitchDst * (2*height - 1);    
  1712.         /* invoke color converter: */                       
  1713.         IMAGE_STRETCH2X (dst, 0, 0, 2*width, 2*height,      
  1714.             pitchDst*BPP(df), BPP(df),                      
  1715.             ysrc, usrc, vsrc, 0, 0, width, height,          
  1716.             pitchSrc, pitchSrc / 2,                         
  1717.             is_alpha? DBLROW_FN(df,I420,FULL,STRETCH2X)     
  1718.                     : DBLROW_FN(df,I420,FAST,STRETCH2X),    
  1719.             is_alpha? DBLROW2X_FN(df,I420,FULL,STRETCH2X)   
  1720.                     : DBLROW2X_FN(df,I420,FAST,STRETCH2X)); 
  1721.     }
  1722. #else
  1723. #define OLD_YUVTORGB_FUNC(df)                               
  1724.     void oldI420to##df (unsigned char *ysrc,                
  1725.         unsigned char *usrc, unsigned char *vsrc, int pitchSrc, 
  1726.         unsigned char *dst, int width, int height, int pitchDst)
  1727.     {                                                       
  1728.         /* correct pointer if bottom-up bitmap: */          
  1729.         if (pitchDst < 0)                                   
  1730.             dst += BPP(df) * -pitchDst * (height - 1);      
  1731.         /* invoke color converter: */                       
  1732.         IMAGE_COPY (dst, 0, 0, width, height,               
  1733.             pitchDst*BPP(df), BPP(df),                      
  1734.             ysrc, usrc, vsrc, 0, 0, width, height,          
  1735.             pitchSrc, pitchSrc / 2,                         
  1736.     DBLROW_FN(df,I420,FAST,COPY),     
  1737.             DBLROW2X_FN(df,I420,FAST,COPY));     
  1738.     }
  1739. #define OLD_YUVTORGB_X2_FUNC(df)                            
  1740.     void oldI420to##df##x2 (unsigned char *ysrc,            
  1741.         unsigned char *usrc, unsigned char *vsrc, int pitchSrc, 
  1742.         unsigned char *dst, int width, int height, int pitchDst)
  1743.     {                                                       
  1744.         /* correct pointer if bottom-up bitmap: */          
  1745.         if (pitchDst < 0)                                   
  1746.             dst += BPP(df) * -pitchDst * (2*height - 1);    
  1747.         /* invoke color converter: */                       
  1748.         IMAGE_STRETCH2X (dst, 0, 0, 2*width, 2*height,      
  1749.             pitchDst*BPP(df), BPP(df),                      
  1750.             ysrc, usrc, vsrc, 0, 0, width, height,          
  1751.             pitchSrc, pitchSrc / 2,                         
  1752.     DBLROW_FN(df,I420,FAST,STRETCH2X),     
  1753.             DBLROW2X_FN(df,I420,FAST,STRETCH2X));     
  1754.     }
  1755. #endif
  1756. OLD_YUVTORGB_FUNC(RGB32 )
  1757. OLD_YUVTORGB_FUNC(RGB24 )
  1758. OLD_YUVTORGB_FUNC(RGB565)
  1759. OLD_YUVTORGB_FUNC(RGB555)
  1760. OLD_YUVTORGB_X2_FUNC(RGB32 )
  1761. OLD_YUVTORGB_X2_FUNC(RGB24 )
  1762. OLD_YUVTORGB_X2_FUNC(RGB565)
  1763. OLD_YUVTORGB_X2_FUNC(RGB555)
  1764. /***********************************************************/
  1765. #ifdef TEST
  1766. /*
  1767.  * YUV2RGB: converts QCIF YUV image to an RGB bitmap
  1768.  * Use:
  1769.  *  YUV2RGB <output file> <input file> [<new width> <new height>] [<new format>]
  1770.  */
  1771. /* Note: use /Zp1 (no structure alignments) to compile it !!! */
  1772. /* Windows Header Files: */
  1773. #include <windows.h>
  1774. /* C RunTime Header Files */
  1775. #include <stdio.h>
  1776. #include <stdlib.h>
  1777. /* SetDestI420Colors() interface: */
  1778. #include "colorlib.h"
  1779. /* Main program: */
  1780. int main (int argc, char *argv[])
  1781. {
  1782. /* frame buffers: */
  1783. # define QCIF_HEIGHT 144
  1784. # define QCIF_WIDTH 176
  1785. # define QCIF_FRAME_SIZE
  1786. (QCIF_HEIGHT * QCIF_WIDTH + QCIF_HEIGHT * QCIF_WIDTH / 2)
  1787. #   define  MAX_HEIGHT 1024
  1788. #   define  MAX_WIDTH  1280
  1789. #   define  MAX_RGB_FRAME_SIZE 
  1790.             (MAX_HEIGHT * MAX_WIDTH * 4)
  1791.     static unsigned char yuv [QCIF_FRAME_SIZE]; /* Flawfinder: ignore */
  1792.     static struct BMP {
  1793.         BITMAPFILEHEADER hdr;           /* bitmap file-header */
  1794.         BITMAPINFOHEADER bihdr;         /* bitmap info-header */
  1795.         unsigned char rgb [MAX_RGB_FRAME_SIZE + 256*4 + 3]; /* Flawfinder: ignore */
  1796.     } bmp;
  1797.     /* local variables: */
  1798.     FILE *ifp, *ofp;
  1799.     int width = QCIF_WIDTH, height = QCIF_HEIGHT, format = ID(RGB32);
  1800.     int offs, colors, sz;
  1801.     /* process program arguments: */
  1802.     if (argc < 3) {
  1803.         fprintf (stderr, "Use:ntYUV2RGB <output file> <input file> [width] [height] [format]n");
  1804. exit (EXIT_FAILURE);
  1805. }
  1806.     /* open work files: */
  1807.     if ((ofp = fopen (argv[1], "wb+")) == NULL) { /* Flawfinder: ignore */
  1808.         fprintf (stderr, "Cannot open output file.n");
  1809. exit (EXIT_FAILURE);
  1810. }
  1811. if ((ifp = fopen (argv[2], "rb")) == NULL) { /* Flawfinder: ignore */
  1812.         fprintf (stderr, "Cannot open input file.n");
  1813. exit (EXIT_FAILURE);
  1814. }
  1815.     /* retrieve optional arguments: */
  1816.     if ((argc >= 4)
  1817.      && (width = atoi(argv[3])) == 0) {
  1818.         fprintf (stderr, "Invalid image width.n");
  1819. exit (EXIT_FAILURE);
  1820.     }
  1821.     if ((argc >= 5)
  1822.      && (height = atoi(argv[4])) == 0) {
  1823.         fprintf (stderr, "Invalid image height.n");
  1824. exit (EXIT_FAILURE);
  1825.     }
  1826.     if ((argc >= 6)
  1827.      && (format = atoi(argv[5])) == 0) {
  1828.         fprintf (stderr, "Invalid image format.n");
  1829. exit (EXIT_FAILURE);
  1830.      }
  1831. /* read YVU12 frame: */
  1832.     if (fread (yuv, 1, QCIF_FRAME_SIZE, ifp) != QCIF_FRAME_SIZE) {
  1833. fprintf (stderr, "Cannot read input file.n");
  1834. exit (EXIT_FAILURE);
  1835. }
  1836.     /* initialize I420toRGB converters: */
  1837.     SetSrcI420Colors (0., 0., 0., 0.);
  1838.     /* calculate size of bitmap: */
  1839.     sz = height * width * bpp [format];     /* image size in bytes */
  1840.     offs = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); /* offset to the array of color indices */
  1841.     colors = 0;
  1842.     if (format == ID(RGB8)) {
  1843.         /* generate palette: */
  1844. #if 0
  1845.         static unsigned int pal_ptr[256], pal_idx[256];
  1846.         unsigned int *pal_bmp_ptr = (unsigned int *)((unsigned char *)&bmp + offs);
  1847.         register int i;
  1848.         for (i = 0; i < 256; i++) pal_idx[i] = i;
  1849.         colors = SuggestDestRGB8Palette (0, pal_ptr);
  1850. #else
  1851.         /* palette from AIX player: */
  1852.         static unsigned int pal_ptr[256] = {
  1853.             0x000000, 0xffffff, 0x737373, 0xa8b2c6, 0x70a8ed, 0x5f8ec9,
  1854.             0xc0d9f7, 0x3b597d, 0xffffff, 0x999999, 0x828282, 0xd2d1d1,
  1855.             0x4e4e4e, 0xffffff, 0xaa9889, 0x908174, 0xd9d1ca, 0x564d46,
  1856.             0xffffff, 0x655650, 0x554944, 0xb7b0ad, 0x2e2724, 0xffffff,
  1857.             0xa8b2c6, 0x8f98a8, 0xdadee7, 0x5a606a, 0x000000, 0xa79249,
  1858.             0x8d7c3e, 0xd7cead, 0x310800, 0x800000, 0x840204, 0xce2900,
  1859.             0xff0000, 0x0c0f0c, 0x3c3700, 0x6b2900, 0x943900, 0xce2900,
  1860.             0xf75a00, 0x008000, 0x3c3700, 0x675f1a, 0x997f19, 0xde6300,
  1861.             0xff6300, 0x008000, 0x008000, 0x808000, 0x808000, 0xff9200,
  1862.             0xff9200, 0x00ff00, 0x55ff24, 0x55ff24, 0x808000, 0xff9200,
  1863.             0xff9200, 0x00ff00, 0x55ff24, 0x55ff24, 0x55ff24, 0xcece5a,
  1864.             0xffff00, 0x000029, 0x311818, 0x6f2529, 0x840204, 0xff0029,
  1865.             0xff0029, 0x002929, 0x2e333b, 0x663333, 0x8b3d48, 0xbd425a,
  1866.             0xff0029, 0x005a39, 0x424a42, 0x636339, 0x9c6329, 0xd66b18,
  1867.             0xd66b18, 0x299c5a, 0x299c5a, 0x887e2f, 0xa79a42, 0xa79a42,
  1868.             0xff9200, 0x00ff00, 0x299c5a, 0x55ff24, 0xa79a42, 0xcece5a,
  1869.             0xcece5a, 0x00ff00, 0x55ff24, 0x55ff24, 0x55ff24, 0xcece5a,
  1870.             0xffff00, 0x080852, 0x080852, 0x660099, 0x8b3d48, 0xbd425a,
  1871.             0xff0029, 0x004263, 0x313163, 0x655650, 0x8b3d48, 0xbd425a,
  1872.             0xbd425a, 0x004263, 0x29635a, 0x6d6d6d, 0xa0766f, 0xcc6666,
  1873.             0xcc6666, 0x008080, 0x299c5a, 0x6b736b, 0x908174, 0xd6a58c,
  1874.             0xff9999, 0x299c5a, 0x299c5a, 0x5a9c9c, 0xcece5a, 0xcece5a,
  1875.             0xf7ce8c, 0x00ff00, 0x55ff24, 0x55ff24, 0xcece5a, 0xcece5a,
  1876.             0xffff9c, 0x000080, 0x29299c, 0x660099, 0x660099, 0xbd425a,
  1877.             0xff0029, 0x101884, 0x29299c, 0x4a42bd, 0x660099, 0xbd425a,
  1878.             0xcc6666, 0x00639c, 0x29638c, 0x6b849c, 0x848284, 0xcc6666,
  1879.             0xff9999, 0x009cad, 0x427ba5, 0x5a9c9c, 0xd6a58c, 0xff9999,
  1880.             0x009cad, 0x5a9c9c, 0x5a9c9c, 0xc6ce94, 0xcece9c, 0xf7ce8c,
  1881.             0x04fefc, 0x5a9c9c, 0x5a9c9c, 0xceff9c, 0xceff9c, 0xffff9c,
  1882.             0x0000ff, 0x29299c, 0x660099, 0x660099, 0x660099, 0xbd425a,
  1883.             0x29299c, 0x4a42bd, 0x4a42bd, 0x4a42bd, 0xcc6666, 0xff9999,
  1884.             0x00639c, 0x4a42bd, 0x5f8ec9, 0x8f98a8, 0xceadad, 0xff9999,
  1885.             0x009cad, 0x5a9cce, 0x639cc6, 0x9cb5ce, 0xceadad, 0xff9999,
  1886.             0x00ceff, 0x5a9cce, 0x639cc6, 0x9cb5ce, 0xcccccc, 0xd9d1ca,
  1887.             0x04fefc, 0x04fefc, 0x9cb5ce, 0xc0d9f7, 0xe4e4e4, 0xffffce,
  1888.             0x0000ff, 0x0000ff, 0x4a42bd, 0x660099, 0x660099, 0xff00ff,
  1889.             0x0000ff, 0x4a42bd, 0x4a42bd, 0x4a42bd, 0xff00ff, 0xff00ff,
  1890.             0x009cef, 0x009cef, 0x5f8ec9, 0x70a8ed, 0xa8b2c6, 0xff00ff,
  1891.             0x009cef, 0x009cef, 0x70a8ed, 0x70a8ed, 0xc0d9f7, 0xdadee7,
  1892.             0x00ceff, 0x00ceff, 0x70a8ed, 0xc0d9f7, 0xc0d9f7, 0xe4e4e4,
  1893.             0x00ffff, 0x04fefc, 0x70a8ed, 0xccffff, 0xccffff
  1894.         },
  1895.         pal_idx[256] = {
  1896.             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
  1897.             19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 157, 239, 250,
  1898.             163, 240, 104, 124, 182, 156, 35, 158, 231, 38, 131, 133, 187, 166,
  1899.             43, 43, 135, 51, 141, 53, 230, 144, 56, 51, 53, 53, 230, 56, 56,
  1900.             56, 215, 54, 218, 244, 97, 34, 243, 71, 220, 105, 252, 88, 226, 71,
  1901.             208, 184, 132, 227, 229, 83, 217, 85, 134, 120, 88, 53, 55, 85, 56,
  1902.             88, 65, 65, 55, 56, 56, 56, 65, 66, 203, 103, 248, 76, 77, 71, 225,
  1903.             206, 19, 76, 77, 77, 109, 207, 142, 121, 253, 119, 234, 85, 160,
  1904.             15, 235, 254, 85, 85, 209, 65, 65, 214, 55, 56, 56, 65, 65, 211,
  1905.             232, 192, 248, 105, 77, 71, 204, 140, 205, 105, 77, 119, 221, 193,
  1906.             195, 247, 119, 126, 224, 197, 129, 125, 254, 157, 129, 129, 216,
  1907.             212, 132, 251, 129, 129, 213, 171, 138, 233, 140, 105, 105, 105,
  1908.             77, 140, 147, 147, 147, 119, 126, 151, 147, 5, 25, 228, 126, 157,
  1909.             202, 201, 196, 190, 126, 222, 193, 194, 195, 113, 16, 168, 168,
  1910.             195, 6, 255, 210, 233, 174, 147, 105, 105, 55, 174, 147, 147, 147,
  1911.             215, 215, 223, 222, 5, 4, 3, 215, 222, 222, 4, 4, 6, 26, 198, 198,
  1912.             4, 6, 6, 208, 53, 168, 4, 249, 249
  1913.         };
  1914.         unsigned int *pal_bmp_ptr = (unsigned int *)((unsigned char *)&bmp + offs);
  1915.         register int i;
  1916.         colors = 256;
  1917. #endif
  1918.         SetSrcRGB8Palette (colors, pal_ptr, pal_idx);
  1919.         SetDestRGB8Palette (colors, pal_ptr, pal_idx);
  1920.         /* copy it to bitmap: */
  1921.         for (i = 0; i < colors; i++) {
  1922.             register int j = palette[i];
  1923.             pal_bmp_ptr[i] = ((j & 0xFF) << 16) | (j & 0xFF00) | ((j & 0xFF0000) >> 16);
  1924.         }
  1925.         /* shift bitmap offset: */
  1926.         offs += colors * 4;
  1927.     }
  1928.     offs = (offs + 3) & ~3; /* round to the nearest dword */
  1929. /* create BMP file header */
  1930.     bmp.hdr.bfType = 0x4d42;            // "BM"
  1931.     bmp.hdr.bfSize = sz;
  1932.     bmp.hdr.bfReserved1 = 0;
  1933.     bmp.hdr.bfReserved2 = 0;
  1934.     bmp.hdr.bfOffBits = offs;
  1935.     /* create bitmap header: */
  1936.     bmp.bihdr.biSize = sizeof(BITMAPINFOHEADER);
  1937.     bmp.bihdr.biWidth = width;
  1938.     bmp.bihdr.biHeight = height;
  1939.     bmp.bihdr.biPlanes = 1;            // must be 1.
  1940.     bmp.bihdr.biCompression = BI_RGB;
  1941.     bmp.bihdr.biBitCount = bpp [format] * 8;
  1942.     bmp.bihdr.biSizeImage = sz;
  1943.     bmp.bihdr.biXPelsPerMeter = 0;
  1944.     bmp.bihdr.biYPelsPerMeter = 0;
  1945.     bmp.bihdr.biClrUsed = colors;
  1946.     bmp.bihdr.biClrImportant = colors;
  1947.     /* convert image: */
  1948.     YUVtoRGB (format,
  1949.         (unsigned char *)&bmp + offs, width, height, -width * bpp[format], 0, 0, width, height,
  1950.         yuv, QCIF_WIDTH, QCIF_HEIGHT, QCIF_WIDTH, 0, 0, QCIF_WIDTH, QCIF_HEIGHT);
  1951. /* write bitmap file: */
  1952.     if ((int)fwrite (&bmp, 1, sz+offs, ofp) != sz+offs) {
  1953. fprintf (stderr, "Cannot create BMP file.n");
  1954. exit (EXIT_FAILURE);
  1955. }
  1956. /* close files & exit: */
  1957. fclose (ifp);
  1958. fclose (ofp);
  1959.     return EXIT_SUCCESS;
  1960. }
  1961. #endif
  1962. /* yuv2rgb.c -- end of file */