Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/internal/image/PngEncoder.d @ 120:536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
===D2===
* added [Try]Immutable/Const/Shared templates to work with differenses in D1/D2 instead of version statements
used these templates to work with strict type storage rules of dmd-2.053
* com.ibm.icu now also compilable with D2, but not tested yet
* small fixes
Snippet288 - shared data is in TLS
===Phobos===
* fixed critical bugs in Phobos implemention
completely incorrect segfault prone fromStringz (Linux's port ruthless killer)
terrible, incorrect StringBuffer realization (StyledText killer)
* fixed small bugs as well
Snippet72 - misprint in the snippet
* implemented missed functionality for Phobos
ByteArrayOutputStream implemented (image loading available)
formatting correctly works for all DWT's cases
As a result, folowing snippets now works with Phobos (Snippet### - what is fixed):
Snippet24, 42, 111, 115, 130, 235, 276 - bad string formatting
Snippet48, 282 - crash on image loading
Snippet163, 189, 211, 213, 217, 218, 222 - crash on copy/cut in StyledText
Snippet244 - hang-up
===Tango===
* few changes for the latest Tango trunc-r5661
* few small performance improvments
===General===
* implMissing-s for only one version changed to implMissingInTango/InPhobos
* incorrect calls to Format in toString-s fixed
* fixed loading \uXXXX characters in ResourceBundle
* added good UTF-8 support for StyledText, TextLayout (Win32) and friends
UTF functions revised and tested. It is now in java.nonstandard.*Utf modules
StyledText and TextLayout (Win32) modules revised for UTF-8 support
* removed small diferences in most identical files in *.swt.* folders
*.swt.internal.image, *.swt.events and *.swt.custom are identical in Win32/Linux32
now 179 of 576 (~31%) files in *.swt.* folders are fully identical
* Win32: snippets now have right subsystem, pretty icons and native system style controls
* small fixes in snippets
Snippet44 - it's not Snippet44
Snippet212 - functions work with different images and offsets arrays
Win32: Snippet282 - crash on close if the button has an image
Snippet293 - setGrayed is commented
and others
Win32: As a result, folowing snippets now works
Snippet68 - color doesn't change
Snippet163, 189, 211, 213, 217, 218, 222 - UTF-8 issues (see above)
Snippet193 - no tabel headers
author | Denis Shelomovskij <verylonglogin.reg@gmail.com> |
---|---|
date | Sat, 09 Jul 2011 15:50:20 +0300 |
parents | ddbfe84d86df |
children |
rev | line source |
---|---|
25 | 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 java.lang.all; | |
16 | |
17 import org.eclipse.swt.internal.image.LEDataOutputStream; | |
18 import org.eclipse.swt.internal.image.PngDeflater; | |
19 import java.io.ByteArrayOutputStream; | |
20 import java.io.OutputStream; | |
21 import org.eclipse.swt.SWT; | |
22 import org.eclipse.swt.graphics.ImageData; | |
23 import org.eclipse.swt.graphics.ImageLoader; | |
24 import org.eclipse.swt.graphics.RGB; | |
25 import org.eclipse.swt.internal.Compatibility; | |
26 import org.eclipse.swt.internal.image.PngChunk; | |
27 | |
28 | |
29 final class PngEncoder { | |
30 | |
31 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']; | |
32 static const byte TAG_IHDR[] = [cast(byte) 'I', cast(byte) 'H', cast(byte) 'D', cast(byte) 'R']; | |
33 static const byte TAG_PLTE[] = [cast(byte) 'P', cast(byte) 'L', cast(byte) 'T', cast(byte) 'E']; | |
34 static const byte TAG_TRNS[] = [cast(byte) 't', cast(byte) 'R', cast(byte) 'N', cast(byte) 'S']; | |
35 static const byte TAG_IDAT[] = [cast(byte) 'I', cast(byte) 'D', cast(byte) 'A', cast(byte) 'T']; | |
36 static const byte TAG_IEND[] = [cast(byte) 'I', cast(byte) 'E', cast(byte) 'N', cast(byte) 'D']; | |
37 | |
38 ByteArrayOutputStream bytes; | |
39 PngChunk chunk; | |
40 | |
41 ImageLoader loader; | |
42 ImageData data; | |
43 int transparencyType; | |
44 | |
45 int width, height, bitDepth, colorType; | |
46 | |
47 int compressionMethod = 0; | |
48 int filterMethod = 0; | |
49 int interlaceMethod = 0; | |
50 | |
51 public this(ImageLoader loader) { | |
52 this.bytes = new ByteArrayOutputStream(1024); | |
53 this.loader = loader; | |
54 this.data = loader.data[0]; | |
55 this.transparencyType = data.getTransparencyType(); | |
56 | |
57 this.width = data.width; | |
58 this.height = data.height; | |
59 | |
60 this.bitDepth = 8; | |
61 | |
62 this.colorType = 2; | |
63 | |
64 if (data.palette.isDirect) { | |
65 if (transparencyType is SWT.TRANSPARENCY_ALPHA) { | |
66 this.colorType = 6; | |
67 } | |
68 } | |
69 else { | |
70 this.colorType = 3; | |
71 } | |
72 | |
73 if (!(colorType is 2 || colorType is 3 || colorType is 6)) SWT.error(SWT.ERROR_INVALID_IMAGE); | |
74 | |
75 } | |
76 | |
77 void writeShort(ByteArrayOutputStream baos, int theShort) { | |
78 | |
79 byte byte1 = cast(byte) ((theShort >> 8) & 0xff); | |
80 byte byte2 = cast(byte) (theShort & 0xff); | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
48
diff
changeset
|
81 byte[2] temp = [byte1, byte2]; |
25 | 82 baos.write(temp, 0, 2); |
83 | |
84 } | |
85 | |
86 void writeInt(ByteArrayOutputStream baos, int theInt) { | |
87 | |
88 byte byte1 = cast(byte) ((theInt >> 24) & 0xff); | |
89 byte byte2 = cast(byte) ((theInt >> 16) & 0xff); | |
90 byte byte3 = cast(byte) ((theInt >> 8) & 0xff); | |
91 byte byte4 = cast(byte) (theInt & 0xff); | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
48
diff
changeset
|
92 byte[4] temp = [byte1, byte2, byte3, byte4]; |
25 | 93 baos.write(temp, 0, 4); |
94 | |
95 } | |
96 | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
48
diff
changeset
|
97 void writeChunk(in byte[] tag, in byte[] buffer) { |
25 | 98 |
99 int bufferLength = (buffer !is null) ? buffer.length : 0; | |
100 | |
101 chunk = new PngChunk(bufferLength); | |
102 | |
103 writeInt(bytes, bufferLength); | |
104 bytes.write(tag, 0, 4); | |
105 chunk.setType(tag); | |
106 if (bufferLength !is 0) { | |
107 bytes.write(buffer, 0, bufferLength); | |
108 chunk.setData(buffer); | |
109 } | |
110 else { | |
111 chunk.setCRC(chunk.computeCRC()); | |
112 } | |
113 writeInt(bytes, chunk.getCRC()); | |
114 | |
115 } | |
116 | |
117 void writeSignature() { | |
118 | |
119 bytes.write(SIGNATURE, 0, 8); | |
120 | |
121 } | |
122 | |
123 void writeHeader() { | |
124 | |
125 ByteArrayOutputStream baos = new ByteArrayOutputStream(13); | |
126 | |
127 writeInt(baos, width); | |
128 writeInt(baos, height); | |
129 baos.write(bitDepth); | |
130 baos.write(colorType); | |
131 baos.write(compressionMethod); | |
132 baos.write(filterMethod); | |
133 baos.write(interlaceMethod); | |
134 | |
135 writeChunk(TAG_IHDR, baos.toByteArray()); | |
136 | |
137 } | |
138 | |
139 void writePalette() { | |
140 | |
141 RGB[] RGBs = data.palette.getRGBs(); | |
142 | |
143 if (RGBs.length > 256) SWT.error(SWT.ERROR_INVALID_IMAGE); | |
144 | |
145 ByteArrayOutputStream baos = new ByteArrayOutputStream(RGBs.length); | |
146 | |
147 for (int i = 0; i < RGBs.length; i++) { | |
148 | |
149 baos.write(cast(byte) RGBs[i].red); | |
150 baos.write(cast(byte) RGBs[i].green); | |
151 baos.write(cast(byte) RGBs[i].blue); | |
152 | |
153 } | |
154 | |
155 writeChunk(TAG_PLTE, baos.toByteArray()); | |
156 | |
157 } | |
158 | |
159 void writeTransparency() { | |
160 | |
161 ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
162 | |
163 switch (transparencyType) { | |
164 | |
165 case SWT.TRANSPARENCY_ALPHA: | |
166 | |
167 int pixelValue, alphaValue; | |
168 | |
169 byte[] alphas = new byte[data.palette.getRGBs().length]; | |
170 | |
171 for (int y = 0; y < height; y++) { | |
172 | |
173 for (int x = 0; x < width; x++) { | |
174 | |
175 pixelValue = data.getPixel(x, y); | |
176 alphaValue = data.getAlpha(x, y); | |
177 | |
178 alphas[pixelValue] = cast(byte) alphaValue; | |
179 | |
180 } | |
181 | |
182 } | |
183 | |
184 baos.write(alphas, 0, alphas.length); | |
185 | |
186 break; | |
187 | |
188 case SWT.TRANSPARENCY_PIXEL: | |
189 | |
190 int pixel = data.transparentPixel; | |
191 | |
192 if (colorType is 2) { | |
193 | |
194 int redMask = data.palette.redMask; | |
195 int redShift = data.palette.redShift; | |
196 int greenMask = data.palette.greenMask; | |
197 int greenShift = data.palette.greenShift; | |
198 int blueShift = data.palette.blueShift; | |
199 int blueMask = data.palette.blueMask; | |
200 | |
201 int r = pixel & redMask; | |
202 r = (redShift < 0) ? r >>> -redShift : r << redShift; | |
203 int g = pixel & greenMask; | |
204 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift; | |
205 int b = pixel & blueMask; | |
206 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift; | |
207 | |
208 writeShort(baos, r); | |
209 writeShort(baos, g); | |
210 writeShort(baos, b); | |
211 | |
212 } | |
213 | |
214 if (colorType is 3) { | |
215 | |
216 byte[] padding = new byte[pixel + 1]; | |
217 | |
218 for (int i = 0; i < pixel; i++) { | |
219 | |
220 padding[i] = cast(byte) 255; | |
221 | |
222 } | |
223 | |
224 padding[pixel] = cast(byte) 0; | |
225 | |
226 baos.write(padding, 0, padding.length); | |
227 | |
228 } | |
229 | |
230 break; | |
231 default: | |
232 | |
233 } | |
234 | |
235 writeChunk(TAG_TRNS, baos.toByteArray()); | |
236 | |
237 } | |
238 | |
239 void writeImageData() { | |
240 | |
241 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); | |
242 OutputStream os = Compatibility.newDeflaterOutputStream(baos); | |
243 if (os is null) os = baos; | |
244 | |
245 if (colorType is 3) { | |
246 | |
247 byte[] lineData = new byte[width]; | |
248 | |
249 for (int y = 0; y < height; y++) { | |
250 | |
251 int filter = 0; | |
252 os.write(filter); | |
253 | |
254 data.getPixels(0, y, width, lineData, 0); | |
255 | |
256 for (int x = 0; x < lineData.length; x++) { | |
257 | |
258 os.write(lineData[x]); | |
259 | |
260 } | |
261 | |
262 } | |
263 | |
264 } | |
265 | |
266 else { | |
267 | |
268 int[] lineData = new int[width]; | |
269 byte[] alphaData = null; | |
270 if (colorType is 6) { | |
271 alphaData = new byte[width]; | |
272 } | |
273 | |
274 int redMask = data.palette.redMask; | |
275 int redShift = data.palette.redShift; | |
276 int greenMask = data.palette.greenMask; | |
277 int greenShift = data.palette.greenShift; | |
278 int blueShift = data.palette.blueShift; | |
279 int blueMask = data.palette.blueMask; | |
280 | |
281 for (int y = 0; y < height; y++) { | |
282 | |
283 int filter = 0; | |
284 os.write(filter); | |
285 | |
286 data.getPixels(0, y, width, lineData, 0); | |
287 | |
288 if (colorType is 6) { | |
289 data.getAlphas(0, y, width, alphaData, 0); | |
290 } | |
291 | |
292 for (int x = 0; x < lineData.length; x++) { | |
293 | |
294 int pixel = lineData[x]; | |
295 | |
296 int r = pixel & redMask; | |
297 r = (redShift < 0) ? r >>> -redShift : r << redShift; | |
298 int g = pixel & greenMask; | |
299 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift; | |
300 int b = pixel & blueMask; | |
301 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift; | |
302 | |
303 os.write(r); | |
304 os.write(g); | |
305 os.write(b); | |
306 | |
307 if (colorType is 6) { | |
308 os.write(alphaData[x]); | |
309 } | |
310 | |
311 } | |
312 | |
313 } | |
314 | |
315 } | |
316 | |
317 os.flush(); | |
318 os.close(); | |
319 | |
320 byte[] compressed = baos.toByteArray(); | |
321 if (os is baos) { | |
322 PngDeflater deflater = new PngDeflater(); | |
323 compressed = deflater.deflate(compressed); | |
324 } | |
325 | |
326 writeChunk(TAG_IDAT, compressed); | |
327 | |
328 } | |
329 | |
330 void writeEnd() { | |
331 | |
332 writeChunk(TAG_IEND, null); | |
333 | |
334 } | |
335 | |
336 public void encode(LEDataOutputStream outputStream) { | |
337 | |
338 try { | |
339 | |
340 writeSignature(); | |
341 writeHeader(); | |
342 | |
343 if (colorType is 3) { | |
344 writePalette(); | |
345 } | |
346 | |
347 bool transparencyAlpha = (transparencyType is SWT.TRANSPARENCY_ALPHA); | |
348 bool transparencyPixel = (transparencyType is SWT.TRANSPARENCY_PIXEL); | |
349 bool type2Transparency = (colorType is 2 && transparencyPixel); | |
350 bool type3Transparency = (colorType is 3 && (transparencyAlpha || transparencyPixel)); | |
351 | |
352 if (type2Transparency || type3Transparency) { | |
353 writeTransparency(); | |
354 } | |
355 | |
356 writeImageData(); | |
357 writeEnd(); | |
358 | |
359 outputStream.write(bytes.toByteArray()); | |
360 | |
361 } | |
362 | |
363 catch (IOException e) { | |
364 | |
365 SWT.error(SWT.ERROR_IO, e); | |
366 | |
367 } | |
368 | |
369 } | |
370 | |
371 } |