KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > internal > image > PngEncoder


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  *******************************************************************************/

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