Skip to content
Permalink
Browse files
8263622: The java.awt.color.ICC_Profile#setData invert the order of b…
…ytes for the "head" tag

Reviewed-by: azvegint
  • Loading branch information
mrserb committed Mar 18, 2021
1 parent e34f766 commit 01ddf3d28004834d57f4cee92d0e055fb544a292
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 44 deletions.
@@ -31,43 +31,9 @@
#include "Trace.h"
#include "Disposer.h"
#include <lcms2.h>
#include <lcms2_plugin.h>
#include "jlong.h"


#define ALIGNLONG(x) (((x)+3) & ~(3)) // Aligns to DWORD boundary

#ifdef USE_BIG_ENDIAN
#define AdjustEndianess32(a)
#else

static
void AdjustEndianess32(cmsUInt8Number *pByte)
{
cmsUInt8Number temp1;
cmsUInt8Number temp2;

temp1 = *pByte++;
temp2 = *pByte++;
*(pByte-1) = *pByte;
*pByte++ = temp2;
*(pByte-3) = *pByte;
*pByte = temp1;
}

#endif

// Transports to properly encoded values - note that icc profiles does use
// big endian notation.

static
cmsInt32Number TransportValue32(cmsInt32Number Value)
{
cmsInt32Number Temp = Value;

AdjustEndianess32((cmsUInt8Number*) &Temp);
return Temp;
}

#define SigMake(a,b,c,d) \
( ( ((int) ((unsigned char) (a))) << 24) | \
( ((int) ((unsigned char) (b))) << 16) | \
@@ -760,16 +726,18 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
memcpy(&pfHeader, pBuffer, sizeof(cmsICCHeader));

// now set header fields, which we can access using the lcms2 public API
cmsSetHeaderFlags(pf, pfHeader.flags);
cmsSetHeaderManufacturer(pf, pfHeader.manufacturer);
cmsSetHeaderModel(pf, pfHeader.model);
cmsSetHeaderAttributes(pf, pfHeader.attributes);
cmsSetHeaderFlags(pf, _cmsAdjustEndianess32(pfHeader.flags));
cmsSetHeaderManufacturer(pf, _cmsAdjustEndianess32(pfHeader.manufacturer));
cmsSetHeaderModel(pf, _cmsAdjustEndianess32(pfHeader.model));
cmsUInt64Number attributes;
_cmsAdjustEndianess64(&attributes, &pfHeader.attributes);
cmsSetHeaderAttributes(pf, attributes);
cmsSetHeaderProfileID(pf, (cmsUInt8Number*)&(pfHeader.profileID));
cmsSetHeaderRenderingIntent(pf, pfHeader.renderingIntent);
cmsSetPCS(pf, pfHeader.pcs);
cmsSetColorSpace(pf, pfHeader.colorSpace);
cmsSetDeviceClass(pf, pfHeader.deviceClass);
cmsSetEncodedICCversion(pf, pfHeader.version);
cmsSetHeaderRenderingIntent(pf, _cmsAdjustEndianess32(pfHeader.renderingIntent));
cmsSetPCS(pf, _cmsAdjustEndianess32(pfHeader.pcs));
cmsSetColorSpace(pf, _cmsAdjustEndianess32(pfHeader.colorSpace));
cmsSetDeviceClass(pf, _cmsAdjustEndianess32(pfHeader.deviceClass));
cmsSetEncodedICCversion(pf, _cmsAdjustEndianess32(pfHeader.version));

return TRUE;
}
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.util.Arrays;

/**
* @test
* @bug 8263622
* @summary The ICC_Profile#setData invert the order of bytes for the "head" tag
*/
public final class SetHeaderInfo {

public static void main(String[] args) {
int[] cspaces = {ColorSpace.CS_sRGB, ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_CIEXYZ, ColorSpace.CS_PYCC,
ColorSpace.CS_GRAY};
for (int cspace : cspaces) {
ICC_Profile icc = ICC_Profile.getInstance(cspace);
testSame(icc);
testCustom(icc);
// some corner cases
negative(icc, null);
negative(icc, new byte[0]);
negative(icc, new byte[1]);
byte[] header = icc.getData(ICC_Profile.icSigHead);
negative(icc, new byte[header.length - 1]);
}
}

private static void testSame(ICC_Profile icc) {
byte[] expected = icc.getData(ICC_Profile.icSigHead);
icc.setData(ICC_Profile.icSigHead, expected);
byte[] actual = icc.getData(ICC_Profile.icSigHead);
if (!Arrays.equals(expected, actual)) {
System.err.println("Expected: " + Arrays.toString(expected));
System.err.println("Actual: " + Arrays.toString(actual));
throw new RuntimeException();
}
}

private static void testCustom(ICC_Profile icc) {
byte[] expected = icc.getData(ICC_Profile.icSigHead);
// small modification of the default profile
expected[ICC_Profile.icHdrFlags + 3] = 1;
expected[ICC_Profile.icHdrModel + 3] = 1;
icc.setData(ICC_Profile.icSigHead, expected);
byte[] actual = icc.getData(ICC_Profile.icSigHead);
if (!Arrays.equals(expected, actual)) {
System.err.println("Expected: " + Arrays.toString(expected));
System.err.println("Actual: " + Arrays.toString(actual));
throw new RuntimeException();
}
}

private static void negative(ICC_Profile icc, byte[] tagData) {
try {
icc.setData(ICC_Profile.icSigHead, tagData);
throw new RuntimeException("IllegalArgumentException expected");
} catch (IllegalArgumentException iae) {
// expected
}
}
}

0 comments on commit 01ddf3d

Please sign in to comment.