KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)WBMPImageReader.java 1.10 03/12/19 16:54:40
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.Rectangle JavaDoc;
11 import java.awt.image.BufferedImage JavaDoc;
12 import java.awt.image.DataBufferByte JavaDoc;
13 import java.awt.image.MultiPixelPackedSampleModel JavaDoc;
14 import java.awt.image.Raster JavaDoc;
15 import java.awt.image.WritableRaster JavaDoc;
16
17 import javax.imageio.IIOException JavaDoc;
18 import javax.imageio.ImageReader JavaDoc;
19 import javax.imageio.ImageReadParam JavaDoc;
20 import javax.imageio.ImageTypeSpecifier JavaDoc;
21 import javax.imageio.metadata.IIOMetadata JavaDoc;
22 import javax.imageio.spi.ImageReaderSpi JavaDoc;
23 import javax.imageio.stream.ImageInputStream JavaDoc;
24
25 import java.io.*;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Iterator JavaDoc;
28
29 import com.sun.imageio.plugins.common.I18N;
30
31 /** This class is the Java Image IO plugin reader for WBMP images.
32  * It may subsample the image, clip the image,
33  * and shift the decoded image origin if the proper decoding parameter
34  * are set in the provided <code>WBMPImageReadParam</code>.
35  */

36 public class WBMPImageReader extends ImageReader JavaDoc {
37     /** The input stream where reads from */
38     private ImageInputStream JavaDoc iis = null;
39
40     /** Indicates whether the header is read. */
41     private boolean gotHeader = false;
42
43     /** The original image width. */
44     private int width;
45
46     /** The original image height. */
47     private int height;
48
49     private int wbmpType;
50     
51     private WBMPMetadata metadata;
52
53     /** Constructs <code>WBMPImageReader</code> from the provided
54      * <code>ImageReaderSpi</code>.
55      */

56     public WBMPImageReader(ImageReaderSpi JavaDoc originator) {
57         super(originator);
58     }
59
60     /** Overrides the method defined in the superclass. */
61     public void setInput(Object JavaDoc input,
62                          boolean seekForwardOnly,
63                          boolean ignoreMetadata) {
64         super.setInput(input, seekForwardOnly, ignoreMetadata);
65         iis = (ImageInputStream JavaDoc) input; // Always works
66
gotHeader = false;
67     }
68
69     /** Overrides the method defined in the superclass. */
70     public int getNumImages(boolean allowSearch) throws IOException JavaDoc {
71         if (iis == null) {
72             throw new IllegalStateException JavaDoc(I18N.getString("GetNumImages0"));
73         }
74         if (seekForwardOnly && allowSearch) {
75             throw new IllegalStateException JavaDoc(I18N.getString("GetNumImages1"));
76         }
77         return 1;
78     }
79
80     public int getWidth(int imageIndex) throws IOException JavaDoc {
81         checkIndex(imageIndex);
82         readHeader();
83         return width;
84     }
85
86     public int getHeight(int imageIndex) throws IOException JavaDoc {
87         checkIndex(imageIndex);
88         readHeader();
89         return height;
90     }
91
92     public boolean isRandomAccessEasy(int imageIndex) throws IOException JavaDoc {
93         checkIndex(imageIndex);
94         return true;
95     }
96
97     private void checkIndex(int imageIndex) {
98         if (imageIndex != 0) {
99             throw new IndexOutOfBoundsException JavaDoc(I18N.getString("WBMPImageReader0"));
100         }
101     }
102
103     public void readHeader() throws IOException JavaDoc {
104         if (gotHeader)
105             return;
106
107         if (iis == null) {
108             throw new IllegalStateException JavaDoc("Input source not set!");
109         }
110
111         metadata = new WBMPMetadata();
112         
113         wbmpType = iis.readByte(); // TypeField
114
byte fixHeaderField = iis.readByte();
115
116         // check for valid wbmp image
117
if (fixHeaderField != 0
118             || !isValidWbmpType(wbmpType))
119         {
120             throw new IIOException JavaDoc(I18N.getString("WBMPImageReader2"));
121         }
122
123         metadata.wbmpType = wbmpType;
124         
125         // Read image width
126
width = readMultiByteInteger();
127         metadata.width = width;
128         
129         // Read image height
130
height = readMultiByteInteger();
131         metadata.height = height;
132         
133         gotHeader = true;
134     }
135
136     public Iterator JavaDoc getImageTypes(int imageIndex)
137         throws IOException JavaDoc {
138         checkIndex(imageIndex);
139         readHeader();
140
141         BufferedImage JavaDoc bi =
142             new BufferedImage JavaDoc(1, 1, BufferedImage.TYPE_BYTE_BINARY);
143         ArrayList JavaDoc list = new ArrayList JavaDoc(1);
144         list.add(new ImageTypeSpecifier JavaDoc(bi));
145         return list.iterator();
146     }
147
148     public ImageReadParam JavaDoc getDefaultReadParam() {
149         return new ImageReadParam JavaDoc();
150     }
151
152     public IIOMetadata JavaDoc getImageMetadata(int imageIndex)
153         throws IOException JavaDoc {
154         checkIndex(imageIndex);
155         if (metadata == null) {
156             readHeader();
157         }
158         return metadata;
159     }
160
161     public IIOMetadata JavaDoc getStreamMetadata() throws IOException JavaDoc {
162         return null;
163     }
164
165     public BufferedImage JavaDoc read(int imageIndex, ImageReadParam JavaDoc param)
166         throws IOException JavaDoc {
167
168         if (iis == null) {
169             throw new IllegalStateException JavaDoc(I18N.getString("WBMPImageReader1"));
170         }
171
172         checkIndex(imageIndex);
173         clearAbortRequest();
174         processImageStarted(imageIndex);
175         if (param == null)
176             param = getDefaultReadParam();
177
178         //read header
179
readHeader();
180
181         Rectangle JavaDoc sourceRegion = new Rectangle JavaDoc(0, 0, 0, 0);
182         Rectangle JavaDoc destinationRegion = new Rectangle JavaDoc(0, 0, 0, 0);
183
184         computeRegions(param, this.width, this.height,
185                        param.getDestination(),
186                        sourceRegion,
187                        destinationRegion);
188
189         int scaleX = param.getSourceXSubsampling();
190         int scaleY = param.getSourceYSubsampling();
191         int xOffset = param.getSubsamplingXOffset();
192         int yOffset = param.getSubsamplingYOffset();
193
194         // If the destination is provided, then use it. Otherwise, create new one
195
BufferedImage JavaDoc bi = param.getDestination();
196
197         if (bi == null)
198             bi = new BufferedImage JavaDoc(destinationRegion.x + destinationRegion.width,
199                               destinationRegion.y + destinationRegion.height,
200                               BufferedImage.TYPE_BYTE_BINARY);
201
202         boolean noTransform =
203             destinationRegion.equals(new Rectangle JavaDoc(0, 0, width, height)) &&
204             destinationRegion.equals(new Rectangle JavaDoc(0, 0, bi.getWidth(), bi.getHeight()));
205         
206         // Get the image data.
207
WritableRaster JavaDoc tile = bi.getWritableTile(0, 0);
208
209         // Get the SampleModel.
210
MultiPixelPackedSampleModel JavaDoc sm =
211             (MultiPixelPackedSampleModel JavaDoc)bi.getSampleModel();
212
213         if (noTransform) {
214             if (abortRequested()) {
215                 processReadAborted();
216                 return bi;
217             }
218
219             // If noTransform is necessary, read the data.
220
iis.read(((DataBufferByte JavaDoc)tile.getDataBuffer()).getData(),
221                      0, height*sm.getScanlineStride());
222             processImageUpdate(bi,
223                                0, 0,
224                                width, height, 1, 1,
225                                new int[]{0});
226             processImageProgress(100.0F);
227         } else {
228             int len = (this.width + 7) / 8;
229             byte[] buf = new byte[len];
230             byte[] data = ((DataBufferByte JavaDoc)tile.getDataBuffer()).getData();
231             int lineStride = sm.getScanlineStride();
232             iis.skipBytes(len * sourceRegion.y);
233             int skipLength = len * (scaleY - 1);
234
235             // cache the values to avoid duplicated computation
236
int[] srcOff = new int[destinationRegion.width];
237             int[] destOff = new int[destinationRegion.width];
238             int[] srcPos = new int[destinationRegion.width];
239             int[] destPos = new int[destinationRegion.width];
240
241             for (int i = destinationRegion.x, x = sourceRegion.x, j = 0;
242                 i < destinationRegion.x + destinationRegion.width;
243                     i++, j++, x += scaleX) {
244                 srcPos[j] = x >> 3;
245                 srcOff[j] = 7 - (x & 7);
246                 destPos[j] = i >> 3;
247                 destOff[j] = 7 - (i & 7);
248             }
249
250             for (int j = 0, y = sourceRegion.y,
251                 k = destinationRegion.y * lineStride;
252                 j < destinationRegion.height; j++, y+=scaleY) {
253
254                 if (abortRequested())
255                     break;
256                 iis.read(buf, 0, len);
257                 for (int i = 0; i < destinationRegion.width; i++) {
258                     //get the bit and assign to the data buffer of the raster
259
int v = (buf[srcPos[i]] >> srcOff[i]) & 1;
260                     data[k + destPos[i]] |= v << destOff[i];
261                 }
262
263                 k += lineStride;
264                 iis.skipBytes(skipLength);
265                         processImageUpdate(bi,
266                                            0, j,
267                                            destinationRegion.width, 1, 1, 1,
268                                            new int[]{0});
269                         processImageProgress(100.0F*j/destinationRegion.height);
270             }
271         }
272
273         if (abortRequested())
274             processReadAborted();
275         else
276             processImageComplete();
277         return bi;
278     }
279
280     public boolean canReadRaster() {
281         return true;
282     }
283
284     public Raster JavaDoc readRaster(int imageIndex,
285                              ImageReadParam JavaDoc param) throws IOException JavaDoc {
286         BufferedImage JavaDoc bi = read(imageIndex, param);
287         return bi.getData();
288     }
289
290     public void reset() {
291         super.reset();
292         iis = null;
293         gotHeader = false;
294     }
295
296     private int readMultiByteInteger() throws IOException JavaDoc {
297         int value = iis.readByte();
298         int result = value & 0x7f;
299         while((value & 0x80) == 0x80) {
300             result <<= 7;
301             value = iis.readByte();
302             result |= (value & 0x7f);
303         }
304         return result;
305     }
306     
307     /*
308      * This method verifies that given byte is valid wbmp type marker.
309      * At the moment only 0x0 marker is described by wbmp spec.
310      */

311     boolean isValidWbmpType(int type) {
312         return type == 0;
313     }
314 }
315
Popular Tags