/*********************************************************************
*
* Copyright (C) 2006 Andrew Khan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/
package jxl.biff.drawing;
import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;
public class PNGReader
{
private byte[] pngData;
private Chunk ihdr;
private Chunk phys;
private int pixelWidth;
private int pixelHeight;
private int verticalResolution;
private int horizontalResolution;
private int resolutionUnit;
private static byte[] PNG_MAGIC_NUMBER = new byte[]
{(byte) 0x89, (byte) 0x50, (byte) 0x4e, (byte) 0x47,
(byte) 0x0d, (byte) 0x0a, (byte) 0x1a, (byte) 0x0a};
public PNGReader(byte[] data)
{
pngData = data;
}
void read()
{
// Verify the magic data
byte[] header = new byte[PNG_MAGIC_NUMBER.length];
System.arraycopy(pngData, 0, header, 0, header.length);
boolean pngFile = Arrays.equals(PNG_MAGIC_NUMBER, header);
if (!pngFile)
{
return;
}
int pos = 8;
while (pos < pngData.length)
{
int length = getInt(pngData[pos],
pngData[pos+1],
pngData[pos+2],
pngData[pos+3]);
ChunkType chunkType = ChunkType.getChunkType(pngData[pos+4],
pngData[pos+5],
pngData[pos+6],
pngData[pos+7]);
if (chunkType == ChunkType.IHDR)
{
ihdr = new Chunk(pos + 8, length, chunkType, pngData);
}
else if (chunkType == ChunkType.PHYS)
{
phys = new Chunk(pos + 8, length, chunkType, pngData);
}
pos += length + 12;
}
// Get the width and height from the ihdr
byte[] ihdrData = ihdr.getData();
pixelWidth = getInt(ihdrData[0], ihdrData[1], ihdrData[2], ihdrData[3]);
pixelHeight = getInt(ihdrData[4], ihdrData[5], ihdrData[6], ihdrData[7]);
if (phys != null)
{
byte[] physData = phys.getData();
resolutionUnit = physData[8];
horizontalResolution = getInt(physData[0], physData[1],
physData[2], physData[3]);
verticalResolution = getInt(physData[4], physData[5],
physData[6], physData[7]);
}
}
// Gets the big-Endian integer
private int getInt(byte d1, byte d2, byte d3, byte d4)
{
int i1 = d1 & 0xff;
int i2 = d2 & 0xff;
int i3 = d3 & 0xff;
int i4 = d4 & 0xff;
int val = i1 << 24 |
i2 << 16 |
i3 << 8 |
i4;
return val;
}
public int getHeight()
{
return pixelHeight;
}
public int getWidth()
{
return pixelWidth;
}
public int getHorizontalResolution()
{
// only return if the resolution unit is in metres
return resolutionUnit == 1 ? horizontalResolution : 0;
}
public int getVerticalResolution()
{
// only return if the resolution unit is in metres
return resolutionUnit == 1 ? verticalResolution : 0;
}
public static void main(String args[])
{
try
{
File f = new File(args[0]);
int size = (int) f.length();
byte[] data = new byte[size];
FileInputStream fis = new FileInputStream(f);
fis.read(data);
fis.close();
PNGReader reader = new PNGReader(data);
reader.read();
}
catch (Throwable t)
{
t.printStackTrace();
}
}
}
|