diff options
Diffstat (limited to 'libjava/classpath/gnu/javax/imageio')
14 files changed, 1707 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPDecoder.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPDecoder.java new file mode 100644 index 00000000000..c4a582bfa20 --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPDecoder.java @@ -0,0 +1,169 @@ +/* BMPDecoder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.BufferedImage; + +public abstract class BMPDecoder { + + protected BMPInfoHeader infoHeader; + protected BMPFileHeader fileHeader; + protected long offset; + + public BMPDecoder(BMPFileHeader fh, BMPInfoHeader ih){ + fileHeader = fh; + infoHeader = ih; + offset = BMPFileHeader.SIZE + BMPInfoHeader.SIZE; + } + + /** + * Determines the coding type of the bitmap and returns the corresponding + * decoder. + */ + public static BMPDecoder getDecoder(BMPFileHeader fh, BMPInfoHeader ih){ + switch(ih.getCompression()){ + case BMPInfoHeader.BI_RGB: // uncompressed RGB + switch(ih.getBitCount()){ + case 32: + return new DecodeBF32(fh, ih, true); + + case 24: + return new DecodeRGB24(fh, ih); + + case 16: + return new DecodeBF16(fh, ih, true); + + case 8: + return new DecodeRGB8(fh, ih); + + case 4: + return new DecodeRGB4(fh, ih); + + case 1: + return new DecodeRGB1(fh, ih); + + default: + return null; + } + + case BMPInfoHeader.BI_RLE8: + return new DecodeRLE8(fh, ih); + + case BMPInfoHeader.BI_RLE4: + return new DecodeRLE4(fh, ih); + + case BMPInfoHeader.BI_BITFIELDS: + switch(ih.getBitCount()){ + case 16: + return new DecodeBF16(fh, ih, false); + + case 32: + return new DecodeBF32(fh, ih, false); + + default: + return null; + } + + default: + return null; + } + } + + /** + * The image decoder. + */ + public abstract BufferedImage decode(ImageInputStream in) + throws IOException, BMPException; + + /** + * Reads r,g,b bit masks from an inputstream + */ + protected int[] readBitMasks(ImageInputStream in) throws IOException { + int[] bitmasks = new int[3]; + byte[] temp = new byte[12]; + if(in.read(temp) != 12) + throw new IOException("Couldn't read bit masks."); + offset += 12; + + ByteBuffer buf = ByteBuffer.wrap(temp); + buf.order(ByteOrder.LITTLE_ENDIAN); + bitmasks[0] = buf.getInt(); + bitmasks[1] = buf.getInt(); + bitmasks[2] = buf.getInt(); + return bitmasks; + } + + /** + * Reads an N-color palette from an inputstream in RGBQUAD format and + * returns an equivalent ColorModel object + */ + protected IndexColorModel readPalette(ImageInputStream in) throws IOException { + int N = infoHeader.getNumberOfPaletteEntries(); + byte[] r = new byte[N]; + byte[] g = new byte[N]; + byte[] b = new byte[N]; + for(int i=0;i<N;i++){ + byte[] RGBquad = new byte[4]; + if(in.read(RGBquad) != 4) + throw new IOException("Error reading palette information."); + // RGBQUAD structure is b,g,r,0 + r[i] = RGBquad[2]; + g[i] = RGBquad[1]; + b[i] = RGBquad[0]; + } + + offset += 4*N; + return new IndexColorModel(8, N, r, g, b); + } + + /** + * Read bytes to the start of the image data + */ + protected void skipToImage(ImageInputStream in) throws IOException { + byte[] d = new byte[1]; + long n = fileHeader.getOffset() - offset; + for(int i=0;i<n;i++) + in.read(d); + } +} diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPException.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPException.java new file mode 100644 index 00000000000..d3c62e7597e --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPException.java @@ -0,0 +1,47 @@ +/* BMPException.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import javax.imageio.IIOException; + +public class BMPException extends IIOException { + + public BMPException(String message){ + super(message); + } +} diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPFileHeader.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPFileHeader.java new file mode 100644 index 00000000000..246e0eacfeb --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPFileHeader.java @@ -0,0 +1,128 @@ +/* BMPFileHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +public class BMPFileHeader { + /** Header signature, always 'BM' */ + private final static short bfType = 0x424d; + + /** Bitmap file size, in bytes. */ + private long bfSize; + + /** Offset from the beginning of the file to the bitmap data */ + private long bfOffBits; + + /** BITMAPFILEHEADER is 14 bytes */ + public static final int SIZE = 14; + + /** + * Creates the header from an input stream, which is not closed. + * @throws IOException if an I/O error occured. + * @throws BMPException if the header was invalid + */ + public BMPFileHeader(ImageInputStream in) throws IOException, BMPException { + byte[] data = new byte[SIZE]; + + if (in.read(data) != SIZE) + throw new IOException("Couldn't read header."); + ByteBuffer buf = ByteBuffer.wrap(data); + + if(buf.getShort(0) != bfType) + throw new BMPException("Not a BMP file."); + + buf.order(ByteOrder.LITTLE_ENDIAN); + + // get size (keep unsigned) + bfSize = ((long)buf.getInt(2) & (0xFFFFFFFF)); + + // Two reserved shorts are here, and should be zero, + // perhaps they should be tested to be zero, but I don't + // feel this strictness is necessary. + + bfOffBits = ((long)buf.getInt(10) & (0xFFFFFFFF)); + } + + /** + * Writes the header to an output stream, which is not closed or flushed. + * @throws IOException if an I/O error occured. + */ + public void write(OutputStream out) throws IOException { + ByteBuffer buf = ByteBuffer.allocate(SIZE); + buf.putShort(0, bfType); // ID + buf.putInt(2, (int)(bfSize & (0xFFFFFFFF))); // size + buf.putInt(6, 0); // 4 reserved bytes set to zero + buf.putInt(2, (int)(bfOffBits & (0xFFFFFFFF))); // size + out.write(buf.array()); + } + + /** + * Sets the file size + */ + public void setSize(long size){ + bfSize = size; + } + + /** + * Sets the bitmap offset within the file + */ + public void setOffset(long offset){ + bfOffBits = offset; + } + + /** + * Gets the file size + */ + public long getSize(){ + return bfSize; + } + + /** + * Gets the bitmap offset within the file + */ + public long getOffset(){ + return bfOffBits; + } +} + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReader.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReader.java new file mode 100644 index 00000000000..3341d4b4aed --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReader.java @@ -0,0 +1,153 @@ +/* BMPImageReader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.*; +import javax.imageio.spi.*; +import javax.imageio.metadata.*; +import javax.imageio.stream.ImageInputStream; +import java.util.Iterator; +import java.awt.image.BufferedImage; + +public class BMPImageReader extends ImageReader { + private BMPInfoHeader infoHeader; + private BMPFileHeader fileHeader; + private BMPDecoder decoder; + + protected BMPImageReader(ImageReaderSpi originatingProvider){ + super(originatingProvider); + infoHeader = null; + fileHeader = null; + decoder = null; + } + + private void validateIndex(int imageIndex) + throws IndexOutOfBoundsException { + if (imageIndex != 0) + throw new IndexOutOfBoundsException("Invalid image index."); + } + + public void setInput(Object input) { + super.setInput(input); + } + + public void setInput(Object input, + boolean seekForwardOnly, + boolean ignoreMetadata) { + super.setInput(input, seekForwardOnly, ignoreMetadata); + } + + public void setInput(Object input, boolean isStreamable) { + super.setInput(input, isStreamable); + + if (!(input instanceof ImageInputStream)) + throw new IllegalArgumentException("Input not an ImageInputStream."); + } + + private void checkStream() throws IOException { + if (!(input instanceof ImageInputStream)) + throw new IllegalStateException("Input not an ImageInputStream."); + if(input == null) + throw new IllegalStateException("No input stream."); + + } + + private void readHeaders() throws IOException, IIOException { + if(fileHeader != null) + return; + + checkStream(); + + fileHeader = new BMPFileHeader((ImageInputStream)input); + infoHeader = new BMPInfoHeader((ImageInputStream)input); + decoder = BMPDecoder.getDecoder(fileHeader, infoHeader); + } + + public int getWidth(int imageIndex) throws IOException { + validateIndex(imageIndex); + readHeaders(); + return infoHeader.getWidth(); + } + + public int getHeight(int imageIndex) throws IOException { + validateIndex(imageIndex); + readHeaders(); + return infoHeader.getHeight(); + } + + public Iterator getImageTypes(int imageIndex){ + validateIndex(imageIndex); + return null; + } + + /** + * Returns the number of images. BMP files can only contain a single one. + */ + public int getNumImages(boolean allowSearch){ + return 1; + } + + + // FIXME: Support metadata + public IIOMetadata getImageMetadata(int imageIndex){ + validateIndex(imageIndex); + return null; + } + + // FIXME: Support metadata + public IIOMetadata getStreamMetadata(){ + return null; + } + + /** + * Reads the image indexed by imageIndex and returns it as + * a complete BufferedImage, using a supplied ImageReadParam. + */ + public BufferedImage read(int imageIndex, ImageReadParam param) + throws IOException, IIOException { + validateIndex(imageIndex); + readHeaders(); + return decoder.decode((ImageInputStream)input); + } + + +} + + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReaderSpi.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReaderSpi.java new file mode 100644 index 00000000000..b175c7d076b --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPImageReaderSpi.java @@ -0,0 +1,123 @@ +/* BMPImageReaderSpi.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import java.util.Locale; +import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; + +public class BMPImageReaderSpi extends ImageReaderSpi { + + static final String vendorName = "GNU"; + static final String version = "0.1"; + static final String readerClassName = + "gnu.javax.imageio.bmp.BMPImageReader"; + static final String[] names = { "Microsoft Windows BMP" }; + static final String[] suffixes = { ".bmp", ".bm" }; + static final String[] MIMETypes = { + "image/bmp", + "image/x-windows-bmp"}; + + static final String[] writerSpiNames = null; + //{"com.mycompany.imageio.MyFormatImageWriterSpi" }; + + static final boolean supportsStandardStreamMetadataFormat = false; + static final String nativeStreamMetadataFormatName = null; + static final String nativeStreamMetadataFormatClassName = null; + static final String[] extraStreamMetadataFormatNames = null; + static final String[] extraStreamMetadataFormatClassNames = null; + static final boolean supportsStandardImageMetadataFormat = false; + static final String nativeImageMetadataFormatName = null; + static final String nativeImageMetadataFormatClassName = null; + static final String[] extraImageMetadataFormatNames = null; + static final String[] extraImageMetadataFormatClassNames = null; + + public BMPImageReaderSpi() { + super(vendorName, version, + names, suffixes, MIMETypes, + readerClassName, + STANDARD_INPUT_TYPE, // Accept ImageImageInputStreams + writerSpiNames, + supportsStandardStreamMetadataFormat, + nativeStreamMetadataFormatName, + nativeStreamMetadataFormatClassName, + extraStreamMetadataFormatNames, + extraStreamMetadataFormatClassNames, + supportsStandardImageMetadataFormat, + nativeImageMetadataFormatName, + nativeImageMetadataFormatClassName, + extraImageMetadataFormatNames, + extraImageMetadataFormatClassNames); + } + + public String getDescription(Locale locale) { + return "Microsoft BMP v3"; + } + + public boolean canDecodeInput(Object input) + throws IOException { + if (!(input instanceof ImageInputStream)) + return false; + + ImageInputStream in = (ImageInputStream)input; + boolean retval; + + in.mark(); + try { + new BMPFileHeader(in); + retval = true; + } catch(BMPException e){ + retval = false; + } + in.reset(); + + return retval; + } + + public ImageReader createReaderInstance(Object extension) { + return new BMPImageReader(this); + } +} + + + + + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/BMPInfoHeader.java b/libjava/classpath/gnu/javax/imageio/bmp/BMPInfoHeader.java new file mode 100644 index 00000000000..edcb4e644cc --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/BMPInfoHeader.java @@ -0,0 +1,201 @@ +/* BMPInfoHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.awt.Dimension; + +public class BMPInfoHeader { + /** Size of the bitmap info header*/ + private int biSize; + + /** Pixel width of the bitmap */ + private int biWidth; + + /** Pixel height of the bitmap */ + private int biHeight; + + /** Number of bitplanes = 1 */ + private short biPlanes; + + /** Number of bpp = 1,4,8,24 */ + private short biBitCount; + + /** Compression type, RGB8, RLE8, RLE4, BITFIELDS */ + private int biCompression; + + /** Byte size of the uncompressed bitmap, can be 0. */ + private int biSizeImage; + + /** X resolution, dots per meter */ + private int biXPelsPerMeter; + + /** Y resolution, dots per meter */ + private int biYPelsPerMeter; + + /** Number of colors used (palette only, can be 0 for all) */ + private int biClrUsed; + + /** Number of 'important' colors, 0 for all */ + private int biClrImportant; + + /** BITMAPINFOHEADER is 40 bytes */ + public static final int SIZE = 40; + + /** + * Compression types + */ + public static final int BI_RGB = 0; + public static final int BI_RLE8 = 1; + public static final int BI_RLE4 = 2; + public static final int BI_BITFIELDS = 3; + + /** + * Creates the header from an input stream, which is not closed. + * @throws IOException if an I/O error occured. + * @throws BMPException if the header was invalid + */ + public BMPInfoHeader(ImageInputStream in) throws IOException, BMPException { + byte[] data = new byte[SIZE]; + + if (in.read(data) != SIZE) + throw new IOException("Couldn't read header."); + ByteBuffer buf = ByteBuffer.wrap(data); + buf.order(ByteOrder.LITTLE_ENDIAN); + + int n; + if((n=buf.getInt()) != SIZE) + throw new BMPException("Invalid BITMAPINFOHEADER size: "+n); + + biWidth = buf.getInt(); + biHeight = buf.getInt(); + biPlanes = buf.getShort(); + setBitCount(buf.getShort()); + setCompression(buf.getInt()); + biSizeImage = buf.getInt(); + biXPelsPerMeter = buf.getInt(); + biYPelsPerMeter = buf.getInt(); + biClrUsed = buf.getInt(); + biClrImportant = buf.getInt(); + } + + public void setBitCount(short bitcount) throws BMPException { + switch(bitcount){ + case 1: + case 4: + case 8: + case 16: + case 24: + case 32: + biBitCount = bitcount; + break; + + default: + throw new BMPException("Invalid number of bits per pixel: "+ + bitcount); + } + } + + public short getBitCount() { return biBitCount; } + + public void setCompression(int compression) throws BMPException { + switch(compression){ + case BI_RLE8: + if(getBitCount() != 8) + throw new BMPException("Invalid number of bits per pixel."); + biCompression = compression; + break; + case BI_RLE4: + if(getBitCount() != 4) + throw new BMPException("Invalid number of bits per pixel."); + biCompression = compression; + break; + + case BI_RGB: + case BI_BITFIELDS: + biCompression = compression; + break; + + default: + throw new BMPException("Unknown bitmap compression type."); + } + } + + public int getNumberOfPaletteEntries(){ + if(biClrUsed == 0) + switch(biBitCount){ + case 1: + return 2; + case 4: + return 16; + case 8: + return 256; + + default: // should not happen + return 0; + } + + return biClrUsed; + } + + public int getCompression(){ + return biCompression; + } + + public Dimension getSize(){ + return new Dimension(biWidth, biHeight); + } + + public int getWidth(){ + return biWidth; + } + + public int getHeight(){ + return biHeight; + } + + public void setSize(Dimension d){ + biWidth = (int)d.getWidth(); + biHeight = (int)d.getHeight(); + } + +} diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF16.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF16.java new file mode 100644 index 00000000000..702c93ab3ca --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF16.java @@ -0,0 +1,104 @@ +/* DecodeBF16.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferUShort; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.SampleModel; +import java.awt.Dimension; + +public class DecodeBF16 extends BMPDecoder { + private int[] bitmasks; + private boolean useDefaultMasks; + + public DecodeBF16(BMPFileHeader fh, BMPInfoHeader ih, + boolean udm){ + super(fh,ih); + + useDefaultMasks = udm; + if(useDefaultMasks) // 5-6-5 mask, B,G,R + bitmasks = new int[] { 0x00F800, 0x0007E0, 0x00001F }; + } + + public BufferedImage decode(ImageInputStream in) throws IOException, BMPException { + if(!useDefaultMasks) + bitmasks = readBitMasks(in); + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + + // BMP scanlines are padded to dword offsets + int scansize = (w + (w&1)) << 1; + short[] data = new short[w*h]; + + for(int y=h-1;y>=0;y--){ + byte[] scanline = new byte[scansize]; + if(in.read(scanline) != scansize) + throw new IOException("Couldn't read image data."); + + for(int x=0;x<w;x++) + data[x + y*w] = (short)((scanline[x*2] & (0xFF)) | + ((scanline[x*2+1] & (0xFF)) << 8)); + } + + ColorModel cm = new DirectColorModel(16, + bitmasks[0], bitmasks[1], bitmasks[2]); + SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_USHORT, + w, h, + bitmasks); + DataBuffer db = new DataBufferUShort(data, w*h, 0); + WritableRaster raster = Raster.createWritableRaster(sm, db, null); + return new BufferedImage(cm, raster, false, null); + } + +} + + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF32.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF32.java new file mode 100644 index 00000000000..ee64f4b0eac --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeBF32.java @@ -0,0 +1,108 @@ +/* DecodeBF32.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.SampleModel; +import java.awt.Dimension; + +public class DecodeBF32 extends BMPDecoder { + private int[] bitmasks; + private boolean useDefaultMasks; + + public DecodeBF32(BMPFileHeader fh, BMPInfoHeader ih, + boolean udm){ + super(fh,ih); + + useDefaultMasks = udm; + if(useDefaultMasks) + bitmasks = new int[] { 0x00FF0000, 0x0000FF00, 0x000000FF }; + } + + public BufferedImage decode(ImageInputStream in) throws IOException, BMPException { + if(!useDefaultMasks) + bitmasks = readBitMasks(in); + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + + // BMP scanlines are padded to dword offsets + int scansize = w << 2; + int[] data = new int[w*h]; + + + for(int y=h-1;y>=0;y--){ + byte[] scanline = new byte[scansize]; + if(in.read(scanline) != scansize) + throw new IOException("Couldn't read image data."); + + for(int x=0;x<w;x++) + data[x + y*w] = ((scanline[x<<2] & (0xFF)) | + ((scanline[(x<<2)+1] & (0xFF)) << 8) | + ((scanline[(x<<2)+2] & (0xFF)) << 16) | + ((scanline[(x<<2)+3] & (0xFF)) << 24)); + } + + ColorModel cm = new DirectColorModel(32, + bitmasks[0], bitmasks[1], bitmasks[2]); + SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, + w, h, + bitmasks); + DataBuffer db = new DataBufferInt(data, w*h); + WritableRaster raster = Raster.createWritableRaster(sm, db, null); + + return new BufferedImage(cm, raster, false, null); + } + +} + + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB1.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB1.java new file mode 100644 index 00000000000..9ca82d9ee4a --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB1.java @@ -0,0 +1,96 @@ +/* DecodeRGB1.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.SampleModel; +import java.awt.Dimension; + +public class DecodeRGB1 extends BMPDecoder { + + public DecodeRGB1(BMPFileHeader fh, BMPInfoHeader ih){ + super(fh, ih); + } + + public BufferedImage decode(ImageInputStream in) + throws IOException, BMPException { + + IndexColorModel palette = readPalette(in); + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + int size = (w*h)>>3; + + int scansize = w>>3; + byte[] data = new byte[size]; + + for(int y=h-1;y>=0;y--){ + // Scanlines are padded to dword boundries + int readsize = scansize; + if((readsize & 3) != 0) readsize += (4 - (scansize & 3)); + + byte[] scanline = new byte[readsize]; + if(in.read(scanline) != readsize) + throw new IOException("Couldn't read image data."); + + for(int x=0;x<scansize;x++) + data[x + y*scansize] = scanline[x]; + } + + SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, + w, h, 1); + + DataBuffer db = new DataBufferByte(data, size, 0); + WritableRaster raster = Raster.createWritableRaster(sm, db, null); + + return new BufferedImage(palette, raster, false, null); + } + +} + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB24.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB24.java new file mode 100644 index 00000000000..2a910cb3063 --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB24.java @@ -0,0 +1,77 @@ +/* DecodeRGB24.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.awt.Dimension; + +public class DecodeRGB24 extends BMPDecoder { + + public DecodeRGB24(BMPFileHeader fh, BMPInfoHeader ih){ + super(fh, ih); + } + + public BufferedImage decode(ImageInputStream in) throws IOException, BMPException { + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + BufferedImage image = new BufferedImage(w, h, + BufferedImage.TYPE_INT_RGB); + // BMP scanlines are padded to dword offsets + int scansize = ((w*3 & 3) != 0)? w*3 + 4 - (w*3 & 3): w*3; + int[] data = new int[w*h]; + + for(int y=h-1;y>=0;y--){ + byte[] scanline = new byte[scansize]; + if(in.read(scanline) != scansize) + throw new IOException("Couldn't read image data."); + + for(int x=0;x<w;x++) + data[x + y*w] = scanline[x*3] + + (scanline[x*3+1] << 8) + + (scanline[x*3+2] << 16); + } + image.setRGB(0, 0, w, h, data, 0, w); + return image; + } + +} diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB4.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB4.java new file mode 100644 index 00000000000..a10d390ab82 --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB4.java @@ -0,0 +1,92 @@ +/* DecodeRGB4.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.SampleModel; +import java.awt.Dimension; + +public class DecodeRGB4 extends BMPDecoder { + + public DecodeRGB4(BMPFileHeader fh, BMPInfoHeader ih){ + super(fh, ih); + } + + public BufferedImage decode(ImageInputStream in) throws IOException, BMPException { + IndexColorModel palette = readPalette(in); + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + int size = (w*h) >> 1; + + // Scanline padded to dword offsets + int wbytes = (w + (w & 1)) >> 1; + int scansize = ((wbytes & 3) != 0)? (wbytes + 4 - (wbytes&3)) : wbytes; + + byte[] data = new byte[wbytes*h]; + + for(int y=h-1;y>=0;y--){ + byte[] scanline = new byte[scansize]; + if(in.read(scanline) != scansize) + throw new IOException("Couldn't read image data."); + + for(int x=0;x<wbytes;x++) + data[x + y*wbytes] = scanline[x]; + } + SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, + w, h, 4); + + DataBuffer db = new DataBufferByte(data, w*h, 0); + WritableRaster raster = Raster.createWritableRaster(sm, db, null); + + return new BufferedImage(palette, raster, false, null); + } + +} + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB8.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB8.java new file mode 100644 index 00000000000..dfe4a19e8be --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRGB8.java @@ -0,0 +1,90 @@ +/* DecodeRGB8.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.SampleModel; +import java.awt.Dimension; + +public class DecodeRGB8 extends BMPDecoder { + + public DecodeRGB8(BMPFileHeader fh, BMPInfoHeader ih){ + super(fh, ih); + } + + public BufferedImage decode(ImageInputStream in) throws IOException, BMPException { + IndexColorModel palette = readPalette(in); + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + + // BMP scanlines are padded to dword offsets + int scansize = ((w & 3) != 0)? w + 4 - (w & 3): w; + byte[] data = new byte[w*h]; + + for(int y=h-1;y>=0;y--){ + byte[] scanline = new byte[scansize]; + if(in.read(scanline) != scansize) + throw new IOException("Couldn't read image data."); + + for(int x=0;x<w;x++) + data[x + y*w] = scanline[x]; + } + + SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE, + w, h, + new int[] {0xFF}); + DataBuffer db = new DataBufferByte(data, w*h, 0); + WritableRaster raster = Raster.createWritableRaster(sm, db, null); + + return new BufferedImage(palette, raster, false, null); + } + +} + + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE4.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE4.java new file mode 100644 index 00000000000..55d314f05f1 --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE4.java @@ -0,0 +1,176 @@ +/* DecodeRLE4.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.SampleModel; +import java.awt.Dimension; + +public class DecodeRLE4 extends BMPDecoder { + + public DecodeRLE4(BMPFileHeader fh, BMPInfoHeader ih){ + super(fh, ih); + } + + /** + * RLE control codes + */ + private static final byte ESCAPE = (byte)0; + private static final byte EOL = (byte)0; // end of line + private static final byte EOB = (byte)1; // end of bitmap + private static final byte DELTA = (byte)2; // delta + + public BufferedImage decode(ImageInputStream in) throws IOException, BMPException { + IndexColorModel palette = readPalette(in); + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + + byte[] data = uncompress(w, h, in); + SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, + w, h, 4); + + DataBuffer db = new DataBufferByte(data, w*h, 0); + WritableRaster raster = Raster.createWritableRaster(sm, db, null); + + return new BufferedImage(palette, raster, false, null); + } + + private byte[] uncompress(int w, int h, ImageInputStream in) + throws BMPException, IOException { + byte[] cmd = new byte[2]; + byte[] data = new byte[w*h>>1]; + int offIn = 0; + int x=0,y=0; + + // width in bytes + w += (w&1); + w = w >> 1; + + try { + while(((x>>1) + y*w) < w*h){ + if(in.read(cmd) != 2) + throw new IOException("Error reading compressed data."); + + if(cmd[0] == ESCAPE){ + switch(cmd[1]){ + case EOB: // end of bitmap + return data; + case EOL: // end of line + x = 0; + y++; + break; + case DELTA: // delta + if(in.read(cmd) != 2) + throw new IOException("Error reading compressed data."); + int dx = cmd[0] & (0xFF); + int dy = cmd[1] & (0xFF); + x += dx; + y += dy; + break; + + default: + // decode a literal run + int length = cmd[1] & (0xFF); + + // size of run, which is word aligned. + int bytesize = length; + bytesize += (bytesize & 1); + bytesize >>= 1; + bytesize += (bytesize & 1); + + byte[] run = new byte[bytesize]; + if(in.read(run) != bytesize) + throw new IOException("Error reading compressed data."); + + if((x&1) == 0){ + length += (length&1); + length >>= 1; + System.arraycopy(run, 0, data, ((x>>1) + w*(h-y-1)), + length); + } else { + for(int i=0;i<length;i++){ + if((i&1) == 0) // copy high to low + data[((x+i)>>1) + w*(h-y-1)] + |= ((run[i>>1]&0xF0) >> 4); + else // copy low to high + data[((x+i)>>1) + w*(h-y-1)] + |= ((run[i>>1]&0x0F) << 4); + } + } + x += cmd[1] & (0xFF); + break; + } + } else { + // decode a byte run + int length = cmd[0] & (0xFF); + if((x&1) == 0){ + length += (length&1); + length >>= 1; + for(int i=0;i<length;i++) + data[(h-y-1)*w + i + (x >> 1)] = cmd[1]; + } else { + for(int i=0;i<length;i++){ + if((i&1) == 0) // copy high to low + data[((x+i)>>1) + w*(h-y-1)] + |= ((cmd[1]&0xF0) >> 4); + else // copy low to high + data[((x+i)>>1) + w*(h-y-1)] + |= ((cmd[1]&0x0F) << 4); + } + } + x += cmd[0] & (0xFF); + } + } + return data; + } catch(ArrayIndexOutOfBoundsException e){ + throw new BMPException("Invalid RLE data."); + } + } +} + diff --git a/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE8.java b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE8.java new file mode 100644 index 00000000000..1d00e6751d0 --- /dev/null +++ b/libjava/classpath/gnu/javax/imageio/bmp/DecodeRLE8.java @@ -0,0 +1,143 @@ +/* DecodeRLE8.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.javax.imageio.bmp; + +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.SampleModel; +import java.awt.Dimension; + +public class DecodeRLE8 extends BMPDecoder { + + public DecodeRLE8(BMPFileHeader fh, BMPInfoHeader ih){ + super(fh, ih); + } + + /** + * RLE control codes + */ + private static final byte ESCAPE = (byte)0; + private static final byte EOL = (byte)0; // end of line + private static final byte EOB = (byte)1; // end of bitmap + private static final byte DELTA = (byte)2; // delta + + public BufferedImage decode(ImageInputStream in) throws IOException, BMPException { + IndexColorModel palette = readPalette(in); + skipToImage(in); + + Dimension d = infoHeader.getSize(); + int h = (int)d.getHeight(); + int w = (int)d.getWidth(); + + byte[] data = uncompress(w, h, in); + SampleModel sm = new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE, + w, h, + new int[] {0xFF}); + DataBuffer db = new DataBufferByte(data, w*h, 0); + WritableRaster raster = Raster.createWritableRaster(sm, db, null); + + return new BufferedImage(palette, raster, false, null); + } + + private byte[] uncompress(int w, int h, ImageInputStream in) + throws BMPException, IOException { + byte[] cmd = new byte[2]; + byte[] data = new byte[w*h]; + int offIn = 0; + int x=0,y=0; + + try { + while((x + y*w) < w*h){ + if(in.read(cmd) != 2) + throw new IOException("Error reading compressed data."); + + if(cmd[0] == ESCAPE){ + switch(cmd[1]){ + case EOB: // end of bitmap + return data; + case EOL: // end of line + x = 0; + y++; + break; + case DELTA: // delta + if(in.read(cmd) != 2) + throw new IOException("Error reading compressed data."); + int dx = cmd[0] & (0xFF); + int dy = cmd[1] & (0xFF); + x += dx; + y += dy; + break; + + default: + // decode a literal run + int length = cmd[1] & (0xFF); + int copylength = length; + + // absolute mode must be word-aligned + length += (length & 1); + + byte[] run = new byte[length]; + if(in.read(run) != length) + throw new IOException("Error reading compressed data."); + + System.arraycopy(run, 0, data, (x+w*(h-y-1)), + copylength); + x += copylength; + break; + } + } else { + // decode a byte run + int length = cmd[0] & (0xFF); + for(int i=0;i<length;i++) + data[(h-y-1)*w + x++] = cmd[1]; + } + } + return data; + } catch(ArrayIndexOutOfBoundsException e){ + throw new BMPException("Invalid RLE data."); + } + } +} + |