The MMIOM_READ message requests that bytes be read from an open file; MMIOM_WRITE message requests that bytes be written to an open file. These messages should be handled differently for each IOProc, depending on the requirements imposed by the file's data. Because a file might be using buffered I/O, mmioRead and mmioWrite maintain the lBufOffset and the lDiskOffset fields. The IOProc should not modify these fields. If these fields are needed by the IOProc, the IOProc can use the aulInfo array to maintain. Additionally, the pExtraInfoStruct can be used for any user-defined structure that the IOProc requires. The sample IOProc stores its header in this field to demonstrate this capability. If the IOProc is a file format IOProc, it should use mmioRead or mmioWrite calls to the storage system IOProc, using the internal handle generated during the open processing. A storage system IOProc might simply issue calls to DosRead or DosWrite.

To implement a file format IOProc for translation mode, and provide support for the MMIO_TRANSLATEDATA flag, additional code is required for the MMIOM_READ and MMIOM_WRITE message processing. During read processing, after data is read from the file to a private buffer in its native encoding format, the data must be translated from its native encoding scheme to the standard presentation format encoding scheme for its media type. The translated data is then presented to the application in its read buffer. Likewise, for write processing, data is received from the application in the standard presentation format, and must be translated to its native encoding scheme before being written to the file.

The following example shows an example of how the M-Motion IOProc supports the MMIOM_READ and MMIOM_WRITE messages.

case MMIOM_READ:
     {
     /************************************************************
      * Declare Local Variables
      ************************************************************/
     PMMFILESTATUS   pVidInfo;
     LONG            rc;
     LONG            lBytesToRead;

     /************************************************************
      * Check for valid MMIOINFO block.
      ************************************************************/
     if (!pmmioinfo)
         return (MMIO_ERROR);

     /************************************************************
      * Set up our working file status variable.
      ************************************************************/
     pVidInfo = (PMMFILESTATUS)pmmioinfo->pExtraInfoStruct;

     /************************************************************
      * Is Translate Data off?
      ************************************************************/
     if (!(pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA))
         {
         /********************************************************
          * Since no translation, provide exact number of bytes req.
          ********************************************************/
         if (!lParam1)
             return (MMIO_ERROR);

         rc = mmioRead (pVidInfo->hmmioSS,
                        (PVOID) lParam1,
                        (ULONG) lParam2);

         return (rc);
         }

     /************************************************************
      * Otherwise, Translate Data is on...
      ************************************************************/

     /************************************************************
      * Ensure we do NOT write more data out than is remaining
      *    in the buffer.  The length of read was requested in
      *    image bytes, so confirm that there are that many of
      *    virtual bytes remaining.
      ************************************************************/
     if ((ULONG)(pVidInfo->lImgBytePos + lParam2) >
          pVidInfo->ulImgTotalBytes)
        lBytesToRead =
            pVidInfo->ulImgTotalBytes - pVidInfo->lImgBytePos;
     else
        lBytesToRead = (ULONG)lParam2;

     /************************************************************
      * Perform this block on ALL reads.  The image data should
      * be in the RGB buffer at this point, and can be handed
      * to the application.
      *
      * Conveniently, the virtual image position is the same
      *    as the RGB buffer position, since both are 24 bit-RGB
      ************************************************************/
     memcpy ((PVOID)lParam1,
             &(pVidInfo->lpRGBBuf[pVidInfo->lImgBytePos]),
             lBytesToRead);

     /************************************************************
      * Move RGB buffer pointer forward by number of bytes read.
      * The Img buffer pos is identical since both are 24 bits.
      ************************************************************/
     pVidInfo->lImgBytePos += lBytesToRead;

     return (lBytesToRead);
     }   /* end case  of MMIOM_READ */

 case MMIOM_WRITE:
      {
      /************************************************************
       * Declare Local Variables.
       ************************************************************/
      PMMFILESTATUS       pVidInfo;
      USHORT              usBitCount;
      LONG                lBytesWritten;
      ULONG               ulImgBytesToWrite;

      /************************************************************
       * Check for valid MMIOINFO block.
       ************************************************************/
      if (!pmmioinfo)
          return (MMIO_ERROR);

      /************************************************************
       * Set up our working variable MMFILESTATUS.
       ************************************************************/
      pVidInfo = (PMMFILESTATUS) pmmioinfo->pExtraInfoStruct;

      /************************************************************
       * See if a SetHeader has been done on this file.
       ************************************************************/
      if ((!pVidInfo) || (!pVidInfo->bSetHeader))
          {
          return (MMIO_ERROR);
          }

      if (!(pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA))
          {
          /********************************************************
           * Translation is off, take amount of bytes sent and
           * write to the file.
           ********************************************************
           * Ensure that there is a data buffer to write from.
           ********************************************************/
          if (!lParam1)
              return (MMIO_ERROR);

          lBytesWritten = mmioWrite (pVidInfo->hmmioSS,
                                     (PVOID) lParam1,
                                     (ULONG) lParam2);

          return (lBytesWritten);
          }

      /************************************************************
       * Translation is on.
       ************************************************************
       * Set up local variables.
       ************************************************************/
      usBitCount =
         pVidInfo->mmImgHdr.mmXDIBHeader.BMPInfoHeader2.cBitCount;


      /************************************************************
       * Ensure we do not attempt to write past the end of the
       *    buffer...
       ************************************************************/
      if ((ULONG)(pVidInfo->lImgBytePos + lParam2) >
         pVidInfo->ulImgTotalBytes)
         ulImgBytesToWrite =
             pVidInfo->ulImgTotalBytes - pVidInfo->lImgBytePos;
      else
         ulImgBytesToWrite = (ULONG)lParam2;

      /************************************************************
       * Write the data into the image buffer.  It will be converted to
       *   RGB, then YUV  when the file is closed.  This allows the
       *   application to seek to arbitrary  positions within the
       *   image in terms of the bits/pel, etc they are writing.
       ************************************************************/
      memcpy (&(pVidInfo->lpImgBuf[pVidInfo->lImgBytePos]),
              (PVOID)lParam1,
              ulImgBytesToWrite);

      /* Update current position in the image buffer */
      pVidInfo->lImgBytePos += ulImgBytesToWrite;

      return (ulImgBytesToWrite);
      }   /* end case of MMIOM_WRITE */

  /*
   * If the IOProc has a child IOProc, then pass the message
   *  on to the Child, otherwise return Unsupported Message
   */
  default:
      {
       /*
        * Declare Local Variables.
        */
       PMMFILESTATUS       pVidInfo;
       LONG                lRC;

       /************************************************************
        * Check for valid MMIOINFO block.
        ************************************************************/
       if (!pmmioinfo)
           return (MMIO_ERROR);

       /************************************************************
        * Set up our working variable MMFILESTATUS.
        ************************************************************/
       pVidInfo = (PMMFILESTATUS) pmmioinfo->pExtraInfoStruct;

       if (pVidInfo != NULL && pVidInfo->hmmioSS)
          {
           lRC = mmioSendMessage (pVidInfo->hmmioSS,
                                  usMsg,
                                  lParam1,
                                  lParam2);
           if (!lRC)
              pmmioinfo->ulErrorRet = mmioGetLastError (pVidInfo->hmmioSS);
           return (lRC);
          }
      else
         {
          if (pmmioinfo != NULL)
             pmmioinfo->ulErrorRet = MMIOERR_UNSUPPORTED_MESSAGE;
          return (MMIOERR_UNSUPPORTED_MESSAGE);
         }

      }   /* end case of Default */

  } /* end SWITCH statement for MMIO messages */

return (0);
}      /* end of window procedure */


[Back] [Next]