-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathIcon.h
131 lines (111 loc) · 5.7 KB
/
Icon.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
// TortoiseSVN - a Windows shell extension for easy version control
//
// Copyright (C) 2010, 2014 - TortoiseSVN
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// https://code.google.com/p/tortoisesvn/source/browse/trunk/src/Utils/IconExtractor.cpp?r=23796
// Copyright (C) 2015 - Patrik Mlekuž
// Reorganized code (2015-10-23):
// - Optimized some procedures.
// - Reduced number of code rows in "Icon.cpp" from 261 to 151 with all functionality preserved, plus additional method "importIcon(LPCTSTR iconPath)" supplied.
// - Added "icon import" functionality for multi-language resource.
// - Fixed memory leak at line "lpIR->IconImages[i].lpBits =(LPBYTE) malloc(lpIR->IconImages[i].dwNumBytes);" in method "DWORD CIconExtractor::ExtractIcon(HINSTANCE hResource, LPCTSTR id, LPCTSTR TargetICON)".
// http://www.codeproject.com/Articles/1036270/Advanced-Image-Control
#pragma once
#define WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2)
// These next two structures represent how the icon information is stored in an ICO file.
// https://msdn.microsoft.com/en-us/library/ms997538
//
typedef struct
{
BYTE bWidth; // Width (in pixels) of the image.
BYTE bHeight; // Height (in pixels )of the image.
BYTE bColorCount; // Number of colors in image (0 if >= 8bpp).
BYTE bReserved; // Reserved (must be 0).
WORD wPlanes; // Color Planes.
WORD wBitCount; // Bits per pixel.
DWORD dwBytesInRes; // How many bytes in this resource?
DWORD dwImageOffset; // Where in the file is this image?
} ICONDIRENTRY, * LPICONDIRENTRY;
typedef struct
{
WORD idReserved; // Reserved (must be 0).
WORD idType; // Resource type (1 for icons).
WORD idCount; // How many icon images?
ICONDIRENTRY idEntries[1]; // An entry for each icon image.
} ICONDIR, * LPICONDIR;
//
// These next two structs represent how the icon information is stored in an DLL/EXE file.
// The RT_GROUP_ICON resource is simply a GRPICONDIR structure.
// https://msdn.microsoft.com/en-us/library/ms997538
//
// #pragma pack
// Instructs the compiler to pack structure members with particular alignment.
// Most compilers, when you declare a struct, will insert padding between members to ensure that they are aligned to appropriate addresses in memory (usually a multiple of the type's size).
#pragma pack(push, 2) // This directive is used to insure that structure's packing in memory reserved by compiler matches the one from EXE (or DLL).
typedef struct
{
BYTE bWidth; // Width (in pixels) of the image.
BYTE bHeight; // Height (in pixels )of the image.
BYTE bColorCount; // Number of colors in image (0 if >= 8bpp).
BYTE bReserved; // Reserved (must be 0).
WORD wPlanes; // Color Planes.
WORD wBitCount; // Bits per pixel.
DWORD dwBytesInRes; // How many bytes in this resource?
WORD nID; // The ID.
} GRPICONDIRENTRY, * LPGRPICONDIRENTRY;
typedef struct
{
WORD idReserved; // Reserved (must be 0).
WORD idType; // Resource type (1 for icons).
WORD idCount; // Number of icon images.
GRPICONDIRENTRY idEntries[1]; // An entry for each icon image.
} GRPICONDIR, * LPGRPICONDIR;
#pragma pack(pop) // Default packing.
typedef struct
{
UINT width; // Width.
UINT height; // Height.
UINT colors; // Colors.
LPBYTE lpBits; // Pointer to DIB bits.
DWORD dwNumBytes; // How many bytes in this image?
LPBITMAPINFO lpbi; // Pointer to image header.
LPBYTE lpXOR; // Pointer to XOR image bits.
LPBYTE lpAND; // Pointer to AND image bits.
} ICONIMAGE, * LPICONIMAGE;
typedef struct
{
UINT nImages; // How many icon images?
ICONIMAGE iconImages[1]; // Icon Image entries.
} ICONRESOURCE, * LPICONRESOURCE;
typedef struct
{
DWORD dwBytes;
DWORD dwOffset;
} RESOURCEPOSINFO, * LPRESOURCEPOSINFO;
class CIconExtractor
{
public:
CIconExtractor() { m_lpIR = NULL; m_nImages = 0; }
~CIconExtractor() { release(); }
BOOL importIcon(HMODULE hModule, LPCTSTR name, WORD wlan); // Import icon from resource module (RT_GROUP_ICON).
BOOL importIcon(LPCTSTR iconPath); // Import icon from *.ico file.
BOOL exportIcon(LPCTSTR iconPath); // Export icon to *.ico file.
private:
void release();
inline LPSTR findDibBits(LPSTR lpbi) { return (lpbi + *(LPDWORD)lpbi + paletteSize(lpbi)); }
inline WORD paletteSize(LPSTR lpbi) { return (dibNumColors(lpbi) * sizeof(RGBQUAD)); }
inline DWORD bytesPerLine(LPBITMAPINFOHEADER lpBMIH) { return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount); }
WORD dibNumColors(LPSTR lpbi);
LPICONRESOURCE m_lpIR; // Pointer to icon resource data.
UINT m_nImages; // Number of icon images.
};