home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / audio / wavefile / extra.c next >
C/C++ Source or Header  |  1997-10-05  |  5KB  |  187 lines

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (C) 1992 - 1997 Microsoft Corporation.  All Rights Reserved.
  9.  *
  10.  **************************************************************************/
  11. /****************************************************************************
  12.  *
  13.  *  EXTRA.C
  14.  *
  15.  *  Routines for reading and managing extra chunks in a RIFF file besides
  16.  *  the actual stream data.
  17.  *
  18.  ***************************************************************************/
  19.  
  20. #define   NOCOMPMAN
  21. #define   NODRAWDIB
  22. #define   NOVIDEO
  23. #define   NOAVIFMT
  24. #define   NOMMREG
  25. #define   NOMCIWND
  26. #define   NOAVICAP
  27. #define   NOMSACM
  28.  
  29. #define INC_OLE2
  30. #include <windows.h>
  31. #include <windowsx.h>
  32. #include <mmsystem.h>
  33. #include <string.h>
  34. #include <stdarg.h>
  35. #include <vfw.h>
  36.  
  37. #include "extra.h"
  38.  
  39. //
  40. // Search the EXTRA chunks for a particular chunk ID and return it's data.
  41. //
  42. HRESULT ReadExtra(
  43.     LPEXTRA extra,
  44.     DWORD ckid,
  45.     LPVOID lpData,
  46.     LONG FAR *lpcbData)
  47. {
  48.  
  49. #define lpdw ((DWORD FAR *) lp)
  50.  
  51.     LPBYTE lp = (LPBYTE) extra->lp;
  52.     LONG cb = extra->cb;
  53.  
  54.     while (cb > 0) {
  55.     if (lpdw[0] == ckid) {
  56.         if (!lpData) {
  57.             *lpcbData = lpdw[1];
  58.             return AVIERR_OK;
  59.         }
  60.  
  61.         hmemcpy(lpData, lp + 2 * sizeof(DWORD), min((LONG) lpdw[1], *lpcbData));
  62.         *lpcbData = lpdw[1];
  63.  
  64.         return ResultFromScode(AVIERR_OK);
  65.     }
  66.     cb -= lpdw[1] + sizeof(DWORD) * 2;
  67.     lp += lpdw[1] + sizeof(DWORD) * 2;
  68.     }
  69. #undef lpdw
  70.     *lpcbData = 0;
  71.     return ResultFromScode(AVIERR_NODATA);
  72. }
  73.  
  74. //
  75. // Write data for the given chunk ID into the extra data
  76. //
  77. HRESULT WriteExtra(
  78.     LPEXTRA extra,
  79.     DWORD ckid,
  80.     LPVOID lpData,
  81.     LONG cbData)
  82. {
  83.     LPBYTE lp;
  84.     
  85.     cbData += sizeof(DWORD) * 2;
  86.     if (extra->lp) {
  87.     lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE);
  88.     } else {
  89.     lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE, cbData);
  90.     }
  91.  
  92.     if (!lp)
  93.     return ResultFromScode(AVIERR_MEMORY);
  94.  
  95.     // build RIFF chunk in block
  96.     ((DWORD FAR *) (lp + extra->cb))[0] = ckid;
  97.     ((DWORD FAR *) (lp + extra->cb))[1] = cbData - sizeof(DWORD) * 2;
  98.     
  99.     hmemcpy(lp + extra->cb + sizeof(DWORD) * 2,
  100.         lpData,
  101.         cbData - sizeof(DWORD) * 2);
  102.     extra->lp = lp;
  103.     extra->cb += cbData;
  104.     
  105.     return ResultFromScode(AVIERR_OK);
  106. }
  107.  
  108. //
  109. // Reads the data from the given chunk into the EXTRA pile.
  110. //
  111. HRESULT ReadIntoExtra(
  112.     LPEXTRA extra,
  113.     HMMIO hmmio,
  114.     MMCKINFO FAR * lpck)
  115. {
  116.     LPBYTE    lp;
  117.     LONG    cbData = lpck->cksize + sizeof(DWORD) * 2;
  118.     
  119.     if (extra->lp) {
  120.     lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE);
  121.     } else {
  122.     lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE, cbData);
  123.     }
  124.  
  125.     if (!lp)
  126.     return ResultFromScode(AVIERR_MEMORY);
  127.  
  128.     // build RIFF chunk in block
  129.     ((DWORD FAR *) (lp + extra->cb))[0] = lpck->ckid;
  130.     ((DWORD FAR *) (lp + extra->cb))[1] = lpck->cksize;
  131.  
  132.     cbData += (cbData & 1);
  133.  
  134.     mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
  135.     if (mmioRead(hmmio, (HPSTR) lp + extra->cb + sizeof(DWORD) * 2, lpck->cksize) !=
  136.         (LONG) lpck->cksize)
  137.     return ResultFromScode(AVIERR_FILEREAD);
  138.     
  139.     extra->lp = lp;
  140.     extra->cb += cbData;
  141.     
  142.     return ResultFromScode(AVIERR_OK);
  143. }
  144.  
  145.  
  146. //
  147. // Look for a specific chunk.  Throw all of the extra stuff we didn't want
  148. // into the EXTRA pile.
  149. //
  150. LONG FindChunkAndKeepExtras(
  151.     LPEXTRA extra, HMMIO hmmio,
  152.     MMCKINFO FAR* lpck,
  153.     MMCKINFO FAR* lpckParent,
  154.     UINT uFlags)
  155. {
  156.     FOURCC        ckidFind;    // chunk ID to find (or NULL)
  157.     FOURCC        fccTypeFind;    // form/list type to find (or NULL)
  158.     LONG        lRet;
  159.  
  160.     /* figure out what chunk id and form/list type to search for */
  161.     if (uFlags & MMIO_FINDCHUNK)
  162.         ckidFind = lpck->ckid, fccTypeFind = 0;
  163.     else if (uFlags & MMIO_FINDRIFF)
  164.         ckidFind = FOURCC_RIFF, fccTypeFind = lpck->fccType;
  165.     else if (uFlags & MMIO_FINDLIST)
  166.         ckidFind = FOURCC_LIST, fccTypeFind = lpck->fccType;
  167.     else
  168.         ckidFind = fccTypeFind = (FOURCC) -1; // keep looking indefinitely
  169.     
  170.     for (;;) {
  171.         lRet = mmioDescend(hmmio, lpck, lpckParent, 0);
  172.         if (lRet) {
  173.             if (uFlags == 0 && lRet == MMIOERR_CHUNKNOTFOUND)
  174.                 lRet = 0;
  175.             return lRet;
  176.         }
  177.  
  178.         if ((!ckidFind || lpck->ckid == ckidFind) &&
  179.             (!fccTypeFind || lpck->fccType == fccTypeFind))
  180.             return 0;
  181.  
  182.         lRet = (LONG) ReadIntoExtra(extra, hmmio, lpck);
  183.         if (lRet != AVIERR_OK)
  184.             return lRet;
  185.     }
  186. }
  187.