home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / viscobv6.zip / vac22os2 / ibmcobol / samples / toolkit / mm / mmioproc / mmotfunc.c next >
C/C++ Source or Header  |  1996-11-19  |  34KB  |  872 lines

  1. /********************** START OF SPECIFICATIONS *************************/
  2. /*                                                                      */
  3. /* SOURCE FILE NAME: MMOTFUNC.C                                        */
  4. /*                                                                      */
  5. /* DESCRIPTIVE NAME: Multi-Media I/O Procedure for M-Motion Video       */
  6. /*                                                                      */
  7. /* COPYRIGHT:                                                           */
  8. /*              Copyright (c) IBM Corporation  1990, 1993               */
  9. /*                        All Rights Reserved                           */
  10. /*                                                                      */
  11. /* ABSTRACT: This file contains misc functions for use with the         */
  12. /*           M-Motion IOProc (file MMOT.C)                              */
  13. /*                                                                      */
  14. /*********************** END OF SPECIFICATIONS **************************/
  15. /************************************************************************/
  16. /* Put all #defines here                                                */
  17. /************************************************************************/
  18.  
  19. #define INCL_32                          * force 32 bit compile
  20. #define INCL_GPIBITMAPS
  21. #define INCL_DOSFILEMGR
  22. #define INCL_DOSRESOURCES
  23. #define INCL_DOSMODULEMGR
  24. #define INCL_WIN
  25. #define INCL_GPI
  26. #define INCL_PM                         /* force 32 bit compile */
  27.  
  28. /************************************************************************/
  29. /* Put all #includes here                                               */
  30. /************************************************************************/
  31.  
  32. #include <limits.h>
  33. #include <os2.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #include <os2medef.h>
  37. #include <mmioos2.h>
  38. #include "mmotproc.h"
  39.  
  40.  
  41. int _CRT_init( VOID );
  42.  
  43. /************************************************************************
  44.  * Function : GetYUV
  45.  * Description :
  46.  *   This function takes 3 raw YUV values and creates the 6 discrete
  47.  *   Y, U, and V values necessary to convert to RGB.
  48.  ************************************************************************/
  49. void GetYUV (PYUV pYuv,         /* Pointer to packed YUV buffer   */
  50.              SHORT Y[],         /* Separated Y components         */
  51.              SHORT *U1,         /* Shared U component             */
  52.              SHORT *V1)         /* Shared V component             */
  53.     {
  54.     Y[0] = (SHORT)((pYuv->YUVWord1 & 0x0FE0) >> 4);
  55.     Y[1] = (SHORT)((pYuv->YUVWord2 & 0xFE00) >> 8);
  56.     Y[2] = (SHORT)(((pYuv->YUVWord2 & 0x000F) << 4) +
  57.                ((pYuv->YUVWord3 & 0xE000) >> 12));
  58.     Y[3] = (SHORT)(pYuv->YUVWord3 & 0x00FE);
  59.  
  60.     *U1 = (SHORT)(((pYuv->YUVWord1 & 0xC000) >> 8) +
  61.                   ((pYuv->YUVWord1 & 0x000C) << 2) +
  62.                   ((pYuv->YUVWord2 & 0x00C0) >> 4) +
  63.                  ((pYuv->YUVWord3 & 0x0800) >> 10));
  64.  
  65.     *V1 = (SHORT)(((pYuv->YUVWord1 & 0x3000) >> 6) +
  66.                   ((pYuv->YUVWord1 & 0x0003) << 4) +
  67.                   ((pYuv->YUVWord2 & 0x0030) >> 2) +
  68.                   ((pYuv->YUVWord3 & 0x0200) >> 8));
  69.  
  70.     if (*U1 > 127)
  71.         *U1 -= 256;
  72.     if (*V1 > 127)
  73.         *V1 -= 256;
  74.     }
  75.  
  76. /************************************************************************
  77.  * Function : YUVtoRGB
  78.  * Description:
  79.  *    This function takes 6 discrete YUV values and processes it into 4
  80.  *    24 bpp RGB pixels.  It also requires an address to store the processed
  81.  *    RGB values.
  82.  ************************************************************************/
  83. void YUVtoRGB (SHORT Y[],       /* Array of 4 Y values, 1 per pel             */
  84.                SHORT U1,        /* Shared U value                             */
  85.                SHORT V1,        /* Shared V value                             */
  86.                PBYTE lpRGBBuf)  /* Pointer to RGB buffer where 4 pels will go */
  87.     {
  88.     /********************************************************************
  89.      * Declare Local Variables.
  90.      ********************************************************************/
  91.     USHORT          i;
  92.     LONG            lR, lG, lB;
  93.  
  94.     /********************************************************************
  95.      * Processing and writing out 4 pel block.
  96.      ********************************************************************/
  97.     for (i = 0; i < 4; i++)
  98.         {
  99.         /****************************************
  100.          * no saturation accounted for.
  101.          *  lR = (V1 * 179L / 127L) + Y[i];
  102.          *  lB = (U1 * 227L / 127L) + Y[i];
  103.  
  104.          * Calculate Red and Blue values...
  105.  
  106.          * R = (V * 179/127 * 80%) + Y
  107.          *   = (V * 179/127 * 8/10) + Y
  108.          *   = (V * 1432/1270) + Y
  109.          ****************************************/
  110.         lR = (((LONG)V1 * 179L) / 127L) + Y[i];
  111.  
  112.         /****************************************
  113.          * B = (U * 227/127 * 80%) + Y
  114.          *   = (U * 227/127 * 8/10) + Y
  115.          *   = (U * 1816/1270) + Y
  116.          ****************************************/
  117.         lB = (((LONG)U1 * 227L) / 127L) + Y[i];
  118.  
  119.         lG = (Y[i]*170L - lR*51L - lB*19L) / 100L;
  120.  
  121.         /****************************************************************
  122.          * Determine the BLUE byte and put it into buffer.
  123.          ****************************************************************/
  124.         if (lB>255L)
  125.             *lpRGBBuf++=255;
  126.         else if (lB<0L)
  127.             *lpRGBBuf++=0;
  128.         else
  129.             *lpRGBBuf++=(BYTE)lB;
  130.  
  131.         /****************************************************************
  132.          * Determine the GREEN byte and put it into buffer.
  133.          ****************************************************************/
  134.         if (lG>255L)
  135.             *lpRGBBuf++=255;
  136.         else if (lG<0L)
  137.             *lpRGBBuf++=0;
  138.         else
  139.             *lpRGBBuf++=(BYTE)lG;
  140.  
  141.         /****************************************************************
  142.          * Determine the RED byte and put it into buffer.
  143.          ****************************************************************/
  144.         if (lR>255L)
  145.             *lpRGBBuf++=255;
  146.         else if (lR<0L)
  147.             *lpRGBBuf++=0;
  148.         else
  149.             *lpRGBBuf++=(BYTE)lR;
  150.         }
  151.     }
  152.  
  153. /************************************************************************
  154.  * Function : RGBtoYUV
  155.  * Description:
  156.  *    Take twelve bytes of RGB data (4 pels) and use them to create the
  157.  *    6 discrete Y, U, and V values needed to build the 4 pixels (6 bytes)
  158.  *    of YUV data.
  159.  ************************************************************************/
  160. void RGBtoYUV (SHORT YO[],      /* Array of 4 Y values to be created    */
  161.                SHORT *U1,       /* Shared U value to be created         */
  162.                SHORT *V1,       /* Shared V value to be created         */
  163.                PBYTE lpRGBBuf)  /* Pointer to RGB buf holding 4 pels    */
  164.     {
  165.     /********************************************************************
  166.      * Declare Local Variables.
  167.      ********************************************************************/
  168.     PRGB4       prgb4;
  169.  
  170.     /********************************************************************
  171.      * Set up and cast rgb pointer to correct type.
  172.      ********************************************************************/
  173.     prgb4 = (PRGB4) lpRGBBuf;
  174.  
  175.     /********************************************************************
  176.      * Calculate Y, U, and V values.
  177.      ********************************************************************/
  178.  
  179.     YO[0] = (SHORT)(((100 * (USHORT)prgb4->bG1) +
  180.              (51  * (USHORT)prgb4->bR1) +
  181.              (19  * (USHORT)prgb4->bB1)) / 170);
  182.     YO[1] = (SHORT)(((100 * (USHORT)prgb4->bG2) +
  183.              (51  * (USHORT)prgb4->bR2) +
  184.              (19  * (USHORT)prgb4->bB2)) / 170);
  185.     YO[2] = (SHORT)(((100 * (USHORT)prgb4->bG3) +
  186.              (51  * (USHORT)prgb4->bR3) +
  187.              (19  * (USHORT)prgb4->bB3)) / 170);
  188.     YO[3] = (SHORT)(((100 * (USHORT)prgb4->bG4) +
  189.              (51  * (USHORT)prgb4->bR4) +
  190.              (19  * (USHORT)prgb4->bB4)) / 170);
  191.  
  192.     /************************************************************
  193.      * Calculate the shared U value - it is the average of the
  194.      *   U values of each of the 4 pels
  195.      * U = (B - Y) * 127/227
  196.      ************************************************************/
  197.     *U1 = (SHORT)((((((LONG)prgb4->bB1 - YO[0])*127)/227)+
  198.                    ((((LONG)prgb4->bB2 - YO[1])*127)/227)+
  199.                    ((((LONG)prgb4->bB3 - YO[2])*127)/227)+
  200.                    ((((LONG)prgb4->bB4 - YO[3])*127)/227)) >>2);
  201.  
  202.     /************************************************************
  203.      * Calculate the shared V value - it is the average of the
  204.      *   V values of each of the 4 pels
  205.      * V = (R - Y) * 127/179
  206.      ************************************************************/
  207.     *V1 = (SHORT)((((((LONG)prgb4->bR1 - YO[0])*127)/179)+
  208.                    ((((LONG)prgb4->bR2 - YO[1])*127)/179)+
  209.                    ((((LONG)prgb4->bR3 - YO[2])*127)/179)+
  210.                    ((((LONG)prgb4->bR4 - YO[3])*127)/179)) >>2);
  211.     }
  212.  
  213. /************************************************************************
  214.  * Function : PutYUV
  215.  * Description:
  216.  *    This function will take an array of 4 Y values and a separate U and
  217.  *    V value and process it into 3 packed USHORT YUV values (6 bytes).
  218.  ************************************************************************/
  219. void PutYUV (PBYTE lpTempBuf,   /* Packed YUV buffer to place data into */
  220.              SHORT YO[],        /* Array of 4 Y values to use           */
  221.              SHORT U1,          /* Shared U value                       */
  222.              SHORT V1)          /* Shared V value                       */
  223.     {
  224.     /********************************************************************
  225.      * Declare Local Variables.
  226.      ********************************************************************/
  227.     USHORT          YUVWord1, YUVWord2, YUVWord3;
  228.  
  229.     /********************************************************************
  230.      * Breakdown 6 values into (3) USHORTs
  231.      ********************************************************************/
  232.     YUVWord1 = (USHORT)(((U1 & 0x00C0) << 8) +
  233.                ((V1 & 0x00C0) << 6) +
  234.                (YO[0] << 4) +
  235.                ((U1 & 0x0030) >> 2) +
  236.                ((V1 & 0x0030) >> 4));
  237.  
  238.     YUVWord2 = (USHORT)((YO[1] << 8) +
  239.                ((U1 & 0x000C) << 4) +
  240.                ((V1 & 0x000C) << 2) +
  241.                ((YO[2] & 0x00F0) >> 4));
  242.  
  243.     YUVWord3 = (USHORT)(((YO[2] & 0x000E) << 12) +
  244.                          ((U1 & 0x0002) << 10) +
  245.                          ((V1 & 0x0002) << 8) + YO[3]);
  246.  
  247.     *lpTempBuf++= LOBYTE(YUVWord1);
  248.     *lpTempBuf++= HIBYTE(YUVWord1);
  249.     *lpTempBuf++= LOBYTE(YUVWord2);
  250.     *lpTempBuf++= HIBYTE(YUVWord2);
  251.     *lpTempBuf++= LOBYTE(YUVWord3);
  252.     *lpTempBuf++= HIBYTE(YUVWord3);
  253.     }
  254.  
  255. /************************************************************************
  256.  * Function : InitFileStruct
  257.  * Description:
  258.  *    This function will reset the fields of the current FileStatus
  259.  *    structure to initialized values.
  260.  ************************************************************************/
  261. void InitFileStruct (PMMFILESTATUS pVidInfo)  /* MMotion IOProc data struct */
  262.  
  263.     {
  264.     pVidInfo->lpRGBBuf                         = 0L;
  265.     pVidInfo->lpImgBuf                         = 0L;
  266.     pVidInfo->lImgBytePos                      = 0L;
  267.     pVidInfo->ulRGBTotalBytes                  = 0L;
  268.     pVidInfo->ulImgTotalBytes                  = 0L;
  269.     pVidInfo->mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cBitCount    = 24L;
  270.     pVidInfo->ulFlags                          = 0L;
  271.     pVidInfo->bSetHeader                       = FALSE;
  272.     }
  273.  
  274. /************************************************************************
  275.  * Function : RGBBytesToPels
  276.  * Description :
  277.  *    This function will return the number of pels that the input parameter
  278.  *    bytes maps out to.
  279.  ************************************************************************/
  280. ULONG RGBBytesToPels (ULONG ulBytes,    /* Number of bytes to evaluate        */
  281.                       USHORT usBitCount) /* Number of bits/pel for these bytes */
  282.     {
  283.  
  284.     switch (usBitCount)
  285.         {
  286.         case 24:
  287.             return (ulBytes / 3);   /* 1 pel represented by 3 bytes */
  288.         case 8:
  289.             return (ulBytes);       /* 1 pel represented by 1 byte  */
  290.         case 4:
  291.             return (ulBytes << 1);  /* 1 pel represented by 4 bits. */
  292.                                     /* Bytes multiplied by 2        */
  293.         case 1:
  294.             return (ulBytes << 3);  /* 1 pel represented by 1 bit.  */
  295.                                     /* Bytes multiplied by 8        */
  296.  
  297.         default:
  298.             return( 0L );
  299.         }
  300.  
  301.     }
  302.  
  303. /************************************************************************
  304.  * Function : PelsToRGBBytes
  305.  * Description :
  306.  *    This function will return the number of bytes that the input parameter
  307.  *    pels maps out to.
  308.  ************************************************************************/
  309. ULONG PelsToRGBBytes (ULONG ulPels,     /* Number of pels to evaluate   */
  310.                       USHORT usBitCount) /* Number of bits/pel          */
  311.     {
  312.  
  313.     switch (usBitCount)
  314.         {
  315.         case 24:
  316.             return (ulPels * 3);    /* 1 pel represented by 3 bytes     */
  317.         case 8:
  318.             return (ulPels);        /* 1 pel represented by 1 byte      */
  319.         case 4:
  320.             return (ulPels  >> 1);  /* 1 pel represented by 4 bits.     */
  321.                                     /* Pels divided by 2                */
  322.         case 1:
  323.             return (ulPels  >> 3);  /* 1 pel represented by 1 bit.      */
  324.                                     /* Pels divided by 8                */
  325.  
  326.         default:
  327.             return( 0L );
  328.         }
  329.     }
  330.  
  331. /************************************************************************
  332.  * Function : Convert1BitTo24Bit
  333.  * Description:
  334.  *    This function will convert a buffer of 1 bit palettized data
  335.  *    into 24 bit RGB data.
  336.  ************************************************************************/
  337. void Convert1BitTo24Bit (PBYTE  lpInputPtr,   /* Ptr to 1 bpp data to convert */
  338.                          PRGB   RGBBufPtr,    /* Ptr to RGB buffer to write to*/
  339.                          PRGB   Palette,      /* Palette to use for 1 bpp     */
  340.                          ULONG  ulInputBytes) /* # of bytes to process        */
  341.     {
  342.     ULONG       ulPalValues;
  343.     ULONG       ulByteCnt = 0;
  344.  
  345.     /********************************************************************
  346.      * Loop through each byte in the 1 bpp source.  Each bit is one pel's
  347.      *    palette reference.
  348.      * Obtain the RGB data for each pel, place the RGB info into the
  349.      *    the RGB buffer.
  350.      ********************************************************************/
  351.     for (ulByteCnt = 0; ulByteCnt < ulInputBytes; ulByteCnt++)
  352.         {
  353.         /****************************************************************
  354.          * Get the current palette index.
  355.          ****************************************************************/
  356.         ulPalValues = (ULONG)lpInputPtr[ulByteCnt];
  357.  
  358.         /****************************************************************
  359.          * Advance through the RGBLine pointer placing a 3 byte palette
  360.          * value into each element.
  361.          ****************************************************************/
  362.         RGBBufPtr[0] = Palette[(ulPalValues & 0x80) >> 7]; /* Bit #7 */
  363.         RGBBufPtr[1] = Palette[(ulPalValues & 0x40) >> 6]; /* Bit #6 */
  364.         RGBBufPtr[2] = Palette[(ulPalValues & 0x20) >> 5]; /* Bit #5 */
  365.         RGBBufPtr[3] = Palette[(ulPalValues & 0x10) >> 4]; /* Bit #4 */
  366.         RGBBufPtr[4] = Palette[(ulPalValues & 0x08) >> 3]; /* Bit #3 */
  367.         RGBBufPtr[5] = Palette[(ulPalValues & 0x04) >> 2]; /* Bit #2 */
  368.         RGBBufPtr[6] = Palette[(ulPalValues & 0x02) >> 1]; /* Bit #1 */
  369.         RGBBufPtr[7] = Palette[(ulPalValues & 0x01)];      /* Bit #0 */
  370.  
  371.         /****************************************************************
  372.          * Make sure the pointer is now set 8 pels further so we can
  373.          * come back in again to the correct place.
  374.          ****************************************************************/
  375.         RGBBufPtr += 8;
  376.         }
  377.     }
  378.  
  379. /************************************************************************
  380.  * Function : Convert4BitTo24Bit
  381.  * Description:
  382.  *    This function will convert a buffer of 4 bit palettized data
  383.  *    into 24 bit RGB data.
  384.  ************************************************************************/
  385. void Convert4BitTo24Bit (PBYTE  lpInputPtr,   /* Ptr to 4 bpp data to convert  */
  386.                          PRGB   RGBBufPtr,    /* Ptr to RGB buffer to write to */
  387.                          PRGB   Palette,      /* Palette to use for 1 bpp      */
  388.                          ULONG  ulInputBytes) /* # of bytes to process         */
  389.     {
  390.     ULONG       ulPalValues;
  391.     ULONG       ulByteCnt = 0;
  392.  
  393.     /********************************************************************
  394.      * Loop through each pel in the source and look it up in the palette
  395.      * table and then put the looked up value into the position RGBBufPtr.
  396.      ********************************************************************/
  397.     for (ulByteCnt = 0; ulByteCnt < ulInputBytes; ulByteCnt++)
  398.  
  399.         {
  400.         /****************************************************************
  401.          * Get the current palette index.
  402.          ****************************************************************/
  403.         ulPalValues = (ULONG)lpInputPtr[ulByteCnt];
  404.  
  405.         /****************************************************************
  406.          * Get first pel (held in xxxx0000, first half of byte)
  407.          ****************************************************************/
  408.         RGBBufPtr[0] = Palette[ulPalValues >> 4];
  409.  
  410.         /****************************************************************
  411.          * Get second pel (held in 0000xxxx, second half of byte)
  412.          ****************************************************************/
  413.         RGBBufPtr[1] = Palette[ulPalValues++ & 0x0F];
  414.  
  415.         /****************************************************************
  416.          * Bump RGBBufPtr pointer by 2 and start again.
  417.          ****************************************************************/
  418.         RGBBufPtr += 2;
  419.         }
  420.     }
  421.  
  422. /************************************************************************
  423.  * Function : Convert8BitTo24Bit
  424.  * Description:
  425.  *    This function will convert a buffer of 8 bit palettized data
  426.  *    into 24 bit RGB data.
  427.  ************************************************************************/
  428. void Convert8BitTo24Bit (PBYTE  lpInputPtr,   /* Ptr to 8 bpp data to convert  */
  429.                          PRGB   RGBBufPtr,    /* Ptr to RGB buffer to write to */
  430.                          PRGB   Palette,      /* Palette to use for 1 bpp      */
  431.                          ULONG  ulInputBytes) /* # of bytes to process         */
  432.     {
  433.     BYTE        bPalValue;
  434.     ULONG       ulByteCnt;
  435.  
  436.     /********************************************************************
  437.      * Loop through each pel in the source and look it up in the palette
  438.      * table and then put the looked up value into the destination.
  439.      ********************************************************************/
  440.     for (ulByteCnt = 0; ulByteCnt < ulInputBytes; ulByteCnt++)
  441.  
  442.         {
  443.         /****************************************************************
  444.          * Get the current palette index.
  445.          ****************************************************************/
  446.         bPalValue = lpInputPtr[ulByteCnt];
  447.  
  448.         /****************************************************************
  449.          * Store the one pel and increment pointer for next pass.
  450.          ****************************************************************/
  451.         *RGBBufPtr++ = Palette[bPalValue];
  452.         }
  453.     }
  454.  
  455. /************************************************************************
  456.  * Function : RGB2_To_RGB
  457.  * Description :
  458.  *    This function will take a RGB2 Palette which is in BGRX order and
  459.  *    convert it to an RGB Palette in BGR order.  It accepts a pointer
  460.  *    to both arrays as well as a number of colors that are in the
  461.  *    original palette.
  462.  *
  463.  *    We will ignore the extra flag byte in the RGB2 data structure at
  464.  *    this time.
  465.  ************************************************************************/
  466. void RGB2_To_RGB (PRGB2     rgb2Palette,     /* B-G-R-flags palette       */
  467.                   PRGB      rgbPalette,      /* B-G-R palette             */
  468.                   USHORT    usNumEntries)    /* # entries in palette to do*/
  469.     {
  470.     USHORT      i;
  471.  
  472.     /* Go through each array element in the RGB2 palette and set    */
  473.     /* correct values in the RGB palette.                           */
  474.     for (i = 0; i < usNumEntries; i++)
  475.         {
  476.         rgbPalette[i].bRed   = rgb2Palette[i].bRed;
  477.         rgbPalette[i].bGreen = rgb2Palette[i].bGreen;
  478.         rgbPalette[i].bBlue  = rgb2Palette[i].bBlue;
  479.         }
  480.     }
  481.  
  482. /************************************************************************
  483.  * Function : ConvertOneLineYUVtoRGB
  484.  * Description :
  485.  *    This function takes one line of YUV data and converts it into RGB.
  486.  ************************************************************************/
  487. void ConvertOneLineYUVtoRGB (PBYTE  lpYUVBuf,          /* Pointer to line of YUV */
  488.                              PBYTE  lpRGBBuf,          /* Pointer to line of RGB */
  489.                              ULONG  ulYUVBytesPerLine) /* # bytes to process     */
  490.     {
  491.     ULONG       ulYUVByteCtr;
  492.     PBYTE       lpRGBBufPtr;
  493.     PYUV        pYuv;
  494.     SHORT       Y[4], U1, V1;
  495.  
  496.     lpRGBBufPtr = lpRGBBuf;
  497.     pYuv = (PYUV) lpYUVBuf;
  498.  
  499.     for (ulYUVByteCtr = 0;
  500.          ulYUVByteCtr < ulYUVBytesPerLine;
  501.          ulYUVByteCtr += 6)
  502.         {
  503.         /* Change a 3 USHORTs/4 pel YUV Block into separate Y, U & V values. */
  504.         GetYUV (pYuv, Y, &U1, &V1);
  505.  
  506.         /* Change 4 pels Y, U & V into 4 pels RGB          */
  507.         YUVtoRGB (Y, U1, V1, lpRGBBufPtr);
  508.  
  509.         /* move to next YUV 4-pel block                    */
  510.         pYuv++;
  511.  
  512.         /* move lpRGBBufPtr past the 4 pels just created   */
  513.         lpRGBBufPtr += 12;
  514.         }
  515.     }
  516.  
  517. /************************************************************************
  518.  * Function : ConvertOneLineRGBtoYUV
  519.  * Description :
  520.  *    This function takes one line of RGB data and converts it into YUV.
  521.  ************************************************************************/
  522. void ConvertOneLineRGBtoYUV (PBYTE  lpRGBBuf,      /* Pointer to 1 line RGB */
  523.                              PBYTE  lpYUVBuf,      /* Pointer to 1 line YUV */
  524.                              ULONG  ulYUVPelWidth) /* # bytes to process    */
  525.     {
  526.     ULONG       ulPelCtr;
  527.     PRGB4       prgb4;
  528.     SHORT       Y[4], U1, V1;
  529.  
  530.     prgb4 = (PRGB4) lpRGBBuf;
  531.  
  532.     for (ulPelCtr = 0;
  533.          ulPelCtr < ulYUVPelWidth;
  534.          ulPelCtr += 4)
  535.  
  536.         {
  537.         /* convert 12 bytes RGB to 6 Y, U & V values.     */
  538.         RGBtoYUV (Y, &U1, &V1, (PBYTE) prgb4);
  539.  
  540.         /* pack 6 Y, U & V values into a 3 USHORT format. */
  541.         PutYUV (lpYUVBuf, Y, U1, V1);
  542.  
  543.         /* move up lpFullYUVBuf for next block            */
  544.         lpYUVBuf += 6;
  545.  
  546.         prgb4++;
  547.         }
  548.     }
  549.  
  550. /************************************************************************
  551.  * Function : ImgBufferFlip
  552.  * Description :
  553.  *    This function will take a full image buffer and reverse the order of
  554.  *    the lines, effectively flipping the image vertically.
  555.  *    This is needed because MMotion stores the YUV image data from the
  556.  *    top down, and PM Bitmaps store data from bottom up.
  557.  *
  558.  *    THE IOPROC IS EXPECTED TO PASS DATA TO, AND ACCEPT DATA FROM THE
  559.  *    APPLICATION IN BOTTOM UP ORDER!!
  560.  ************************************************************************/
  561. BOOL ImgBufferFlip (PBYTE   lpImgBuf,       /* Buffer to flip             */
  562.                     ULONG   ulBytesPerRow,  /* Total bytes - w/ pads, etc */
  563.                     ULONG   ulHeight)       /* Rows high                  */
  564.  
  565.     {
  566.     PBYTE       lpTempBuf;
  567.     ULONG       ulRowCount;
  568.     ULONG       ulImgTotalBytes;
  569.     ULONG       ulLastLine;
  570.     PBYTE       lpFrom;
  571.     PBYTE       lpTo;
  572.  
  573.     ulImgTotalBytes = (ulBytesPerRow * ulHeight);
  574.     ulLastLine      = ulImgTotalBytes - ulBytesPerRow;
  575.  
  576.     if (DosAllocMem ((PPVOID) &lpTempBuf,
  577.                      ulBytesPerRow,
  578.                      fALLOC))
  579.  
  580.         return (FALSE);
  581.  
  582.     lpFrom = (PBYTE)lpImgBuf;
  583.     lpTo   = (PBYTE)&lpImgBuf[ulLastLine];
  584.  
  585.     for (ulRowCount = 0;
  586.          ulRowCount < (ulHeight >> 1);
  587.          ulRowCount++)
  588.  
  589.         {
  590.         memcpy (lpTempBuf,
  591.                 lpFrom,
  592.                 ulBytesPerRow);
  593.  
  594.         memcpy (lpFrom,
  595.                 lpTo,
  596.                 ulBytesPerRow);
  597.  
  598.         memcpy (lpTo,
  599.                 lpTempBuf,
  600.                 ulBytesPerRow);
  601.  
  602.         lpFrom += ulBytesPerRow;
  603.         lpTo   -= ulBytesPerRow;
  604.  
  605.         }   /* end of FOR loop   */
  606.  
  607.     return (TRUE);
  608.     }   /* end of function call  */
  609.  
  610.  
  611.  
  612. /************************************************************************
  613.  * Function : ImgBytesToRGBBytes
  614.  * Description :
  615.  *    This function will convert the number of bytes (lImgBytes) that
  616.  *    is specified relative in a particular color space (usBitCount) into the
  617.  *    number of bytes in 24-bit RGB color space required to represent
  618.  *    the same number of "pels".
  619.  ************************************************************************/
  620. LONG ImgBytesToRGBBytes (LONG lImgBytes,        /* Length of image buffer   */
  621.                          USHORT usBitCount)     /* bits/pel in image buffer */
  622.    {
  623.    switch (usBitCount)
  624.       {
  625.       case 24:
  626.          /* 1 RGB bytes/1 Img byte */
  627.          return (lImgBytes);
  628.  
  629.       case  8:
  630.          /* 3 RGB bytes/1 Img byte */
  631.          return (lImgBytes * 3);
  632.  
  633.       case  4:
  634.          /* 6 RGB bytes/1 Img byte */
  635.          return ((lImgBytes << 1) * 3);
  636.  
  637.       case  1:
  638.          /* 24 RGB bytes/1 Img byte */
  639.          return ((lImgBytes << 3) * 3);
  640.  
  641.       default:
  642.          return( 0L );
  643.  
  644.       }
  645.    }
  646.  
  647. /*************************************************************************************
  648.  * Routine is called on each DLL instantiation and termination.
  649.  * Caller assures that no two instances execute this code
  650.  * at the same time.
  651.  * 00) Change name to _DLL_InitTerm and use the linkage pragma.
  652.  *************************************************************************************/
  653. /*************************************************************************************
  654.  * Variable holds DLL module handle.  Gets set at initialization.
  655.  * Data area is separate for each using process, so this value
  656.  * could be different (or same) per process.
  657.  *************************************************************************************/
  658. HMODULE hModuleHandle;
  659.  
  660. #pragma linkage (_DLL_InitTerm, system)
  661. /* #pragma checkout (suspend)       /* Prevent unreferenced parameter messages */
  662. ULONG _DLL_InitTerm (ULONG hModHandle, ULONG fTerm, BOOL FirstInstance)
  663. {
  664.    hModuleHandle = hModHandle;  /* Remember for NLS lookup */
  665.    if (!fTerm) {
  666.       if (_CRT_init())
  667.          return (0L);
  668.    } /* endif */
  669.  
  670.    return (1L);                 /* Success */
  671. } /* DLL_InitTerm */
  672. /* #pragma checkout (resume) */
  673.  
  674.  
  675. /**************************************************************************
  676.  *   GetFormatString                                                     **
  677.  **************************************************************************
  678.  *
  679.  * ARGUMENTS:
  680.  *
  681.  *     lSearchId         - Table search key
  682.  *     pszFormatString   - Address where to return string.
  683.  *                         If null, then string is not returned.
  684.  *     lBytes            - Number of bytes to copy.
  685.  *
  686.  * RETURN:
  687.  *
  688.  *     Returns 0 if string not found, or the number of characters (bytes)
  689.  *     copied to the callers buffer.
  690.  *     Note, returned string is not ASCII nul terminated
  691.  *
  692.  * DESCRIPTION:
  693.  *
  694.  *     This function will retrieve the format string for the specified
  695.  *     IOProc from the resource file that contains the strings.
  696.  *
  697.  ***************************************************************************/
  698. LONG GetFormatString (LONG lSearchId,
  699.                       PSZ  pszFormatString,   /* Null, or dest address     */
  700.                       LONG lBytes)            /* Caller provided maximum   */
  701. {
  702.    PVOID   pResourceData;
  703.    CHAR    *pTemp;
  704.    LONG    lStringLen;      /* Length of format string  */
  705.    LONG    lRetVal = 0;     /* Function return value    */
  706.    LONG    lSearchTemp;
  707.  
  708.    if (DosGetResource(hModuleHandle,
  709.                       RT_RCDATA,
  710.                       MMOTION_IOPROC_NAME_TABLE,
  711.                       &pResourceData))
  712.       {
  713.       return (MMIO_ERROR);
  714.       }
  715.  
  716.    /*
  717.     * The resource table is of the form : FOURCC String\0
  718.     * Loop until a match is found, then return the string.
  719.     * Copy up to the number of bytes specified.
  720.     */
  721.  
  722.    lStringLen = 0;
  723.    pTemp = (CHAR *)pResourceData;
  724.  
  725.    while (pTemp)
  726.       {
  727.       memmove(&lSearchTemp, pTemp, sizeof(LONG));
  728.  
  729.       if (lSearchTemp == 0L)
  730.          {
  731.          break;  /* End of table, search item not found */
  732.          }
  733.  
  734.       if (lSearchTemp == lSearchId)   /* Search item found?               */
  735.          {
  736.          pTemp += sizeof(LONG);       /* Bypass numeric search id         */
  737.          lStringLen = strlen(pTemp);  /* Determine length of found string */
  738.          if (lStringLen >= lBytes)    /* Truncate, if necessary           */
  739.             {
  740.             if (lBytes > 0)
  741.                lStringLen = lBytes;   /* Number of characters to return   */
  742.             else
  743.                {
  744.                /* Callers buffer has zero size.  Cannot return any data   */
  745.                lRetVal = 0;           /* Size of returned data            */
  746.                break;                 /* Done searching                   */
  747.                }
  748.             }
  749.          if (pszFormatString != NULL)
  750.             {
  751.             memcpy(pszFormatString, pTemp, lStringLen); /* Copy string to caller */
  752.             }
  753.          lRetVal = lStringLen;        /* Function return value            */
  754.          break;                       /* We're done searching             */
  755.          }
  756.  
  757.       pTemp += sizeof(FOURCC);
  758.       pTemp += (strlen(pTemp) + 1);   /* Advance to next search key       */
  759.       }
  760.  
  761.    DosFreeResource( pResourceData );
  762.  
  763.    return (lRetVal);  /* Zero or strlen */
  764. }
  765.  
  766.  
  767. /**************************************************************************
  768.  *   GetFormatStringLength                                               **
  769.  **************************************************************************
  770.  *
  771.  * ARGUMENTS:
  772.  *
  773.  *     lSearchId         - Table search key
  774.  *     plNameLength      - Address where to return string length.
  775.  *
  776.  * RETURN:
  777.  *
  778.  *     Length of the format string not including the terminating '\0'.
  779.  *     That is, the same value as would be returned from strlen().
  780.  *
  781.  * DESCRIPTION:
  782.  *
  783.  *     This function will retrieve the length of the format string
  784.  *     for the specified IOProc from the resource file that contains
  785.  *     the strings.
  786.  *
  787.  ***************************************************************************/
  788. LONG GetFormatStringLength (LONG  lSearchId,
  789.                             PLONG plNameLength)
  790. {
  791.    LONG  lStringSize;
  792.    LONG  lRetVal;
  793.  
  794.    lStringSize = GetFormatString (lSearchId, NULL, LONG_MAX);
  795.    if (lStringSize > 0)             /* String found?                      */
  796.       {
  797.       *plNameLength = lStringSize;  /* yes, return strlen                 */
  798.       lRetVal = 0;                  /* and indicate success to caller     */
  799.       }
  800.    else
  801.       {
  802.       *plNameLength = 0;            /* no, error.  Return zero for length */
  803.       lRetVal = lStringSize;        /* and error code from called routine */
  804.       }
  805.    return (lRetVal);
  806. }
  807.  
  808.  
  809. /**************************************************************************
  810.  *   GetNLSData                                                          **
  811.  **************************************************************************
  812.  *
  813.  * ARGUMENTS:
  814.  *
  815.  *     pulCodePage       - Address where to return the code page/country.
  816.  *     pulLanguage       - Address where to return the language/dialect.
  817.  *
  818.  * RETURN:
  819.  *
  820.  *     Error code or 0.
  821.  *
  822.  * DESCRIPTION:
  823.  *
  824.  *     This function will retrieve the NLS information for the IOProc
  825.  *     strings contained in the resource file.
  826.  *
  827.  ***************************************************************************/
  828.  
  829. ULONG APIENTRY GetNLSData( PULONG pulCodePage,
  830.                            PULONG pulLanguage )
  831. {
  832.    PVOID   pResourceData;
  833.    CHAR    *pTemp;
  834.  
  835.    if (DosGetResource( hModuleHandle,
  836.                        RT_RCDATA,
  837.                        MMOTION_NLS_CHARSET_INFO,
  838.                        &pResourceData ))
  839.       {
  840.       return (MMIO_ERROR);
  841.       }
  842.  
  843.    /*
  844.     * The resource table is of the form :
  845.     *   usCodePage     Low
  846.     *   usCountryCode  High
  847.     *   usLanguage     Low
  848.     *   usDialect      High
  849.     */
  850.  
  851.    pTemp = (CHAR *)pResourceData;
  852.  
  853.    while (pTemp)
  854.       {
  855.       memmove( pulCodePage, pTemp, sizeof(ULONG) );
  856.       pTemp += sizeof(ULONG);
  857.  
  858.       if (pTemp == NULL)
  859.          {
  860.          break;
  861.          }
  862.  
  863.       memmove( pulLanguage, pTemp, sizeof(ULONG) );
  864.  
  865.       break;
  866.       }
  867.  
  868.    DosFreeResource( pResourceData );
  869.  
  870.    return (MMIO_SUCCESS);
  871. }
  872.