@@ -371,9 +371,7 @@ public Image(Device device, ImageData data) {
371371 super (device );
372372 if (data == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
373373 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
374- int deviceZoom = getZoom ();
375- data = scaleImageData (data , deviceZoom , 100 );
376- init (data , deviceZoom );
374+ this .imageProvider = new PlainImageDataProviderWrapper (data );
377375 init ();
378376 this .device .registerResourceWithZoomSupport (this );
379377}
@@ -416,10 +414,7 @@ public Image(Device device, ImageData source, ImageData mask) {
416414 SWT .error (SWT .ERROR_INVALID_ARGUMENT );
417415 }
418416 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
419- source = scaleImageData (source , getZoom (), 100 );
420- mask = scaleImageData (mask , getZoom (), 100 );
421- mask = ImageData .convertMask (mask );
422- initIconHandle (this .device , source , mask , getZoom ());
417+ this .imageProvider = new MaskedImageDataProviderWrapper (source , mask );
423418 init ();
424419 this .device .registerResourceWithZoomSupport (this );
425420}
@@ -479,11 +474,9 @@ public Image(Device device, ImageData source, ImageData mask) {
479474 */
480475public Image (Device device , InputStream stream ) {
481476 super (device );
477+ if (stream == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
482478 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
483- int deviceZoom = getZoom ();
484- ElementAtZoom <ImageData > imageCandidate = ImageDataLoader .load (stream , FileFormat .DEFAULT_ZOOM , deviceZoom );
485- ImageData data = scaleImageData (imageCandidate .element (), deviceZoom , imageCandidate .zoom ());
486- init (data , deviceZoom );
479+ this .imageProvider = new ImageDataLoaderStreamProviderWrapper (stream );
487480 init ();
488481 this .device .registerResourceWithZoomSupport (this );
489482}
@@ -524,10 +517,7 @@ public Image (Device device, String filename) {
524517 super (device );
525518 if (filename == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
526519 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
527- int deviceZoom = getZoom ();
528- ElementAtZoom <ImageData > imageCandidate = ImageDataLoader .load (filename , FileFormat .DEFAULT_ZOOM , deviceZoom );
529- ImageData data = scaleImageData (imageCandidate .element (), deviceZoom , imageCandidate .zoom ());
530- init (data , deviceZoom );
520+ this .imageProvider = new ImageDataLoaderFileProviderWrapper (filename );
531521 init ();
532522 this .device .registerResourceWithZoomSupport (this );
533523}
@@ -1947,6 +1937,156 @@ protected void destroy() {
19471937 }
19481938}
19491939
1940+ private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper {
1941+
1942+ protected abstract ElementAtZoom <ImageData > loadImageData (int zoom );
1943+
1944+ void initImage () {
1945+ // As the init call configured some Image attributes (e.g. type)
1946+ // it must be called
1947+ ImageData imageDataAt100 = getImageData (100 );
1948+ init (imageDataAt100 , 100 );
1949+ destroyHandleForZoom (100 );
1950+ }
1951+
1952+ @ Override
1953+ ImageData getImageData (int zoom ) {
1954+ if (zoomLevelToImageHandle .containsKey (zoom )) {
1955+ return zoomLevelToImageHandle .get (zoom ).getImageData ();
1956+ }
1957+ if (!zoomLevelToImageHandle .isEmpty ()) {
1958+ return getScaledImageData (zoom );
1959+ }
1960+ ElementAtZoom <ImageData > loadedImageData = loadImageData (zoom );
1961+ return DPIUtil .scaleImageData (device , loadedImageData , zoom );
1962+ }
1963+
1964+ @ Override
1965+ ImageHandle getImageMetadata (int zoom ) {
1966+ if (zoomLevelToImageHandle .containsKey (zoom )) {
1967+ return zoomLevelToImageHandle .get (zoom );
1968+ } else {
1969+ ImageData scaledImageData = getImageData (zoom );
1970+ ImageHandle imageHandle = init (scaledImageData , zoom );
1971+ return imageHandle ;
1972+ }
1973+ }
1974+ }
1975+
1976+ private class PlainImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
1977+ private ImageData imageDataAt100 ;
1978+
1979+ PlainImageDataProviderWrapper (ImageData imageData ) {
1980+ this .imageDataAt100 = (ImageData ) imageData .clone ();
1981+ initImage ();
1982+ }
1983+
1984+ @ Override
1985+ protected Rectangle getBounds (int zoom ) {
1986+ Rectangle rectangle = new Rectangle (0 , 0 , imageDataAt100 .width , imageDataAt100 .height );
1987+ return DPIUtil .scaleUp (rectangle , zoom );
1988+ }
1989+
1990+ @ Override
1991+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
1992+ return new ElementAtZoom <>(imageDataAt100 , 100 );
1993+ }
1994+
1995+ @ Override
1996+ AbstractImageProviderWrapper createCopy (Image image ) {
1997+ return image .new PlainImageDataProviderWrapper (this .imageDataAt100 );
1998+ }
1999+ }
2000+
2001+ private class MaskedImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
2002+ private final ImageData srcAt100 ;
2003+ private final ImageData maskAt100 ;
2004+
2005+ MaskedImageDataProviderWrapper (ImageData srcAt100 , ImageData maskAt100 ) {
2006+ this .srcAt100 = (ImageData ) srcAt100 .clone ();
2007+ this .maskAt100 = (ImageData ) maskAt100 .clone ();
2008+ initImage ();
2009+ }
2010+
2011+ @ Override
2012+ protected Rectangle getBounds (int zoom ) {
2013+ Rectangle rectangle = new Rectangle (0 , 0 , srcAt100 .width , srcAt100 .height );
2014+ return DPIUtil .scaleUp (rectangle , zoom );
2015+ }
2016+
2017+ @ Override
2018+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2019+ ImageData scaledSource = DPIUtil .scaleImageData (device , srcAt100 , zoom , 100 );
2020+ ImageData scaledMask = DPIUtil .scaleImageData (device , maskAt100 , zoom , 100 );
2021+ scaledMask = ImageData .convertMask (scaledMask );
2022+ ImageData mergedData = applyMask (scaledSource , scaledMask );
2023+ return new ElementAtZoom <>(mergedData , zoom );
2024+ }
2025+
2026+ @ Override
2027+ AbstractImageProviderWrapper createCopy (Image image ) {
2028+ return image .new MaskedImageDataProviderWrapper (this .srcAt100 , this .maskAt100 );
2029+ }
2030+ }
2031+
2032+ private class ImageDataLoaderStreamProviderWrapper extends ImageFromImageDataProviderWrapper {
2033+ private byte [] inputStreamData ;
2034+
2035+ ImageDataLoaderStreamProviderWrapper (InputStream inputStream ) {
2036+ try {
2037+ this .inputStreamData = inputStream .readAllBytes ();
2038+ initImage ();
2039+ } catch (IOException e ) {
2040+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , e );
2041+ }
2042+ }
2043+
2044+ private ImageDataLoaderStreamProviderWrapper (byte [] inputStreamData ) {
2045+ this .inputStreamData = inputStreamData ;
2046+ }
2047+
2048+ @ Override
2049+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2050+ return ImageDataLoader .load (new ByteArrayInputStream (inputStreamData ), FileFormat .DEFAULT_ZOOM , zoom );
2051+ }
2052+
2053+ @ Override
2054+ protected Rectangle getBounds (int zoom ) {
2055+ ImageData scaledImageData = getImageData (zoom );
2056+ return new Rectangle (0 , 0 , scaledImageData .width , scaledImageData .height );
2057+ }
2058+
2059+ @ Override
2060+ AbstractImageProviderWrapper createCopy (Image image ) {
2061+ return new ImageDataLoaderStreamProviderWrapper (inputStreamData );
2062+ }
2063+ }
2064+
2065+ private class ImageDataLoaderFileProviderWrapper extends ImageFromImageDataProviderWrapper {
2066+ private String fileName ;
2067+
2068+ ImageDataLoaderFileProviderWrapper (String fileName ) {
2069+ this .fileName = fileName ;
2070+ initImage ();
2071+ }
2072+
2073+ @ Override
2074+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2075+ return ImageDataLoader .load (fileName , FileFormat .DEFAULT_ZOOM , zoom );
2076+ }
2077+
2078+ @ Override
2079+ protected Rectangle getBounds (int zoom ) {
2080+ ImageData scaledImageData = getImageData (zoom );
2081+ return new Rectangle (0 , 0 , scaledImageData .width , scaledImageData .height );
2082+ }
2083+
2084+ @ Override
2085+ AbstractImageProviderWrapper createCopy (Image image ) {
2086+ return new ImageDataLoaderFileProviderWrapper (fileName );
2087+ }
2088+ }
2089+
19502090private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
19512091 private final int width ;
19522092 private final int height ;
0 commit comments