| 1 |
////////////////////////////////////////////////////////////////////////// |
| 2 |
// PictureEx.cpp: implementation of the CPictureEx class. |
| 3 |
// |
| 4 |
// Picture displaying control with support for the following formats: |
| 5 |
// GIF (including animated GIF87a and GIF89a), JPEG, BMP, WMF, ICO, CUR |
| 6 |
// |
| 7 |
// Written by Oleg Bykov (oleg_bykoff@rsdn.ru) |
| 8 |
// Copyright (c) 2001 |
| 9 |
// |
| 10 |
////////////////////////////////////////////////////////////////////////// |
| 11 |
|
| 12 |
#if !defined(AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_) |
| 13 |
#define AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_ |
| 14 |
|
| 15 |
#if _MSC_VER > 1000 |
| 16 |
#pragma once |
| 17 |
#endif // _MSC_VER > 1000 |
| 18 |
#include <vector> |
| 19 |
|
| 20 |
//#define GIF_TRACING // uncomment it if you want detailed TRACEs |
| 21 |
|
| 22 |
////////////////////////////////////////////////////////////////////////// |
| 23 |
|
| 24 |
class CPictureEx: public CStatic |
| 25 |
{ |
| 26 |
public: |
| 27 |
|
| 28 |
struct TFrame // structure that keeps a single frame info |
| 29 |
{ |
| 30 |
IPicture *m_pPicture; // pointer to the interface used for drawing |
| 31 |
SIZE m_frameSize; |
| 32 |
SIZE m_frameOffset; |
| 33 |
UINT m_nDelay; // delay (in 1/100s of a second) |
| 34 |
UINT m_nDisposal; // disposal method |
| 35 |
}; |
| 36 |
|
| 37 |
#pragma pack(1) // turn byte alignment on |
| 38 |
enum GIFBlockTypes |
| 39 |
{ |
| 40 |
BLOCK_UNKNOWN, |
| 41 |
BLOCK_APPEXT, |
| 42 |
BLOCK_COMMEXT, |
| 43 |
BLOCK_CONTROLEXT, |
| 44 |
BLOCK_PLAINTEXT, |
| 45 |
BLOCK_IMAGE, |
| 46 |
BLOCK_TRAILER |
| 47 |
}; |
| 48 |
|
| 49 |
enum ControlExtValues // graphic control extension packed field values |
| 50 |
{ |
| 51 |
GCX_PACKED_DISPOSAL, // disposal method |
| 52 |
GCX_PACKED_USERINPUT, |
| 53 |
GCX_PACKED_TRANSPCOLOR |
| 54 |
}; |
| 55 |
|
| 56 |
enum LSDPackedValues // logical screen descriptor packed field values |
| 57 |
{ |
| 58 |
LSD_PACKED_GLOBALCT, |
| 59 |
LSD_PACKED_CRESOLUTION, |
| 60 |
LSD_PACKED_SORT, |
| 61 |
LSD_PACKED_GLOBALCTSIZE |
| 62 |
}; |
| 63 |
|
| 64 |
enum IDPackedValues // image descriptor packed field values |
| 65 |
{ |
| 66 |
ID_PACKED_LOCALCT, |
| 67 |
ID_PACKED_INTERLACE, |
| 68 |
ID_PACKED_SORT, |
| 69 |
ID_PACKED_LOCALCTSIZE |
| 70 |
}; |
| 71 |
|
| 72 |
struct TGIFHeader // GIF header |
| 73 |
{ |
| 74 |
char m_cSignature[3]; // Signature - Identifies the GIF Data Stream |
| 75 |
// This field contains the fixed value 'GIF' |
| 76 |
char m_cVersion[3]; // Version number. May be one of the following: |
| 77 |
// "87a" or "89a" |
| 78 |
}; |
| 79 |
|
| 80 |
struct TGIFLSDescriptor // Logical Screen Descriptor |
| 81 |
{ |
| 82 |
WORD m_wWidth; // 2 bytes. Logical screen width |
| 83 |
WORD m_wHeight; // 2 bytes. Logical screen height |
| 84 |
|
| 85 |
unsigned char m_cPacked; // packed field |
| 86 |
|
| 87 |
unsigned char m_cBkIndex; // 1 byte. Background color index |
| 88 |
unsigned char m_cPixelAspect; // 1 byte. Pixel aspect ratio |
| 89 |
inline int GetPackedValue(enum LSDPackedValues Value); |
| 90 |
}; |
| 91 |
|
| 92 |
struct TGIFAppExtension // application extension block |
| 93 |
{ |
| 94 |
unsigned char m_cExtIntroducer; // extension introducer (0x21) |
| 95 |
unsigned char m_cExtLabel; // app. extension label (0xFF) |
| 96 |
unsigned char m_cBlockSize; // fixed value of 11 |
| 97 |
char m_cAppIdentifier[8]; // application identifier |
| 98 |
char m_cAppAuth[3]; // application authentication code |
| 99 |
}; |
| 100 |
|
| 101 |
struct TGIFControlExt // graphic control extension block |
| 102 |
{ |
| 103 |
unsigned char m_cExtIntroducer; // extension introducer (0x21) |
| 104 |
unsigned char m_cControlLabel; // control extension label (0xF9) |
| 105 |
unsigned char m_cBlockSize; // fixed value of 4 |
| 106 |
unsigned char m_cPacked; // packed field |
| 107 |
WORD m_wDelayTime; // delay time |
| 108 |
unsigned char m_cTColorIndex; // transparent color index |
| 109 |
unsigned char m_cBlockTerm; // block terminator (0x00) |
| 110 |
public: |
| 111 |
inline int GetPackedValue(enum ControlExtValues Value); |
| 112 |
}; |
| 113 |
|
| 114 |
struct TGIFCommentExt // comment extension block |
| 115 |
{ |
| 116 |
unsigned char m_cExtIntroducer; // extension introducer (0x21) |
| 117 |
unsigned char m_cCommentLabel; // comment extension label (0xFE) |
| 118 |
}; |
| 119 |
|
| 120 |
struct TGIFPlainTextExt // plain text extension block |
| 121 |
{ |
| 122 |
unsigned char m_cExtIntroducer; // extension introducer (0x21) |
| 123 |
unsigned char m_cPlainTextLabel; // text extension label (0x01) |
| 124 |
unsigned char m_cBlockSize; // fixed value of 12 |
| 125 |
WORD m_wLeftPos; // text grid left position |
| 126 |
WORD m_wTopPos; // text grid top position |
| 127 |
WORD m_wGridWidth; // text grid width |
| 128 |
WORD m_wGridHeight; // text grid height |
| 129 |
unsigned char m_cCellWidth; // character cell width |
| 130 |
unsigned char m_cCellHeight; // character cell height |
| 131 |
unsigned char m_cFgColor; // text foreground color index |
| 132 |
unsigned char m_cBkColor; // text background color index |
| 133 |
}; |
| 134 |
|
| 135 |
struct TGIFImageDescriptor // image descriptor block |
| 136 |
{ |
| 137 |
unsigned char m_cImageSeparator; // image separator byte (0x2C) |
| 138 |
WORD m_wLeftPos; // image left position |
| 139 |
WORD m_wTopPos; // image top position |
| 140 |
WORD m_wWidth; // image width |
| 141 |
WORD m_wHeight; // image height |
| 142 |
unsigned char m_cPacked; // packed field |
| 143 |
inline int GetPackedValue(enum IDPackedValues Value); |
| 144 |
}; |
| 145 |
|
| 146 |
#pragma pack() // turn byte alignment off |
| 147 |
public: |
| 148 |
BOOL GetPaintRect(RECT *lpRect); |
| 149 |
BOOL SetPaintRect(const RECT *lpRect); |
| 150 |
CPictureEx(); |
| 151 |
virtual ~CPictureEx(); |
| 152 |
void Stop(); // stops animation |
| 153 |
void UnLoad(); // stops animation plus releases all resources |
| 154 |
|
| 155 |
BOOL IsGIF() const; |
| 156 |
BOOL IsPlaying() const; |
| 157 |
BOOL IsAnimatedGIF() const; |
| 158 |
SIZE GetSize() const; |
| 159 |
int GetFrameCount() const; |
| 160 |
COLORREF GetBkColor() const; |
| 161 |
void SetBkColor(COLORREF clr); |
| 162 |
|
| 163 |
// draws the picture (starts an animation thread if needed) |
| 164 |
// if an animation was previously stopped by Stop(), |
| 165 |
// continues it from the last displayed frame |
| 166 |
BOOL Draw(); |
| 167 |
|
| 168 |
// loads a picture from a file |
| 169 |
// i.e. Load(_T("mypic.gif")); |
| 170 |
BOOL Load(LPCTSTR szFileName); |
| 171 |
|
| 172 |
// loads a picture from a global memory block (allocated by GlobalAlloc) |
| 173 |
// Warning: this function DOES NOT free the global memory, pointed to by hGlobal |
| 174 |
BOOL Load(HGLOBAL hGlobal, DWORD dwSize); |
| 175 |
|
| 176 |
// loads a picture from a program resource |
| 177 |
// i.e. Load(MAKEINTRESOURCE(IDR_MYPIC),_T("GIFTYPE")); |
| 178 |
BOOL Load(LPCTSTR szResourceName, LPCTSTR szResourceType); |
| 179 |
|
| 180 |
protected: |
| 181 |
|
| 182 |
#ifdef GIF_TRACING |
| 183 |
void EnumGIFBlocks(); |
| 184 |
void WriteDataOnDisk(CString szFileName, HGLOBAL hData, DWORD dwSize); |
| 185 |
#endif // GIF_TRACING |
| 186 |
RECT m_PaintRect; |
| 187 |
SIZE m_PictureSize; |
| 188 |
COLORREF m_clrBackground; |
| 189 |
UINT m_nCurrFrame; |
| 190 |
UINT m_nDataSize; |
| 191 |
UINT m_nCurrOffset; |
| 192 |
UINT m_nGlobalCTSize; |
| 193 |
BOOL m_bIsGIF; |
| 194 |
BOOL m_bIsPlaying; |
| 195 |
volatile BOOL m_bExitThread; |
| 196 |
BOOL m_bIsInitialized; |
| 197 |
HDC m_hMemDC; |
| 198 |
|
| 199 |
HDC m_hDispMemDC; |
| 200 |
HBITMAP m_hDispMemBM; |
| 201 |
HBITMAP m_hDispOldBM; |
| 202 |
|
| 203 |
HBITMAP m_hBitmap; |
| 204 |
HBITMAP m_hOldBitmap; |
| 205 |
HANDLE m_hThread; |
| 206 |
HANDLE m_hExitEvent; |
| 207 |
IPicture * m_pPicture; |
| 208 |
TGIFHeader * m_pGIFHeader; |
| 209 |
unsigned char * m_pRawData; |
| 210 |
TGIFLSDescriptor * m_pGIFLSDescriptor; |
| 211 |
std::vector<TFrame> m_arrFrames; |
| 212 |
|
| 213 |
void ThreadAnimation();static UINT WINAPI _ThreadAnimation(LPVOID pParam); |
| 214 |
|
| 215 |
int GetNextBlockLen() const; |
| 216 |
BOOL SkipNextBlock(); |
| 217 |
BOOL SkipNextGraphicBlock(); |
| 218 |
BOOL PrepareDC(int nWidth, int nHeight); |
| 219 |
void ResetDataPointer(); |
| 220 |
enum GIFBlockTypes GetNextBlock() const; |
| 221 |
UINT GetSubBlocksLen(UINT nStartingOffset) const; |
| 222 |
HGLOBAL GetNextGraphicBlock(UINT *pBlockLen, UINT *pDelay, |
| 223 |
SIZE *pBlockSize, SIZE *pBlockOffset, UINT *pDisposal); |
| 224 |
|
| 225 |
// Generated message map functions |
| 226 |
//{{AFX_MSG(CPictureEx) |
| 227 |
afx_msg void OnDestroy(); |
| 228 |
afx_msg void OnPaint(); |
| 229 |
//}}AFX_MSG |
| 230 |
|
| 231 |
DECLARE_MESSAGE_MAP() |
| 232 |
}; |
| 233 |
|
| 234 |
#endif // !defined(AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_) |
| 235 |
|
| 236 |
////////////////////////////////////////////////////////////////////////// |