You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
6.2 KiB
173 lines
6.2 KiB
package com.fr.third.JAI; |
|
/* |
|
* Copyright (c) 2001 Sun Microsystems, Inc. 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. |
|
* |
|
* -Redistribution in binary form must reproduct 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 Sun Microsystems, Inc. or the names of contributors may |
|
* be used to endorse or promote products derived from this software without |
|
* specific prior written permission. |
|
* |
|
* This software is provided "AS IS," without a warranty of any kind. ALL |
|
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY |
|
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR |
|
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE |
|
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING |
|
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS |
|
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, |
|
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER |
|
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF |
|
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE |
|
* POSSIBILITY OF SUCH DAMAGES. |
|
* |
|
* You acknowledge that Software is not designed,licensed or intended for use in |
|
* the design, construction, operation or maintenance of any nuclear facility. |
|
*/ |
|
import java.awt.Graphics2D; |
|
import java.awt.Point; |
|
import java.awt.geom.AffineTransform; |
|
import java.awt.image.BufferedImage; |
|
import java.awt.image.ComponentSampleModel; |
|
import java.awt.image.Raster; |
|
import java.awt.image.RenderedImage; |
|
import java.io.FilterInputStream; |
|
import java.io.InputStream; |
|
import java.io.IOException; |
|
|
|
import com.sun.image.codec.jpeg.ImageFormatException; |
|
|
|
/** |
|
*/ |
|
public class JPEGImageDecoder extends ImageDecoderImpl { |
|
|
|
public JPEGImageDecoder(InputStream input, |
|
ImageDecodeParam param) { |
|
super(input, param); |
|
} |
|
|
|
public RenderedImage decodeAsRenderedImage(int page) throws IOException { |
|
if (page != 0) { |
|
throw new IOException(JaiI18N.getString("JPEGImageDecoder0")); |
|
} |
|
return new JPEGImage(input, param); |
|
} |
|
} |
|
|
|
/** |
|
* FilterInputStream subclass which does not support mark/reset. |
|
* Used to work around a failure of com.sun.image.codec.jpeg.JPEGImageDecoder |
|
* in which decodeAsBufferedImage() blocks in reset() if a corrupted JPEG |
|
* image is encountered. |
|
*/ |
|
class NoMarkStream extends FilterInputStream { |
|
NoMarkStream(InputStream in) { |
|
super(in); |
|
} |
|
|
|
/** |
|
* Disallow mark/reset. |
|
*/ |
|
public boolean markSupported() { |
|
return false; |
|
} |
|
|
|
/** |
|
* Disallow close() from closing the stream passed in. |
|
*/ |
|
public final void close() throws IOException { |
|
// Deliberately do nothing. |
|
} |
|
} |
|
|
|
class JPEGImage extends SimpleRenderedImage { |
|
|
|
/** |
|
* Mutex for the entire class to circumvent thread unsafety of |
|
* com.sun.image.codec.jpeg.JPEGImageDecoder implementation. |
|
*/ |
|
private static final Object LOCK = new Object(); |
|
|
|
private Raster theTile = null; |
|
|
|
/** |
|
* Construct a JPEGmage. |
|
* |
|
* @param stream The JPEG InputStream. |
|
* @param param The decoding parameters. |
|
*/ |
|
public JPEGImage(InputStream stream, ImageDecodeParam param) { |
|
// If the supplied InputStream supports mark/reset wrap it so |
|
// it does not. |
|
if(stream.markSupported()) { |
|
stream = new NoMarkStream(stream); |
|
} |
|
|
|
// Lock the entire class to work around lack of thread safety |
|
// in com.sun.image.codec.jpeg.JPEGImageDecoder implementation. |
|
BufferedImage image = null; |
|
synchronized(LOCK) { |
|
com.sun.image.codec.jpeg.JPEGImageDecoder decoder = |
|
com.sun.image.codec.jpeg.JPEGCodec.createJPEGDecoder(stream); |
|
try { |
|
// decodeAsBufferedImage performs default color conversions |
|
image = decoder.decodeAsBufferedImage(); |
|
} catch (ImageFormatException e) { |
|
throw new RuntimeException(JaiI18N.getString("JPEGImageDecoder1")); |
|
} catch (IOException e) { |
|
throw new RuntimeException(JaiI18N.getString("JPEGImageDecoder2")); |
|
} |
|
} |
|
|
|
minX = 0; |
|
minY = 0; |
|
tileWidth = width = image.getWidth(); |
|
tileHeight = height = image.getHeight(); |
|
|
|
// Force image to have a ComponentSampleModel if it does not have one |
|
// and the ImageDecodeParam is either null or is a JPEGDecodeParam |
|
// with 'decodeToCSM' set to 'true'. |
|
if ((param == null || |
|
(param instanceof JPEGDecodeParam && |
|
((JPEGDecodeParam)param).getDecodeToCSM())) && |
|
!(image.getSampleModel() instanceof ComponentSampleModel)) { |
|
|
|
int type = -1; |
|
int numBands = image.getSampleModel().getNumBands(); |
|
if (numBands == 1) { |
|
type = BufferedImage.TYPE_BYTE_GRAY; |
|
} else if (numBands == 3) { |
|
type = BufferedImage.TYPE_3BYTE_BGR; |
|
} else if (numBands == 4) { |
|
type = BufferedImage.TYPE_4BYTE_ABGR; |
|
} else { |
|
throw new RuntimeException(JaiI18N.getString("JPEGImageDecoder3")); |
|
} |
|
|
|
BufferedImage bi = new BufferedImage(width, height, type); |
|
bi.getWritableTile(0, 0).setRect(image.getWritableTile(0, 0)); |
|
bi.releaseWritableTile(0, 0); |
|
image = bi; |
|
} |
|
|
|
sampleModel = image.getSampleModel(); |
|
colorModel = image.getColorModel(); |
|
|
|
theTile = image.getWritableTile(0, 0); |
|
} |
|
|
|
public synchronized Raster getTile(int tileX, int tileY) { |
|
if (tileX != 0 || tileY != 0) { |
|
throw new IllegalArgumentException(JaiI18N.getString("JPEGImageDecoder4")); |
|
} |
|
|
|
return theTile; |
|
} |
|
}
|
|
|