#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); 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); cache.put(key, cs);
} }

View File

@ -14,6 +14,8 @@ import java.awt.color.ICC_Profile;
interface ICCProfileSanitizer { interface ICCProfileSanitizer {
void fixProfile(ICC_Profile profile); void fixProfile(ICC_Profile profile);
boolean validationAltersProfileHeader();
class Factory { class Factory {
static ICCProfileSanitizer get() { static ICCProfileSanitizer get() {
// Strategy pattern: // 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. * Fixes problematic 'XYZ ' tags in Corbis RGB profile.
* *
@ -58,7 +63,7 @@ final class KCMSSanitizerStrategy implements ICCProfileSanitizer {
} }
// TODO: Move to some common util // 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) | return ((array[index ] & 0xff) << 24) |
((array[index + 1] & 0xff) << 16) | ((array[index + 1] & 0xff) << 16) |
((array[index + 2] & 0xff) << 8) | ((array[index + 2] & 0xff) << 8) |
@ -66,7 +71,7 @@ final class KCMSSanitizerStrategy implements ICCProfileSanitizer {
} }
// TODO: Move to some common util // 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 ] = (byte) (value >> 24);
array[index + 1] = (byte) (value >> 16); array[index + 1] = (byte) (value >> 16);
array[index + 2] = (byte) (value >> 8); array[index + 2] = (byte) (value >> 8);

View File

@ -16,4 +16,9 @@ final class LCMSSanitizerStrategy implements ICCProfileSanitizer {
Validate.notNull(profile, "profile"); Validate.notNull(profile, "profile");
// Let LCMS handle things internally for now // 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 java.io.IOException;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;
/** /**
* ColorSpacesTest * ColorSpacesTest
@ -45,6 +46,25 @@ import static org.junit.Assert.*;
* @version $Id: ColorSpacesTest.java,v 1.0 07.02.11 14.32 haraldk Exp$ * @version $Id: ColorSpacesTest.java,v 1.0 07.02.11 14.32 haraldk Exp$
*/ */
public class ColorSpacesTest { 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 @Test
public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_sRGB() { public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_sRGB() {
@ -134,20 +154,6 @@ public class ColorSpacesTest {
assertEquals(ColorSpace.TYPE_RGB, ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998).getType()); 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 @Test
public void testCMYKNotNull() { public void testCMYKNotNull() {
assertNotNull(ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK)); 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()); 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 @Test
public void testIsCS_sRGBTrue() { public void testIsCS_sRGBTrue() {
assertTrue(ColorSpaces.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_sRGB))); assertTrue(ColorSpaces.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_sRGB)));