mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 12:05:29 -04:00
Implemted thumbnail support.
This commit is contained in:
parent
1a67e1721e
commit
a86cf5bf15
@ -95,7 +95,11 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageTypeSpecifier getRawImageType(int pIndex) throws IOException {
|
public ImageTypeSpecifier getRawImageType(final int pIndex) throws IOException {
|
||||||
|
return getRawImageTypeInternal(pIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageTypeSpecifier getRawImageTypeInternal(final int pIndex) throws IOException {
|
||||||
checkBounds(pIndex);
|
checkBounds(pIndex);
|
||||||
readHeader();
|
readHeader();
|
||||||
|
|
||||||
@ -193,7 +197,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
// Could use similar concept to create lazily-created ImageTypeSpecifiers (util candidate, based on FilterIterator?)
|
// Could use similar concept to create lazily-created ImageTypeSpecifiers (util candidate, based on FilterIterator?)
|
||||||
|
|
||||||
// Get the raw type. Will fail for unsupported types
|
// Get the raw type. Will fail for unsupported types
|
||||||
ImageTypeSpecifier rawType = getRawImageType(pIndex);
|
ImageTypeSpecifier rawType = getRawImageTypeInternal(pIndex);
|
||||||
|
|
||||||
ColorSpace cs = rawType.getColorModel().getColorSpace();
|
ColorSpace cs = rawType.getColorModel().getColorSpace();
|
||||||
List<ImageTypeSpecifier> types = new ArrayList<ImageTypeSpecifier>();
|
List<ImageTypeSpecifier> types = new ArrayList<ImageTypeSpecifier>();
|
||||||
@ -264,18 +268,19 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
return mColorSpace;
|
return mColorSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
|
public BufferedImage read(final int pIndex, final ImageReadParam pParam) throws IOException {
|
||||||
checkBounds(pIndex);
|
checkBounds(pIndex);
|
||||||
|
|
||||||
readHeader();
|
readHeader();
|
||||||
|
|
||||||
processImageStarted(pIndex);
|
|
||||||
|
|
||||||
readImageResources(false);
|
readImageResources(false);
|
||||||
readLayerAndMaskInfo(false);
|
readLayerAndMaskInfo(false);
|
||||||
|
|
||||||
|
// TODO: Test if explicit destination is compatible or throw IllegalArgumentException
|
||||||
BufferedImage image = getDestination(pParam, getImageTypes(pIndex), mHeader.mWidth, mHeader.mHeight);
|
BufferedImage image = getDestination(pParam, getImageTypes(pIndex), mHeader.mWidth, mHeader.mHeight);
|
||||||
|
|
||||||
|
processImageStarted(pIndex);
|
||||||
|
|
||||||
final Rectangle source = new Rectangle();
|
final Rectangle source = new Rectangle();
|
||||||
final Rectangle dest = new Rectangle();
|
final Rectangle dest = new Rectangle();
|
||||||
computeRegions(pParam, mHeader.mWidth, mHeader.mHeight, image, source, dest);
|
computeRegions(pParam, mHeader.mWidth, mHeader.mHeight, image, source, dest);
|
||||||
@ -339,19 +344,7 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
throw new IIOException("Unknown compression type: " + compression);
|
throw new IIOException("Unknown compression type: " + compression);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mHeader.mBits) {
|
readImageData(image, source, dest, xSub, ySub, offsets, compression);
|
||||||
case 1:
|
|
||||||
read1bitData(image.getRaster(), image.getColorModel(), source, dest, xSub, ySub, offsets, compression == PSD.COMPRESSION_RLE);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
read8bitData(image.getRaster(), image.getColorModel(), source, dest, xSub, ySub, offsets, compression == PSD.COMPRESSION_RLE);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
read16bitData(image.getRaster(), image.getColorModel(), source, dest, xSub, ySub, offsets, compression == PSD.COMPRESSION_RLE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IIOException("Unknown bit depth: " + mHeader.mBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abortRequested()) {
|
if (abortRequested()) {
|
||||||
processReadAborted();
|
processReadAborted();
|
||||||
@ -363,11 +356,31 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readImageData(final BufferedImage pImage,
|
||||||
|
final Rectangle pSource, final Rectangle pDest,
|
||||||
|
final int pXSub, final int pYSub,
|
||||||
|
final int[] pOffsets, final int pCompression) throws IOException {
|
||||||
|
// TODO: Refactor so that we loop through channels here, and read one channel in each of the methods below
|
||||||
|
|
||||||
|
switch (mHeader.mBits) {
|
||||||
|
case 1:
|
||||||
|
read1bitData(pImage.getRaster(), pImage.getColorModel(), pSource, pDest, pXSub, pYSub, pOffsets, pCompression == PSD.COMPRESSION_RLE);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
read8bitData(pImage.getRaster(), pImage.getColorModel(), pSource, pDest, pXSub, pYSub, pOffsets, pCompression == PSD.COMPRESSION_RLE);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
read16bitData(pImage.getRaster(), pImage.getColorModel(), pSource, pDest, pXSub, pYSub, pOffsets, pCompression == PSD.COMPRESSION_RLE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IIOException("Unknown bit depth: " + mHeader.mBits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void read16bitData(final WritableRaster pRaster, final ColorModel pDestinationColorModel,
|
private void read16bitData(final WritableRaster pRaster, final ColorModel pDestinationColorModel,
|
||||||
final Rectangle pSource, final Rectangle pDest,
|
final Rectangle pSource, final Rectangle pDest,
|
||||||
final int pXSub, final int pYSub,
|
final int pXSub, final int pYSub,
|
||||||
final int[] pRowOffsets, final boolean pRLECompressed) throws IOException
|
final int[] pRowOffsets, final boolean pRLECompressed) throws IOException {
|
||||||
{
|
|
||||||
final int channels = pRaster.getNumBands();
|
final int channels = pRaster.getNumBands();
|
||||||
|
|
||||||
// TODO: FixMe: Use real source color model from native (raw) image type, and convert if needed
|
// TODO: FixMe: Use real source color model from native (raw) image type, and convert if needed
|
||||||
@ -872,6 +885,78 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Thumbnail support
|
||||||
|
@Override
|
||||||
|
public boolean readerSupportsThumbnails() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PSDThumbnail> getThumbnailResources(final int pIndex) throws IOException {
|
||||||
|
checkBounds(pIndex);
|
||||||
|
|
||||||
|
readHeader();
|
||||||
|
|
||||||
|
List<PSDThumbnail> thumbnails = null;
|
||||||
|
|
||||||
|
if (mImageResources != null) {
|
||||||
|
// TODO: Need flag here, to specify what resources to read...
|
||||||
|
readImageResources(true);
|
||||||
|
// TODO: Skip this, requires storing some stream offsets
|
||||||
|
readLayerAndMaskInfo(false);
|
||||||
|
|
||||||
|
for (PSDImageResource resource : mImageResources) {
|
||||||
|
if (resource instanceof PSDThumbnail) {
|
||||||
|
if (thumbnails == null) {
|
||||||
|
thumbnails = new ArrayList<PSDThumbnail>();
|
||||||
|
}
|
||||||
|
thumbnails.add((PSDThumbnail) resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnails;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumThumbnails(int pIndex) throws IOException {
|
||||||
|
List<PSDThumbnail> thumbnails = getThumbnailResources(pIndex);
|
||||||
|
|
||||||
|
if (thumbnails == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnails.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getThumbnailWidth(int imageIndex, int thumbnailIndex) throws IOException {
|
||||||
|
// TODO: We could get this without decoding the thumbnail first
|
||||||
|
return super.getThumbnailWidth(imageIndex, thumbnailIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getThumbnailHeight(int imageIndex, int thumbnailIndex) throws IOException {
|
||||||
|
// TODO: We could get this without decoding the thumbnail first
|
||||||
|
return super.getThumbnailHeight(imageIndex, thumbnailIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage readThumbnail(int pImageIndex, int pThumbnailIndex) throws IOException {
|
||||||
|
// TODO: Thumbnail listeners...
|
||||||
|
List<PSDThumbnail> thumbnails = getThumbnailResources(pImageIndex);
|
||||||
|
if (thumbnails == null) {
|
||||||
|
throw new IndexOutOfBoundsException(String.format("%d > 0", pThumbnailIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Defer decoding
|
||||||
|
// TODO: It's possible to attach listeners to the ImageIO reader delegate... But do we really care?
|
||||||
|
processThumbnailStarted(pImageIndex, pThumbnailIndex);
|
||||||
|
processThumbnailComplete();
|
||||||
|
|
||||||
|
return thumbnails.get(pThumbnailIndex).getThumbnail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Functional testing
|
||||||
public static void main(final String[] pArgs) throws IOException {
|
public static void main(final String[] pArgs) throws IOException {
|
||||||
int subsampleFactor = 1;
|
int subsampleFactor = 1;
|
||||||
Rectangle sourceRegion = null;
|
Rectangle sourceRegion = null;
|
||||||
@ -924,6 +1009,13 @@ public class PSDImageReader extends ImageReaderBase {
|
|||||||
System.out.println("imageReader.mLayerInfo: " + imageReader.mLayerInfo);
|
System.out.println("imageReader.mLayerInfo: " + imageReader.mLayerInfo);
|
||||||
System.out.println("imageReader.mGlobalLayerMask: " + imageReader.mGlobalLayerMask);
|
System.out.println("imageReader.mGlobalLayerMask: " + imageReader.mGlobalLayerMask);
|
||||||
|
|
||||||
|
if (imageReader.hasThumbnails(0)) {
|
||||||
|
int thumbnails = imageReader.getNumThumbnails(0);
|
||||||
|
for (int i = 0; i < thumbnails; i++) {
|
||||||
|
showIt(imageReader.readThumbnail(0, i), String.format("Thumbnail %d", i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
ImageReadParam param = imageReader.getDefaultReadParam();
|
ImageReadParam param = imageReader.getDefaultReadParam();
|
||||||
|
1
twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java
Executable file → Normal file
1
twelvemonkeys-imageio/psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDThumbnail.java
Executable file → Normal file
@ -65,6 +65,7 @@ class PSDThumbnail extends PSDImageResource {
|
|||||||
// TODO: Warning/Exception
|
// TODO: Warning/Exception
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Defer decoding until getThumbnail?
|
||||||
// TODO: Support BGR if id == RES_THUMBNAIL_PS4? Or is that already supported in the JPEG?
|
// TODO: Support BGR if id == RES_THUMBNAIL_PS4? Or is that already supported in the JPEG?
|
||||||
mThumbnail = ImageIO.read(IIOUtil.createStreamAdapter(pInput, sizeCompressed));
|
mThumbnail = ImageIO.read(IIOUtil.createStreamAdapter(pInput, sizeCompressed));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user