-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPictureEx.h
305 lines (268 loc) · 10.3 KB
/
PictureEx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
//////////////////////////////////////////////////////////////////////
// PictureEx.cpp: implementation of the CPictureEx class.
//
// Picture displaying control with support for the following formats:
// GIF (including animated GIF87a and GIF89a), JPEG, BMP, WMF, ICO, CUR
//
// Written by Oleg Bykov ([email protected])
// Copyright (c) 2001
//
// To use CPictureEx, follow these steps:
// - place a static control on your dialog (either a text or a bitmap)
// - change its identifier to something else (e.g. IDC_MYPIC)
// - associate a CStatic with it using ClassWizard
// - in your dialog's header file replace CStatic with CPictureEx
// (don't forget to #include "PictureEx.h" and add
// PictureEx.h and PictureEx.cpp to your project)
// - call one of the overloaded CPictureEx::Load() functions somewhere
// (OnInitDialog is a good place to start)
// - if the preceding Load() succeeded call Draw()
//
// You can also add the control by defining a member variable of type
// CPictureEx, calling CPictureEx::Create (derived from CStatic), then
// CPictureEx::Load and CPictureEx::Draw.
//
// By default, the control initializes its background to COLOR_3DFACE
// (see CPictureEx::PrepareDC()). You can change the background by
// calling CPictureEx::SetBkColor(COLORREF) after CPictureEx::Load().
//
// I decided to leave in the class the functions to write separate frames from
// animated GIF to disk. If you want to use them, uncomment #define GIF_TRACING
// and an appropriate section in CPictureEx::Load(HGLOBAL, DWORD). These functions
// won't be compiled and linked to your project unless you uncomment #define GIF_TRACING,
// so you don't have to worry.
//
// Warning: this code hasn't been subject to a heavy testing, so
// use it on your own risk. The author accepts no liability for the
// possible damage caused by this code.
//
// Version 1.0 7 Aug 2001
// Initial release
//
// Version 1.1 6 Sept 2001
// ATL version of the class
//
// Version 1.2 14 Oct 2001
// - Fixed a problem with loading GIFs from resources
// in MFC-version of the class for multi-modules apps.
// Thanks to Ruben Avila-Carretero for finding this out.
//
// - Got rid of waitable timer in ThreadAnimation()
// Now CPictureEx[Wnd] works in Win95 too.
// Thanks to Alex Egiazarov and Wayne King for the idea.
//
// - Fixed a visual glitch of using SetBkColor.
// Thanks to Kwangjin Lee for finding this out.
//
// Version 1.3 10 Nov 2001
// - Fixed a DC leak. One DC leaked per each UnLoad()
// (forgot to put a ReleaseDC() in the end of
// CPictureExWnd::PrepareDC() function).
//
// - Now it is possible to set a clipping rectangle using
// CPictureEx[Wnd]::SetPaintRect(const LPRECT) function.
// The LPRECT parameter tells the class what portion of
// a picture should it display. If the clipping rect is
// not set, the whole picture is shown.
// Thanks to Fabrice Rodriguez for the idea.
//
// - Added support for Stop/Draw. Now you can Stop() an
// animated GIF, then Draw() it again, it will continue
// animation from the frame it was stopped on. You can
// also know if a GIF is currently playing with the
// IsPlaying() function.
//
// - Got rid of math.h and made m_bExitThread volatile.
// Thanks to Piotr Sawicki for the suggestion.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_)
#define AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <vector>
//#define GIF_TRACING // uncomment it if you want detailed TRACEs
class CPictureEx : public CStatic
{
public:
struct TFrame // structure that keeps a single frame info
{
IPicture *m_pPicture; // pointer to the interface used for drawing
SIZE m_frameSize;
SIZE m_frameOffset;
UINT m_nDelay; // delay (in 1/100s of a second)
UINT m_nDisposal; // disposal method
};
#pragma pack(1) // turn byte alignment on
enum GIFBlockTypes
{
BLOCK_UNKNOWN,
BLOCK_APPEXT,
BLOCK_COMMEXT,
BLOCK_CONTROLEXT,
BLOCK_PLAINTEXT,
BLOCK_IMAGE,
BLOCK_TRAILER
};
enum ControlExtValues // graphic control extension packed field values
{
GCX_PACKED_DISPOSAL, // disposal method
GCX_PACKED_USERINPUT,
GCX_PACKED_TRANSPCOLOR
};
enum LSDPackedValues // logical screen descriptor packed field values
{
LSD_PACKED_GLOBALCT,
LSD_PACKED_CRESOLUTION,
LSD_PACKED_SORT,
LSD_PACKED_GLOBALCTSIZE
};
enum IDPackedValues // image descriptor packed field values
{
ID_PACKED_LOCALCT,
ID_PACKED_INTERLACE,
ID_PACKED_SORT,
ID_PACKED_LOCALCTSIZE
};
struct TGIFHeader // GIF header
{
char m_cSignature[3]; // Signature - Identifies the GIF Data Stream
// This field contains the fixed value 'GIF'
char m_cVersion[3]; // Version number. May be one of the following:
// "87a" or "89a"
};
struct TGIFLSDescriptor // Logical Screen Descriptor
{
WORD m_wWidth; // 2 bytes. Logical screen width
WORD m_wHeight; // 2 bytes. Logical screen height
unsigned char m_cPacked; // packed field
unsigned char m_cBkIndex; // 1 byte. Background color index
unsigned char m_cPixelAspect; // 1 byte. Pixel aspect ratio
inline int GetPackedValue(enum LSDPackedValues Value);
};
struct TGIFAppExtension // application extension block
{
unsigned char m_cExtIntroducer; // extension introducer (0x21)
unsigned char m_cExtLabel; // app. extension label (0xFF)
unsigned char m_cBlockSize; // fixed value of 11
char m_cAppIdentifier[8]; // application identifier
char m_cAppAuth[3]; // application authentication code
};
struct TGIFControlExt // graphic control extension block
{
unsigned char m_cExtIntroducer; // extension introducer (0x21)
unsigned char m_cControlLabel; // control extension label (0xF9)
unsigned char m_cBlockSize; // fixed value of 4
unsigned char m_cPacked; // packed field
WORD m_wDelayTime; // delay time
unsigned char m_cTColorIndex; // transparent color index
unsigned char m_cBlockTerm; // block terminator (0x00)
public:
inline int GetPackedValue(enum ControlExtValues Value);
};
struct TGIFCommentExt // comment extension block
{
unsigned char m_cExtIntroducer; // extension introducer (0x21)
unsigned char m_cCommentLabel; // comment extension label (0xFE)
};
struct TGIFPlainTextExt // plain text extension block
{
unsigned char m_cExtIntroducer; // extension introducer (0x21)
unsigned char m_cPlainTextLabel; // text extension label (0x01)
unsigned char m_cBlockSize; // fixed value of 12
WORD m_wLeftPos; // text grid left position
WORD m_wTopPos; // text grid top position
WORD m_wGridWidth; // text grid width
WORD m_wGridHeight; // text grid height
unsigned char m_cCellWidth; // character cell width
unsigned char m_cCellHeight; // character cell height
unsigned char m_cFgColor; // text foreground color index
unsigned char m_cBkColor; // text background color index
};
struct TGIFImageDescriptor // image descriptor block
{
unsigned char m_cImageSeparator; // image separator byte (0x2C)
WORD m_wLeftPos; // image left position
WORD m_wTopPos; // image top position
WORD m_wWidth; // image width
WORD m_wHeight; // image height
unsigned char m_cPacked; // packed field
inline int GetPackedValue(enum IDPackedValues Value);
};
#pragma pack() // turn byte alignment off
public:
BOOL GetPaintRect(RECT *lpRect);
BOOL SetPaintRect(const RECT *lpRect);
CPictureEx();
virtual ~CPictureEx();
void Stop(); // stops animation
void UnLoad(); // stops animation plus releases all resources
BOOL IsGIF() const;
BOOL IsPlaying() const;
BOOL IsAnimatedGIF() const;
SIZE GetSize() const;
int GetFrameCount() const;
COLORREF GetBkColor() const;
void SetBkColor(COLORREF clr);
// draws the picture (starts an animation thread if needed)
// if an animation was previously stopped by Stop(),
// continues it from the last displayed frame
BOOL Draw();
// loads a picture from a file
// i.e. Load(_T("mypic.gif"));
BOOL Load(LPCTSTR szFileName);
// loads a picture from a global memory block (allocated by GlobalAlloc)
// Warning: this function DOES NOT free the global memory, pointed to by hGlobal
BOOL Load(HGLOBAL hGlobal, DWORD dwSize);
// loads a picture from a program resource
// i.e. Load(MAKEINTRESOURCE(IDR_MYPIC),_T("GIFTYPE"));
BOOL Load(LPCTSTR szResourceName,LPCTSTR szResourceType);
protected:
#ifdef GIF_TRACING
void EnumGIFBlocks();
void WriteDataOnDisk(CString szFileName, HGLOBAL hData, DWORD dwSize);
#endif // GIF_TRACING
RECT m_PaintRect;
SIZE m_PictureSize;
COLORREF m_clrBackground;
UINT m_nCurrFrame;
UINT m_nDataSize;
UINT m_nCurrOffset;
UINT m_nGlobalCTSize;
BOOL m_bIsGIF;
BOOL m_bIsPlaying;
volatile BOOL m_bExitThread;
BOOL m_bIsInitialized;
HDC m_hMemDC;
HDC m_hDispMemDC;
HBITMAP m_hDispMemBM;
HBITMAP m_hDispOldBM;
HBITMAP m_hBitmap;
HBITMAP m_hOldBitmap;
HANDLE m_hThread;
HANDLE m_hExitEvent;
IPicture * m_pPicture;
TGIFHeader * m_pGIFHeader;
unsigned char * m_pRawData;
TGIFLSDescriptor * m_pGIFLSDescriptor;
std::vector<TFrame> m_arrFrames;
void ThreadAnimation();
static UINT WINAPI _ThreadAnimation(LPVOID pParam);
int GetNextBlockLen() const;
BOOL SkipNextBlock();
BOOL SkipNextGraphicBlock();
BOOL PrepareDC(int nWidth, int nHeight);
void ResetDataPointer();
enum GIFBlockTypes GetNextBlock() const;
UINT GetSubBlocksLen(UINT nStartingOffset) const;
HGLOBAL GetNextGraphicBlock(UINT *pBlockLen, UINT *pDelay,
SIZE *pBlockSize, SIZE *pBlockOffset, UINT *pDisposal);
// Generated message map functions
//{{AFX_MSG(CPictureEx)
afx_msg void OnDestroy();
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif // !defined(AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_)