KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > imageio > plugins > wbmp > WBMPImageWriter


1 /*
2  * @(#)WBMPImageWriter.java 1.3 03/09/20 21:28:34
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.imageio.plugins.wbmp;
9
10 import java.awt.Point JavaDoc;
11 import java.awt.Rectangle JavaDoc;
12 import java.awt.image.ColorModel JavaDoc;
13 import java.awt.image.DataBuffer JavaDoc;
14 import java.awt.image.DataBufferByte JavaDoc;
15 import java.awt.image.IndexColorModel JavaDoc;
16 import java.awt.image.MultiPixelPackedSampleModel JavaDoc;
17 import java.awt.image.Raster JavaDoc;
18 import java.awt.image.RenderedImage JavaDoc;
19 import java.awt.image.SampleModel JavaDoc;
20 import java.awt.image.WritableRaster JavaDoc;
21
22 import java.io.IOException JavaDoc;
23
24 import javax.imageio.IIOImage JavaDoc;
25 import javax.imageio.IIOException JavaDoc;
26 import javax.imageio.ImageTypeSpecifier JavaDoc;
27 import javax.imageio.ImageWriteParam JavaDoc;
28 import javax.imageio.ImageWriter JavaDoc;
29 import javax.imageio.metadata.IIOMetadata JavaDoc;
30 import javax.imageio.metadata.IIOMetadataFormatImpl JavaDoc;
31 import javax.imageio.metadata.IIOInvalidTreeException JavaDoc;
32 import javax.imageio.spi.ImageWriterSpi JavaDoc;
33 import javax.imageio.stream.ImageOutputStream JavaDoc;
34
35 import com.sun.imageio.plugins.common.I18N;
36
37 /**
38  * The Java Image IO plugin writer for encoding a binary RenderedImage into
39  * a WBMP format.
40  *
41  * The encoding process may clip, subsample using the parameters
42  * specified in the <code>ImageWriteParam</code>.
43  *
44  * @see com.sun.media.imageio.plugins.WBMPImageWriteParam
45  */

