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.

339 lines
7.8 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 - 1995 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 <vfw.h>
  18. #include "avifilei.h"
  19. #include "avimem.h"
  20. #define WIDTHBYTES(i) ((UINT)((i+31)&(~31))/8)
  21. #define DIBWIDTHBYTES(lpbi) (UINT)WIDTHBYTES((UINT)(lpbi)->biWidth * (UINT)(lpbi)->biBitCount)
  22. STDAPI AVIMakeStreamFromClipboard(UINT cfFormat, HANDLE hGlobal, PAVISTREAM FAR *ppstream)
  23. {
  24. CAVIMemStream FAR* pAVIStream;
  25. HRESULT hr;
  26. LPVOID lp;
  27. if (cfFormat != CF_DIB && cfFormat != CF_WAVE)
  28. return ResultFromScode(AVIERR_UNSUPPORTED);
  29. pAVIStream = new FAR CAVIMemStream();
  30. if (!pAVIStream)
  31. return ResultFromScode(E_OUTOFMEMORY);
  32. lp = GlobalAllocPtr(GMEM_MOVEABLE, GlobalSize(hGlobal));
  33. if (!lp)
  34. return ResultFromScode(E_OUTOFMEMORY);
  35. hmemcpy(lp, GlobalLock(hGlobal), GlobalSize(hGlobal));
  36. pAVIStream->Create((LPARAM) cfFormat, (LPARAM) lp);
  37. GlobalUnlock(hGlobal);
  38. hr = pAVIStream->QueryInterface(IID_IAVIStream, (LPVOID FAR *) ppstream);
  39. if (FAILED(GetScode(hr)))
  40. delete pAVIStream;
  41. return hr;
  42. }
  43. /* - - - - - - - - */
  44. CAVIMemStream::CAVIMemStream()
  45. {
  46. m_lpData = NULL;
  47. m_lpMemory = NULL;
  48. m_lpFormat = NULL;
  49. m_refs = 0;
  50. }
  51. /* - - - - - - - - */
  52. STDMETHODIMP CAVIMemStream::QueryInterface(
  53. const IID FAR& iid,
  54. void FAR* FAR* ppv)
  55. {
  56. if (iid == IID_IUnknown)
  57. *ppv = this;
  58. else if (iid == IID_IAVIStream)
  59. *ppv = this;
  60. else {
  61. *ppv = NULL;
  62. return ResultFromScode(E_NOINTERFACE);
  63. }
  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(LPARAM lParam1, LPARAM 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(AVISTREAMINFOW 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. if (lpBuffer) {
  184. hmemcpy(lpBuffer,
  185. (BYTE _huge *) m_lpData + lStart * m_avistream.dwSampleSize,
  186. lSamples * m_avistream.dwSampleSize);
  187. if (cbBuffer < (LONG) m_avistream.dwSampleSize)
  188. return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  189. }
  190. } else {
  191. if (plBytes)
  192. *plBytes = m_cbData;
  193. if (plSamples)
  194. *plSamples = 1;
  195. if (lpBuffer) {
  196. hmemcpy(lpBuffer, m_lpData, min(cbBuffer, m_cbData));
  197. if (cbBuffer < m_cbData)
  198. return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  199. }
  200. }
  201. return AVIERR_OK;
  202. }
  203. STDMETHODIMP_(LONG) CAVIMemStream::FindSample(LONG lPos, LONG lFlags)
  204. {
  205. if (lFlags & FIND_FORMAT) {
  206. if (lFlags & FIND_PREV)
  207. return 0;
  208. else {
  209. if (lPos > 0)
  210. return -1;
  211. else
  212. return 0;
  213. }
  214. }
  215. return lPos;
  216. }
  217. STDMETHODIMP CAVIMemStream::SetFormat(LONG lPos,LPVOID lpFormat,LONG cbFormat)
  218. {
  219. return ResultFromScode(AVIERR_UNSUPPORTED);
  220. }
  221. STDMETHODIMP CAVIMemStream::Write(LONG lStart,
  222. LONG lSamples,
  223. LPVOID lpBuffer,
  224. LONG cbBuffer,
  225. DWORD dwFlags,
  226. LONG FAR *plSampWritten,
  227. LONG FAR *plBytesWritten)
  228. {
  229. return ResultFromScode(AVIERR_UNSUPPORTED);
  230. }
  231. STDMETHODIMP CAVIMemStream::Delete(LONG lStart,LONG lSamples)
  232. {
  233. return ResultFromScode(AVIERR_UNSUPPORTED);
  234. }
  235. STDMETHODIMP CAVIMemStream::ReadData(DWORD fcc, LPVOID lp, LONG FAR *lpcb)
  236. {
  237. return ResultFromScode(AVIERR_UNSUPPORTED);
  238. }
  239. STDMETHODIMP CAVIMemStream::WriteData(DWORD fcc, LPVOID lp, LONG cb)
  240. {
  241. return ResultFromScode(AVIERR_UNSUPPORTED);
  242. }
  243. #if 0
  244. STDMETHODIMP CAVIMemStream::Clone(PAVISTREAM FAR * ppaviNew)
  245. {
  246. return ResultFromScode(AVIERR_UNSUPPORTED);
  247. }
  248. #endif
  249. #ifdef _WIN32
  250. STDMETHODIMP CAVIMemStream::SetInfo(AVISTREAMINFOW FAR *lpInfo, LONG cbInfo)
  251. {
  252. return ResultFromScode(AVIERR_UNSUPPORTED);
  253. }
  254. #else
  255. STDMETHODIMP CAVIMemStream::Reserved1(void)
  256. {
  257. return ResultFromScode(AVIERR_UNSUPPORTED);
  258. }
  259. STDMETHODIMP CAVIMemStream::Reserved2(void)
  260. {
  261. return ResultFromScode(AVIERR_UNSUPPORTED);
  262. }
  263. STDMETHODIMP CAVIMemStream::Reserved3(void)
  264. {
  265. return ResultFromScode(AVIERR_UNSUPPORTED);
  266. }
  267. STDMETHODIMP CAVIMemStream::Reserved4(void)
  268. {
  269. return ResultFromScode(AVIERR_UNSUPPORTED);
  270. }
  271. STDMETHODIMP CAVIMemStream::Reserved5(void)
  272. {
  273. return ResultFromScode(AVIERR_UNSUPPORTED);
  274. }
  275. #endif