EXTRA.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:4k
源码类别:

Windows编程

开发平台:

Visual C++

  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. #define   NOCOMPMAN
  20. #define   NODRAWDIB
  21. #define   NOVIDEO
  22. #define   NOAVIFMT
  23. #define   NOMMREG
  24. #define   NOMCIWND
  25. #define   NOAVICAP
  26. #define   NOMSACM
  27. #define INC_OLE2
  28. #include <windows.h>
  29. #include <windowsx.h>
  30. #include <mmsystem.h>
  31. #include <string.h>
  32. #include <stdarg.h>
  33. #include <vfw.h>
  34. #include "extra.h"
  35. //
  36. // Search the EXTRA chunks for a particular chunk ID and return it's data.
  37. //
  38. HRESULT ReadExtra(
  39. LPEXTRA extra,
  40. DWORD ckid,
  41. LPVOID lpData,
  42. LONG FAR *lpcbData)
  43. {
  44. #define lpdw ((DWORD FAR *) lp)
  45. LPBYTE lp = (LPBYTE) extra->lp;
  46. LONG cb = extra->cb;
  47. while (cb > 0) {
  48. if (lpdw[0] == ckid) {
  49. if (!lpData) {
  50. *lpcbData = lpdw[1];
  51. return AVIERR_OK;
  52. }
  53. hmemcpy(lpData, lp + 2 * sizeof(DWORD), min((LONG) lpdw[1], *lpcbData));
  54. *lpcbData = lpdw[1];
  55. return ResultFromScode(AVIERR_OK);
  56. }
  57. cb -= lpdw[1] + sizeof(DWORD) * 2;
  58. lp += lpdw[1] + sizeof(DWORD) * 2;
  59. }
  60. #undef lpdw
  61. *lpcbData = 0;
  62. return ResultFromScode(AVIERR_NODATA);
  63. }
  64. //
  65. // Write data for the given chunk ID into the extra data
  66. //
  67. HRESULT WriteExtra(
  68. LPEXTRA extra,
  69. DWORD ckid,
  70. LPVOID lpData,
  71. LONG cbData)
  72. {
  73. LPBYTE lp;
  74. cbData += sizeof(DWORD) * 2;
  75. if (extra->lp) {
  76. lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE);
  77. } else {
  78. lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE, cbData);
  79. }
  80. if (!lp)
  81. return ResultFromScode(AVIERR_MEMORY);
  82. // build RIFF chunk in block
  83. ((DWORD FAR *) (lp + extra->cb))[0] = ckid;
  84. ((DWORD FAR *) (lp + extra->cb))[1] = cbData - sizeof(DWORD) * 2;
  85. hmemcpy(lp + extra->cb + sizeof(DWORD) * 2,
  86. lpData,
  87. cbData - sizeof(DWORD) * 2);
  88. extra->lp = lp;
  89. extra->cb += cbData;
  90. return ResultFromScode(AVIERR_OK);
  91. }
  92. //
  93. // Reads the data from the given chunk into the EXTRA pile.
  94. //
  95. HRESULT ReadIntoExtra(
  96. LPEXTRA extra,
  97. HMMIO hmmio,
  98. MMCKINFO FAR * lpck)
  99. {
  100. LPBYTE lp;
  101. LONG cbData = lpck->cksize + sizeof(DWORD) * 2;
  102. if (extra->lp) {
  103. lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE);
  104. } else {
  105. lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE, cbData);
  106. }
  107. if (!lp)
  108. return ResultFromScode(AVIERR_MEMORY);
  109. // build RIFF chunk in block
  110. ((DWORD FAR *) (lp + extra->cb))[0] = lpck->ckid;
  111. ((DWORD FAR *) (lp + extra->cb))[1] = lpck->cksize;
  112. cbData += (cbData & 1);
  113. mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
  114. if (mmioRead(hmmio, (HPSTR) lp + extra->cb + sizeof(DWORD) * 2, lpck->cksize) !=
  115. (LONG) lpck->cksize)
  116. return ResultFromScode(AVIERR_FILEREAD);
  117. extra->lp = lp;
  118. extra->cb += cbData;
  119. return ResultFromScode(AVIERR_OK);
  120. }
  121. //
  122. // Look for a specific chunk.  Throw all of the extra stuff we didn't want
  123. // into the EXTRA pile.
  124. //
  125. LONG FindChunkAndKeepExtras(
  126. LPEXTRA extra, HMMIO hmmio,
  127. MMCKINFO FAR* lpck,
  128. MMCKINFO FAR* lpckParent,
  129. UINT uFlags)
  130. {
  131. FOURCC ckidFind; // chunk ID to find (or NULL)
  132. FOURCC fccTypeFind; // form/list type to find (or NULL)
  133. LONG lRet;
  134. /* figure out what chunk id and form/list type to search for */
  135. if (uFlags & MMIO_FINDCHUNK)
  136. ckidFind = lpck->ckid, fccTypeFind = 0;
  137. else if (uFlags & MMIO_FINDRIFF)
  138. ckidFind = FOURCC_RIFF, fccTypeFind = lpck->fccType;
  139. else if (uFlags & MMIO_FINDLIST)
  140. ckidFind = FOURCC_LIST, fccTypeFind = lpck->fccType;
  141. else
  142. ckidFind = fccTypeFind = (FOURCC) -1; // keep looking indefinitely
  143. for (;;) {
  144. lRet = mmioDescend(hmmio, lpck, lpckParent, 0);
  145. if (lRet) {
  146. if (uFlags == 0 && lRet == MMIOERR_CHUNKNOTFOUND)
  147. lRet = 0;
  148. return lRet;
  149. }
  150. if ((!ckidFind || lpck->ckid == ckidFind) &&
  151. (!fccTypeFind || lpck->fccType == fccTypeFind))
  152. return 0;
  153. lRet = (LONG) ReadIntoExtra(extra, hmmio, lpck);
  154. if (lRet != AVIERR_OK)
  155. return lRet;
  156. }
  157. }