46 public class WBMPImageWriter extends ImageWriter JavaDoc {
47     /** The output stream to write into */
48     private ImageOutputStream JavaDoc stream = null;
49
50     // Get the number of bits required to represent an int.
51
private static int getNumBits(int intValue) {
52         int numBits = 32;
53         int mask = 0x80000000;
54         while(mask != 0 && (intValue & mask) == 0) {
55             numBits--;
56             mask >>>= 1;
57         }
58         return numBits;
59     }
60
61     // Convert an int value to WBMP multi-byte format.
62
private static byte[] intToMultiByte(int intValue) {
63         int numBitsLeft = getNumBits(intValue);
64         byte[] multiBytes = new byte[(numBitsLeft + 6)/7];
65
66         int maxIndex = multiBytes.length - 1;
67         for(int b = 0; b <= maxIndex; b++) {
68             multiBytes[b] = (byte)((intValue >>> ((maxIndex - b)*7))&0x7f);
69             if(b != maxIndex) {
70                 multiBytes[b] |= (byte)0x80;
71             }
72         }
73
74         return multiBytes;
75     }
76
77     /** Constructs <code>WBMPImageWriter</code> based on the provided
78      * <code>ImageWriterSpi</code>.
79      */

80     public WBMPImageWriter(ImageWriterSpi JavaDoc originator) {
81         super(originator);
82     }
83
84     public void setOutput(Object JavaDoc output) {
85         super.setOutput(output); // validates output
86
if (output != null) {
87             if (!(output instanceof ImageOutputStream JavaDoc))
88                 throw new IllegalArgumentException JavaDoc(I18N.getString("WBMPImageWriter"));
89             this.stream = (ImageOutputStream JavaDoc)output;
90         } else
91             this.stream = null;
92     }
93
94     public IIOMetadata JavaDoc getDefaultStreamMetadata(ImageWriteParam JavaDoc param) {
95         return null;
96     }
97
98     public IIOMetadata JavaDoc getDefaultImageMetadata(ImageTypeSpecifier JavaDoc imageType,
99                                                ImageWriteParam JavaDoc param) {
100         WBMPMetadata meta = new WBMPMetadata();
101         meta.wbmpType = 0; // default wbmp level
102
return meta;
103     }
104
105     public IIOMetadata JavaDoc convertStreamMetadata(IIOMetadata JavaDoc inData,
106                                              ImageWriteParam JavaDoc param) {
107         return null;
108     }
109
110     public IIOMetadata JavaDoc convertImageMetadata(IIOMetadata JavaDoc metadata,
111                                             ImageTypeSpecifier JavaDoc type,
112                                             ImageWriteParam JavaDoc param) {
113         return null;
114     }
115
116     public boolean canWriteRasters() {
117         return true;
118     }
119
120     public void write(IIOMetadata JavaDoc streamMetadata,
121                       IIOImage JavaDoc image,
122                       ImageWriteParam JavaDoc param) throws IOException JavaDoc {
123
124         if (stream == null) {
125             throw new IllegalStateException JavaDoc(I18N.getString("WBMPImageWriter3"));
126         }
127
128         if (image == null) {
129             throw new IllegalArgumentException JavaDoc(I18N.getString("WBMPImageWriter4"));
130         }
131
132         clearAbortRequest();
133         processImageStarted(0);
134         if (param == null)
135             param = getDefaultWriteParam();
136
137         RenderedImage JavaDoc input = null;
138         Raster JavaDoc inputRaster = null;
139         boolean writeRaster = image.hasRaster();
140         Rectangle JavaDoc sourceRegion = param.getSourceRegion();
141         SampleModel JavaDoc sampleModel = null;
142
143         if (writeRaster) {
144             inputRaster = image.getRaster();
145             sampleModel = inputRaster.getSampleModel();
146         } else {
147             input = image.getRenderedImage();
148             sampleModel = input.getSampleModel();
149
150             inputRaster = input.getData();
151         }
152
153         checkSampleModel(sampleModel);
154         if (sourceRegion == null)
155             sourceRegion = inputRaster.getBounds();
156         else
157             sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
158
159         if (sourceRegion.isEmpty())
160             throw new RuntimeException JavaDoc(I18N.getString("WBMPImageWriter1"));
161
162         int scaleX = param.getSourceXSubsampling();
163         int scaleY = param.getSourceYSubsampling();
164         int xOffset = param.getSubsamplingXOffset();
165         int yOffset = param.getSubsamplingYOffset();
166
167         sourceRegion.translate(xOffset, yOffset);
168         sourceRegion.width -= xOffset;
169         sourceRegion.height -= yOffset;
170
171         int minX = sourceRegion.x / scaleX;
172         int minY = sourceRegion.y / scaleY;
173         int w = (sourceRegion.width + scaleX - 1) / scaleX;
174         int h = (sourceRegion.height + scaleY - 1) / scaleY;
175
176         Rectangle JavaDoc destinationRegion = new Rectangle JavaDoc(minX, minY, w, h);
177         sampleModel = sampleModel.createCompatibleSampleModel(w, h);
178
179         SampleModel JavaDoc destSM= sampleModel;
180
181         // If the data are not formatted nominally then reformat.
182
if(sampleModel.getDataType() != DataBuffer.TYPE_BYTE ||
183            !(sampleModel instanceof MultiPixelPackedSampleModel JavaDoc) ||
184            ((MultiPixelPackedSampleModel JavaDoc)sampleModel).getDataBitOffset() != 0) {
185            destSM =
186                 new MultiPixelPackedSampleModel JavaDoc(DataBuffer.TYPE_BYTE,
187                                                 w, h, 1,
188                                                 w + 7 >> 3, 0);
189         }
190
191         if (!destinationRegion.equals(sourceRegion)) {
192             if (scaleX == 1 && scaleY == 1)
193                 inputRaster = inputRaster.createChild(inputRaster.getMinX(),
194                                                       inputRaster.getMinY(),
195                                                       w, h, minX, minY, null);
196             else {
197                 WritableRaster JavaDoc ras = Raster.createWritableRaster(destSM,
198                                                                  new Point JavaDoc(minX, minY));
199
200                 byte[] data = ((DataBufferByte JavaDoc)ras.getDataBuffer()).getData();
201
202                 for(int j = minY, y = sourceRegion.y, k = 0;
203                     j < minY + h; j++, y += scaleY) {
204
205                     for (int i = 0, x = sourceRegion.x;
206                         i <w; i++, x +=scaleX) {
207                         int v = inputRaster.getSample(x, y, 0);
208                         data[k + (i >> 3)] |= v << (7 - (i & 7));
209                     }
210                     k += w + 7 >> 3;
211                 }
212                 inputRaster = ras;
213             }
214         }
215
216         // If the data are not formatted nominally then reformat.
217
if(!destSM.equals(inputRaster.getSampleModel())) {
218             WritableRaster JavaDoc raster =
219                 Raster.createWritableRaster(destSM,
220                                             new Point JavaDoc(inputRaster.getMinX(),
221                                                       inputRaster.getMinY()));
222             raster.setRect(inputRaster);
223             inputRaster = raster;
224         }
225
226         // Check whether the image is white-is-zero.
227
boolean isWhiteZero = false;
228         if(!writeRaster && input.getColorModel() instanceof IndexColorModel JavaDoc) {
229             IndexColorModel JavaDoc icm = (IndexColorModel JavaDoc)input.getColorModel();
230             isWhiteZero = icm.getRed(0) > icm.getRed(1);
231         }
232
233         // Get the line stride, bytes per row, and data array.
234
int lineStride =
235             ((MultiPixelPackedSampleModel JavaDoc)destSM).getScanlineStride();
236         int bytesPerRow = (w + 7)/8;
237         byte[] bdata = ((DataBufferByte JavaDoc)inputRaster.getDataBuffer()).getData();
238
239         // Write WBMP header.
240
stream.write(0); // TypeField
241
stream.write(0); // FixHeaderField
242
stream.write(intToMultiByte(w)); // width
243
stream.write(intToMultiByte(h)); // height
244

245         // Write the data.
246
if(!isWhiteZero && lineStride == bytesPerRow) {
247             // Write the entire image.
248
stream.write(bdata, 0, h * bytesPerRow);
249             processImageProgress(100.0F);
250         } else {
251             // Write the image row-by-row.
252
int offset = 0;
253             if(!isWhiteZero) {
254                 // Black-is-zero
255
for(int row = 0; row < h; row++) {
256                     if (abortRequested())
257                         break;
258                     stream.write(bdata, offset, bytesPerRow);
259                     offset += lineStride;
260                     processImageProgress(100.0F * row / h);
261                 }
262             } else {
263                 // White-is-zero: need to invert data.
264
byte[] inverted = new byte[bytesPerRow];
265                 for(int row = 0; row < h; row++) {
266                     if (abortRequested())
267                         break;
268                     for(int col = 0; col < bytesPerRow; col++) {
269                         inverted[col] = (byte)(~(bdata[col+offset]));
270                     }
271                     stream.write(inverted, 0, bytesPerRow);
272                     offset += lineStride;
273                     processImageProgress(100.0F * row / h);
274                 }
275             }
276         }
277
278         if (abortRequested())
279             processWriteAborted();
280         else {
281             processImageComplete();
282             stream.flushBefore(stream.getStreamPosition());
283         }
284     }
285
286     public void reset() {
287         super.reset();
288         stream = null;
289     }
290
291     private void checkSampleModel(SampleModel JavaDoc sm) {
292         int type = sm.getDataType();
293         if (type < DataBuffer.TYPE_BYTE || type > DataBuffer.TYPE_INT
294         || sm.getNumBands() != 1 || sm.getSampleSize(0) != 1)
295             throw new IllegalArgumentException JavaDoc(I18N.getString("WBMPImageWriter2"));
296     }
297 }
298
Popular Tags