javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/org/eclipse/swt/internal/qt/graphics/ImageLoader.java
changeset 21 2a9601315dfc
child 61 bf7ee68962da
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 import java.io.*;
       
    14 
       
    15 import org.eclipse.swt.graphics.Point;
       
    16 
       
    17 /**
       
    18  * ImageLoader is class for image loading from various data formats.
       
    19  *
       
    20  *
       
    21  */
       
    22 
       
    23 final public class ImageLoader {
       
    24 
       
    25     /**
       
    26      * Size of block, in bytes, used for transferring read data to native side in iterative way.
       
    27      * Value given for this field affects on the memory consumption peak when loading
       
    28      * data trough java to native buffer. If value is very small, i.e. 100 the transfer
       
    29      * takes place many times and may result in performance loss, however memory usage will
       
    30      * be steadier. With bigger value transfer is faster but, it creates steeper peak in
       
    31      * memory consumption.
       
    32      *
       
    33      * If value is negative or zero, then block size is set based on InputStream.available(), otherwise
       
    34      * given positive integer value is used as block size (e.g. 4096).
       
    35      * Negative values are not allowed.
       
    36      */
       
    37     private static final int BLOCKSIZE = 0;
       
    38 
       
    39     /**
       
    40      * Native imageloader handle
       
    41      */
       
    42     private int handle = 0;
       
    43 
       
    44     /**
       
    45      * Status of native peer
       
    46      */
       
    47     private boolean disposed;
       
    48 
       
    49     /**
       
    50      * Creates an instance of this class and initializes native
       
    51      * image loader.
       
    52      */
       
    53     public ImageLoader() {
       
    54     	Utils.validateUiThread();
       
    55         handle = OS.imageLoader_init();
       
    56         if (handle == 0) {
       
    57             throw new OutOfMemoryError();
       
    58         }
       
    59         disposed = false;
       
    60     }
       
    61 
       
    62     /**
       
    63      * Disposes native image, i.e. frees resources.
       
    64      */
       
    65     public void dispose() {
       
    66     	Utils.validateUiThread();
       
    67         if (disposed) {
       
    68             return;
       
    69         } else {
       
    70             OS.imageLoader_dispose(handle);
       
    71             handle = 0;
       
    72             disposed = true;
       
    73         }
       
    74     }
       
    75 
       
    76     /**
       
    77      * Gets the status of this image loader.
       
    78      *
       
    79      * @return True if this instance has been already disposed otherwise false
       
    80      */
       
    81     public boolean isDisposed() {
       
    82         return disposed;
       
    83     }
       
    84 
       
    85     /**
       
    86      * Loads image from path specified.
       
    87      * Throws an error of image loading fails or it is unsupported format.
       
    88      *
       
    89      * @param path The path for image to be loaded
       
    90      * @return Instance of loaded image
       
    91      * @throws NullPointerException if path is null
       
    92      * @throws OutOfMemoryError if memory allocation for new image fails
       
    93      * @throws IOException if image cannot be loaded
       
    94      * @throws IllegalStateException if image data is invalid
       
    95      * @throws IllegalArgumentException if image format is not supported
       
    96      */
       
    97     public Image loadImage(String path) throws IOException {
       
    98         checkState();
       
    99 
       
   100         if (path == null) {
       
   101             throw new NullPointerException("path is null");
       
   102         }
       
   103 
       
   104         InputStream is = getClass().getResourceAsStream(path);
       
   105 
       
   106         if (is == null) {
       
   107             throw new IOException("Cannot obtain inputstream for given path: " +path);
       
   108         }
       
   109         return loadImage(is);
       
   110     }
       
   111 
       
   112     /**
       
   113      * Loads image from given byte array.
       
   114      *
       
   115      * @param data The array containing image data
       
   116      * @param offset The offset from beginnig of data where image data starts
       
   117      * @param length The length of data beginning form offset
       
   118      * @return Instance of loaded image
       
   119      * @throws NullPointerException if data is null
       
   120      * @throws IllegalArgumentException if offset is less than 0
       
   121      * @throws IllegalArgumentException if length is equal or less than 0
       
   122      * @throws ArrayIndexOutOfBoundsException if offset and length define an invalid range
       
   123      * @throws IOException if image cannot be loaded or it is unsupported format
       
   124      * @throws OutOfMemoryError if native buffer allocation fails
       
   125      */
       
   126     public Image loadImage(byte[] data, int offset, int length) throws IOException {
       
   127         checkState();
       
   128 
       
   129         if (data == null) {
       
   130             throw new NullPointerException("data is null");
       
   131         }
       
   132         if (offset < 0) {
       
   133             throw new IllegalArgumentException("offset is negative");
       
   134         }
       
   135         if (length <= 0) {
       
   136             throw new IllegalArgumentException("length is negative or zero");
       
   137         }
       
   138         if ((offset + length) > data.length) {
       
   139             throw new ArrayIndexOutOfBoundsException("offset and lenght define invalid range");
       
   140         }
       
   141 
       
   142         // All checks ok, so upload data to loader, with one go
       
   143         OS.imageLoader_beginStream(handle, length + 1);
       
   144         OS.imageLoader_append(handle, length, offset, data);
       
   145 
       
   146         return new Image(OS.imageLoader_endStream(handle));
       
   147     }
       
   148 
       
   149 	/**
       
   150 	 * Loads image from file directly using the native APIs. Note that Java
       
   151 	 * security checks are not done.
       
   152 	 *
       
   153 	 * @param filename The filename to pass to the native APIs.
       
   154 	 * @return Image The loaded image.
       
   155 	 * @throws IOException
       
   156 	 */
       
   157     public Image nativelyLoadImageFromFileNoSecurity(String filename) throws IOException {
       
   158         checkState();
       
   159         if (filename == null) {
       
   160             throw new NullPointerException("data is null");
       
   161         }
       
   162         return new Image(OS.imageLoader_load(handle, filename));
       
   163     }
       
   164 
       
   165     /**
       
   166      * Contructs an instance of Image by reading image data from given InputStream.
       
   167      *
       
   168      * @param is The InputStream from where to read the image data from
       
   169      * @return Instance of loaded image
       
   170      * @throws NullPointerException if InputStream is is null
       
   171      * @throws IOException if image cannot be loaded
       
   172      * @throws OutOfMemoryError if allocation of native buffer of image creation fails
       
   173      * @throws IllegalStateException if image data is invalid
       
   174      * @throws IllegalArgumentException if image format is not supported
       
   175      */
       
   176     public Image loadImage(InputStream is) throws IOException {
       
   177         checkState();
       
   178 
       
   179         if (is == null) {
       
   180             throw new NullPointerException("InputStream is null");
       
   181         }
       
   182 
       
   183         int bytesRead = 0;
       
   184         int bytesAvailable = 0;
       
   185         byte[] data;
       
   186 
       
   187         // Determine transfer buffer size
       
   188         if (BLOCKSIZE <= 0) {
       
   189             bytesAvailable = is.available(); // may throw IOException
       
   190 
       
   191             if (bytesAvailable == 0) {
       
   192                 throw new IllegalArgumentException("Empty file");
       
   193             }
       
   194 
       
   195             data = new byte[bytesAvailable];
       
   196         } else {
       
   197             data = new byte[BLOCKSIZE];
       
   198         }
       
   199 
       
   200         // Start streaming to native buffer, with initial buffer size
       
   201         OS.imageLoader_beginStream(handle, bytesAvailable);
       
   202 
       
   203         // Read input stream and pass blocks to native buffer
       
   204         try {
       
   205             while ((bytesRead = is.read(data, 0, data.length)) != -1) {
       
   206                 OS.imageLoader_append(handle, bytesRead, 0, data);
       
   207             }
       
   208         } catch (IOException e) {
       
   209             // Throw exception forward, native loader automatically resets state
       
   210             // when problems occur so there's no need to do any extra native calls here
       
   211             throw e;
       
   212         }
       
   213         catch (IllegalStateException e) {
       
   214             throw e;
       
   215         }
       
   216         catch (IllegalArgumentException e) {
       
   217             throw e;
       
   218         }
       
   219         return new Image(OS.imageLoader_endStream(handle));
       
   220     }
       
   221 
       
   222     /**
       
   223      * Sets the size that the Image will be scaled to when loaded. Useful for
       
   224      * SVG images.
       
   225      * @param width The width to scale to
       
   226      * @param height The height to scale to
       
   227      */
       
   228     public void setLoadSize(int width, int height) {
       
   229     	OS.imageLoader_setLoadSize(handle, width, height);
       
   230     }
       
   231 
       
   232     /**
       
   233      * Private helper to check the state of the current instance.
       
   234      */
       
   235     private void checkState() {
       
   236     	Utils.validateUiThread();
       
   237         if (disposed) {
       
   238             throw new IllegalStateException("Image loader already disposed");
       
   239         }
       
   240     }
       
   241 }