|
|
/****************************************************************************
* * AVIMEM.C * * routine for putting a stream interface on top of data in memory * * Copyright (c) 1992 - 1995 Microsoft Corporation. All Rights Reserved. * * You have a royalty-free right to use, modify, reproduce and * distribute the Sample Files (and/or any modified version) in * any way you find useful, provided that you agree that * Microsoft has no warranty obligations or liability for any * Sample Application Files which are modified. * ***************************************************************************/
#include <win32.h>
#include <vfw.h>
#include "avifilei.h"
#include "avimem.h"
#define WIDTHBYTES(i) ((UINT)((i+31)&(~31))/8)
#define DIBWIDTHBYTES(lpbi) (UINT)WIDTHBYTES((UINT)(lpbi)->biWidth * (UINT)(lpbi)->biBitCount)
STDAPI AVIMakeStreamFromClipboard(UINT cfFormat, HANDLE hGlobal, PAVISTREAM FAR *ppstream) { CAVIMemStream FAR* pAVIStream; HRESULT hr; LPVOID lp;
if (cfFormat != CF_DIB && cfFormat != CF_WAVE) return ResultFromScode(AVIERR_UNSUPPORTED);
pAVIStream = new FAR CAVIMemStream(); if (!pAVIStream) return ResultFromScode(E_OUTOFMEMORY);
lp = GlobalAllocPtr(GMEM_MOVEABLE, GlobalSize(hGlobal)); if (!lp) return ResultFromScode(E_OUTOFMEMORY);
hmemcpy(lp, GlobalLock(hGlobal), GlobalSize(hGlobal)); pAVIStream->Create((LPARAM) cfFormat, (LPARAM) lp);
GlobalUnlock(hGlobal);
hr = pAVIStream->QueryInterface(IID_IAVIStream, (LPVOID FAR *) ppstream); if (FAILED(GetScode(hr))) delete pAVIStream; return hr; }
/* - - - - - - - - */
CAVIMemStream::CAVIMemStream() { m_lpData = NULL; m_lpMemory = NULL; m_lpFormat = NULL; m_refs = 0; }
/* - - - - - - - - */
STDMETHODIMP CAVIMemStream::QueryInterface( const IID FAR& iid, void FAR* FAR* ppv) { if (iid == IID_IUnknown) *ppv = this; else if (iid == IID_IAVIStream) *ppv = this; else { *ppv = NULL; return ResultFromScode(E_NOINTERFACE); } AddRef(); return AVIERR_OK; }
/* - - - - - - - - */
STDMETHODIMP_(ULONG) CAVIMemStream::AddRef() { uUseCount++; return ++m_refs; }
/* - - - - - - - - */
STDMETHODIMP CAVIMemStream::Create(LPARAM lParam1, LPARAM lParam2) { UINT cfFormat = (UINT) lParam1; m_lpMemory = (LPVOID) lParam2;
if (cfFormat == CF_DIB) { LPBITMAPINFOHEADER lpbi; m_lpFormat = m_lpMemory; lpbi = (LPBITMAPINFOHEADER) m_lpFormat;
if (lpbi->biSizeImage == 0) { if (lpbi->biCompression = BI_RGB) { lpbi->biSizeImage = DIBWIDTHBYTES(lpbi) * lpbi->biHeight; } }
_fmemset(&m_avistream, 0, sizeof(m_avistream)); m_avistream.fccType = streamtypeVIDEO; m_avistream.fccHandler = 0; m_avistream.dwStart = 0; m_avistream.dwLength = 1; m_avistream.dwScale = 1; m_avistream.dwRate = 15; m_avistream.dwSampleSize = 0; SetRect(&m_avistream.rcFrame, 0, 0, (int) lpbi->biWidth, (int) lpbi->biHeight); m_cbFormat = lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD); m_lpData = (LPBYTE) m_lpMemory + m_cbFormat; m_cbData = lpbi->biSizeImage; } else if (cfFormat == CF_WAVE) { DWORD _huge * lpdw; LPWAVEFORMAT lpwf; #define ckidWAVEFORMAT mmioFOURCC('f', 'm', 't', ' ')
#define ckidWAVEDATA mmioFOURCC('d', 'a', 't', 'a')
lpdw = (DWORD _huge *) ((LPBYTE) m_lpMemory + 12);
while (*lpdw != ckidWAVEFORMAT) lpdw = (DWORD _huge *) (((BYTE _huge *) lpdw) + lpdw[1] + sizeof(DWORD) * 2); m_lpFormat = (LPBYTE) (lpdw + 2); m_cbFormat = lpdw[1];
do { lpdw = (DWORD _huge *) (((BYTE _huge *) lpdw) + lpdw[1] + sizeof(DWORD) * 2); } while (*lpdw != ckidWAVEDATA); m_lpData = (LPBYTE) (lpdw + 2); m_cbData = lpdw[1];
lpwf = (LPWAVEFORMAT) m_lpFormat; _fmemset(&m_avistream, 0, sizeof(m_avistream)); m_avistream.fccType = streamtypeAUDIO; m_avistream.fccHandler = 0; m_avistream.dwStart = 0; m_avistream.dwSampleSize = lpwf->nBlockAlign; m_avistream.dwLength = m_cbData / m_avistream.dwSampleSize; m_avistream.dwScale = lpwf->nBlockAlign; m_avistream.dwRate = lpwf->nAvgBytesPerSec; }
return 0; }
STDMETHODIMP_(ULONG) CAVIMemStream::Release() { uUseCount--; if (!--m_refs) { if (m_lpMemory) { GlobalFreePtr(m_lpMemory); }
delete this; return 0; }
return m_refs; }
STDMETHODIMP CAVIMemStream::Info(AVISTREAMINFOW FAR * psi, LONG lSize) { hmemcpy(psi, &m_avistream, min(lSize, sizeof(m_avistream)));
// return sizeof(m_avistream);
return ResultFromScode(0); }
STDMETHODIMP CAVIMemStream::ReadFormat(LONG lPos, LPVOID lpFormat, LONG FAR *lpcbFormat) { if (lpFormat) { hmemcpy(lpFormat, m_lpFormat, min(*lpcbFormat, (LONG) m_cbFormat)); }
*lpcbFormat = m_cbFormat; return AVIERR_OK; }
STDMETHODIMP CAVIMemStream::Read( LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG FAR * plBytes, LONG FAR * plSamples) { // !!! CONVENIENT?
if (lStart + lSamples > (LONG) m_avistream.dwLength) lSamples = (LONG) m_avistream.dwLength - lStart; if (lSamples == 0 || lStart >= (LONG) m_avistream.dwLength) { if (plBytes) *plBytes = 0; if (plSamples) *plSamples = 0; }
if (m_avistream.dwSampleSize) { if (lSamples > 0) lSamples = min(lSamples, cbBuffer / (LONG) m_avistream.dwSampleSize); else lSamples = cbBuffer / m_avistream.dwSampleSize;
if (plBytes) *plBytes = lSamples * m_avistream.dwSampleSize;
if (plSamples) *plSamples = lSamples;
if (lpBuffer) { hmemcpy(lpBuffer, (BYTE _huge *) m_lpData + lStart * m_avistream.dwSampleSize, lSamples * m_avistream.dwSampleSize); if (cbBuffer < (LONG) m_avistream.dwSampleSize) return ResultFromScode(AVIERR_BUFFERTOOSMALL); } } else { if (plBytes) *plBytes = m_cbData;
if (plSamples) *plSamples = 1; if (lpBuffer) { hmemcpy(lpBuffer, m_lpData, min(cbBuffer, m_cbData));
if (cbBuffer < m_cbData) return ResultFromScode(AVIERR_BUFFERTOOSMALL); } }
return AVIERR_OK; }
STDMETHODIMP_(LONG) CAVIMemStream::FindSample(LONG lPos, LONG lFlags) { if (lFlags & FIND_FORMAT) { if (lFlags & FIND_PREV) return 0; else { if (lPos > 0) return -1; else return 0; } } return lPos; }
STDMETHODIMP CAVIMemStream::SetFormat(LONG lPos,LPVOID lpFormat,LONG cbFormat) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::Write(LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG FAR *plSampWritten, LONG FAR *plBytesWritten) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::Delete(LONG lStart,LONG lSamples) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::ReadData(DWORD fcc, LPVOID lp, LONG FAR *lpcb) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::WriteData(DWORD fcc, LPVOID lp, LONG cb) { return ResultFromScode(AVIERR_UNSUPPORTED); }
#if 0
STDMETHODIMP CAVIMemStream::Clone(PAVISTREAM FAR * ppaviNew) { return ResultFromScode(AVIERR_UNSUPPORTED); }
#endif
#ifdef _WIN32
STDMETHODIMP CAVIMemStream::SetInfo(AVISTREAMINFOW FAR *lpInfo, LONG cbInfo) { return ResultFromScode(AVIERR_UNSUPPORTED); } #else
STDMETHODIMP CAVIMemStream::Reserved1(void) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::Reserved2(void) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::Reserved3(void) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::Reserved4(void) { return ResultFromScode(AVIERR_UNSUPPORTED); }
STDMETHODIMP CAVIMemStream::Reserved5(void) { return ResultFromScode(AVIERR_UNSUPPORTED); } #endif
|