comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/internal/image/PngEncoder.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children f36c67707cb3
comparison
equal deleted inserted replaced
-1:000000000000 0:6dd524f61e62
1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 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 org.eclipse.swt.internal.image.PngEncoder;
14
15 import org.eclipse.swt.internal.image.LEDataOutputStream;
16 import org.eclipse.swt.internal.image.PngDeflater;
17 import java.io.ByteArrayOutputStream;
18 import java.io.OutputStream;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.graphics.ImageData;
21 import org.eclipse.swt.graphics.ImageLoader;
22 import org.eclipse.swt.graphics.RGB;
23 import org.eclipse.swt.internal.Compatibility;
24 import org.eclipse.swt.internal.image.PngChunk;
25
26 import tango.core.Exception;
27
28 final class PngEncoder {
29
30 static const byte SIGNATURE[] = [cast(byte) '\211', cast(byte) 'P', cast(byte) 'N', cast(byte) 'G', cast(byte) '\r', cast(byte) '\n', cast(byte) '\032', cast(byte) '\n'];
31 static const byte TAG_IHDR[] = [cast(byte) 'I', cast(byte) 'H', cast(byte) 'D', cast(byte) 'R'];
32 static const byte TAG_PLTE[] = [cast(byte) 'P', cast(byte) 'L', cast(byte) 'T', cast(byte) 'E'];
33 static const byte TAG_TRNS[] = [cast(byte) 't', cast(byte) 'R', cast(byte) 'N', cast(byte) 'S'];
34 static const byte TAG_IDAT[] = [cast(byte) 'I', cast(byte) 'D', cast(byte) 'A', cast(byte) 'T'];
35 static const byte TAG_IEND[] = [cast(byte) 'I', cast(byte) 'E', cast(byte) 'N', cast(byte) 'D'];
36
37 ByteArrayOutputStream bytes;
38 PngChunk chunk;
39
40 ImageLoader loader;
41 ImageData data;
42 int transparencyType;
43
44 int width, height, bitDepth, colorType;
45
46 int compressionMethod = 0;
47 int filterMethod = 0;
48 int interlaceMethod = 0;
49
50 public this(ImageLoader loader) {
51 this.bytes = new ByteArrayOutputStream(1024);
52 this.loader = loader;
53 this.data = loader.data[0];
54 this.transparencyType = data.getTransparencyType();
55
56 this.width = data.width;
57 this.height = data.height;
58
59 this.bitDepth = 8;
60
61 this.colorType = 2;
62
63 if (data.palette.isDirect) {
64 if (transparencyType is SWT.TRANSPARENCY_ALPHA) {
65 this.colorType = 6;
66 }
67 }
68 else {
69 this.colorType = 3;
70 }
71
72 if (!(colorType is 2 || colorType is 3 || colorType is 6)) SWT.error(SWT.ERROR_INVALID_IMAGE);
73
74 }
75
76 void writeShort(ByteArrayOutputStream baos, int theShort) {
77
78 byte byte1 = cast(byte) ((theShort >> 8) & 0xff);
79 byte byte2 = cast(byte) (theShort & 0xff);
80 byte[] temp = [byte1, byte2];
81 baos.write(temp, 0, 2);
82
83 }
84
85 void writeInt(ByteArrayOutputStream baos, int theInt) {
86
87 byte byte1 = cast(byte) ((theInt >> 24) & 0xff);
88 byte byte2 = cast(byte) ((theInt >> 16) & 0xff);
89 byte byte3 = cast(byte) ((theInt >> 8) & 0xff);
90 byte byte4 = cast(byte) (theInt & 0xff);
91 byte[] temp = [byte1, byte2, byte3, byte4];
92 baos.write(temp, 0, 4);
93
94 }
95
96 void writeChunk(byte[] tag, byte[] buffer) {
97
98 int bufferLength = (buffer !is null) ? buffer.length : 0;
99
100 chunk = new PngChunk(bufferLength);
101
102 writeInt(bytes, bufferLength);
103 bytes.write(tag, 0, 4);
104 chunk.setType(tag);
105 if (bufferLength !is 0) {
106 bytes.write(buffer, 0, bufferLength);
107 chunk.setData(buffer);
108 }
109 else {
110 chunk.setCRC(chunk.computeCRC());
111 }
112 writeInt(bytes, chunk.getCRC());
113
114 }
115
116 void writeSignature() {
117
118 bytes.write(SIGNATURE, 0, 8);
119
120 }
121
122 void writeHeader() {
123
124 ByteArrayOutputStream baos = new ByteArrayOutputStream(13);
125
126 writeInt(baos, width);
127 writeInt(baos, height);
128 baos.write(bitDepth);
129 baos.write(colorType);
130 baos.write(compressionMethod);
131 baos.write(filterMethod);
132 baos.write(interlaceMethod);
133
134 writeChunk(TAG_IHDR, baos.toByteArray());
135
136 }
137
138 void writePalette() {
139
140 RGB[] RGBs = data.palette.getRGBs();
141
142 if (RGBs.length > 256) SWT.error(SWT.ERROR_INVALID_IMAGE);
143
144 ByteArrayOutputStream baos = new ByteArrayOutputStream(RGBs.length);
145
146 for (int i = 0; i < RGBs.length; i++) {
147
148 baos.write(cast(byte) RGBs[i].red);
149 baos.write(cast(byte) RGBs[i].green);
150 baos.write(cast(byte) RGBs[i].blue);
151
152 }
153
154 writeChunk(TAG_PLTE, baos.toByteArray());
155
156 }
157
158 void writeTransparency() {
159
160 ByteArrayOutputStream baos = new ByteArrayOutputStream();
161
162 switch (transparencyType) {
163
164 case SWT.TRANSPARENCY_ALPHA:
165
166 int pixelValue, alphaValue;
167
168 byte[] alphas = new byte[data.palette.getRGBs().length];
169
170 for (int y = 0; y < height; y++) {
171
172 for (int x = 0; x < width; x++) {
173
174 pixelValue = data.getPixel(x, y);
175 alphaValue = data.getAlpha(x, y);
176
177 alphas[pixelValue] = cast(byte) alphaValue;
178
179 }
180
181 }
182
183 baos.write(alphas, 0, alphas.length);
184
185 break;
186
187 case SWT.TRANSPARENCY_PIXEL:
188
189 int pixel = data.transparentPixel;
190
191 if (colorType is 2) {
192
193 int redMask = data.palette.redMask;
194 int redShift = data.palette.redShift;
195 int greenMask = data.palette.greenMask;
196 int greenShift = data.palette.greenShift;
197 int blueShift = data.palette.blueShift;
198 int blueMask = data.palette.blueMask;
199
200 int r = pixel & redMask;
201 r = (redShift < 0) ? r >>> -redShift : r << redShift;
202 int g = pixel & greenMask;
203 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
204 int b = pixel & blueMask;
205 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
206
207 writeShort(baos, r);
208 writeShort(baos, g);
209 writeShort(baos, b);
210
211 }
212
213 if (colorType is 3) {
214
215 byte[] padding = new byte[pixel + 1];
216
217 for (int i = 0; i < pixel; i++) {
218
219 padding[i] = cast(byte) 255;
220
221 }
222
223 padding[pixel] = cast(byte) 0;
224
225 baos.write(padding, 0, padding.length);
226
227 }
228
229 break;
230 default:
231
232 }
233
234 writeChunk(TAG_TRNS, baos.toByteArray());
235
236 }
237
238 void writeImageData() {
239
240 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
241 OutputStream os = Compatibility.newDeflaterOutputStream(baos);
242 if (os is null) os = baos;
243
244 if (colorType is 3) {
245
246 byte[] lineData = new byte[width];
247
248 for (int y = 0; y < height; y++) {
249
250 int filter = 0;
251 os.write(filter);
252
253 data.getPixels(0, y, width, lineData, 0);
254
255 for (int x = 0; x < lineData.length; x++) {
256
257 os.write(lineData[x]);
258
259 }
260
261 }
262
263 }
264
265 else {
266
267 int[] lineData = new int[width];
268 byte[] alphaData = null;
269 if (colorType is 6) {
270 alphaData = new byte[width];
271 }
272
273 int redMask = data.palette.redMask;
274 int redShift = data.palette.redShift;
275 int greenMask = data.palette.greenMask;
276 int greenShift = data.palette.greenShift;
277 int blueShift = data.palette.blueShift;
278 int blueMask = data.palette.blueMask;
279
280 for (int y = 0; y < height; y++) {
281
282 int filter = 0;
283 os.write(filter);
284
285 data.getPixels(0, y, width, lineData, 0);
286
287 if (colorType is 6) {
288 data.getAlphas(0, y, width, alphaData, 0);
289 }
290
291 for (int x = 0; x < lineData.length; x++) {
292
293 int pixel = lineData[x];
294
295 int r = pixel & redMask;
296 r = (redShift < 0) ? r >>> -redShift : r << redShift;
297 int g = pixel & greenMask;
298 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
299 int b = pixel & blueMask;
300 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
301
302 os.write(r);
303 os.write(g);
304 os.write(b);
305
306 if (colorType is 6) {
307 os.write(alphaData[x]);
308 }
309
310 }
311
312 }
313
314 }
315
316 os.flush();
317 os.close();
318
319 byte[] compressed = baos.toByteArray();
320 if (os is baos) {
321 PngDeflater deflater = new PngDeflater();
322 compressed = deflater.deflate(compressed);
323 }
324
325 writeChunk(TAG_IDAT, compressed);
326
327 }
328
329 void writeEnd() {
330
331 writeChunk(TAG_IEND, null);
332
333 }
334
335 public void encode(LEDataOutputStream outputStream) {
336
337 try {
338
339 writeSignature();
340 writeHeader();
341
342 if (colorType is 3) {
343 writePalette();
344 }
345
346 bool transparencyAlpha = (transparencyType is SWT.TRANSPARENCY_ALPHA);
347 bool transparencyPixel = (transparencyType is SWT.TRANSPARENCY_PIXEL);
348 bool type2Transparency = (colorType is 2 && transparencyPixel);
349 bool type3Transparency = (colorType is 3 && (transparencyAlpha || transparencyPixel));
350
351 if (type2Transparency || type3Transparency) {
352 writeTransparency();
353 }
354
355 writeImageData();
356 writeEnd();
357
358 outputStream.write(bytes.toByteArray());
359
360 }
361
362 catch (IOException e) {
363
364 SWT.error(SWT.ERROR_IO, e);
365
366 }
367
368 }
369
370 }