ReactOS 0.4.16-dev-1019-g2c2cdfd
loader.cpp File Reference
#include <windows.h>
#include <objbase.h>
#include <gdiplus.h>
#include "shimgvw.h"
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for loader.cpp:

Go to the source code of this file.

Classes

struct  IMAGESTATS
 
class  BitmapInfoHeader
 
union  PNGSIGNATURE
 
struct  PNGCHUNKHEADER
 
struct  PNGCHUNKFOOTER
 
struct  PNGIHDR
 
struct  PNGSIGANDIHDR
 
struct  PNGFOOTER
 

Macros

#define HResultFromWin32   SHIMGVW_HResultFromWin32
 

Functions

static HRESULT Read (HANDLE hFile, void *Buffer, DWORD Size)
 
static bool IsPngSignature (const void *buffer)
 
static bool IsPngSignature (const void *buffer, SIZE_T size)
 
static BYTE GetPngBppFromIHDRData (const void *buffer)
 
static bool GetInfoFromPng (const void *file, SIZE_T size, IMAGESTATS &info)
 
static bool GetInfoFromBmp (const void *pBitmapInfo, IMAGESTATS &info)
 
static bool GetInfoFromIcoBmp (const void *pBitmapInfo, IMAGESTATS &info)
 
EXTERN_C PCWSTR GetExtraExtensionsGdipList (VOID)
 
static void OverrideFileContent (HGLOBAL &hMem, DWORD &Size)
 
static HRESULT LoadImageFromStream (IStream *pStream, GpImage **ppImage)
 
static HRESULT LoadImageFromFileHandle (HANDLE hFile, GpImage **ppImage)
 
EXTERN_C HRESULT LoadImageFromPath (LPCWSTR Path, GpImage **ppImage)
 

Macro Definition Documentation

◆ HResultFromWin32

#define HResultFromWin32   SHIMGVW_HResultFromWin32

Definition at line 14 of file loader.cpp.

Function Documentation

◆ GetExtraExtensionsGdipList()

EXTERN_C PCWSTR GetExtraExtensionsGdipList ( VOID  )

Definition at line 131 of file loader.cpp.

132{
133 return L"*.CUR"; // "*.FOO;*.BAR" etc.
134}
#define L(x)
Definition: ntvdm.h:50

Referenced by pBuildFileList().

◆ GetInfoFromBmp()

static bool GetInfoFromBmp ( const void pBitmapInfo,
IMAGESTATS info 
)
static

Definition at line 114 of file loader.cpp.

115{
116 BitmapInfoHeader bih(pBitmapInfo);
117 info.w = bih.biWidth;
118 info.h = abs((int)bih.biHeight);
119 UINT bpp = bih.biBitCount * bih.biPlanes;
120 info.bpp = LOBYTE(bpp);
121 return info.w && bpp == info.bpp;
122}
DWORD bpp
Definition: surface.c:185
#define abs(i)
Definition: fconv.c:206
#define LOBYTE(W)
Definition: jmemdos.c:487
unsigned int UINT
Definition: ndis.h:50

Referenced by GetInfoFromIcoBmp().

◆ GetInfoFromIcoBmp()

static bool GetInfoFromIcoBmp ( const void pBitmapInfo,
IMAGESTATS info 
)
static

Definition at line 124 of file loader.cpp.

125{
126 bool ret = GetInfoFromBmp(pBitmapInfo, info);
127 info.h /= 2; // Don't include mask
128 return ret && info.h;
129}
static bool GetInfoFromBmp(const void *pBitmapInfo, IMAGESTATS &info)
Definition: loader.cpp:114
int ret

Referenced by OverrideFileContent().

◆ GetInfoFromPng()

static bool GetInfoFromPng ( const void file,
SIZE_T  size,
IMAGESTATS info 
)
static

Definition at line 94 of file loader.cpp.

95{
96 C_ASSERT(sizeof(PNGSIGNATURE) == 8);
97 C_ASSERT(sizeof(PNGSIGANDIHDR) == 8 + (4 + 4 + (4 + 4 + 5) + 4));
98
99 if (size > sizeof(PNGSIGANDIHDR) + sizeof(PNGFOOTER) && IsPngSignature(file))
100 {
101 const UINT PNGIHDRSIG = 0x52444849; // Note: Big endian
102 const UINT* chunkhdr = (UINT*)((char*)file + sizeof(PNGSIGNATURE));
103 if (BigToHost32(chunkhdr[0]) >= sizeof(PNGIHDR) && chunkhdr[1] == PNGIHDRSIG)
104 {
105 info.w = BigToHost32(chunkhdr[2]);
106 info.h = BigToHost32(chunkhdr[3]);
107 info.bpp = GetPngBppFromIHDRData(&chunkhdr[2]);
108 return info.bpp != 0;
109 }
110 }
111 return false;
112}
GLsizeiptr size
Definition: glext.h:5919
#define C_ASSERT(e)
Definition: intsafe.h:73
static BYTE GetPngBppFromIHDRData(const void *buffer)
Definition: loader.cpp:87
static bool IsPngSignature(const void *buffer)
Definition: loader.cpp:75
Definition: fci.c:127

