Leaked source code of windows server 2003
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.

315 lines
6.7 KiB

  1. /****************************************************************************
  2. *
  3. * (C) COPYRIGHT 2000, MICROSOFT CORP.
  4. *
  5. * FILE: CImageStream.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * DATE: 11/8/2000
  10. *
  11. * AUTHOR: Dave Parsons
  12. *
  13. * DESCRIPTION:
  14. * Implements a special IStream, which can be used with GDI+ image
  15. * format conversions.
  16. *
  17. *****************************************************************************/
  18. #include "pch.h"
  19. CImageStream::CImageStream() :
  20. m_pBuffer(NULL),
  21. m_iSize(0),
  22. m_iPosition(0),
  23. m_iOffset(0),
  24. m_cRef(1)
  25. {
  26. }
  27. CImageStream::~CImageStream()
  28. {
  29. }
  30. STDMETHODIMP CImageStream::SetBuffer(BYTE *pBuffer, INT iSize, SKIP_AMOUNT iSkipAmt)
  31. {
  32. HRESULT hr = S_OK;
  33. REQUIRE_ARGS(!pBuffer, hr, "SetBuffer");
  34. // wiauDbgDump("SetBuffer", "Buffer set to size %d bytes", iSize);
  35. m_pBuffer = pBuffer;
  36. m_iSize = iSize;
  37. m_iPosition = 0;
  38. switch (iSkipAmt) {
  39. case SKIP_OFF:
  40. m_iOffset = 0;
  41. break;
  42. case SKIP_FILEHDR:
  43. m_iOffset = sizeof(BITMAPFILEHEADER);
  44. break;
  45. case SKIP_BOTHHDR:
  46. m_iOffset = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  47. break;
  48. default:
  49. m_iOffset = 0;
  50. break;
  51. }
  52. memset(&m_Header, 0, sizeof(m_Header));
  53. Cleanup:
  54. return hr;
  55. }
  56. STDMETHODIMP CImageStream::QueryInterface(REFIID riid, void **ppvObject)
  57. {
  58. if (ppvObject == 0)
  59. {
  60. return E_POINTER;
  61. }
  62. if (riid == IID_IUnknown)
  63. {
  64. AddRef();
  65. *ppvObject = (IUnknown*) this;
  66. return S_OK;
  67. }
  68. if (riid == IID_IStream)
  69. {
  70. AddRef();
  71. *ppvObject = (IStream *) this;
  72. return S_OK;
  73. }
  74. *ppvObject = 0;
  75. return E_NOINTERFACE;
  76. }
  77. ULONG CImageStream::AddRef(VOID)
  78. {
  79. return InterlockedIncrement(&m_cRef);
  80. }
  81. ULONG CImageStream::Release(VOID)
  82. {
  83. ULONG result;
  84. result = InterlockedDecrement(&m_cRef);
  85. if(result == 0) {
  86. delete this;
  87. }
  88. return result;
  89. }
  90. STDMETHODIMP CImageStream::Read(void *pv, ULONG cb, ULONG *pcbRead)
  91. {
  92. HRESULT hr = S_OK;
  93. // wiauDbgDump("Read", "Reading %d bytes from buffer", cb);
  94. if (pcbRead)
  95. {
  96. *pcbRead = 0;
  97. }
  98. if (cb > 0)
  99. {
  100. if (m_iPosition >= m_iOffset + m_iSize)
  101. {
  102. wiauDbgError("Read", "Attempting to read past end of buffer");
  103. hr = S_FALSE;
  104. goto Cleanup;
  105. }
  106. if ((INT) cb > m_iOffset + m_iSize - m_iPosition)
  107. {
  108. hr = S_FALSE;
  109. cb = m_iOffset + m_iSize - m_iPosition;
  110. }
  111. if (m_iPosition < m_iOffset)
  112. {
  113. INT iBytesToReadInHeader = min((INT) cb, m_iOffset - m_iPosition);
  114. memcpy(pv, &m_Header + m_iPosition, iBytesToReadInHeader);
  115. pv = (PBYTE) pv + iBytesToReadInHeader;
  116. cb -= iBytesToReadInHeader;
  117. m_iPosition += iBytesToReadInHeader;
  118. if (pcbRead)
  119. {
  120. *pcbRead += iBytesToReadInHeader;
  121. }
  122. }
  123. if (cb > 0)
  124. {
  125. memcpy(pv, m_pBuffer + m_iPosition - m_iOffset, cb);
  126. m_iPosition += cb;
  127. if (pcbRead)
  128. {
  129. *pcbRead += cb;
  130. }
  131. }
  132. }
  133. Cleanup:
  134. return hr;
  135. }
  136. STDMETHODIMP CImageStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
  137. {
  138. HRESULT hr = S_OK;
  139. // wiauDbgDump("Write", "Writing %d bytes into buffer", cb);
  140. if (pcbWritten)
  141. {
  142. *pcbWritten = 0;
  143. }
  144. if (cb > 0)
  145. {
  146. if (m_iPosition >= m_iOffset + m_iSize)
  147. {
  148. wiauDbgError("Write", "Attempting to write past end of buffer");
  149. hr = S_FALSE;
  150. goto Cleanup;
  151. }
  152. if ((INT) cb > m_iOffset + m_iSize - m_iPosition)
  153. {
  154. hr = S_FALSE;
  155. cb = m_iOffset + m_iSize - m_iPosition;
  156. }
  157. if (m_iPosition < m_iOffset)
  158. {
  159. INT iBytesToWriteInHeader = min((INT) cb, m_iOffset - m_iPosition);
  160. memcpy((PBYTE) &m_Header + m_iPosition, pv, iBytesToWriteInHeader);
  161. pv = (PBYTE) pv + iBytesToWriteInHeader;
  162. cb -= iBytesToWriteInHeader;
  163. m_iPosition += iBytesToWriteInHeader;
  164. if (pcbWritten)
  165. {
  166. *pcbWritten += iBytesToWriteInHeader;
  167. }
  168. }
  169. if (cb > 0)
  170. {
  171. memcpy(m_pBuffer + m_iPosition - m_iOffset, pv, cb);
  172. m_iPosition += cb;
  173. if (pcbWritten)
  174. {
  175. *pcbWritten += cb;
  176. }
  177. }
  178. }
  179. Cleanup:
  180. return hr;
  181. }
  182. STDMETHODIMP CImageStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
  183. {
  184. HRESULT hr = S_OK;
  185. switch (dwOrigin)
  186. {
  187. case STREAM_SEEK_SET:
  188. m_iPosition = dlibMove.LowPart;
  189. break;
  190. case STREAM_SEEK_CUR:
  191. m_iPosition += (LONG) dlibMove.LowPart;
  192. break;
  193. case STREAM_SEEK_END:
  194. m_iPosition = m_iSize - (LONG) dlibMove.LowPart;
  195. break;
  196. default:
  197. hr = E_INVALIDARG;
  198. goto Cleanup;
  199. }
  200. if (plibNewPosition)
  201. {
  202. plibNewPosition->HighPart = 0;
  203. plibNewPosition->LowPart = m_iPosition;
  204. }
  205. // wiauDbgDump("Seek", "Position set to %d in the buffer", m_iPosition);
  206. Cleanup:
  207. return hr;
  208. }
  209. STDMETHODIMP CImageStream::SetSize(ULARGE_INTEGER libNewSize)
  210. {
  211. HRESULT hr = S_OK;
  212. if (libNewSize.HighPart != 0 ||
  213. (LONG) libNewSize.LowPart > (m_iSize + m_iOffset)) {
  214. hr = STG_E_INVALIDFUNCTION;
  215. }
  216. return hr;
  217. }
  218. STDMETHODIMP CImageStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
  219. {
  220. return E_NOTIMPL;
  221. }
  222. STDMETHODIMP CImageStream::Commit(DWORD grfCommitFlags)
  223. {
  224. return E_NOTIMPL;
  225. }
  226. STDMETHODIMP CImageStream::Revert( void)
  227. {
  228. return E_NOTIMPL;
  229. }
  230. STDMETHODIMP CImageStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
  231. {
  232. return E_NOTIMPL;
  233. }
  234. STDMETHODIMP CImageStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
  235. {
  236. return E_NOTIMPL;
  237. }
  238. STDMETHODIMP CImageStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
  239. {
  240. ZeroMemory(pstatstg, sizeof(STATSTG));
  241. pstatstg->type = STGTY_STREAM;
  242. pstatstg->cbSize.QuadPart = m_iSize;
  243. pstatstg->grfMode = STGM_READ;
  244. if (!(grfStatFlag & STATFLAG_NONAME))
  245. {
  246. pstatstg->pwcsName = NULL;
  247. }
  248. return S_OK;
  249. }
  250. STDMETHODIMP CImageStream::Clone(IStream **ppstm)
  251. {
  252. return E_NOTIMPL;
  253. }