javauis/lcdui_qt/src/javax/microedition/lcdui/Image.java
branchRCL_3
changeset 65 ae942d28ec0e
equal deleted inserted replaced
60:6c158198356e 65:ae942d28ec0e
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 package javax.microedition.lcdui;
       
    18 
       
    19 import java.io.*;
       
    20 
       
    21 import javax.microedition.lcdui.game.Sprite;
       
    22 
       
    23 import org.eclipse.swt.graphics.Internal_GfxPackageSupport;
       
    24 
       
    25 /**
       
    26  * Class containing graphical data of image.<br>
       
    27  * <br>
       
    28  * Image path handling is not implemented correctly, for example "standard"
       
    29  * LCDUI accepts path "/TestMIDlets/images/100x100.png" but corresponding path
       
    30  * with this image-class must be "/100x100.png".
       
    31  */
       
    32 public class Image
       
    33 {
       
    34 
       
    35     private static Image createImageReturnValue;
       
    36 
       
    37     private org.eclipse.swt.graphics.Image eswtImage;
       
    38     private int eswtImageWidth;
       
    39     private int eswtImageHeight;
       
    40     private boolean mutable;
       
    41     private com.nokia.mj.impl.rt.support.Finalizer finalizer;
       
    42 
       
    43     // buffer has package visibility so that it can be used as
       
    44     // a lock in other classes
       
    45     ImageBuffer graphicsBuffer;
       
    46     
       
    47     // Graphics for transferring instance
       
    48     // between application and UI thread
       
    49     Graphics tempGraphics;
       
    50 
       
    51     /**
       
    52      * Constructor.
       
    53      */
       
    54     Image(org.eclipse.swt.graphics.Image eswtImage, boolean isMutable)
       
    55     {
       
    56         this.eswtImage = eswtImage;
       
    57         this.mutable = isMutable;
       
    58         eswtImageWidth = eswtImage.getBounds().width;
       
    59         eswtImageHeight = eswtImage.getBounds().height;
       
    60         graphicsBuffer = new ImageBuffer(this);
       
    61         finalizer = ((finalizer != null) ? finalizer
       
    62                      : new com.nokia.mj.impl.rt.support.Finalizer()
       
    63         {
       
    64             public void finalizeImpl()
       
    65             {
       
    66                 if(finalizer != null)
       
    67                 {
       
    68                     finalizer = null;
       
    69                     if(!ESWTUIThreadRunner.isDisposed())
       
    70                     {
       
    71                         dispose();
       
    72                     }
       
    73                 }
       
    74             }
       
    75         });
       
    76         ESWTUIThreadRunner.update(getClass().getName(), 1);
       
    77     }
       
    78 
       
    79     /**
       
    80      * Called by finalizer when Image is ready to free its resources.
       
    81      */
       
    82     void dispose()
       
    83     {
       
    84         ESWTUIThreadRunner.update(getClass().getName(), -1);
       
    85         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
    86         {
       
    87             public void run()
       
    88             {
       
    89                 if(eswtImage != null)
       
    90                 {
       
    91                     eswtImage.dispose();
       
    92                     eswtImage = null;
       
    93                 }
       
    94                 graphicsBuffer.dispose();
       
    95             }
       
    96         });
       
    97     }
       
    98 
       
    99     /**
       
   100      * Return eSWT Image object.
       
   101      */
       
   102     org.eclipse.swt.graphics.Image getESWTImage()
       
   103     {
       
   104         return eswtImage;
       
   105     }
       
   106 
       
   107     /**
       
   108      * Return eSWT Image object.
       
   109      *
       
   110      * @param img Image
       
   111      * @return eSWT Image
       
   112      */
       
   113     static org.eclipse.swt.graphics.Image getESWTImage(Image img)
       
   114     {
       
   115         if(img != null)
       
   116         {
       
   117             return img.eswtImage;
       
   118         }
       
   119         return null;
       
   120     }
       
   121 
       
   122     /**
       
   123      * Creates new mutable image where every pixel is white.
       
   124      *
       
   125      * @param w The width of the image to be created.
       
   126      * @param h The height of the image to be created.
       
   127      * @return Image created.
       
   128      * @throws IllegalArgumentException if width or height are zero or less.
       
   129      */
       
   130     public static Image createImage(int w, int h)
       
   131     {
       
   132         if(w <= 0 || h <= 0)
       
   133         {
       
   134             throw new IllegalArgumentException(
       
   135                 MsgRepository.IMAGE_EXCEPTION_INVALID_DIMENSIONS);
       
   136         }
       
   137 
       
   138         final int width = w;
       
   139         final int height = h;
       
   140         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   141         {
       
   142             public void run()
       
   143             {
       
   144                 org.eclipse.swt.graphics.Image eswtImg =
       
   145                     eswtCreateImage(width, height);
       
   146 
       
   147                 if(eswtImg != null)
       
   148                 {
       
   149                     createImageReturnValue = new Image(eswtImg, true);
       
   150                 }
       
   151                 else
       
   152                 {
       
   153                     createImageReturnValue = null;
       
   154                     throw new OutOfMemoryError();
       
   155                 }
       
   156             }
       
   157         });
       
   158         return createImageReturnValue;
       
   159     }
       
   160 
       
   161     /**
       
   162      * Creates an immutable image with the specified size from the existing
       
   163      * image source.
       
   164      *
       
   165      * @param srcImage the source of image.
       
   166      * @param width the width of the new image.
       
   167      * @param height the height of the new image.
       
   168      * @return the resized Image.
       
   169      * @throws NullPointerException if aImage is null.
       
   170      */
       
   171     static Image createImage(Image srcImage, int width, int height)
       
   172     {
       
   173         if(srcImage == null)
       
   174         {
       
   175             throw new NullPointerException(
       
   176                 MsgRepository.IMAGE_EXCEPTION_IS_NULL);
       
   177         }
       
   178         final Image finalImage = srcImage;
       
   179         final int finalWidth = width;
       
   180         final int finalHeight = height;
       
   181         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   182         {
       
   183             public void run()
       
   184             {
       
   185                 org.eclipse.swt.graphics.Image eswtImg =
       
   186                     eswtCreateImage(finalImage.eswtImage, finalWidth, finalHeight);
       
   187 
       
   188                 if(eswtImg != null)
       
   189                 {
       
   190                     createImageReturnValue = new Image(eswtImg, false);
       
   191                 }
       
   192                 else
       
   193                 {
       
   194                     createImageReturnValue = null;
       
   195                     throw new OutOfMemoryError();
       
   196                 }
       
   197             }
       
   198         });
       
   199         return createImageReturnValue;
       
   200     }
       
   201 
       
   202     /**
       
   203      * Creates immutable image from existing image source.
       
   204      *
       
   205      * @param srcImage The source of image.
       
   206      * @return Image created.
       
   207      * @throws NullPointerException if source image is null.
       
   208      */
       
   209     public static Image createImage(Image srcImage)
       
   210     {
       
   211         if(srcImage == null)
       
   212         {
       
   213             throw new NullPointerException(
       
   214                 MsgRepository.IMAGE_EXCEPTION_IS_NULL);
       
   215         }
       
   216 
       
   217         if(!srcImage.isMutable())
       
   218         {
       
   219             return srcImage;
       
   220         }
       
   221 
       
   222         final Image finalImage = srcImage;
       
   223         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   224         {
       
   225             public void run()
       
   226             {
       
   227                 org.eclipse.swt.graphics.Image eswtImg =
       
   228                     eswtCreateImage(finalImage.eswtImage);
       
   229 
       
   230                 if(eswtImg != null)
       
   231                 {
       
   232                     createImageReturnValue = new Image(eswtImg, false);
       
   233                 }
       
   234                 else
       
   235                 {
       
   236                     createImageReturnValue = null;
       
   237                     throw new OutOfMemoryError();
       
   238                 }
       
   239             }
       
   240         });
       
   241         return createImageReturnValue;
       
   242     }
       
   243 
       
   244     /**
       
   245      * Creates an immutable image from named resource.
       
   246      *
       
   247      * @param name The name of the resource.
       
   248      * @return Image created.
       
   249      * @throws NullPointerException if name is null.
       
   250      * @throws IOException If resource doesn't exist, data cannot be loaded or
       
   251      *             data is invalid.
       
   252      */
       
   253     public static Image createImage(String name) throws IOException
       
   254     {
       
   255         if(name == null)
       
   256         {
       
   257             throw new NullPointerException(
       
   258                 MsgRepository.IMAGE_EXCEPTION_FILE_NAME_IS_NULL);
       
   259         }
       
   260 
       
   261         String fileName = name;
       
   262         if(!fileName.startsWith("/"))
       
   263         {
       
   264             fileName = "/" + fileName;
       
   265         }
       
   266 
       
   267         InputStream stream = Image.class.getResourceAsStream(fileName);
       
   268         if(stream == null)
       
   269         {
       
   270             throw new IOException(MsgRepository.IMAGE_EXCEPTION_IO_ERROR);
       
   271         }
       
   272         Image image = createImage(stream);
       
   273         try
       
   274         {
       
   275             stream.close();
       
   276         }
       
   277         catch(IOException e)
       
   278         {
       
   279             // ignore
       
   280         }
       
   281         return image;
       
   282     }
       
   283 
       
   284     /**
       
   285      * Creates immutable image from stream. Thread's execution is blocked until
       
   286      * this method is finished.
       
   287      *
       
   288      * @param stream The stream.
       
   289      * @return Image created.
       
   290      * @throws NullPointerException if stream is null.
       
   291      * @throws java.io.IOException If I/O error occurs or data from stream is
       
   292      *             invalid.
       
   293      */
       
   294     public static Image createImage(InputStream stream) throws java.io.IOException
       
   295     {
       
   296         if(stream == null)
       
   297         {
       
   298             throw new NullPointerException(
       
   299                 MsgRepository.IMAGE_EXCEPTION_FILE_STREAM_IS_NULL);
       
   300         }
       
   301         final InputStream finalStream = stream;
       
   302         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   303         {
       
   304             public void run()
       
   305             {
       
   306                 org.eclipse.swt.graphics.Image eswtImg = eswtCreateImage(finalStream);
       
   307 
       
   308                 if(eswtImg != null)
       
   309                 {
       
   310                     createImageReturnValue = new Image(eswtImg, false);
       
   311                 }
       
   312                 else
       
   313                 {
       
   314                     createImageReturnValue = null;
       
   315                 }
       
   316             }
       
   317         });
       
   318         if(createImageReturnValue == null)
       
   319         {
       
   320             throw new IOException(MsgRepository.IMAGE_EXCEPTION_IO_ERROR);
       
   321         }
       
   322         return createImageReturnValue;
       
   323     }
       
   324 
       
   325     /**
       
   326      * Creates new immutable image from image data provided.
       
   327      *
       
   328      * @param imgData Image data.
       
   329      * @param imgOffset Start offset in image data.
       
   330      * @param imgLength Length of data used.
       
   331      * @return Image created.
       
   332      * @throws ArrayIndexOutOfBoundsException if imgOffset and imgLength
       
   333      *             specifies invalid range.
       
   334      * @throws NullPointerException if imgData is null.
       
   335      * @throws IllegalArgumentException if imgData content is invalid.
       
   336      */
       
   337     public static Image createImage(byte[] imgData, int imgOffset, int imgLength)
       
   338     {
       
   339         if(imgData == null)
       
   340         {
       
   341             throw new NullPointerException(
       
   342                 MsgRepository.IMAGE_EXCEPTION_DATA_IS_NULL);
       
   343         }
       
   344         if(imgOffset + imgLength > imgData.length)
       
   345         {
       
   346             throw new ArrayIndexOutOfBoundsException(
       
   347                 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS);
       
   348         }
       
   349         if(imgOffset < 0 || imgLength < 0)
       
   350         {
       
   351             throw new ArrayIndexOutOfBoundsException(
       
   352                 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS);
       
   353         }
       
   354 
       
   355         InputStream inputStream = new ByteArrayInputStream(imgData, imgOffset, imgLength);
       
   356         try
       
   357         {
       
   358             createImageReturnValue = createImage(inputStream);
       
   359         }
       
   360         catch(IOException e)
       
   361         {
       
   362             throw new IllegalArgumentException(
       
   363                 MsgRepository.IMAGE_EXCEPTION_INVALID_DATA);
       
   364         }
       
   365         finally
       
   366         {
       
   367             try
       
   368             {
       
   369                 inputStream.close();
       
   370             }
       
   371             catch(IOException e)
       
   372             {
       
   373                 // ignore
       
   374             }
       
   375         }
       
   376         return createImageReturnValue;
       
   377     }
       
   378 
       
   379     /**
       
   380      * Creates an immutable image from specified region of existing source image
       
   381      * with specified transform.
       
   382      *
       
   383      * @param srcImage Source image.
       
   384      * @param x Region's x.
       
   385      * @param y Region's y.
       
   386      * @param w Regions width.
       
   387      * @param h Regions height.
       
   388      * @param transform Transform, one of the transforms specified in
       
   389      *            Sprite-class.
       
   390      * @return Image created.
       
   391      * @throws NullPointerException if img is null.
       
   392      * @throws IllegalArgumentException if Region specified exceeds the source
       
   393      *             image or if w or h is zero or less or if transform is not one
       
   394      *             defined in Sprite-class.
       
   395      */
       
   396     public static Image createImage(Image srcImage,
       
   397                                     int x,
       
   398                                     int y,
       
   399                                     int w,
       
   400                                     int h,
       
   401                                     int transform)
       
   402     {
       
   403         if(srcImage == null)
       
   404         {
       
   405             throw new NullPointerException(
       
   406                 MsgRepository.IMAGE_EXCEPTION_IS_NULL);
       
   407         }
       
   408         if(w <= 0 || h <= 0)
       
   409         {
       
   410             throw new IllegalArgumentException(
       
   411                 MsgRepository.IMAGE_EXCEPTION_INVALID_DIMENSIONS);
       
   412         }
       
   413         if(!validateTransform(transform))
       
   414         {
       
   415             throw new IllegalArgumentException(
       
   416                 MsgRepository.IMAGE_EXCEPTION_INVALID_TRANSFORM);
       
   417         }
       
   418         if(!validateRegion(srcImage.getWidth(), srcImage.getHeight(), x, y, w, h))
       
   419         {
       
   420             throw new IllegalArgumentException(
       
   421                 MsgRepository.IMAGE_EXCEPTION_INVALID_REGION);
       
   422         }
       
   423 
       
   424         final Image fImage = srcImage;
       
   425         final int fx = x;
       
   426         final int fy = y;
       
   427         final int fw = w;
       
   428         final int fh = h;
       
   429         final int fTransform = transform;
       
   430         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   431         {
       
   432             public void run()
       
   433             {
       
   434                 org.eclipse.swt.internal.qt.graphics.Image srcCgImage =
       
   435                     Internal_GfxPackageSupport.getImage(fImage.getESWTImage());
       
   436 
       
   437                 org.eclipse.swt.internal.qt.graphics.Image cgImage =
       
   438                     new org.eclipse.swt.internal.qt.graphics.Image(
       
   439                     srcCgImage, fx, fy, fw, fh);
       
   440 
       
   441                 cgImage.transform(getCgTransformValue(fTransform));
       
   442 
       
   443                 org.eclipse.swt.graphics.Image eswtImg =
       
   444                     Internal_GfxPackageSupport.new_Image(
       
   445                         ESWTUIThreadRunner.getInstance().getDisplay(),
       
   446                         cgImage);
       
   447 
       
   448                 if(eswtImg != null)
       
   449                 {
       
   450                     createImageReturnValue = new Image(eswtImg, false);
       
   451                 }
       
   452                 else
       
   453                 {
       
   454                     createImageReturnValue = null;
       
   455                     throw new OutOfMemoryError();
       
   456                 }
       
   457             }
       
   458         });
       
   459         return createImageReturnValue;
       
   460     }
       
   461 
       
   462     /**
       
   463      * Validates that a specified region is fully located within the image
       
   464      * bounds. Method is package-private, used by Graphics.drawRegion as well.
       
   465      */
       
   466     static boolean validateRegion(int srcWidth, int srcHeight, int x, int y,
       
   467                                   int w, int h)
       
   468     {
       
   469         return x >= 0 && y >= 0 && w <= srcWidth && h <= srcHeight;
       
   470     }
       
   471 
       
   472     /**
       
   473      * Validates if transform has a valid value. Method is package-private, used
       
   474      * by Graphics.drawRegion as well.
       
   475      */
       
   476     static boolean validateTransform(int transform)
       
   477     {
       
   478         return transform == Sprite.TRANS_NONE
       
   479                || transform == Sprite.TRANS_MIRROR
       
   480                || transform == Sprite.TRANS_MIRROR_ROT90
       
   481                || transform == Sprite.TRANS_MIRROR_ROT180
       
   482                || transform == Sprite.TRANS_MIRROR_ROT270
       
   483                || transform == Sprite.TRANS_ROT90
       
   484                || transform == Sprite.TRANS_ROT180
       
   485                || transform == Sprite.TRANS_ROT270;
       
   486     }
       
   487 
       
   488     /**
       
   489      *  Maps LCDUI transform constants to Common Graphics. Method is package-private, used
       
   490      *  by Graphics.drawRegion as well.
       
   491      */
       
   492     static int getCgTransformValue(int transform)
       
   493     {
       
   494         int retVal = org.eclipse.swt.internal.qt.graphics.Image.TRANS_NONE;
       
   495         switch(transform)
       
   496         {
       
   497         case Sprite.TRANS_NONE:
       
   498             retVal = org.eclipse.swt.internal.qt.graphics.Image.TRANS_NONE;
       
   499             break;
       
   500         case Sprite.TRANS_ROT90:
       
   501             retVal = org.eclipse.swt.internal.qt.graphics.Image.TRANS_ROT90;
       
   502             break;
       
   503         case Sprite.TRANS_ROT180:
       
   504             retVal =
       
   505                 org.eclipse.swt.internal.qt.graphics.Image.TRANS_ROT180;
       
   506             break;
       
   507         case Sprite.TRANS_ROT270:
       
   508             retVal =
       
   509                 org.eclipse.swt.internal.qt.graphics.Image.TRANS_ROT270;
       
   510             break;
       
   511         case Sprite.TRANS_MIRROR:
       
   512             retVal =
       
   513                 org.eclipse.swt.internal.qt.graphics.Image.TRANS_MIRROR;
       
   514             break;
       
   515         case Sprite.TRANS_MIRROR_ROT90:
       
   516             retVal = org.eclipse.swt.internal.qt.graphics.
       
   517                      Image.TRANS_MIRROR_ROT90;
       
   518             break;
       
   519         case Sprite.TRANS_MIRROR_ROT180:
       
   520             retVal = org.eclipse.swt.internal.qt.graphics.
       
   521                      Image.TRANS_MIRROR_ROT180;
       
   522             break;
       
   523         case Sprite.TRANS_MIRROR_ROT270:
       
   524             retVal = org.eclipse.swt.internal.qt.graphics.
       
   525                      Image.TRANS_MIRROR_ROT270;
       
   526             break;
       
   527         default:
       
   528             break;
       
   529         }
       
   530         return retVal;
       
   531     }
       
   532 
       
   533     /**
       
   534      * Creates eSWT image as a copy of existing image.
       
   535      *
       
   536      * @param image - image to be copied.
       
   537      * @return new eSWT image.
       
   538      */
       
   539     private static org.eclipse.swt.graphics.Image eswtCreateImage(
       
   540         org.eclipse.swt.graphics.Image srcImage)
       
   541     {
       
   542         org.eclipse.swt.graphics.Image ret = null;
       
   543         try
       
   544         {
       
   545             org.eclipse.swt.internal.qt.graphics.Image cgImage =
       
   546                 Internal_GfxPackageSupport.getImage(srcImage);
       
   547 
       
   548             org.eclipse.swt.internal.qt.graphics.Image cgImage2 =
       
   549                 new org.eclipse.swt.internal.qt.graphics.Image(cgImage);
       
   550 
       
   551             ret = Internal_GfxPackageSupport.new_Image(
       
   552                       ESWTUIThreadRunner.getInstance().getDisplay(), cgImage2);
       
   553         }
       
   554         catch(IllegalArgumentException ex)
       
   555         {
       
   556             // Device is null or there's no current device.
       
   557             ret = null;
       
   558         }
       
   559         catch(org.eclipse.swt.SWTException ex)
       
   560         {
       
   561             ret = null;
       
   562         }
       
   563         catch(org.eclipse.swt.SWTError err)
       
   564         {
       
   565             ret = null;
       
   566         }
       
   567         return ret;
       
   568     }
       
   569 
       
   570     /**
       
   571      * Creates eSWT image of the specified size from the given image.
       
   572      */
       
   573     static org.eclipse.swt.graphics.Image eswtCreateImage(
       
   574         org.eclipse.swt.graphics.Image image, int newWidth, int newHeight)
       
   575     {
       
   576         org.eclipse.swt.graphics.Image ret = null;
       
   577         try
       
   578         {
       
   579             ret = new org.eclipse.swt.graphics.Image(
       
   580                 ESWTUIThreadRunner.getInstance().getDisplay(),
       
   581                 image.getImageData().scaledTo(newWidth, newHeight));
       
   582         }
       
   583         catch(IllegalArgumentException ex)
       
   584         {
       
   585             // Device is null or there's no current device.
       
   586             ret = null;
       
   587         }
       
   588         catch(org.eclipse.swt.SWTException ex)
       
   589         {
       
   590             ret = null;
       
   591         }
       
   592         catch(org.eclipse.swt.SWTError err)
       
   593         {
       
   594             ret = null;
       
   595         }
       
   596         return ret;
       
   597     }
       
   598 
       
   599     /**
       
   600      * Creates eSWT image of the specified size.
       
   601      */
       
   602     static org.eclipse.swt.graphics.Image eswtCreateImage(int width, int height)
       
   603     {
       
   604         org.eclipse.swt.graphics.Image ret = null;
       
   605         try
       
   606         {
       
   607             ret = new org.eclipse.swt.graphics.Image(
       
   608                 ESWTUIThreadRunner.getInstance().getDisplay(), width, height);
       
   609         }
       
   610         catch(IllegalArgumentException ex)
       
   611         {
       
   612             // Device is null or there's no current device.
       
   613             ret = null;
       
   614         }
       
   615         catch(org.eclipse.swt.SWTException ex)
       
   616         {
       
   617             ret = null;
       
   618         }
       
   619         catch(org.eclipse.swt.SWTError err)
       
   620         {
       
   621             ret = null;
       
   622         }
       
   623         return ret;
       
   624     }
       
   625 
       
   626     /**
       
   627      * Creates and eSWT image out of the InputStream.
       
   628      */
       
   629     static org.eclipse.swt.graphics.Image eswtCreateImage(InputStream inputStream)
       
   630     {
       
   631         org.eclipse.swt.graphics.Image ret = null;
       
   632         try
       
   633         {
       
   634             ret = new org.eclipse.swt.graphics.Image(
       
   635                 ESWTUIThreadRunner.getInstance().getDisplay(), inputStream);
       
   636         }
       
   637         catch(IllegalArgumentException ex)
       
   638         {
       
   639             // Device is null or there's no current device.
       
   640             ret = null;
       
   641         }
       
   642         catch(org.eclipse.swt.SWTException ex)
       
   643         {
       
   644             ret = null;
       
   645         }
       
   646         catch(org.eclipse.swt.SWTError err)
       
   647         {
       
   648             ret = null;
       
   649         }
       
   650         return ret;
       
   651     }
       
   652 
       
   653     /**
       
   654      * Synchronizes any pending draw commands to this image. The buffer sync 
       
   655      * must be executed in UI thread and if this method is not requested to switch to
       
   656      * UI thread, the caller must take care of serializing the call over the graphicsBuffer
       
   657      * of this instance.
       
   658      * 
       
   659      * @param switchToUIThread If true the sync is run in UI thread, oherwise
       
   660      *        caller must take care of switching to UI thread
       
   661      */
       
   662     void sync(boolean switchToUIThread)
       
   663     {
       
   664     	if(switchToUIThread) 
       
   665 		{
       
   666     	    synchronized(graphicsBuffer)
       
   667             {
       
   668                 ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   669                 {
       
   670                     public void run()
       
   671                     {
       
   672                         graphicsBuffer.sync();
       
   673                     }
       
   674                 });
       
   675             }
       
   676          } 
       
   677     	else 
       
   678     	{
       
   679     		graphicsBuffer.sync();
       
   680     	}
       
   681     }
       
   682 
       
   683     /**
       
   684      * Creates new image from specified RGB array data.
       
   685      *
       
   686      * @param rgbData Pixel data.
       
   687      * @param width Width of the image to be created.
       
   688      * @param height Height of the image to be created.
       
   689      * @param processAlpha true if there's alpha channel in image data.
       
   690      *            Otherwise method assumes that all pixels are fully opaque.
       
   691      * @return Image created.
       
   692      * @throws NullPointerException if rgb is null.
       
   693      * @throws IllegalArgumentException if w or h is zero or less.
       
   694      * @throws ArrayIndexOutOfBoundsException if the w and h parameters doesn't
       
   695      *             match the length of the data array provided.
       
   696      */
       
   697     public static Image createRGBImage(int[] rgbData,
       
   698                                        int width,
       
   699                                        int height,
       
   700                                        boolean processAlpha)
       
   701     {
       
   702 
       
   703         if(rgbData == null)
       
   704         {
       
   705             throw new NullPointerException(
       
   706                 MsgRepository.IMAGE_EXCEPTION_DATA_IS_NULL);
       
   707         }
       
   708         if(width <= 0 || height <= 0)
       
   709         {
       
   710             throw new IllegalArgumentException(
       
   711                 MsgRepository.IMAGE_EXCEPTION_INVALID_DIMENSIONS);
       
   712         }
       
   713         if(width * height > rgbData.length)
       
   714         {
       
   715             throw new ArrayIndexOutOfBoundsException(
       
   716                 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS);
       
   717         }
       
   718 
       
   719         final int[] rgb = rgbData;
       
   720         final int w = width;
       
   721         final int h = height;
       
   722         final boolean alpha = processAlpha;
       
   723         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   724         {
       
   725             public void run()
       
   726             {
       
   727                 org.eclipse.swt.internal.qt.graphics.Image cgImage =
       
   728                     new org.eclipse.swt.internal.qt.graphics.Image(rgb, w, h, alpha);
       
   729 
       
   730                 org.eclipse.swt.graphics.Image eswtImg =
       
   731                     Internal_GfxPackageSupport.new_Image(
       
   732                         ESWTUIThreadRunner.getInstance().getDisplay(), cgImage);
       
   733 
       
   734                 if(eswtImg != null)
       
   735                 {
       
   736                     createImageReturnValue = new Image(eswtImg, false);
       
   737                 }
       
   738                 else
       
   739                 {
       
   740                     createImageReturnValue = null;
       
   741                     throw new OutOfMemoryError();
       
   742                 }
       
   743             }
       
   744         });
       
   745         return createImageReturnValue;
       
   746     }
       
   747 
       
   748     /**
       
   749      * Returns ARGB data of image region to an int[] array.
       
   750      *
       
   751      * @param rgbData - array to be filled with ARGB data.
       
   752      * @param offset - first index in the array to store the data.
       
   753      * @param length - relative distance in the array between corresponding
       
   754      *            pixels of consecutive rows.
       
   755      * @param xPos - x-coordinate of the top-left corner of the region.
       
   756      * @param yPos - y-coordinate of the top-left corner of the region.
       
   757      * @param width - width of the region.
       
   758      * @param height - height of the region.
       
   759      */
       
   760     public void getRGB(int[] rgbData,
       
   761                        int offset,
       
   762                        int length,
       
   763                        int xPos,
       
   764                        int yPos,
       
   765                        int width,
       
   766                        int height)
       
   767     {
       
   768 
       
   769         if(rgbData == null)
       
   770         {
       
   771             throw new NullPointerException(
       
   772                 MsgRepository.IMAGE_EXCEPTION_DATA_IS_NULL);
       
   773         }
       
   774         if(!validateRegion(this.getWidth(), this.getHeight(),
       
   775                            xPos, yPos, width, height))
       
   776         {
       
   777             throw new IllegalArgumentException(
       
   778                 MsgRepository.IMAGE_EXCEPTION_INVALID_BOUNDS);
       
   779         }
       
   780         if(Math.abs(length) < width)
       
   781         {
       
   782             throw new IllegalArgumentException(
       
   783                 MsgRepository.IMAGE_EXCEPTION_INVALID_SCANLENGTH);
       
   784         }
       
   785 
       
   786         synchronized(graphicsBuffer)
       
   787         {
       
   788             final int[] localRgbData = rgbData;
       
   789             final int localOffset = offset;
       
   790             final int localLength = length;
       
   791             final int localX = xPos;
       
   792             final int localY = yPos;
       
   793             final int localW = width;
       
   794             final int localH = height;
       
   795             ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   796             {
       
   797                 public void run()
       
   798                 {
       
   799                 	graphicsBuffer.sync();
       
   800                     org.eclipse.swt.internal.qt.graphics.Image cgImage = Internal_GfxPackageSupport.getImage(eswtImage);
       
   801                     cgImage.getRGB(localRgbData, localOffset, localLength,
       
   802                                    localX, localY, localW, localH);
       
   803                 }
       
   804             });
       
   805         }
       
   806     }
       
   807 
       
   808     /**
       
   809      * Creates a new Graphics-objects that is able to draw to this image.
       
   810      *
       
   811      * @return New Graphics-object.
       
   812      * @throws IllegalStateException if image is immutable.
       
   813      */
       
   814     public Graphics getGraphics()
       
   815     {
       
   816         if(mutable)
       
   817         {	
       
   818         	tempGraphics = null;
       
   819         	ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   820             {
       
   821                 public void run()
       
   822                 {
       
   823         	        tempGraphics =  graphicsBuffer.getGraphics();
       
   824                 }
       
   825             });
       
   826             return tempGraphics;
       
   827         }
       
   828         throw new IllegalStateException(MsgRepository.IMAGE_EXCEPTION_IMMUTABLE);
       
   829     }
       
   830 
       
   831     /**
       
   832      * Gets width of the image.
       
   833      *
       
   834      * @return Image width.
       
   835      */
       
   836     public int getWidth()
       
   837     {
       
   838         return eswtImageWidth;
       
   839     }
       
   840 
       
   841     /**
       
   842      * Gets height of the image.
       
   843      *
       
   844      * @return Image height.
       
   845      */
       
   846     public int getHeight()
       
   847     {
       
   848         return eswtImageHeight;
       
   849     }
       
   850 
       
   851     /**
       
   852      * Check is it possible to modify this image.
       
   853      *
       
   854      * @return true, if image is mutable.
       
   855      */
       
   856     public boolean isMutable()
       
   857     {
       
   858         return mutable;
       
   859     }
       
   860 
       
   861 }