MYFILE.CPP
上传用户:zbjinju
上传日期:2022-07-30
资源大小:11893k
文件大小:6k
源码类别:

图形图象

开发平台:

Visual C++

  1. //  myfile.cpp
  2. //
  3. //  Source file for Device-Independent Bitmap (DIB) API.  Provides
  4. //  the following functions:
  5. //
  6. //  SaveDIB()           - Saves the specified dib in a file
  7. //  ReadDIBFile()       - Loads a DIB from a file
  8. //
  9. //
  10. // This is a part of the Microsoft Foundation Classes C++ library.
  11. // Copyright (C) 1992-1998 Microsoft Corporation
  12. // All rights reserved.
  13. //
  14. // This source code is only intended as a supplement to the
  15. // Microsoft Foundation Classes Reference and related
  16. // electronic documentation provided with the library.
  17. // See these sources for detailed information regarding the
  18. // Microsoft Foundation Classes product.
  19. #include "stdafx.h"
  20. #include <math.h>
  21. #include <io.h>
  22. #include <direct.h>
  23. #include "dibapi.h"
  24. /*
  25.  * Dib Header Marker - used in writing DIBs to files
  26.  */
  27. #define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')
  28. /*************************************************************************
  29.  *
  30.  * SaveDIB()
  31.  *
  32.  * Saves the specified DIB into the specified CFile.  The CFile
  33.  * is opened and closed by the caller.
  34.  *
  35.  * Parameters:
  36.  *
  37.  * HDIB hDib - Handle to the dib to save
  38.  *
  39.  * CFile& file - open CFile used to save DIB
  40.  *
  41.  * Return value: TRUE if successful, else FALSE or CFileException
  42.  *
  43.  *************************************************************************/
  44. BOOL WINAPI SaveDIB(HDIB hDib, CFile& file)
  45. {
  46. BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
  47. LPBITMAPINFOHEADER lpBI;   // Pointer to DIB info structure
  48. DWORD dwDIBSize;
  49. if (hDib == NULL)
  50. return FALSE;
  51. /*
  52.  * Get a pointer to the DIB memory, the first of which contains
  53.  * a BITMAPINFO structure
  54.  */
  55. lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
  56. if (lpBI == NULL)
  57. return FALSE;
  58. if (!IS_WIN30_DIB(lpBI))
  59. {
  60. ::GlobalUnlock((HGLOBAL) hDib);
  61. return FALSE;       // It's an other-style DIB (save not supported)
  62. }
  63. /*
  64.  * Fill in the fields of the file header
  65.  */
  66. /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
  67. bmfHdr.bfType = DIB_HEADER_MARKER;  // "BM"
  68. // Calculating the size of the DIB is a bit tricky (if we want to
  69. // do it right).  The easiest way to do this is to call GlobalSize()
  70. // on our global handle, but since the size of our global memory may have
  71. // been padded a few bytes, we may end up writing out a few too
  72. // many bytes to the file (which may cause problems with some apps).
  73. //
  74. // So, instead let's calculate the size manually (if we can)
  75. //
  76. // First, find size of header plus size of color table.  Since the
  77. // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
  78. // the size of the structure, let's use this.
  79. dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI);  // Partial Calculation
  80. // Now calculate the size of the image
  81. if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
  82. {
  83. // It's an RLE bitmap, we can't calculate size, so trust the
  84. // biSizeImage field
  85. dwDIBSize += lpBI->biSizeImage;
  86. }
  87. else
  88. {
  89. DWORD dwBmBitsSize;  // Size of Bitmap Bits only
  90. // It's not RLE, so size is Width (DWORD aligned) * Height
  91. dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
  92. dwDIBSize += dwBmBitsSize;
  93. // Now, since we have calculated the correct size, why don't we
  94. // fill in the biSizeImage field (this will fix any .BMP files which
  95. // have this field incorrect).
  96. lpBI->biSizeImage = dwBmBitsSize;
  97. }
  98. // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
  99. bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
  100. bmfHdr.bfReserved1 = 0;
  101. bmfHdr.bfReserved2 = 0;
  102. /*
  103.  * Now, calculate the offset the actual bitmap bits will be in
  104.  * the file -- It's the Bitmap file header plus the DIB header,
  105.  * plus the size of the color table.
  106.  */
  107. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
  108.   + PaletteSize((LPSTR)lpBI);
  109. TRY
  110. {
  111. // Write the file header
  112. file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
  113. //
  114. // Write the DIB header and the bits
  115. //
  116. file.Write(lpBI, dwDIBSize);
  117. }
  118. CATCH (CFileException, e)
  119. {
  120. ::GlobalUnlock((HGLOBAL) hDib);
  121. THROW_LAST();
  122. }
  123. END_CATCH
  124. ::GlobalUnlock((HGLOBAL) hDib);
  125. return TRUE;
  126. }
  127. /*************************************************************************
  128.   Function:  ReadDIBFile (CFile&)
  129.    Purpose:  Reads in the specified DIB file into a global chunk of
  130.  memory.
  131.    Returns:  A handle to a dib (hDIB) if successful.
  132.  NULL if an error occurs.
  133.   Comments:  BITMAPFILEHEADER is stripped off of the DIB.  Everything
  134.  from the end of the BITMAPFILEHEADER structure on is
  135.  returned in the global memory handle.
  136. *************************************************************************/
  137. HDIB WINAPI ReadDIBFile(CFile& file)
  138. {
  139. BITMAPFILEHEADER bmfHeader;
  140. DWORD dwBitsSize;
  141. HDIB hDIB;
  142. LPSTR pDIB;
  143. /*
  144.  * get length of DIB in bytes for use when reading
  145.  */
  146. dwBitsSize = (DWORD)file.GetLength();
  147. /*
  148.  * Go read the DIB file header and check if it's valid.
  149.  */
  150. if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
  151. return NULL;
  152. if (bmfHeader.bfType != DIB_HEADER_MARKER)
  153. return NULL;
  154. /*
  155.  * Allocate memory for DIB
  156.  */
  157. hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
  158. if (hDIB == 0)
  159. {
  160. return NULL;
  161. }
  162. pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
  163. /*
  164.  * Go read the bits.
  165.  */
  166. if (file.Read(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
  167. dwBitsSize - sizeof(BITMAPFILEHEADER) )
  168. {
  169. ::GlobalUnlock((HGLOBAL) hDIB);
  170. ::GlobalFree((HGLOBAL) hDIB);
  171. return NULL;
  172. }
  173. ::GlobalUnlock((HGLOBAL) hDIB);
  174. return hDIB;
  175. }