@@ -553,14 +553,15 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
553553 this .imageProvider = new ImageFileNameProviderWrapper (imageFileNameProvider );
554554 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
555555 ElementAtZoom <String > fileName = DPIUtil .validateAndGetImagePathAtZoom (imageFileNameProvider , getZoom ());
556- if (fileName .zoom () == getZoom ()) {
557- ImageHandle imageMetadata = initNative (fileName .element (), getZoom ());
558- if (imageMetadata == null ) {
559- init (new ImageData (fileName .element ()), getZoom ());
556+ ImageHandle imageMetadata = initNative (fileName .element (), getZoom ());
557+ if (imageMetadata == null ) {
558+ if (fileName .zoom () == getZoom ()) {
559+ init (new ImageData (fileName .element ()), getZoom ());
560+ } else {
561+ ImageData resizedData = DPIUtil .autoScaleImageData (device , new ImageData (fileName .element ()),
562+ fileName .zoom ());
563+ init (resizedData , getZoom ());
560564 }
561- } else {
562- ImageData resizedData = DPIUtil .autoScaleImageData (device , new ImageData (fileName .element ()), fileName .zoom ());
563- init (resizedData , getZoom ());
564565 }
565566 init ();
566567 this .device .registerResourceWithZoomSupport (this );
@@ -840,167 +841,181 @@ ImageHandle initNative(String filename, int zoom) {
840841 * The fix is to not use GDI+ image loading in this case.
841842 */
842843 if (filename .toLowerCase ().endsWith (".gif" )) gdip = false ;
843- if (gdip ) {
844- int length = filename .length ();
845- char [] chars = new char [length +1 ];
846- filename .getChars (0 , length , chars , 0 );
847- long bitmap = Gdip .Bitmap_new (chars , false );
848- if (bitmap != 0 ) {
849- int error = SWT .ERROR_NO_HANDLES ;
850- int status = Gdip .Image_GetLastStatus (bitmap );
851- if (status == 0 ) {
852- if (filename .toLowerCase ().endsWith (".ico" )) {
853- this .type = SWT .ICON ;
854- long [] hicon = new long [1 ];
855- status = Gdip .Bitmap_GetHICON (bitmap , hicon );
856- handle = hicon [0 ];
857- imageMetadata = new ImageHandle (handle , zoom );
858- } else {
859- this .type = SWT .BITMAP ;
860- width = Gdip .Image_GetWidth (bitmap );
861- height = Gdip .Image_GetHeight (bitmap );
862- int pixelFormat = Gdip .Image_GetPixelFormat (bitmap );
863- switch (pixelFormat ) {
864- case Gdip .PixelFormat16bppRGB555 :
865- case Gdip .PixelFormat16bppRGB565 :
866- handle = createDIB (width , height , 16 );
867- break ;
868- case Gdip .PixelFormat24bppRGB :
869- case Gdip .PixelFormat32bppCMYK :
870- handle = createDIB (width , height , 24 );
871- break ;
872- case Gdip .PixelFormat32bppRGB :
873- // These will lose either precision or transparency
874- case Gdip .PixelFormat16bppGrayScale :
875- case Gdip .PixelFormat48bppRGB :
876- case Gdip .PixelFormat32bppPARGB :
877- case Gdip .PixelFormat64bppARGB :
878- case Gdip .PixelFormat64bppPARGB :
879- handle = createDIB (width , height , 32 );
880- break ;
844+
845+ if (!gdip ) return null ;
846+
847+ int length = filename .length ();
848+ char [] chars = new char [length +1 ];
849+ filename .getChars (0 , length , chars , 0 );
850+ long bitmap = Gdip .Bitmap_new (chars , false );
851+ if (bitmap == 0 ) return null ;
852+
853+ int error = SWT .ERROR_NO_HANDLES ;
854+ int status = Gdip .Image_GetLastStatus (bitmap );
855+ if (status == 0 ) {
856+ if (filename .toLowerCase ().endsWith (".ico" )) {
857+ this .type = SWT .ICON ;
858+ long [] hicon = new long [1 ];
859+ status = Gdip .Bitmap_GetHICON (bitmap , hicon );
860+ handle = hicon [0 ];
861+ imageMetadata = new ImageHandle (handle , zoom );
862+ } else {
863+ this .type = SWT .BITMAP ;
864+ width = Gdip .Image_GetWidth (bitmap );
865+ height = Gdip .Image_GetHeight (bitmap );
866+ int pixelFormat = Gdip .Image_GetPixelFormat (bitmap );
867+ handle = extractHandleForPixelFormat (width , height , pixelFormat );
868+ if (handle != 0 ) {
869+ /*
870+ * This performs better than getting the bits with Bitmap.LockBits(),
871+ * but it cannot be used when there is transparency.
872+ */
873+ long hDC = device .internal_new_GC (null );
874+ long srcHDC = OS .CreateCompatibleDC (hDC );
875+ long oldSrcBitmap = OS .SelectObject (srcHDC , handle );
876+ long graphics = Gdip .Graphics_new (srcHDC );
877+ if (graphics != 0 ) {
878+ Rect rect = new Rect ();
879+ rect .Width = width ;
880+ rect .Height = height ;
881+ status = Gdip .Graphics_DrawImage (graphics , bitmap , rect , 0 , 0 , width , height , Gdip .UnitPixel , 0 , 0 , 0 );
882+ if (status != 0 ) {
883+ error = SWT .ERROR_INVALID_IMAGE ;
884+ OS .DeleteObject (handle );
885+ handle = 0 ;
881886 }
882- if (handle != 0 ) {
883- /*
884- * This performs better than getting the bits with Bitmap.LockBits(),
885- * but it cannot be used when there is transparency.
886- */
887- long hDC = device .internal_new_GC (null );
888- long srcHDC = OS .CreateCompatibleDC (hDC );
889- long oldSrcBitmap = OS .SelectObject (srcHDC , handle );
890- long graphics = Gdip .Graphics_new (srcHDC );
891- if (graphics != 0 ) {
892- Rect rect = new Rect ();
893- rect .Width = width ;
894- rect .Height = height ;
895- status = Gdip .Graphics_DrawImage (graphics , bitmap , rect , 0 , 0 , width , height , Gdip .UnitPixel , 0 , 0 , 0 );
896- if (status != 0 ) {
897- error = SWT .ERROR_INVALID_IMAGE ;
898- OS .DeleteObject (handle );
899- handle = 0 ;
887+ Gdip .Graphics_delete (graphics );
888+ }
889+ OS .SelectObject (srcHDC , oldSrcBitmap );
890+ OS .DeleteDC (srcHDC );
891+ device .internal_dispose_GC (hDC , null );
892+ imageMetadata = new ImageHandle (handle , zoom );
893+ } else {
894+ long lockedBitmapData = Gdip .BitmapData_new ();
895+ if (lockedBitmapData != 0 ) {
896+ status = Gdip .Bitmap_LockBits (bitmap , 0 , 0 , pixelFormat , lockedBitmapData );
897+ if (status == 0 ) {
898+ BitmapData bitmapData = new BitmapData ();
899+ Gdip .MoveMemory (bitmapData , lockedBitmapData );
900+ int stride = bitmapData .Stride ;
901+ long pixels = bitmapData .Scan0 ;
902+ int depth = 0 , scanlinePad = 4 , transparentPixel = -1 ;
903+ depth = extractDepthForPixelFormat (bitmapData );
904+ if (depth != 0 ) {
905+ PaletteData paletteData = null ;
906+ switch (bitmapData .PixelFormat ) {
907+ case Gdip .PixelFormat1bppIndexed :
908+ case Gdip .PixelFormat4bppIndexed :
909+ case Gdip .PixelFormat8bppIndexed :
910+ int paletteSize = Gdip .Image_GetPaletteSize (bitmap );
911+ long hHeap = OS .GetProcessHeap ();
912+ long palette = OS .HeapAlloc (hHeap , OS .HEAP_ZERO_MEMORY , paletteSize );
913+ if (palette == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
914+ Gdip .Image_GetPalette (bitmap , palette , paletteSize );
915+ ColorPalette colorPalette = new ColorPalette ();
916+ Gdip .MoveMemory (colorPalette , palette , ColorPalette .sizeof );
917+ int [] entries = new int [colorPalette .Count ];
918+ OS .MoveMemory (entries , palette + 8 , entries .length * 4 );
919+ OS .HeapFree (hHeap , 0 , palette );
920+ RGB [] rgbs = new RGB [colorPalette .Count ];
921+ paletteData = new PaletteData (rgbs );
922+ for (int i = 0 ; i < entries .length ; i ++) {
923+ if (((entries [i ] >> 24 ) & 0xFF ) == 0 && (colorPalette .Flags & Gdip .PaletteFlagsHasAlpha ) != 0 ) {
924+ transparentPixel = i ;
925+ }
926+ rgbs [i ] = new RGB (((entries [i ] & 0xFF0000 ) >> 16 ), ((entries [i ] & 0xFF00 ) >> 8 ), ((entries [i ] & 0xFF ) >> 0 ));
927+ }
928+ break ;
929+ case Gdip .PixelFormat16bppARGB1555 :
930+ case Gdip .PixelFormat16bppRGB555 : paletteData = new PaletteData (0x7C00 , 0x3E0 , 0x1F ); break ;
931+ case Gdip .PixelFormat16bppRGB565 : paletteData = new PaletteData (0xF800 , 0x7E0 , 0x1F ); break ;
932+ case Gdip .PixelFormat24bppRGB : paletteData = new PaletteData (0xFF , 0xFF00 , 0xFF0000 ); break ;
933+ case Gdip .PixelFormat32bppRGB :
934+ case Gdip .PixelFormat32bppARGB : paletteData = new PaletteData (0xFF00 , 0xFF0000 , 0xFF000000 ); break ;
900935 }
901- Gdip .Graphics_delete (graphics );
902- }
903- OS .SelectObject (srcHDC , oldSrcBitmap );
904- OS .DeleteDC (srcHDC );
905- device .internal_dispose_GC (hDC , null );
906- imageMetadata = new ImageHandle (handle , zoom );
907- } else {
908- long lockedBitmapData = Gdip .BitmapData_new ();
909- if (lockedBitmapData != 0 ) {
910- status = Gdip .Bitmap_LockBits (bitmap , 0 , 0 , pixelFormat , lockedBitmapData );
911- if (status == 0 ) {
912- BitmapData bitmapData = new BitmapData ();
913- Gdip .MoveMemory (bitmapData , lockedBitmapData );
914- int stride = bitmapData .Stride ;
915- long pixels = bitmapData .Scan0 ;
916- int depth = 0 , scanlinePad = 4 , transparentPixel = -1 ;
917- switch (bitmapData .PixelFormat ) {
918- case Gdip .PixelFormat1bppIndexed : depth = 1 ; break ;
919- case Gdip .PixelFormat4bppIndexed : depth = 4 ; break ;
920- case Gdip .PixelFormat8bppIndexed : depth = 8 ; break ;
921- case Gdip .PixelFormat16bppARGB1555 :
922- case Gdip .PixelFormat16bppRGB555 :
923- case Gdip .PixelFormat16bppRGB565 : depth = 16 ; break ;
924- case Gdip .PixelFormat24bppRGB : depth = 24 ; break ;
925- case Gdip .PixelFormat32bppRGB :
926- case Gdip .PixelFormat32bppARGB : depth = 32 ; break ;
927- }
928- if (depth != 0 ) {
929- PaletteData paletteData = null ;
930- switch (bitmapData .PixelFormat ) {
931- case Gdip .PixelFormat1bppIndexed :
932- case Gdip .PixelFormat4bppIndexed :
933- case Gdip .PixelFormat8bppIndexed :
934- int paletteSize = Gdip .Image_GetPaletteSize (bitmap );
935- long hHeap = OS .GetProcessHeap ();
936- long palette = OS .HeapAlloc (hHeap , OS .HEAP_ZERO_MEMORY , paletteSize );
937- if (palette == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
938- Gdip .Image_GetPalette (bitmap , palette , paletteSize );
939- ColorPalette colorPalette = new ColorPalette ();
940- Gdip .MoveMemory (colorPalette , palette , ColorPalette .sizeof );
941- int [] entries = new int [colorPalette .Count ];
942- OS .MoveMemory (entries , palette + 8 , entries .length * 4 );
943- OS .HeapFree (hHeap , 0 , palette );
944- RGB [] rgbs = new RGB [colorPalette .Count ];
945- paletteData = new PaletteData (rgbs );
946- for (int i = 0 ; i < entries .length ; i ++) {
947- if (((entries [i ] >> 24 ) & 0xFF ) == 0 && (colorPalette .Flags & Gdip .PaletteFlagsHasAlpha ) != 0 ) {
948- transparentPixel = i ;
949- }
950- rgbs [i ] = new RGB (((entries [i ] & 0xFF0000 ) >> 16 ), ((entries [i ] & 0xFF00 ) >> 8 ), ((entries [i ] & 0xFF ) >> 0 ));
951- }
952- break ;
953- case Gdip .PixelFormat16bppARGB1555 :
954- case Gdip .PixelFormat16bppRGB555 : paletteData = new PaletteData (0x7C00 , 0x3E0 , 0x1F ); break ;
955- case Gdip .PixelFormat16bppRGB565 : paletteData = new PaletteData (0xF800 , 0x7E0 , 0x1F ); break ;
956- case Gdip .PixelFormat24bppRGB : paletteData = new PaletteData (0xFF , 0xFF00 , 0xFF0000 ); break ;
957- case Gdip .PixelFormat32bppRGB :
958- case Gdip .PixelFormat32bppARGB : paletteData = new PaletteData (0xFF00 , 0xFF0000 , 0xFF000000 ); break ;
936+ byte [] data = new byte [stride * height ], alphaData = null ;
937+ OS .MoveMemory (data , pixels , data .length );
938+ switch (bitmapData .PixelFormat ) {
939+ case Gdip .PixelFormat16bppARGB1555 :
940+ alphaData = new byte [width * height ];
941+ for (int i = 1 , j = 0 ; i < data .length ; i += 2 , j ++) {
942+ alphaData [j ] = (byte )((data [i ] & 0x80 ) != 0 ? 255 : 0 );
959943 }
960- byte [] data = new byte [stride * height ], alphaData = null ;
961- OS .MoveMemory (data , pixels , data .length );
962- switch (bitmapData .PixelFormat ) {
963- case Gdip .PixelFormat16bppARGB1555 :
964- alphaData = new byte [width * height ];
965- for (int i = 1 , j = 0 ; i < data .length ; i += 2 , j ++) {
966- alphaData [j ] = (byte )((data [i ] & 0x80 ) != 0 ? 255 : 0 );
967- }
968- break ;
969- case Gdip .PixelFormat32bppARGB :
970- alphaData = new byte [width * height ];
971- for (int i = 3 , j = 0 ; i < data .length ; i += 4 , j ++) {
972- alphaData [j ] = data [i ];
973- }
974- break ;
944+ break ;
945+ case Gdip .PixelFormat32bppARGB :
946+ alphaData = new byte [width * height ];
947+ for (int i = 3 , j = 0 ; i < data .length ; i += 4 , j ++) {
948+ alphaData [j ] = data [i ];
975949 }
976- ImageData img = new ImageData (width , height , depth , paletteData , scanlinePad , data );
977- img .transparentPixel = transparentPixel ;
978- img .alphaData = alphaData ;
979-
980- ImageData newData = adaptImageDataIfDisabledOrGray (img );
981- init (newData , zoom );
982- imageMetadata = zoomLevelToImageHandle .get (zoom );
983- handle = imageMetadata .handle ;
984- }
985- Gdip .Bitmap_UnlockBits (bitmap , lockedBitmapData );
986- } else {
987- error = SWT .ERROR_INVALID_IMAGE ;
950+ break ;
988951 }
989- Gdip .BitmapData_delete (lockedBitmapData );
952+ ImageData img = new ImageData (width , height , depth , paletteData , scanlinePad , data );
953+ img .transparentPixel = transparentPixel ;
954+ img .alphaData = alphaData ;
955+
956+ ImageData newData = adaptImageDataIfDisabledOrGray (img );
957+ init (newData , zoom );
958+ imageMetadata = zoomLevelToImageHandle .get (zoom );
959+ handle = imageMetadata .handle ;
990960 }
961+ Gdip .Bitmap_UnlockBits (bitmap , lockedBitmapData );
962+ } else {
963+ error = SWT .ERROR_INVALID_IMAGE ;
991964 }
965+ Gdip .BitmapData_delete (lockedBitmapData );
992966 }
993967 }
994- Gdip .Bitmap_delete (bitmap );
995- if (status == 0 ) {
996- if (handle == 0 ) SWT .error (error );
997- if (imageMetadata == null ) SWT .error (error );
998- }
999968 }
1000969 }
970+ Gdip .Bitmap_delete (bitmap );
971+ if (status == 0 ) {
972+ if (handle == 0 ) SWT .error (error );
973+ if (imageMetadata == null ) SWT .error (error );
974+ }
975+
1001976 return imageMetadata ;
1002977}
1003978
979+ private int extractDepthForPixelFormat (BitmapData bitmapData ) {
980+ int depth = 0 ;
981+ switch (bitmapData .PixelFormat ) {
982+ case Gdip .PixelFormat1bppIndexed : depth = 1 ; break ;
983+ case Gdip .PixelFormat4bppIndexed : depth = 4 ; break ;
984+ case Gdip .PixelFormat8bppIndexed : depth = 8 ; break ;
985+ case Gdip .PixelFormat16bppARGB1555 :
986+ case Gdip .PixelFormat16bppRGB555 :
987+ case Gdip .PixelFormat16bppRGB565 : depth = 16 ; break ;
988+ case Gdip .PixelFormat24bppRGB : depth = 24 ; break ;
989+ case Gdip .PixelFormat32bppRGB :
990+ case Gdip .PixelFormat32bppARGB : depth = 32 ; break ;
991+ }
992+ return depth ;
993+ }
994+
995+ private long extractHandleForPixelFormat (int width , int height , int pixelFormat ) {
996+ long handle = 0 ;
997+ switch (pixelFormat ) {
998+ case Gdip .PixelFormat16bppRGB555 :
999+ case Gdip .PixelFormat16bppRGB565 :
1000+ handle = createDIB (width , height , 16 );
1001+ break ;
1002+ case Gdip .PixelFormat24bppRGB :
1003+ case Gdip .PixelFormat32bppCMYK :
1004+ handle = createDIB (width , height , 24 );
1005+ break ;
1006+ case Gdip .PixelFormat32bppRGB :
1007+ // These will lose either precision or transparency
1008+ case Gdip .PixelFormat16bppGrayScale :
1009+ case Gdip .PixelFormat48bppRGB :
1010+ case Gdip .PixelFormat32bppPARGB :
1011+ case Gdip .PixelFormat64bppARGB :
1012+ case Gdip .PixelFormat64bppPARGB :
1013+ handle = createDIB (width , height , 32 );
1014+ break ;
1015+ }
1016+ return handle ;
1017+ }
1018+
10041019long [] createGdipImage () {
10051020 return createGdipImage (this .getZoom ());
10061021}
@@ -2144,16 +2159,19 @@ ImageData getImageData(int zoom) {
21442159 @ Override
21452160 ImageHandle getImageMetadata (int zoom ) {
21462161 ElementAtZoom <String > imageCandidate = DPIUtil .validateAndGetImagePathAtZoom (provider , zoom );
2147- ImageData imageData = new ImageData (imageCandidate .element ());
2148- if (imageCandidate .zoom () == zoom ) {
2149- /* Release current native resources */
2150- ImageHandle imageMetadata = initNative (imageCandidate .element (), zoom );
2151- if (imageMetadata == null ) init (imageData , zoom );
2152- init ();
2153- } else {
2154- ImageData resizedData = DPIUtil .scaleImageData (device , imageData , zoom , imageCandidate .zoom ());
2155- ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2156- init (newData , zoom );
2162+ ImageHandle imageMetadata = initNative (imageCandidate .element (), zoom );
2163+ if (imageMetadata == null ) {
2164+ if (imageCandidate .zoom () == zoom ) {
2165+ /* Release current native resources */
2166+ ImageData imageData = new ImageData (imageCandidate .element ());
2167+ init (imageData , zoom );
2168+ init ();
2169+ } else {
2170+ ImageData imageData = new ImageData (imageCandidate .element ());
2171+ ImageData resizedData = DPIUtil .scaleImageData (device , imageData , zoom , imageCandidate .zoom ());
2172+ ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2173+ init (newData , zoom );
2174+ }
21572175 }
21582176 return zoomLevelToImageHandle .get (zoom );
21592177 }
0 commit comments