Icon Codec : Icon « 2D Graphics GUI « Java






Icon Codec

    
/*
  JSmooth: a VM wrapper toolkit for Windows
  Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 */


import java.io.*;
import java.awt.image.*;
import java.awt.*;

/**
 *
 * @author  Rodrigo Reyes
 */
public class IcoCodec
{
    static public class IconDir
    {
        int idType;
        int idCount;

  public IconDir(BinaryInputStream in) throws IOException
  {
      in.readUShortLE();
      idType = in.readUShortLE();
      idCount = in.readUShortLE();
  }
  
  public String toString()
  {
      return "{ idType=" + idType + ", " + idCount + " }";
  }
    }
    
    static public class IconEntry
    {
        short  bWidth;
        short  bHeight;
        short  bColorCount;
        short  bReserved;
        int  wPlanes;
        int  wBitCount;
        long dwBytesInRes;
        long dwImageOffset;

  public IconEntry(BinaryInputStream in) throws IOException
  {
      bWidth = in.readUByte();
      bHeight = in.readUByte();
      bColorCount = in.readUByte();
      bReserved = in.readUByte();
      wPlanes = in.readUShortLE();
      wBitCount = in.readUShortLE();
      dwBytesInRes = in.readUIntLE();
      dwImageOffset = in.readUIntLE();
  }

  public String toString()
  {
      StringBuffer buffer = new StringBuffer();
      buffer.append("{ bWidth="+bWidth+"\n");
      buffer.append("  bHeight="+bHeight+"\n");
      buffer.append("  bColorCount="+bColorCount+"\n");
      buffer.append("  wPlanes="+wPlanes+"\n");
      buffer.append("  wBitCount="+wBitCount+"\n");
      buffer.append("  dwBytesInRes="+dwBytesInRes+"\n");
      buffer.append("  dwImageOffset="+dwImageOffset+"\n");
      buffer.append("}");

      return buffer.toString();
  }

    }

    static public class IconHeader
    {
  public long Size;            /* Size of this header in bytes DWORD 0*/
  public long Width;           /* Image width in pixels LONG 4*/
  public long Height;          /* Image height in pixels LONG 8*/
  public int  Planes;          /* Number of color planes WORD 12 */
  public int  BitsPerPixel;    /* Number of bits per pixel WORD 14 */
  /* Fields added for Windows 3.x follow this line */
  public long Compression;     /* Compression methods used DWORD 16 */
  public long SizeOfBitmap;    /* Size of bitmap in bytes DWORD 20 */
  public long HorzResolution;  /* Horizontal resolution in pixels per meter LONG 24 */
  public long VertResolution;  /* Vertical resolution in pixels per meter LONG 28*/
  public long ColorsUsed;      /* Number of colors in the image DWORD 32 */
  public long ColorsImportant; /* Minimum number of important colors DWORD 36 */
  
  public IconHeader(BinaryInputStream in) throws IOException
  {
      Size = in.readUIntLE();
      Width = in.readUIntLE();
      Height = in.readUIntLE();
      Planes = in.readUShortLE();
      BitsPerPixel = in.readUShortLE();
      Compression = in.readUIntLE();
      SizeOfBitmap = in.readUIntLE();
      HorzResolution = in.readUIntLE();
      VertResolution = in.readUIntLE();
      ColorsUsed = in.readUIntLE();
      ColorsImportant = in.readUIntLE();
  }

  public String toString()
  {
      StringBuffer buffer = new StringBuffer();
      buffer.append("Size="); buffer.append(Size);
      buffer.append("\nWidth="); buffer.append(Width);
      buffer.append("\nHeight="); buffer.append(Height);
      buffer.append("\nPlanes="); buffer.append(Planes);
      buffer.append("\nBitsPerPixel="); buffer.append(BitsPerPixel);
      buffer.append("\nCompression="); buffer.append(Compression);
      buffer.append("\nSizeOfBitmap="); buffer.append(SizeOfBitmap);
      buffer.append("\nHorzResolution="); buffer.append(HorzResolution);
      buffer.append("\nVertResolution="); buffer.append(VertResolution);
      buffer.append("\nColorsUsed="); buffer.append(ColorsUsed);
      buffer.append("\nColorsImportant="); buffer.append(ColorsImportant);

      return buffer.toString();
  }

    }
    