Referenced by OverrideFileContent().

◆ GetPngBppFromIHDRData()

static BYTE GetPngBppFromIHDRData ( const void buffer)
static

Definition at line 87 of file loader.cpp.

88{
89 static const BYTE channels[] = { 1, 0, 3, 1, 2, 0, 4 };
90 const BYTE* p = (BYTE*)buffer, depth = p[8], type = p[8 + 1];
91 return (depth <= 16 && type <= 6) ? channels[type] * depth : 0;
92}
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLfloat GLfloat p
Definition: glext.h:8902
int This channels
Definition: rdpsnd_libao.c:37
unsigned char BYTE
Definition: xxhash.c:193

Referenced by GetInfoFromPng().

◆ IsPngSignature() [1/2]

static bool IsPngSignature ( const void buffer)
inlinestatic

Definition at line 75 of file loader.cpp.

76{
77 const BYTE* p = (BYTE*)buffer;
78 return p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G' &&
79 p[4] == 0x0D && p[5] == 0x0A && p[6] == 0x1A && p[7] == 0x0A;
80}

Referenced by GetInfoFromPng(), IsPngSignature(), and OverrideFileContent().

◆ IsPngSignature() [2/2]

static bool IsPngSignature ( const void buffer,
SIZE_T  size 
)
inlinestatic

Definition at line 82 of file loader.cpp.

83{
84 return size >= sizeof(PNGSIGNATURE) && IsPngSignature(buffer);
85}

◆ LoadImageFromFileHandle()

static HRESULT LoadImageFromFileHandle ( HANDLE  hFile,
GpImage **  ppImage 
)
static

Definition at line 236 of file loader.cpp.

237{
239 if (!size || size == INVALID_FILE_SIZE)
241
243 if (!hMem)
245 HRESULT hr = E_FAIL;
246 void* buffer = GlobalLock(hMem);
247 if (buffer)
248 {
249 hr = Read(hFile, buffer, size);
250 GlobalUnlock(hMem);
251 if (SUCCEEDED(hr))
252 {
254 IStream* pStream;
255 if (SUCCEEDED(hr = CreateStreamOnHGlobal(hMem, TRUE, &pStream)))
256 {
257 // CreateStreamOnHGlobal does not know the real size, we do
258 pStream->SetSize(MakeULargeInteger(size));
259 hr = LoadImageFromStream(pStream, ppImage);
260 pStream->Release(); // Calls GlobalFree
261 return hr;
262 }
263 }
264 }
265 GlobalFree(hMem);
266 return hr;
267}
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
unsigned long DWORD
Definition: ntddk_ex.h:95
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
HRESULT SetSize([in] ULARGE_INTEGER libNewSize)
ULONG Release()
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static HRESULT LoadImageFromStream(IStream *pStream, GpImage **ppImage)
Definition: loader.cpp:230
static void OverrideFileContent(HGLOBAL &hMem, DWORD &Size)
Definition: loader.cpp:136
#define HResultFromWin32
Definition: loader.cpp:14
_In_ HANDLE hFile
Definition: mswsock.h:90
static ULARGE_INTEGER MakeULargeInteger(UINT64 value)
Definition: shimgvw.h:106
HRESULT hr
Definition: shlfolder.c:183
_In_ BOOLEAN Read
Definition: strmini.h:479
#define INVALID_FILE_SIZE
Definition: winbase.h:574
#define GMEM_MOVEABLE
Definition: winbase.h:320

Referenced by LoadImageFromPath().

◆ LoadImageFromPath()

EXTERN_C HRESULT LoadImageFromPath ( LPCWSTR  Path,
GpImage **  ppImage 
)

Definition at line 269 of file loader.cpp.

270{
271 // NOTE: GdipLoadImageFromFile locks the file.
272 // Avoid file locking by using GdipLoadImageFromStream and memory stream.
273
277 {
280 return hr;
281 }
283}
PRTL_UNICODE_STRING_BUFFER Path
#define CloseHandle
Definition: compat.h:739
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
static HRESULT LoadImageFromFileHandle(HANDLE hFile, GpImage **ppImage)
Definition: loader.cpp:236
#define FILE_FLAG_SEQUENTIAL_SCAN
Definition: disk.h:43
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by Preview_pLoadImage().

◆ LoadImageFromStream()

static HRESULT LoadImageFromStream ( IStream pStream,
GpImage **  ppImage 
)
static

Definition at line 230 of file loader.cpp.

231{
232 Status status = DllExports::GdipLoadImageFromStream(pStream, ppImage);
234}
Status
Definition: gdiplustypes.h:25
static HRESULT HResultFromGdiplus(Status status)
Definition: shimgvw.h:119
Definition: ps.c:97

Referenced by LoadImageFromFileHandle().

◆ OverrideFileContent()

static void OverrideFileContent ( HGLOBAL hMem,
DWORD Size 
)
static

Definition at line 136 of file loader.cpp.

