]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/internal/image/PngTrnsChunk.java
9df7d9d32ffc109d08aab868f462a4459f17dd63
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / internal / image / PngTrnsChunk.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 IBM Corporation and others.
3  *
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/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.internal.image;
15
16
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.graphics.*;
19
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;
24
25 PngTrnsChunk(RGB rgb) {
26         super(RGB_DATA_LENGTH);
27         setType(TYPE_tRNS);
28         setInt16(DATA_OFFSET, rgb.red);
29         setInt16(DATA_OFFSET + 2, rgb.green);
30         setInt16(DATA_OFFSET + 4, rgb.blue);
31         setCRC(computeCRC());
32 }
33
34 PngTrnsChunk(byte[] reference){
35         super(reference);
36 }
37
38 @Override
39 int getChunkType() {
40         return CHUNK_tRNS;
41 }
42
43 void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) {
44         boolean valid;
45         switch (header.getColorType()) {
46                 case PngIhdrChunk.COLOR_TYPE_RGB:
47                         // Three 2-byte values (RGB)
48                         valid = getLength() == 6;
49                         break;
50                 case PngIhdrChunk.COLOR_TYPE_PALETTE:
51                         // Three 2-byte values (RGB)
52                         valid = getLength() <= paletteChunk.getLength();
53                         break;
54                 case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
55                         // One 2-byte value
56                         valid = getLength() == 2;
57                         break;
58                 // Cannot use both Alpha and tRNS
59                 case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA:
60                 case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
61                 default:
62                         valid = false;
63         }
64         if (!valid) {
65                 SWT.error(SWT.ERROR_INVALID_IMAGE);
66         }
67 }
68
69 /**
70  * Answer whether the chunk is a valid tRNS chunk.
71  */
72 void validate(PngFileReadState readState, PngIhdrChunk headerChunk, PngPlteChunk paletteChunk) {
73         if (!readState.readIHDR
74                 || (headerChunk.getMustHavePalette() && !readState.readPLTE)
75                 || readState.readIDAT
76                 || readState.readIEND)
77         {
78                 SWT.error(SWT.ERROR_INVALID_IMAGE);
79         } else {
80                 readState.readTRNS = true;
81         }
82
83         validateLength(headerChunk, paletteChunk);
84
85         super.validate(readState, headerChunk);
86 }
87
88
89 int getTransparencyType(PngIhdrChunk header) {
90         if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) {
91                 return TRANSPARENCY_TYPE_ALPHAS;
92         }
93         return TRANSPARENCY_TYPE_PIXEL;
94 }
95
96 /**
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
101  * a palette index.
102  * It will compress a 6 byte RGB into a 3 byte
103  * RGB.
104  */
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);
112                         }
113                         return gray & 0xFF;
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);
125                         }
126                         return (red << 16) | (green << 8) | blue;
127                 default:
128                         SWT.error(SWT.ERROR_INVALID_IMAGE);
129                         return -1;
130         }
131 }
132
133 /**
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.
137  */
138 byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) {
139         if (header.getColorType() != PngIhdrChunk.COLOR_TYPE_PALETTE) {
140                 SWT.error(SWT.ERROR_INVALID_IMAGE);
141         }
142         byte[] alphas = new byte[paletteChunk.getPaletteSize()];
143         int dataLength = getLength();
144         int i = 0;
145         for (i = 0; i < dataLength; i++) {
146                 alphas[i] = reference[DATA_OFFSET + i];
147         }
148         /**
149          * Any palette entries which do not have a corresponding
150          * alpha value in the tRNS chunk are spec'd to have an
151          * alpha of 255.
152          */
153         for (int j = i; j < alphas.length; j++) {
154                 alphas[j] = (byte) 255;
155         }
156         return alphas;
157 }
158 }