mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-10-04 11:26:44 -04:00
#841: Filter out incompatible ICC profiles
This commit is contained in:
@@ -77,6 +77,11 @@ final class WebPImageReader extends ImageReaderBase {
|
|||||||
// Either VP8_, VP8L or VP8X chunk
|
// Either VP8_, VP8L or VP8X chunk
|
||||||
private long fileSize;
|
private long fileSize;
|
||||||
private VP8xChunk header;
|
private VP8xChunk header;
|
||||||
|
|
||||||
|
// The ICC Profile contained in the stream, only suitable for metadata.
|
||||||
|
private ICC_Profile containedICCP;
|
||||||
|
|
||||||
|
// A safe, verified RGB ICC Profile used for color conversion.
|
||||||
private ICC_Profile iccProfile;
|
private ICC_Profile iccProfile;
|
||||||
private final List<AnimationFrame> frames = new ArrayList<>();
|
private final List<AnimationFrame> frames = new ArrayList<>();
|
||||||
|
|
||||||
@@ -88,6 +93,7 @@ final class WebPImageReader extends ImageReaderBase {
|
|||||||
protected void resetMembers() {
|
protected void resetMembers() {
|
||||||
fileSize = -1;
|
fileSize = -1;
|
||||||
header = null;
|
header = null;
|
||||||
|
containedICCP = null;
|
||||||
iccProfile = null;
|
iccProfile = null;
|
||||||
lsbBitReader = null;
|
lsbBitReader = null;
|
||||||
frames.clear();
|
frames.clear();
|
||||||
@@ -299,13 +305,20 @@ final class WebPImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
if (header.containsICCP) {
|
if (header.containsICCP) {
|
||||||
// ICCP chunk must be first chunk, if present
|
// ICCP chunk must be first chunk, if present
|
||||||
while (iccProfile == null && imageInput.getStreamPosition() < fileSize) {
|
while (containedICCP == null && imageInput.getStreamPosition() < fileSize) {
|
||||||
int nextChunk = imageInput.readInt();
|
int nextChunk = imageInput.readInt();
|
||||||
long chunkLength = imageInput.readUnsignedInt();
|
long chunkLength = imageInput.readUnsignedInt();
|
||||||
long chunkStart = imageInput.getStreamPosition();
|
long chunkStart = imageInput.getStreamPosition();
|
||||||
|
|
||||||
if (nextChunk == WebP.CHUNK_ICCP) {
|
if (nextChunk == WebP.CHUNK_ICCP) {
|
||||||
iccProfile = ColorProfiles.readProfile(IIOUtil.createStreamAdapter(imageInput, chunkLength));
|
containedICCP = ColorProfiles.readProfile(IIOUtil.createStreamAdapter(imageInput, chunkLength));
|
||||||
|
|
||||||
|
if (containedICCP.getColorSpaceType() == ColorSpace.TYPE_RGB) {
|
||||||
|
iccProfile = containedICCP;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
processWarningOccurred("Encountered non-RGB ICC Profile, ignoring color profile, colors may appear incorrect");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
processWarningOccurred(String.format("Expected 'ICCP' chunk, '%s' chunk encountered", fourCC(nextChunk)));
|
processWarningOccurred(String.format("Expected 'ICCP' chunk, '%s' chunk encountered", fourCC(nextChunk)));
|
||||||
@@ -386,9 +399,10 @@ final class WebPImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
if (iccProfile != null && !ColorProfiles.isCS_sRGB(iccProfile)) {
|
if (iccProfile != null && !ColorProfiles.isCS_sRGB(iccProfile)) {
|
||||||
ICC_ColorSpace colorSpace = ColorSpaces.createColorSpace(iccProfile);
|
ICC_ColorSpace colorSpace = ColorSpaces.createColorSpace(iccProfile);
|
||||||
int[] bandOffsets = header.containsALPH ? new int[] {0, 1, 2, 3} : new int[] {0, 1, 2};
|
int[] bandOffsets = header.containsALPH ? new int[]{0, 1, 2, 3} : new int[]{0, 1, 2};
|
||||||
return ImageTypeSpecifiers.createInterleaved(colorSpace, bandOffsets, DataBuffer.TYPE_BYTE, header.containsALPH, false);
|
return ImageTypeSpecifiers.createInterleaved(colorSpace, bandOffsets, DataBuffer.TYPE_BYTE, header.containsALPH, false);
|
||||||
}
|
}
|
||||||
|
// Non-RGB profile is simply ignored
|
||||||
|
|
||||||
return ImageTypeSpecifiers.createFromBufferedImageType(header.containsALPH ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);
|
return ImageTypeSpecifiers.createFromBufferedImageType(header.containsALPH ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,9 @@ public class WebPImageReaderTest extends ImageReaderAbstractTest<WebPImageReader
|
|||||||
new Dimension(394, 383), new Dimension(394, 394), new Dimension(372, 394),
|
new Dimension(394, 383), new Dimension(394, 394), new Dimension(372, 394),
|
||||||
new Dimension(400, 400), new Dimension(320, 382)),
|
new Dimension(400, 400), new Dimension(320, 382)),
|
||||||
// Alpha transparency and Alpha filtering
|
// Alpha transparency and Alpha filtering
|
||||||
new TestData(getClassLoaderResource("/webp/alpha_filter.webp"), new Dimension(1600, 1600))
|
new TestData(getClassLoaderResource("/webp/alpha_filter.webp"), new Dimension(1600, 1600)),
|
||||||
|
// Lossy with grayscale ICC profile
|
||||||
|
new TestData(getClassLoaderResource("/webp/incompatible-icc-gray.webp"), new Dimension(766, 1100))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
imageio/imageio-webp/src/test/resources/webp/incompatible-icc-gray.webp
Executable file
BIN
imageio/imageio-webp/src/test/resources/webp/incompatible-icc-gray.webp
Executable file
Binary file not shown.
After Width: | Height: | Size: 181 KiB |
Reference in New Issue
Block a user