Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
7.6 KiB

  1. /****************************************************************************
  2. *
  3. * AVIMEM.C
  4. *
  5. * routine for putting a stream interface on top of data in memory
  6. *
  7. * Copyright (c) 1992 Microsoft Corporation. All Rights Reserved.
  8. *
  9. * You have a royalty-free right to use, modify, reproduce and
  10. * distribute the Sample Files (and/or any modified version) in
  11. * any way you find useful, provided that you agree that
  12. * Microsoft has no warranty obligations or liability for any
  13. * Sample Application Files which are modified.
  14. *
  15. ***************************************************************************/
  16. #include <win32.h>
  17. #include <compman.h>
  18. #include <compobj.h>
  19. #include <avifmt.h>
  20. #include "avifile.h"
  21. #include "avifilei.h"
  22. #include "avimem.h"
  23. #define WIDTHBYTES(i) ((UINT)((i+31)&(~31))/8)
  24. #define DIBWIDTHBYTES(lpbi) (UINT)WIDTHBYTES((UINT)(lpbi)->biWidth * (UINT)(lpbi)->biBitCount)
  25. STDAPI AVIMakeStreamFromClipboard(UINT cfFormat, HANDLE hGlobal, PAVISTREAM FAR *ppstream)
  26. {
  27. CAVIMemStream FAR* pAVIStream;
  28. HRESULT hr;
  29. LPVOID lp;
  30. if (cfFormat != CF_DIB && cfFormat != CF_WAVE)
  31. return ResultFromScode(AVIERR_UNSUPPORTED);
  32. pAVIStream = new FAR CAVIMemStream();
  33. if (!pAVIStream)
  34. return ResultFromScode(E_OUTOFMEMORY);
  35. lp = GlobalAllocPtr(GMEM_MOVEABLE, GlobalSize(hGlobal));
  36. if (!lp)
  37. return ResultFromScode(E_OUTOFMEMORY);
  38. hmemcpy(lp, GlobalLock(hGlobal), GlobalSize(hGlobal));
  39. pAVIStream->Create((LONG) cfFormat, (LONG) lp);
  40. hr = pAVIStream->QueryInterface(IID_IAVIStream, (LPVOID FAR *) ppstream);
  41. if (FAILED(GetScode(hr)))
  42. delete pAVIStream;
  43. return hr;
  44. }
  45. /* - - - - - - - - */
  46. CAVIMemStream::CAVIMemStream()
  47. {
  48. m_lpData = NULL;
  49. m_lpMemory = NULL;
  50. m_lpFormat = NULL;
  51. m_refs = 0;
  52. }
  53. /* - - - - - - - - */
  54. STDMETHODIMP CAVIMemStream::QueryInterface(
  55. const IID FAR& iid,
  56. void FAR* FAR* ppv)
  57. {
  58. if (iid == IID_IUnknown)
  59. *ppv = this;
  60. else if (iid == IID_IAVIStream)
  61. *ppv = this;
  62. else
  63. return ResultFromScode(E_NOINTERFACE);
  64. AddRef();
  65. return AVIERR_OK;
  66. }
  67. /* - - - - - - - - */
  68. STDMETHODIMP_(ULONG) CAVIMemStream::AddRef()
  69. {
  70. uUseCount++;
  71. return ++m_refs;
  72. }
  73. /* - - - - - - - - */
  74. STDMETHODIMP CAVIMemStream::Create(LONG lParam1, LONG lParam2)
  75. {
  76. UINT cfFormat = (UINT) lParam1;
  77. m_lpMemory = (LPVOID) lParam2;
  78. if (cfFormat == CF_DIB) {
  79. LPBITMAPINFOHEADER lpbi;
  80. m_lpFormat = m_lpMemory;
  81. lpbi = (LPBITMAPINFOHEADER) m_lpFormat;
  82. if (lpbi->biSizeImage == 0) {
  83. if (lpbi->biCompression = BI_RGB) {
  84. lpbi->biSizeImage = DIBWIDTHBYTES(lpbi) *
  85. lpbi->biHeight;
  86. }
  87. }
  88. _fmemset(&m_avistream, 0, sizeof(m_avistream));
  89. m_avistream.fccType = streamtypeVIDEO;
  90. m_avistream.fccHandler = 0;
  91. m_avistream.dwStart = 0;
  92. m_avistream.dwLength = 1;
  93. m_avistream.dwScale = 1;
  94. m_avistream.dwRate = 15;
  95. m_avistream.dwSampleSize = 0;
  96. SetRect(&m_avistream.rcFrame, 0, 0,
  97. (int) lpbi->biWidth,
  98. (int) lpbi->biHeight);
  99. m_cbFormat = lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
  100. m_lpData = (LPBYTE) m_lpMemory + m_cbFormat;
  101. m_cbData = lpbi->biSizeImage;
  102. } else if (cfFormat == CF_WAVE) {
  103. DWORD _huge * lpdw;
  104. LPWAVEFORMAT lpwf;
  105. #define ckidWAVEFORMAT mmioFOURCC('f', 'm', 't', ' ')
  106. #define ckidWAVEDATA mmioFOURCC('d', 'a', 't', 'a')
  107. lpdw = (DWORD _huge *) ((LPBYTE) m_lpMemory + 12);
  108. while (*lpdw != ckidWAVEFORMAT)
  109. lpdw = (DWORD _huge *)
  110. (((BYTE _huge *) lpdw) + lpdw[1] + sizeof(DWORD) * 2);
  111. m_lpFormat = (LPBYTE) (lpdw + 2);
  112. m_cbFormat = lpdw[1];
  113. do {
  114. lpdw = (DWORD _huge *)
  115. (((BYTE _huge *) lpdw) + lpdw[1] + sizeof(DWORD) * 2);
  116. } while (*lpdw != ckidWAVEDATA);
  117. m_lpData = (LPBYTE) (lpdw + 2);
  118. m_cbData = lpdw[1];
  119. lpwf = (LPWAVEFORMAT) m_lpFormat;
  120. _fmemset(&m_avistream, 0, sizeof(m_avistream));
  121. m_avistream.fccType = streamtypeAUDIO;
  122. m_avistream.fccHandler = 0;
  123. m_avistream.dwStart = 0;
  124. m_avistream.dwSampleSize = lpwf->nBlockAlign;
  125. m_avistream.dwLength = m_cbData / m_avistream.dwSampleSize;
  126. m_avistream.dwScale = lpwf->nBlockAlign;
  127. m_avistream.dwRate = lpwf->nAvgBytesPerSec;
  128. }
  129. return 0;
  130. }
  131. STDMETHODIMP_(ULONG) CAVIMemStream::Release()
  132. {
  133. uUseCount--;
  134. if (!--m_refs) {
  135. if (m_lpMemory) {
  136. GlobalFreePtr(m_lpMemory);
  137. }
  138. delete this;
  139. return 0;
  140. }
  141. return m_refs;
  142. }
  143. STDMETHODIMP CAVIMemStream::Info(AVISTREAMINFO FAR * psi, LONG lSize)
  144. {
  145. hmemcpy(psi, &m_avistream, min(lSize, sizeof(m_avistream)));
  146. // return sizeof(m_avistream);
  147. return ResultFromScode(0);
  148. }
  149. STDMETHODIMP CAVIMemStream::ReadFormat(LONG lPos, LPVOID lpFormat, LONG FAR *lpcbFormat)
  150. {
  151. if (lpFormat) {
  152. hmemcpy(lpFormat, m_lpFormat, min(*lpcbFormat, (LONG) m_cbFormat));
  153. }
  154. *lpcbFormat = m_cbFormat;
  155. return AVIERR_OK;
  156. }
  157. STDMETHODIMP CAVIMemStream::Read(
  158. LONG lStart,
  159. LONG lSamples,
  160. LPVOID lpBuffer,
  161. LONG cbBuffer,
  162. LONG FAR * plBytes,
  163. LONG FAR * plSamples)
  164. {
  165. // !!! CONVENIENT?
  166. if (lStart + lSamples > (LONG) m_avistream.dwLength)
  167. lSamples = (LONG) m_avistream.dwLength - lStart;
  168. if (lSamples == 0 || lStart >= (LONG) m_avistream.dwLength) {
  169. if (plBytes)
  170. *plBytes = 0;
  171. if (plSamples)
  172. *plSamples = 0;
  173. }
  174. if (m_avistream.dwSampleSize) {
  175. if (lSamples > 0)
  176. lSamples = min(lSamples, cbBuffer / (LONG) m_avistream.dwSampleSize);
  177. else
  178. lSamples = cbBuffer / m_avistream.dwSampleSize;
  179. if (plBytes)
  180. *plBytes = lSamples * m_avistream.dwSampleSize;
  181. if (plSamples)
  182. *plSamples = lSamples;
  183. hmemcpy(lpBuffer,
  184. (BYTE _huge *) m_lpData + lStart * m_avistream.dwSampleSize,
  185. lSamples * m_avistream.dwSampleSize);
  186. if (cbBuffer < (LONG) m_avistream.dwSampleSize)
  187. return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  188. } else {
  189. if (plBytes)
  190. *plBytes = m_cbData;
  191. if (plSamples)
  192. *plSamples = 1;
  193. if (lpBuffer) {
  194. hmemcpy(lpBuffer, m_lpData, min(cbBuffer, m_cbData));
  195. if (cbBuffer < m_cbData)
  196. return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  197. }
  198. }
  199. return AVIERR_OK;
  200. }
  201. STDMETHODIMP_(LONG) CAVIMemStream::FindSample(LONG lPos, LONG lFlags)
  202. {
  203. if (lFlags & FIND_FORMAT) {
  204. if (lFlags & FIND_PREV)
  205. return 0;
  206. else {
  207. if (lPos > 0)
  208. return -1;
  209. else
  210. return 0;
  211. }
  212. }
  213. return lPos;
  214. }
  215. STDMETHODIMP CAVIMemStream::SetFormat(LONG lPos,LPVOID lpFormat,LONG cbFormat)
  216. {
  217. return ResultFromScode(AVIERR_UNSUPPORTED);
  218. }
  219. STDMETHODIMP CAVIMemStream::Write(LONG lStart,
  220. LONG lSamples,
  221. LPVOID lpBuffer,
  222. LONG cbBuffer,
  223. DWORD dwFlags,
  224. LONG FAR *plSampWritten,
  225. LONG FAR *plBytesWritten)
  226. {
  227. return ResultFromScode(AVIERR_UNSUPPORTED);
  228. }
  229. STDMETHODIMP CAVIMemStream::Delete(LONG lStart,LONG lSamples)
  230. {
  231. return ResultFromScode(AVIERR_UNSUPPORTED);
  232. }
  233. STDMETHODIMP CAVIMemStream::ReadData(DWORD fcc, LPVOID lp, LONG FAR *lpcb)
  234. {
  235. return ResultFromScode(AVIERR_UNSUPPORTED);
  236. }
  237. STDMETHODIMP CAVIMemStream::WriteData(DWORD fcc, LPVOID lp, LONG cb)
  238. {
  239. return ResultFromScode(AVIERR_UNSUPPORTED);
  240. }
  241. #if 0
  242. STDMETHODIMP CAVIMemStream::Clone(PAVISTREAM FAR * ppaviNew)
  243. {
  244. return ResultFromScode(AVIERR_UNSUPPORTED);
  245. }
  246. #endif
  247. STDMETHODIMP CAVIMemStream::Reserved1(void)
  248. {
  249. return ResultFromScode(AVIERR_UNSUPPORTED);
  250. }
  251. STDMETHODIMP CAVIMemStream::Reserved2(void)
  252. {
  253. return ResultFromScode(AVIERR_UNSUPPORTED);
  254. }
  255. STDMETHODIMP CAVIMemStream::Reserved3(void)
  256. {
  257. return ResultFromScode(AVIERR_UNSUPPORTED);
  258. }
  259. STDMETHODIMP CAVIMemStream::Reserved4(void)
  260. {
  261. return ResultFromScode(AVIERR_UNSUPPORTED);
  262. }
  263. STDMETHODIMP CAVIMemStream::Reserved5(void)
  264. {
  265. return ResultFromScode(AVIERR_UNSUPPORTED);
  266. }