I'm trying to load an ICO file but I seem to get weird values in the image data size and image data offset value causing an ArrayOutOfBoundsException. Any help is appreciated. I tried Little/Big endian but no success. I found the info for the ICO structure here.
Code:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
public class IcoFileReader {
public static void main(String[] args) {
URL url = null;
try {
url = new URL("https://www.google.be/favicon.ico");
} catch (MalformedURLException e) {
e.printStackTrace();
}
if(url == null) {
System.err.println("Url is null");
System.exit(-1);
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
final byte[] chunk = new byte[4096];
final InputStream stream = url.openStream();
int bytesRead;
while ((bytesRead = stream.read(chunk)) > 0) {
outputStream.write(chunk, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
final byte[] icoBytes = outputStream.toByteArray();
System.out.println("Ico bytes: " + Arrays.toString(icoBytes));
System.out.println("-- HEADER --");
System.out.println("Reserved: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 0, 2)));
System.out.println("Image type: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 2, 4)));
System.out.println("Num images: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 4, 6)));
System.out.println("");
System.out.println("-- BODY --");
System.out.println("Width: " + icoBytes[6]);
System.out.println("Height: " + icoBytes[7]);
System.out.println("Color Palette: " + icoBytes[8]);
System.out.println("Reserved: " + icoBytes[9]);
System.out.println("Color planes: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 10, 11)));
System.out.println("Bits per pixel: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 12, 13)));
System.out.println("Img data size: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 13, 17)) + " - " + ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 13, 17)).order(ByteOrder.LITTLE_ENDIAN).getInt());
System.out.println("Offset beginning data: " + Arrays.toString(Arrays.copyOfRange(icoBytes, 17, 21)) + " - " + ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 17, 21)).order(ByteOrder.LITTLE_ENDIAN).getInt());
final int imgSize = ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 13, 17)).order(ByteOrder.LITTLE_ENDIAN).getInt();
final int offset = ByteBuffer.wrap(Arrays.copyOfRange(icoBytes, 17, 21)).order(ByteOrder.LITTLE_ENDIAN).getInt();
System.out.println("Bytes length: " + icoBytes.length);
System.out.println("Image data: " + Arrays.toString(Arrays.copyOfRange(icoBytes, offset, offset + imgSize)));
/* for(int i = 0; i < icoBytes[4]; i ++) {
final int start = (i * offset);
System.out.println("Image data: " + Arrays.toString(Arrays.copyOfRange(icoBytes, start, start + imgSize)));
}*/
}
}
And the output:
-- HEADER --
Reserved: [0, 0]
Image type: [1, 0]
Num images: [2, 0]
-- BODY --
Width: 16
Height: 16
Color Palette: 0
Reserved: 0
Color planes: 1
Bits per pixel: [32]
Img data size: [0, 104, 4, 0] - 288768
Offset beginning data: [0, 38, 0, 0] - 9728
Bytes length: 5430
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException