Source code: com/sixlegs/image/png/Chunk_IHDR.java
1 // Copyright (C) 1998, 1999, 2001 Chris Nokleberg
2 // Please see included LICENSE.TXT
3
4 package com.sixlegs.image.png;
5
6 import java.awt.image.ColorModel;
7 import java.awt.image.DirectColorModel;
8 import java.io.IOException;
9
10 final class Chunk_IHDR
11 extends Chunk
12 {
13 /* package */ int width;
14 /* package */ int height;
15 /* package */ int depth;
16 /* package */ int outputDepth;
17 /* package */ int compress;
18 /* package */ int filter;
19 /* package */ int interlace;
20 /* package */ Interlacer interlacer;
21
22 /* package */ int samples = 1;
23 /* package */ int colorType;
24 /* package */ int cmBits;
25
26 /* package */ boolean paletteUsed = false;
27 /* package */ boolean colorUsed = false;
28 /* package */ boolean alphaUsed = false;
29
30 /* package */ ColorModel alphaModel;
31 /* package */ ColorModel model;
32
33 Chunk_IHDR()
34 {
35 super(IHDR);
36 }
37
38 protected boolean multipleOK()
39 {
40 return false;
41 }
42
43 // TODO: shorten
44 protected void readData()
45 throws IOException
46 {
47 img.data.header = this;
48 if (length != 13) badLength(13);
49
50 width = in_data.readInt();
51 height = in_data.readInt();
52 if (width <= 0 || height <= 0) {
53 throw new PngException("Bad image size: " + in_data.unsign(width) +
54 "x" + in_data.unsign(height));
55 }
56
57 depth = in_data.readUnsignedByte();
58 outputDepth = (depth == 16 ? 8 : depth);
59
60 int blue = 0;
61 switch (outputDepth) {
62 case 1: blue = 0x01; break;
63 case 2: blue = 0x03; break;
64 case 4: blue = 0x0F; break;
65 case 8: blue = 0xFF; break;
66 default:
67 throw new PngException("Bad bit depth: " + depth);
68 }
69
70 byte[] sbit = null;
71
72 int green = blue << outputDepth;
73 int red = green << outputDepth;
74 int alpha = red << outputDepth;
75
76 byte b_depth = (byte)depth;
77
78 colorType = in_data.readUnsignedByte();
79 switch (colorType) {
80 case PngImage.COLOR_TYPE_GRAY:
81 sbit = new byte[]{b_depth, b_depth, b_depth};
82 cmBits = 3 * outputDepth;
83 break;
84 case PngImage.COLOR_TYPE_RGB:
85 sbit = new byte[]{b_depth, b_depth, b_depth};
86 cmBits = 3 * outputDepth;
87 samples = 3;
88 colorUsed = true;
89 break;
90 case PngImage.COLOR_TYPE_PALETTE:
91 sbit = new byte[]{8, 8, 8};
92 cmBits = outputDepth;
93 colorUsed = paletteUsed = true;
94 break;
95 case PngImage.COLOR_TYPE_GRAY_ALPHA:
96 sbit = new byte[]{b_depth, b_depth, b_depth, b_depth};
97 cmBits = 4 * outputDepth;
98 samples = 2;
99 alphaUsed = true;
100 break;
101 case PngImage.COLOR_TYPE_RGB_ALPHA:
102 sbit = new byte[]{b_depth, b_depth, b_depth, b_depth};
103 cmBits = 4 * outputDepth;
104 samples = 4;
105 alphaUsed = colorUsed = true;
106 break;
107 default:
108 cmBits = 0;
109 throw new PngException("Bad color type: " + colorType);
110 }
111
112 img.data.properties.put("significant bits", sbit);
113
114 if (paletteUsed) {
115 // set later when we see the PLTE chunk
116 } else {
117 if (alphaUsed) {
118 model = alphaModel = new DirectColorModel(cmBits, red, green, blue, alpha);
119 } else {
120 // we may switch to alphaModel if a tRNS chunk is found later
121 alphaModel = ColorModel.getRGBdefault();
122 model = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
123 }
124 }
125
126 switch (colorType) {
127 case PngImage.COLOR_TYPE_GRAY:
128 break;
129 case PngImage.COLOR_TYPE_PALETTE:
130 if (depth == 16)
131 throw new PngException("Bad bit depth for color type " + colorType + ": " + depth);
132 break;
133 default:
134 if (depth <= 4)
135 throw new PngException("Bad bit depth for color type " + colorType + ": " + depth);
136 }
137
138 if ((compress = in_data.readUnsignedByte()) != PngImage.COMPRESSION_TYPE_BASE)
139 throw new PngException("Unrecognized compression method: " + compress);
140
141 if ((filter = in_data.readUnsignedByte()) != PngImage.FILTER_TYPE_BASE)
142 throw new PngException("Unrecognized filter method: " + filter);
143
144 interlace = in_data.readUnsignedByte();
145 switch (interlace) {
146 case PngImage.INTERLACE_TYPE_NONE:
147 interlacer = new NullInterlacer(width, height);
148 break;
149 case PngImage.INTERLACE_TYPE_ADAM7:
150 interlacer = new Adam7Interlacer(width, height);
151 break;
152 default:
153 throw new PngException("Unrecognized interlace method: " + interlace);
154 }
155
156 img.data.properties.put("width", new Integer(width));
157 img.data.properties.put("height", new Integer(height));
158 img.data.properties.put("bit depth", new Integer(depth));
159 img.data.properties.put("interlace type", new Integer(interlace));
160 img.data.properties.put("compression type", new Integer(compress));
161 img.data.properties.put("filter type", new Integer(filter));
162 img.data.properties.put("color type", new Integer(colorType));
163 }
164 }