1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.internal.image;
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.graphics.*;
20 public class PngTrnsChunk extends PngChunk {
21 static final int TRANSPARENCY_TYPE_PIXEL = 0;
22 static final int TRANSPARENCY_TYPE_ALPHAS = 1;
23 static final int RGB_DATA_LENGTH = 6;
25 PngTrnsChunk(RGB rgb) {
26 super(RGB_DATA_LENGTH);
28 setInt16(DATA_OFFSET, rgb.red);
29 setInt16(DATA_OFFSET + 2, rgb.green);
30 setInt16(DATA_OFFSET + 4, rgb.blue);
34 PngTrnsChunk(byte[] reference){
43 void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) {
45 switch (header.getColorType()) {
46 case PngIhdrChunk.COLOR_TYPE_RGB:
47 // Three 2-byte values (RGB)
48 valid = getLength() == 6;
50 case PngIhdrChunk.COLOR_TYPE_PALETTE:
51 // Three 2-byte values (RGB)
52 valid = getLength() <= paletteChunk.getLength();
54 case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
56 valid = getLength() == 2;
58 // Cannot use both Alpha and tRNS
59 case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA:
60 case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
65 SWT.error(SWT.ERROR_INVALID_IMAGE);
70 * Answer whether the chunk is a valid tRNS chunk.
72 void validate(PngFileReadState readState, PngIhdrChunk headerChunk, PngPlteChunk paletteChunk) {
73 if (!readState.readIHDR
74 || (headerChunk.getMustHavePalette() && !readState.readPLTE)
76 || readState.readIEND)
78 SWT.error(SWT.ERROR_INVALID_IMAGE);
80 readState.readTRNS = true;
83 validateLength(headerChunk, paletteChunk);
85 super.validate(readState, headerChunk);
89 int getTransparencyType(PngIhdrChunk header) {
90 if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) {
91 return TRANSPARENCY_TYPE_ALPHAS;
93 return TRANSPARENCY_TYPE_PIXEL;
97 * Answer the transparent pixel RGB value.
98 * This is not valid for palette color types.
99 * This is not valid for alpha color types.
100 * This will convert a grayscale value into
102 * It will compress a 6 byte RGB into a 3 byte
105 int getSwtTransparentPixel(PngIhdrChunk header) {
106 switch (header.getColorType()) {
107 case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
108 int gray = ((reference[DATA_OFFSET] & 0xFF) << 8)
109 + (reference[DATA_OFFSET + 1] & 0xFF);
110 if (header.getBitDepth() > 8) {
111 return PNGFileFormat.compress16BitDepthTo8BitDepth(gray);
114 case PngIhdrChunk.COLOR_TYPE_RGB:
115 int red = ((reference[DATA_OFFSET] & 0xFF) << 8)
116 | (reference[DATA_OFFSET + 1] & 0xFF);
117 int green = ((reference[DATA_OFFSET + 2] & 0xFF) << 8)
118 | (reference[DATA_OFFSET + 3] & 0xFF);
119 int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8)
120 | (reference[DATA_OFFSET + 5] & 0xFF);
121 if (header.getBitDepth() > 8) {
122 red = PNGFileFormat.compress16BitDepthTo8BitDepth(red);
123 green = PNGFileFormat.compress16BitDepthTo8BitDepth(green);
124 blue = PNGFileFormat.compress16BitDepthTo8BitDepth(blue);
126 return (red << 16) | (green << 8) | blue;
128 SWT.error(SWT.ERROR_INVALID_IMAGE);
134 * Answer an array of Alpha values that correspond to the
135 * colors in the palette.
136 * This is only valid for the COLOR_TYPE_PALETTE color type.
138 byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) {
139 if (header.getColorType() != PngIhdrChunk.COLOR_TYPE_PALETTE) {
140 SWT.error(SWT.ERROR_INVALID_IMAGE);
142 byte[] alphas = new byte[paletteChunk.getPaletteSize()];
143 int dataLength = getLength();
145 for (i = 0; i < dataLength; i++) {
146 alphas[i] = reference[DATA_OFFSET + i];
149 * Any palette entries which do not have a corresponding
150 * alpha value in the tRNS chunk are spec'd to have an
153 for (int j = i; j < alphas.length; j++) {
154 alphas[j] = (byte) 255;