Class JPEGImageReader
- java.lang.Object
-
- javax.imageio.ImageReader
-
- com.twelvemonkeys.imageio.ImageReaderBase
-
- com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader
-
public final class JPEGImageReader extends ImageReaderBase
A JPEGImageReader
implementation based on the JREJPEGImageReader
, that adds support and properly handles cases where the JRE version throws exceptions.
Main features:- Support for YCbCr JPEGs without JFIF segment (converted to RGB, using the embedded ICC profile if applicable)
- Support for CMYK JPEGs (converted to RGB by default or as CMYK, using the embedded ICC profile if applicable)
- Support for Adobe YCCK JPEGs (converted to RGB by default or as CMYK, using the embedded ICC profile if applicable)
- Support for JPEGs containing ICC profiles with interpretation other than 'Perceptual' (profile is assumed to be 'Perceptual' and used)
- Support for JPEGs containing ICC profiles with class other than 'Display' (profile is assumed to have class 'Display' and used)
- Support for JPEGs containing ICC profiles that are incompatible with stream data (image data is read, profile is ignored)
- Support for JPEGs with corrupted ICC profiles (image data is read, profile is ignored)
- Support for JPEGs with corrupted
ICC_PROFILE
segments (image data is read, profile is ignored) - Support for JPEGs using non-standard color spaces, unsupported by Java 2D (image data is read, profile is ignored)
- Issues warnings instead of throwing exceptions in cases of corrupted data where ever the image data can still be read in a reasonable way
- Support for JFIF thumbnails (even if stream contains inconsistent metadata)
- Support for JFXX thumbnails (JPEG, Indexed and RGB)
- Support for EXIF thumbnails (JPEG, RGB and YCbCr)
- Support for JPEG metadata in both standard and native formats (even if stream contains inconsistent metadata)
- Support for
javax_imageio_jpeg_image_1.0
format (currently as native format, may change in the future) - Support for illegal combinations of JFIF, Exif and Adobe markers, using "unknown" segments in the
"MarkerSequence" tag for the unsupported segments (for
javax_imageio_jpeg_image_1.0
format)
- Version:
- $Id: JPEGImageReader.java,v 1.0 24.01.11 16.37 haraldk Exp$
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private class
JPEGImageReader.JPEGSegmentWarningDelegate
private class
JPEGImageReader.ProgressDelegator
-
Field Summary
Fields Modifier and Type Field Description (package private) static int
ALL_APP_MARKERS
Internal constant for referring all APP segmentsprivate int
currentStreamIndex
(package private) static boolean
DEBUG
private javax.imageio.ImageReader
delegate
Our JPEG reading delegate(package private) static boolean
FORCE_RASTER_CONVERSION
private JPEGImageReader.ProgressDelegator
progressDelegator
Listens to progress updates in the delegate, and delegates back to this instanceprivate java.util.List<Segment>
segments
Cached list of JPEG segments we filter from the underlying streamprivate java.util.List<java.lang.Long>
streamOffsets
private javax.imageio.ImageReader
thumbnailReader
Extra delegate for reading JPEG encoded thumbnailsprivate java.util.List<ThumbnailReader>
thumbnails
-
Fields inherited from class com.twelvemonkeys.imageio.ImageReaderBase
imageInput
-
-
Constructor Summary
Constructors Constructor Description JPEGImageReader(javax.imageio.spi.ImageReaderSpi provider, javax.imageio.ImageReader delegate)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
abort()
boolean
canReadRaster()
private void
checkThumbnailBounds(int imageIndex, int thumbnailIndex)
private static void
convertYCbCr2RGB(java.awt.image.Raster raster, int numComponents)
private static void
convertYCCK2CMYK(java.awt.image.Raster raster)
private boolean
delegateCSTypeMismatch(JFIF jfif, AdobeDCT adobeDCT, Frame startOfFrame, JPEGColorSpace sourceCSType)
void
dispose()
private java.awt.color.ICC_Profile
ensureDisplayProfile(java.awt.color.ICC_Profile profile)
(package private) AdobeDCT
getAdobeDCT()
(package private) java.util.List<Application>
getAppSegments(int marker, java.lang.String identifier)
javax.imageio.ImageReadParam
getDefaultReadParam()
(package private) java.awt.color.ICC_Profile
getEmbeddedICCProfile(boolean allowBadIndexes)
private EXIF
getExif()
java.lang.String
getFormatName()
int
getHeight(int imageIndex)
javax.imageio.metadata.IIOMetadata
getImageMetadata(int imageIndex)
Default implementation that always returnsnull
.java.util.Iterator<javax.imageio.ImageTypeSpecifier>
getImageTypes(int imageIndex)
(package private) JFIF
getJFIF()
(package private) JFXX
getJFXX()
int
getNumImages(boolean allowSearch)
Default implementation that always returns1
.int
getNumThumbnails(int imageIndex)
javax.imageio.ImageTypeSpecifier
getRawImageType(int imageIndex)
(package private) Frame
getSOF()
(package private) static JPEGColorSpace
getSourceCSType(JFIF jfif, AdobeDCT adobeDCT, Frame startOfFrame)
javax.imageio.metadata.IIOMetadata
getStreamMetadata()
Default implementation that always returnsnull
.int
getThumbnailHeight(int imageIndex, int thumbnailIndex)
(package private) javax.imageio.ImageReader
getThumbnailReader()
int
getThumbnailWidth(int imageIndex, int thumbnailIndex)
int
getWidth(int imageIndex)
private void
gotoImage(int imageIndex)
private void
initDelegate(boolean seekForwardOnly, boolean ignoreMetadata)
private void
initHeader()
private void
initHeader(int imageIndex)
private void
installListeners()
(package private) static int
intFromBigEndian(byte[] array, int index)
(package private) static void
intToBigEndian(int value, byte[] array, int index)
private static void
invertCMYK(java.awt.image.Raster raster)
private boolean
isLossless()
private Application
lastAppSegment(int marker, java.lang.String identifier)
static void
main(java.lang.String[] args)
private CompoundDirectory
parseExif(EXIF exif)
protected void
processWarningOccurred(java.lang.String warning)
java.awt.image.BufferedImage
read(int imageIndex, javax.imageio.ImageReadParam param)
java.awt.image.RenderedImage
readAsRenderedImage(int imageIndex, javax.imageio.ImageReadParam param)
boolean
readerSupportsThumbnails()
private java.awt.color.ICC_Profile
readICCProfileSafe(java.io.InputStream stream, boolean allowBadProfile)
private java.awt.image.BufferedImage
readImageAsRasterAndReplaceColorProfile(int imageIndex, javax.imageio.ImageReadParam param, Frame startOfFrame, JPEGColorSpace csType, java.awt.color.ICC_Profile profile)
java.awt.image.Raster
readRaster(int imageIndex, javax.imageio.ImageReadParam param)
private java.util.List<JPEGSegment>
readSegments()
java.awt.image.BufferedImage
readThumbnail(int imageIndex, int thumbnailIndex)
private void
readThumbnailMetadata(int imageIndex)
protected void
resetMembers()
Resets all member variables.void
setInput(java.lang.Object input, boolean seekForwardOnly, boolean ignoreMetadata)
OverridessetInput
, to allow easy access to the input, in case it is anImageInputStream
.protected static void
showIt(java.awt.image.BufferedImage pImage, java.lang.String pTitle)
-
Methods inherited from class com.twelvemonkeys.imageio.ImageReaderBase
assertInput, checkBounds, fakeAOI, fakeSubsampling, getDestination, hasExplicitDestination, reset
-
Methods inherited from class javax.imageio.ImageReader
abortRequested, addIIOReadProgressListener, addIIOReadUpdateListener, addIIOReadWarningListener, checkReadParamBandSettings, clearAbortRequest, computeRegions, getAspectRatio, getAvailableLocales, getImageMetadata, getInput, getLocale, getMinIndex, getOriginatingProvider, getSourceRegion, getStreamMetadata, getTileGridXOffset, getTileGridYOffset, getTileHeight, getTileWidth, hasThumbnails, isIgnoringMetadata, isImageTiled, isRandomAccessEasy, isSeekForwardOnly, processImageComplete, processImageProgress, processImageStarted, processImageUpdate, processPassComplete, processPassStarted, processReadAborted, processSequenceComplete, processSequenceStarted, processThumbnailComplete, processThumbnailPassComplete, processThumbnailPassStarted, processThumbnailProgress, processThumbnailStarted, processThumbnailUpdate, processWarningOccurred, read, readAll, readAll, readTile, readTileRaster, removeAllIIOReadProgressListeners, removeAllIIOReadUpdateListeners, removeAllIIOReadWarningListeners, removeIIOReadProgressListener, removeIIOReadUpdateListener, removeIIOReadWarningListener, setInput, setInput, setLocale
-
-
-
-
Field Detail
-
DEBUG
static final boolean DEBUG
-
FORCE_RASTER_CONVERSION
static final boolean FORCE_RASTER_CONVERSION
-
ALL_APP_MARKERS
static final int ALL_APP_MARKERS
Internal constant for referring all APP segments- See Also:
- Constant Field Values
-
delegate
private final javax.imageio.ImageReader delegate
Our JPEG reading delegate
-
progressDelegator
private final JPEGImageReader.ProgressDelegator progressDelegator
Listens to progress updates in the delegate, and delegates back to this instance
-
thumbnailReader
private javax.imageio.ImageReader thumbnailReader
Extra delegate for reading JPEG encoded thumbnails
-
thumbnails
private java.util.List<ThumbnailReader> thumbnails
-
segments
private java.util.List<Segment> segments
Cached list of JPEG segments we filter from the underlying stream
-
currentStreamIndex
private int currentStreamIndex
-
streamOffsets
private final java.util.List<java.lang.Long> streamOffsets
-
-
Method Detail
-
installListeners
private void installListeners()
-
resetMembers
protected void resetMembers()
Description copied from class:ImageReaderBase
Resets all member variables. This method is by default invoked from:- Specified by:
resetMembers
in classImageReaderBase
-
dispose
public void dispose()
- Overrides:
dispose
in classImageReaderBase
-
getFormatName
public java.lang.String getFormatName() throws java.io.IOException
- Overrides:
getFormatName
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
isLossless
private boolean isLossless() throws java.io.IOException
- Throws:
java.io.IOException
-
getWidth
public int getWidth(int imageIndex) throws java.io.IOException
- Specified by:
getWidth
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
getHeight
public int getHeight(int imageIndex) throws java.io.IOException
- Specified by:
getHeight
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
getImageTypes
public java.util.Iterator<javax.imageio.ImageTypeSpecifier> getImageTypes(int imageIndex) throws java.io.IOException
- Specified by:
getImageTypes
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
getRawImageType
public javax.imageio.ImageTypeSpecifier getRawImageType(int imageIndex) throws java.io.IOException
- Overrides:
getRawImageType
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
read
public java.awt.image.BufferedImage read(int imageIndex, javax.imageio.ImageReadParam param) throws java.io.IOException
- Specified by:
read
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
delegateCSTypeMismatch
private boolean delegateCSTypeMismatch(JFIF jfif, AdobeDCT adobeDCT, Frame startOfFrame, JPEGColorSpace sourceCSType) throws java.io.IOException
- Throws:
java.io.IOException
-
readImageAsRasterAndReplaceColorProfile
private java.awt.image.BufferedImage readImageAsRasterAndReplaceColorProfile(int imageIndex, javax.imageio.ImageReadParam param, Frame startOfFrame, JPEGColorSpace csType, java.awt.color.ICC_Profile profile) throws java.io.IOException
- Throws:
java.io.IOException
-
getSourceCSType
static JPEGColorSpace getSourceCSType(JFIF jfif, AdobeDCT adobeDCT, Frame startOfFrame) throws javax.imageio.IIOException
- Throws:
javax.imageio.IIOException
-
ensureDisplayProfile
private java.awt.color.ICC_Profile ensureDisplayProfile(java.awt.color.ICC_Profile profile) throws java.io.IOException
- Throws:
java.io.IOException
-
intFromBigEndian
static int intFromBigEndian(byte[] array, int index)
-
intToBigEndian
static void intToBigEndian(int value, byte[] array, int index)
-
setInput
public void setInput(java.lang.Object input, boolean seekForwardOnly, boolean ignoreMetadata)
Description copied from class:ImageReaderBase
OverridessetInput
, to allow easy access to the input, in case it is anImageInputStream
.- Overrides:
setInput
in classImageReaderBase
- Parameters:
input
- theImageInputStream
or otherObject
to use for future decoding.seekForwardOnly
- iftrue
, images and metadata may only be read in ascending order from this input source.ignoreMetadata
- iftrue
, metadata may be ignored during reads.- See Also:
ImageInputStream
-
initDelegate
private void initDelegate(boolean seekForwardOnly, boolean ignoreMetadata) throws java.io.IOException
- Throws:
java.io.IOException
-
initHeader
private void initHeader() throws java.io.IOException
- Throws:
java.io.IOException
-
initHeader
private void initHeader(int imageIndex) throws java.io.IOException
- Throws:
java.io.IOException
-
gotoImage
private void gotoImage(int imageIndex) throws java.io.IOException
- Throws:
java.io.IOException
-
getNumImages
public int getNumImages(boolean allowSearch) throws java.io.IOException
Description copied from class:ImageReaderBase
Default implementation that always returns1
.- Overrides:
getNumImages
in classImageReaderBase
- Parameters:
allowSearch
- ignored, unless overridden- Returns:
1
, unless overridden- Throws:
java.io.IOException
- never, unless overridden
-
readSegments
private java.util.List<JPEGSegment> readSegments() throws java.io.IOException
- Throws:
java.io.IOException
-
getAppSegments
java.util.List<Application> getAppSegments(int marker, java.lang.String identifier) throws java.io.IOException
- Throws:
java.io.IOException
-
getSOF
Frame getSOF() throws java.io.IOException
- Throws:
java.io.IOException
-
lastAppSegment
private Application lastAppSegment(int marker, java.lang.String identifier) throws java.io.IOException
- Throws:
java.io.IOException
-
getAdobeDCT
AdobeDCT getAdobeDCT() throws java.io.IOException
- Throws:
java.io.IOException
-
getJFIF
JFIF getJFIF() throws java.io.IOException
- Throws:
java.io.IOException
-
getJFXX
JFXX getJFXX() throws java.io.IOException
- Throws:
java.io.IOException
-
getExif
private EXIF getExif() throws java.io.IOException
- Throws:
java.io.IOException
-
parseExif
private CompoundDirectory parseExif(EXIF exif) throws java.io.IOException
- Throws:
java.io.IOException
-
getEmbeddedICCProfile
java.awt.color.ICC_Profile getEmbeddedICCProfile(boolean allowBadIndexes) throws java.io.IOException
- Throws:
java.io.IOException
-
readICCProfileSafe
private java.awt.color.ICC_Profile readICCProfileSafe(java.io.InputStream stream, boolean allowBadProfile)
-
canReadRaster
public boolean canReadRaster()
- Overrides:
canReadRaster
in classjavax.imageio.ImageReader
-
readRaster
public java.awt.image.Raster readRaster(int imageIndex, javax.imageio.ImageReadParam param) throws java.io.IOException
- Overrides:
readRaster
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
readAsRenderedImage
public java.awt.image.RenderedImage readAsRenderedImage(int imageIndex, javax.imageio.ImageReadParam param) throws java.io.IOException
- Overrides:
readAsRenderedImage
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
abort
public void abort()
- Overrides:
abort
in classjavax.imageio.ImageReader
-
getDefaultReadParam
public javax.imageio.ImageReadParam getDefaultReadParam()
- Overrides:
getDefaultReadParam
in classjavax.imageio.ImageReader
-
readerSupportsThumbnails
public boolean readerSupportsThumbnails()
- Overrides:
readerSupportsThumbnails
in classjavax.imageio.ImageReader
-
readThumbnailMetadata
private void readThumbnailMetadata(int imageIndex) throws java.io.IOException
- Throws:
java.io.IOException
-
getThumbnailReader
javax.imageio.ImageReader getThumbnailReader() throws java.io.IOException
- Throws:
java.io.IOException
-
getNumThumbnails
public int getNumThumbnails(int imageIndex) throws java.io.IOException
- Overrides:
getNumThumbnails
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
checkThumbnailBounds
private void checkThumbnailBounds(int imageIndex, int thumbnailIndex) throws java.io.IOException
- Throws:
java.io.IOException
-
getThumbnailWidth
public int getThumbnailWidth(int imageIndex, int thumbnailIndex) throws java.io.IOException
- Overrides:
getThumbnailWidth
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
getThumbnailHeight
public int getThumbnailHeight(int imageIndex, int thumbnailIndex) throws java.io.IOException
- Overrides:
getThumbnailHeight
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
readThumbnail
public java.awt.image.BufferedImage readThumbnail(int imageIndex, int thumbnailIndex) throws java.io.IOException
- Overrides:
readThumbnail
in classjavax.imageio.ImageReader
- Throws:
java.io.IOException
-
getImageMetadata
public javax.imageio.metadata.IIOMetadata getImageMetadata(int imageIndex) throws java.io.IOException
Description copied from class:ImageReaderBase
Default implementation that always returnsnull
.- Overrides:
getImageMetadata
in classImageReaderBase
- Parameters:
imageIndex
- ignored, unless overridden- Returns:
null
, unless overridden- Throws:
java.io.IOException
- never, unless overridden.
-
getStreamMetadata
public javax.imageio.metadata.IIOMetadata getStreamMetadata() throws java.io.IOException
Description copied from class:ImageReaderBase
Default implementation that always returnsnull
.- Overrides:
getStreamMetadata
in classImageReaderBase
- Returns:
null
, unless overridden- Throws:
java.io.IOException
- never, unless overridden.
-
processWarningOccurred
protected void processWarningOccurred(java.lang.String warning)
- Overrides:
processWarningOccurred
in classjavax.imageio.ImageReader
-
invertCMYK
private static void invertCMYK(java.awt.image.Raster raster)
-
convertYCbCr2RGB
private static void convertYCbCr2RGB(java.awt.image.Raster raster, int numComponents)
-
convertYCCK2CMYK
private static void convertYCCK2CMYK(java.awt.image.Raster raster)
-
showIt
protected static void showIt(java.awt.image.BufferedImage pImage, java.lang.String pTitle)
-
main
public static void main(java.lang.String[] args) throws java.io.IOException
- Throws:
java.io.IOException
-
-