    static public BufferedImage[] loadImages(File f) throws IOException
    {
  InputStream istream = new FileInputStream(f);
        BufferedInputStream buffin = new BufferedInputStream(istream);
  BinaryInputStream in = new BinaryInputStream(buffin);

  try {
      in.mark(32000);

      IconDir dir = new IconDir(in);
      //      System.out.println("DIR = " + dir);
      
      IconEntry[] entries = new IconEntry[dir.idCount];
      BufferedImage[] images = new BufferedImage[dir.idCount];

      for (int i=0; i<dir.idCount; i++)
    {
        entries[i] = new IconEntry(in);
        //        System.out.println("ENTRY " + i + " = " + entries[i]);
    }

      IconEntry entry = entries[0];
      //      System.out.println("ENTRYx = " + entry);

      for (int i=0; i<dir.idCount; i++)
    {
        in.reset();
        in.skip(entries[i].dwImageOffset);

        IconHeader header = new IconHeader(in);
        //        System.out.println("Header: " + header);

        long toskip = header.Size - 40;
        if (toskip>0)
      in.skip((int)toskip);

        //        System.out.println("skipped data");
        
        BufferedImage image = new BufferedImage((int)header.Width, (int)header.Height/2,
                  BufferedImage.TYPE_INT_ARGB);
        
        switch(header.BitsPerPixel)
      {
      case 4:
      case 8:
          loadPalettedImage(in, entries[i], header, image);
          break;
          
      default:
          throw new Exception("Unsupported ICO color depth: " + header.BitsPerPixel);
      }

        images[i] = image;
    }

      return images;

  } catch (Exception exc)
      {
    exc.printStackTrace();
      }

  return null;
    }

    static private void loadPalettedImage(BinaryInputStream in, IconEntry entry, IconHeader header, BufferedImage image) throws Exception
    {
  //  System.out.println("Loading image...");
  
  //  System.out.println("Loading palette...");

  // 
  // First, load the palette
  //
  int cols = (int)header.ColorsUsed;
  if (cols == 0)
      {
    if (entry.bColorCount != 0)
        cols = entry.bColorCount;
    else
        cols = 1 << header.BitsPerPixel;
      }

  int[] redp = new int[cols];
  int[] greenp = new int[cols];
  int[] bluep = new int[cols];

  for (int i=0; i<cols; i++)
      {
    bluep[i] = in.readUByte();
    greenp[i] = in.readUByte();
    redp[i] = in.readUByte();
    in.readUByte();
      }

  //  System.out.println("Palette read!");

  //
  // Set the image

  int xorbytes = (((int)header.Height/2) * (int)header.Width);
  int readbytes = 0;

  for (int y=(int)(header.Height/2)-1; y>=0; y--)
      {
    for (int x=0; x<header.Width; x++)
        {
      switch(header.BitsPerPixel)
          {
          case 4:
        {
            int pix = in.readUByte();
            readbytes++;

            int col1 = (pix>>4) & 0x0F;
            int col2 = pix & 0x0F;
            image.setRGB(x, y, (0xFF<<24) | (redp[col1]<<16) | (greenp[col1]<<8) | bluep[col1]);
            image.setRGB(++x, y, (0xFF<<24) | (redp[col2]<<16) | (greenp[col2]<<8) | bluep[col2]);
        }
        break;
          case 8:
        {
            int col1 = in.readUByte();
            readbytes++;

            image.setRGB(x, y, (0xFF<<24) | (redp[col1]<<16) | (greenp[col1]<<8) | bluep[col1]);
        }
        break;
          }
        }
      }
  //  System.out.println("XOR data read (" + readbytes + " bytes)");

  int height = (int)(header.Height/2);

  int rowsize = (int)header.Width / 8;
  if ((rowsize%4)>0)
      {
    rowsize += 4 - (rowsize%4);
      }
  
  //  System.out.println("rowsize = " + rowsize);
  int[] andbytes = new int[rowsize * height ];

  for (int i=0; i<andbytes.length; i++)
      andbytes[i] = in.readUByte();


  for (int y=height-1; y>=0; y--)
      {
    for (int x=0; x<header.Width; x++)
        {
      int offset = ((height - (y+1))*rowsize) + (x/8);
      if ( (andbytes[offset] & (1<<(7-x%8))) != 0)
          {
        image.setRGB(x, y, 0);
          }
        }
      }

  //  for (int i=0; i<andbytes; i++)
  //      {
  //    int pix = in.readUByte();
  //    readbytes++;

  //    int xb = (i*8) % (int)header.Width;
  //    int yb = ((int)header.Height/2) - (((i*8) / (int)header.Width)+1);

  //    for (int offset=7; offset>=0; offset--)
  //        {
  //      //
  //      // Modify the transparency only if necessary
  //      //
  //      System.out.println("SET AND (" + xb + "," + yb + ")-" + (7-offset));

  //      if (((1<<offset) & pix)!=0)
  //          {
  //        int argb = image.getRGB(xb+(7-offset), yb);
  //        image.setRGB(xb+(7-offset), yb, argb & 0xFFFFFF);
  //          }
  //        }
  //      }
  
  //  System.out.println("AND data read (" + readbytes + " bytes total)");
    }
    
