Skip to content

Commit c51c9c9

Browse files
Unify instantiation of image handles in ImageFileNameProvider
Initializing image handle only using initNative method for both the cases where zoom is equal to the filezoom and when its not equal to the filezoom. The handle in case of not equal is created temporarily and destroyed later before calling init.
1 parent 2974864 commit c51c9c9

File tree

1 file changed

+177
-156
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+177
-156
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java

Lines changed: 177 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -832,167 +832,182 @@ ImageHandle initNative(String filename, int zoom) {
832832
* The fix is to not use GDI+ image loading in this case.
833833
*/
834834
if (filename.toLowerCase().endsWith(".gif")) gdip = false;
835-
if (gdip) {
836-
int length = filename.length();
837-
char[] chars = new char[length+1];
838-
filename.getChars(0, length, chars, 0);
839-
long bitmap = Gdip.Bitmap_new(chars, false);
840-
if (bitmap != 0) {
841-
int error = SWT.ERROR_NO_HANDLES;
842-
int status = Gdip.Image_GetLastStatus(bitmap);
843-
if (status == 0) {
844-
if (filename.toLowerCase().endsWith(".ico")) {
845-
this.type = SWT.ICON;
846-
long[] hicon = new long[1];
847-
status = Gdip.Bitmap_GetHICON(bitmap, hicon);
848-
handle = hicon[0];
849-
imageMetadata = new ImageHandle(handle, zoom);
850-
} else {
851-
this.type = SWT.BITMAP;
852-
width = Gdip.Image_GetWidth(bitmap);
853-
height = Gdip.Image_GetHeight(bitmap);
854-
int pixelFormat = Gdip.Image_GetPixelFormat(bitmap);
855-
switch (pixelFormat) {
856-
case Gdip.PixelFormat16bppRGB555:
857-
case Gdip.PixelFormat16bppRGB565:
858-
handle = createDIB(width, height, 16);
859-
break;
860-
case Gdip.PixelFormat24bppRGB:
861-
case Gdip.PixelFormat32bppCMYK:
862-
handle = createDIB(width, height, 24);
863-
break;
864-
case Gdip.PixelFormat32bppRGB:
865-
// These will lose either precision or transparency
866-
case Gdip.PixelFormat16bppGrayScale:
867-
case Gdip.PixelFormat48bppRGB:
868-
case Gdip.PixelFormat32bppPARGB:
869-
case Gdip.PixelFormat64bppARGB:
870-
case Gdip.PixelFormat64bppPARGB:
871-
handle = createDIB(width, height, 32);
872-
break;
835+
836+
if(!gdip) return null;
837+
838+
int length = filename.length();
839+
char[] chars = new char[length+1];
840+
filename.getChars(0, length, chars, 0);
841+
long bitmap = Gdip.Bitmap_new(chars, false);
842+
if (bitmap == 0) return null;
843+
844+
int error = SWT.ERROR_NO_HANDLES;
845+
int status = Gdip.Image_GetLastStatus(bitmap);
846+
if (status == 0) {
847+
if (filename.toLowerCase().endsWith(".ico")) {
848+
this.type = SWT.ICON;
849+
long[] hicon = new long[1];
850+
status = Gdip.Bitmap_GetHICON(bitmap, hicon);
851+
handle = hicon[0];
852+
imageMetadata = new ImageHandle(handle, zoom);
853+
} else {
854+
this.type = SWT.BITMAP;
855+
width = Gdip.Image_GetWidth(bitmap);
856+
height = Gdip.Image_GetHeight(bitmap);
857+
int pixelFormat = Gdip.Image_GetPixelFormat(bitmap);
858+
handle = extractHandleForPixelFormat(width, height, pixelFormat);
859+
if (handle != 0) {
860+
/*
861+
* This performs better than getting the bits with Bitmap.LockBits(),
862+
* but it cannot be used when there is transparency.
863+
*/
864+
long hDC = device.internal_new_GC(null);
865+
long srcHDC = OS.CreateCompatibleDC(hDC);
866+
long oldSrcBitmap = OS.SelectObject(srcHDC, handle);
867+
long graphics = Gdip.Graphics_new(srcHDC);
868+
if (graphics != 0) {
869+
Rect rect = new Rect();
870+
rect.Width = width;
871+
rect.Height = height;
872+
status = Gdip.Graphics_DrawImage(graphics, bitmap, rect, 0, 0, width, height, Gdip.UnitPixel, 0, 0, 0);
873+
if (status != 0) {
874+
error = SWT.ERROR_INVALID_IMAGE;
875+
OS.DeleteObject(handle);
876+
handle = 0;
873877
}
874-
if (handle != 0) {
875-
/*
876-
* This performs better than getting the bits with Bitmap.LockBits(),
877-
* but it cannot be used when there is transparency.
878-
*/
879-
long hDC = device.internal_new_GC(null);
880-
long srcHDC = OS.CreateCompatibleDC(hDC);
881-
long oldSrcBitmap = OS.SelectObject(srcHDC, handle);
882-
long graphics = Gdip.Graphics_new(srcHDC);
883-
if (graphics != 0) {
884-
Rect rect = new Rect();
885-
rect.Width = width;
886-
rect.Height = height;
887-
status = Gdip.Graphics_DrawImage(graphics, bitmap, rect, 0, 0, width, height, Gdip.UnitPixel, 0, 0, 0);
888-
if (status != 0) {
889-
error = SWT.ERROR_INVALID_IMAGE;
890-
OS.DeleteObject(handle);
891-
handle = 0;
878+
Gdip.Graphics_delete(graphics);
879+
}
880+
OS.SelectObject(srcHDC, oldSrcBitmap);
881+
OS.DeleteDC(srcHDC);
882+
device.internal_dispose_GC(hDC, null);
883+
imageMetadata = new ImageHandle(handle, zoom);
884+
} else {
885+
long lockedBitmapData = Gdip.BitmapData_new();
886+
if (lockedBitmapData != 0) {
887+
status = Gdip.Bitmap_LockBits(bitmap, 0, 0, pixelFormat, lockedBitmapData);
888+
if (status == 0) {
889+
BitmapData bitmapData = new BitmapData();
890+
Gdip.MoveMemory(bitmapData, lockedBitmapData);
891+
int stride = bitmapData.Stride;
892+
long pixels = bitmapData.Scan0;
893+
int depth = 0, scanlinePad = 4, transparentPixel = -1;
894+
depth = extractDepthForPixelFormat(bitmapData);
895+
if (depth != 0) {
896+
PaletteData paletteData = null;
897+
switch (bitmapData.PixelFormat) {
898+
case Gdip.PixelFormat1bppIndexed:
899+
case Gdip.PixelFormat4bppIndexed:
900+
case Gdip.PixelFormat8bppIndexed:
901+
int paletteSize = Gdip.Image_GetPaletteSize(bitmap);
902+
long hHeap = OS.GetProcessHeap();
903+
long palette = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, paletteSize);
904+
if (palette == 0) SWT.error(SWT.ERROR_NO_HANDLES);
905+
Gdip.Image_GetPalette(bitmap, palette, paletteSize);
906+
ColorPalette colorPalette = new ColorPalette();
907+
Gdip.MoveMemory(colorPalette, palette, ColorPalette.sizeof);
908+
int[] entries = new int[colorPalette.Count];
909+
OS.MoveMemory(entries, palette + 8, entries.length * 4);
910+
OS.HeapFree(hHeap, 0, palette);
911+
RGB[] rgbs = new RGB[colorPalette.Count];
912+
paletteData = new PaletteData(rgbs);
913+
for (int i = 0; i < entries.length; i++) {
914+
if (((entries[i] >> 24) & 0xFF) == 0 && (colorPalette.Flags & Gdip.PaletteFlagsHasAlpha) != 0) {
915+
transparentPixel = i;
916+
}
917+
rgbs[i] = new RGB(((entries[i] & 0xFF0000) >> 16), ((entries[i] & 0xFF00) >> 8), ((entries[i] & 0xFF) >> 0));
918+
}
919+
break;
920+
case Gdip.PixelFormat16bppARGB1555:
921+
case Gdip.PixelFormat16bppRGB555: paletteData = new PaletteData(0x7C00, 0x3E0, 0x1F); break;
922+
case Gdip.PixelFormat16bppRGB565: paletteData = new PaletteData(0xF800, 0x7E0, 0x1F); break;
923+
case Gdip.PixelFormat24bppRGB: paletteData = new PaletteData(0xFF, 0xFF00, 0xFF0000); break;
924+
case Gdip.PixelFormat32bppRGB:
925+
case Gdip.PixelFormat32bppARGB: paletteData = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); break;
892926
}
893-
Gdip.Graphics_delete(graphics);
894-
}
895-
OS.SelectObject(srcHDC, oldSrcBitmap);
896-
OS.DeleteDC(srcHDC);
897-
device.internal_dispose_GC(hDC, null);
898-
imageMetadata = new ImageHandle(handle, zoom);
899-
} else {
900-
long lockedBitmapData = Gdip.BitmapData_new();
901-
if (lockedBitmapData != 0) {
902-
status = Gdip.Bitmap_LockBits(bitmap, 0, 0, pixelFormat, lockedBitmapData);
903-
if (status == 0) {
904-
BitmapData bitmapData = new BitmapData();
905-
Gdip.MoveMemory(bitmapData, lockedBitmapData);
906-
int stride = bitmapData.Stride;
907-
long pixels = bitmapData.Scan0;
908-
int depth = 0, scanlinePad = 4, transparentPixel = -1;
909-
switch (bitmapData.PixelFormat) {
910-
case Gdip.PixelFormat1bppIndexed: depth = 1; break;
911-
case Gdip.PixelFormat4bppIndexed: depth = 4; break;
912-
case Gdip.PixelFormat8bppIndexed: depth = 8; break;
913-
case Gdip.PixelFormat16bppARGB1555:
914-
case Gdip.PixelFormat16bppRGB555:
915-
case Gdip.PixelFormat16bppRGB565: depth = 16; break;
916-
case Gdip.PixelFormat24bppRGB: depth = 24; break;
917-
case Gdip.PixelFormat32bppRGB:
918-
case Gdip.PixelFormat32bppARGB: depth = 32; break;
919-
}
920-
if (depth != 0) {
921-
PaletteData paletteData = null;
922-
switch (bitmapData.PixelFormat) {
923-
case Gdip.PixelFormat1bppIndexed:
924-
case Gdip.PixelFormat4bppIndexed:
925-
case Gdip.PixelFormat8bppIndexed:
926-
int paletteSize = Gdip.Image_GetPaletteSize(bitmap);
927-
long hHeap = OS.GetProcessHeap();
928-
long palette = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, paletteSize);
929-
if (palette == 0) SWT.error(SWT.ERROR_NO_HANDLES);
930-
Gdip.Image_GetPalette(bitmap, palette, paletteSize);
931-
ColorPalette colorPalette = new ColorPalette();
932-
Gdip.MoveMemory(colorPalette, palette, ColorPalette.sizeof);
933-
int[] entries = new int[colorPalette.Count];
934-
OS.MoveMemory(entries, palette + 8, entries.length * 4);
935-
OS.HeapFree(hHeap, 0, palette);
936-
RGB[] rgbs = new RGB[colorPalette.Count];
937-
paletteData = new PaletteData(rgbs);
938-
for (int i = 0; i < entries.length; i++) {
939-
if (((entries[i] >> 24) & 0xFF) == 0 && (colorPalette.Flags & Gdip.PaletteFlagsHasAlpha) != 0) {
940-
transparentPixel = i;
941-
}
942-
rgbs[i] = new RGB(((entries[i] & 0xFF0000) >> 16), ((entries[i] & 0xFF00) >> 8), ((entries[i] & 0xFF) >> 0));
943-
}
944-
break;
945-
case Gdip.PixelFormat16bppARGB1555:
946-
case Gdip.PixelFormat16bppRGB555: paletteData = new PaletteData(0x7C00, 0x3E0, 0x1F); break;
947-
case Gdip.PixelFormat16bppRGB565: paletteData = new PaletteData(0xF800, 0x7E0, 0x1F); break;
948-
case Gdip.PixelFormat24bppRGB: paletteData = new PaletteData(0xFF, 0xFF00, 0xFF0000); break;
949-
case Gdip.PixelFormat32bppRGB:
950-
case Gdip.PixelFormat32bppARGB: paletteData = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); break;
927+
byte[] data = new byte[stride * height], alphaData = null;
928+
OS.MoveMemory(data, pixels, data.length);
929+
switch (bitmapData.PixelFormat) {
930+
case Gdip.PixelFormat16bppARGB1555:
931+
alphaData = new byte[width * height];
932+
for (int i = 1, j = 0; i < data.length; i += 2, j++) {
933+
alphaData[j] = (byte)((data[i] & 0x80) != 0 ? 255 : 0);
951934
}
952-
byte[] data = new byte[stride * height], alphaData = null;
953-
OS.MoveMemory(data, pixels, data.length);
954-
switch (bitmapData.PixelFormat) {
955-
case Gdip.PixelFormat16bppARGB1555:
956-
alphaData = new byte[width * height];
957-
for (int i = 1, j = 0; i < data.length; i += 2, j++) {
958-
alphaData[j] = (byte)((data[i] & 0x80) != 0 ? 255 : 0);
959-
}
960-
break;
961-
case Gdip.PixelFormat32bppARGB:
962-
alphaData = new byte[width * height];
963-
for (int i = 3, j = 0; i < data.length; i += 4, j++) {
964-
alphaData[j] = data[i];
965-
}
966-
break;
935+
break;
936+
case Gdip.PixelFormat32bppARGB:
937+
alphaData = new byte[width * height];
938+
for (int i = 3, j = 0; i < data.length; i += 4, j++) {
939+
alphaData[j] = data[i];
967940
}
968-
ImageData img = new ImageData(width, height, depth, paletteData, scanlinePad, data);
969-
img.transparentPixel = transparentPixel;
970-
img.alphaData = alphaData;
971-
972-
ImageData newData = adaptImageDataIfDisabledOrGray(img);
973-
init(newData, zoom);
974-
imageMetadata = zoomLevelToImageHandle.get(zoom);
975-
handle = imageMetadata.handle;
976-
}
977-
Gdip.Bitmap_UnlockBits(bitmap, lockedBitmapData);
978-
} else {
979-
error = SWT.ERROR_INVALID_IMAGE;
941+
break;
980942
}
981-
Gdip.BitmapData_delete(lockedBitmapData);
943+
ImageData img = new ImageData(width, height, depth, paletteData, scanlinePad, data);
944+
img.transparentPixel = transparentPixel;
945+
img.alphaData = alphaData;
946+
947+
ImageData newData = adaptImageDataIfDisabledOrGray(img);
948+
init(newData, zoom);
949+
imageMetadata = zoomLevelToImageHandle.get(zoom);
950+
handle = imageMetadata.handle;
982951
}
952+
Gdip.Bitmap_UnlockBits(bitmap, lockedBitmapData);
953+
} else {
954+
error = SWT.ERROR_INVALID_IMAGE;
983955
}
956+
Gdip.BitmapData_delete(lockedBitmapData);
984957
}
985958
}
986-
Gdip.Bitmap_delete(bitmap);
987-
if (status == 0) {
988-
if (handle == 0) SWT.error(error);
989-
if (imageMetadata == null) SWT.error(error);
990-
}
991959
}
992960
}
961+
Gdip.Bitmap_delete(bitmap);
962+
if (status == 0) {
963+
if (handle == 0) SWT.error(error);
964+
if (imageMetadata == null) SWT.error(error);
965+
}
966+
993967
return imageMetadata;
994968
}
995969

970+
private int extractDepthForPixelFormat(BitmapData bitmapData) {
971+
int depth = 0;
972+
switch (bitmapData.PixelFormat) {
973+
case Gdip.PixelFormat1bppIndexed: depth = 1; break;
974+
case Gdip.PixelFormat4bppIndexed: depth = 4; break;
975+
case Gdip.PixelFormat8bppIndexed: depth = 8; break;
976+
case Gdip.PixelFormat16bppARGB1555:
977+
case Gdip.PixelFormat16bppRGB555:
978+
case Gdip.PixelFormat16bppRGB565: depth = 16; break;
979+
case Gdip.PixelFormat24bppRGB: depth = 24; break;
980+
case Gdip.PixelFormat32bppRGB:
981+
case Gdip.PixelFormat32bppARGB: depth = 32; break;
982+
}
983+
return depth;
984+
}
985+
986+
private long extractHandleForPixelFormat(int width, int height, int pixelFormat) {
987+
long handle = 0;
988+
switch (pixelFormat) {
989+
case Gdip.PixelFormat16bppRGB555:
990+
case Gdip.PixelFormat16bppRGB565:
991+
handle = createDIB(width, height, 16);
992+
break;
993+
case Gdip.PixelFormat24bppRGB:
994+
case Gdip.PixelFormat32bppCMYK:
995+
handle = createDIB(width, height, 24);
996+
break;
997+
case Gdip.PixelFormat32bppRGB:
998+
// These will lose either precision or transparency
999+
case Gdip.PixelFormat16bppGrayScale:
1000+
case Gdip.PixelFormat48bppRGB:
1001+
case Gdip.PixelFormat32bppPARGB:
1002+
case Gdip.PixelFormat64bppARGB:
1003+
case Gdip.PixelFormat64bppPARGB:
1004+
handle = createDIB(width, height, 32);
1005+
break;
1006+
}
1007+
return handle;
1008+
}
1009+
1010+
9961011
long [] createGdipImage() {
9971012
return createGdipImage(this.getZoom());
9981013
}
@@ -1185,6 +1200,17 @@ private void destroyHandle () {
11851200
zoomLevelToImageHandle.clear();
11861201
}
11871202

1203+
private void destroyHandle(int zoom) {
1204+
zoomLevelToImageHandle.entrySet().removeIf(entry -> {
1205+
final Integer zoomKey = entry.getKey();
1206+
if (zoom == zoomKey) {
1207+
destroyHandle(entry.getValue().handle);
1208+
return true;
1209+
}
1210+
return false;
1211+
});
1212+
}
1213+
11881214
@Override
11891215
void destroyHandlesExcept(Set<Integer> zoomLevels) {
11901216
zoomLevelToImageHandle.entrySet().removeIf(entry -> {
@@ -2136,16 +2162,11 @@ ImageData getImageData(int zoom) {
21362162
@Override
21372163
ImageHandle getImageMetadata(int zoom) {
21382164
ElementAtZoom<String> fileForZoom = DPIUtil.validateAndGetImagePathAtZoom (provider, zoom);
2139-
ImageHandle nativeInitializedImage = null;
2140-
if (fileForZoom.zoom() == zoom) {
2141-
nativeInitializedImage = initNative(fileForZoom.element(), zoom);
2142-
}
2143-
if (nativeInitializedImage == null) {
2144-
ImageData imageData = new ImageData (fileForZoom.element());
2145-
if (fileForZoom.zoom() != zoom) {
2146-
imageData = DPIUtil.scaleImageData(device, imageData, zoom, fileForZoom.zoom());
2147-
}
2165+
ImageHandle nativeInitializedImage = initNative(fileForZoom.element(), zoom);
2166+
if (fileForZoom.zoom() != zoom) {
2167+
ImageData imageData = DPIUtil.scaleImageData(device, nativeInitializedImage.getImageData(), zoom, fileForZoom.zoom());
21482168
imageData = adaptImageDataIfDisabledOrGray(imageData);
2169+
destroyHandle(zoom);
21492170
init(imageData, zoom);
21502171
}
21512172
return zoomLevelToImageHandle.get(zoom);

0 commit comments

Comments
 (0)