|
Java example source code file (PNGImageDecoder.java)
The PNGImageDecoder.java Java example source code
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.image;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.awt.image.*;
import java.awt.Color;
/** PNG - Portable Network Graphics - image file reader.
See <a href=http://www.ietf.org/rfc/rfc2083.txt>RFC2083 for details. */
/* this is changed
public class PNGImageDecoder extends FilterInputStream implements Runnable
{ */
public class PNGImageDecoder extends ImageDecoder
{
private static final int GRAY=0;
private static final int PALETTE=1;
private static final int COLOR=2;
private static final int ALPHA=4;
private static final int bKGDChunk = 0x624B4744;
private static final int cHRMChunk = 0x6348524D;
private static final int gAMAChunk = 0x67414D41;
private static final int hISTChunk = 0x68495354;
private static final int IDATChunk = 0x49444154;
private static final int IENDChunk = 0x49454E44;
private static final int IHDRChunk = 0x49484452;
private static final int PLTEChunk = 0x504C5445;
private static final int pHYsChunk = 0x70485973;
private static final int sBITChunk = 0x73424954;
private static final int tEXtChunk = 0x74455874;
private static final int tIMEChunk = 0x74494D45;
private static final int tRNSChunk = 0x74524E53;
private static final int zTXtChunk = 0x7A545874;
private int width;
private int height;
private int bitDepth;
private int colorType;
private int compressionMethod;
private int filterMethod;
private int interlaceMethod;
private int gamma = 100000;
private java.util.Hashtable properties;
/* this is not needed
ImageConsumer target;
*/
private ColorModel cm;
private byte[] red_map, green_map, blue_map, alpha_map;
private int transparentPixel = -1;
private byte[] transparentPixel_16 = null; // we need 6 bytes to store 16bpp value
private static ColorModel greyModels[] = new ColorModel[4];
/* this is not needed
PNGImageDecoder next;
*/
private void property(String key,Object value) {
if(value==null) return;
if(properties==null) properties=new java.util.Hashtable();
properties.put(key,value);
}
private void property(String key,float value) {
property(key,new Float(value));
}
private final void pngassert(boolean b) throws IOException {
if(!b) {
PNGException e = new PNGException("Broken file");
e.printStackTrace();
throw e;
}
}
protected boolean handleChunk(int key, byte[] buf, int st, int len)
throws IOException {
switch(key) {
case bKGDChunk:
Color c = null;
switch(colorType) {
case COLOR:
case COLOR|ALPHA:
pngassert(len==6);
c = new Color(buf[st]&0xff,buf[st+2]&0xff,buf[st+4]&0xff);
break;
case COLOR|PALETTE:
case COLOR|PALETTE|ALPHA:
pngassert(len==1);
int ix = buf[st]&0xFF;
pngassert(red_map!=null && ix<red_map.length);
c = new Color(red_map[ix]&0xff,green_map[ix]&0xff,blue_map[ix]&0xff);
break;
case GRAY:
case GRAY|ALPHA:
pngassert(len==2);
int t = buf[st]&0xFF;
c = new Color(t,t,t);
break;
}
if(c!=null) property("background",c);
break;
case cHRMChunk:
property("chromaticities",
new Chromaticities(
getInt(st),
getInt(st+4),
getInt(st+8),
getInt(st+12),
getInt(st+16),
getInt(st+20),
getInt(st+24),
getInt(st+28)));
break;
case gAMAChunk:
if(len!=4) throw new PNGException("bogus gAMA");
gamma = getInt(st);
if(gamma!=100000) property("gamma",gamma/100000.0f);
break;
case hISTChunk: break;
case IDATChunk: return false;
case IENDChunk: break;
case IHDRChunk:
if(len!=13
||(width = getInt(st))==0
||(height = getInt(st+4))==0
) throw new PNGException("bogus IHDR");
bitDepth = getByte(st+8);
colorType = getByte(st+9);
compressionMethod = getByte(st+10);
filterMethod = getByte(st+11);
interlaceMethod = getByte(st+12);
/* this is not needed
if(target!=null) target.setDimensions(width,height);
*/
break;
case PLTEChunk:
{ int tsize = len/3;
red_map = new byte[tsize];
green_map = new byte[tsize];
blue_map = new byte[tsize];
for(int i=0,j=st; i<tsize; i++, j+=3) {
red_map[i] = buf[j];
green_map[i] = buf[j+1];
blue_map[i] = buf[j+2];
}
}
break;
case pHYsChunk: break;
case sBITChunk: break;
case tEXtChunk:
int klen = 0;
while(klen<len && buf[st+klen]!=0) klen++;
if(klen<len) {
String tkey = new String(buf,st,klen);
String tvalue = new String(buf,st+klen+1,len-klen-1);
property(tkey,tvalue);
}
break;
case tIMEChunk:
property("modtime",new GregorianCalendar(
getShort(st+0),
getByte(st+2)-1,
getByte(st+3),
getByte(st+4),
getByte(st+5),
getByte(st+6)).getTime());
break;
case tRNSChunk:
switch(colorType) {
case PALETTE|COLOR:
case PALETTE|COLOR|ALPHA:
int alen = len;
if(red_map!=null) alen = red_map.length;
alpha_map = new byte[alen];
System.arraycopy(buf,st,alpha_map,0,len<alen ? len : alen);
while (--alen>=len) alpha_map[alen] = (byte)0xFF;
break;
case COLOR: // doesn't deal with 16 bit colors properly
case COLOR|ALPHA: // doesn't deal with 16 bit colors properly
pngassert(len==6);
if (bitDepth == 16) {
transparentPixel_16 = new byte[6];
for (int i = 0; i < 6; i++) {
transparentPixel_16[i] = (byte)getByte(st + i);
}
} else {
transparentPixel =
((getShort(st + 0)&0xFF)<<16)
| ((getShort(st + 2)&0xFF)<< 8)
| ((getShort(st + 4)&0xFF) );
}
break;
case GRAY: // doesn't deal with 16 bit colors properly
case GRAY|ALPHA: // doesn't deal with 16 bit colors properly
pngassert(len==2);
/* REMIND: Discarding the LSB for 16 bit depth here
* means that the all pixels which match the MSB
* will be treated as transparent.
*/
int t = getShort(st);
t = 0xFF & ((bitDepth == 16) ? (t >> 8) : t);
transparentPixel = (t<<16) | (t<< 8) | t;
break;
}
break;
case zTXtChunk: break;
}
return true;
}
public class PNGException extends IOException {
PNGException(String s) { super(s); }
}
/* this is changed
public void run() {
*/
public void produceImage() throws IOException, ImageFormatException {
/* this is not needed
ImageConsumer t = target;
if(t!=null) try {
*/
try {
for(int i=0; i<signature.length; i++)
if((signature[i]&0xFF)!=underlyingInputStream.read())
throw new PNGException("Chunk signature mismatch");
InputStream is = new BufferedInputStream(new InflaterInputStream(inputStream,new Inflater()));
getData();
byte[] bPixels = null;
int[] wPixels = null;
int pixSize = width;
int rowStride;
int logDepth = 0;
switch(bitDepth) {
case 1: logDepth = 0; break;
case 2: logDepth = 1; break;
case 4: logDepth = 2; break;
case 8: logDepth = 3; break;
case 16: logDepth = 4; break;
default: throw new PNGException("invalid depth");
}
if(interlaceMethod!=0) {pixSize *= height;rowStride=width;}
else rowStride = 0;
int combinedType = colorType|(bitDepth<<3);
int bitMask = (1<<(bitDepth>=8?8:bitDepth))-1;
//Figure out the color model
switch(colorType) {
case COLOR|PALETTE:
case COLOR|PALETTE|ALPHA:
if(red_map==null) throw new PNGException("palette expected");
if(alpha_map==null)
cm = new IndexColorModel(bitDepth,red_map.length,
red_map,green_map,blue_map);
else
cm = new IndexColorModel(bitDepth,red_map.length,
red_map,green_map,blue_map,alpha_map);
bPixels = new byte[pixSize];
break;
case GRAY:
{ int llog = logDepth>=4 ? 3 : logDepth;
if((cm=greyModels[llog]) == null) {
int size = 1<<(1<
Other Java examples (source code examples)Here is a short list of links related to this Java PNGImageDecoder.java source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.