/* * JPEGInfo.java * Transform * * Copyright (c) 2009-2010 Flagstone Software Ltd. 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 Flagstone Software Ltd. 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 OWNER 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.flagstone.transform.image; import com.flagstone.transform.coder.Coder; /** * JPEGInfo is used to extract the width and height from a JPEG encoded image. */ public final class JPEGInfo { /** Bit mask for the least significant byte. */ private static final int BYTE_MASK = 255; /** Marks the start of an image. */ public static final int SOI = 0xFFD8; /** Marks the end of an image. */ public static final int EOI = 0xFFD9; /** Marks the start of a frame - baseline DCT. */ public static final int SOF0 = 0xFFC0; /** Marks the start of a frame - progressive DCT. */ public static final int SOF2 = 0xFFC2; /** Marks the start of a JPG block. */ public static final int JPG = 0xFFC8; /** Marks the start of a JPG block. */ public static final int SOFF = 0xFFCF; /** Marks the Huffman table. */ public static final int DHT = 0xFFC4; /** Marks the quantization table. */ public static final int DQT = 0xFFDB; /** Marks the restart interval. */ public static final int DRI = 0xFFDD; /** Marks the start of scan. */ public static final int SOS = 0xFFDA; /** Marks a restart. */ public static final int RST = 0xFFD0; /** Marks the start of an application specific block. */ public static final int APP = 0xFFE0; /** Marks the start of an comment block. */ public static final int COM = 0xFFFE; /** The width of the image. */ private transient int width; /** The height of the image. */ private transient int height; /** * Get the width of the image in pixels, not twips. * * @return the width of the image */ public int getWidth() { return width; } /** * Return the height of the image in pixels, not twips. * * @return the height of the image */ public int getHeight() { return height; } /** * Decode a JPEG encoded image. * * @param image the image data. */ public void decode(final byte[] image) { final int limit = image.length - 2; int marker; int length; int index = 0; while (index < limit) { marker = ((image[index++] & BYTE_MASK) << Coder.TO_UPPER_BYTE) | (image[index++] & BYTE_MASK); if (marker == SOI || marker == EOI) { continue; } length = ((image[index++] & BYTE_MASK) << Coder.TO_UPPER_BYTE) | (image[index++] & BYTE_MASK); if (marker >= SOF0 && marker <= SOFF && marker != DHT && marker != JPG) { index++; height = ((image[index++] & BYTE_MASK) << Coder.TO_UPPER_BYTE) | (image[index++] & BYTE_MASK); width = ((image[index++] & BYTE_MASK) << Coder.TO_UPPER_BYTE) | (image[index++] & BYTE_MASK); break; } else { index += length - 2; } } } }