Skip to content

Commit 2867734

Browse files
committed
Fix generating thumbnail from non-compressed composite image, Add test files
1 parent aaee70c commit 2867734

9 files changed

Lines changed: 71 additions & 53 deletions

File tree

PsdThumbnailProvider/GetThumbnail.cpp

Lines changed: 68 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -117,75 +117,95 @@ HBITMAP GetPSDThumbnail(IStream* stream) {
117117

118118
USHORT compression = ReadUInt16(stream);
119119

120-
if (compression == 1) {
121-
int channelCount = 3;
122-
int offsets[16] = { 2, 1, 0 };
123-
124-
if (channels && channels > 3) {
125-
for (int i = 3; i < channels; i++) {
126-
offsets[i] = i;
127-
channelCount++;
128-
}
129-
}
130-
else if (globalAlpha) {
131-
offsets[3] = 3;
120+
int channelCount = 3;
121+
int offsets[16] = { 2, 1, 0 };
122+
123+
if (channels && channels > 3) {
124+
for (int i = 3; i < channels; i++) {
125+
offsets[i] = i;
132126
channelCount++;
133127
}
128+
} else if (globalAlpha) {
129+
offsets[3] = 3;
130+
channelCount++;
131+
}
134132

135-
USHORT* lengths = new USHORT[channelCount * height];
133+
if (compression == 1 || compression == 0) {
136134
int dataLength = width * height * 4;
137-
int step = 4;
138-
int maxLength = 0;
139135
BYTE* data = new BYTE[dataLength];
140136

141-
for (int i = 0; i < dataLength; i++) {
142-
data[i] = 0xff;
143-
}
137+
if (compression == 1) {
138+
USHORT* lengths = new USHORT[channelCount * height];
139+
int step = 4;
140+
int maxLength = 0;
144141

145-
for (int o = 0, li = 0; o < channelCount; o++) {
146-
for (int y = 0; y < height; y++, li++) {
147-
lengths[li] = ReadUInt16(stream);
148-
maxLength = maxLength < lengths[li] ? lengths[li] : maxLength;
142+
for (int i = 0; i < dataLength; i++) {
143+
data[i] = 0xff;
149144
}
150-
}
151-
152-
BYTE* buffer = new BYTE[maxLength];
153-
154-
for (int c = 0, li = 0; c < channelCount; c++) {
155-
int offset = offsets[c];
156-
int extra = c > 3 || offset > 3;
157145

158-
if (extra) {
146+
for (int o = 0, li = 0; o < channelCount; o++) {
159147
for (int y = 0; y < height; y++, li++) {
160-
Seek(stream, lengths[li], STREAM_SEEK_CUR);
148+
lengths[li] = ReadUInt16(stream);
149+
maxLength = maxLength < lengths[li] ? lengths[li] : maxLength;
161150
}
162151
}
163-
else {
164-
for (int y = 0, p = offset; y < height; y++, li++) {
165-
int length = lengths[li];
166-
ReadData(stream, buffer, length);
167152

168-
for (int i = 0; i < length; i++) {
169-
BYTE header = buffer[i];
153+
BYTE* buffer = new BYTE[maxLength];
170154

171-
if (header >= 128) {
172-
BYTE value = buffer[++i];
173-
header = (256 - header);
155+
for (int c = 0, li = 0; c < channelCount; c++) {
156+
int offset = offsets[c];
157+
int extra = c > 3 || offset > 3;
174158

175-
for (int j = 0; j <= header; j++) {
176-
data[p] = value;
177-
p += step;
159+
if (extra) {
160+
for (int y = 0; y < height; y++, li++) {
161+
Seek(stream, lengths[li], STREAM_SEEK_CUR);
162+
}
163+
}
164+
else {
165+
for (int y = 0, p = offset; y < height; y++, li++) {
166+
int length = lengths[li];
167+
ReadData(stream, buffer, length);
168+
169+
for (int i = 0; i < length; i++) {
170+
BYTE header = buffer[i];
171+
172+
if (header >= 128) {
173+
BYTE value = buffer[++i];
174+
header = (256 - header);
175+
176+
for (int j = 0; j <= header; j++) {
177+
data[p] = value;
178+
p += step;
179+
}
178180
}
179-
}
180-
else { // header < 128
181-
for (int j = 0; j <= header; j++) {
182-
data[p] = buffer[++i];
183-
p += step;
181+
else { // header < 128
182+
for (int j = 0; j <= header; j++) {
183+
data[p] = buffer[++i];
184+
p += step;
185+
}
184186
}
185187
}
186188
}
187189
}
188190
}
191+
delete lengths;
192+
delete buffer;
193+
} else {
194+
memset(data, 0xff, width * height * 4);
195+
int pixels = width * height;
196+
BYTE* buffer = new BYTE[pixels];
197+
if (channelCount > 4) channelCount = 4;
198+
199+
for (int c = 0; c < channelCount; c++) {
200+
int o = offsets[c];
201+
ReadData(stream, buffer, pixels);
202+
203+
for (int i = 0; i < pixels; i++) {
204+
data[i * 4 + o] = buffer[i];
205+
}
206+
}
207+
208+
delete buffer;
189209
}
190210

191211
if (width > 256 || height > 256) {
@@ -229,8 +249,6 @@ HBITMAP GetPSDThumbnail(IStream* stream) {
229249
result = CreateBitmap(width, height, 1, 32, data);
230250
}
231251

232-
delete lengths;
233-
delete buffer;
234252
delete data;
235253
}
236254
}

Setup/Product.wxs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
3-
<Product Id="*" Name="PSD Thumbnail Provider" Language="1033" Version="1.3.0.0" Manufacturer="Agamnentzar" UpgradeCode="cb88ff56-355c-48fd-8343-8d3f40ef02ce">
3+
<Product Id="*" Name="PSD Thumbnail Provider" Language="1033" Version="1.4.0.0" Manufacturer="Agamnentzar" UpgradeCode="cb88ff56-355c-48fd-8343-8d3f40ef02ce">
44
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
55
<Condition Message="You need to be an administrator to install this product.">Privileged</Condition>
66
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A newer version of PSD Thumbnail Provider is already installed." />

Test/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LRESULT CALLBACK windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
99
switch (message) {
1010
case WM_CREATE: {
1111
IStream* stream;
12-
SHCreateStreamOnFileEx(L"test4.psd", STGM_READ, FILE_ATTRIBUTE_NORMAL, false, NULL, &stream);
12+
SHCreateStreamOnFileEx(L"test6.psd", STGM_READ, FILE_ATTRIBUTE_NORMAL, false, NULL, &stream);
1313
bitmap = GetPSDThumbnail(stream);
1414
BITMAP bm = {};
1515
GetObject(bitmap, sizeof(bm), &bm);
@@ -73,7 +73,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
7373
HWND mainWindow = CreateWindowEx(
7474
0, // WS_EX_ACCEPTFILES
7575
windowClass.lpszClassName,
76-
TEXT("Aggie Brush"),
76+
TEXT("PSD Preview Test"),
7777
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7878
CW_USEDEFAULT,
7979
CW_USEDEFAULT,

Test/test.psd

29.6 KB
Binary file not shown.

Test/test2.psd

41 KB
Binary file not shown.

Test/test3.psd

149 KB
Binary file not shown.

Test/test4.psd

28.3 KB
Binary file not shown.

Test/test5.psd

26.4 KB
Binary file not shown.

Test/test6.psd

762 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)