1:
37:
38: package ;
39:
40:
43: public class PNGHeader extends PNGChunk
44: {
45: private int width, height, depth;
46: private int colorType, compression, filter, interlace;
47:
48:
51: public static final int INTERLACE_NONE = 0;
52: public static final int INTERLACE_ADAM7 = 1;
53:
54:
57: public static final int GRAYSCALE = 0;
58: public static final int RGB = 2;
59: public static final int INDEXED = 3;
60: public static final int GRAYSCALE_WITH_ALPHA = 4;
61: public static final int RGB_WITH_ALPHA = 6;
62:
63:
66: protected PNGHeader( int type, byte[] data, int crc ) throws PNGException
67: {
68: super( type, data, crc );
69: if( data.length < 13 )
70: throw new PNGException("Unexpectedly short header chunk. (" + data.length
71: + " bytes)");
72:
73: width = ((data[0] & 0xFF) << 24) | ( (data[1] & 0xFF) << 16 ) |
74: ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
75: height = ((data[4] & 0xFF) << 24) | ( (data[5] & 0xFF) << 16 ) |
76: ((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
77: depth = (data[8] & 0xFF);
78: colorType = (data[9] & 0xFF);
79: compression = (data[10] & 0xFF);
80: filter = (data[11] & 0xFF);
81: interlace = (data[12] & 0xFF);
82: }
83:
84:
88: public PNGHeader(int width, int height, int depth,
89: int colorType, boolean interlace)
90: {
91: super( TYPE_HEADER );
92: data = new byte[ 13 ];
93:
94: this.width = width;
95: this.height = height;
96: this.depth = depth;
97: compression = filter = 0;
98: this.colorType = colorType;
99: this.interlace = interlace ? 1 : 0;
100:
101:
102: byte[] a = getInt( width );
103: byte[] b = getInt( height );
104: data[0] = a[0]; data[1] = a[1]; data[2] = a[2]; data[3] = a[3];
105: data[4] = b[0]; data[5] = b[1]; data[6] = b[2]; data[7] = b[3];
106: data[8] = (byte)depth;
107: data[9] = (byte)colorType;
108: data[10] = (byte)compression;
109: data[11] = (byte)filter;
110: data[12] = (byte)this.interlace;
111: }
112:
113:
116: public boolean isValidChunk()
117: {
118: if( !super.isValidChunk() )
119: return false;
120:
121:
122: if( width == 0 || height == 0 )
123: return false;
124:
125: if( (colorType & 0xFFFFFFF8) != 0 || colorType == 5 || colorType == 1)
126: return false;
127:
128: if( !((depth == 1) || (depth == 2) || (depth == 4) ||
129: (depth == 8) || (depth == 16)) )
130: return false;
131: if( colorType == INDEXED && depth == 16 )
132: return false;
133: if( ( colorType == RGB || colorType == GRAYSCALE_WITH_ALPHA ||
134: colorType == RGB_WITH_ALPHA ) &&
135: depth < 8 )
136: return false;
137:
138: if( compression != 0 || filter != 0 )
139: return false;
140:
141: if( (interlace & 0xFFFFFFFE) != 0 )
142: return false;
143:
144: return true;
145: }
146:
147:
150: public boolean isIndexed()
151: {
152: return (colorType == INDEXED);
153: }
154:
155:
158: public boolean isGrayscale()
159: {
160: return ((colorType == GRAYSCALE) || (colorType == GRAYSCALE_WITH_ALPHA));
161: }
162:
163:
166: public int getColorType()
167: {
168: return colorType;
169: }
170:
171:
174: public boolean isInterlaced()
175: {
176: return (interlace != 0);
177: }
178:
179:
182: public int bytesPerPixel()
183: {
184: switch( colorType )
185: {
186: case GRAYSCALE_WITH_ALPHA:
187: return ((depth * 2) >> 3);
188: case RGB:
189: return ((depth * 3) >> 3);
190: case RGB_WITH_ALPHA:
191: return ((depth * 4) >> 3);
192:
193: default:
194: case GRAYSCALE:
195: case INDEXED:
196: int i = (depth >> 3);
197: if( i > 0 ) return i;
198: return 1;
199: }
200: }
201:
202:
205: public int getScanlineStride()
206: {
207: long nBits = 0;
208: switch( colorType )
209: {
210: case GRAYSCALE:
211: nBits = width * depth;
212: break;
213: case RGB:
214: nBits = width * depth * 3;
215: break;
216: case INDEXED:
217: nBits = depth * width;
218: break;
219: case GRAYSCALE_WITH_ALPHA:
220: nBits = depth * width * 2;
221: break;
222: case RGB_WITH_ALPHA:
223: nBits = depth * width * 4;
224: break;
225: }
226:
227: if( (nBits & 0x07) != 0 )
228: nBits += (8 - (nBits & 0x07));
229:
230: return (int)(nBits >> 3);
231: }
232:
233: public int getWidth()
234: {
235: return width;
236: }
237:
238: public int getHeight()
239: {
240: return height;
241: }
242:
243: public int getDepth()
244: {
245: return depth;
246: }
247:
248:
251: public String toString()
252: {
253: return "Header Chunk. Image width:"+width+" height:"+height+
254: " depth:"+depth+" color type:"+colorType+" compression type:"+
255: compression+" filter type:"+ filter+" interlace:"+interlace;
256: }
257: }