001: /*
002: * $RCSfile: PNGCodec.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:55:37 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.codecimpl;
013:
014: import java.awt.image.ColorModel;
015: import java.awt.image.DataBuffer;
016: import java.awt.image.IndexColorModel;
017: import java.awt.image.RenderedImage;
018: import java.awt.image.SampleModel;
019: import java.io.File;
020: import java.io.FileInputStream;
021: import java.io.InputStream;
022: import java.io.IOException;
023: import java.io.OutputStream;
024: import com.sun.media.jai.codec.ImageCodec;
025: import com.sun.media.jai.codec.ImageDecoder;
026: import com.sun.media.jai.codec.ImageDecodeParam;
027: import com.sun.media.jai.codec.ImageEncoder;
028: import com.sun.media.jai.codec.ImageEncodeParam;
029: import com.sun.media.jai.codec.PNGDecodeParam;
030: import com.sun.media.jai.codec.PNGEncodeParam;
031: import com.sun.media.jai.codec.SeekableStream;
032:
033: /**
034: * @since EA3
035: */
036: public final class PNGCodec extends ImageCodec {
037:
038: public PNGCodec() {
039: }
040:
041: public String getFormatName() {
042: return "png";
043: }
044:
045: public Class getEncodeParamClass() {
046: return com.sun.media.jai.codec.PNGEncodeParam.class;
047: }
048:
049: public Class getDecodeParamClass() {
050: return com.sun.media.jai.codec.PNGDecodeParam.class;
051: }
052:
053: public boolean canEncodeImage(RenderedImage im,
054: ImageEncodeParam param) {
055: SampleModel sampleModel = im.getSampleModel();
056:
057: // PNG doesn't handle float or double pixels
058: int dataType = sampleModel.getTransferType();
059: if ((dataType == DataBuffer.TYPE_FLOAT)
060: || (dataType == DataBuffer.TYPE_DOUBLE)) {
061: return false;
062: }
063:
064: int[] sampleSize = sampleModel.getSampleSize();
065: int bitDepth = sampleSize[0];
066:
067: // Ensure all channels have the same bit depth
068: for (int i = 1; i < sampleSize.length; i++) {
069: if (sampleSize[i] != bitDepth) {
070: return false;
071: }
072: }
073:
074: // Bit depth must be between 1 and 16
075: if (bitDepth < 1 || bitDepth > 16) {
076: return false;
077: }
078:
079: // Number of bands must be between 1 and 4
080: int numBands = sampleModel.getNumBands();
081: if (numBands < 1 || numBands > 4) {
082: return false;
083: }
084:
085: // Palette images must be 1-banded, depth 8 or less
086: ColorModel colorModel = im.getColorModel();
087: if (colorModel instanceof IndexColorModel) {
088: if (numBands != 1 || bitDepth > 8) {
089: return false;
090: }
091: }
092:
093: // If a param object is supplied, check that it is of the right type
094: if (param != null) {
095: if (param instanceof PNGEncodeParam) {
096: if (colorModel instanceof IndexColorModel) {
097: if (!(param instanceof PNGEncodeParam.Palette)) {
098: return false;
099: }
100: } else if (numBands < 3) {
101: if (!(param instanceof PNGEncodeParam.Gray)) {
102: return false;
103: }
104: } else {
105: if (!(param instanceof PNGEncodeParam.RGB)) {
106: return false;
107: }
108: }
109: } else {
110: return false;
111: }
112: }
113:
114: return true;
115: }
116:
117: protected ImageEncoder createImageEncoder(OutputStream dst,
118: ImageEncodeParam param) {
119: PNGEncodeParam p = null;
120: if (param != null) {
121: p = (PNGEncodeParam) param;
122: }
123: return new PNGImageEncoder(dst, p);
124: }
125:
126: protected ImageDecoder createImageDecoder(InputStream src,
127: ImageDecodeParam param) {
128: PNGDecodeParam p = null;
129: if (param != null) {
130: p = (PNGDecodeParam) param;
131: }
132: return new PNGImageDecoder(src, p);
133: }
134:
135: protected ImageDecoder createImageDecoder(File src,
136: ImageDecodeParam param) throws IOException {
137: PNGDecodeParam p = null;
138: if (param != null) {
139: p = (PNGDecodeParam) param;
140: }
141: return new PNGImageDecoder(new FileInputStream(src), p);
142: }
143:
144: protected ImageDecoder createImageDecoder(SeekableStream src,
145: ImageDecodeParam param) {
146: PNGDecodeParam p = null;
147: if (param != null) {
148: p = (PNGDecodeParam) param;
149: }
150: return new PNGImageDecoder(src, p);
151: }
152:
153: public int getNumHeaderBytes() {
154: return 8;
155: }
156:
157: public boolean isFormatRecognized(byte[] header) {
158: return ((header[0] == (byte) 0x89)
159: && (header[1] == (byte) 0x50)
160: && (header[2] == (byte) 0x4e)
161: && (header[3] == (byte) 0x47)
162: && (header[4] == (byte) 0x0d)
163: && (header[5] == (byte) 0x0a)
164: && (header[6] == (byte) 0x1a) && (header[7] == (byte) 0x0a));
165: }
166: }
|