KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > internal > image > PngIhdrChunk


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.internal.image;
12
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.graphics.*;
16
17 class PngIhdrChunk extends PngChunk {
18     static final int IHDR_DATA_LENGTH = 13;
19     
20     static final int WIDTH_DATA_OFFSET = DATA_OFFSET + 0;
21     static final int HEIGHT_DATA_OFFSET = DATA_OFFSET + 4;
22     static final int BIT_DEPTH_OFFSET = DATA_OFFSET + 8;
23     static final int COLOR_TYPE_OFFSET = DATA_OFFSET + 9;
24     static final int COMPRESSION_METHOD_OFFSET = DATA_OFFSET + 10;
25     static final int FILTER_METHOD_OFFSET = DATA_OFFSET + 11;
26     static final int INTERLACE_METHOD_OFFSET = DATA_OFFSET + 12;
27     
28     static final byte COLOR_TYPE_GRAYSCALE = 0;
29     static final byte COLOR_TYPE_RGB = 2;
30     static final byte COLOR_TYPE_PALETTE = 3;
31     static final byte COLOR_TYPE_GRAYSCALE_WITH_ALPHA = 4;
32     static final byte COLOR_TYPE_RGB_WITH_ALPHA = 6;
33     
34     static final int INTERLACE_METHOD_NONE = 0;
35     static final int INTERLACE_METHOD_ADAM7 = 1;
36     
37     static final int FILTER_NONE = 0;
38     static final int FILTER_SUB = 1;
39     static final int FILTER_UP = 2;
40     static final int FILTER_AVERAGE = 3;
41     static final int FILTER_PAETH = 4;
42     
43     static final byte[] ValidBitDepths = {1, 2, 4, 8, 16};
44     static final byte[] ValidColorTypes = {0, 2, 3, 4, 6};
45     
46     int width, height;
47     byte bitDepth, colorType, compressionMethod, filterMethod, interlaceMethod;
48     
49 PngIhdrChunk(int width, int height, byte bitDepth, byte colorType, byte compressionMethod, byte filterMethod, byte interlaceMethod) {
50     super(IHDR_DATA_LENGTH);
51     setType(TYPE_IHDR);
52     setWidth(width);
53     setHeight(height);
54     setBitDepth(bitDepth);
55     setColorType(colorType);
56     setCompressionMethod(compressionMethod);
57     setFilterMethod(filterMethod);
58     setInterlaceMethod(interlaceMethod);
59     setCRC(computeCRC());
60 }
61
62 /**
63  * Construct a PNGChunk using the reference bytes
64  * given.
65  */

66 PngIhdrChunk(byte[] reference) {
67     super(reference);
68     if (reference.length <= IHDR_DATA_LENGTH) SWT.error(SWT.ERROR_INVALID_IMAGE);
69     width = getInt32(WIDTH_DATA_OFFSET);
70     height = getInt32(HEIGHT_DATA_OFFSET);
71     bitDepth = reference[BIT_DEPTH_OFFSET];
72     colorType = reference[COLOR_TYPE_OFFSET];
73     compressionMethod = reference[COMPRESSION_METHOD_OFFSET];
74     filterMethod = reference[FILTER_METHOD_OFFSET];
75     interlaceMethod = reference[INTERLACE_METHOD_OFFSET];
76 }
77
78 int getChunkType() {
79     return CHUNK_IHDR;
80 }
81
82 /**
83  * Get the image's width in pixels.
84  */

85 int getWidth() {
86     return width;
87 }
88
89 /**
90  * Set the image's width in pixels.
91  */

92 void setWidth(int value) {
93     setInt32(WIDTH_DATA_OFFSET, value);
94     width = value;
95 }
96
97 /**
98  * Get the image's height in pixels.
99  */

100 int getHeight() {
101     return height;
102 }
103
104 /**
105  * Set the image's height in pixels.
106  */

107 void setHeight(int value) {
108     setInt32(HEIGHT_DATA_OFFSET, value);
109     height = value;
110 }
111
112 /**
113  * Get the image's bit depth.
114  * This is limited to the values 1, 2, 4, 8, or 16.
115  */

116 byte getBitDepth() {
117     return bitDepth;
118 }
119
120 /**
121  * Set the image's bit depth.
122  * This is limited to the values 1, 2, 4, 8, or 16.
123  */

124 void setBitDepth(byte value) {
125     reference[BIT_DEPTH_OFFSET] = value;
126     bitDepth = value;
127 }
128
129 /**
130  * Get the image's color type.
131  * This is limited to the values:
132  * 0 - Grayscale image.
133  * 2 - RGB triple.
134  * 3 - Palette.
135  * 4 - Grayscale with Alpha channel.
136  * 6 - RGB with Alpha channel.
137  */

138 byte getColorType() {
139     return colorType;
140 }
141
142 /**
143  * Set the image's color type.
144  * This is limited to the values:
145  * 0 - Grayscale image.
146  * 2 - RGB triple.
147  * 3 - Palette.
148  * 4 - Grayscale with Alpha channel.
149  * 6 - RGB with Alpha channel.
150  */

151 void setColorType(byte value) {
152     reference[COLOR_TYPE_OFFSET] = value;
153     colorType = value;
154 }
155
156 /**
157  * Get the image's compression method.
158  * This value must be 0.
159  */

160 byte getCompressionMethod() {
161     return compressionMethod;
162 }
163
164 /**
165  * Set the image's compression method.
166  * This value must be 0.
167  */

168 void setCompressionMethod(byte value) {
169     reference[COMPRESSION_METHOD_OFFSET] = value;
170     compressionMethod = value;
171 }
172
173 /**
174  * Get the image's filter method.
175  * This value must be 0.
176  */

177 byte getFilterMethod() {
178     return filterMethod;
179 }
180
181 /**
182  * Set the image's filter method.
183  * This value must be 0.
184  */

185 void setFilterMethod(byte value) {
186     reference[FILTER_METHOD_OFFSET] = value;
187     filterMethod = value;
188 }
189
190 /**
191  * Get the image's interlace method.
192  * This value is limited to:
193  * 0 - No interlacing used.
194  * 1 - Adam7 interlacing used.
195  */

196 byte getInterlaceMethod() {
197     return interlaceMethod;
198 }
199
200 /**
201  * Set the image's interlace method.
202  * This value is limited to:
203  * 0 - No interlacing used.
204  * 1 - Adam7 interlacing used.
205  */

206 void setInterlaceMethod(byte value) {
207     reference[INTERLACE_METHOD_OFFSET] = value;
208     interlaceMethod = value;
209 }
210
211 /**
212  * Answer whether the chunk is a valid IHDR chunk.
213  */

214 void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
215     // An IHDR chunk is invalid if any other chunk has
216
// been read.
217
if (readState.readIHDR
218         || readState.readPLTE
219         || readState.readIDAT
220         || readState.readIEND)
221     {
222         SWT.error(SWT.ERROR_INVALID_IMAGE);
223     } else {
224         readState.readIHDR = true;
225     }
226     
227     super.validate(readState, headerChunk);
228     
229     if (length != IHDR_DATA_LENGTH) SWT.error(SWT.ERROR_INVALID_IMAGE);
230     if (compressionMethod != 0) SWT.error(SWT.ERROR_INVALID_IMAGE);
231     if (interlaceMethod != INTERLACE_METHOD_NONE &&
232         interlaceMethod != INTERLACE_METHOD_ADAM7) {
233             SWT.error(SWT.ERROR_INVALID_IMAGE);
234     }
235     
236     boolean colorTypeIsValid = false;
237     for (int i = 0; i < ValidColorTypes.length; i++) {
238         if (ValidColorTypes[i] == colorType) {
239             colorTypeIsValid = true;
240             break;
241         }
242     }
243     if (!colorTypeIsValid) SWT.error(SWT.ERROR_INVALID_IMAGE);
244
245     boolean bitDepthIsValid = false;
246     for (int i = 0; i < ValidBitDepths.length; i++) {
247         if (ValidBitDepths[i] == bitDepth) {
248             bitDepthIsValid = true;
249             break;
250         }
251     }
252     if (!bitDepthIsValid) SWT.error(SWT.ERROR_INVALID_IMAGE);
253     
254     if ((colorType == COLOR_TYPE_RGB
255         || colorType == COLOR_TYPE_RGB_WITH_ALPHA
256         || colorType == COLOR_TYPE_GRAYSCALE_WITH_ALPHA)
257         && bitDepth < 8)
258     {
259             SWT.error(SWT.ERROR_INVALID_IMAGE);
260     }
261     
262     if (colorType == COLOR_TYPE_PALETTE && bitDepth > 8) {
263         SWT.error(SWT.ERROR_INVALID_IMAGE);
264     }
265 }
266
267 String JavaDoc getColorTypeString() {
268     switch (colorType) {
269         case COLOR_TYPE_GRAYSCALE: return "Grayscale";
270         case COLOR_TYPE_RGB: return "RGB";
271         case COLOR_TYPE_PALETTE: return "Palette";
272         case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: return "Grayscale with Alpha";
273         case COLOR_TYPE_RGB_WITH_ALPHA: return "RGB with Alpha";
274         default: return "Unknown - " + colorType;
275     }
276 }
277
278 String JavaDoc getFilterMethodString() {
279     switch (filterMethod) {
280         case FILTER_NONE: return "None";
281         case FILTER_SUB: return "Sub";
282         case FILTER_UP: return "Up";
283         case FILTER_AVERAGE: return "Average";
284         case FILTER_PAETH: return "Paeth";
285         default: return "Unknown";
286     }
287 }
288
289 String JavaDoc getInterlaceMethodString() {
290     switch (interlaceMethod) {
291         case INTERLACE_METHOD_NONE: return "Not Interlaced";
292         case INTERLACE_METHOD_ADAM7: return "Interlaced - ADAM7";
293         default: return "Unknown";
294     }
295 }
296
297 void contributeToString(StringBuffer JavaDoc buffer) {
298     buffer.append("\n\tWidth: ");
299     buffer.append(width);
300     buffer.append("\n\tHeight: ");
301     buffer.append(height);
302     buffer.append("\n\tBit Depth: ");
303     buffer.append(bitDepth);
304     buffer.append("\n\tColor Type: ");
305     buffer.append(getColorTypeString());
306     buffer.append("\n\tCompression Method: ");
307     buffer.append(compressionMethod);
308     buffer.append("\n\tFilter Method: ");
309     buffer.append(getFilterMethodString());
310     buffer.append("\n\tInterlace Method: ");
311     buffer.append(getInterlaceMethodString());
312 }
313
314 boolean getMustHavePalette() {
315     return colorType == COLOR_TYPE_PALETTE;
316 }
317
318 boolean getCanHavePalette() {
319     return colorType != COLOR_TYPE_GRAYSCALE &&
320         colorType != COLOR_TYPE_GRAYSCALE_WITH_ALPHA;
321 }
322
323 /**
324  * Answer the pixel size in bits based on the color type
325  * and bit depth.
326  */

