BMHDChunk.java
/*
* Copyright (c) 2008, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.iff;
import javax.imageio.IIOException;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* BMHDChunk
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: BMHDChunk.java,v 1.0 28.feb.2006 00:04:32 haku Exp$
*/
final class BMHDChunk extends IFFChunk {
//
// typedef UBYTE Masking; /* Choice of masking technique. */
//
// #define mskNone 0
// #define mskHasMask 1
// #define mskHasTransparentColor 2
// #define mskLasso 3
//
// typedef UBYTE Compression; /* Choice of compression algorithm
// applied to the rows of all source and mask planes. "cmpByteRun1"
// is the byte run encoding described in Appendix C. Do not compress
// across rows! */
// #define cmpNone 0
// #define cmpByteRun1 1
//
// typedef struct {
// UWORD w, h; /* raster width & height in pixels */
// WORD x, y; /* pixel position for this image */
// UBYTE nPlanes; /* # source bitplanes */
// Masking masking;
// Compression compression;
// UBYTE pad1; /* unused; ignore on read, write as 0 */
// UWORD transparentColor; /* transparent "color number" (sort of) */
// UBYTE xAspect, yAspect; /* pixel aspect, a ratio width : height */
// WORD pageWidth, pageHeight; /* source "page" size in pixels */
// } BitMapHeader;*/
static final int MASK_NONE = 0;
static final int MASK_HAS_MASK = 1;
static final int MASK_TRANSPARENT_COLOR = 2;
static final int MASK_LASSO = 3;
static final int COMPRESSION_NONE = 0;
// RLE
static final int COMPRESSION_BYTE_RUN = 1;
// NOTE: Each row of the image is stored in an integral number of 16 bit
// words. The number of words per row is words=((w+15)/16)
// Dimensions of raster
int width;
int height;
// Source offsets
// Hmm.. Consider making these Image.properties?
int xPos;
int yPos;
// The number of source bitplanes in the BODY chunk (see below) is stored in
// nPlanes. An ILBM with a CMAP but no BODY and nPlanes = 0 is the
// recommended way to store a color map.
int bitplanes;
int maskType;
int compressionType;
int transparentIndex;
// NOTE: Typical values are 10:11 (320 x 200)
int xAspect;
int yAspect;
// Source page dimension
// NOTE: The image may be larger than the page, probably ignore these
int pageWidth;
int pageHeight;
BMHDChunk(int chunkLength) {
super(IFF.CHUNK_BMHD, chunkLength);
}
BMHDChunk(int width, int height, int bitplanes, int maskType, int compressionType, int transparentIndex) {
super(IFF.CHUNK_BMHD, 20);
this.width = width;
this.height = height;
xPos = 0;
yPos = 0;
this.bitplanes = bitplanes;
this.maskType = maskType;
this.compressionType = compressionType;
this.transparentIndex = transparentIndex;
xAspect = 1;
yAspect = 1;
pageWidth = Math.min(width, Short.MAX_VALUE); // For some reason, these are signed?
pageHeight = Math.min(height, Short.MAX_VALUE);
}
@Override
void readChunk(final DataInput input) throws IOException {
if (chunkLength != 20) {
throw new IIOException("Unknown BMHD chunk length: " + chunkLength);
}
width = input.readUnsignedShort();
height = input.readUnsignedShort();
xPos = input.readShort();
yPos = input.readShort();
bitplanes = input.readUnsignedByte();
maskType = input.readUnsignedByte();
compressionType = input.readUnsignedByte();
input.readByte(); // PAD
transparentIndex = input.readUnsignedShort();
xAspect = input.readUnsignedByte();
yAspect = input.readUnsignedByte();
pageWidth = input.readShort();
pageHeight = input.readShort();
}
@Override
void writeChunk(final DataOutput output) throws IOException {
output.writeInt(chunkId);
output.writeInt(chunkLength);
output.writeShort(width);
output.writeShort(height);
output.writeShort(xPos);
output.writeShort(yPos);
output.writeByte(bitplanes);
output.writeByte(maskType);
output.writeByte(compressionType);
output.writeByte(0); // PAD
output.writeShort(transparentIndex);
output.writeByte(xAspect);
output.writeByte(yAspect);
output.writeShort(pageWidth);
output.writeShort(pageHeight);
}
@Override
public String toString() {
return super.toString()
+ " {w=" + width + ", h=" + height
+ ", x=" + xPos + ", y=" + yPos
+ ", planes=" + bitplanes + ", mask=" + maskType
+ ", compression=" + compressionType + ", trans=" + transparentIndex
+ ", xAspect=" + xAspect + ", yAspect=" + yAspect
+ ", pageWidth=" + pageWidth + ", pageHeight=" + pageHeight + "}";
}
}