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