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.

348 lines
9.6 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: MEMDIB.H
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 7/14/1998
  12. *
  13. * DESCRIPTION: This class allows you to construct a bitmap from raw bitmap data.
  14. * IMPORTANT: All source data is assumed to be TOP-DOWN!!!!!!
  15. *
  16. *******************************************************************************/
  17. #ifndef __MEMDIB_H_INCLUDED
  18. #define __MEMDIB_H_INCLUDED
  19. #include <windows.h>
  20. #include "miscutil.h"
  21. #include "wiadebug.h"
  22. class CMemoryDib
  23. {
  24. private:
  25. PBYTE m_pBitmapBits;
  26. HBITMAP m_hBitmap;
  27. UINT m_nHeaderLength;
  28. private:
  29. // No implementation
  30. int operator=( const CMemoryDib & );
  31. CMemoryDib( const CMemoryDib & );
  32. public:
  33. CMemoryDib(void)
  34. : m_hBitmap(NULL),
  35. m_pBitmapBits(NULL),
  36. m_nHeaderLength(0)
  37. {
  38. }
  39. virtual ~CMemoryDib(void)
  40. {
  41. Destroy();
  42. }
  43. void Destroy(void)
  44. {
  45. if (m_hBitmap)
  46. {
  47. DeleteObject(m_hBitmap);
  48. m_hBitmap = NULL;
  49. }
  50. m_nHeaderLength = 0;
  51. m_pBitmapBits = NULL;
  52. }
  53. bool IsValid(void) const
  54. {
  55. bool bResult = (m_hBitmap && m_pBitmapBits && m_nHeaderLength);
  56. return bResult;
  57. }
  58. PBYTE GetBitmapBits(void)
  59. {
  60. if (!IsValid())
  61. {
  62. return NULL;
  63. }
  64. return (m_pBitmapBits);
  65. }
  66. bool GetDibSection( DIBSECTION &ds )
  67. {
  68. if (IsValid() && GetObject( m_hBitmap, sizeof(DIBSECTION), &ds ))
  69. {
  70. return true;
  71. }
  72. return false;
  73. }
  74. LONG GetBitsPerPixel(void)
  75. {
  76. if (!IsValid())
  77. {
  78. return 0;
  79. }
  80. DIBSECTION ds;
  81. if (GetDibSection(ds))
  82. {
  83. return ds.dsBmih.biBitCount;
  84. }
  85. return 0;
  86. }
  87. LONG GetWidthInPixels(void)
  88. {
  89. if (!IsValid())
  90. {
  91. return 0;
  92. }
  93. DIBSECTION ds;
  94. if (GetDibSection(ds))
  95. {
  96. return ds.dsBmih.biWidth;
  97. }
  98. return 0;
  99. }
  100. LONG GetPackedWidthInBytes(void)
  101. {
  102. if (!IsValid())
  103. {
  104. return 0;
  105. }
  106. return (GetWidthInPixels() * GetBitsPerPixel()) / 8;
  107. }
  108. LONG GetUnpackedWidthInBytes(void)
  109. {
  110. if (!IsValid())
  111. {
  112. return 0;
  113. }
  114. return (WiaUiUtil::Align(GetWidthInPixels() * GetBitsPerPixel(), sizeof(DWORD)*8)/8);
  115. }
  116. LONG GetHeight(void)
  117. {
  118. if (!IsValid())
  119. {
  120. return 0;
  121. }
  122. DIBSECTION ds;
  123. if (GetDibSection(ds))
  124. {
  125. return ds.dsBmih.biHeight;
  126. }
  127. return 0;
  128. }
  129. UINT GetHeaderLength(void) const
  130. {
  131. if (!IsValid())
  132. {
  133. return 0;
  134. }
  135. return m_nHeaderLength;
  136. }
  137. LONG GetUnpackedBitmapDataSize(void)
  138. {
  139. if (!IsValid())
  140. {
  141. return 0;
  142. }
  143. return (GetUnpackedWidthInBytes() * GetHeight());
  144. }
  145. LONG GetPackedBitmapDataSize(void)
  146. {
  147. if (!IsValid())
  148. {
  149. return 0;
  150. }
  151. return (GetPackedWidthInBytes() * GetHeight());
  152. }
  153. HBITMAP Bitmap(void)
  154. {
  155. if (!IsValid())
  156. {
  157. return NULL;
  158. }
  159. return m_hBitmap;
  160. }
  161. HBITMAP DetachBitmap(void)
  162. {
  163. HBITMAP hBitmap = m_hBitmap;
  164. m_hBitmap = NULL;
  165. m_pBitmapBits = NULL;
  166. return hBitmap;
  167. }
  168. static void DumpBitmap( PBITMAPINFO pBitmapInfo )
  169. {
  170. WIA_TRACE((TEXT("pBitmapInfo: %08X"), pBitmapInfo ));
  171. WIA_TRACE((TEXT("biSize: %d\nbiWidth: %d\nbiHeight: %d\nbiPlanes: %d\nbiBitCount: %d\nbiCompression: %d\nbiSizeImage: %d\nbiXPelsPerMeter: %d\nbiYPelsPerMeter: %d\nbiClrUsed: %d\nbiClrImportant: %d"),
  172. pBitmapInfo->bmiHeader.biSize,
  173. pBitmapInfo->bmiHeader.biWidth,
  174. pBitmapInfo->bmiHeader.biHeight,
  175. pBitmapInfo->bmiHeader.biPlanes,
  176. pBitmapInfo->bmiHeader.biBitCount,
  177. pBitmapInfo->bmiHeader.biCompression,
  178. pBitmapInfo->bmiHeader.biSizeImage,
  179. pBitmapInfo->bmiHeader.biXPelsPerMeter,
  180. pBitmapInfo->bmiHeader.biYPelsPerMeter,
  181. pBitmapInfo->bmiHeader.biClrUsed,
  182. pBitmapInfo->bmiHeader.biClrImportant));
  183. }
  184. bool Initialize( PBITMAPINFO pBitmapInfo )
  185. {
  186. //
  187. // Clear everything
  188. //
  189. Destroy();
  190. if (pBitmapInfo)
  191. {
  192. //
  193. // What kind of bitmap is this?
  194. //
  195. DumpBitmap(pBitmapInfo);
  196. //
  197. // Get the header size. We'll need it later
  198. //
  199. m_nHeaderLength = WiaUiUtil::GetBmiSize(pBitmapInfo);
  200. if (m_nHeaderLength)
  201. {
  202. //
  203. // Allocate a new BITMAPINFOHEADER + palette
  204. //
  205. BITMAPINFO *pNewBitmapInfo = reinterpret_cast<BITMAPINFO*>( new BYTE[m_nHeaderLength] );
  206. if (pNewBitmapInfo)
  207. {
  208. //
  209. // Copy the header and palette
  210. //
  211. CopyMemory( pNewBitmapInfo, pBitmapInfo, m_nHeaderLength );
  212. //
  213. // Make sure we have a positive height
  214. //
  215. pNewBitmapInfo->bmiHeader.biHeight = WiaUiUtil::Absolute( pNewBitmapInfo->bmiHeader.biHeight );
  216. //
  217. // If this is one of those "unknown length" bitmaps, normalize it to be 8.5 x 11
  218. //
  219. if (!pNewBitmapInfo->bmiHeader.biHeight)
  220. {
  221. pNewBitmapInfo->bmiHeader.biHeight = WiaUiUtil::MulDivNoRound(pNewBitmapInfo->bmiHeader.biWidth,1100,850);
  222. }
  223. m_hBitmap = CreateDIBSection( NULL, pNewBitmapInfo, DIB_RGB_COLORS, (void**)&m_pBitmapBits, 0, 0 );
  224. if (m_hBitmap)
  225. {
  226. //
  227. // Initialize it to white. We hope. It will depend on the palette.
  228. //
  229. FillMemory( m_pBitmapBits, GetUnpackedBitmapDataSize(), 0xFF );
  230. }
  231. else
  232. {
  233. WIA_PRINTHRESULT((HRESULT_FROM_WIN32(GetLastError()),TEXT("CreateDIBSection FAILED")));
  234. }
  235. //
  236. // Free up our temporary header
  237. //
  238. delete[] reinterpret_cast<BYTE*>(pNewBitmapInfo);
  239. }
  240. else
  241. {
  242. WIA_ERROR((TEXT("pNewBitmapInfo is NULL")));
  243. }
  244. }
  245. else
  246. {
  247. WIA_ERROR((TEXT("m_nHeaderLength was 0")));
  248. }
  249. //
  250. // Make sure there are no turds left over
  251. //
  252. if (!IsValid())
  253. {
  254. WIA_ERROR((TEXT("IsValid() was FALSE")));
  255. Destroy();
  256. }
  257. }
  258. else
  259. {
  260. WIA_ERROR((TEXT("pBitmapInfo is NULL")));
  261. }
  262. return IsValid();
  263. }
  264. bool SetPackedData( PBYTE pData, int nStartLine, int nLineCount )
  265. {
  266. if (!IsValid())
  267. {
  268. return false;
  269. }
  270. nStartLine = WiaUiUtil::Absolute(nStartLine);
  271. nLineCount = WiaUiUtil::Absolute(nLineCount);
  272. for (int i=0;i<nLineCount;i++)
  273. {
  274. if (nStartLine + i >= 0 && nStartLine + i < GetHeight())
  275. {
  276. PBYTE pDest = GetBitmapBits() + (GetHeight()-nStartLine-i-1) * GetUnpackedWidthInBytes();
  277. CopyMemory( pDest, pData + GetPackedWidthInBytes() * i, GetPackedWidthInBytes() );
  278. }
  279. else
  280. {
  281. WIA_ERROR((TEXT("CMemoryDib::SetPackedData: Ignoring out-of-range data: nStartLine: %d, nLineCount: %d"), nStartLine, nLineCount ));
  282. }
  283. }
  284. return true;
  285. }
  286. bool ScrollDataUp( int nScrollCount )
  287. {
  288. if (!IsValid())
  289. {
  290. return false;
  291. }
  292. if (nScrollCount > GetHeight())
  293. {
  294. nScrollCount = GetHeight();
  295. }
  296. PBYTE pSourceLine = GetBitmapBits() + (GetHeight() - nScrollCount - 1) * GetUnpackedWidthInBytes();
  297. PBYTE pTargetLine = GetBitmapBits() + (GetHeight() - 1) * GetUnpackedWidthInBytes();
  298. for (int i=0;i < GetHeight() - nScrollCount;i++)
  299. {
  300. CopyMemory(pTargetLine,pSourceLine,GetUnpackedWidthInBytes());
  301. pSourceLine -= GetUnpackedWidthInBytes();
  302. pTargetLine -= GetUnpackedWidthInBytes();
  303. }
  304. return true;
  305. }
  306. bool SetUnpackedData( PBYTE pData, int nStartLine, int nLineCount )
  307. {
  308. if (!IsValid())
  309. {
  310. return false;
  311. }
  312. nStartLine = WiaUiUtil::Absolute(nStartLine);
  313. nLineCount = WiaUiUtil::Absolute(nLineCount);
  314. for (int i=0;i<nLineCount;i++)
  315. {
  316. if (nStartLine + i >= 0 && nStartLine + i < GetHeight())
  317. {
  318. PBYTE pDest = GetBitmapBits() + (GetHeight()-nStartLine-i-1) * GetUnpackedWidthInBytes();
  319. CopyMemory( pDest, pData + GetUnpackedWidthInBytes() * i, GetUnpackedWidthInBytes() );
  320. }
  321. else
  322. {
  323. WIA_ERROR((TEXT("CMemoryDib::SetPackedData: Ignoring out-of-range data: nStartLine: %d, nLineCount: %d"), nStartLine, nLineCount ));
  324. }
  325. }
  326. return true;
  327. }
  328. };
  329. #endif // __MEMDIB_H_INCLUDED