javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/org/eclipse/swt/internal/qt/graphics/Image.java
changeset 21 2a9601315dfc
child 47 f40128debb5d
child 78 71ad690e91f5
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved. This program and the accompanying materials
       
     4  * are made available under the terms of the Eclipse Public License v1.0
       
     5  * which accompanies this distribution, and is available at
       
     6  * http://www.eclipse.org/legal/epl-v10.html
       
     7  *
       
     8  * Contributors:
       
     9  *     Nokia Corporation - initial implementation
       
    10  *******************************************************************************/
       
    11 package org.eclipse.swt.internal.qt.graphics;
       
    12 
       
    13 
       
    14 import org.eclipse.swt.graphics.ImageData;
       
    15 
       
    16 public final class Image {
       
    17 
       
    18     /**
       
    19      * Specifies no transformation.
       
    20      */
       
    21     public static final int TRANS_NONE = 100;
       
    22     /**
       
    23      * Specifies transformation for 90 degrees clockwise
       
    24      * along z-axis.
       
    25      */
       
    26     public static final int TRANS_ROT90 = 101;
       
    27     /**
       
    28      * Specifies transformation for 180 degrees clockwise
       
    29      * along z-axis.
       
    30      */
       
    31     public static final int TRANS_ROT180 = 102;
       
    32     /**
       
    33      * Specifies transformation for 270 degrees clockwise
       
    34      * along z-axis.
       
    35      */
       
    36     public static final int TRANS_ROT270 = 103;
       
    37     /**
       
    38      * Specifies transformation for image mirror along y-axis.
       
    39      */
       
    40     public static final int TRANS_MIRROR = 104;
       
    41     /**
       
    42      * Specifies transformation for first image mirror along y-axis
       
    43      * and then 90 degrees rotation clockwise along z-axis.
       
    44      */
       
    45     public static final int TRANS_MIRROR_ROT90 = 105;
       
    46     /**
       
    47      * Specifies transformation for first image mirror along y-axis
       
    48      * and then 180 degrees rotation clockwise along z-axis.
       
    49      */
       
    50     public static final int TRANS_MIRROR_ROT180 = 106;
       
    51     /**
       
    52      * Specifies transformation for first image mirror along y-axis
       
    53      * and then 270 degrees rotation clockwise along z-axis.
       
    54      */
       
    55     public static final int TRANS_MIRROR_ROT270 = 107;
       
    56 
       
    57     /**
       
    58      * Specifies transformation for mirror the image along x-axis.
       
    59      */
       
    60     public static final int TRANS_FLIP_HORIZONTAL = 108;
       
    61 
       
    62     /**
       
    63      * Specifies transformation for mirror the image along y-axis.
       
    64      */
       
    65     public static final int TRANS_FLIP_VERTICAL = 109;
       
    66 
       
    67     /**
       
    68      * Specifies default image format.
       
    69      */
       
    70     public static final int FORMAT_IMG_NONE = 0;
       
    71 
       
    72     /**
       
    73      * Specifies 32 bit per pixel image format.
       
    74      */
       
    75     public static final int FORMAT_IMG_RGB32 = 1;
       
    76 
       
    77     /**
       
    78      * Specifies 32 bit per pixel image format with alpha channel.
       
    79      */
       
    80     public static final int FORMAT_IMG_ARGB32 = 2;
       
    81 
       
    82     /**
       
    83      * Specifies 32 bit per pixel image format with alpha channel.
       
    84      */
       
    85     public static final int FORMAT_IMG_ARGB32PREMULTIPLIED = 3;
       
    86 
       
    87     /**
       
    88      * Specifies 16 bit per pixel image format.
       
    89      */
       
    90     public static final int FORMAT_IMG_RGB16 = 4;
       
    91 
       
    92     /**
       
    93      * Specifies 16 bit per pixel image format.
       
    94      */
       
    95     public static final int FORMAT_IMG_RGB555 = 5;
       
    96 
       
    97     /**
       
    98      * Specifies 16 bit per pixel image format.
       
    99      */
       
   100     public static final int FORMAT_IMG_RGB444 = 6;
       
   101 
       
   102     /**
       
   103      * Specifies 16 bit per pixel image format.
       
   104      */
       
   105     public static final int FORMAT_IMG_RGB4444PREMULTIPLIED = 7;
       
   106 
       
   107     /**
       
   108      * Specifies 1 bit per pixel image format.
       
   109      */
       
   110     public static final int FORMAT_IMG_MONO = 8;
       
   111 
       
   112     // Native image handle
       
   113     int handle;
       
   114     // Handle of native QPixmap wrapped by image
       
   115     int pixmapHandle;
       
   116     // Status of native peer
       
   117     private boolean disposed;
       
   118     // Image dimensions
       
   119     private int w;
       
   120     private int h;
       
   121     
       
   122     // Image pixel format
       
   123     private int pixelFormat = FORMAT_IMG_NONE;
       
   124 
       
   125     // flag to indicate if this image is currently
       
   126     // bound as rendering target by GraphicsContext
       
   127     private boolean isBound = false;
       
   128     // GraphicsContext bound to this image
       
   129     private GraphicsContext boundingGc = null;
       
   130 
       
   131     /**
       
   132      * Constructs new image with given native image handle.
       
   133      *
       
   134      * @param imgHandle The handle of valid native image
       
   135      * @throws OutOfMemoryError if imgHandlde is invalid
       
   136      */
       
   137     Image(int imgHandle) {
       
   138     	Utils.validateUiThread();
       
   139         // validate handle
       
   140         if(imgHandle == 0) {
       
   141             throw new OutOfMemoryError();
       
   142         }
       
   143         // store handle & get dimensions
       
   144         handle = imgHandle;
       
   145         updateSize();
       
   146     }
       
   147 
       
   148     /**
       
   149      * Constructs new image filled with default fill color with specified width and height.
       
   150      *
       
   151      * @param width The width of new image
       
   152      * @param height The height of new image
       
   153      * @throws IllegalArgumetException if width or height is equal or less than zero
       
   154      * @throws OutOfMemoryError if memory allocation for new image fails
       
   155      */
       
   156     public Image(int width, int height) {
       
   157         Utils.validateUiThread();
       
   158         // check width and height
       
   159         if (width <= 0 || height <= 0) {
       
   160             throw new IllegalArgumentException("width or height is equal or less than 0");
       
   161         }
       
   162 
       
   163         // Construct image in native side and store the handle
       
   164         handle = OS.image_create(width, height, Config.IMAGE_DEFAULT_FILL_COLOR);     // may throw outOfMemoryError
       
   165         // set dimensions
       
   166         updateSize();
       
   167     }
       
   168 
       
   169     /**
       
   170      * Constructs new image with specified width, height and fill color.
       
   171      * The RGB values passed in is interpreted with the least significant eight bits giving the blue
       
   172      * component, the next eight more significant bits giving the green component, and the next eight
       
   173      * bits giving the red component. The high order byte of this value, i.e. alpha, is ignored.
       
   174      *
       
   175      * @param width The width of new image
       
   176      * @param height The height of new image
       
   177      * @param fillColor The initial fill color for the image in format #00RRGGBB.
       
   178      * @throws IllegalArgumetException if width or height is equal or less than zero
       
   179      * @throws OutOfMemoryError if memory allocation for new image fails
       
   180      */
       
   181     public Image(int width, int height, int fillColor) {
       
   182         Utils.validateUiThread();
       
   183         // check width and height
       
   184         if (width <= 0 || height <= 0) {
       
   185             throw new IllegalArgumentException("width or height is equal or less than 0");
       
   186         }
       
   187 
       
   188         // Construct image in native side and store the handle
       
   189         handle = OS.image_create(width, height, fillColor);     // may throw outOfMemoryError
       
   190         // set dimensions
       
   191         updateSize();
       
   192     }
       
   193 
       
   194     /**
       
   195      * Constructs a new instance of this class based on given image.
       
   196      *
       
   197      * @param sourceImage The image used as source
       
   198      * @throws NullPointerException if sourceImage is null
       
   199      * @throws OutOfMemoryError if memory allocation for new image fails
       
   200      */
       
   201     public Image(Image sourceImage) {
       
   202         this(sourceImage, 0, 0, 0, 0);
       
   203     }
       
   204 
       
   205     /**
       
   206      * Constructs a new instance of this class based on given image.
       
   207      * If the given copy region is empty, the whole image is copied.
       
   208      *
       
   209      * @param sourceImage The image used as source
       
   210      * @param x The top-left x coordinate of the copy region.
       
   211      * @param y The top-left y coordinate of the copy region.
       
   212      * @param width The width of the copy region.
       
   213      * @param height The height of the copy region.
       
   214      * @throws NullPointerException if sourceImage is null
       
   215      */
       
   216     public Image(Image sourceImage, int x, int y, int width, int height) {
       
   217         // validate sourceImage
       
   218         if (sourceImage == null) {
       
   219             throw new NullPointerException("img is null");
       
   220         }
       
   221         // Construct image in native side and store the handle
       
   222         handle = OS.image_create(sourceImage.handle, x, y, width, height); // may throw outOfMemoryError
       
   223         // set dimensions
       
   224         updateSize();
       
   225     }
       
   226 
       
   227     /**
       
   228      * Creates a new image from given ImageData
       
   229      * @param imageData
       
   230      * @throws NullPointerException if imageData is null
       
   231      */
       
   232     public Image(ImageData imageData) {
       
   233         if (imageData == null) {
       
   234             throw new NullPointerException("imageData is null");
       
   235         }
       
   236         handle = OS.image_create(imageData);
       
   237         // set dimensions
       
   238         updateSize();
       
   239     }
       
   240 
       
   241     /**
       
   242      * Constructs a new instance of this class based on the given rgb data.
       
   243      *
       
   244      * @param argbData a RGB data array where one pixel is specified as 0xAARRGGBB.
       
   245      * @param width The width of the image
       
   246      * @param height The height of the image
       
   247      * @param hasAlpha If true the rgb data has also an alpha channel,
       
   248      * otherwise all pixels are fully opaque, e.g. 0xFFRRGGBB.
       
   249      * @throws NullPointerException if the <code>argbData</code> is null
       
   250      *
       
   251      */
       
   252     public Image(int[] argbData, int width, int height, boolean hasAlpha) {
       
   253         // input validation
       
   254         if(argbData == null) {
       
   255             throw new NullPointerException("argbData is null");
       
   256         }
       
   257         // Construct an ge in native side and store the handle
       
   258         handle = OS.image_create(argbData, width, height, hasAlpha);
       
   259         // set dimensions
       
   260         updateSize();
       
   261     }
       
   262 
       
   263     /**
       
   264      * Disposes the instance if this image and frees memory.
       
   265      * After disposing image the only valid metdod is isDisposed(), other
       
   266      * methods will throw illegalStateException.
       
   267      *
       
   268      * If this instance is being disposed before gc has released it, the
       
   269      * releaseTarget() of binding gc is called automatically.
       
   270      */
       
   271     public void dispose() {
       
   272     	Utils.validateUiThread();
       
   273         if (handle != 0 || !disposed) {
       
   274             // If this instance is being disposed while
       
   275             // gc is still bound, release binding before disposing.
       
   276             if(isBound) {
       
   277                 isBound = false;
       
   278                 if(boundingGc != null) {
       
   279                     boundingGc.releaseTarget();
       
   280                 }
       
   281                 boundingGc = null;
       
   282             }
       
   283 
       
   284             // Delete window surface from cache in case
       
   285             // it is created for this instance
       
   286             SurfaceCache.getInstance().deleteSurface(this);
       
   287 
       
   288             // dispose native peer
       
   289             OS.image_dispose(handle);
       
   290             handle = 0;
       
   291             pixmapHandle = 0;
       
   292             disposed = true;
       
   293         }
       
   294     }
       
   295 
       
   296     /**
       
   297      * Gets the state of the image, is it disposed or not.
       
   298      *
       
   299      * @return true if this instanace has been disposed, otherwise false
       
   300      */
       
   301     public boolean isDisposed() {
       
   302         return disposed;
       
   303     }
       
   304 
       
   305     /**
       
   306      * Gets the format of the image.
       
   307      *
       
   308      * @return image format
       
   309      */
       
   310     public int getFormat() {
       
   311     	checkState();
       
   312     	if (pixelFormat == FORMAT_IMG_NONE) {
       
   313     		pixelFormat = OS.image_getFormat(handle);
       
   314     	}
       
   315         return pixelFormat;
       
   316     }
       
   317     /**
       
   318      * Gets the height of the image in pixels.
       
   319      *
       
   320      * @return The height of this image
       
   321      * @throws IllegalStateException if the image has already been disposed
       
   322      */
       
   323     public int getHeight() {
       
   324         checkState();
       
   325         return h;
       
   326     }
       
   327 
       
   328     /**
       
   329      * Gets the width of the image in pixels.
       
   330      *
       
   331      * @return The width of this image
       
   332      * @throws IllegalStateException if the image has already been disposed
       
   333      */
       
   334     public int getWidth() {
       
   335         checkState();
       
   336         return w;
       
   337     }
       
   338 
       
   339     /**
       
   340      * Copies image data to given integer array from rectangle specified
       
   341      * by x, y, width and height.
       
   342      *
       
   343      * @param argbData The integer array where image data is copied to
       
   344      * @param offset The index into the array where first pixel is stored
       
   345      * @param scanlength The relative offset in the array between pixles in consecutive rows of the region
       
   346      * @param x The x-coordinate of upper left corner of the region
       
   347      * @param y The y-coordinate of upper left corner of the region
       
   348      * @param width The width of the region
       
   349      * @param height The height of the region
       
   350      *
       
   351      * @throws ArrayIndexOutOfBoundsException if the operation tries to access an element in argbData outside is range
       
   352      * @throws IllegalArgumentException if the absolute value of scanlength is less than width
       
   353      * @throws IllegalArgumentException if area to be retrieved exceed the bounds of the image
       
   354      * @throws NullPointerException if argbData is null
       
   355      * @throws OutOfMemoryError if memory allocation failure occurs during operation
       
   356      * @throws IllegalStateException if the image has already been disposed
       
   357      */
       
   358     public void getRGB(int[] argbData, int offset, int scanlength,
       
   359                        int x, int y, int width, int height) {
       
   360         checkState();
       
   361 
       
   362         // input validation
       
   363         if(argbData == null) {
       
   364             throw new NullPointerException("argbData is null");
       
   365         }
       
   366         if(((x+width) > getWidth()) || ((y+height) > getHeight()) || (x < 0) || (y < 0)) {
       
   367                 throw new IllegalArgumentException("Area specified is out of image bounds");
       
   368         }
       
   369         if(scanlength < 0) {
       
   370             // End of first row
       
   371             int a = width - 1;
       
   372             int b = 0;
       
   373             int index = offset + (a - x) + (b -y) * scanlength;
       
   374             if(index > argbData.length - 1) {
       
   375                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   376             }
       
   377             // Beginning of last row
       
   378             a = 0;
       
   379             b = height - 1;
       
   380             index = offset + (a - x) + (b -y) * scanlength;
       
   381             if(index < 0) {
       
   382                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   383             }
       
   384         } else {
       
   385             if((argbData.length < (offset + (scanlength * height))) || offset < 0) {
       
   386                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   387             }
       
   388         }
       
   389         if((scanlength > 0 ? scanlength : -scanlength) < width) {
       
   390             throw new IllegalArgumentException("scanlength is less than width");
       
   391         }
       
   392 
       
   393 
       
   394         OS.image_getRGB(handle, argbData, offset, scanlength, x, y, width, height);
       
   395     }
       
   396 
       
   397 
       
   398     /**TODO: change comments
       
   399      * Copies image data to given integer array from rectangle specified
       
   400      * by x, y, width and height.
       
   401      *
       
   402      * @param argbData The byte array where image data is copied to
       
   403      * @param transparencyMask the byte array where mask values are copied to
       
   404      * @param offset The index into the array where first pixel is stored
       
   405      * @param scanlength The relative offset in the array between pixles in consecutive rows of the region
       
   406      * @param x The x-coordinate of upper left corner of the region
       
   407      * @param y The y-coordinate of upper left corner of the region
       
   408      * @param width The width of the region
       
   409      * @param height The height of the region
       
   410      * @param format The format in which pixels are stored into argbData
       
   411      * @throws ArrayIndexOutOfBoundsException if the operation tries to access an element in argbData outside is range
       
   412      * @throws IllegalArgumentException if the absolute value of scanlength is less than width
       
   413      * @throws IllegalArgumentException if area to be retrieved exceed the bounds of the image
       
   414      * @throws NullPointerException if argbData is null
       
   415      * @throws OutOfMemoryError if memory allocation failure occurs during operation
       
   416      * @throws IllegalStateException if the image has already been disposed
       
   417      */
       
   418     public void getRGB(byte[] argbData, byte[] transparencyMask, int offset, int scanlength,
       
   419                        int x, int y, int width, int height, int format) {
       
   420         checkState();
       
   421 
       
   422         // input validation
       
   423         if(argbData == null) {
       
   424             throw new NullPointerException("argbData is null");
       
   425         }
       
   426         if(transparencyMask == null) {
       
   427             throw new IllegalArgumentException("transparencyMask is null");
       
   428         }
       
   429         if(((x+width) > getWidth()) || ((y+height) > getHeight()) || (x < 0) || (y < 0)) {
       
   430                 throw new IllegalArgumentException("Area specified is out of image bounds");
       
   431         }
       
   432         if(scanlength < 0) {
       
   433             // End of first row
       
   434             int a = width - 1;
       
   435             int b = 0;
       
   436             int index = offset + (a - x) + (b -y) * scanlength;
       
   437             if(index > argbData.length - 1) {
       
   438                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   439             }
       
   440             if(index > transparencyMask.length - 1) {
       
   441                 throw new ArrayIndexOutOfBoundsException("Mask does not fit in given array");
       
   442             }
       
   443             // Beginning of last row
       
   444             a = 0;
       
   445             b = height - 1;
       
   446             index = offset + (a - x) + (b -y) * scanlength;
       
   447             if(index < 0) {
       
   448                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   449             }
       
   450         } else {
       
   451             if((argbData.length < (offset + (scanlength * height))) || offset < 0) {
       
   452                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   453             }
       
   454             if((transparencyMask.length < (offset + (scanlength * height))) || offset < 0) {
       
   455                 throw new ArrayIndexOutOfBoundsException("Mask does not fit in given array");
       
   456             }
       
   457         }
       
   458         if((scanlength > 0 ? scanlength : -scanlength) < width) {
       
   459             throw new IllegalArgumentException("scanlength is less than width");
       
   460         }
       
   461 
       
   462 
       
   463         OS.image_getRGB(handle, argbData, transparencyMask,offset, scanlength, x, y, width, height, format);
       
   464     }
       
   465 
       
   466 
       
   467     /**
       
   468      * Copies image data to given integer array from rectangle specified
       
   469      * by x, y, width and height.
       
   470      *
       
   471      * @param argbData The short array where image data is copied to
       
   472      * @param offset The index into the array where first pixel is stored
       
   473      * @param scanlength The relative offset in the array between pixles in consecutive rows of the region
       
   474      * @param x The x-coordinate of upper left corner of the region
       
   475      * @param y The y-coordinate of upper left corner of the region
       
   476      * @param width The width of the region
       
   477      * @param height The height of the region
       
   478      * @param format Image format in which pixels are store into argbData //TODO:add explanation when format are addewd to image.
       
   479      *
       
   480      * @throws ArrayIndexOutOfBoundsException if the operation tries to access an element in argbData outside is range
       
   481      * @throws IllegalArgumentException if the absolute value of scanlength is less than width
       
   482      * @throws IllegalArgumentException if area to be retrieved exceed the bounds of the image
       
   483      * @throws NullPointerException if argbData is null
       
   484      * @throws OutOfMemoryError if memory allocation failure occurs during operation
       
   485      * @throws IllegalStateException if the image has already been disposed
       
   486      */
       
   487     public void getRGB(short[] argbData, int offset, int scanlength,
       
   488                        int x, int y, int width, int height, int format) {
       
   489         checkState();
       
   490 
       
   491         // input validation
       
   492         if(argbData == null) {
       
   493             throw new NullPointerException("argbData is null");
       
   494         }
       
   495         if(((x+width) > getWidth()) || ((y+height) > getHeight()) || (x < 0) || (y < 0)) {
       
   496                 throw new IllegalArgumentException("Area specified is out of image bounds");
       
   497         }
       
   498         if(scanlength < 0) {
       
   499             // End of first row
       
   500             int a = width - 1;
       
   501             int b = 0;
       
   502             int index = offset + (a - x) + (b -y) * scanlength;
       
   503             if(index > argbData.length - 1) {
       
   504                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   505             }
       
   506             // Beginning of last row
       
   507             a = 0;
       
   508             b = height - 1;
       
   509             index = offset + (a - x) + (b -y) * scanlength;
       
   510             if(index < 0) {
       
   511                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   512             }
       
   513         } else {
       
   514             if((argbData.length < (offset + (scanlength * height))) || offset < 0) {
       
   515                 throw new ArrayIndexOutOfBoundsException("Data does not fit in given array");
       
   516             }
       
   517         }
       
   518         if((scanlength > 0 ? scanlength : -scanlength) < width) {
       
   519             throw new IllegalArgumentException("scanlength is less than width");
       
   520         }
       
   521 
       
   522 
       
   523         OS.image_getRGB(handle, argbData, offset, scanlength, x, y, width, height, format);
       
   524     }
       
   525 
       
   526     /**
       
   527      * Pixel level collision detection.
       
   528      */
       
   529     public static boolean detectCollision(Image image1, int transform1, int p1x, int p1y, int r1x1, int r1y1, int r1x2, int r1y2,
       
   530                                           Image image2, int transform2, int p2x, int p2y, int r2x1, int r2y1, int r2x2, int r2y2) {
       
   531 
       
   532         return OS.image_detectCollision(
       
   533                 image1.getNativePixmapHandle(), transform1, p1x, p1y, r1x1, r1y1, r1x2, r1y2,
       
   534                 image2.getNativePixmapHandle(), transform2, p2x, p2y, r2x1, r2y1, r2x2, r2y2);
       
   535     }
       
   536 
       
   537     /**
       
   538      * Transforms image with given transform.
       
   539      *
       
   540      * @throws IllegalArgumentException if transform is not valid
       
   541      * @throws IllegalStateException if the image has already been disposed
       
   542      */
       
   543     public void transform(int transform) {
       
   544         checkState();
       
   545 
       
   546         // validate transform
       
   547         if (transform != TRANS_NONE &&
       
   548             transform != TRANS_ROT90 &&
       
   549             transform != TRANS_ROT180 &&
       
   550             transform != TRANS_ROT270 &&
       
   551             transform != TRANS_MIRROR &&
       
   552             transform != TRANS_MIRROR_ROT90 &&
       
   553             transform != TRANS_MIRROR_ROT180 &&
       
   554             transform != TRANS_MIRROR_ROT270 ) {
       
   555             throw new IllegalArgumentException("Invalid transform");
       
   556         }
       
   557 
       
   558         // if no transformation is requested, return
       
   559         if(transform == TRANS_NONE) {
       
   560             return;
       
   561         }
       
   562 
       
   563         // perform transform
       
   564         OS.image_transform(handle, transform);
       
   565 
       
   566         // update width and height
       
   567         updateSize();
       
   568     }
       
   569 
       
   570     /**
       
   571      * Package private method to infrom this image that
       
   572      * it has been bound as rendering target by GraphicsContext.
       
   573      *
       
   574      * @param gc The GraphicsContext that binds this image as target
       
   575      */
       
   576     void notifyBind(GraphicsContext gc) {
       
   577         boundingGc = gc;
       
   578         isBound = true;
       
   579     }
       
   580 
       
   581     /**
       
   582      * Package private method to infrom this image that
       
   583      * it is no longer as a rendering target of gc.
       
   584      */
       
   585     void notifyRelease() {
       
   586         boundingGc = null;
       
   587         isBound = false;
       
   588     }
       
   589 
       
   590     /**
       
   591      * Returns native side handle.
       
   592      * @return the native handle.
       
   593      */
       
   594     public int getHandle()
       
   595     {
       
   596     	checkState();
       
   597         return handle;
       
   598     }
       
   599 
       
   600     /**
       
   601      * Returns native side QPixmap handle.
       
   602      * @return the native QPixmap handle.
       
   603      */
       
   604     synchronized public int getNativePixmapHandle()
       
   605     {
       
   606     	checkState();
       
   607         if(pixmapHandle == 0)
       
   608         {
       
   609             // In the current implementation this will return
       
   610             // pointer to the already existing QPixmap (which
       
   611             // will be destroyed with the object), so the
       
   612             // handle does not need to be released manually.
       
   613             pixmapHandle = OS.image_getPixmapHandle(handle);
       
   614         }
       
   615         return pixmapHandle;
       
   616     }
       
   617 
       
   618     /**
       
   619     /**
       
   620      * Creates <code>ImageData</code> objects
       
   621      * @return New object
       
   622      */
       
   623     public ImageData getImageData() {
       
   624     	checkState();
       
   625         return OS.image_getImageData(handle);
       
   626     }
       
   627 
       
   628     /**
       
   629      * Private helper to check the state of the current instance.
       
   630      */
       
   631     private void checkState() {
       
   632     	Utils.validateUiThread();
       
   633         if(disposed) {
       
   634             throw new IllegalStateException("Image already disposed");
       
   635         }
       
   636     }
       
   637 
       
   638     /**
       
   639      * private helper for updating iWidth and iHeight from native image.
       
   640      */
       
   641     private void updateSize() {
       
   642         w = OS.image_getWidth(handle);
       
   643         h = OS.image_getHeight(handle);
       
   644     }
       
   645 
       
   646     /**
       
   647      * Contructs an instance of Image based on the given <code>imageData</code>.
       
   648      *
       
   649      * @param imageData Image data @see org.eclipse.swt.graphics.ImageData
       
   650      * @return Instance of loaded image
       
   651      * @throws IllegalArgumentException if <code>imageData</code> is null.
       
   652      */
       
   653     public static Image createImage(ImageData imageData) {
       
   654         if (imageData == null) {
       
   655             throw new IllegalArgumentException("imageData is null");
       
   656         }
       
   657         int imageHandle = OS.image_create(imageData);
       
   658         return new Image(imageHandle);
       
   659     }
       
   660 }