root/dwt/internal/image/PngTrnsChunk.d

Revision 213:36f5cb12e1a2, 5.2 kB (checked in by Frank Benoit <benoit@tionex.de>, 8 months ago)

Update to SWT 3.4M7

Line 
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  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module dwt.internal.image.PngTrnsChunk;
14
15 import dwt.DWT;
16 import dwt.graphics.PaletteData;
17 import dwt.graphics.RGB;
18 import dwt.internal.image.PngChunk;
19 import dwt.internal.image.PNGFileFormat;
20 import dwt.internal.image.PngFileReadState;
21 import dwt.internal.image.PngIhdrChunk;
22 import dwt.internal.image.PngPlteChunk;
23
24 public class PngTrnsChunk : PngChunk {
25
26     alias PngChunk.validate validate;
27
28     static const int TRANSPARENCY_TYPE_PIXEL = 0;
29     static const int TRANSPARENCY_TYPE_ALPHAS = 1;
30     static const int RGB_DATA_LENGTH = 6;
31
32 this(RGB rgb) {
33     super(RGB_DATA_LENGTH);
34     setType(TYPE_tRNS);
35     setInt16(DATA_OFFSET, rgb.red);
36     setInt16(DATA_OFFSET + 2, rgb.green);
37     setInt16(DATA_OFFSET + 4, rgb.blue);
38     setCRC(computeCRC());
39 }
40
41 this(byte[] reference){
42     super(reference);
43 }
44
45 override int getChunkType() {
46     return CHUNK_tRNS;
47 }
48
49 void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) {
50     bool valid;
51     switch (header.getColorType()) {
52         case PngIhdrChunk.COLOR_TYPE_RGB:
53             // Three 2-byte values (RGB)
54             valid = getLength() is 6;
55             break;
56         case PngIhdrChunk.COLOR_TYPE_PALETTE:
57             // Three 2-byte values (RGB)
58             valid = getLength() <= paletteChunk.getLength();
59             break;
60         case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
61             // One 2-byte value
62             valid = getLength() is 2;
63             break;
64         // Cannot use both Alpha and tRNS
65         case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA:
66         case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
67         default:
68             valid = false;
69     }
70     if (!valid) {
71         DWT.error(DWT.ERROR_INVALID_IMAGE);
72     }
73 }
74
75 /**
76  * Answer whether the chunk is a valid tRNS chunk.
77  */
78 void validate(PngFileReadState readState, PngIhdrChunk headerChunk, PngPlteChunk paletteChunk) {
79     if (!readState.readIHDR
80         || (headerChunk.getMustHavePalette() && !readState.readPLTE)
81         || readState.readIDAT
82         || readState.readIEND)
83     {
84         DWT.error(DWT.ERROR_INVALID_IMAGE);
85     } else {
86         readState.readTRNS = true;
87     }
88
89     validateLength(headerChunk, paletteChunk);
90
91     super.validate(readState, headerChunk);
92 }
93
94
95 int getTransparencyType(PngIhdrChunk header) {
96     if (header.getColorType() is PngIhdrChunk.COLOR_TYPE_PALETTE) {
97         return TRANSPARENCY_TYPE_ALPHAS;
98     }
99     return TRANSPARENCY_TYPE_PIXEL;
100 }
101
102 /**
103  * Answer the transparent pixel RGB value.
104  * This is not valid for palette color types.
105  * This is not valid for alpha color types.
106  * This will convert a grayscale value into
107  * a palette index.
108  * It will compress a 6 byte RGB into a 3 byte
109  * RGB.
110  */
111 int getSwtTransparentPixel(PngIhdrChunk header) {
112     switch (header.getColorType()) {
113         case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
114             int gray = ((reference[DATA_OFFSET] & 0xFF) << 8)
115                 + (reference[DATA_OFFSET + 1] & 0xFF);
116             if (header.getBitDepth() > 8) {
117                 return PNGFileFormat.compress16BitDepthTo8BitDepth(gray);
118             }
119             return gray & 0xFF;
120         case PngIhdrChunk.COLOR_TYPE_RGB:
121             int red = ((reference[DATA_OFFSET] & 0xFF) << 8)
122                 | (reference[DATA_OFFSET + 1] & 0xFF);
123             int green = ((reference[DATA_OFFSET + 2] & 0xFF) << 8)
124                 | (reference[DATA_OFFSET + 3] & 0xFF);
125             int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8)
126                 | (reference[DATA_OFFSET + 5] & 0xFF);
127             if (header.getBitDepth() > 8) {
128                 red = PNGFileFormat.compress16BitDepthTo8BitDepth(red);
129                 green = PNGFileFormat.compress16BitDepthTo8BitDepth(green);
130                 blue = PNGFileFormat.compress16BitDepthTo8BitDepth(blue);
131             }
132             return (red << 16) | (green << 8) | blue;
133         default:
134             DWT.error(DWT.ERROR_INVALID_IMAGE);
135             return -1;
136     }
137 }
138
139 /**
140  * Answer an array of Alpha values that correspond to the
141  * colors in the palette.
142  * This is only valid for the COLOR_TYPE_PALETTE color type.
143  */
144 byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) {
145     if (header.getColorType() !is PngIhdrChunk.COLOR_TYPE_PALETTE) {
146         DWT.error(DWT.ERROR_INVALID_IMAGE);
147     }
148     byte[] alphas = new byte[paletteChunk.getPaletteSize()];
149     int dataLength = getLength();
150     int i = 0;
151     for (i = 0; i < dataLength; i++) {
152         alphas[i] = reference[DATA_OFFSET + i];
153     }
154     /**
155      * Any palette entries which do not have a corresponding
156      * alpha value in the tRNS chunk are spec'd to have an
157      * alpha of 255.
158      */
159     for (int j = i; j < alphas.length; j++) {
160         alphas[j] = cast(byte) 255;
161     }
162     return alphas;
163 }
164 }
Note: See TracBrowser for help on using the browser.