1 /*
2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.imageio.plugins.wbmp;
27 
28 import java.util.Locale;
29 import javax.imageio.spi.ImageReaderSpi;
30 import javax.imageio.stream.ImageInputStream;
31 import javax.imageio.spi.IIORegistry;
32 import javax.imageio.spi.ServiceRegistry;
33 import java.io.IOException;
34 import javax.imageio.ImageReader;
35 import javax.imageio.IIOException;
36 import com.sun.imageio.plugins.common.ReaderUtil;
37 
38 public class WBMPImageReaderSpi extends ImageReaderSpi {
39 
40     private static final int MAX_WBMP_WIDTH = 1024;
41     private static final int MAX_WBMP_HEIGHT = 768;
42 
43     private static String [] writerSpiNames =
44         {"com.sun.imageio.plugins.wbmp.WBMPImageWriterSpi"};
45     private static String[] formatNames = {"wbmp", "WBMP"};
46     private static String[] entensions = {"wbmp"};
47     private static String[] mimeType = {"image/vnd.wap.wbmp"};
48 
49     private boolean registered = false;
50 
WBMPImageReaderSpi()51     public WBMPImageReaderSpi() {
52         super("Oracle Corporation",
53               "1.0",
54               formatNames,
55               entensions,
56               mimeType,
57               "com.sun.imageio.plugins.wbmp.WBMPImageReader",
58               new Class<?>[] { ImageInputStream.class },
59               writerSpiNames,
60               true,
61               null, null, null, null,
62               true,
63               WBMPMetadata.nativeMetadataFormatName,
64               "com.sun.imageio.plugins.wbmp.WBMPMetadataFormat",
65               null, null);
66     }
67 
onRegistration(ServiceRegistry registry, Class<?> category)68     public void onRegistration(ServiceRegistry registry,
69                                Class<?> category) {
70         if (registered) {
71             return;
72         }
73         registered = true;
74     }
75 
getDescription(Locale locale)76     public String getDescription(Locale locale) {
77         return "Standard WBMP Image Reader";
78     }
79 
canDecodeInput(Object source)80     public boolean canDecodeInput(Object source) throws IOException {
81         if (!(source instanceof ImageInputStream)) {
82             return false;
83         }
84 
85         ImageInputStream stream = (ImageInputStream)source;
86 
87         stream.mark();
88         try {
89             int type = stream.readByte();   // TypeField
90             int fixHeaderField = stream.readByte();
91             // check WBMP "header"
92             if (type != 0 || fixHeaderField != 0) {
93                 // while WBMP reader does not support ext WBMP headers
94                 return false;
95             }
96 
97             int width = ReaderUtil.readMultiByteInteger(stream);
98             int height = ReaderUtil.readMultiByteInteger(stream);
99             // check image dimension
100             if (width <= 0 || height <= 0) {
101                 return false;
102             }
103 
104             long dataLength = stream.length();
105             if (dataLength == -1) {
106                 // We can't verify that amount of data in the stream
107                 // corresponds to image dimension because we do not know
108                 // the length of the data stream.
109                 // Assuming that wbmp image are used for mobile devices,
110                 // let's introduce an upper limit for image dimension.
111                 // In case if exact amount of raster data is unknown,
112                 // let's reject images with dimension above the limit.
113                 return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT);
114             }
115 
116             dataLength -= stream.getStreamPosition();
117 
118             long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1);
119 
120             return (dataLength == scanSize * height);
121         } finally {
122             stream.reset();
123         }
124     }
125 
createReaderInstance(Object extension)126     public ImageReader createReaderInstance(Object extension)
127         throws IIOException {
128         return new WBMPImageReader(this);
129     }
130 }
131