#280 Support for bitsPerSample == 6, 10, 12, 14 & 24

This commit is contained in:
Harald Kuhr
2016-11-16 18:52:39 +01:00
parent ab13084f44
commit e0b9bdef7e
10 changed files with 573 additions and 76 deletions
@@ -29,7 +29,6 @@
package com.twelvemonkeys.imageio.util;
import com.twelvemonkeys.imageio.color.DiscreteAlphaIndexColorModel;
import com.twelvemonkeys.lang.Validate;
import javax.imageio.ImageTypeSpecifier;
import java.awt.color.ColorSpace;
@@ -84,7 +83,7 @@ public final class ImageTypeSpecifiers {
final boolean isAlphaPremultiplied) {
// As the ComponentColorModel is broken for 32 bit unsigned int, we'll use our own version
if (dataType == DataBuffer.TYPE_INT) {
return new UInt32ImageTypeSpecifier(colorSpace, bandOffsets, hasAlpha, isAlphaPremultiplied);
return UInt32ImageTypeSpecifier.createInterleaved(colorSpace, bandOffsets, hasAlpha, isAlphaPremultiplied);
}
// ...or fall back to default for anything else
@@ -95,6 +94,12 @@ public final class ImageTypeSpecifiers {
final int[] bankIndices, final int[] bandOffsets,
final int dataType,
final boolean hasAlpha, final boolean isAlphaPremultiplied) {
// As the ComponentColorModel is broken for 32 bit unsigned int, we'll use our own version
if (dataType == DataBuffer.TYPE_INT) {
return UInt32ImageTypeSpecifier.createBanded(colorSpace, bankIndices, bandOffsets, hasAlpha, isAlphaPremultiplied);
}
// ...or fall back to default for anything else
return ImageTypeSpecifier.createBanded(colorSpace, bankIndices, bandOffsets, dataType, hasAlpha, isAlphaPremultiplied);
}
@@ -105,7 +110,7 @@ public final class ImageTypeSpecifiers {
}
else if (bits == 32 && dataType == DataBuffer.TYPE_INT) {
// As the ComponentColorModel is broken for 32 bit unsigned int, we'll use our own version
return new UInt32ImageTypeSpecifier(ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] {0}, false, false);
return UInt32ImageTypeSpecifier.createInterleaved(ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] {0}, false, false);
}
// NOTE: The isSigned boolean is stored but *not used for anything* in the Grayscale ImageTypeSpecifier...
@@ -119,7 +124,7 @@ public final class ImageTypeSpecifiers {
}
else if (bits == 32 && dataType == DataBuffer.TYPE_INT) {
// As the ComponentColorModel is broken for 32 bit unsigned int, we'll use our own version
return new UInt32ImageTypeSpecifier(ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] {0, 1}, true, isAlphaPremultiplied);
return UInt32ImageTypeSpecifier.createInterleaved(ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] {0, 1}, true, isAlphaPremultiplied);
}
// NOTE: The isSigned boolean is stored but *not used for anything* in the Grayscale ImageTypeSpecifier...
@@ -166,7 +171,7 @@ public final class ImageTypeSpecifiers {
}
public static ImageTypeSpecifier createFromIndexColorModel(final IndexColorModel pColorModel) {
return new IndexedImageTypeSpecifier(pColorModel);
return IndexedImageTypeSpecifier.createFromIndexColorModel(pColorModel);
}
public static ImageTypeSpecifier createDiscreteAlphaIndexedFromIndexColorModel(final IndexColorModel pColorModel) {
@@ -15,24 +15,27 @@ import static com.twelvemonkeys.lang.Validate.notNull;
* @author last modified by $Author: haraldk$
* @version $Id: IndexedImageTypeSpecifier.java,v 1.0 May 19, 2008 11:04:28 AM haraldk Exp$
*/
final class IndexedImageTypeSpecifier extends ImageTypeSpecifier {
IndexedImageTypeSpecifier(final IndexColorModel pColorModel) {
// For some reason, we need a sample model
super(notNull(pColorModel, "colorModel"), pColorModel.createCompatibleSampleModel(1, 1));
}
final class IndexedImageTypeSpecifier {
private IndexedImageTypeSpecifier() {}
@Override
public final BufferedImage createBufferedImage(final int pWidth, final int pHeight) {
try {
// This is a fix for the super-method, that first creates a sample model, and then
// creates a raster from it, using Raster.createWritableRaster. The problem with
// that approach, is that it always creates a TYPE_CUSTOM BufferedImage for indexed images.
WritableRaster raster = colorModel.createCompatibleWritableRaster(pWidth, pHeight);
return new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), new Hashtable());
}
catch (NegativeArraySizeException e) {
// Exception most likely thrown from a DataBuffer constructor
throw new IllegalArgumentException("Array size > Integer.MAX_VALUE!");
}
static ImageTypeSpecifier createFromIndexColorModel(final IndexColorModel pColorModel) {
// For some reason, we need a sample model
return new ImageTypeSpecifier(notNull(pColorModel, "colorModel"), pColorModel.createCompatibleSampleModel(1, 1)) {
@Override
public final BufferedImage createBufferedImage(final int pWidth, final int pHeight) {
try {
// This is a fix for the super-method, that first creates a sample model, and then
// creates a raster from it, using Raster.createWritableRaster. The problem with
// that approach, is that it always creates a TYPE_CUSTOM BufferedImage for indexed images.
WritableRaster raster = colorModel.createCompatibleWritableRaster(pWidth, pHeight);
return new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), new Hashtable());
}
catch (NegativeArraySizeException e) {
// Exception most likely thrown from a DataBuffer constructor
throw new IllegalArgumentException("Array size > Integer.MAX_VALUE!");
}
}
};
}
}
@@ -32,8 +32,10 @@ import com.twelvemonkeys.imageio.color.UInt32ColorModel;
import javax.imageio.ImageTypeSpecifier;
import java.awt.color.ColorSpace;
import java.awt.image.BandedSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.SampleModel;
/**
* ImageTypeSpecifier for interleaved 32 bit unsigned integral samples.
@@ -43,10 +45,12 @@ import java.awt.image.PixelInterleavedSampleModel;
* @author last modified by $Author: haraldk$
* @version $Id: UInt32ImageTypeSpecifier.java,v 1.0 24.01.11 17.51 haraldk Exp$
*/
final class UInt32ImageTypeSpecifier extends ImageTypeSpecifier {
UInt32ImageTypeSpecifier(final ColorSpace cs, int[] bandOffsets, final boolean hasAlpha, final boolean isAlphaPremultiplied) {
super(
new UInt32ColorModel(cs, hasAlpha, isAlphaPremultiplied),
final class UInt32ImageTypeSpecifier {
private UInt32ImageTypeSpecifier() {}
static ImageTypeSpecifier createInterleaved(final ColorSpace cs, final int[] bandOffsets, final boolean hasAlpha, final boolean isAlphaPremultiplied) {
return create(
cs, hasAlpha, isAlphaPremultiplied,
new PixelInterleavedSampleModel(
DataBuffer.TYPE_INT, 1, 1,
cs.getNumComponents() + (hasAlpha ? 1 : 0),
@@ -55,4 +59,18 @@ final class UInt32ImageTypeSpecifier extends ImageTypeSpecifier {
)
);
}
static ImageTypeSpecifier createBanded(final ColorSpace cs, final int[] bandIndices, final int[] bandOffsets, final boolean hasAlpha, final boolean isAlphaPremultiplied) {
return create(
cs, hasAlpha, isAlphaPremultiplied,
new BandedSampleModel(
DataBuffer.TYPE_INT, 1, 1, 1,
bandIndices, bandOffsets
)
);
}
private static ImageTypeSpecifier create(final ColorSpace cs, final boolean hasAlpha, final boolean isAlphaPremultiplied, final SampleModel sampleModel) {
return new ImageTypeSpecifier(new UInt32ColorModel(cs, hasAlpha, isAlphaPremultiplied), sampleModel);
}
}