KickJava   Java API By Example, From Geeks To Geeks.

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


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 public class PngTrnsChunk extends PngChunk {
18     static final int TRANSPARENCY_TYPE_PIXEL = 0;
19     static final int TRANSPARENCY_TYPE_ALPHAS = 1;
20     static final int RGB_DATA_LENGTH = 6;
21     
22 PngTrnsChunk(RGB rgb) {
23     super(RGB_DATA_LENGTH);
24     setType(TYPE_tRNS);
25     setInt16(DATA_OFFSET, rgb.red);
26     setInt16(DATA_OFFSET + 2, rgb.green);
27     setInt16(DATA_OFFSET + 4, rgb.blue);
28     setCRC(computeCRC());
29 }
30
31 PngTrnsChunk(byte[] reference){
32     super(reference);
33 }
34
35 int getChunkType() {
36     return CHUNK_tRNS;
37 }
38
39 void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) {
40     boolean valid;
41     switch (header.getColorType()) {
42         case PngIhdrChunk.COLOR_TYPE_RGB:
43             // Three 2-byte values (RGB)
44
valid = getLength() == 6;
45             break;
46         case PngIhdrChunk.COLOR_TYPE_PALETTE:
47             // Three 2-byte values (RGB)
48
valid = getLength() <= paletteChunk.getLength();
49             break;
50         case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
51             // One 2-byte value
52
valid = getLength() == 2;
53             break;
54         // Cannot use both Alpha and tRNS
55
case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA:
56         case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
57         default:
58             valid = false;
59     }
60     if (!valid) {
61         SWT.error(SWT.ERROR_INVALID_IMAGE);
62     }
63 }
64
65 /**
66  * Answer whether the chunk is a valid tRNS chunk.
67  */

68 void validate(PngFileReadState readState, PngIhdrChunk headerChunk, PngPlteChunk paletteChunk) {
69     if (!readState.readIHDR
70         || (headerChunk.getMustHavePalette() && !readState.readPLTE)
71         || readState.readIDAT
72         || readState.readIEND)
73     {
74         SWT.error(SWT.ERROR_INVALID_IMAGE);
75     } else {
76         readState.readTRNS = true;
77     }
78     
79     validateLength(headerChunk, paletteChunk);
80     
81     super.validate(readState, headerChunk);
82 }
83
84
85 int getTransparencyType(PngIhdrChunk header) {
86     if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) {
87         return TRANSPARENCY_TYPE_ALPHAS;
88     }
89     return TRANSPARENCY_TYPE_PIXEL;
90 }
91
92 /**
93  * Answer the transparent pixel RGB value.
94  * This is not valid for palette color types.
95  * This is not valid for alpha color types.
96  * This will convert a grayscale value into
97  * a palette index.
98  * It will compress a 6 byte RGB into a 3 byte
99  * RGB.
100  */

101 int getSwtTransparentPixel(PngIhdrChunk header) {
102     switch (header.getColorType()) {
103         case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
104             int gray = ((reference[DATA_OFFSET] & 0xFF) << 8)
105                 + (reference[DATA_OFFSET + 1] & 0xFF);
106             if (header.getBitDepth() > 8) {
107                 return PNGFileFormat.compress16BitDepthTo8BitDepth(gray);
108             }
109             return gray & 0xFF;
110         case PngIhdrChunk.COLOR_TYPE_RGB:
111             int red = ((reference[DATA_OFFSET] & 0xFF) << 8)
112                 | (reference[DATA_OFFSET + 1] & 0xFF);
113             int green = ((reference[DATA_OFFSET + 2] & 0xFF) << 8)
114                 | (reference[DATA_OFFSET + 3] & 0xFF);
115             int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8)
116                 | (reference[DATA_OFFSET + 5] & 0xFF);
117             if (header.getBitDepth() > 8) {
118                 red = PNGFileFormat.compress16BitDepthTo8BitDepth(red);
119                 green = PNGFileFormat.compress16BitDepthTo8BitDepth(green);
120                 blue = PNGFileFormat.compress16BitDepthTo8BitDepth(blue);
121             }
122             return (red << 16) | (green << 8) | blue;
123         default:
124             SWT.error(SWT.ERROR_INVALID_IMAGE);
125             return -1;
126     }
127 }
128
129 /**
130  * Answer an array of Alpha values that correspond to the
131  * colors in the palette.
132  * This is only valid for the COLOR_TYPE_PALETTE color type.
133  */

134 byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) {
135     if (header.getColorType() != PngIhdrChunk.COLOR_TYPE_PALETTE) {
136         SWT.error(SWT.ERROR_INVALID_IMAGE);
137     }
138     byte[] alphas = new byte[paletteChunk.getPaletteSize()];
139     int dataLength = getLength();
140     int i = 0;
141     for (i = 0; i < dataLength; i++) {
142         alphas[i] = reference[DATA_OFFSET + i];
143     }
144     /**
145      * Any palette entries which do not have a corresponding
146      * alpha value in the tRNS chunk are spec'd to have an
147      * alpha of 255.
148      */

149     for (int j = i; j < alphas.length; j++) {
150         alphas[j] = (byte) 255;
151     }
152     return alphas;
153 }
154 }
155
Popular Tags