initial upstream import
[drnoksnes] / VOIMAGE.CPP
1 //-------------------------------------------------------------------
2 // VOImage implementation
3 //-------------------------------------------------------------------
4 // 
5 // Copyright ©2000 Virtual Office Systems Incorporated
6 // All Rights Reserved                      
7 //
8 // This code may be used in compiled form in any way you desire. This
9 // file may be redistributed unmodified by any means PROVIDING it is 
10 // not sold for profit without the authors written consent, and 
11 // providing that this notice and the authors name is included.
12 //
13 // This code can be compiled, modified and distributed freely, providing
14 // that this copyright information remains intact in the distribution.
15 //
16 // This code may be compiled in original or modified form in any private 
17 // or commercial application.
18 //
19 // This file is provided "as is" with no expressed or implied warranty.
20 // The author accepts no liability for any damage, in any form, caused
21 // by this code. Use it at your own risk.
22 //-------------------------------------------------------------------
23
24 #include "stdafx.h"
25
26 #include "VOImage.h"
27
28 #ifdef _DEBUG
29 #undef THIS_FILE
30 static char THIS_FILE[]=__FILE__;
31 #define new DEBUG_NEW
32 #endif
33
34 //////////////////////////////////////////////////////////////////////
35 // Construction/Destruction
36 //////////////////////////////////////////////////////////////////////
37
38 HDC             CVOImage::g_hdc;
39 int             CVOImage::g_iScale = 100;
40 int             CVOImage::g_iMaxWidth = 10000;
41 int             CVOImage::g_iMaxHeight = 10000;
42 BOOL    CVOImage::g_bStretchBlt = FALSE;
43
44 CVOImage::CVOImage()
45 {
46         m_hbitmap = 0;
47 }
48
49 CVOImage::~CVOImage()
50 {
51         if(m_hbitmap)
52                 DeleteObject(m_hbitmap);
53 }
54
55 BOOL CVOImage::Load(HDC hdc, LPCTSTR pcszFileName)
56 {
57         if(m_hbitmap)
58                 DeleteObject(m_hbitmap);
59
60         if(!g_hdc)
61                 g_hdc = CreateCompatibleDC(hdc);
62
63         HRESULT hr;
64         BYTE    szBuffer[1024] = {0};
65         HANDLE hFile = INVALID_HANDLE_VALUE;
66
67         DecompressImageInfo     dii;
68
69         hFile = CreateFile(pcszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
70         if (hFile == INVALID_HANDLE_VALUE)
71                 return FALSE;
72
73         // Fill in the 'DecompressImageInfo' structure
74         dii.dwSize = sizeof( DecompressImageInfo );             // Size of this structure
75         dii.pbBuffer = szBuffer;                                                // Pointer to the buffer to use for data
76         dii.dwBufferMax = 1024;                                                 // Size of the buffer
77         dii.dwBufferCurrent = 0;                                                // The amount of data which is current in the buffer
78         dii.phBM = &m_hbitmap;                                                  // Pointer to the bitmap returned (can be NULL)
79         dii.ppImageRender = NULL;                                               // Pointer to an IImageRender object (can be NULL)
80         dii.iBitDepth = GetDeviceCaps(hdc,BITSPIXEL);   // Bit depth of the output image
81         dii.lParam = ( LPARAM ) hFile;                                  // User parameter for callback functions
82         dii.hdc = g_hdc;                                                                // HDC to use for retrieving palettes
83         dii.iScale = g_iScale;                                                  // Scale factor (1 - 100)
84         dii.iMaxWidth = g_iMaxWidth;                                    // Maximum width of the output image
85         dii.iMaxHeight = g_iMaxHeight;                                  // Maxumum height of the output image
86         dii.pfnGetData = GetImageData;                                  // Callback function to get image data
87         dii.pfnImageProgress = ImageProgress;                   // Callback function to notify caller of progress decoding the image
88         dii.crTransparentOverride = ( UINT ) -1;                // If this color is not (UINT)-1, it will override the
89                                                                                                         // transparent color in the image with this color. (GIF ONLY)
90
91         // Process and decompress the image data
92         hr = DecompressImageIndirect( &dii );
93                 
94         // Clean up 
95         CloseHandle( hFile );
96
97         BITMAP  bmp;
98
99         GetObject(m_hbitmap, sizeof(BITMAP), &bmp);
100
101         m_dwWidth = bmp.bmWidth;
102         m_dwHeight = bmp.bmHeight;
103
104         return TRUE;
105 }
106
107 HBITMAP CVOImage::Copy()
108 {
109         BITMAP  bm, bmNew;
110         HBITMAP hNew;
111
112         SelectObject(g_hdc, m_hbitmap);
113
114         ::GetObject(m_hbitmap, sizeof(BITMAP), &bm);
115
116         HDC hdc = CreateCompatibleDC(g_hdc);
117         hNew = CreateCompatibleBitmap(g_hdc, bm.bmWidth, bm.bmHeight);
118         SelectObject(hdc, hNew);
119
120         if(BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, g_hdc, 0, 0, SRCCOPY))
121         {
122                 HBITMAP hPrev = (HBITMAP) ::GetObject(hNew, sizeof(BITMAP), &bmNew);
123                         
124                 ::SelectObject(hdc, hPrev);
125         }
126
127         DeleteDC(hdc);
128         return hNew;
129 }
130
131 BOOL CVOImage::Draw(HDC hdc, int x, int y, int cx, int cy)
132 {
133         BITMAP  bmp;
134         HGDIOBJ hOldBitmap;
135
136         g_bStretchBlt = !(cx == -1 && cy == -1);
137         hOldBitmap = SelectObject(g_hdc, m_hbitmap);
138         GetObject(m_hbitmap, sizeof(BITMAP), &bmp);
139
140         if (g_bStretchBlt)
141         {
142                 // Stretch to fit
143                 StretchBlt(hdc, x , y, cx, cy, g_hdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY );
144         }
145         else
146         {
147                 BitBlt(hdc, x, y, bmp.bmWidth, bmp.bmHeight, g_hdc,0,0,SRCCOPY );
148         }
149
150         SelectObject(g_hdc, hOldBitmap);
151
152         return TRUE;
153 }
154
155 DWORD CVOImage::GetHeight()
156 {
157         return m_dwHeight;
158 }
159
160 DWORD CVOImage::GetWidth()
161 {
162         return m_dwWidth;
163 }
164
165 BOOL CVOImage::SetBitmap(HDC hdc, DWORD dwResourceID, LPCTSTR pcszClass, HMODULE hModule)
166 {
167         if(!g_hdc)
168                 g_hdc = CreateCompatibleDC(hdc);
169
170         HRESULT hr;
171         BYTE    szBuffer[1024] = {0}; 
172         DecompressImageInfo     dii;
173
174         CVOResource     res(hModule, dwResourceID, pcszClass);
175
176         if(!res.IsLoaded())
177                 return FALSE;
178
179         res.SetUserData(0);     // Use this for the current resource offset
180
181         // Fill in the 'DecompressImageInfo' structure
182         dii.dwSize = sizeof( DecompressImageInfo );             // Size of this structure
183         dii.pbBuffer = szBuffer;                                                // Pointer to the buffer to use for data
184         dii.dwBufferMax = 1024;                                                 // Size of the buffer
185         dii.dwBufferCurrent = 0;                                                // The amount of data which is current in the buffer
186         dii.phBM = &m_hbitmap;                                                  // Pointer to the bitmap returned (can be NULL)
187         dii.ppImageRender = NULL;                                               // Pointer to an IImageRender object (can be NULL)
188         dii.iBitDepth = GetDeviceCaps(hdc,BITSPIXEL);   // Bit depth of the output image
189         dii.lParam = ( LPARAM ) &res;                                   // User parameter for callback functions
190         dii.hdc = g_hdc;                                                                // HDC to use for retrieving palettes
191         dii.iScale = g_iScale;                                                  // Scale factor (1 - 100)
192         dii.iMaxWidth = g_iMaxWidth;                                    // Maximum width of the output image
193         dii.iMaxHeight = g_iMaxHeight;                                  // Maxumum height of the output image
194         dii.pfnGetData = GetImageResourceData;                  // Callback function to get image data
195         dii.pfnImageProgress = ImageProgress;                   // Callback function to notify caller of progress decoding the image
196         dii.crTransparentOverride = ( UINT ) -1;                // If this color is not (UINT)-1, it will override the
197                                                                                                                                                                                                 // transparent color in the image with this color. (GIF ONLY)
198         // Process and decompress the image data
199         hr = DecompressImageIndirect( &dii );
200                 
201         BITMAP  bmp;
202
203         GetObject(m_hbitmap, sizeof(BITMAP), &bmp);
204
205         m_dwWidth = bmp.bmWidth;
206         m_dwHeight = bmp.bmHeight;
207
208         return TRUE;
209 }
210
211 DWORD CALLBACK CVOImage::GetImageData(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam )
212 {
213         DWORD dwNumberOfBytesRead;
214
215         if ( (HANDLE)lParam == INVALID_HANDLE_VALUE )
216                 return 0;
217
218         ReadFile( (HANDLE)lParam, szBuffer, dwBufferMax, &dwNumberOfBytesRead, NULL );
219
220         // Return number of bytes read
221         return dwNumberOfBytesRead;
222 }
223
224 DWORD CALLBACK CVOImage::GetImageResourceData(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam)
225 {
226         DWORD                   dwNumberOfBytesToRead = dwBufferMax;
227         CVOResource*    pRes = (CVOResource*) lParam;
228
229         if(!pRes)
230                 return 0;
231
232         DWORD                   dwResourceOffset = pRes->GetUserData();
233
234         if(dwResourceOffset + dwNumberOfBytesToRead > pRes->GetSize() )
235                 dwNumberOfBytesToRead = pRes->GetSize() - dwResourceOffset;
236
237         memmove(szBuffer, pRes->GetData() + dwResourceOffset, dwNumberOfBytesToRead);
238
239         pRes->SetUserData(dwResourceOffset + dwNumberOfBytesToRead);
240         return dwNumberOfBytesToRead;   // return amount read
241 }
242
243 void CALLBACK CVOImage::ImageProgress(IImageRender *pRender, BOOL bComplete, LPARAM lParam )
244 {
245         if( bComplete )
246         {
247                 ;// (Optional) add code here for completion processing
248         }
249 }
250
251 BOOL CVOImage::IsLoaded()
252 {
253         return (m_hbitmap != 0);
254 }
255
256 CVOResource::CVOResource(HMODULE hModule, DWORD dwResourceID, LPCTSTR pcszClass)
257 {
258         m_dwSize = 0;
259         m_hGlobal = 0;
260         m_pData = 0;
261
262         m_hrsrc = FindResource(hModule, (LPCWSTR)dwResourceID, pcszClass);
263
264         if(m_hrsrc == 0)
265                 return;
266
267         m_dwSize = SizeofResource(hModule, m_hrsrc);
268         m_hGlobal = LoadResource(hModule, m_hrsrc);
269         m_pData = (PBYTE) LockResource(m_hGlobal);
270 }
271
272 CVOResource::~CVOResource()
273 {
274         if(m_hGlobal)
275                 DeleteObject(m_hGlobal);
276 }
277
278 BOOL CVOResource::IsLoaded()
279 {
280         return (m_pData != NULL);
281 }