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.

361 lines
9.6 KiB

  1. #ifndef _DATADUMP
  2. #define _DATADUMP
  3. #define MAX_PAD_DATA 1048576 // 1 meg of padding
  4. typedef struct _DATA_DESCRIPTION {
  5. DWORD dwDataSize;
  6. DWORD dwbpp;
  7. DWORD dwWidth;
  8. DWORD dwHeight;
  9. PBYTE pRawData;
  10. }DATA_DESCRIPTION,*PDATA_DESCRIPTION;
  11. class CDATADUMP {
  12. public:
  13. CDATADUMP()
  14. {
  15. m_pDIB = NULL;
  16. m_pDIBHeader = NULL;
  17. }
  18. ~CDATADUMP()
  19. {
  20. FreeDIBMemory();
  21. }
  22. BOOL DumpDataToBitmap(LPTSTR szBitmapFileName,
  23. PDATA_DESCRIPTION pDataDesc)
  24. {
  25. if(!AllocateDIBMemory(pDataDesc))
  26. return FALSE;
  27. if(!WriteDIBHeader(pDataDesc))
  28. return FALSE;
  29. if(!WriteRawDataToDIB(pDataDesc))
  30. return FALSE;
  31. if(!WriteDIBToDisk(szBitmapFileName))
  32. return FALSE;
  33. return TRUE;
  34. }
  35. BOOL DumpDataToDIB(PDATA_DESCRIPTION pDataDesc)
  36. {
  37. if(!AllocateDIBMemory(pDataDesc))
  38. return FALSE;
  39. if(!WriteDIBHeader(pDataDesc))
  40. return FALSE;
  41. if(!WriteRawDataToDIB(pDataDesc))
  42. return FALSE;
  43. return TRUE;
  44. }
  45. PBYTE GetDIBPtr()
  46. {
  47. return m_pDIB;
  48. }
  49. BOOL OwnDIBPtr(PBYTE *ppOUTDIB)
  50. {
  51. if(NULL != m_pDIB){
  52. //
  53. // assign the DIB pointer to new owner's pointer
  54. // new owner must free allocated DIB
  55. //
  56. *ppOUTDIB = m_pDIB;
  57. //
  58. // set our pointer to NULL, so we don't try to
  59. // free the new owner's memory.
  60. //
  61. m_pDIB = NULL;
  62. m_pDIBHeader = NULL;
  63. return TRUE;
  64. }
  65. return FALSE;
  66. }
  67. private:
  68. PBYTE m_pDIB;
  69. BITMAPINFOHEADER *m_pDIBHeader;
  70. VOID FreeDIBMemory(){
  71. if (NULL != m_pDIB){
  72. LocalFree(m_pDIB);
  73. m_pDIB = NULL;
  74. m_pDIBHeader = NULL;
  75. }
  76. }
  77. BOOL AllocateDIBMemory(PDATA_DESCRIPTION pDataDesc)
  78. {
  79. m_pDIB = (PBYTE)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER) +
  80. (sizeof(RGBQUAD) * 256) +
  81. pDataDesc->dwDataSize +
  82. MAX_PAD_DATA);
  83. if (NULL == m_pDIB)
  84. return FALSE;
  85. m_pDIBHeader = (BITMAPINFOHEADER*)m_pDIB;
  86. return TRUE;
  87. }
  88. LONG RawWidthBytes()
  89. {
  90. switch(m_pDIBHeader->biBitCount){
  91. case 1:
  92. return (LONG)((m_pDIBHeader->biWidth + 7) / 8);
  93. break;
  94. case 8:
  95. return (LONG)(m_pDIBHeader->biWidth);
  96. break;
  97. case 24:
  98. return (LONG)(m_pDIBHeader->biWidth * 3);
  99. break;
  100. default:
  101. break;
  102. }
  103. return 0;
  104. }
  105. BOOL WriteDIBHeader(PDATA_DESCRIPTION pDataDesc)
  106. {
  107. if(NULL == m_pDIB)
  108. return FALSE;
  109. m_pDIBHeader->biSize = sizeof(BITMAPINFOHEADER);
  110. m_pDIBHeader->biBitCount = (WORD)pDataDesc->dwbpp;
  111. m_pDIBHeader->biCompression = BI_RGB;
  112. m_pDIBHeader->biHeight = pDataDesc->dwHeight;
  113. m_pDIBHeader->biWidth = pDataDesc->dwWidth;
  114. m_pDIBHeader->biSizeImage = pDataDesc->dwDataSize;
  115. m_pDIBHeader->biPlanes = 1;
  116. m_pDIBHeader->biXPelsPerMeter = 0;
  117. m_pDIBHeader->biYPelsPerMeter = 0;
  118. switch(pDataDesc->dwbpp){
  119. case 1:
  120. m_pDIBHeader->biClrImportant= 2;
  121. m_pDIBHeader->biClrUsed = 2;
  122. break;
  123. case 8:
  124. m_pDIBHeader->biClrImportant= 256;
  125. m_pDIBHeader->biClrUsed = 256;
  126. break;
  127. case 24:
  128. m_pDIBHeader->biClrImportant= 0;
  129. m_pDIBHeader->biClrUsed = 0;
  130. break;
  131. default:
  132. FreeDIBMemory();
  133. return FALSE;
  134. break;
  135. }
  136. return TRUE;
  137. }
  138. BOOL BuildPalette(RGBQUAD *pPalette)
  139. {
  140. BYTE i = 0;
  141. switch(m_pDIBHeader->biBitCount){
  142. case 1: // black and white palette
  143. {
  144. pPalette[0].rgbBlue = 0;
  145. pPalette[0].rgbGreen = 0;
  146. pPalette[0].rgbRed = 0;
  147. pPalette[0].rgbReserved = 0;
  148. pPalette[1].rgbBlue = 255;
  149. pPalette[1].rgbGreen = 255;
  150. pPalette[1].rgbRed = 255;
  151. pPalette[1].rgbReserved = 0;
  152. }
  153. break;
  154. case 8: // grayscale palette
  155. {
  156. for (i = 0; i < 255;i++) {
  157. pPalette[i].rgbBlue = i;
  158. pPalette[i].rgbGreen = i;
  159. pPalette[i].rgbRed = i;
  160. pPalette[i].rgbReserved = 0;
  161. }
  162. }
  163. break;
  164. case 24:
  165. default:
  166. break;
  167. }
  168. return TRUE;
  169. }
  170. BOOL WriteRawDataToDIB(PDATA_DESCRIPTION pDataDesc)
  171. {
  172. //
  173. // create a palette (for 1-bit, and 8-bit images)
  174. //
  175. RGBQUAD *pPalette = (RGBQUAD*)LocalAlloc(LPTR,(sizeof(RGBQUAD) * m_pDIBHeader->biClrUsed));
  176. BuildPalette(pPalette);
  177. //
  178. // insert palette into DIB memory block, past BITMAPINFOHEADER
  179. //
  180. PBYTE pDest = m_pDIB + sizeof(BITMAPINFOHEADER);
  181. memcpy(pDest,
  182. pPalette,
  183. (sizeof(RGBQUAD) * m_pDIBHeader->biClrUsed));
  184. if(NULL != pPalette)
  185. LocalFree(pPalette);
  186. //
  187. // insert raw bits to DIB memory block
  188. // (DWORD alignment will happen here too)
  189. //
  190. pDest = m_pDIB + sizeof(BITMAPINFOHEADER) + (m_pDIBHeader->biClrUsed * sizeof(RGBQUAD));
  191. PBYTE pRawData = pDataDesc->pRawData;
  192. LONG lRawWidthBytes = RawWidthBytes();
  193. LONG PadWidthBytes = ((((m_pDIBHeader->biWidth * m_pDIBHeader->biBitCount) + 31) / 8) & 0xfffffffc) - (lRawWidthBytes);
  194. //
  195. // update image size in BITMAPINFOHEADER, padding will increase total image size
  196. //
  197. m_pDIBHeader->biSizeImage += (PadWidthBytes * m_pDIBHeader->biHeight);
  198. PBYTE pPadData = new BYTE[PadWidthBytes]; //(PBYTE)LocalAlloc(LPTR, PadWidthBytes);
  199. if(NULL != pPadData) {
  200. memset(pPadData,0,PadWidthBytes); // clear padded byte memory...
  201. Trace(TEXT("Copying Line data (%d total lines)"),m_pDIBHeader->biHeight);
  202. for(LONG Line = 1; Line <= m_pDIBHeader->biHeight; Line++) {
  203. // Trace(TEXT("Copy Line %d of %d"),Line,m_pDIBHeader->biHeight);
  204. //
  205. // copy a raw data line to DIB
  206. //
  207. memcpy(pDest,pRawData,lRawWidthBytes);
  208. //
  209. // move destination pointer (RawWidthBytes)
  210. //
  211. pDest += lRawWidthBytes;
  212. //
  213. // copy a padded buffer to DIB
  214. //
  215. memcpy(pDest,pPadData,PadWidthBytes);
  216. //
  217. // move destination pointer (PadWidthBytes)
  218. //
  219. pDest += PadWidthBytes;
  220. //
  221. // move src pointer RawWidthBytes only
  222. //
  223. pRawData += lRawWidthBytes;
  224. }
  225. Trace(TEXT("Done... data copy complete..for %d lines"),(Line - 1));
  226. //
  227. // free padded bytes memory
  228. //
  229. delete pPadData; //LocalFree(pPadData);
  230. } else
  231. return FALSE;
  232. return TRUE;
  233. }
  234. VOID Trace(LPCTSTR format,...)
  235. {
  236. TCHAR Buffer[1024];
  237. va_list arglist;
  238. va_start(arglist, format);
  239. wvsprintf(Buffer, format, arglist);
  240. va_end(arglist);
  241. OutputDebugString(Buffer);
  242. OutputDebugString(TEXT("\n"));
  243. }
  244. BOOL WriteDIBToDisk(LPTSTR szBitmapFileName)
  245. {
  246. //
  247. // create bitmap file on disk
  248. //
  249. HANDLE hBitmapFile = CreateFile(szBitmapFileName,
  250. GENERIC_READ | GENERIC_WRITE, // Access mask
  251. 0, // Share mode
  252. NULL, // SA
  253. CREATE_ALWAYS, // Create disposition
  254. FILE_ATTRIBUTE_NORMAL, // Attributes
  255. NULL );
  256. if(NULL == hBitmapFile)
  257. return FALSE;
  258. //
  259. // create bitmap file header
  260. //
  261. BITMAPFILEHEADER BitmapFileHeader;
  262. BitmapFileHeader.bfOffBits = (sizeof(BITMAPFILEHEADER) +
  263. sizeof(BITMAPINFOHEADER) +
  264. (m_pDIBHeader->biClrUsed * sizeof(RGBQUAD)));
  265. BitmapFileHeader.bfReserved1 = 0;
  266. BitmapFileHeader.bfReserved2 = 0;
  267. BitmapFileHeader.bfSize = (BitmapFileHeader.bfOffBits +
  268. m_pDIBHeader->biSizeImage);
  269. BitmapFileHeader.bfType = MAKEWORD('B','M');
  270. DWORD dwWritten = 0;
  271. //
  272. // write bitmap file header to open bitmap file
  273. //
  274. WriteFile(hBitmapFile,&BitmapFileHeader,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);
  275. //
  276. // write DIB memory to opend bitmap file
  277. //
  278. WriteFile(hBitmapFile,
  279. m_pDIB,
  280. (sizeof(BITMAPINFOHEADER) + m_pDIBHeader->biSizeImage + (sizeof(RGBQUAD) * m_pDIBHeader->biClrUsed)),
  281. &dwWritten,
  282. NULL);
  283. CloseHandle(hBitmapFile);
  284. return TRUE;
  285. }
  286. protected:
  287. };
  288. #endif