libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
Load n Save BMPs.hpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2002 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 // DESCRIPTION:
19 // This bit of code was copied from an article called:
20 // "Bitmap & Palette - Drawing a bitmap from a BMP file" by
21 // Zafir Anjum (05/97). I found it at <a href="http://www.dsp.net/zafir/bitmap/draw_bmp.html"/>
22 //
23 // LoadBMP - Loads a BMP file and creates a logical palette for it.
24 // Returns - TRUE for success
25 // BMPFile - Full path of the BMP file
26 // hDIB - Pointer to a HGLOBAL variable to hold the loaded bitmap
27 // Memory is allocated by this function but should be
28 // released by the caller.
29 // Pal - Will hold the logical palette
30 //
31 
32 #pragma once
33 
34 #include "../../../core/ttypes.hpp"
35 
36 #include <boost/shared_ptr.hpp>
37 
38 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace NTUtils {
39 
41  public:
42  explicit inline __stdcall BitMapInfoWrapper(const unsigned long size =0);
43  inline __stdcall BitMapInfoWrapper(const unsigned int width,const unsigned int height,const unsigned short colour_depth);
44  inline __stdcall BitMapInfoWrapper(const HBITMAP hbitmap,const unsigned short colour_depth);
45  inline __stdcall BitMapInfoWrapper(BitMapInfoWrapper const &bmi) noexcept(true)
46  : buff(bmi.buff) {
47  }
48  inline __stdcall ~BitMapInfoWrapper(void) noexcept(true) {
49  }
50 
51  inline BitMapInfoWrapper & __fastcall operator=(BitMapInfoWrapper &bmi) noexcept(true) {
52  buff=bmi.buff;
53  return *this;
54  }
55 
56  inline const BITMAPINFO * __fastcall Info(void) const noexcept(true) {
57  return reinterpret_cast<BITMAPINFO *>(buff.get());
58  }
59  inline BITMAPINFO * __fastcall Info(void) noexcept(true) {
60  return reinterpret_cast<BITMAPINFO *>(buff.get());
61  }
62  inline const BITMAPINFOHEADER * __fastcall Header(void) const noexcept(true) {
63  return reinterpret_cast<BITMAPINFOHEADER *>(buff.get());
64  }
65  inline BITMAPINFOHEADER * __fastcall Header(void) noexcept(true) {
66  return reinterpret_cast<BITMAPINFOHEADER *>(buff.get());
67  }
68 
69  static inline DWORD __fastcall ColSize(const unsigned short colour_depth) noexcept(true);
70 
71  private:
72  class DCWrapper {
73  public:
74  explicit inline __stdcall DCWrapper(void) noexcept(true)
75  : dc_(CreateCompatibleDC(NULL)) {
76  }
77  inline __stdcall ~DCWrapper(void) noexcept(true) {
78  DeleteDC(dc_);
79  }
80 
81  inline HDC __fastcall dc(void) noexcept(true) {
82  return dc_;
83  }
84 
85  private:
86  HDC dc_;
87 
88  inline __stdcall DCWrapper(const DCWrapper &) noexcept(true);
89  inline DCWrapper & __fastcall operator=(const DCWrapper &) noexcept(true);
90  };
91 
92  boost::shared_ptr<char> buff;
93 
94  inline void __fastcall InitHeader(void) noexcept(true);
95  inline void __fastcall InitHeader(const unsigned int width,const unsigned int height,const unsigned short colour_depth) noexcept(true);
96 
97  static inline DWORD __fastcall CalcSize(const unsigned int width,const unsigned int height,const unsigned short colour_depth) noexcept(true);
98  };
99 
102  AFX_EXT_CLASS BitMapInfoWrapper __fastcall CreateBitmapInfoStruct(const CBitmap &);
103  AFX_EXT_CLASS bool __fastcall CreateBMPFile(const tstring &,const CBitmap &,const CDC &);
104  AFX_EXT_CLASS bool __fastcall CreateBMPFile(CFile &,const CBitmap &,const CDC &);
105 
106  inline __stdcall
107  BitMapInfoWrapper::BitMapInfoWrapper(const unsigned long size)
108  : buff(new char[sizeof(BITMAPINFOHEADER)+size]) {
109  InitHeader();
110  }
111 
112  inline __stdcall
113  BitMapInfoWrapper::BitMapInfoWrapper(const unsigned int width,const unsigned int height,const unsigned short colour_depth)
114  : buff(new char[CalcSize(width,height,colour_depth)]) {
115  InitHeader(width,height,colour_depth);
116  }
117 
118  inline __stdcall
119  BitMapInfoWrapper::BitMapInfoWrapper(const HBITMAP hbitmap,const unsigned short colour_depth) {
120  BITMAP bitmap;
121  GetObject(hbitmap,sizeof(BITMAP),&bitmap);
122  buff=std::auto_ptr<char>(new char[CalcSize(bitmap.bmWidth,bitmap.bmHeight,colour_depth)]);
123  InitHeader(bitmap.bmWidth,bitmap.bmHeight,colour_depth);
124  // Get the bits from the bitmap and stuff them after the LPBI
125  BYTE * const lpBits=reinterpret_cast<BYTE * const>(reinterpret_cast<BITMAPINFO *>(buff.get())->bmiColors)+ColSize(colour_depth);
126  DCWrapper temp_dc;
127  GetDIBits(temp_dc.dc(),hbitmap,0,bitmap.bmHeight,lpBits,reinterpret_cast<BITMAPINFO *>(buff.get()),DIB_RGB_COLORS);
128  // Fix this if GetDIBits messed it up....
129  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biClrUsed=ColSize(colour_depth)/sizeof(RGBQUAD);
130  }
131 
132  inline DWORD __fastcall
133  BitMapInfoWrapper::ColSize(const unsigned short colour_depth) {
134  return sizeof(RGBQUAD)*((colour_depth<= 8) ? 1<<colour_depth : 0);
135  }
136 
137  inline void __fastcall
138  BitMapInfoWrapper::InitHeader(void) {
139  assert(buff.get());
140  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biSize=sizeof(BITMAPINFOHEADER);
141  /* If the bitmap is not compressed, set the BI_RGB flag. */
142  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biCompression=BI_RGB;
143  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biXPelsPerMeter=reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biYPelsPerMeter=0;
144  /*
145  * Set biClrImportant to 0, indicating that all of the
146  * device colors are important.
147  */
148  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biClrImportant=0;
149  }
150 
151  inline void __fastcall
152  BitMapInfoWrapper::InitHeader(const unsigned int width,const unsigned int height,const unsigned short colour_depth) {
153  InitHeader();
154  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biWidth=width;
155  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biHeight=height;
156  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biPlanes=1;
157  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biBitCount=colour_depth;
158  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biSizeImage=CalcSize(width,height,colour_depth)-sizeof(BITMAPINFOHEADER)-ColSize(colour_depth);
159  reinterpret_cast<BITMAPINFOHEADER *>(buff.get())->biClrUsed=ColSize(colour_depth)/sizeof(RGBQUAD);
160  }
161 
162  inline DWORD __fastcall
163  BitMapInfoWrapper::CalcSize(const unsigned int width,const unsigned int height,const unsigned short colour_depth) {
164  //
165  // DWORD align the width of the DIB
166  // Figure out the size of the colour table
167  // Calculate the size of the DIB
168  //
169  const UINT LineLen = (width*colour_depth+31)/32 * 4;
170  return sizeof(BITMAPINFOHEADER)
171  +ColSize(colour_depth)
172  +static_cast<DWORD>(LineLen)*static_cast<DWORD>(height);
173  }
174 
175 } } }