Skip to content

Commit b638bb3

Browse files
Jan Kratochvilantonvoznia
authored andcommitted
8263622: The java.awt.color.ICC_Profile#setData invert the order of bytes for the "head" tag
Co-authored-by: Anton Voznia <[email protected]> Backport-of: 01ddf3d
1 parent 8a13967 commit b638bb3

File tree

2 files changed

+98
-45
lines changed

2 files changed

+98
-45
lines changed

src/java.desktop/share/native/liblcms/LCMS.c

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,43 +31,9 @@
3131
#include "Trace.h"
3232
#include "Disposer.h"
3333
#include <lcms2.h>
34+
#include <lcms2_plugin.h>
3435
#include "jlong.h"
3536

36-
37-
#define ALIGNLONG(x) (((x)+3) & ~(3)) // Aligns to DWORD boundary
38-
39-
#ifdef USE_BIG_ENDIAN
40-
#define AdjustEndianess32(a)
41-
#else
42-
43-
static
44-
void AdjustEndianess32(cmsUInt8Number *pByte)
45-
{
46-
cmsUInt8Number temp1;
47-
cmsUInt8Number temp2;
48-
49-
temp1 = *pByte++;
50-
temp2 = *pByte++;
51-
*(pByte-1) = *pByte;
52-
*pByte++ = temp2;
53-
*(pByte-3) = *pByte;
54-
*pByte = temp1;
55-
}
56-
57-
#endif
58-
59-
// Transports to properly encoded values - note that icc profiles does use
60-
// big endian notation.
61-
62-
static
63-
cmsInt32Number TransportValue32(cmsInt32Number Value)
64-
{
65-
cmsInt32Number Temp = Value;
66-
67-
AdjustEndianess32((cmsUInt8Number*) &Temp);
68-
return Temp;
69-
}
70-
7137
#define SigMake(a,b,c,d) \
7238
( ( ((int) ((unsigned char) (a))) << 24) | \
7339
( ((int) ((unsigned char) (b))) << 16) | \
@@ -784,16 +750,18 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
784750
memcpy(&pfHeader, pBuffer, sizeof(cmsICCHeader));
785751

786752
// now set header fields, which we can access using the lcms2 public API
787-
cmsSetHeaderFlags(pf, pfHeader.flags);
788-
cmsSetHeaderManufacturer(pf, pfHeader.manufacturer);
789-
cmsSetHeaderModel(pf, pfHeader.model);
790-
cmsSetHeaderAttributes(pf, pfHeader.attributes);
753+
cmsSetHeaderFlags(pf, _cmsAdjustEndianess32(pfHeader.flags));
754+
cmsSetHeaderManufacturer(pf, _cmsAdjustEndianess32(pfHeader.manufacturer));
755+
cmsSetHeaderModel(pf, _cmsAdjustEndianess32(pfHeader.model));
756+
cmsUInt64Number attributes;
757+
_cmsAdjustEndianess64(&attributes, &pfHeader.attributes);
758+
cmsSetHeaderAttributes(pf, attributes);
791759
cmsSetHeaderProfileID(pf, (cmsUInt8Number*)&(pfHeader.profileID));
792-
cmsSetHeaderRenderingIntent(pf, pfHeader.renderingIntent);
793-
cmsSetPCS(pf, pfHeader.pcs);
794-
cmsSetColorSpace(pf, pfHeader.colorSpace);
795-
cmsSetDeviceClass(pf, pfHeader.deviceClass);
796-
cmsSetEncodedICCversion(pf, pfHeader.version);
760+
cmsSetHeaderRenderingIntent(pf, _cmsAdjustEndianess32(pfHeader.renderingIntent));
761+
cmsSetPCS(pf, _cmsAdjustEndianess32(pfHeader.pcs));
762+
cmsSetColorSpace(pf, _cmsAdjustEndianess32(pfHeader.colorSpace));
763+
cmsSetDeviceClass(pf, _cmsAdjustEndianess32(pfHeader.deviceClass));
764+
cmsSetEncodedICCversion(pf, _cmsAdjustEndianess32(pfHeader.version));
797765

798766
return TRUE;
799767
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.awt.color.ColorSpace;
25+
import java.awt.color.ICC_Profile;
26+
import java.util.Arrays;
27+
28+
/**
29+
* @test
30+
* @bug 8263622
31+
* @summary The ICC_Profile#setData invert the order of bytes for the "head" tag
32+
*/
33+
public final class SetHeaderInfo {
34+
35+
public static void main(String[] args) {
36+
int[] cspaces = {ColorSpace.CS_sRGB, ColorSpace.CS_LINEAR_RGB,
37+
ColorSpace.CS_CIEXYZ, ColorSpace.CS_PYCC,
38+
ColorSpace.CS_GRAY};
39+
for (int cspace : cspaces) {
40+
ICC_Profile icc = ICC_Profile.getInstance(cspace);
41+
testSame(icc);
42+
testCustom(icc);
43+
// some corner cases
44+
negative(icc, null);
45+
negative(icc, new byte[0]);
46+
negative(icc, new byte[1]);
47+
byte[] header = icc.getData(ICC_Profile.icSigHead);
48+
negative(icc, new byte[header.length - 1]);
49+
}
50+
}
51+
52+
private static void testSame(ICC_Profile icc) {
53+
byte[] expected = icc.getData(ICC_Profile.icSigHead);
54+
icc.setData(ICC_Profile.icSigHead, expected);
55+
byte[] actual = icc.getData(ICC_Profile.icSigHead);
56+
if (!Arrays.equals(expected, actual)) {
57+
System.err.println("Expected: " + Arrays.toString(expected));
58+
System.err.println("Actual: " + Arrays.toString(actual));
59+
throw new RuntimeException();
60+
}
61+
}
62+
63+
private static void testCustom(ICC_Profile icc) {
64+
byte[] expected = icc.getData(ICC_Profile.icSigHead);
65+
// small modification of the default profile
66+
expected[ICC_Profile.icHdrFlags + 3] = 1;
67+
expected[ICC_Profile.icHdrModel + 3] = 1;
68+
icc.setData(ICC_Profile.icSigHead, expected);
69+
byte[] actual = icc.getData(ICC_Profile.icSigHead);
70+
if (!Arrays.equals(expected, actual)) {
71+
System.err.println("Expected: " + Arrays.toString(expected));
72+
System.err.println("Actual: " + Arrays.toString(actual));
73+
throw new RuntimeException();
74+
}
75+
}
76+
77+
private static void negative(ICC_Profile icc, byte[] tagData) {
78+
try {
79+
icc.setData(ICC_Profile.icSigHead, tagData);
80+
throw new RuntimeException("IllegalArgumentException expected");
81+
} catch (IllegalArgumentException iae) {
82+
// expected
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)