Code: Select all
#include "pch.h"
#include "PSDThumbnailProvider.h"
#include "PSDReader.h"
#include
...
bool g_magickInitialized = false;
PSDThumbnailProvider::PSDThumbnailProvider() {
...
if (!g_magickInitialized) {
char dllPath[MAX_PATH];
GetModuleFileNameA(g_hModule, dllPath, MAX_PATH);
// I'm not sure this is right, but it makes the exception popup have my dll's name
// on it, instead of "DllHost.exe"
Magick::InitializeMagick(dllPath);
g_magickInitialized = true;
}
}
...
Code: Select all
#include "pch.h"
#include "PSDReader.h"
#include
HRESULT getStreamLength(IStream* pstream, size_t* pLength) {
STATSTG stat;
HRESULT hr = pstream->Stat(&stat, STATFLAG_DEFAULT);
*pLength = stat.cbSize.QuadPart;
return hr;
}
HRESULT PSDReader::CreateThumbnailBitmap(
IStream* pstream,
UINT maxWidth, UINT maxHeigth,
HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha)
{
// Get stream length
size_t streamLength;
HRESULT hr = getStreamLength(pstream, &streamLength);
if (FAILED(hr)) return hr;
// Read from stream until end
std::vector buffer(streamLength);
ULONG bytesRead = 0;
while (bytesRead < streamLength) {
ULONG chunk = 0;
HRESULT hr = pstream->Read(
buffer.data() + bytesRead,
streamLength - bytesRead,
&chunk);
if (FAILED(hr) || chunk == 0) break;
bytesRead += chunk;
}
if (bytesRead != streamLength) {
return E_FAIL; // Truncated is bad
}
// Load ImageMagick's Image from the buffer
Magick::Image magickImage;
Magick::Blob blob = Magick::Blob(buffer.data(), bytesRead);
try {
magickImage.read(blob);
// This does not throw an exception, but `magickImage.format()` doesn't work.
// `magickImage.columns()`, `magickImage.rows()` and `magickImage.thumbnail()` seem to work.
}
catch (Magick::Exception&) {
return E_FAIL;
}
{ // Debugging image loading
try {
Magick::Image magickImage;
magickImage.read("G:\\test\\test.jpeg");
MessageBoxA(NULL, "It works!", "Debug", MB_OK);
}
catch (Magick::Exception& ex) {
MessageBoxA(NULL, ex.what(), "Debug", MB_OK | MB_ICONERROR);
}
}
return S_OK;
}
Code: Select all
const size_t actualWidth = magickImage.columns();
const size_t actualHeight = magickImage.rows();
std::vector pixels(actualWidth * actualHeight * 4);
try {
magickImage.write(0, 0, actualWidth, actualHeight, "BGRA", Magick::CharPixel, pixels.data());
MessageBoxW(NULL, L"It works!", L"Debug", MB_OK);
}
catch (Magick::Exception& ex) {
MessageBoxA(NULL, ex.what(), "Debug", MB_OK | MB_ICONERROR);
// Is throwing "unrecognized pixel map" and sometimes "memory allocation failed" or something like that
return E_FAIL;
}
Code: Select all
Path: [built-in]
Name Value
-------------------------------------------------------------------------------
DELEGATES bzlib cairo freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib
FEATURES Channel-masks(64-bit) Cipher DPC Modules OpenCL OpenMP(2.0)
MAGICK_TEMPORARY_PATH C:/Users/UCQ/AppData/Local/Temp
NAME ImageMagick
QuantumDepth Q8
Path: C:\Program Files\ImageMagick-7.1.2-Q8\configure.xml
Name Value
-------------------------------------------------------------------------------
CC VS2022
CHANNEL_MASK_DEPTH 64
COPYRIGHT Copyright (C) 1999 ImageMagick Studio LLC
CXX VS2022
DOCUMENTATION_PATH unavailable
GIT_REVISION 83b6fc3:20250811
LIB_VERSION 0x712
LIB_VERSION_NUMBER 7,1,2,1
NAME ImageMagick
QuantumDepth 8
RELEASE_DATE 2025-08-12
TARGET_CPU x64
TARGET_OS Windows
VERSION 7.1.2
WEBSITE https://imagemagick.org