Skip to content

Commit c9b7ea9

Browse files
committed
fix: more stable
1 parent 4f0d131 commit c9b7ea9

1 file changed

Lines changed: 26 additions & 17 deletions

File tree

src/winicon.cc

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <shlwapi.h>
88
#include <gdiplus.h>
99
#include <thumbcache.h>
10+
#include <memory>
1011

1112
#pragma comment(lib, "Ole32.lib")
1213
#pragma comment(lib, "Shlwapi.lib")
@@ -65,26 +66,27 @@ HRESULT GetThumbnailImage(const std::wstring& filePath, int size, HBITMAP& hBitm
6566
void SaveBitmapAsPNG(HBITMAP hBitmap, const std::wstring& outputPath) {
6667
GdiplusStartupInput gdiplusStartupInput;
6768
ULONG_PTR gdiplusToken;
68-
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
69+
if (GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr) != Ok) return;
6970

7071
BITMAP bm;
71-
GetObject(hBitmap, sizeof(BITMAP), &bm);
72+
if (!GetObject(hBitmap, sizeof(BITMAP), &bm)) return;
7273

7374
Bitmap bitmap(bm.bmWidth, bm.bmHeight, PixelFormat32bppARGB);
74-
75-
Gdiplus::BitmapData bmpData;
75+
BitmapData bmpData;
7676
Rect rect(0, 0, bm.bmWidth, bm.bmHeight);
7777

7878
if (bitmap.LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bmpData) == Ok) {
79-
int bytesPerPixel = 4;
80-
BYTE* srcData = (BYTE*)bm.bmBits;
81-
BYTE* destData = (BYTE*)bmpData.Scan0;
82-
83-
for (int y = 0; y < bm.bmHeight; y++) {
84-
BYTE* srcRow = srcData + (bm.bmHeight - 1 - y) * bm.bmWidth * bytesPerPixel;
85-
BYTE* destRow = destData + y * bmpData.Stride;
86-
memcpy(destRow, srcRow, bm.bmWidth * bytesPerPixel);
87-
}
79+
BITMAPINFO bmi = {};
80+
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
81+
bmi.bmiHeader.biWidth = bm.bmWidth;
82+
bmi.bmiHeader.biHeight = -bm.bmHeight;
83+
bmi.bmiHeader.biPlanes = 1;
84+
bmi.bmiHeader.biBitCount = 32;
85+
bmi.bmiHeader.biCompression = BI_RGB;
86+
87+
HDC hdc = GetDC(nullptr);
88+
GetDIBits(hdc, hBitmap, 0, bm.bmHeight, bmpData.Scan0, &bmi, DIB_RGB_COLORS);
89+
ReleaseDC(nullptr, hdc);
8890

8991
bitmap.UnlockBits(&bmpData);
9092
}
@@ -109,9 +111,16 @@ void getImage(const Napi::CallbackInfo& info, bool useThumbnail) {
109111

110112
GdiplusStartupInput gdiplusStartupInput;
111113
ULONG_PTR gdiplusToken;
112-
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
114+
if (GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr) != Ok) {
115+
Napi::Error::New(env, "Failed to initialize GDI+").ThrowAsJavaScriptException();
116+
return;
117+
}
113118

114-
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
119+
if (FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) {
120+
GdiplusShutdown(gdiplusToken);
121+
Napi::Error::New(env, "Failed to initialize COM").ThrowAsJavaScriptException();
122+
return;
123+
}
115124

116125
HBITMAP hBitmap = nullptr;
117126
HRESULT hr = useThumbnail
@@ -122,7 +131,7 @@ void getImage(const Napi::CallbackInfo& info, bool useThumbnail) {
122131
SaveBitmapAsPNG(hBitmap, outputPath);
123132
DeleteObject(hBitmap);
124133
} else {
125-
Napi::Error::New(env, "Failed to retrieve image.").ThrowAsJavaScriptException();
134+
Napi::Error::New(env, "Failed to retrieve image").ThrowAsJavaScriptException();
126135
}
127136

128137
CoUninitialize();
@@ -162,4 +171,4 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
162171

163172
NODE_API_MODULE(winicon, Init)
164173

165-
#endif
174+
#endif

0 commit comments

Comments
 (0)