mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 20:15:28 -04:00
TMI-140: JPEG with corrupted ICC profile (new kind) can now be read.
This commit is contained in:
parent
c97ebae303
commit
bbaa3e1186
@ -161,6 +161,11 @@ public final class ColorSpaces {
|
||||
|
||||
if (cs == null) {
|
||||
cs = new ICC_ColorSpace(profile);
|
||||
|
||||
// Validate the color space, to avoid caching bad color spaces
|
||||
// Will throw IllegalArgumentException or CMMException if the profile is bad
|
||||
cs.fromRGB(new float[] {1f, 0f, 0f});
|
||||
|
||||
cache.put(key, cs);
|
||||
}
|
||||
|
||||
@ -195,7 +200,7 @@ public final class ColorSpaces {
|
||||
* @return {@code true} if known to be offending, {@code false} otherwise
|
||||
* @throws IllegalArgumentException if {@code profile} is {@code null}
|
||||
*/
|
||||
public static boolean isOffendingColorProfile(final ICC_Profile profile) {
|
||||
static boolean isOffendingColorProfile(final ICC_Profile profile) {
|
||||
Validate.notNull(profile, "profile");
|
||||
|
||||
// NOTE:
|
||||
@ -213,6 +218,26 @@ public final class ColorSpaces {
|
||||
return data[ICC_Profile.icHdrRenderingIntent] != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether an ICC color profile is valid.
|
||||
* Invalid profiles are known to cause problems for {@link java.awt.image.ColorConvertOp}.
|
||||
* <p />
|
||||
* <em>
|
||||
* Note that this method only tests if a color conversion using this profile is known to fail.
|
||||
* There's no guarantee that the color conversion will succeed even if this method returns {@code false}.
|
||||
* </em>
|
||||
*
|
||||
* @param profile the ICC color profile. May not be {@code null}.
|
||||
* @return {@code profile} if valid.
|
||||
* @throws IllegalArgumentException if {@code profile} is {@code null}
|
||||
* @throws java.awt.color.CMMException if {@code profile} is invalid.
|
||||
*/
|
||||
public static ICC_Profile validateProfile(final ICC_Profile profile) {
|
||||
createColorSpace(profile); // Creating a color space will fail if the profile is bad
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color space specified by the given color space constant.
|
||||
* <p />
|
||||
|
@ -409,6 +409,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
if (DEBUG) {
|
||||
System.err.println("Converting from " + intendedCS + " to " + (image.getColorModel().getColorSpace().isCS_sRGB() ? "sRGB" : image.getColorModel().getColorSpace()));
|
||||
}
|
||||
|
||||
convert = new ColorConvertOp(intendedCS, image.getColorModel().getColorSpace(), null);
|
||||
}
|
||||
// Else, pass through with no conversion
|
||||
@ -858,7 +859,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
return readICCProfileSafe(stream);
|
||||
return readICCProfileSafe(stream, allowBadIndexes);
|
||||
}
|
||||
else if (!segments.isEmpty()) {
|
||||
// NOTE: This is probably over-complicated, as I've never encountered ICC_PROFILE chunks out of order...
|
||||
@ -905,15 +906,17 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
streams[badICC ? i : chunkNumber - 1] = stream;
|
||||
}
|
||||
|
||||
return readICCProfileSafe(new SequenceInputStream(Collections.enumeration(Arrays.asList(streams))));
|
||||
return readICCProfileSafe(new SequenceInputStream(Collections.enumeration(Arrays.asList(streams))), allowBadIndexes);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ICC_Profile readICCProfileSafe(final InputStream stream) throws IOException {
|
||||
private ICC_Profile readICCProfileSafe(final InputStream stream, final boolean allowBadProfile) throws IOException {
|
||||
try {
|
||||
return ICC_Profile.getInstance(stream);
|
||||
ICC_Profile profile = ICC_Profile.getInstance(stream);
|
||||
|
||||
return allowBadProfile ? profile : ColorSpaces.validateProfile(profile);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
// NOTE: Throws either IllegalArgumentException or CMMException, depending on platform.
|
||||
@ -1306,6 +1309,8 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
|
||||
int subX = 1;
|
||||
int subY = 1;
|
||||
int xOff = 0;
|
||||
int yOff = 0;
|
||||
Rectangle roi = null;
|
||||
boolean metadata = false;
|
||||
boolean thumbnails = false;
|
||||
@ -1318,9 +1323,17 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
String[] sub = args[++argIdx].split(",");
|
||||
|
||||
try {
|
||||
if (sub.length >= 4) {
|
||||
subX = Integer.parseInt(sub[0]);
|
||||
subY = Integer.parseInt(sub[1]);
|
||||
xOff = Integer.parseInt(sub[2]);
|
||||
yOff = Integer.parseInt(sub[3]);
|
||||
}
|
||||
else {
|
||||
subX = Integer.parseInt(sub[0]);
|
||||
subY = sub.length > 1 ? Integer.parseInt(sub[1]) : subX;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
System.err.println("Bad sub sampling (x,y): '" + args[argIdx] + "'");
|
||||
}
|
||||
@ -1423,7 +1436,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
BufferedImage image;
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
if (subX > 1 || subY > 1 || roi != null) {
|
||||
param.setSourceSubsampling(subX, subY, 0, 0);
|
||||
param.setSourceSubsampling(subX, subY, xOff, yOff);
|
||||
param.setSourceRegion(roi);
|
||||
|
||||
image = reader.getImageTypes(0).next().createBufferedImage((reader.getWidth(0) + subX - 1)/ subX, (reader.getHeight(0) + subY - 1) / subY);
|
||||
|
@ -86,6 +86,7 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTest<JPEGImageReader
|
||||
return Arrays.asList(
|
||||
new TestData(getClassLoaderResource("/jpeg/cmm-exception-adobe-rgb.jpg"), new Dimension(626, 76)),
|
||||
new TestData(getClassLoaderResource("/jpeg/cmm-exception-srgb.jpg"), new Dimension(1800, 1200)),
|
||||
new TestData(getClassLoaderResource("/jpeg/corrupted-icc-srgb.jpg"), new Dimension(1024, 685)),
|
||||
new TestData(getClassLoaderResource("/jpeg/gray-sample.jpg"), new Dimension(386, 396)),
|
||||
new TestData(getClassLoaderResource("/jpeg/cmyk-sample.jpg"), new Dimension(160, 227)),
|
||||
new TestData(getClassLoaderResource("/jpeg/cmyk-sample-multiple-chunk-icc.jpg"), new Dimension(2707, 3804)),
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 242 KiB |
Loading…
x
Reference in New Issue
Block a user