/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id: PNGChunk.java 1732019 2016-02-24 05:01:10Z gadams $ */

package org.apache.xmlgraphics.image.codec.png;

import java.io.DataInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PNGChunk {
    int length;
    int type;
    byte[] data;
    int crc;

    String typeString;

    
logger
/** logger */
protected static final Log log = LogFactory.getLog(PNGChunk.class);
See http://en.wikipedia.org/wiki/Portable_Network_Graphics for a light explanation; See http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html for the spec.
/** * See http://en.wikipedia.org/wiki/Portable_Network_Graphics for a light explanation; * See http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html for the spec. */
public enum ChunkType { IHDR, // IHDR must be the first chunk PLTE, // PLTE contains the palette IDAT, // IDAT contains the image, which may be split among multiple IDAT chunks IEND, // IEND marks the image end bKGD, // bKGD gives the default background color cHRM, // cHRM gives the chromaticity coordinates gAMA, // gAMA specifies gamma hIST, // hIST can store the histogram iCCP, // iCCP is an ICC color profile iTXt, // iTXt contains UTF-8 text pHYs, // pHYs holds the intended pixel size sBIT, // sBIT (significant bits) indicates the color-accuracy sPLT, // sPLT suggests a palette to use sRGB, // sRGB indicates that the standard sRGB color space is used sTER, // sTER stereo-image indicator chunk for stereoscopic images tEXt, // tEXt can store text that can be represented in ISO/IEC 8859-1 tIME, // tIME stores the time that the image was last changed tRNS, // tRNS contains transparency information zTXt; // zTXt contains compressed text with the same limits as tEXt } public PNGChunk(int length, int type, byte[] data, int crc) { this.length = length; this.type = type; this.data = data; this.crc = crc; this.typeString = typeIntToString(this.type); } public int getLength() { return length; } public int getType() { return type; } public String getTypeString() { return typeString; } public byte[] getData() { return data; } public byte getByte(int offset) { return data[offset]; } public int getInt1(int offset) { return data[offset] & 0xff; } public int getInt2(int offset) { return ((data[offset] & 0xff) << 8) | (data[offset + 1] & 0xff); } public int getInt4(int offset) { return ((data[offset] & 0xff) << 24) | ((data[offset + 1] & 0xff) << 16) | ((data[offset + 2] & 0xff) << 8) | (data[offset + 3] & 0xff); } public String getString4(int offset) { return "" + (char) data[offset] + (char) data[offset + 1] + (char) data[offset + 2] + (char) data[offset + 3]; } public boolean isType(String typeName) { return typeString.equals(typeName); }
Reads the next chunk from the input stream.
Params:
  • distream – the input stream
Returns:the chunk
/** * Reads the next chunk from the input stream. * @param distream the input stream * @return the chunk */
public static PNGChunk readChunk(DataInputStream distream) { try { int length = distream.readInt(); int type = distream.readInt(); byte[] data = new byte[length]; distream.readFully(data); int crc = distream.readInt(); return new PNGChunk(length, type, data, crc); } catch (Exception e) { e.printStackTrace(); return null; } }
Returns the PNG chunk type, a four letter case sensitive ASCII type/name.
Params:
  • distream – the input stream
Returns:a four letter case sensitive ASCII type/name
/** * Returns the PNG chunk type, a four letter case sensitive ASCII type/name. * @param distream the input stream * @return a four letter case sensitive ASCII type/name */
public static String getChunkType(DataInputStream distream) { try { distream.mark(8); /* int length = */distream.readInt(); int type = distream.readInt(); distream.reset(); return typeIntToString(type); } catch (Exception e) { e.printStackTrace(); return null; } } private static String typeIntToString(int type) { String typeString = ""; typeString += (char) (type >> 24); typeString += (char) ((type >> 16) & 0xff); typeString += (char) ((type >> 8) & 0xff); typeString += (char) (type & 0xff); return typeString; }
Skips the next chunk from the input stream.
Params:
  • distream – the input stream
Returns:true if skipping successful, false otherwise
/** * Skips the next chunk from the input stream. * @param distream the input stream * @return true if skipping successful, false otherwise */
public static boolean skipChunk(DataInputStream distream) { try { int length = distream.readInt(); distream.readInt(); // is this really faster than reading? int skipped = distream.skipBytes(length); distream.readInt(); if (skipped != length) { log.warn("Incorrect number of bytes skipped."); return false; } return true; } catch (Exception e) { log.warn(e.getMessage()); return false; } } }