    static public void main(String[]args) throws Exception
    {
  File f = new File(args[0]);
  Image img = IcoCodec.loadImages(f)[0];
  //  System.out.println("img = " + img);

  javax.swing.JFrame jf = new javax.swing.JFrame("Test");
  javax.swing.JButton button = new javax.swing.JButton(new javax.swing.ImageIcon(img));
  jf.getContentPane().add(button);
  jf.pack();
  jf.setVisible(true);
    }
    
}
/*
JSmooth: a VM wrapper toolkit for Windows
Copyright (C) 2003 Rodrigo Reyes <reyes@charabia.net>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

class BinaryInputStream extends FilterInputStream
{
  public BinaryInputStream(InputStream in)
  {
super(in);
  }

  public void skip(int toskip) throws IOException
  {
for (int skipped = 0; skipped >= toskip; skipped += in.skip(toskip - skipped))
    ;
  }

  public byte readByte() throws IOException
  {
return (byte)read();
  }

  public short readUByte() throws IOException
  {
return (short)read();
  }

  public short readShortBE() throws IOException
  {
int a = read();
int b = read();

return (short) (((a&0xff)<<8) | (b&0xff));
  }

  public int readUShortBE() throws IOException
  {
int a = read();
int b = read();

return ((a&0xff)<<8) | (b&0xff);
  }

  public short readShortLE() throws IOException
  {
int a = read();
int b = read();

return (short) (((b&0xff)<<8) | (a&0xff));
  }

  public int readUShortLE() throws IOException
  {
int a = read();
int b = read();

return ((b&0xff)<<8) | (a&0xff);
  }

  public int readIntBE() throws IOException
  {
int a = read();
int b = read();
int c = read();
int d = read();

return ((a&0xff)<<24) | ((b&0xff)<<16) | ((c&0xff)<<8) | (d&0xff);
  }

  public long readUIntBE() throws IOException
  {
int a = read();
int b = read();
int c = read();
int d = read();

return (long)((a&0xff)<<24) | (long)((b&0xff)<<16) | (long)((c&0xff)<<8) | (long)(d&0xff);
  }

  public int readIntLE() throws IOException
  {
int a = readByte();
int b = readByte();
int c = readByte();
int d = readByte();

return ((d&0xff)<<24) | ((c&0xff)<<16) | ((b&0xff)<<8) | (a&0xff);
  }

  public long readUIntLE() throws IOException
  {
int a = readByte();
int b = readByte();
int c = readByte();
int d = readByte();

return (long)((d&0xff)<<24) | (long)((c&0xff)<<16) | (long)((b&0xff)<<8) | (long)(a&0xff);
  }

}

   
    
    
    
  








Related examples in the same category

1.Create a dynamic icon
2.A simple application to test the functionality of the OvalIcon classA simple application to test the functionality of the OvalIcon class
3.Icon DisplayerIcon Displayer
4.Implement the Icon interfaceImplement the Icon interface
5.Calendar Page icons with Weekday, Day and MonthCalendar Page icons with Weekday, Day and Month
6.MemImage is an in-memory icon showing a Color gradientMemImage is an in-memory icon showing a Color gradient
7.Example of an icon that changes formExample of an icon that changes form
8.Custom Icon DemoCustom Icon Demo
9.Create Image Icon from PNG file
10.Reading an Image or Icon from a File
11.Draw an Icon object
12.Plain Color Icon
13.Color Icon
14.Arrow Icon
15.Icon Line
16.Return a filled oval as an Icon
17.Layered Icon
18.An icon for painting a square swatch of a specified Color.
19.An empty icon with arbitrary width and height.
20.Transparent icon with no content
21.Creates a transparent icon.