1/** 2 * Copyright (c) 2015, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24package simp; 25 26import java.awt.image.BufferedImage; 27import java.io.IOException; 28import java.util.ArrayList; 29import java.util.Iterator; 30import javax.imageio.IIOException; 31import javax.imageio.ImageReadParam; 32import javax.imageio.ImageReader; 33import javax.imageio.ImageTypeSpecifier; 34import javax.imageio.metadata.IIOMetadata; 35import javax.imageio.spi.ImageReaderSpi; 36import javax.imageio.stream.ImageInputStream; 37 38/** 39 * A simple image format which has no compression and is a 40 * header with bytes 'SIMP', two signed bytes for width and height, 41 * and then unpadded 3 byte per pixel data representing RGB assumed 42 * to be in sRGB. The signed byte implies a maximum size of 127x127 pixels. 43 * Trailing data is ignored but there must be at least 44 * 3*width*height bytes of data following the simple 6 byte header. 45 */ 46public class SIMPImageReader extends ImageReader { 47 48 private ImageInputStream stream = null; 49 private byte width = -1, height = -1; 50 SIMPMetadata metadata = null; 51 byte[] imageData = null; 52 53 public SIMPImageReader(ImageReaderSpi originatingProvider) { 54 super(originatingProvider); 55 } 56 57 public void setInput(Object input, 58 boolean seekForwardOnly, 59 boolean ignoreMetadata) { 60 super.setInput(input, seekForwardOnly, ignoreMetadata); 61 stream = (ImageInputStream) input; 62 } 63 64 private void checkState(int imageIndex) throws IOException { 65 if (stream == null) { 66 throw new IllegalStateException("input not set."); 67 } 68 if (imageIndex != 0) { 69 throw new IndexOutOfBoundsException("index != 0"); 70 } 71 if (width==-1) { 72 byte[] sig = new byte[4]; 73 stream.reset(); 74 stream.read(sig); 75 boolean ok = sig[0]=='S' && sig[1]=='I' && 76 sig[2]=='M' && sig[3]=='P'; 77 if (!ok) { 78 throw new IIOException("Not a SIMP image"); 79 } 80 width = stream.readByte(); 81 height = stream.readByte(); 82 } 83 if (width <= 0 || height <= 0) { 84 throw new IOException("bad image size"); 85 } 86 metadata = new SIMPMetadata(width, height); 87 } 88 89 public int getWidth(int imageIndex) throws IOException { 90 checkState(imageIndex); 91 return width; 92 } 93 94 public int getHeight(int imageIndex) throws IOException { 95 checkState(imageIndex); 96 return height; 97 } 98 99 public int getNumImages(boolean allowSearch) throws IOException { 100 checkState(0); 101 return 1; 102 } 103 104 public IIOMetadata getStreamMetadata() throws IOException { 105 return null; 106 } 107 108 public IIOMetadata getImageMetadata(int imageIndex) throws IOException { 109 checkState(imageIndex); 110 return metadata; 111 } 112 113 public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) 114 throws IOException { 115 116 checkState(imageIndex); 117 BufferedImage bi = 118 new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); 119 ArrayList<ImageTypeSpecifier> list = new ArrayList<>(1); 120 list.add(new ImageTypeSpecifier(bi)); 121 return list.iterator(); 122 } 123 124 public BufferedImage read(int imageIndex, ImageReadParam param) 125 throws IOException { 126 checkState(imageIndex); 127 int len = 3*width*height; 128 byte[] imageData = new byte[len]; 129 // The following is not efficient and is skipping all the 130 // progress updates, and ignoring the ImageReadParam, which 131 // it should not, but it is all we need for this test. 132 stream.readFully(imageData, 0, len); 133 BufferedImage bi = 134 new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 135 int off = 0; 136 for (int h=0;h<height;h++) { 137 int rgb = imageData[off]++ << 16 | 138 imageData[off++] << 8 | imageData[off++]; 139 for (int w=0;w<width;w++) { 140 bi.setRGB(w, h, rgb); 141 } 142 } 143 return bi; 144 } 145} 146