Flush current work
[desktopswitcher.git] / png.cpp
blob83a488c8c090f9fc017ffd9018be9f593e4755fe
1 /////////////////////////////////////////////////////////////////////////////////
2 //
3 // $Id: png.cpp,v 1.4 2003/08/03 16:56:29 nedko Exp $
4 //
5 // DESCRIPTION:
6 //
7 // NOTES:
8 //
9 /////////////////////////////////////////////////////////////////////////////////
11 #include "ph.h"
12 #include "png.h"
14 #define NOT_LOADED_BITMAP_HEIGHT 30
15 #define NOT_LOADED_BITMAP_WIDTH 400
16 #define NOT_LOADED_BITMAP_RED 0x80
17 #define NOT_LOADED_BITMAP_GREEN 0xE0
18 #define NOT_LOADED_BITMAP_BLUE 0xFF
19 #define NOT_LOADED_BITMAP_ALPHA 0xE0
21 CPNGImage::CPNGImage()
23 m_nWidth = NOT_LOADED_BITMAP_WIDTH;
24 m_nHeight = NOT_LOADED_BITMAP_HEIGHT;
25 m_pData = NULL;
28 CPNGImage::~CPNGImage()
30 if (m_pData)
31 delete m_pData;
34 void PNGAPI
35 CPNGImage::PNG_ErrorHandler PNGARG((png_structp s, png_const_charp str))
37 ::MessageBox(NULL,str,"PNG Error",MB_OK);
40 bool
41 CPNGImage::LoadPNGImage(const char *pszPath)
43 png_structp png_ptr;
44 png_infop info_ptr;
45 unsigned int sig_read = 0;
47 FILE *fp = fopen(pszPath, "rb");
48 if (!fp)
50 return false;
53 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
54 NULL,
55 PNG_ErrorHandler,
56 PNG_ErrorHandler);
58 if (png_ptr == NULL)
60 fclose(fp);
61 return false;
64 info_ptr = png_create_info_struct(png_ptr);
65 if (info_ptr == NULL)
67 fclose(fp);
68 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
69 return false;
72 if (setjmp(png_jmpbuf(png_ptr)))
74 /* Free all of the memory associated with the png_ptr and info_ptr */
75 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
76 fclose(fp);
77 /* If we get here, we had a problem reading the file */
78 return false;
81 png_init_io(png_ptr, fp);
83 /* If we have already read some of the signature */
84 png_set_sig_bytes(png_ptr, sig_read);
86 png_read_png(png_ptr,
87 info_ptr,
88 PNG_TRANSFORM_IDENTITY,
89 png_voidp_NULL);
91 m_nHeight = png_get_image_height(png_ptr, info_ptr);
92 m_nWidth = png_get_image_width(png_ptr, info_ptr);
94 m_pData = new unsigned char[m_nWidth*m_nHeight*4];
95 png_bytep *row_pointers = png_get_rows(png_ptr, info_ptr);
96 for (unsigned int y = 0 ; y < m_nHeight; y++)
98 memcpy(m_pData + m_nWidth * 4 * y,row_pointers[y],m_nWidth*4);
101 PremultiplyAlpha(m_nWidth, m_nHeight, m_pData);
103 /* clean up after the read, and free any memory allocated - REQUIRED */
104 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
106 /* close the file */
107 fclose(fp);
109 return true;
112 unsigned int
113 CPNGImage::GetWidth()
115 return m_nWidth;
118 unsigned int
119 CPNGImage::GetHeight()
121 return m_nHeight;
124 HBITMAP
125 CPNGImage::CreateBitmap(HDC hMemoryDC)
127 HBITMAP hBitmap;
128 BITMAPINFO bi;
129 ZeroMemory(&bi,sizeof(bi));
130 bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
131 bi.bmiHeader.biWidth = m_nWidth;
132 bi.bmiHeader.biHeight = m_nHeight;
133 bi.bmiHeader.biPlanes = 1;
134 bi.bmiHeader.biBitCount = 32;
135 bi.bmiHeader.biCompression = BI_RGB;
137 void *pDIBBits;
139 hBitmap = ::CreateDIBSection(hMemoryDC,&bi,DIB_RGB_COLORS,&pDIBBits,NULL,0);
141 if (m_pData)
143 memcpy(pDIBBits, m_pData, m_nWidth * m_nHeight * 4);
145 else
147 unsigned char *pData = GenerateNotLoadedBitmapData(m_nWidth, m_nHeight);
149 memcpy(pDIBBits, pData, m_nWidth * m_nHeight * 4);
151 delete pData;
154 return hBitmap;
157 unsigned char *
158 CPNGImage::GenerateNotLoadedBitmapData(unsigned int nWidth, unsigned int nHeight)
160 unsigned int x,y;
161 unsigned char *pPixel;
163 unsigned char *pData = new unsigned char[nWidth*nHeight*4];
164 for (y = 0 ; y < nHeight; y++)
166 pPixel= pData + nWidth * 4 * y;
168 for (x = 0 ; x < nWidth ; x++)
170 pPixel[0]= NOT_LOADED_BITMAP_BLUE;
171 pPixel[1]= NOT_LOADED_BITMAP_GREEN;
172 pPixel[2]= NOT_LOADED_BITMAP_RED;
173 pPixel[3]= NOT_LOADED_BITMAP_ALPHA;
175 pPixel+= 4;
179 PremultiplyAlpha(nWidth, nHeight, pData);
181 return pData;
184 void
185 CPNGImage::PremultiplyAlpha(unsigned int nWidth,
186 unsigned int nHeight,
187 unsigned char *pData)
189 unsigned int x,y;
190 unsigned char *pPixel;
192 for (y = 0 ; y < nHeight; y++)
194 pPixel = pData + nWidth * 4 * y;
196 for (x = 0 ; x < nWidth ; x++)
198 pPixel[0]= (unsigned __int8)(((unsigned int)pPixel[0])*pPixel[3]/255);
199 pPixel[1]= (unsigned __int8)(((unsigned int)pPixel[1])*pPixel[3]/255);
200 pPixel[2]= (unsigned __int8)(((unsigned int)pPixel[2])*pPixel[3]/255);
201 pPixel+= 4;
206 /////////////////////////////////////////////////////////////////////////////////
208 // Modifications log:
210 // !!! WARNING !!! Following lines are automatically updated by the CVS system.
212 // $Log: png.cpp,v $
213 // Revision 1.4 2003/08/03 16:56:29 nedko
214 // Flush current work
216 // Revision 1.3 2002/06/29 16:00:28 nedko
217 // *** empty log message ***
219 // Revision 1.2 2002/06/29 15:20:10 nedko
220 // *** empty log message ***
222 // Revision 1.1 2002/06/29 15:03:33 nedko
223 // *** empty log message ***
225 /////////////////////////////////////////////////////////////////////////////////