diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/editors/ExecutableIcon.java b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/editors/ExecutableIcon.java index 05d5e9a8..e7940dd3 100644 --- a/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/editors/ExecutableIcon.java +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/application/gui/editors/ExecutableIcon.java @@ -108,11 +108,10 @@ public class ExecutableIcon extends Editor // Try to load with our ico codec... // try { - java.awt.image.BufferedImage[] images = net.charabia.util.codec.IcoCodec.loadImages(iconfile); - if ((images != null) && (images.length>0)) + java.awt.image.BufferedImage image = net.charabia.util.codec.IcoCodec.getPreferredImage(iconfile); + if (image != null) { - java.awt.Image img = images[0]; - icon = new ImageIcon(img); + icon = new ImageIcon(image); } } catch (java.io.IOException exc) { diff --git a/jsmooth-0.9.9-7-patch/src/net/charabia/util/codec/IcoCodec.java b/jsmooth-0.9.9-7-patch/src/net/charabia/util/codec/IcoCodec.java index 9ac83289..7e88b27c 100644 --- a/jsmooth-0.9.9-7-patch/src/net/charabia/util/codec/IcoCodec.java +++ b/jsmooth-0.9.9-7-patch/src/net/charabia/util/codec/IcoCodec.java @@ -20,17 +20,30 @@ package net.charabia.util.codec; -import java.io.*; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +import javax.imageio.ImageIO; + import net.charabia.util.io.BinaryInputStream; -import java.awt.image.*; -import java.awt.*; /** * * @author Rodrigo Reyes + * @author Riccardo Gerosa */ public class IcoCodec { + + static private byte[] PNG_SIGNATURE = new byte[] { -119, 80, 78, 71, 13, 10, 26, 10 }; + static public class IconDir { int idType; @@ -63,7 +76,9 @@ public class IcoCodec public IconEntry(BinaryInputStream in) throws IOException { bWidth = in.readUByte(); + if (bWidth == 0) { bWidth = 256; } bHeight = in.readUByte(); + if (bHeight == 0) { bHeight = 256; } bColorCount = in.readUByte(); bReserved = in.readUByte(); wPlanes = in.readUShortLE(); @@ -77,7 +92,7 @@ public class IcoCodec StringBuffer buffer = new StringBuffer(); buffer.append("{ bWidth="+bWidth+"\n"); buffer.append(" bHeight="+bHeight+"\n"); - buffer.append(" bColorCount="+bColorCount+"\n"); + buffer.append(" bColorCount="+bColorCount+(bColorCount == 0 ? "(not paletted)":"")+"\n"); buffer.append(" wPlanes="+wPlanes+"\n"); buffer.append(" wBitCount="+wBitCount+"\n"); buffer.append(" dwBytesInRes="+dwBytesInRes+"\n"); @@ -139,6 +154,68 @@ public class IcoCodec } + public static BufferedImage checkImageSize(BufferedImage img, int width, int height) { + int w = img.getWidth(null); + int h = img.getHeight(null); + if ((w == width) && (h == height)) + return img; + return null; + } + + static boolean isSquareSize(BufferedImage bufferedImage, int size) { + return bufferedImage.getWidth() == bufferedImage.getHeight() && bufferedImage.getWidth() == size; + } + + static int getColorDepth(BufferedImage bufferedImage) { + return bufferedImage.getColorModel().getPixelSize(); + } + + static public BufferedImage getPreferredImage(File f) throws IOException { + BufferedImage selected = null; + BufferedImage[] orgimages = loadImages(f); + if (orgimages != null) { + // select first image + selected = orgimages[0]; + for (int i = 1; (i < orgimages.length); i++) { + // We prefer 32x32 pictures, then 64x64, then 16x16... + if (isSquareSize(orgimages[i], 32)) { + if (!isSquareSize(selected, 32) || getColorDepth(orgimages[i]) > getColorDepth(selected)) { + selected = orgimages[i]; + } + } else if (isSquareSize(orgimages[i], 64)) { + if (!isSquareSize(selected, 32) || + (isSquareSize(selected, 64) && getColorDepth(orgimages[i]) > getColorDepth(selected))) { + selected = orgimages[i]; + } + + } else if (isSquareSize(orgimages[i], 16)) { + if ((!isSquareSize(selected, 32) && !isSquareSize(selected, 64)) || + (isSquareSize(selected, 16) && getColorDepth(orgimages[i]) > getColorDepth(selected))) { + selected = orgimages[i]; + } + } + } + + if (selected == null) { + // + // If there is no 32x32, 64x64, nor 16x16, then we scale the + // biggest image to be 32x32... This should happen mainly when + // loading an image from a png of gif file, and in most case + // there is only one image on the array. + // + int maxsize = 0; + for (int i = 0; (i < orgimages.length) && (selected == null); i++) { + int size = orgimages[i].getWidth(null) * orgimages[i].getHeight(null); + if (size > maxsize) { + maxsize = size; + selected = orgimages[i]; + } + } + } + } + return selected; + } + static public BufferedImage[] loadImages(File f) throws IOException { InputStream istream = new FileInputStream(f); @@ -146,7 +223,7 @@ public class IcoCodec BinaryInputStream in = new BinaryInputStream(buffin); try { - in.mark(32000); + in.mark(1024 * 1024); IconDir dir = new IconDir(in); // System.out.println("DIR = " + dir); @@ -165,33 +242,61 @@ public class IcoCodec for (int i=0; i