Mercurial > projects > dwt2
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 } |