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.

457 lines
8.5 KiB

  1. //
  2. // loadimag.cpp
  3. //
  4. // implementation of the CBmpStream class
  5. //
  6. #include "stdafx.h"
  7. #include "bmpstrm.h"
  8. #include "imaging.h"
  9. //////////////////////////////////////////////////////////////////////////
  10. //
  11. //
  12. //
  13. CBmpStream::CBmpStream()
  14. {
  15. m_cRef = 1;
  16. m_hBuffer = 0;
  17. m_nSize = 0;
  18. m_nPosition = 0;
  19. }
  20. //////////////////////////////////////////////////////////////////////////
  21. //
  22. //
  23. //
  24. CBmpStream::~CBmpStream()
  25. {
  26. }
  27. //////////////////////////////////////////////////////////////////////////
  28. //
  29. //
  30. //
  31. HRESULT CBmpStream::Create(CBmpStream **ppvObject)
  32. {
  33. if (ppvObject == 0)
  34. {
  35. return E_POINTER;
  36. }
  37. TRY
  38. {
  39. *ppvObject = new CBmpStream;
  40. }
  41. CATCH(CMemoryException, e)
  42. {
  43. *ppvObject = 0;
  44. }
  45. END_CATCH
  46. if (*ppvObject == 0)
  47. {
  48. return E_OUTOFMEMORY;
  49. }
  50. return S_OK;
  51. }
  52. //////////////////////////////////////////////////////////////////////////
  53. //
  54. //
  55. //
  56. HGLOBAL CBmpStream::GetBuffer()
  57. {
  58. return m_hBuffer;
  59. }
  60. //////////////////////////////////////////////////////////////////////////
  61. //
  62. //
  63. //
  64. VOID CBmpStream::SetBuffer(HGLOBAL hBuffer, DWORD dwSize, DWORD dwOffBits)
  65. {
  66. m_hBuffer = hBuffer;
  67. m_nSize = dwSize;
  68. m_nPosition = 0;
  69. if (dwOffBits == 0)
  70. {
  71. PBYTE pBuffer = (PBYTE) GlobalLock(m_hBuffer);
  72. if (pBuffer)
  73. {
  74. dwOffBits = FindDibOffBits(pBuffer);
  75. GlobalUnlock(m_hBuffer);
  76. }
  77. }
  78. m_Header.bfType = MAKEWORD('B', 'M');
  79. m_Header.bfSize = sizeof(BITMAPFILEHEADER) + dwSize;
  80. m_Header.bfReserved1 = 0;
  81. m_Header.bfReserved2 = 0;
  82. m_Header.bfOffBits = sizeof(BITMAPFILEHEADER) + dwOffBits;
  83. }
  84. //////////////////////////////////////////////////////////////////////////
  85. //
  86. //
  87. //
  88. VOID CBmpStream::FreeBuffer()
  89. {
  90. if (m_hBuffer)
  91. {
  92. GlobalFree(m_hBuffer);
  93. m_hBuffer = 0;
  94. m_nSize = 0;
  95. m_nPosition = 0;
  96. }
  97. }
  98. //////////////////////////////////////////////////////////////////////////
  99. //
  100. //
  101. //
  102. HRESULT CBmpStream::ReAllocBuffer(SIZE_T dwBytes)
  103. {
  104. HGLOBAL hBuffer;
  105. if (m_hBuffer == 0)
  106. {
  107. hBuffer = GlobalAlloc(GMEM_MOVEABLE, dwBytes);
  108. }
  109. else
  110. {
  111. hBuffer = GlobalReAlloc(m_hBuffer, dwBytes, 0);
  112. }
  113. if (hBuffer == 0)
  114. {
  115. return HRESULT_FROM_WIN32(GetLastError());
  116. }
  117. m_hBuffer = hBuffer;
  118. m_nSize = dwBytes;
  119. return S_OK;
  120. }
  121. //////////////////////////////////////////////////////////////////////////
  122. //
  123. //
  124. //
  125. STDMETHODIMP CBmpStream::QueryInterface(REFIID riid, void **ppvObject)
  126. {
  127. if (ppvObject == 0)
  128. {
  129. return E_POINTER;
  130. }
  131. if (riid == IID_IUnknown)
  132. {
  133. AddRef();
  134. *ppvObject = (IUnknown*) this;
  135. return S_OK;
  136. }
  137. if (riid == IID_IStream)
  138. {
  139. AddRef();
  140. *ppvObject = (IStream *) this;
  141. return S_OK;
  142. }
  143. *ppvObject = 0;
  144. return E_NOINTERFACE;
  145. }
  146. //////////////////////////////////////////////////////////////////////////
  147. //
  148. //
  149. //
  150. STDMETHODIMP_(ULONG) CBmpStream::AddRef()
  151. {
  152. return InterlockedIncrement(&m_cRef);
  153. }
  154. //////////////////////////////////////////////////////////////////////////
  155. //
  156. //
  157. //
  158. STDMETHODIMP_(ULONG) CBmpStream::Release()
  159. {
  160. ASSERT( 0 != m_cRef );
  161. ULONG cRef = InterlockedDecrement(&m_cRef);
  162. if (cRef == 0)
  163. {
  164. delete this;
  165. }
  166. return cRef;
  167. }
  168. //////////////////////////////////////////////////////////////////////////
  169. //
  170. //
  171. //
  172. STDMETHODIMP CBmpStream::Read(void *pv, ULONG cb, ULONG *pcbRead)
  173. {
  174. if (pcbRead)
  175. {
  176. *pcbRead = 0;
  177. }
  178. if (m_nPosition > sizeof(m_Header) + m_nSize)
  179. {
  180. return S_FALSE;
  181. }
  182. if (cb == 0)
  183. {
  184. return S_OK;
  185. }
  186. if (cb > sizeof(m_Header) + m_nSize - m_nPosition)
  187. {
  188. cb = (ULONG) (sizeof(m_Header) + m_nSize - m_nPosition);
  189. }
  190. if (m_nPosition < sizeof(m_Header))
  191. {
  192. ULONG nBytesToReadInHeader = min(cb, sizeof(m_Header) - m_nPosition);
  193. CopyMemory(pv, (PBYTE) &m_Header + m_nPosition, nBytesToReadInHeader);
  194. pv = (PBYTE) pv + nBytesToReadInHeader;
  195. cb -= nBytesToReadInHeader;
  196. m_nPosition += nBytesToReadInHeader;
  197. if (pcbRead)
  198. {
  199. *pcbRead += nBytesToReadInHeader;
  200. }
  201. }
  202. if (cb > 0)
  203. {
  204. PBYTE pBuffer = (PBYTE) GlobalLock(m_hBuffer);
  205. if (pBuffer == 0)
  206. {
  207. return HRESULT_FROM_WIN32(GetLastError());
  208. }
  209. CopyMemory(pv, pBuffer + m_nPosition - sizeof(m_Header), cb);
  210. GlobalUnlock(m_hBuffer);
  211. m_nPosition += cb;
  212. if (pcbRead)
  213. {
  214. *pcbRead += cb;
  215. }
  216. }
  217. return S_OK;
  218. }
  219. //////////////////////////////////////////////////////////////////////////
  220. //
  221. //
  222. //
  223. STDMETHODIMP CBmpStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
  224. {
  225. if (pcbWritten)
  226. {
  227. *pcbWritten = 0;
  228. }
  229. if (cb == 0)
  230. {
  231. return S_OK;
  232. }
  233. if (m_nSize + sizeof(m_Header) < m_nPosition + cb)
  234. {
  235. HRESULT hr = ReAllocBuffer(m_nPosition + cb - sizeof(m_Header));
  236. if (hr != S_OK)
  237. {
  238. return hr;
  239. }
  240. }
  241. if (m_nPosition < sizeof(m_Header))
  242. {
  243. ULONG nBytesToWriteInHeader = min(cb, sizeof(m_Header) - m_nPosition);
  244. CopyMemory((PBYTE) &m_Header + m_nPosition, pv, nBytesToWriteInHeader);
  245. pv = (PBYTE) pv + nBytesToWriteInHeader;
  246. cb -= nBytesToWriteInHeader;
  247. m_nPosition += nBytesToWriteInHeader;
  248. if (pcbWritten)
  249. {
  250. *pcbWritten += nBytesToWriteInHeader;
  251. }
  252. }
  253. if (cb > 0)
  254. {
  255. PBYTE pBuffer = (PBYTE) GlobalLock(m_hBuffer);
  256. if (pBuffer == 0)
  257. {
  258. return HRESULT_FROM_WIN32(GetLastError());
  259. }
  260. CopyMemory(pBuffer + m_nPosition - sizeof(m_Header), pv, cb);
  261. GlobalUnlock(m_hBuffer);
  262. m_nPosition += cb;
  263. if (pcbWritten)
  264. {
  265. *pcbWritten += cb;
  266. }
  267. }
  268. return S_OK;
  269. }
  270. //////////////////////////////////////////////////////////////////////////
  271. //
  272. //
  273. //
  274. STDMETHODIMP CBmpStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
  275. {
  276. switch (dwOrigin)
  277. {
  278. case STREAM_SEEK_SET:
  279. m_nPosition = (SIZE_T) dlibMove.QuadPart;
  280. break;
  281. case STREAM_SEEK_CUR:
  282. m_nPosition += (SIZE_T) dlibMove.QuadPart;
  283. break;
  284. case STREAM_SEEK_END:
  285. m_nPosition = m_nSize - (SIZE_T) dlibMove.QuadPart;
  286. break;
  287. default:
  288. return E_INVALIDARG;
  289. }
  290. if (plibNewPosition)
  291. {
  292. plibNewPosition->QuadPart = m_nPosition;
  293. }
  294. return S_OK;
  295. }
  296. //////////////////////////////////////////////////////////////////////////
  297. //
  298. //
  299. //
  300. STDMETHODIMP CBmpStream::SetSize(ULARGE_INTEGER libNewSize)
  301. {
  302. return ReAllocBuffer((SIZE_T) libNewSize.QuadPart);
  303. }
  304. //////////////////////////////////////////////////////////////////////////
  305. //
  306. //
  307. //
  308. STDMETHODIMP CBmpStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
  309. {
  310. return E_NOTIMPL;
  311. }
  312. //////////////////////////////////////////////////////////////////////////
  313. //
  314. //
  315. //
  316. STDMETHODIMP CBmpStream::Commit(DWORD grfCommitFlags)
  317. {
  318. return E_NOTIMPL;
  319. }
  320. //////////////////////////////////////////////////////////////////////////
  321. //
  322. //
  323. //
  324. STDMETHODIMP CBmpStream::Revert()
  325. {
  326. return E_NOTIMPL;
  327. }
  328. //////////////////////////////////////////////////////////////////////////
  329. //
  330. //
  331. //
  332. STDMETHODIMP CBmpStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
  333. {
  334. return E_NOTIMPL;
  335. }
  336. //////////////////////////////////////////////////////////////////////////
  337. //
  338. //
  339. //
  340. STDMETHODIMP CBmpStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
  341. {
  342. return E_NOTIMPL;
  343. }
  344. //////////////////////////////////////////////////////////////////////////
  345. //
  346. //
  347. //
  348. STDMETHODIMP CBmpStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
  349. {
  350. return E_NOTIMPL;
  351. }
  352. //////////////////////////////////////////////////////////////////////////
  353. //
  354. //
  355. //
  356. STDMETHODIMP CBmpStream::Clone(IStream **ppstm)
  357. {
  358. return E_NOTIMPL;
  359. }