|
| 1 | +// CDibData.h |
| 2 | +// |
| 3 | +// Author : John R. Shaw (shawj2@earthlink.net) |
| 4 | +// Date : Oct 14 2003 |
| 5 | +// |
| 6 | +// Copyright (C) 2003 John R. Shaw |
| 7 | +// All rights reserved. |
| 8 | +// |
| 9 | +// This code may be used in compiled form in any way you desire. This |
| 10 | +// file may be redistributed unmodified by any means PROVIDING it is |
| 11 | +// not sold for profit without the authors written consent, and |
| 12 | +// providing that this notice and the authors name is included. If |
| 13 | +// the source code in this file is used in any commercial application |
| 14 | +// then a simple email would be nice. |
| 15 | +// |
| 16 | +// Warranties and Disclaimers: |
| 17 | +// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND |
| 18 | +// INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, |
| 19 | +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| 20 | +// IN NO EVENT WILL JOHN R. SHAW BE LIABLE FOR ANY DIRECT, |
| 21 | +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES, |
| 22 | +// INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA, |
| 23 | +// INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE |
| 24 | +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. |
| 25 | +// |
| 26 | +// Please email bug reports, bug fixes, enhancements, requests and |
| 27 | +// comments to: shawj2@earthlink.net |
| 28 | +// |
| 29 | + |
| 30 | +#ifndef __CDIBDATA_H__ |
| 31 | +#define __CDIBDATA_H__ |
| 32 | + |
| 33 | +///////////////////////////////////////////////////////////////////////////// |
| 34 | +//! class CDibData |
| 35 | + |
| 36 | +class CDibData; |
| 37 | + |
| 38 | +class CDibData : public CObject |
| 39 | +{ |
| 40 | + DECLARE_DYNAMIC(CDibData) |
| 41 | + |
| 42 | + friend CDibData; |
| 43 | + |
| 44 | + HANDLE m_hDib; //!< Handle to DIB object |
| 45 | + LPBYTE m_pDib; //!< Pointer to DIB |
| 46 | + LPBYTE m_pBits; //!< Pointer to image bits in DIB |
| 47 | + LPBYTE* m_pLine; //!< DIB line pointer array |
| 48 | + LPRGBQUAD m_pColorTable; //!< Pointer to color table in DIB |
| 49 | + WORD m_wBitsPerPixel; //!< Number of bits-per-pixel |
| 50 | + DWORD m_dwColorTableSize; //!< Number of color table entries |
| 51 | + DWORD m_dwBitfields[3]; //!< DIB bitfields (16 & 24 bit images) |
| 52 | + WORD m_wRShift[3]; //!< Right shift values (16 & 24 bit images) |
| 53 | + WORD m_wLShift[3]; //!< Left shift values (16 & 24 bit images) |
| 54 | + |
| 55 | +protected: |
| 56 | + void SetDefaultBitfields(WORD wBitsColor); |
| 57 | + HANDLE CreateBitmapInfo(CBitmap* pbmpSrc, BOOL* pbFinished); |
| 58 | + void FixImageData(); |
| 59 | + CDibData* CreateEmptyDIB(WORD wBitsPerPixel); |
| 60 | + UINT GetOptimalColors(LPRGBQUAD pColors, UINT cColors, UINT nColorBits); |
| 61 | + HBITMAP CreateDIBitmap(); |
| 62 | + |
| 63 | +public: |
| 64 | + // Constructors/Destructors |
| 65 | + CDibData(const CDibData&); |
| 66 | + CDibData(); |
| 67 | + ~CDibData(); |
| 68 | + |
| 69 | + // Attach/Detach |
| 70 | + BOOL Attach(HANDLE hDib); |
| 71 | + HANDLE Detach(); |
| 72 | + |
| 73 | + // DIB deletion |
| 74 | + BOOL DeleteObject(); |
| 75 | + |
| 76 | + // Bitmap update |
| 77 | + BOOL SetDIBits(CBitmap* pbmpDest); |
| 78 | + BOOL SetDIBits(HBITMAP hBitmap); |
| 79 | + |
| 80 | + // Pixel set/get |
| 81 | + DWORD GetPixelValue(int x, int y) const; |
| 82 | + BOOL SetPixelValue(int x, int y, DWORD dwPixel); |
| 83 | + |
| 84 | + COLORREF GetPixel(int x, int y) const; |
| 85 | + BOOL SetPixel(int x, int y, COLORREF clPixel); |
| 86 | + |
| 87 | + BOOL CopyPixelValue(int xDest, int yDest, |
| 88 | + CDibData& dibSrc, int xSrc, int ySrc); |
| 89 | + BOOL CopyPixel(int xDest, int yDest, |
| 90 | + CDibData& dibSrc, int xSrc, int ySrc); |
| 91 | + |
| 92 | + // Palette/Color table |
| 93 | + BOOL GetPaletteEntries( |
| 94 | + UINT uStartIndex, UINT cEntries, LPRGBQUAD pColors) const; |
| 95 | + BOOL SetPaletteEntries( |
| 96 | + UINT uStartIndex, UINT cEntries, const LPRGBQUAD pColors); |
| 97 | + UINT GetNearestPaletteIndex(const LPRGBQUAD pColors) const; |
| 98 | + UINT GetNearestPaletteIndex(COLORREF clrSrc) const; |
| 99 | + |
| 100 | + // DIB creation/initialization |
| 101 | + BOOL CreateDIB(CBitmap* pbmpSrc, BOOL bCompress = FALSE); |
| 102 | + BOOL CreateDIB(HBITMAP hBitmap, BOOL bCompress = FALSE); |
| 103 | + HBITMAP LoadDIB(LPCTSTR lpszPathName); |
| 104 | + |
| 105 | + // DIB storing |
| 106 | + BOOL SaveDIB(LPCTSTR lpszPathName, |
| 107 | + CBitmap* pbmpSrc = NULL, BOOL bCompress = FALSE); |
| 108 | + |
| 109 | + // Create converted copy of DIB |
| 110 | + CDibData* GetConvertedDIB(WORD wBitsPerPixel, BOOL bOptimize = FALSE); |
| 111 | + |
| 112 | + ///////////////////////////////////////////////////////////////////////// |
| 113 | + // Direct DIB access |
| 114 | + LPBYTE GetDibPtr() const; //!< Pointer to DIB |
| 115 | + DWORD GetDibSize() const; //!< Total size of DIB |
| 116 | + LPBITMAPINFOHEADER GetHeaderPtr() const;//!< Pointer to DIB header |
| 117 | + DWORD GetHeaderSize() const; //!< Size of header |
| 118 | + LONG GetWidth() const; //!< Width of image |
| 119 | + LONG GetHeight() const; //!< Height of image (may be negative) |
| 120 | + WORD GetPlanes() const; //!< Number of planes (=1) |
| 121 | + WORD GetBitCount() const; //!< Bits per plane |
| 122 | + DWORD GetCompression() const; //!< BI_RGB, BI_RLE8, BI_RLE4, BI_BITFIELDS |
| 123 | + DWORD GetSizeImage() const; //!< Image size (may be 0) |
| 124 | + LONG GetXPelsPerMeter() const; |
| 125 | + LONG GetYPelsPerMeter() const; |
| 126 | + DWORD GetClrUsed() const; //!< Colors used, 0 to 256 |
| 127 | + DWORD GetClrImportant() const; //!< Important colors, 0 to 256 |
| 128 | + |
| 129 | + WORD GetBitsPerPixel() const; //!< 1, 2, 4, 8, 16, 24, 32 |
| 130 | + DWORD GetByteWidth() const; //!< Bytes per scan line |
| 131 | + DWORD GetMaxImageSize() const; //!< Maximum possible image size |
| 132 | + |
| 133 | + WORD GetSizeOfBitFields() const; //!< Bit field size or 0 |
| 134 | + LPDWORD GetBitFeildsPtr(); //!< Pointer to bit fields or NULL |
| 135 | + |
| 136 | + WORD GetMaxColors() const; //!< Maximum colors, 0 to 256 |
| 137 | + DWORD GetUsedColors() const; //!< Used or maximum colors, 0 to 256 |
| 138 | + |
| 139 | + DWORD GetSizeOfColorTable() const; //!< Size of color table in bytes |
| 140 | + DWORD GetColorTableOffset() const; //!< Offset to color table or 0 |
| 141 | + LPRGBQUAD GetColorTablePtr() const; //!< Pointer to color table or NULL |
| 142 | + |
| 143 | + DWORD GetImageOffset() const; //!< Offset to image data |
| 144 | + LPBYTE GetImagePtr() const; //!< Pointer to image data |
| 145 | + |
| 146 | + ///////////////////////////////////////////////////////////////////////////// |
| 147 | + // Debug: Helpers |
| 148 | +#ifdef _DEBUG |
| 149 | + friend void DumpDibFileHeader(const LPBITMAPINFOHEADER pbmfh); |
| 150 | + friend void DumpDibInfoHeader(const LPBYTE pDib); |
| 151 | + friend void DumpDibBitfields(const LPBYTE pDib); |
| 152 | + friend void DumpDibColorTable(const LPBYTE pDib); |
| 153 | + friend void DumpDib(const LPBYTE pDib); |
| 154 | + friend void DumpDibFile(LPCTSTR lpszPathName,BOOL bPixels); |
| 155 | +#endif |
| 156 | +}; |
| 157 | + |
| 158 | +///////////////////////////////////////////////////////////////////////////// |
| 159 | +//! class CDibData inline functions |
| 160 | + |
| 161 | +inline BOOL CDibData:: |
| 162 | +CopyPixelValue(int xDest, int yDest, |
| 163 | + CDibData& dibSrc, int xSrc, int ySrc) |
| 164 | +{ return SetPixelValue(xDest, yDest, dibSrc.GetPixelValue(xSrc, ySrc)); } |
| 165 | +inline BOOL CDibData:: |
| 166 | +CopyPixel(int xDest, int yDest, |
| 167 | + CDibData& dibSrc, int xSrc, int ySrc) |
| 168 | +{ return SetPixel(xDest, yDest, dibSrc.GetPixel(xSrc, ySrc)); } |
| 169 | + |
| 170 | +inline LPBYTE CDibData::GetDibPtr() const |
| 171 | +{ return m_pDib; } |
| 172 | +inline LPBITMAPINFOHEADER CDibData::GetHeaderPtr() const |
| 173 | +{ ASSERT(m_pDib != NULL); return((LPBITMAPINFOHEADER)m_pDib); } |
| 174 | +inline DWORD CDibData::GetHeaderSize() const |
| 175 | +{ return(GetHeaderPtr()->biSize); } |
| 176 | +inline LONG CDibData::GetWidth() const |
| 177 | +{ return(GetHeaderPtr()->biWidth); } |
| 178 | +inline LONG CDibData::GetHeight() const |
| 179 | +{ return(GetHeaderPtr()->biHeight); } |
| 180 | +inline WORD CDibData::GetPlanes() const |
| 181 | +{ return(GetHeaderPtr()->biPlanes); } |
| 182 | +inline WORD CDibData::GetBitCount() const |
| 183 | +{ return(GetHeaderPtr()->biBitCount); } |
| 184 | +inline DWORD CDibData::GetCompression() const |
| 185 | +{ return(GetHeaderPtr()->biCompression); } |
| 186 | +inline DWORD CDibData::GetSizeImage() const |
| 187 | +{ return(GetHeaderPtr()->biSizeImage); } |
| 188 | +inline LONG CDibData::GetXPelsPerMeter() const |
| 189 | +{ return(GetHeaderPtr()->biXPelsPerMeter); } |
| 190 | +inline LONG CDibData::GetYPelsPerMeter() const |
| 191 | +{ return(GetHeaderPtr()->biYPelsPerMeter); } |
| 192 | +inline DWORD CDibData::GetClrUsed() const |
| 193 | +{ return(GetHeaderPtr()->biClrUsed); } |
| 194 | +inline DWORD CDibData::GetClrImportant() const |
| 195 | +{ return(GetHeaderPtr()->biClrImportant); } |
| 196 | + |
| 197 | +inline WORD CDibData::GetBitsPerPixel() const |
| 198 | +{ return WORD(GetPlanes() * GetBitCount()); } |
| 199 | + |
| 200 | +inline DWORD CDibData::GetByteWidth() const |
| 201 | +{ return(((GetWidth() * GetBitsPerPixel() + 31) & ~31) >> 3); } |
| 202 | + |
| 203 | +inline DWORD CDibData::GetMaxImageSize() const |
| 204 | +{ return(GetByteWidth() * abs(GetHeight())); } |
| 205 | + |
| 206 | +inline WORD CDibData::GetSizeOfBitFields() const |
| 207 | +{ return WORD((GetCompression() == BI_BITFIELDS) ? sizeof(m_dwBitfields) : 0); } |
| 208 | + |
| 209 | +inline LPDWORD CDibData::GetBitFeildsPtr() |
| 210 | +{ return(LPDWORD)(GetSizeOfBitFields() ? (m_pDib + GetHeaderSize()) : NULL); } |
| 211 | + |
| 212 | +inline WORD CDibData::GetMaxColors() const |
| 213 | +{ return WORD((GetBitsPerPixel() <= 8) ? (1 << GetBitsPerPixel()) : 0); } |
| 214 | + |
| 215 | +inline DWORD CDibData::GetUsedColors() const |
| 216 | +{ return(GetClrUsed() ? GetClrUsed() : GetMaxColors()); } |
| 217 | + |
| 218 | +inline DWORD CDibData::GetSizeOfColorTable() const |
| 219 | +{ return(GetUsedColors() * sizeof(RGBQUAD)); } |
| 220 | + |
| 221 | +inline DWORD CDibData::GetColorTableOffset() const |
| 222 | +{ return(GetHeaderSize() + GetSizeOfBitFields()); } |
| 223 | + |
| 224 | +inline LPRGBQUAD CDibData::GetColorTablePtr() const |
| 225 | +{ return(LPRGBQUAD)(GetUsedColors() ? (m_pDib + GetColorTableOffset()) : NULL); } |
| 226 | + |
| 227 | +inline DWORD CDibData::GetImageOffset() const |
| 228 | +{ return(GetColorTableOffset() + GetSizeOfColorTable()); } |
| 229 | + |
| 230 | +inline LPBYTE CDibData::GetImagePtr() const |
| 231 | +{ return(m_pDib + GetImageOffset()); } |
| 232 | + |
| 233 | +inline DWORD CDibData::GetDibSize() const |
| 234 | +{ |
| 235 | + if( GetSizeImage() ) |
| 236 | + return GetImageOffset() + GetSizeImage(); |
| 237 | + return GetImageOffset() + GetMaxImageSize(); |
| 238 | +} |
| 239 | + |
| 240 | +///////////////////////////////////////////////////////////////////////////// |
| 241 | +//! Debug: Helpers |
| 242 | + |
| 243 | +#ifdef _DEBUG |
| 244 | + |
| 245 | +// Dib dump helpers |
| 246 | +void DumpDibFileHeader(const LPBITMAPINFOHEADER pbmfh); |
| 247 | +void DumpDibInfoHeader(const LPBYTE pDib); |
| 248 | +void DumpDibBitfields(const LPBYTE pDib); |
| 249 | +void DumpDibColorTable(const LPBYTE pDib); |
| 250 | +void DumpDib(const LPBYTE pDib); |
| 251 | +void DumpDibFile(LPCTSTR lpszPathName,BOOL bPixels); |
| 252 | + |
| 253 | +#define DEBUG_TRACE_FHEADER(pbmfh) DumpDibFileHeader(pbmfh) |
| 254 | +#define DEBUG_TRACE_IHEADER(pDib) DumpDibInfoHeader(pDib) |
| 255 | +#define DEBUG_TRACE_BITFIELDS(pDib) DumpDibBitfields(pDib) |
| 256 | +#define DEBUG_TRACE_COLORTABLE(pDib) DumpDibColorTable(pDib) |
| 257 | +#define DEBUG_TRACE_DIB(pDib) DumpDib(pDib) |
| 258 | +#define DEBUG_TRACE_DIBFILE(lpszPathName,bPixels) \ |
| 259 | + DumpDibFile(lpszPathName,bPixels) |
| 260 | + |
| 261 | +// Allocation helpers |
| 262 | +HANDLE DibAlloc(DWORD dwLen); |
| 263 | +LPBYTE DibLock(HANDLE hDib); |
| 264 | +BOOL DibUnlock(HANDLE hDib); |
| 265 | +HANDLE DibFree(HANDLE hDib); |
| 266 | + |
| 267 | +#else |
| 268 | + |
| 269 | +// Dib dump helpers |
| 270 | +#define DEBUG_TRACE_FHEADER(pbmfh) ((void)0) |
| 271 | +#define DEBUG_TRACE_IHEADER(pDib) ((void)0) |
| 272 | +#define DEBUG_TRACE_BITFIELDS(pDib) ((void)0) |
| 273 | +#define DEBUG_TRACE_COLORTABLE(pDib) ((void)0) |
| 274 | +#define DEBUG_TRACE_DIB(pDib) ((void)0) |
| 275 | +#define DEBUG_TRACE_DIBFILE(lpszPathName, bPixels) ((void)0) |
| 276 | + |
| 277 | +// Allocation helpers |
| 278 | +#define DibAlloc(dwLen) ::GlobalAlloc(GHND, dwLen) |
| 279 | +#define DibLock(hDib) (LPBYTE)::GlobalLock(hDib) |
| 280 | +#define DibUnlock(hDib) ::GlobalUnlock(hDib) |
| 281 | +#define DibFree(hDib) ::GlobalFree(hDib) |
| 282 | + |
| 283 | +#endif // _DEBUG |
| 284 | + |
| 285 | +#endif // __CDIBDATA_H__ |
0 commit comments