137{
138 PBYTE buffer = (PBYTE)GlobalLock(hMem);
139 if (!buffer)
140 return;
141
142 // TODO: We could try to load an ICO/PNG/BMP resource from a PE file here into buffer
143
144 // ICO/CUR
145 struct ICOHDR { WORD Sig, Type, Count; };
146 ICOHDR* pIcoHdr = (ICOHDR*)buffer;
147 if (Size > sizeof(ICOHDR) && !pIcoHdr->Sig && pIcoHdr->Type > 0 && pIcoHdr->Type < 3 && pIcoHdr->Count)
148 {
149 const UINT minbmp = sizeof(BITMAPCOREHEADER) + 1, minpng = sizeof(PNGSIGANDIHDR);
150 const UINT minfile = min(minbmp, minpng), count = pIcoHdr->Count;
151 struct ICOENTRY { BYTE w, h, pal, null; WORD planes, bpp; UINT size, offset; };
152 ICOENTRY* entries = (ICOENTRY*)&pIcoHdr[1];
153 if (Size - sizeof(ICOHDR) > (sizeof(ICOENTRY) + minfile) * count)
154 {
155 UINT64 best = 0;
156 int bestindex = -1;
157 // Inspect all the images and find the "best" image
158 for (UINT i = 0; i < count; ++i)
159 {
160 BOOL valid = FALSE;
162 const BYTE* data = buffer + entries[i].offset;
163 if (IsPngSignature(data, entries[i].size))
164 valid = GetInfoFromPng(data, entries[i].size, info);
165 else
167
168 if (valid)
169 {
170 // Note: This treats bpp as more important compared to LookupIconIdFromDirectoryEx
171 UINT64 score = UINT64(info.w) * info.h * info.bpp;
172 if (score > best)
173 {
174 best = score;
175 bestindex = i;
176 }
177 }
178 }
179 if (bestindex >= 0)
180 {
181 if (pIcoHdr->Type == 2)
182 {
183 // GDI+ does not support .cur files, convert to .ico
184 pIcoHdr->Type = 1;
185#if 0 // Because we are already overriding the order, we don't need to correct the ICOENTRY lookup info
186 for (UINT i = 0; i < count; ++i)
187 {
189 const BYTE* data = buffer + entries[i].offset;
190 if (IsPngSignature(data, entries[i].size))
191 {
193 if (!GetInfoFromPng(data, entries[i].size, info))
194 continue;
195 bih.biPlanes = 1;
196 bih.biBitCount = info.bpp;
197 entries[i].pal = 0;
198 }
199 else
200 {
201 bih.Initialize(data);
202 entries[i].pal = bih.biPlanes * bih.biBitCount <= 8 ? bih.biClrUsed : 0;
203 }
204 entries[i].planes = (WORD)bih.biPlanes;
205 entries[i].bpp = (WORD)bih.biBitCount;
206 }
207#endif
208 }
209#if 0
210 // Convert to a .ico with a single image
211 pIcoHdr->Count = 1;
212 const BYTE* data = buffer + entries[bestindex].offset;
213 entries[0] = entries[bestindex];
214 entries[0].offset = (UINT)UINT_PTR((PBYTE)&entries[1] - buffer);
215 MoveMemory(buffer + entries[0].offset, data, entries[0].size);
216 Size = entries[0].offset + entries[0].size;
217#else
218 // Place the best image first, GDI+ will return the first image
219 ICOENTRY temp = entries[0];
220 entries[0] = entries[bestindex];
221 entries[bestindex] = temp;
222#endif
223 }
224 }
225 }
226
227 GlobalUnlock(hMem);
228}
unsigned long long UINT64
Type
Definition: Type.h:7
int null(void)
Definition: ftp.c:1794
void Initialize(const void *pbmiHeader)
Definition: loader.cpp:36
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
BOOLEAN valid
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLintptr offset
Definition: glext.h:5920
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static bool GetInfoFromIcoBmp(const void *pBitmapInfo, IMAGESTATS &info)
Definition: loader.cpp:124
static bool GetInfoFromPng(const void *file, SIZE_T size, IMAGESTATS &info)
Definition: loader.cpp:94
#define min(a, b)
Definition: monoChain.cc:55
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
int Count
Definition: noreturn.cpp:7
BYTE * PBYTE
Definition: pedump.c:66
static calc_node_t temp
Definition: rpn_ieee.c:38
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define MoveMemory
Definition: winbase.h:1740
struct tagBITMAPCOREHEADER BITMAPCOREHEADER

Referenced by LoadImageFromFileHandle().

◆ Read()

static HRESULT Read ( HANDLE  hFile,
void Buffer,
DWORD  Size 
)
static

Definition at line 16 of file loader.cpp.

17{
18 DWORD Transferred;
19 if (!ReadFile(hFile, Buffer, Size, &Transferred, NULL))
21 return Size == Transferred ? S_OK : HResultFromWin32(ERROR_HANDLE_EOF);
22}
Definition: bufpool.h:45
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define S_OK
Definition: intsafe.h:52
#define ERROR_HANDLE_EOF
Definition: winerror.h:140