1 |
/* wptJPG.cpp : JPG picture class |
/* wptJPG.cpp - Routines for showing JPG pictures |
2 |
* Copyright (C) 2001 Dr.Yovav Gad <[email protected]> |
* Copyright (C) 2001 Dr.Yovav Gad |
3 |
* Copyright (C) 2005 Timo Schulz |
* Copyright (C) 2005, 2006 Timo Schulz |
4 |
* |
* |
5 |
* This file is part of PTD. |
* This file is part of WinPT. |
6 |
* |
* |
7 |
* PTD is free software; you can redistribute it and/or modify |
* WinPT is free software; you can redistribute it and/or modify |
8 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
9 |
* the Free Software Foundation; either version 2 of the License, or |
* the Free Software Foundation; either version 2 of the License, or |
10 |
* (at your option) any later version. |
* (at your option) any later version. |
11 |
* |
* |
12 |
* PTD is distributed in the hope that it will be useful, |
* WinPT is distributed in the hope that it will be useful, |
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
* GNU General Public License for more details. |
* GNU General Public License for more details. |
16 |
* |
* |
17 |
* You should have received a copy of the GNU General Public License |
* You should have received a copy of the GNU General Public License |
18 |
* along with PTD; if not, write to the Free Software Foundation, |
* along with PTD; if not, write to the Free Software Foundation, |
19 |
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
20 |
*/ |
*/ |
21 |
|
|
22 |
/*----------------------------------------------------------------------------- |
/*----------------------------------------------------------------------------- |
23 |
* Picture (Implementations) Version 1.00 |
* Picture (Implementations) Version 1.00 |
24 |
* |
* Author: Dr. Yovav Gad, EMail: [email protected] |
25 |
* Routinges for showing JPG pictur files |
* Web: www.SuperMain.com |
26 |
* |
* |
27 |
* Author: Dr. Yovav Gad, EMail: [email protected] ,Web: www.SuperMain.com |
* This version uses a stripped down and heavily modified version of |
28 |
* |
* Picture.cpp and Picture.h. |
29 |
* This version uses a stripped down version of Picture.cpp and Picture.h. |
*/ |
30 |
*/ |
#ifdef HAVE_CONFIG_H |
31 |
#include <windows.h> |
#include <config.h> |
32 |
#include <ocidl.h> |
#endif |
33 |
#include <olectl.h> |
|
34 |
|
#include <windows.h> |
35 |
#include <stdio.h> |
#include <ocidl.h> |
36 |
#include <string.h> |
#include <olectl.h> |
37 |
#include <errno.h> |
|
38 |
#include <sys/stat.h> |
#include <stdio.h> |
39 |
|
#include <string.h> |
40 |
#include "wptJPG.h" |
#include <errno.h> |
41 |
|
#include <sys/stat.h> |
42 |
#define HIMETRIC_INCH 2540 |
|
43 |
#define ERROR_TITLE "CJPG Error" /* Error Title (Related To This Class)...*/ |
#include "wptJPG.h" |
44 |
|
|
45 |
|
#define HIMETRIC_INCH 2540 |
46 |
CJPG::CJPG () |
#define ERROR_TITLE "WinPT - CJPG Error" |
47 |
{ |
|
48 |
m_IPicture = NULL; |
#define out_of_core() do { \ |
49 |
m_Height = 0; |
MessageBox (NULL, "Can not allocate memory", ERROR_TITLE, MB_OK|MB_ICONSTOP); \ |
50 |
m_Weight = 0; |
return FALSE; \ |
51 |
m_Width = 0; |
} while (0) |
52 |
} |
|
53 |
|
|
54 |
|
/* Constructor to create an empty JPG container. */ |
55 |
CJPG::~CJPG () |
CJPG::CJPG (void) |
56 |
{ |
{ |
57 |
if (m_IPicture != NULL) |
m_IPicture = NULL; |
58 |
FreePictureData (); |
m_Height = 0; |
59 |
} |
m_Weight = 0; |
60 |
|
m_Width = 0; |
61 |
|
} |
62 |
|
|
63 |
/* Free The Allocated Memory That Holdes The IPicture Interface Data |
|
64 |
And Clear Picture Information. */ |
/* Deconstructor. Free all internal data. */ |
65 |
void CJPG::FreePictureData() |
CJPG::~CJPG (void) |
66 |
{ |
{ |
67 |
if (m_IPicture != NULL) { |
if (m_IPicture != NULL) |
68 |
m_IPicture->Release(); |
freePictureData (); |
69 |
m_IPicture = NULL; |
} |
70 |
m_Height = 0; |
|
71 |
m_Weight = 0; |
|
72 |
m_Width = 0; |
|
73 |
} |
/* Free the allocated memory that holdes the IPicture Interface data |
74 |
} |
and clear picture information. */ |
75 |
|
void |
76 |
|
CJPG::freePictureData (void) |
77 |
/* Open a JPG File And Load It Into IPicture (Interface) */ |
{ |
78 |
BOOL CJPG::Load(LPCSTR sFilePathName) |
if (m_IPicture != NULL) { |
79 |
{ |
m_IPicture->Release(); |
80 |
BOOL bResult = FALSE; |
m_IPicture = NULL; |
81 |
FILE * f; |
} |
82 |
int nSize = 0; |
m_Height = 0; |
83 |
|
m_Weight = 0; |
84 |
if (m_IPicture != NULL) |
m_Width = 0; |
85 |
FreePictureData (); |
} |
86 |
|
|
87 |
f = fopen (sFilePathName, "rb"); |
|
88 |
if (f) { |
/* Open a JPG File And Load It Into IPicture (Interface) */ |
89 |
struct stat st; |
BOOL |
90 |
fstat (fileno (f), &st); |
CJPG::load (LPCSTR sFilePathName) |
91 |
nSize = st.st_size; |
{ |
92 |
BYTE* pBuffer = new BYTE[nSize]; |
struct stat st; |
93 |
if (fread(pBuffer, 1, nSize, f) > 0) { |
FILE *fp; |
94 |
if (LoadPictureData (pBuffer, nSize)) |
BYTE *pBuffer; |
95 |
bResult = TRUE; |
int n; |
96 |
} |
|
97 |
fclose (f); |
if (m_IPicture != NULL) |
98 |
delete [] pBuffer; |
freePictureData (); |
99 |
} |
|
100 |
else { /* Open Failed... */ |
fp = fopen (sFilePathName, "rb"); |
101 |
MessageBox (NULL, strerror (errno), ERROR_TITLE, MB_OK | MB_ICONSTOP); |
if (!fp) { |
102 |
bResult = FALSE; |
MessageBox (NULL, strerror (errno), ERROR_TITLE, MB_OK|MB_ICONSTOP); |
103 |
} |
return FALSE; |
104 |
|
} |
105 |
m_Weight = nSize; /* Update Picture Size Info... */ |
|
106 |
|
/* avoid to load empty JPG files and make sure we still can |
107 |
if(m_IPicture != NULL) { /* Do Not Try To Read From Memory That Is Not Exist... */ |
access the file handle. */ |
108 |
m_IPicture->get_Height (&m_Height); |
if (fstat (fileno (fp), &st) || st.st_size == 0) { |
109 |
m_IPicture->get_Width (&m_Width); |
fclose (fp); |
110 |
/* Calculate Its Size On a "Standard" (96 DPI) Device Context */ |
return FALSE; |
111 |
m_Height = MulDiv (m_Height, 96, HIMETRIC_INCH); |
} |
112 |
m_Width = MulDiv (m_Width, 96, HIMETRIC_INCH); |
pBuffer = new BYTE[st.st_size]; |
113 |
} |
if (!pBuffer) |
114 |
else { /* Picture Data Is Not a Known Picture Type */ |
out_of_core (); |
115 |
m_Height = 0; |
memset (pBuffer, 0, st.st_size); |
116 |
m_Width = 0; |
n = fread (pBuffer, 1, st.st_size, fp); |
117 |
bResult = FALSE; |
fclose (fp); |
118 |
} |
|
119 |
return (bResult); |
/* not the entire file were read in, so abort here. */ |
120 |
} |
if (n != st.st_size) { |
121 |
|
delete []pBuffer; |
122 |
|
return FALSE; |
123 |
|
} |
124 |
/* Read The Picture Data From a Source (File / Resource) |
if (!loadPictureData (pBuffer, st.st_size)) { |
125 |
And Load It Into The Current IPicture Object In Use */ |
delete []pBuffer; |
126 |
BOOL CJPG::LoadPictureData (BYTE *pBuffer, int nSize) |
return FALSE; |
127 |
|
} |
128 |
{ |
delete [] pBuffer; |
129 |
BOOL bResult = FALSE; |
|
130 |
HGLOBAL hGlobal; |
m_Weight = st.st_size; /* Update Picture Size Info... */ |
131 |
void* pData; |
if (m_IPicture == NULL) { |
132 |
IStream* pStream = NULL; |
m_Height = 0; |
133 |
|
m_Width = 0; |
134 |
hGlobal = GlobalAlloc (GMEM_MOVEABLE, nSize); |
return FALSE; |
135 |
if (hGlobal == NULL) { |
} |
136 |
MessageBox (NULL, "Can not allocate enough memory", ERROR_TITLE, MB_OK | MB_ICONSTOP); |
m_IPicture->get_Height (&m_Height); |
137 |
return (FALSE); |
m_IPicture->get_Width (&m_Width); |
138 |
} |
/* Calculate Its Size On a "Standard" (96 DPI) Device Context */ |
139 |
|
m_Height = MulDiv (m_Height, 96, HIMETRIC_INCH); |
140 |
pData = GlobalLock (hGlobal); |
m_Width = MulDiv (m_Width, 96, HIMETRIC_INCH); |
141 |
memcpy (pData, pBuffer, nSize); |
return TRUE; |
142 |
GlobalUnlock (hGlobal); |
} |
143 |
|
|
144 |
if (CreateStreamOnHGlobal (hGlobal, TRUE, &pStream) == S_OK) { |
|
145 |
HRESULT hr; |
|
146 |
if ((hr = OleLoadPicture (pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&m_IPicture)) == E_NOINTERFACE) { |
/* read the picture data from a source (file / resource) |
147 |
MessageBox (NULL, "IPicture interface is not supported\t", ERROR_TITLE, MB_OK | MB_ICONSTOP); |
and load it into the current IPicture object in use */ |
148 |
return(FALSE); |
BOOL |
149 |
} |
CJPG::loadPictureData (BYTE *pBuffer, int nSize) |
150 |
else { // S_OK |
|
151 |
pStream->Release (); |
{ |
152 |
pStream = NULL; |
HGLOBAL hGlobal; |
153 |
bResult = TRUE; |
IStream* pStream = NULL; |
154 |
} |
void* pData; |
155 |
} |
BOOL bResult = FALSE; |
156 |
|
|
157 |
GlobalFree (hGlobal); |
hGlobal = GlobalAlloc (GMEM_MOVEABLE, nSize); |
158 |
return (bResult); |
if (hGlobal == NULL) |
159 |
} |
out_of_core (); |
160 |
|
|
161 |
|
pData = GlobalLock (hGlobal); |
162 |
/* Draw The Loaded Picture Direct To The Client DC */ |
memcpy (pData, pBuffer, nSize); |
163 |
BOOL CJPG::Show (HDC pDC, POINT *LeftTop, POINT *WidthHeight, int MagnifyX, int MagnifyY) |
GlobalUnlock (hGlobal); |
164 |
|
|
165 |
{ |
if (CreateStreamOnHGlobal (hGlobal, TRUE, &pStream) == S_OK) { |
166 |
if (pDC == NULL || m_IPicture == NULL) |
HRESULT hr; |
167 |
return FALSE; |
hr = OleLoadPicture (pStream, nSize, FALSE, IID_IPicture, |
168 |
|
(LPVOID *)&m_IPicture); |
169 |
long Width = 0; |
if (hr == E_NOINTERFACE) |
170 |
long Height = 0; |
MessageBox (NULL, "IPicture interface is not supported", |
171 |
m_IPicture->get_Width (&Width); |
ERROR_TITLE, MB_OK|MB_ICONSTOP); |
172 |
m_IPicture->get_Height (&Height); |
else { /* S_OK */ |
173 |
|
pStream->Release (); |
174 |
if (MagnifyX == NULL) |
pStream = NULL; |
175 |
MagnifyX = 0; |
bResult = TRUE; |
176 |
if (MagnifyY == NULL) |
} |
177 |
MagnifyY = 0; |
} |
178 |
MagnifyX = int(MulDiv (Width, GetDeviceCaps(pDC, LOGPIXELSX), HIMETRIC_INCH) * MagnifyX); |
|
179 |
MagnifyY = int(MulDiv (Height, GetDeviceCaps(pDC, LOGPIXELSY), HIMETRIC_INCH) * MagnifyY); |
GlobalFree (hGlobal); |
180 |
|
return bResult; |
181 |
RECT DrawRect; |
} |
182 |
DrawRect.left = LeftTop->x; |
|
183 |
DrawRect.top = LeftTop->y; |
|
184 |
DrawRect.right = MagnifyX; |
/* Draw the loaded picture direct to the client DC */ |
185 |
DrawRect.bottom = MagnifyY; |
BOOL |
186 |
|
CJPG::show (HDC pDC, POINT *leftTop, POINT *widthHeight, |
187 |
HRESULT hrP = NULL; |
int magnifyX, int magnifyY) |
188 |
|
|
189 |
hrP = m_IPicture->Render (pDC, |
{ |
190 |
LeftTop->x, // Left |
RECT drawRect; |
191 |
LeftTop->y, // Top |
HRESULT hr = 0; |
192 |
WidthHeight->x +MagnifyX, // Width |
long width = 0; |
193 |
WidthHeight->y +MagnifyY, // Height |
long height = 0; |
194 |
0, |
|
195 |
Height, |
if (pDC == NULL || m_IPicture == NULL) |
196 |
Width, |
return FALSE; |
197 |
-Height, |
|
198 |
&DrawRect); |
m_IPicture->get_Width (&width); |
199 |
|
m_IPicture->get_Height (&height); |
200 |
if (SUCCEEDED (hrP)) |
|
201 |
return (TRUE); |
if (magnifyX == 0) |
202 |
|
magnifyX = 0; |
203 |
MessageBox (NULL, "Can not allocate enough memory", ERROR_TITLE, MB_OK | MB_ICONSTOP); |
if (magnifyY == 0) |
204 |
return (FALSE); |
magnifyY = 0; |
205 |
} |
magnifyX = int(MulDiv (width, GetDeviceCaps(pDC, LOGPIXELSX), HIMETRIC_INCH) * magnifyX); |
206 |
|
magnifyY = int(MulDiv (height, GetDeviceCaps(pDC, LOGPIXELSY), HIMETRIC_INCH) * magnifyY); |
207 |
|
|
208 |
/* Get The Original Picture Pixel Size (Ignor What Current DC Is Using) |
drawRect.left = leftTop->x; |
209 |
Pointer To a Device Context Is Needed For Pixel Calculation, */ |
drawRect.top = leftTop->y; |
210 |
BOOL CJPG::UpdateSizeOnDC(HDC pDC) |
drawRect.right = magnifyX; |
211 |
|
drawRect.bottom = magnifyY; |
212 |
{ |
|
213 |
if(pDC == NULL || m_IPicture == NULL) { |
hr = m_IPicture->Render (pDC, |
214 |
m_Height = 0; |
leftTop->x, // Left |
215 |
m_Width = 0; |
leftTop->y, // Top |
216 |
return (FALSE); |
widthHeight->x +magnifyX, // Width |
217 |
} |
widthHeight->y +magnifyY, // Height |
218 |
|
0, |
219 |
m_IPicture->get_Height (&m_Height); |
height, |
220 |
m_IPicture->get_Width (&m_Width); |
width, |
221 |
|
-height, |
222 |
// Get Current DPI - Dot Per Inch |
&drawRect); |
223 |
int CurrentDPI_X = GetDeviceCaps (pDC, LOGPIXELSX); |
|
224 |
int CurrentDPI_Y = GetDeviceCaps (pDC, LOGPIXELSY); |
if (SUCCEEDED (hr)) |
225 |
|
return TRUE; |
226 |
m_Height = MulDiv (m_Height, CurrentDPI_Y, HIMETRIC_INCH); |
|
227 |
m_Width = MulDiv (m_Width, CurrentDPI_X, HIMETRIC_INCH); |
return FALSE; |
228 |
|
} |
229 |
return (TRUE); |
|
230 |
} |
|
231 |
|
/* Get the original picture pixel size (ignore what current DC is using) |
232 |
|
pointer to a Device Context is needed for pixel calculation, */ |
233 |
int |
BOOL |
234 |
PTD_jpg_show (HWND hwnd, POINT *p, LPCSTR name) |
CJPG::updateSizeOnDC (HDC pDC) |
235 |
{ |
|
236 |
CJPG jpg; |
{ |
237 |
HDC hdc; |
if(pDC == NULL || m_IPicture == NULL) { |
238 |
POINT p2; |
m_Height = 0; |
239 |
BOOL rc; |
m_Width = 0; |
240 |
|
return FALSE; |
241 |
rc = jpg.Load (name); |
} |
242 |
if (!rc) |
|
243 |
return -1; |
m_IPicture->get_Height (&m_Height); |
244 |
hdc = GetWindowDC (hwnd); |
m_IPicture->get_Width (&m_Width); |
245 |
rc = jpg.UpdateSizeOnDC (hdc); |
|
246 |
if (!rc) { |
/* Get Current DPI - Dot Per Inch */ |
247 |
ReleaseDC (hwnd, hdc); |
int CurrentDPI_X = GetDeviceCaps (pDC, LOGPIXELSX); |
248 |
return -2; |
int CurrentDPI_Y = GetDeviceCaps (pDC, LOGPIXELSY); |
249 |
} |
|
250 |
|
m_Height = MulDiv (m_Height, CurrentDPI_Y, HIMETRIC_INCH); |
251 |
p2.x = jpg.m_Width; |
m_Width = MulDiv (m_Width, CurrentDPI_X, HIMETRIC_INCH); |
252 |
p2.y = jpg.m_Height; |
|
253 |
rc = jpg.Show (hdc, p, &p2, 0, 0); |
return TRUE; |
254 |
|
} |
255 |
ReleaseDC (hwnd, hdc); |
|
256 |
jpg.FreePictureData (); |
/* Return height of the current image. */ |
257 |
return rc; |
LONG |
258 |
} |
CJPG::getHeight (void) |
259 |
|
{ |
260 |
|
return m_Height; |
261 |
|
} |
262 |
|
|
263 |
|
|
264 |
|
/* Return weight of the current image. */ |
265 |
|
LONG |
266 |
|
CJPG::getWeight (void) |
267 |
|
{ |
268 |
|
return m_Weight; |
269 |
|
} |
270 |
|
|
271 |
|
|
272 |
|
/* Return width of the current image. */ |
273 |
|
LONG |
274 |
|
CJPG::getWidth (void) |
275 |
|
{ |
276 |
|
return m_Width; |
277 |
|
} |