1 /*
   2  * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package sun.awt;
  26 import java.awt.*;
  27 import java.awt.color.*;
  28 import java.awt.image.*;
  29 import sun.awt.image.ToolkitImage;
  30 import sun.awt.image.ImageRepresentation;
  31 import java.util.Arrays;
  32 
  33 public class IconInfo {
  34     /**
  35      * Representation of image as an int array.
  36      * It's used on platforms where icon data
  37      * is expected to be in 32-bit format.
  38      */
  39     private int[] intIconData;
  40     /**
  41      * Representation of image as an long array.
  42      * It's used on platforms where icon data
  43      * is expected to be in 64-bit format.
  44      */
  45     private long[] longIconData;
  46     /**
  47      * Icon image.
  48      */
  49     private Image image;
  50     /**
  51      * Width of icon image. Being set in constructor.
  52      */
  53     private final int width;
  54     /**
  55      * Height of icon image. Being set in constructor.
  56      */
  57     private final int height;
  58     /**
  59      * Width of scaled icon image. Can be set in setScaledDimension.
  60      */
  61     private int scaledWidth;
  62     /**
  63      * Height of scaled icon image. Can be set in setScaledDimension.
  64      */
  65     private int scaledHeight;
  66     /**
  67      * Length of raw data. Being set in constructor / setScaledDimension.
  68      */
  69     private int rawLength;
  70 
  71     public IconInfo(int[] intIconData) {
  72         this.intIconData =
  73             (null == intIconData) ? null : Arrays.copyOf(intIconData, intIconData.length);
  74         this.width = intIconData[0];
  75         this.height = intIconData[1];
  76         this.scaledWidth = width;
  77         this.scaledHeight = height;
  78         this.rawLength = width * height + 2;
  79     }
  80 
  81     public IconInfo(long[] longIconData) {
  82         this.longIconData =
  83         (null == longIconData) ? null : Arrays.copyOf(longIconData, longIconData.length);
  84         this.width = (int)longIconData[0];
  85         this.height = (int)longIconData[1];
  86         this.scaledWidth = width;
  87         this.scaledHeight = height;
  88         this.rawLength = width * height + 2;
  89     }
  90 
  91     public IconInfo(Image image) {
  92         this.image = image;
  93         if (image instanceof ToolkitImage) {
  94             ImageRepresentation ir = ((ToolkitImage)image).getImageRep();
  95             ir.reconstruct(ImageObserver.ALLBITS);
  96             this.width = ir.getWidth();
  97             this.height = ir.getHeight();
  98         } else {
  99             this.width = image.getWidth(null);
 100             this.height = image.getHeight(null);
 101         }
 102         this.scaledWidth = width;
 103         this.scaledHeight = height;
 104         this.rawLength = width * height + 2;
 105     }
 106 
 107     /*
 108      * It sets size of scaled icon.
 109      */
 110     public void setScaledSize(int width, int height) {
 111         this.scaledWidth = width;
 112         this.scaledHeight = height;
 113         this.rawLength = width * height + 2;
 114     }
 115 
 116     public boolean isValid() {
 117         return (width > 0 && height > 0);
 118     }
 119 
 120     public int getWidth() {
 121         return width;
 122     }
 123 
 124     public int getHeight() {
 125         return height;
 126     }
 127 
 128     public String toString() {
 129         return "IconInfo[w=" + width + ",h=" + height + ",sw=" + scaledWidth + ",sh=" + scaledHeight + "]";
 130     }
 131 
 132     public int getRawLength() {
 133         return rawLength;
 134     }
 135 
 136     public int[] getIntData() {
 137         if (this.intIconData == null) {
 138             if (this.longIconData != null) {
 139                 this.intIconData = longArrayToIntArray(longIconData);
 140             } else if (this.image != null) {
 141                 this.intIconData = imageToIntArray(this.image, scaledWidth, scaledHeight);
 142             }
 143         }
 144         return this.intIconData;
 145     }
 146 
 147     public long[] getLongData() {
 148         if (this.longIconData == null) {
 149             if (this.intIconData != null) {
 150                 this.longIconData = intArrayToLongArray(this.intIconData);
 151             } else if (this.image != null) {
 152                 int[] intIconData = imageToIntArray(this.image, scaledWidth, scaledHeight);
 153                 this.longIconData = intArrayToLongArray(intIconData);
 154             }
 155         }
 156         return this.longIconData;
 157     }
 158 
 159     public Image getImage() {
 160         if (this.image == null) {
 161             if (this.intIconData != null) {
 162                 this.image = intArrayToImage(this.intIconData);
 163             } else if (this.longIconData != null) {
 164                 int[] intIconData = longArrayToIntArray(this.longIconData);
 165                 this.image = intArrayToImage(intIconData);
 166             }
 167         }
 168         return this.image;
 169     }
 170 
 171     private static int[] longArrayToIntArray(long[] longData) {
 172         int[] intData = new int[longData.length];
 173         for (int i = 0; i < longData.length; i++) {
 174             // Such a conversion is valid since the
 175             // original data (see
 176             // make/sun/xawt/ToBin.java) were ints
 177             intData[i] = (int)longData[i];
 178         }
 179         return intData;
 180     }
 181 
 182     private static long[] intArrayToLongArray(int[] intData) {
 183         long[] longData = new long[intData.length];
 184         for (int i = 0; i < intData.length; i++) {
 185             longData[i] = intData[i];
 186         }
 187         return longData;
 188     }
 189 
 190     static Image intArrayToImage(int[] raw) {
 191         ColorModel cm =
 192             new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32,
 193                                  0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000,
 194                                  false, DataBuffer.TYPE_INT);
 195         DataBuffer buffer = new DataBufferInt(raw, raw.length-2, 2);
 196         WritableRaster raster =
 197             Raster.createPackedRaster(buffer, raw[0], raw[1],
 198                                       raw[0],
 199                                       new int[] {0x00ff0000, 0x0000ff00,
 200                                                  0x000000ff, 0xff000000},
 201                                       null);
 202         BufferedImage im = new BufferedImage(cm, raster, false, null);
 203         return im;
 204     }
 205 
 206     /*
 207      * Returns array of integers which holds data for the image.
 208      * It scales the image if necessary.
 209      */
 210     static int[] imageToIntArray(Image image, int width, int height) {
 211         if (width <= 0 || height <= 0) {
 212             return null;
 213         }
 214         ColorModel cm =
 215             new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32,
 216                                  0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000,
 217                                  false, DataBuffer.TYPE_INT);
 218         DataBufferInt buffer = new DataBufferInt(width * height);
 219         WritableRaster raster =
 220             Raster.createPackedRaster(buffer, width, height,
 221                                       width,
 222                                       new int[] {0x00ff0000, 0x0000ff00,
 223                                                  0x000000ff, 0xff000000},
 224                                       null);
 225         BufferedImage im = new BufferedImage(cm, raster, false, null);
 226         Graphics g = im.getGraphics();
 227         g.drawImage(image, 0, 0, width, height, null);
 228         g.dispose();
 229         int[] data = buffer.getData();
 230         int[] raw = new int[width * height + 2];
 231         raw[0] = width;
 232         raw[1] = height;
 233         System.arraycopy(data, 0, raw, 2, width * height);
 234         return raw;
 235     }
 236 
 237 }