#421: Fix for LCMS profile issue, due to LCMS altering the profile header on first use (ie. validation).

This commit is contained in:
Harald Kuhr 2018-04-06 20:45:38 +02:00
parent 2078843086
commit 961dee3d41
5 changed files with 39 additions and 30 deletions

View File

@ -191,6 +191,11 @@ public final class ColorSpaces {
validateColorSpace(cs);
// On LCMS, validation *alters* the profile header, need to re-generate key
key = profileCleaner.validationAltersProfileHeader()
? new Key(getProfileHeaderWithProfileId(cs.getProfile()))
: key;
cache.put(key, cs);
}

View File

@ -14,6 +14,8 @@ import java.awt.color.ICC_Profile;
interface ICCProfileSanitizer {
void fixProfile(ICC_Profile profile);
boolean validationAltersProfileHeader();
class Factory {
static ICCProfileSanitizer get() {
// Strategy pattern:

View File

@ -37,6 +37,11 @@ final class KCMSSanitizerStrategy implements ICCProfileSanitizer {
}
}
@Override
public boolean validationAltersProfileHeader() {
return false;
}
/**
* Fixes problematic 'XYZ ' tags in Corbis RGB profile.
*
@ -58,7 +63,7 @@ final class KCMSSanitizerStrategy implements ICCProfileSanitizer {
}
// TODO: Move to some common util
static int intFromBigEndian(final byte[] array, final int index) {
private static int intFromBigEndian(final byte[] array, final int index) {
return ((array[index ] & 0xff) << 24) |
((array[index + 1] & 0xff) << 16) |
((array[index + 2] & 0xff) << 8) |
@ -66,7 +71,7 @@ final class KCMSSanitizerStrategy implements ICCProfileSanitizer {
}
// TODO: Move to some common util
static void intToBigEndian(final int value, final byte[] array, final int index) {
private static void intToBigEndian(final int value, final byte[] array, final int index) {
array[index ] = (byte) (value >> 24);
array[index + 1] = (byte) (value >> 16);
array[index + 2] = (byte) (value >> 8);

View File

@ -16,4 +16,9 @@ final class LCMSSanitizerStrategy implements ICCProfileSanitizer {
Validate.notNull(profile, "profile");
// Let LCMS handle things internally for now
}
@Override
public boolean validationAltersProfileHeader() {
return true;
}
}

View File

@ -36,6 +36,7 @@ import java.awt.color.ICC_Profile;
import java.io.IOException;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;
/**
* ColorSpacesTest
@ -45,6 +46,25 @@ import static org.junit.Assert.*;
* @version $Id: ColorSpacesTest.java,v 1.0 07.02.11 14.32 haraldk Exp$
*/
public class ColorSpacesTest {
@Test
public void testAdobeRGB98AlwaysSame() {
ColorSpace cs = ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998);
assertSame(cs, ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998));
assertTrue(cs instanceof ICC_ColorSpace);
ICC_ColorSpace iccCs = (ICC_ColorSpace) cs;
assertSame(cs, ColorSpaces.createColorSpace(iccCs.getProfile()));
}
@Test
public void testCMYKAlwaysSame() {
ColorSpace cs = ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK);
assertSame(cs, ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK));
assumeTrue(cs instanceof ICC_ColorSpace); // NOTE: Ignores test on systems without CMYK profile
ICC_ColorSpace iccCs = (ICC_ColorSpace) cs;
assertSame(cs, ColorSpaces.createColorSpace(iccCs.getProfile()));
}
@Test
public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_sRGB() {
@ -134,20 +154,6 @@ public class ColorSpacesTest {
assertEquals(ColorSpace.TYPE_RGB, ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998).getType());
}
@Test
public void testAdobeRGB98AlwaysSame() {
ColorSpace cs = ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998);
assertSame(cs, ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998));
if (cs instanceof ICC_ColorSpace) {
ICC_ColorSpace iccCs = (ICC_ColorSpace) cs;
assertSame(cs, ColorSpaces.createColorSpace(iccCs.getProfile()));
}
else {
System.err.println("WARNING: Not an ICC_ColorSpace: " + cs);
}
}
@Test
public void testCMYKNotNull() {
assertNotNull(ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK));
@ -158,20 +164,6 @@ public class ColorSpacesTest {
assertEquals(ColorSpace.TYPE_CMYK, ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK).getType());
}
@Test
public void testCMYKAlwaysSame() {
ColorSpace cs = ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK);
assertSame(cs, ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK));
if (cs instanceof ICC_ColorSpace) {
ICC_ColorSpace iccCs = (ICC_ColorSpace) cs;
assertSame(cs, ColorSpaces.createColorSpace(iccCs.getProfile()));
}
else {
System.err.println("Warning: Not an ICC_ColorSpace: " + cs);
}
}
@Test
public void testIsCS_sRGBTrue() {
assertTrue(ColorSpaces.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_sRGB)));