davmail/archive/jsmooth-0.9.9-7-patch/src/net/charabia/jsmoothgen/pe/res/ResIcon32.java

127 lines
4.1 KiB
Java
Raw Normal View History

package net.charabia.jsmoothgen.pe.res;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* 32 bits res icon with alpha channel
*/
public class ResIcon32 extends ResIcon {
BufferedImage image;
/**
* Creates a new instance based on the data of the Image argument.
*
* @param img image
* @throws Exception on error
*/
public ResIcon32(Image img) throws Exception {
int width = img.getWidth(null);
int height = img.getHeight(null);
image = (BufferedImage) img;
this.BitsPerPixel = 32;
// header size
this.Size = 40;
this.Width = width;
this.Height = height * 2;
this.Planes = 1;
this.Compression = 0;
this.SizeOfBitmap = 0;
this.HorzResolution = 0;
this.VertResolution = 0;
this.ColorsUsed = 0;
this.ColorsImportant = 0;
}
/**
* Creates and returns a ByteBuffer containing an image under
* the .ico format expected by Windows.
*
* @return a ByteBuffer with the .ico data
*/
public ByteBuffer getData() {
// transparency mask rows must be double bytes aligned
int rowsize = (int) Width / 8;
int padding = 0;
if ((rowsize % 4) > 0) {
padding = (int) ((4 - Width / 8 % 4) * 8);
rowsize += 4 - (rowsize % 4);
}
// transparency line padding size
// create transparency mask buffer
int transparencyBytesSize = (int) (rowsize * (Height / 2));
int[] transparencyMask = new int[transparencyBytesSize];
// allocate header + pixel count * bytes / pixel + transparency mask size
ByteBuffer buf = ByteBuffer.allocate((int) (40 + (Width * ((Height) / 2) * BitsPerPixel/8) + transparencyBytesSize));
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.position(0);
// write header
buf.putInt((int) Size);
buf.putInt((int) Width);
buf.putInt((int) Height);
buf.putShort((short) Planes);
buf.putShort((short) BitsPerPixel);
buf.putInt((int) Compression);
buf.putInt((int) SizeOfBitmap);
buf.putInt((int) HorzResolution);
buf.putInt((int) VertResolution);
buf.putInt((int) ColorsUsed);
buf.putInt((int) ColorsImportant);
int pixelCount = 0;
for (int y = (int) ((Height / 2) - 1); y >= 0; y--) {
for (int x = 0; x < Width; x++) {
int pix = image.getRGB(x, y);
//System.out.println(x+" "+y+":"+Integer.toHexString((pix >> 24) & 0xff));
boolean isTransparent = ((pix >> 24) & 0xff) == 0;
if (isTransparent) {
int index = pixelCount / 8;
byte bitindex = (byte) (pixelCount % 8);
transparencyMask[index] |= 0x80 >> bitindex;
}
buf.putInt(pix);
pixelCount++;
}
// skip to next transparency line
pixelCount += padding;
}
// transparency mask
for (int x = 0; x < transparencyBytesSize; x++) {
buf.put((byte) (transparencyMask[x] & 0xff));
}
buf.position(0);
return buf;
}
public String toString() {
StringBuffer out = new StringBuffer();
out.append("Size: ").append(Size);
out.append("\nWidth: ").append(Width);
out.append("\nHeight: ").append(Height);
out.append("\nPlanes: ").append(Planes);
out.append("\nBitsPerPixel: ").append(BitsPerPixel);
out.append("\nCompression: ").append(Compression);
out.append("\nSizeOfBitmap: ").append(SizeOfBitmap);
out.append("\nHorzResolution: ").append(HorzResolution);
out.append("\nVertResolution: ").append(VertResolution);
out.append("\nColorsUsed: ").append(ColorsUsed);
out.append("\nColorsImportant: ").append(ColorsImportant);
return out.toString();
}
}