327 int getBitsPerPixel() {
328     switch (colorType) {
329         case COLOR_TYPE_RGB_WITH_ALPHA:
330             return 4 * bitDepth;
331         case COLOR_TYPE_RGB:
332             return 3 * bitDepth;
333         case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
334             return 2 * bitDepth;
335         case COLOR_TYPE_GRAYSCALE:
336         case COLOR_TYPE_PALETTE:
337             return bitDepth;
338         default:
339             SWT.error(SWT.ERROR_INVALID_IMAGE);
340             return 0;
341     }
342 }
343
344 /**
345  * Answer the pixel size in bits based on the color type
346  * and bit depth.
347  */

348 int getSwtBitsPerPixel() {
349     switch (colorType) {
350         case COLOR_TYPE_RGB_WITH_ALPHA:
351         case COLOR_TYPE_RGB:
352         case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
353             return 24;
354         case COLOR_TYPE_GRAYSCALE:
355         case COLOR_TYPE_PALETTE:
356             return Math.min(bitDepth, 8);
357         default:
358             SWT.error(SWT.ERROR_INVALID_IMAGE);
359             return 0;
360     }
361 }
362
363 int getFilterByteOffset() {
364     if (bitDepth < 8) return 1;
365     return getBitsPerPixel() / 8;
366 }
367
368 boolean usesDirectColor() {
369     switch (colorType) {
370         case COLOR_TYPE_GRAYSCALE:
371         case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
372         case COLOR_TYPE_RGB:
373         case COLOR_TYPE_RGB_WITH_ALPHA:
374             return true;
375         default:
376             return false;
377     }
378 }
379
380 PaletteData createGrayscalePalette() {
381     int depth = Math.min(bitDepth, 8);
382     int max = (1 << depth) - 1;
383     int delta = 255 / max;
384     int gray = 0;
385     RGB[] rgbs = new RGB[max + 1];
386     for (int i = 0; i <= max; i++) {
387         rgbs[i] = new RGB(gray, gray, gray);
388         gray += delta;
389     }
390     return new PaletteData(rgbs);
391 }
392
393 PaletteData getPaletteData() {
394     switch (colorType) {
395         case COLOR_TYPE_GRAYSCALE:
396             return createGrayscalePalette();
397         case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
398         case COLOR_TYPE_RGB:
399         case COLOR_TYPE_RGB_WITH_ALPHA:
400             return new PaletteData(0xFF0000, 0xFF00, 0xFF);
401         default:
402             return null;
403     }
404 }
405
406
407
408 }
409
Popular Tags