Skip to content

Commit 50ad5e5

Browse files
mrserbjankratochvil
authored andcommitted
8263622: The java.awt.color.ICC_Profile#setData invert the order of bytes for the "head" tag
Reviewed-by: azvegint
1 parent 942d6d0 commit 50ad5e5

File tree

2 files changed

+98
-45
lines changed

2 files changed

+98
-45
lines changed

jdk/src/share/native/sun/java2d/cmm/lcms/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, 2013, 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) | \
@@ -771,16 +737,18 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
771737
memcpy(&pfHeader, pBuffer, sizeof(cmsICCHeader));
772738

773739
// now set header fields, which we can access using the lcms2 public API
774-
cmsSetHeaderFlags(pf, pfHeader.flags);
775-
cmsSetHeaderManufacturer(pf, pfHeader.manufacturer);
776-
cmsSetHeaderModel(pf, pfHeader.model);
777-
cmsSetHeaderAttributes(pf, pfHeader.attributes);
740+
cmsSetHeaderFlags(pf, _cmsAdjustEndianess32(pfHeader.flags));
741+
cmsSetHeaderManufacturer(pf, _cmsAdjustEndianess32(pfHeader.manufacturer));
742+
cmsSetHeaderModel(pf, _cmsAdjustEndianess32(pfHeader.model));
743+
cmsUInt64Number attributes;
744+
_cmsAdjustEndianess64(&attributes, &pfHeader.attributes);
745+
cmsSetHeaderAttributes(pf, attributes);
778746
cmsSetHeaderProfileID(pf, (cmsUInt8Number*)&(pfHeader.profileID));
779-
cmsSetHeaderRenderingIntent(pf, pfHeader.renderingIntent);
780-
cmsSetPCS(pf, pfHeader.pcs);
781-
cmsSetColorSpace(pf, pfHeader.colorSpace);
782-
cmsSetDeviceClass(pf, pfHeader.deviceClass);
783-
cmsSetEncodedICCversion(pf, pfHeader.version);
747+
cmsSetHeaderRenderingIntent(pf, _cmsAdjustEndianess32(pfHeader.renderingIntent));
748+
cmsSetPCS(pf, _cmsAdjustEndianess32(pfHeader.pcs));
749+
cmsSetColorSpace(pf, _cmsAdjustEndianess32(pfHeader.colorSpace));
750+
cmsSetDeviceClass(pf, _cmsAdjustEndianess32(pfHeader.deviceClass));
751+
cmsSetEncodedICCversion(pf, _cmsAdjustEndianess32(pfHeader.version));
784752

785753
return TRUE;
786754
}
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)