Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita Nemkin2021-08-12 13:20:55 +0000
committerSravan Kumar Lakkimsetti2021-08-13 09:37:55 +0000
commitf64260da79aef3b460ca59c993a996620b89f326 (patch)
tree94ca161c578240242c7e7eee7acd3e24db160416
parent33aded892d50aed5607ffec6a30d51549ae32386 (diff)
downloadrt.equinox.framework-f64260da79aef3b460ca59c993a996620b89f326.tar.gz
rt.equinox.framework-f64260da79aef3b460ca59c993a996620b89f326.tar.xz
rt.equinox.framework-f64260da79aef3b460ca59c993a996620b89f326.zip
Bug 114567 - [launcher] Splash screen support for other image formats (Part 1)
On Windows, use WIC for image loading to support a wide range of image formats, including BMP, PNG, JPG and GIF. Note that since the current splash screen implementation on Windows doesn't support transparency, any transparency in the source images is converted to opaque black. Signed-off-by: Nikita Nemkin <nikita@nemkin.ru> Change-Id: I2cec56d831676bfa6c0d0edd3a9f5d08811e2ade Reviewed-on: https://git.eclipse.org/r/c/equinox/rt.equinox.framework/+/183962 Tested-by: Sravan Kumar Lakkimsetti <sravankumarl@in.ibm.com> Reviewed-by: Sravan Kumar Lakkimsetti <sravankumarl@in.ibm.com>
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c107
-rw-r--r--features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak6
2 files changed, 86 insertions, 27 deletions
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c b/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c
index 71a8a710c..58ca6ed96 100644
--- a/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/eclipseWin.c
@@ -23,6 +23,7 @@
#include <windows.h>
#include <commctrl.h>
+#include <wincodec.h>
#include <process.h>
#include <stdio.h>
#include <string.h>
@@ -205,6 +206,82 @@ int reuseWorkbench(_TCHAR** filePath, int timeout) {
return 0;
}
+HBITMAP loadImage(LPCWSTR pszFilename, int targetDpi) {
+ HRESULT hr = S_OK;
+ HBITMAP hBitmap = NULL;
+ IWICImagingFactory *pFactory = NULL;
+ IWICBitmapDecoder *pDecoder = NULL;
+ IWICBitmapFrameDecode *pFrame = NULL;
+ IWICFormatConverter *pConverter = NULL;
+ IWICBitmapScaler *pScaler = NULL;
+ IWICBitmapSource *pSource = NULL; /* borrowed, don't deref */
+
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ if (FAILED(hr)) return NULL;
+ hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &pFactory);
+ if (FAILED(hr)) goto done;
+
+ hr = IWICImagingFactory_CreateDecoderFromFilename(pFactory, pszFilename, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder);
+ if (FAILED(hr)) goto done;
+ hr = IWICBitmapDecoder_GetFrame(pDecoder, 0, &pFrame);
+ if (FAILED(hr)) goto done;
+ pSource = (IWICBitmapSource *)pFrame;
+
+ /* Scale the image to the targetDpi, assuming that the source is always 96 dpi. */
+ UINT uiWidth = 0, uiHeight = 0;
+ hr = IWICBitmapSource_GetSize(pFrame, &uiWidth, &uiHeight);
+ if (FAILED(hr)) goto done;
+ if (targetDpi != 96) {
+ uiWidth = uiWidth * targetDpi / 96;
+ uiHeight = uiHeight * targetDpi / 96;
+ hr = IWICImagingFactory_CreateBitmapScaler(pFactory, &pScaler);
+ if (FAILED(hr)) goto done;
+ hr = IWICBitmapScaler_Initialize(pScaler, pSource, uiWidth, uiHeight, WICBitmapInterpolationModeCubic);
+ if (FAILED(hr)) goto done;
+ pSource = (IWICBitmapSource *)pScaler;
+ }
+
+ /* Convert the image to the 24-bit BGR format. */
+ WICPixelFormatGUID format;
+ hr = IWICBitmapSource_GetPixelFormat(pSource, &format);
+ if (FAILED(hr)) goto done;
+ if (!IsEqualGUID(&format, &GUID_WICPixelFormat24bppBGR)) {
+ hr = IWICImagingFactory_CreateFormatConverter(pFactory, &pConverter);
+ if (FAILED(hr)) goto done;
+ hr = IWICFormatConverter_Initialize(pConverter, pSource, &GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, NULL, 0., WICBitmapPaletteTypeCustom);
+ if (FAILED(hr)) goto done;
+ pSource = (IWICBitmapSource *)pConverter;
+ }
+
+ /* Create a DIB and initialize it from the WIC source. */
+ BITMAPINFO bmi = {{
+ .biSize = sizeof(BITMAPINFOHEADER),
+ .biWidth = (LONG)uiWidth,
+ .biHeight = -(LONG)uiHeight,
+ .biPlanes = 1,
+ .biBitCount = 24,
+ .biCompression = BI_RGB,
+ }};
+ UINT uiStride = (uiWidth * 3 + 3) & ~3; /* rounded up to a multiple of 4 */
+ PVOID pvBits = NULL;
+ hBitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0);
+ if (!hBitmap) goto done;
+ hr = IWICBitmapSource_CopyPixels(pSource, NULL, uiStride, uiStride * uiHeight, pvBits);
+ if (FAILED(hr)) {
+ DeleteObject(hBitmap);
+ hBitmap = NULL;
+ }
+
+done:
+ if (pScaler) IUnknown_Release(pScaler);
+ if (pConverter) IUnknown_Release(pConverter);
+ if (pFrame) IUnknown_Release(pFrame);
+ if (pDecoder) IUnknown_Release(pDecoder);
+ if (pFactory) IUnknown_Release(pFactory);
+ CoUninitialize();
+ return hBitmap;
+}
+
/* Show the Splash Window
*
* Open the bitmap, insert into the splash window and display it.
@@ -216,10 +293,9 @@ int showSplash( const _TCHAR* featureImage )
HBITMAP hBitmap = 0;
BITMAP bmp;
HDC hDC;
- int depth;
int x, y;
int width, height;
- int dpiX, scaledWidth, scaledHeight;
+ int dpiX;
if(splashing) {
/*splash screen is already showing, do nothing */
@@ -233,13 +309,11 @@ int showSplash( const _TCHAR* featureImage )
*/
initWindowSystem(0, NULL, 1);
- /* Load the bitmap for the feature. */
- hDC = GetDC( NULL);
- depth = GetDeviceCaps( hDC, BITSPIXEL ) * GetDeviceCaps( hDC, PLANES);
-
/* fetch screen DPI and round it according to the swt.autoScale setting,
this implementation needs to be kept in sync with org.eclipse.swt.internal.DPIUtil#setDeviceZoom(int) */
+ hDC = GetDC( NULL);
dpiX = GetDeviceCaps ( hDC, LOGPIXELSX );
+ ReleaseDC(NULL, hDC);
switch (autoScaleValue) {
case AUTOSCALE_FALSE:
dpiX = 96;
@@ -261,9 +335,9 @@ int showSplash( const _TCHAR* featureImage )
break;
}
- ReleaseDC(NULL, hDC);
- if (featureImage != NULL)
- hBitmap = LoadImage(NULL, featureImage, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+ /* Load the bitmap for the feature. */
+ if (featureImage != NULL)
+ hBitmap = loadImage(featureImage, dpiX);
/* If the bitmap could not be found, return an error. */
if (hBitmap == 0)
@@ -271,21 +345,6 @@ int showSplash( const _TCHAR* featureImage )
GetObject(hBitmap, sizeof(BITMAP), &bmp);
- /* reload scaled up image when zoom > 100% */
- if (dpiX > 96) {
- /* calculate scaled-up bounds */
- scaledWidth = dpiX * bmp.bmWidth / 96;
- scaledHeight = dpiX * bmp.bmHeight / 96;
-
- hBitmap = LoadImage(NULL, featureImage, IMAGE_BITMAP, scaledWidth, scaledHeight, LR_LOADFROMFILE);
-
- /* If the bitmap could not be found, return an error. */
- if (hBitmap == 0)
- return ERROR_FILE_NOT_FOUND;
-
- GetObject(hBitmap, sizeof(BITMAP), &bmp);
- }
-
/* figure out position */
width = GetSystemMetrics (SM_CXSCREEN);
height = GetSystemMetrics (SM_CYSCREEN);
diff --git a/features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak b/features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak
index 4bf873af3..fdebed469 100644
--- a/features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak
+++ b/features/org.eclipse.equinox.executable.feature/library/win32/make_win64.mak
@@ -43,11 +43,11 @@ DLL_OBJS = eclipse.obj eclipseWin.obj eclipseUtil.obj eclipseJNI.obj eclipseS
cdebug = -Ox -DNDEBUG
cvarsmt = -D_MT -MT
-cflags = $(cdebug) -DUNICODE -D_UNICODE /c -DUSE_ASSEMBLER -GS -DWIN64 -D_WIN64 $(cvarsmt) $(CFLAGS)
+cflags = $(cdebug) -DUNICODE -D_UNICODE -DCOBJMACROS /c -DUSE_ASSEMBLER -GS -DWIN64 -D_WIN64 $(cvarsmt) $(CFLAGS)
LIBS = kernel32.lib user32.lib comctl32.lib libcmt.lib \
- libvcruntime.lib libucrt.lib
+ libvcruntime.lib libucrt.lib ole32.lib windowscodecs.lib
DLL_LIBS = kernel32.lib user32.lib comctl32.lib gdi32.lib Advapi32.lib libcmt.lib version.lib \
- libvcruntime.lib libucrt.lib
+ libvcruntime.lib libucrt.lib ole32.lib windowscodecs.lib
LFLAGS = /DYNAMICBASE /NXCOMPAT /HIGHENTROPYVA /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO -subsystem:windows -entry:wmainCRTStartup
CONSOLEFLAGS = /DYNAMICBASE /NXCOMPAT /HIGHENTROPYVA /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO -subsystem:console -entry:wmainCRTStartup
#DLL_LFLAGS = /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /RELEASE /NOLOGO -entry:_DllMainCRTStartup@12 -dll /BASE:0x72000000 /DLL

Back to the top