# HG changeset patch # User lana # Date 1237947122 25200 # Node ID d8b1468ef5543c530376ccd642157e7523683e49 # Parent 7a90e89e36d103038f8667f6a7daae34ecfa1ad8# Parent f5bcb8ee655580726429b285bb958392dcd94ed4 Merge diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/make/sun/awt/Makefile --- a/jdk/make/sun/awt/Makefile Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/make/sun/awt/Makefile Tue Mar 24 19:12:02 2009 -0700 @@ -339,8 +339,7 @@ FONTCONFIGS_SRC = $(PLATFORM_SRC)/classes/sun/awt/windows _FONTCONFIGS = \ - fontconfig.properties \ - fontconfig.98.properties + fontconfig.properties FONTCONFIGS_SRC_PREFIX = diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/make/sun/xawt/mapfile-vers --- a/jdk/make/sun/xawt/mapfile-vers Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/make/sun/xawt/mapfile-vers Tue Mar 24 19:12:02 2009 -0700 @@ -304,12 +304,14 @@ Java_java_awt_FileDialog_initIDs; Java_sun_awt_X11_XWindow_initIDs; + Java_sun_java2d_opengl_OGLContext_getOGLIdString; Java_sun_java2d_opengl_OGLMaskFill_maskFill; Java_sun_java2d_opengl_OGLRenderer_drawPoly; Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer; Java_sun_java2d_opengl_OGLSurfaceData_initTexture; Java_sun_java2d_opengl_OGLSurfaceData_initFBObject; Java_sun_java2d_opengl_OGLSurfaceData_initFlipBackbuffer; + Java_sun_java2d_opengl_OGLSurfaceData_getTextureID; Java_sun_java2d_opengl_OGLSurfaceData_getTextureTarget; Java_sun_java2d_opengl_OGLTextRenderer_drawGlyphList; Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadata.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadata.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadata.java Tue Mar 24 19:12:02 2009 -0700 @@ -153,7 +153,7 @@ node.setAttribute("imageWidth", Integer.toString(imageWidth)); node.setAttribute("imageHeight", Integer.toString(imageHeight)); node.setAttribute("interlaceFlag", - interlaceFlag ? "true" : "false"); + interlaceFlag ? "TRUE" : "FALSE"); root.appendChild(node); // Local color table @@ -185,9 +185,9 @@ node.setAttribute("disposalMethod", disposalMethodNames[disposalMethod]); node.setAttribute("userInputFlag", - userInputFlag ? "true" : "false"); + userInputFlag ? "TRUE" : "FALSE"); node.setAttribute("transparentColorFlag", - transparentColorFlag ? "true" : "false"); + transparentColorFlag ? "TRUE" : "FALSE"); node.setAttribute("delayTime", Integer.toString(delayTime)); node.setAttribute("transparentColorIndex", diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java Tue Mar 24 19:12:02 2009 -0700 @@ -55,6 +55,7 @@ import org.w3c.dom.NodeList; import com.sun.imageio.plugins.common.LZWCompressor; import com.sun.imageio.plugins.common.PaletteBuilder; +import sun.awt.image.ByteComponentRaster; public class GIFImageWriter extends ImageWriter { private static final boolean DEBUG = false; // XXX false for release! @@ -905,10 +906,18 @@ LZWCompressor compressor = new LZWCompressor(stream, initCodeSize, false); + /* At this moment we know that input image is indexed image. + * We can directly copy data iff: + * - no subsampling required (periodX = 1, periodY = 0) + * - we can access data directly (image is non-tiled, + * i.e. image data are in single block) + * - we can calculate offset in data buffer (next 3 lines) + */ boolean isOptimizedCase = periodX == 1 && periodY == 1 && + image.getNumXTiles() == 1 && image.getNumYTiles() == 1 && sampleModel instanceof ComponentSampleModel && - image.getNumXTiles() == 1 && image.getNumYTiles() == 1 && + image.getTile(0, 0) instanceof ByteComponentRaster && image.getTile(0, 0).getDataBuffer() instanceof DataBufferByte; int numRowsWritten = 0; @@ -921,11 +930,14 @@ if (DEBUG) System.out.println("Writing interlaced"); if (isOptimizedCase) { - Raster tile = image.getTile(0, 0); + ByteComponentRaster tile = + (ByteComponentRaster)image.getTile(0, 0); byte[] data = ((DataBufferByte)tile.getDataBuffer()).getData(); ComponentSampleModel csm = (ComponentSampleModel)tile.getSampleModel(); int offset = csm.getOffset(sourceXOffset, sourceYOffset, 0); + // take into account the raster data offset + offset += tile.getDataOffset(0); int lineStride = csm.getScanlineStride(); writeRowsOpt(data, offset, lineStride, compressor, diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java Tue Mar 24 19:12:02 2009 -0700 @@ -158,13 +158,10 @@ } } String value = attr.getNodeValue(); - // XXX Should be able to use equals() here instead of - // equalsIgnoreCase() but some boolean attributes are incorrectly - // set to "true" or "false" by the J2SE core metadata classes - // getAsTree() method (which are duplicated above). See bug 5082756. - if (value.equalsIgnoreCase("TRUE")) { + // Allow lower case booleans for backward compatibility, #5082756 + if (value.equals("TRUE") || value.equals("true")) { return true; - } else if (value.equalsIgnoreCase("FALSE")) { + } else if (value.equals("FALSE") || value.equals("false")) { return false; } else { fatal(node, "Attribute " + name + " must be 'TRUE' or 'FALSE'!"); diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java Tue Mar 24 19:12:02 2009 -0700 @@ -202,7 +202,7 @@ compression_node.appendChild(node); node = new IIOMetadataNode("Lossless"); - node.setAttribute("value", "true"); + node.setAttribute("value", "TRUE"); compression_node.appendChild(node); // NumProgressiveScans not in stream diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java Tue Mar 24 19:12:02 2009 -0700 @@ -1003,7 +1003,7 @@ 3, new int [] {0, 1, 2}, null); - ColorModel cm = new ComponentColorModel(JPEG.sRGB, + ColorModel cm = new ComponentColorModel(JPEG.JCS.sRGB, false, false, ColorModel.OPAQUE, diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Tue Mar 24 19:12:02 2009 -0700 @@ -208,15 +208,24 @@ public static final int [] bOffsRGB = { 2, 1, 0 }; - protected static final ColorSpace sRGB = - ColorSpace.getInstance(ColorSpace.CS_sRGB); - protected static ColorSpace YCC = null; // Can't be final + /* These are kept in the inner class to avoid static initialization + * of the CMM class until someone actually needs it. + * (e.g. do not init CMM on the request for jpeg mime types) + */ + public static class JCS { + public static final ColorSpace sRGB = + ColorSpace.getInstance(ColorSpace.CS_sRGB); + public static final ColorSpace YCC; - static { - try { - YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC); - } catch (IllegalArgumentException e) { - // PYCC.pf may not always be installed + static { + ColorSpace cs = null; + try { + cs = ColorSpace.getInstance(ColorSpace.CS_PYCC); + } catch (IllegalArgumentException e) { + // PYCC.pf may not always be installed + } finally { + YCC = cs; + } } } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Tue Mar 24 19:12:02 2009 -0700 @@ -228,31 +228,31 @@ (BufferedImage.TYPE_BYTE_GRAY); defaultTypes[JPEG.JCS_RGB] = ImageTypeSpecifier.createInterleaved - (JPEG.sRGB, + (JPEG.JCS.sRGB, JPEG.bOffsRGB, DataBuffer.TYPE_BYTE, false, false); defaultTypes[JPEG.JCS_RGBA] = ImageTypeSpecifier.createPacked - (JPEG.sRGB, + (JPEG.JCS.sRGB, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, DataBuffer.TYPE_INT, false); - if (JPEG.YCC != null) { + if (JPEG.JCS.YCC != null) { defaultTypes[JPEG.JCS_YCC] = ImageTypeSpecifier.createInterleaved - (JPEG.YCC, + (JPEG.JCS.YCC, JPEG.bandOffsets[2], DataBuffer.TYPE_BYTE, false, false); defaultTypes[JPEG.JCS_YCCA] = ImageTypeSpecifier.createInterleaved - (JPEG.YCC, + (JPEG.JCS.YCC, JPEG.bandOffsets[3], DataBuffer.TYPE_BYTE, true, @@ -774,7 +774,7 @@ case JPEG.JCS_RGB: list.add(raw); list.add(getImageType(JPEG.JCS_GRAYSCALE)); - if (JPEG.YCC != null) { + if (JPEG.JCS.YCC != null) { list.add(getImageType(JPEG.JCS_YCC)); } break; @@ -811,7 +811,7 @@ } list.add(getImageType(JPEG.JCS_GRAYSCALE)); - if (JPEG.YCC != null) { // Might be null if PYCC.pf not installed + if (JPEG.JCS.YCC != null) { // Might be null if PYCC.pf not installed list.add(getImageType(JPEG.JCS_YCC)); } break; @@ -893,7 +893,7 @@ (!cs.isCS_sRGB()) && (cm.getNumComponents() == numComponents)) { // Target isn't sRGB, so convert from sRGB to the target - convert = new ColorConvertOp(JPEG.sRGB, cs, null); + convert = new ColorConvertOp(JPEG.JCS.sRGB, cs, null); } else if (csType != ColorSpace.TYPE_RGB) { throw new IIOException("Incompatible color conversion"); } @@ -906,18 +906,18 @@ } break; case JPEG.JCS_YCC: - if (JPEG.YCC == null) { // We can't do YCC at all + if (JPEG.JCS.YCC == null) { // We can't do YCC at all throw new IIOException("Incompatible color conversion"); } - if ((cs != JPEG.YCC) && + if ((cs != JPEG.JCS.YCC) && (cm.getNumComponents() == numComponents)) { - convert = new ColorConvertOp(JPEG.YCC, cs, null); + convert = new ColorConvertOp(JPEG.JCS.YCC, cs, null); } break; case JPEG.JCS_YCCA: // No conversions available; image must be YCCA - if ((JPEG.YCC == null) || // We can't do YCC at all - (cs != JPEG.YCC) || + if ((JPEG.JCS.YCC == null) || // We can't do YCC at all + (cs != JPEG.JCS.YCC) || (cm.getNumComponents() != numComponents)) { throw new IIOException("Incompatible color conversion"); } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java Tue Mar 24 19:12:02 2009 -0700 @@ -39,8 +39,6 @@ private static String [] writerSpiNames = {"com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi"}; - private boolean registered = false; - public JPEGImageReaderSpi() { super(JPEG.vendor, JPEG.version, @@ -61,26 +59,6 @@ ); } - public void onRegistration(ServiceRegistry registry, - Class category) { - if (registered) { - return; - } - try { - java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jpeg")); - // Stuff it all into one lib for first pass - //java.security.AccessController.doPrivileged( - //new sun.security.action.LoadLibraryAction("imageioIJG")); - } catch (Throwable e) { // Fail on any Throwable - // if it can't be loaded, deregister and return - registry.deregisterServiceProvider(this); - return; - } - - registered = true; - } - public String getDescription(Locale locale) { return "Standard JPEG Image Reader"; } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Tue Mar 24 19:12:02 2009 -0700 @@ -812,13 +812,13 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.YCC) { + if (cs == JPEG.JCS.YCC) { if (!alpha) { if (jfif != null) { convertTosRGB = true; convertOp = new ColorConvertOp(cs, - JPEG.sRGB, + JPEG.JCS.sRGB, null); outCsType = JPEG.JCS_YCbCr; } else if (adobe != null) { @@ -1494,7 +1494,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.YCC) { + if (cs == JPEG.JCS.YCC) { if (alpha) { retval = JPEG.JCS_YCCA; } else { @@ -1533,7 +1533,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.YCC) { + if (cs == JPEG.JCS.YCC) { if (alpha) { retval = JPEG.JCS_YCCA; } else { @@ -1579,7 +1579,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.YCC) { + if (cs == JPEG.JCS.YCC) { if (alpha) { retval = JPEG.JCS_YCCA; } else { diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java Tue Mar 24 19:12:02 2009 -0700 @@ -42,8 +42,6 @@ private static String [] readerSpiNames = {"com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi"}; - private boolean registered = false; - public JPEGImageWriterSpi() { super(JPEG.vendor, JPEG.version, @@ -68,23 +66,6 @@ return "Standard JPEG Image Writer"; } - public void onRegistration(ServiceRegistry registry, - Class category) { - if (registered) { - return; - } - try { - java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jpeg")); - } catch (Throwable e) { // Fail on any Throwable - // if it can't be loaded, deregister and return - registry.deregisterServiceProvider(this); - return; - } - - registered = true; - } - public boolean isFormatLossless() { return false; } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Tue Mar 24 19:12:02 2009 -0700 @@ -490,7 +490,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.YCC) { + if (cs == JPEG.JCS.YCC) { wantJFIF = false; componentIDs[0] = (byte) 'Y'; componentIDs[1] = (byte) 'C'; @@ -955,7 +955,7 @@ // Lossless - false IIOMetadataNode lossless = new IIOMetadataNode("Lossless"); - lossless.setAttribute("value", "false"); + lossless.setAttribute("value", "FALSE"); compression.appendChild(lossless); // NumProgressiveScans - count sos segments diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Tue Mar 24 19:12:02 2009 -0700 @@ -37,6 +37,7 @@ import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; +import java.io.EOFException; import java.io.InputStream; import java.io.IOException; import java.io.SequenceInputStream; @@ -59,7 +60,7 @@ import java.io.ByteArrayOutputStream; import sun.awt.image.ByteInterleavedRaster; -class PNGImageDataEnumeration implements Enumeration { +class PNGImageDataEnumeration implements Enumeration { boolean firstTime = true; ImageInputStream stream; @@ -72,7 +73,7 @@ int type = stream.readInt(); // skip chunk type } - public Object nextElement() { + public InputStream nextElement() { try { firstTime = false; ImageInputStream iis = new SubImageInputStream(stream, length); @@ -207,25 +208,17 @@ resetStreamSettings(); } - private String readNullTerminatedString(String charset) throws IOException { + private String readNullTerminatedString(String charset, int maxLen) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int b; - while ((b = stream.read()) != 0) { + int count = 0; + while ((maxLen > count++) && ((b = stream.read()) != 0)) { + if (b == -1) throw new EOFException(); baos.write(b); } return new String(baos.toByteArray(), charset); } - private String readNullTerminatedString() throws IOException { - StringBuilder b = new StringBuilder(); - int c; - - while ((c = stream.read()) != 0) { - b.append((char)c); - } - return b.toString(); - } - private void readHeader() throws IIOException { if (gotHeader) { return; @@ -434,7 +427,7 @@ } private void parse_iCCP_chunk(int chunkLength) throws IOException { - String keyword = readNullTerminatedString(); + String keyword = readNullTerminatedString("ISO-8859-1", 80); metadata.iCCP_profileName = keyword; metadata.iCCP_compressionMethod = stream.readUnsignedByte(); @@ -450,7 +443,7 @@ private void parse_iTXt_chunk(int chunkLength) throws IOException { long chunkStart = stream.getStreamPosition(); - String keyword = readNullTerminatedString(); + String keyword = readNullTerminatedString("ISO-8859-1", 80); metadata.iTXt_keyword.add(keyword); int compressionFlag = stream.readUnsignedByte(); @@ -459,15 +452,17 @@ int compressionMethod = stream.readUnsignedByte(); metadata.iTXt_compressionMethod.add(Integer.valueOf(compressionMethod)); - String languageTag = readNullTerminatedString("UTF8"); + String languageTag = readNullTerminatedString("UTF8", 80); metadata.iTXt_languageTag.add(languageTag); + long pos = stream.getStreamPosition(); + int maxLen = (int)(chunkStart + chunkLength - pos); String translatedKeyword = - readNullTerminatedString("UTF8"); + readNullTerminatedString("UTF8", maxLen); metadata.iTXt_translatedKeyword.add(translatedKeyword); String text; - long pos = stream.getStreamPosition(); + pos = stream.getStreamPosition(); byte[] b = new byte[(int)(chunkStart + chunkLength - pos)]; stream.readFully(b); @@ -511,7 +506,7 @@ private void parse_sPLT_chunk(int chunkLength) throws IOException, IIOException { - metadata.sPLT_paletteName = readNullTerminatedString(); + metadata.sPLT_paletteName = readNullTerminatedString("ISO-8859-1", 80); chunkLength -= metadata.sPLT_paletteName.length() + 1; int sampleDepth = stream.readUnsignedByte(); @@ -554,12 +549,12 @@ } private void parse_tEXt_chunk(int chunkLength) throws IOException { - String keyword = readNullTerminatedString(); + String keyword = readNullTerminatedString("ISO-8859-1", 80); metadata.tEXt_keyword.add(keyword); byte[] b = new byte[chunkLength - keyword.length() - 1]; stream.readFully(b); - metadata.tEXt_text.add(new String(b)); + metadata.tEXt_text.add(new String(b, "ISO-8859-1")); } private void parse_tIME_chunk() throws IOException { @@ -640,7 +635,7 @@ } private void parse_zTXt_chunk(int chunkLength) throws IOException { - String keyword = readNullTerminatedString(); + String keyword = readNullTerminatedString("ISO-8859-1", 80); metadata.zTXt_keyword.add(keyword); int method = stream.readUnsignedByte(); @@ -648,7 +643,7 @@ byte[] b = new byte[chunkLength - keyword.length() - 2]; stream.readFully(b); - metadata.zTXt_text.add(new String(inflate(b))); + metadata.zTXt_text.add(new String(inflate(b), "ISO-8859-1")); } private void readMetadata() throws IIOException { @@ -1263,7 +1258,7 @@ try { stream.seek(imageStartPosition); - Enumeration e = new PNGImageDataEnumeration(stream); + Enumeration e = new PNGImageDataEnumeration(stream); InputStream is = new SequenceInputStream(e); /* InflaterInputStream uses an Inflater instance which consumes diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java Tue Mar 24 19:12:02 2009 -0700 @@ -674,13 +674,8 @@ private byte[] deflate(byte[] b) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DeflaterOutputStream dos = new DeflaterOutputStream(baos); - - int len = b.length; - for (int i = 0; i < len; i++) { - dos.write((int)(0xff & b[i])); - } + dos.write(b); dos.close(); - return baos.toByteArray(); } @@ -736,7 +731,7 @@ cs.writeByte(compressionMethod); String text = (String)textIter.next(); - cs.write(deflate(text.getBytes())); + cs.write(deflate(text.getBytes("ISO-8859-1"))); cs.finish(); } } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Tue Mar 24 19:12:02 2009 -0700 @@ -211,8 +211,8 @@ public int sRGB_renderingIntent; // tEXt chunk - public ArrayList tEXt_keyword = new ArrayList(); // 1-79 char Strings - public ArrayList tEXt_text = new ArrayList(); // Strings + public ArrayList tEXt_keyword = new ArrayList(); // 1-79 characters + public ArrayList tEXt_text = new ArrayList(); // tIME chunk public boolean tIME_present; @@ -235,13 +235,13 @@ public int tRNS_blue; // zTXt chunk - public ArrayList zTXt_keyword = new ArrayList(); // Strings - public ArrayList zTXt_compressionMethod = new ArrayList(); // Integers - public ArrayList zTXt_text = new ArrayList(); // Strings + public ArrayList zTXt_keyword = new ArrayList(); + public ArrayList zTXt_compressionMethod = new ArrayList(); + public ArrayList zTXt_text = new ArrayList(); // Unknown chunks - public ArrayList unknownChunkType = new ArrayList(); // Strings - public ArrayList unknownChunkData = new ArrayList(); // byte arrays + public ArrayList unknownChunkType = new ArrayList(); + public ArrayList unknownChunkData = new ArrayList(); public PNGMetadata() { super(true, @@ -426,21 +426,14 @@ return false; } - private ArrayList cloneBytesArrayList(ArrayList in) { + private ArrayList cloneBytesArrayList(ArrayList in) { if (in == null) { return null; } else { - ArrayList list = new ArrayList(in.size()); - Iterator iter = in.iterator(); - while (iter.hasNext()) { - Object o = iter.next(); - if (o == null) { - list.add(null); - } else { - list.add(((byte[])o).clone()); - } + ArrayList list = new ArrayList(in.size()); + for (byte[] b: in) { + list.add((b == null) ? null : (byte[])b.clone()); } - return list; } } @@ -600,7 +593,7 @@ IIOMetadataNode iTXt_node = new IIOMetadataNode("iTXtEntry"); iTXt_node.setAttribute("keyword", iTXt_keyword.get(i)); iTXt_node.setAttribute("compressionFlag", - iTXt_compressionFlag.get(i) ? "1" : "0"); + iTXt_compressionFlag.get(i) ? "TRUE" : "FALSE"); iTXt_node.setAttribute("compressionMethod", iTXt_compressionMethod.get(i).toString()); iTXt_node.setAttribute("languageTag", @@ -832,7 +825,7 @@ } node = new IIOMetadataNode("BlackIsZero"); - node.setAttribute("value", "true"); + node.setAttribute("value", "TRUE"); chroma_node.appendChild(node); if (PLTE_present) { @@ -894,7 +887,7 @@ compression_node.appendChild(node); node = new IIOMetadataNode("Lossless"); - node.setAttribute("value", "true"); + node.setAttribute("value", "TRUE"); compression_node.appendChild(node); node = new IIOMetadataNode("NumProgressiveScans"); @@ -1040,7 +1033,7 @@ node.setAttribute("language", iTXt_languageTag.get(i)); if (iTXt_compressionFlag.get(i)) { - node.setAttribute("compression", "deflate"); + node.setAttribute("compression", "zip"); } else { node.setAttribute("compression", "none"); } @@ -1052,7 +1045,7 @@ node = new IIOMetadataNode("TextEntry"); node.setAttribute("keyword", (String)zTXt_keyword.get(i)); node.setAttribute("value", (String)zTXt_text.get(i)); - node.setAttribute("compression", "deflate"); + node.setAttribute("compression", "zip"); text_node.appendChild(node); } @@ -1162,12 +1155,13 @@ } } String value = attr.getNodeValue(); - if (value.equals("true")) { + // Allow lower case booleans for backward compatibility, #5082756 + if (value.equals("TRUE") || value.equals("true")) { return true; - } else if (value.equals("false")) { + } else if (value.equals("FALSE") || value.equals("false")) { return false; } else { - fatal(node, "Attribute " + name + " must be 'true' or 'false'!"); + fatal(node, "Attribute " + name + " must be 'TRUE' or 'FALSE'!"); return false; } } @@ -1421,26 +1415,30 @@ } String keyword = getAttribute(iTXt_node, "keyword"); - iTXt_keyword.add(keyword); + if (isValidKeyword(keyword)) { + iTXt_keyword.add(keyword); - boolean compressionFlag = - getBooleanAttribute(iTXt_node, "compressionFlag"); - iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag)); + boolean compressionFlag = + getBooleanAttribute(iTXt_node, "compressionFlag"); + iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag)); - String compressionMethod = - getAttribute(iTXt_node, "compressionMethod"); - iTXt_compressionMethod.add(Integer.valueOf(compressionMethod)); + String compressionMethod = + getAttribute(iTXt_node, "compressionMethod"); + iTXt_compressionMethod.add(Integer.valueOf(compressionMethod)); - String languageTag = - getAttribute(iTXt_node, "languageTag"); - iTXt_languageTag.add(languageTag); + String languageTag = + getAttribute(iTXt_node, "languageTag"); + iTXt_languageTag.add(languageTag); - String translatedKeyword = - getAttribute(iTXt_node, "translatedKeyword"); - iTXt_translatedKeyword.add(translatedKeyword); + String translatedKeyword = + getAttribute(iTXt_node, "translatedKeyword"); + iTXt_translatedKeyword.add(translatedKeyword); - String text = getAttribute(iTXt_node, "text"); - iTXt_text.add(text); + String text = getAttribute(iTXt_node, "text"); + iTXt_text.add(text); + + } + // silently skip invalid text entry iTXt_node = iTXt_node.getNextSibling(); } @@ -1692,11 +1690,45 @@ } } - private boolean isISOLatin(String s) { + /* + * Accrding to PNG spec, keywords are restricted to 1 to 79 bytes + * in length. Keywords shall contain only printable Latin-1 characters + * and spaces; To reduce the chances for human misreading of a keyword, + * leading spaces, trailing spaces, and consecutive spaces are not + * permitted in keywords. + * + * See: http://www.w3.org/TR/PNG/#11keywords + */ + private boolean isValidKeyword(String s) { + int len = s.length(); + if (len < 1 || len >= 80) { + return false; + } + if (s.startsWith(" ") || s.endsWith(" ") || s.contains(" ")) { + return false; + } + return isISOLatin(s, false); + } + + /* + * According to PNG spec, keyword shall contain only printable + * Latin-1 [ISO-8859-1] characters and spaces; that is, only + * character codes 32-126 and 161-255 decimal are allowed. + * For Latin-1 value fields the 0x10 (linefeed) control + * character is aloowed too. + * + * See: http://www.w3.org/TR/PNG/#11keywords + */ + private boolean isISOLatin(String s, boolean isLineFeedAllowed) { int len = s.length(); for (int i = 0; i < len; i++) { - if (s.charAt(i) > 255) { - return false; + char c = s.charAt(i); + if (c < 32 || c > 255 || (c > 126 && c < 161)) { + // not printable. Check whether this is an allowed + // control char + if (!isLineFeedAllowed || c != 0x10) { + return false; + } } } return true; @@ -1929,19 +1961,22 @@ while (child != null) { String childName = child.getNodeName(); if (childName.equals("TextEntry")) { - String keyword = getAttribute(child, "keyword"); + String keyword = + getAttribute(child, "keyword", "", false); String value = getAttribute(child, "value"); - String encoding = getAttribute(child, "encoding"); - String language = getAttribute(child, "language"); + String language = + getAttribute(child, "language", "", false); String compression = - getAttribute(child, "compression"); + getAttribute(child, "compression", "none", false); - if (isISOLatin(value)) { + if (!isValidKeyword(keyword)) { + // Just ignore this node, PNG requires keywords + } else if (isISOLatin(value, true)) { if (compression.equals("zip")) { // Use a zTXt node zTXt_keyword.add(keyword); zTXt_text.add(value); - zTXt_compressionMethod.add(new Integer(0)); + zTXt_compressionMethod.add(Integer.valueOf(0)); } else { // Use a tEXt node tEXt_keyword.add(keyword); @@ -1998,14 +2033,14 @@ sBIT_present = false; sPLT_present = false; sRGB_present = false; - tEXt_keyword = new ArrayList(); - tEXt_text = new ArrayList(); + tEXt_keyword = new ArrayList(); + tEXt_text = new ArrayList(); tIME_present = false; tRNS_present = false; - zTXt_keyword = new ArrayList(); - zTXt_compressionMethod = new ArrayList(); - zTXt_text = new ArrayList(); - unknownChunkType = new ArrayList(); - unknownChunkData = new ArrayList(); + zTXt_keyword = new ArrayList(); + zTXt_compressionMethod = new ArrayList(); + zTXt_text = new ArrayList(); + unknownChunkType = new ArrayList(); + unknownChunkData = new ArrayList(); } } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java --- a/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java Tue Mar 24 19:12:02 2009 -0700 @@ -94,6 +94,10 @@ tgn != null; tg = tgn, tgn = tg.getParent()); streamCloser = new Thread(tg, streamCloserRunnable); + /* Set context class loader to null in order to avoid + * keeping a strong reference to an application classloader. + */ + streamCloser.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(streamCloser); return null; } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/java/awt/GraphicsEnvironment.java --- a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java Tue Mar 24 19:12:02 2009 -0700 @@ -356,6 +356,9 @@ * @since 1.5 */ public void preferLocaleFonts() { + if (!(this instanceof SunGraphicsEnvironment)) { + return; + } sun.font.FontManager.preferLocaleFonts(); } @@ -376,6 +379,9 @@ * @since 1.5 */ public void preferProportionalFonts() { + if (!(this instanceof SunGraphicsEnvironment)) { + return; + } sun.font.FontManager.preferProportionalFonts(); } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/java/awt/color/ICC_Profile.java --- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java Tue Mar 24 19:12:02 2009 -0700 @@ -737,7 +737,7 @@ ICC_Profile(ProfileDeferralInfo pdi) { this.deferralInfo = pdi; this.profileActivator = new ProfileActivator() { - public void activate() { + public void activate() throws ProfileDataException { activateDeferredProfile(); } }; @@ -830,20 +830,16 @@ case ColorSpace.CS_sRGB: synchronized(ICC_Profile.class) { if (sRGBprofile == null) { - try { - /* - * Deferral is only used for standard profiles. - * Enabling the appropriate access privileges is handled - * at a lower level. - */ - sRGBprofile = getDeferredInstance( - new ProfileDeferralInfo("sRGB.pf", - ColorSpace.TYPE_RGB, - 3, CLASS_DISPLAY)); - } catch (IOException e) { - throw new IllegalArgumentException( - "Can't load standard profile: sRGB.pf"); - } + /* + * Deferral is only used for standard profiles. + * Enabling the appropriate access privileges is handled + * at a lower level. + */ + ProfileDeferralInfo pInfo = + new ProfileDeferralInfo("sRGB.pf", + ColorSpace.TYPE_RGB, 3, + CLASS_DISPLAY); + sRGBprofile = getDeferredInstance(pInfo); } thisProfile = sRGBprofile; } @@ -853,7 +849,11 @@ case ColorSpace.CS_CIEXYZ: synchronized(ICC_Profile.class) { if (XYZprofile == null) { - XYZprofile = getStandardProfile("CIEXYZ.pf"); + ProfileDeferralInfo pInfo = + new ProfileDeferralInfo("CIEXYZ.pf", + ColorSpace.TYPE_XYZ, 3, + CLASS_DISPLAY); + XYZprofile = getDeferredInstance(pInfo); } thisProfile = XYZprofile; } @@ -863,7 +863,11 @@ case ColorSpace.CS_PYCC: synchronized(ICC_Profile.class) { if (PYCCprofile == null) { - PYCCprofile = getStandardProfile("PYCC.pf"); + ProfileDeferralInfo pInfo = + new ProfileDeferralInfo("PYCC.pf", + ColorSpace.TYPE_3CLR, 3, + CLASS_DISPLAY); + PYCCprofile = getDeferredInstance(pInfo); } thisProfile = PYCCprofile; } @@ -873,7 +877,11 @@ case ColorSpace.CS_GRAY: synchronized(ICC_Profile.class) { if (GRAYprofile == null) { - GRAYprofile = getStandardProfile("GRAY.pf"); + ProfileDeferralInfo pInfo = + new ProfileDeferralInfo("GRAY.pf", + ColorSpace.TYPE_GRAY, 1, + CLASS_DISPLAY); + GRAYprofile = getDeferredInstance(pInfo); } thisProfile = GRAYprofile; } @@ -883,7 +891,11 @@ case ColorSpace.CS_LINEAR_RGB: synchronized(ICC_Profile.class) { if (LINEAR_RGBprofile == null) { - LINEAR_RGBprofile = getStandardProfile("LINEAR_RGB.pf"); + ProfileDeferralInfo pInfo = + new ProfileDeferralInfo("LINEAR_RGB.pf", + ColorSpace.TYPE_RGB, 3, + CLASS_DISPLAY); + LINEAR_RGBprofile = getDeferredInstance(pInfo); } thisProfile = LINEAR_RGBprofile; } @@ -1047,9 +1059,7 @@ * code will take care of access privileges. * @see activateDeferredProfile() */ - static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi) - throws IOException { - + static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi) { if (!ProfileDeferralMgr.deferring) { return getStandardProfile(pdi.filename); } @@ -1063,33 +1073,37 @@ } - void activateDeferredProfile() { - byte profileData[]; - FileInputStream fis; - String fileName = deferralInfo.filename; + void activateDeferredProfile() throws ProfileDataException { + byte profileData[]; + FileInputStream fis; + String fileName = deferralInfo.filename; profileActivator = null; deferralInfo = null; if ((fis = openProfile(fileName)) == null) { - throw new IllegalArgumentException("Cannot open file " + fileName); + throw new ProfileDataException("Cannot open file " + fileName); } try { profileData = getProfileDataFromStream(fis); fis.close(); /* close the file */ } catch (IOException e) { - throw new IllegalArgumentException("Invalid ICC Profile Data" + - fileName); + ProfileDataException pde = new + ProfileDataException("Invalid ICC Profile Data" + fileName); + pde.initCause(e); + throw pde; } if (profileData == null) { - throw new IllegalArgumentException("Invalid ICC Profile Data" + + throw new ProfileDataException("Invalid ICC Profile Data" + fileName); } try { ID = CMSManager.getModule().loadProfile(profileData); } catch (CMMException c) { - throw new IllegalArgumentException("Invalid ICC Profile Data" + - fileName); + ProfileDataException pde = new + ProfileDataException("Invalid ICC Profile Data" + fileName); + pde.initCause(c); + throw pde; } } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/java/util/logging/LogManager.java --- a/jdk/src/share/classes/java/util/logging/LogManager.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/java/util/logging/LogManager.java Tue Mar 24 19:12:02 2009 -0700 @@ -215,6 +215,14 @@ // This private class is used as a shutdown hook. // It does a "reset" to close all open handlers. private class Cleaner extends Thread { + + private Cleaner() { + /* Set context class loader to null in order to avoid + * keeping a strong reference to an application classloader. + */ + this.setContextClassLoader(null); + } + public void run() { // This is to ensure the LogManager. is completed // before synchronized block. Otherwise deadlocks are possible. diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/javax/imageio/ImageTypeSpecifier.java --- a/jdk/src/share/classes/javax/imageio/ImageTypeSpecifier.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/javax/imageio/ImageTypeSpecifier.java Tue Mar 24 19:12:02 2009 -0700 @@ -67,126 +67,13 @@ * BufferedImage types. */ private static ImageTypeSpecifier[] BISpecifier; - + private static ColorSpace sRGB; // Initialize the standard specifiers static { - ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); + sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); BISpecifier = new ImageTypeSpecifier[BufferedImage.TYPE_BYTE_INDEXED + 1]; - - BISpecifier[BufferedImage.TYPE_CUSTOM] = null; - - BISpecifier[BufferedImage.TYPE_INT_RGB] = - createPacked(sRGB, - 0x00ff0000, - 0x0000ff00, - 0x000000ff, - 0x0, - DataBuffer.TYPE_INT, - false); - - BISpecifier[BufferedImage.TYPE_INT_ARGB] = - createPacked(sRGB, - 0x00ff0000, - 0x0000ff00, - 0x000000ff, - 0xff000000, - DataBuffer.TYPE_INT, - false); - - BISpecifier[BufferedImage.TYPE_INT_ARGB_PRE] = - createPacked(sRGB, - 0x00ff0000, - 0x0000ff00, - 0x000000ff, - 0xff000000, - DataBuffer.TYPE_INT, - true); - - BISpecifier[BufferedImage.TYPE_INT_BGR] = - createPacked(sRGB, - 0x000000ff, - 0x0000ff00, - 0x00ff0000, - 0x0, - DataBuffer.TYPE_INT, - false); - - int[] bOffsRGB = { 2, 1, 0 }; - BISpecifier[BufferedImage.TYPE_3BYTE_BGR] = - createInterleaved(sRGB, - bOffsRGB, - DataBuffer.TYPE_BYTE, - false, - false); - - int[] bOffsABGR = { 3, 2, 1, 0 }; - BISpecifier[BufferedImage.TYPE_4BYTE_ABGR] = - createInterleaved(sRGB, - bOffsABGR, - DataBuffer.TYPE_BYTE, - true, - false); - - BISpecifier[BufferedImage.TYPE_4BYTE_ABGR_PRE] = - createInterleaved(sRGB, - bOffsABGR, - DataBuffer.TYPE_BYTE, - true, - true); - - BISpecifier[BufferedImage.TYPE_USHORT_565_RGB] = - createPacked(sRGB, - 0xF800, - 0x07E0, - 0x001F, - 0x0, - DataBuffer.TYPE_USHORT, - false); - - BISpecifier[BufferedImage.TYPE_USHORT_555_RGB] = - createPacked(sRGB, - 0x7C00, - 0x03E0, - 0x001F, - 0x0, - DataBuffer.TYPE_USHORT, - false); - - BISpecifier[BufferedImage.TYPE_BYTE_GRAY] = - createGrayscale(8, - DataBuffer.TYPE_BYTE, - false); - - BISpecifier[BufferedImage.TYPE_USHORT_GRAY] = - createGrayscale(16, - DataBuffer.TYPE_USHORT, - false); - - BISpecifier[BufferedImage.TYPE_BYTE_BINARY] = - createGrayscale(1, - DataBuffer.TYPE_BYTE, - false); - - BufferedImage bi = - new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED); - IndexColorModel icm = (IndexColorModel)bi.getColorModel(); - int mapSize = icm.getMapSize(); - byte[] redLUT = new byte[mapSize]; - byte[] greenLUT = new byte[mapSize]; - byte[] blueLUT = new byte[mapSize]; - byte[] alphaLUT = new byte[mapSize]; - - icm.getReds(redLUT); - icm.getGreens(greenLUT); - icm.getBlues(blueLUT); - icm.getAlphas(alphaLUT); - - BISpecifier[BufferedImage.TYPE_BYTE_INDEXED] = - createIndexed(redLUT, greenLUT, blueLUT, alphaLUT, - 8, - DataBuffer.TYPE_BYTE); } /** @@ -1011,7 +898,7 @@ ImageTypeSpecifier createFromBufferedImageType(int bufferedImageType) { if (bufferedImageType >= BufferedImage.TYPE_INT_RGB && bufferedImageType <= BufferedImage.TYPE_BYTE_INDEXED) { - return BISpecifier[bufferedImageType]; + return getSpecifier(bufferedImageType); } else if (bufferedImageType == BufferedImage.TYPE_CUSTOM) { throw new IllegalArgumentException("Cannot create from TYPE_CUSTOM!"); } else { @@ -1041,7 +928,7 @@ if (image instanceof BufferedImage) { int bufferedImageType = ((BufferedImage)image).getType(); if (bufferedImageType != BufferedImage.TYPE_CUSTOM) { - return BISpecifier[bufferedImageType]; + return getSpecifier(bufferedImageType); } } @@ -1225,4 +1112,130 @@ public int hashCode() { return (9 * colorModel.hashCode()) + (14 * sampleModel.hashCode()); } + + private static ImageTypeSpecifier getSpecifier(int type) { + if (BISpecifier[type] == null) { + BISpecifier[type] = createSpecifier(type); + } + return BISpecifier[type]; + } + + private static ImageTypeSpecifier createSpecifier(int type) { + switch(type) { + case BufferedImage.TYPE_INT_RGB: + return createPacked(sRGB, + 0x00ff0000, + 0x0000ff00, + 0x000000ff, + 0x0, + DataBuffer.TYPE_INT, + false); + + case BufferedImage.TYPE_INT_ARGB: + return createPacked(sRGB, + 0x00ff0000, + 0x0000ff00, + 0x000000ff, + 0xff000000, + DataBuffer.TYPE_INT, + false); + + case BufferedImage.TYPE_INT_ARGB_PRE: + return createPacked(sRGB, + 0x00ff0000, + 0x0000ff00, + 0x000000ff, + 0xff000000, + DataBuffer.TYPE_INT, + true); + + case BufferedImage.TYPE_INT_BGR: + return createPacked(sRGB, + 0x000000ff, + 0x0000ff00, + 0x00ff0000, + 0x0, + DataBuffer.TYPE_INT, + false); + + case BufferedImage.TYPE_3BYTE_BGR: + return createInterleaved(sRGB, + new int[] { 2, 1, 0 }, + DataBuffer.TYPE_BYTE, + false, + false); + + case BufferedImage.TYPE_4BYTE_ABGR: + return createInterleaved(sRGB, + new int[] { 3, 2, 1, 0 }, + DataBuffer.TYPE_BYTE, + true, + false); + + case BufferedImage.TYPE_4BYTE_ABGR_PRE: + return createInterleaved(sRGB, + new int[] { 3, 2, 1, 0 }, + DataBuffer.TYPE_BYTE, + true, + true); + + case BufferedImage.TYPE_USHORT_565_RGB: + return createPacked(sRGB, + 0xF800, + 0x07E0, + 0x001F, + 0x0, + DataBuffer.TYPE_USHORT, + false); + + case BufferedImage.TYPE_USHORT_555_RGB: + return createPacked(sRGB, + 0x7C00, + 0x03E0, + 0x001F, + 0x0, + DataBuffer.TYPE_USHORT, + false); + + case BufferedImage.TYPE_BYTE_GRAY: + return createGrayscale(8, + DataBuffer.TYPE_BYTE, + false); + + case BufferedImage.TYPE_USHORT_GRAY: + return createGrayscale(16, + DataBuffer.TYPE_USHORT, + false); + + case BufferedImage.TYPE_BYTE_BINARY: + return createGrayscale(1, + DataBuffer.TYPE_BYTE, + false); + + case BufferedImage.TYPE_BYTE_INDEXED: + { + + BufferedImage bi = + new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED); + IndexColorModel icm = (IndexColorModel)bi.getColorModel(); + int mapSize = icm.getMapSize(); + byte[] redLUT = new byte[mapSize]; + byte[] greenLUT = new byte[mapSize]; + byte[] blueLUT = new byte[mapSize]; + byte[] alphaLUT = new byte[mapSize]; + + icm.getReds(redLUT); + icm.getGreens(greenLUT); + icm.getBlues(blueLUT); + icm.getAlphas(alphaLUT); + + return createIndexed(redLUT, greenLUT, blueLUT, alphaLUT, + 8, + DataBuffer.TYPE_BYTE); + } + default: + throw new IllegalArgumentException("Invalid BufferedImage type!"); + } + } + } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/javax/imageio/metadata/IIOMetadataFormat.java --- a/jdk/src/share/classes/javax/imageio/metadata/IIOMetadataFormat.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/javax/imageio/metadata/IIOMetadataFormat.java Tue Mar 24 19:12:02 2009 -0700 @@ -242,8 +242,12 @@ /** * A constant returned by getAttributeDataType - * indicating that the value of an attribute is one of 'true' or - * 'false'. + * indicating that the value of an attribute is one of the boolean + * values 'true' or 'false'. + * Attribute values of type DATATYPE_BOOLEAN should be marked as + * enumerations, and the permitted values should be the string + * literal values "TRUE" or "FALSE", although a plugin may also + * recognise lower or mixed case equivalents. */ int DATATYPE_BOOLEAN = 1; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/awt/FontConfiguration.java --- a/jdk/src/share/classes/sun/awt/FontConfiguration.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/awt/FontConfiguration.java Tue Mar 24 19:12:02 2009 -0700 @@ -98,7 +98,7 @@ if (!inited) { this.preferLocaleFonts = false; this.preferPropFonts = false; - fontConfig = this; /* static initialization */ + setFontConfiguration(); readFontConfigFile(fontConfigFile); initFontConfig(); inited = true; @@ -1244,6 +1244,10 @@ return fontConfig; } + protected void setFontConfiguration() { + fontConfig = this; /* static initialization */ + } + ////////////////////////////////////////////////////////////////////// // FontConfig data tables and the index constants in binary file // ////////////////////////////////////////////////////////////////////// diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/font/FileFontStrike.java --- a/jdk/src/share/classes/sun/font/FileFontStrike.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/font/FileFontStrike.java Tue Mar 24 19:12:02 2009 -0700 @@ -26,6 +26,7 @@ package sun.font; import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; @@ -842,8 +843,36 @@ return fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode); } + private + WeakReference> outlineMapRef; + GeneralPath getGlyphOutline(int glyphCode, float x, float y) { - return fileFont.getGlyphOutline(pScalerContext, glyphCode, x, y); + + GeneralPath gp = null; + ConcurrentHashMap outlineMap = null; + + if (outlineMapRef != null) { + outlineMap = outlineMapRef.get(); + if (outlineMap != null) { + gp = (GeneralPath)outlineMap.get(glyphCode); + } + } + + if (gp == null) { + gp = fileFont.getGlyphOutline(pScalerContext, glyphCode, 0, 0); + if (outlineMap == null) { + outlineMap = new ConcurrentHashMap(); + outlineMapRef = + new WeakReference + >(outlineMap); + } + outlineMap.put(glyphCode, gp); + } + gp = (GeneralPath)gp.clone(); // mutable! + if (x != 0f || y != 0f) { + gp.transform(AffineTransform.getTranslateInstance(x, y)); + } + return gp; } GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) { diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/font/FontManager.java --- a/jdk/src/share/classes/sun/font/FontManager.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/font/FontManager.java Tue Mar 24 19:12:02 2009 -0700 @@ -1601,18 +1601,27 @@ /* Path may be absolute or a base file name relative to one of * the platform font directories */ - private static String getPathName(String s) { + private static String getPathName(final String s) { File f = new File(s); if (f.isAbsolute()) { return s; } else if (pathDirs.length==1) { return pathDirs[0] + File.separator + s; } else { - for (int p=0; p() { + public String run() { + for (int p=0; p(10); cacheRef = new SoftReference>(cache); + } else if (cache.size() >= 512) { + cache.clear(); } cache.put(key, res); } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/font/StrikeCache.java --- a/jdk/src/share/classes/sun/font/StrikeCache.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/font/StrikeCache.java Tue Mar 24 19:12:02 2009 -0700 @@ -232,6 +232,16 @@ if (disposer.pScalerContext != 0L) { freeLongMemory(new long[0], disposer.pScalerContext); } + } else if (disposer.pScalerContext != 0L) { + /* Rarely a strike may have been created that never cached + * any glyphs. In this case we still want to free the scaler + * context. + */ + if (FontManager.longAddresses) { + freeLongMemory(new long[0], disposer.pScalerContext); + } else { + freeIntMemory(new int[0], disposer.pScalerContext); + } } } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/java2d/cmm/ProfileActivator.java --- a/jdk/src/share/classes/sun/java2d/cmm/ProfileActivator.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/cmm/ProfileActivator.java Tue Mar 24 19:12:02 2009 -0700 @@ -25,6 +25,7 @@ package sun.java2d.cmm; +import java.awt.color.ProfileDataException; /** * An interface to allow the ProfileDeferralMgr to activate a @@ -35,6 +36,6 @@ /** * Activate a previously deferred ICC_Profile object. */ - public void activate(); + public void activate() throws ProfileDataException; } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/java2d/cmm/ProfileDeferralMgr.java --- a/jdk/src/share/classes/sun/java2d/cmm/ProfileDeferralMgr.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/cmm/ProfileDeferralMgr.java Tue Mar 24 19:12:02 2009 -0700 @@ -25,6 +25,7 @@ package sun.java2d.cmm; +import java.awt.color.ProfileDataException; import java.util.Vector; @@ -39,7 +40,7 @@ public class ProfileDeferralMgr { public static boolean deferring = true; - private static Vector aVector; + private static Vector aVector; /** * Records a ProfileActivator object whose activate method will @@ -51,7 +52,7 @@ return; } if (aVector == null) { - aVector = new Vector(3, 3); + aVector = new Vector(3, 3); } aVector.addElement(pa); return; @@ -89,8 +90,26 @@ return; } n = aVector.size(); - for (i = 0; i < n; i++) { - ((ProfileActivator) aVector.get(i)).activate(); + for (ProfileActivator pa : aVector) { + try { + pa.activate(); + } catch (ProfileDataException e) { + /* + * Ignore profile activation error for now: + * such exception is pssible due to absence + * or corruption of standard color profile. + * As for now we expect all profiles should + * be shiped with jre and presence of this + * exception is indication of some configuration + * problem in jre installation. + * + * NB: we still are greedy loading deferred profiles + * and load them all if any of them is needed. + * Therefore broken profile (if any) might be never used. + * If there will be attempt to use broken profile then + * it will result in CMMException. + */ + } } aVector.removeAllElements(); aVector = null; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/java2d/pisces/Dasher.java --- a/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Tue Mar 24 19:12:02 2009 -0700 @@ -120,7 +120,7 @@ // Normalize so 0 <= phase < dash[0] int idx = 0; - dashOn = false; + dashOn = true; int d; while (phase >= (d = dash[idx])) { phase -= d; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java --- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Tue Mar 24 19:12:02 2009 -0700 @@ -245,6 +245,7 @@ FloatToS15_16(coords[1])); break; case PathIterator.SEG_CLOSE: + lsink.lineJoin(); lsink.close(); break; default: diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/classes/sun/print/ServiceDialog.java --- a/jdk/src/share/classes/sun/print/ServiceDialog.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/classes/sun/print/ServiceDialog.java Tue Mar 24 19:12:02 2009 -0700 @@ -2149,55 +2149,51 @@ } } } - - rbPortrait.setEnabled(pSupported); - rbLandscape.setEnabled(lSupported); - rbRevPortrait.setEnabled(rpSupported); - rbRevLandscape.setEnabled(rlSupported); - - OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory); - if (or == null || - !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) { - - or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory); - // need to validate if default is not supported - if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) { - or = null; - values = - psCurrent.getSupportedAttributeValues(orCategory, - docFlavor, - asCurrent); - if (values instanceof OrientationRequested[]) { - OrientationRequested[] orValues = - (OrientationRequested[])values; - if (orValues.length > 1) { - // get the first in the list - or = orValues[0]; - } + } + + + rbPortrait.setEnabled(pSupported); + rbLandscape.setEnabled(lSupported); + rbRevPortrait.setEnabled(rpSupported); + rbRevLandscape.setEnabled(rlSupported); + + OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory); + if (or == null || + !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) { + + or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory); + // need to validate if default is not supported + if ((or != null) && + !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) { + or = null; + Object values = + psCurrent.getSupportedAttributeValues(orCategory, + docFlavor, + asCurrent); + if (values instanceof OrientationRequested[]) { + OrientationRequested[] orValues = + (OrientationRequested[])values; + if (orValues.length > 1) { + // get the first in the list + or = orValues[0]; } } - - if (or == null) { - or = OrientationRequested.PORTRAIT; - } - asCurrent.add(or); + } + + if (or == null) { + or = OrientationRequested.PORTRAIT; } - - if (or == OrientationRequested.PORTRAIT) { - rbPortrait.setSelected(true); - } else if (or == OrientationRequested.LANDSCAPE) { - rbLandscape.setSelected(true); - } else if (or == OrientationRequested.REVERSE_PORTRAIT) { - rbRevPortrait.setSelected(true); - } else { // if (or == OrientationRequested.REVERSE_LANDSCAPE) - rbRevLandscape.setSelected(true); - } - } else { - rbPortrait.setEnabled(pSupported); - rbLandscape.setEnabled(lSupported); - rbRevPortrait.setEnabled(rpSupported); - rbRevLandscape.setEnabled(rlSupported); - + asCurrent.add(or); + } + + if (or == OrientationRequested.PORTRAIT) { + rbPortrait.setSelected(true); + } else if (or == OrientationRequested.LANDSCAPE) { + rbLandscape.setSelected(true); + } else if (or == OrientationRequested.REVERSE_PORTRAIT) { + rbRevPortrait.setSelected(true); + } else { // if (or == OrientationRequested.REVERSE_LANDSCAPE) + rbRevLandscape.setSelected(true); } } } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/awt/image/dither.c --- a/jdk/src/share/native/sun/awt/image/dither.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/awt/image/dither.c Tue Mar 24 19:12:02 2009 -0700 @@ -169,6 +169,7 @@ int cubesize = cube_dim * cube_dim * cube_dim; unsigned char *useFlags; unsigned char *newILut = (unsigned char*)malloc(cubesize); + int cmap_mid = (cmap_len >> 1) + (cmap_len & 0x1); if (newILut) { useFlags = (unsigned char *)calloc(cubesize, 1); @@ -188,7 +189,7 @@ currentState.iLUT = newILut; currentState.rgb = (unsigned short *) - malloc(256 * sizeof(unsigned short)); + malloc(cmap_len * sizeof(unsigned short)); if (currentState.rgb == NULL) { free(newILut); free(useFlags); @@ -199,7 +200,7 @@ } currentState.indices = (unsigned char *) - malloc(256 * sizeof(unsigned char)); + malloc(cmap_len * sizeof(unsigned char)); if (currentState.indices == NULL) { free(currentState.rgb); free(newILut); @@ -210,18 +211,18 @@ return NULL; } - for (i = 0; i < 128; i++) { + for (i = 0; i < cmap_mid; i++) { unsigned short rgb; int pixel = cmap[i]; rgb = (pixel & 0x00f80000) >> 9; rgb |= (pixel & 0x0000f800) >> 6; rgb |= (pixel & 0xf8) >> 3; INSERTNEW(currentState, rgb, i); - pixel = cmap[255-i]; + pixel = cmap[cmap_len - i - 1]; rgb = (pixel & 0x00f80000) >> 9; rgb |= (pixel & 0x0000f800) >> 6; rgb |= (pixel & 0xf8) >> 3; - INSERTNEW(currentState, rgb, 255-i); + INSERTNEW(currentState, rgb, cmap_len - i - 1); } if (!recurseLevel(¤tState)) { diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Tue Mar 24 19:12:02 2009 -0700 @@ -396,7 +396,7 @@ data->jpegObj = cinfo; cinfo->client_data = data; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("new structures: data is %p, cinfo is %p\n", data, cinfo); #endif @@ -673,7 +673,7 @@ j_decompress_ptr decomp; qlen = (*env)->GetArrayLength(env, qtables); -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("in setQTables, qlen = %d, write is %d\n", qlen, write); #endif for (i = 0; i < qlen; i++) { @@ -876,7 +876,7 @@ return FALSE; } -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("Filling input buffer, remaining skip is %ld, ", sb->remaining_skip); printf("Buffer length is %d\n", sb->bufferLength); @@ -906,7 +906,7 @@ cinfo->err->error_exit((j_common_ptr) cinfo); } -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("Buffer filled. ret = %d\n", ret); #endif /* @@ -917,7 +917,7 @@ */ if (ret <= 0) { jobject reader = data->imageIOobj; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("YO! Early EOI! ret = %d\n", ret); #endif RELEASE_ARRAYS(env, data, src->next_input_byte); @@ -1216,21 +1216,24 @@ { jpeg_saved_marker_ptr marker; int num_markers = 0; + int num_found_markers = 0; int seq_no; JOCTET *icc_data; + JOCTET *dst_ptr; unsigned int total_length; #define MAX_SEQ_NO 255 // sufficient since marker numbers are bytes - char marker_present[MAX_SEQ_NO+1]; // 1 if marker found - unsigned int data_length[MAX_SEQ_NO+1]; // size of profile data in marker - unsigned int data_offset[MAX_SEQ_NO+1]; // offset for data in marker + jpeg_saved_marker_ptr icc_markers[MAX_SEQ_NO + 1]; + int first; // index of the first marker in the icc_markers array + int last; // index of the last marker in the icc_markers array jbyteArray data = NULL; /* This first pass over the saved markers discovers whether there are * any ICC markers and verifies the consistency of the marker numbering. */ - for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) - marker_present[seq_no] = 0; + for (seq_no = 0; seq_no <= MAX_SEQ_NO; seq_no++) + icc_markers[seq_no] = NULL; + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { if (marker_is_icc(marker)) { @@ -1242,37 +1245,58 @@ return NULL; } seq_no = GETJOCTET(marker->data[12]); - if (seq_no <= 0 || seq_no > num_markers) { + + /* Some third-party tools produce images with profile chunk + * numeration started from zero. It is inconsistent with ICC + * spec, but seems to be recognized by majority of image + * processing tools, so we should be more tolerant to this + * departure from the spec. + */ + if (seq_no < 0 || seq_no > num_markers) { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid icc profile: bad sequence number"); return NULL; } - if (marker_present[seq_no]) { + if (icc_markers[seq_no] != NULL) { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid icc profile: duplicate sequence numbers"); return NULL; } - marker_present[seq_no] = 1; - data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN; + icc_markers[seq_no] = marker; + num_found_markers ++; } } if (num_markers == 0) return NULL; // There is no profile - /* Check for missing markers, count total space needed, - * compute offset of each marker's part of the data. + if (num_markers != num_found_markers) { + JNU_ThrowByName(env, "javax/imageio/IIOException", + "Invalid icc profile: invalid number of icc markers"); + return NULL; + } + + first = icc_markers[0] ? 0 : 1; + last = num_found_markers + first; + + /* Check for missing markers, count total space needed. */ - total_length = 0; - for (seq_no = 1; seq_no <= num_markers; seq_no++) { - if (marker_present[seq_no] == 0) { + for (seq_no = first; seq_no < last; seq_no++) { + unsigned int length; + if (icc_markers[seq_no] == NULL) { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid icc profile: missing sequence number"); return NULL; } - data_offset[seq_no] = total_length; - total_length += data_length[seq_no]; + /* check the data length correctness */ + length = icc_markers[seq_no]->data_length; + if (ICC_OVERHEAD_LEN > length || length > MAX_BYTES_IN_MARKER) { + JNU_ThrowByName(env, "javax/imageio/IIOException", + "Invalid icc profile: invalid data length"); + return NULL; + } + total_length += (length - ICC_OVERHEAD_LEN); } if (total_length <= 0) { @@ -1301,19 +1325,14 @@ } /* and fill it in */ - for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { - if (marker_is_icc(marker)) { - JOCTET FAR *src_ptr; - JOCTET *dst_ptr; - unsigned int length; - seq_no = GETJOCTET(marker->data[12]); - dst_ptr = icc_data + data_offset[seq_no]; - src_ptr = marker->data + ICC_OVERHEAD_LEN; - length = data_length[seq_no]; - while (length--) { - *dst_ptr++ = *src_ptr++; - } - } + dst_ptr = icc_data; + for (seq_no = first; seq_no < last; seq_no++) { + JOCTET FAR *src_ptr = icc_markers[seq_no]->data + ICC_OVERHEAD_LEN; + unsigned int length = + icc_markers[seq_no]->data_length - ICC_OVERHEAD_LEN; + + memcpy(dst_ptr, src_ptr, length); + dst_ptr += length; } /* finally, unpin the array */ @@ -1530,6 +1549,7 @@ j_decompress_ptr cinfo; struct jpeg_source_mgr *src; sun_jpeg_error_ptr jerr; + jbyteArray profileData = NULL; if (data == NULL) { JNU_ThrowByName(env, @@ -1557,7 +1577,7 @@ return retval; } -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("In readImageHeader, data is %p cinfo is %p\n", data, cinfo); printf("clearFirst is %d\n", clearFirst); #endif @@ -1584,7 +1604,7 @@ if (ret == JPEG_HEADER_TABLES_ONLY) { retval = JNI_TRUE; imageio_term_source(cinfo); // Pushback remaining buffer contents -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("just read tables-only image; q table 0 at %p\n", cinfo->quant_tbl_ptrs[0]); #endif @@ -1691,6 +1711,14 @@ } } RELEASE_ARRAYS(env, data, src->next_input_byte); + + /* read icc profile data */ + profileData = read_icc_profile(env, cinfo); + + if ((*env)->ExceptionCheck(env)) { + return retval; + } + (*env)->CallVoidMethod(env, this, JPEGImageReader_setImageDataID, cinfo->image_width, @@ -1698,7 +1726,7 @@ cinfo->jpeg_color_space, cinfo->out_color_space, cinfo->num_components, - read_icc_profile(env, cinfo)); + profileData); if (reset) { jpeg_abort_decompress(cinfo); } @@ -1827,7 +1855,7 @@ (*env)->ReleaseIntArrayElements(env, srcBands, body, JNI_ABORT); -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("---- in reader.read ----\n"); printf("numBands is %d\n", numBands); printf("bands array: "); @@ -2487,7 +2515,7 @@ data->streamBuf.suspendable = FALSE; if (qtables != NULL) { -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("in writeTables: qtables not NULL\n"); #endif setQTables(env, (j_common_ptr) cinfo, qtables, TRUE); @@ -2763,7 +2791,7 @@ cinfo->restart_interval = restartInterval; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("writer setup complete, starting compressor\n"); #endif @@ -2812,13 +2840,13 @@ for (i = 0; i < numBands; i++) { if (scale !=NULL && scale[i] != NULL) { *out++ = scale[i][*(in+i)]; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG if (in == data->pixelBuf.buf.bp){ // Just the first pixel printf("in %d -> out %d, ", *(in+i), *(out-i-1)); } #endif -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG if (in == data->pixelBuf.buf.bp){ // Just the first pixel printf("\n"); } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/font/freetypeScaler.c --- a/jdk/src/share/native/sun/font/freetypeScaler.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/font/freetypeScaler.c Tue Mar 24 19:12:02 2009 -0700 @@ -394,12 +394,14 @@ scalerInfo->env = env; scalerInfo->font2D = font2D; - FT_Set_Transform(scalerInfo->face, &context->transform, NULL); + if (context != NULL) { + FT_Set_Transform(scalerInfo->face, &context->transform, NULL); - errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72); + errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72); - if (errCode == 0) { - errCode = FT_Activate_Size(scalerInfo->face->size); + if (errCode == 0) { + errCode = FT_Activate_Size(scalerInfo->face->size); + } } return errCode; @@ -885,6 +887,14 @@ JNIEnv *env, jobject scaler, jlong pScaler) { FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler); + /* Freetype functions *may* cause callback to java + that can use cached values. Make sure our cache is up to date. + NB: scaler context is not important at this point, can use NULL. */ + int errCode = setupFTContext(env, scaler, scalerInfo, NULL); + if (errCode) { + return; + } + freeNativeResources(env, scalerInfo); } @@ -932,12 +942,21 @@ JNIEnv *env, jobject scaler, jlong pScaler, jchar charCode) { FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler); + int errCode; if (scaler == NULL || scalerInfo->face == NULL) { /* bad/null scaler */ invalidateJavaScaler(env, scaler, scalerInfo); return 0; } + /* Freetype functions *may* cause callback to java + that can use cached values. Make sure our cache is up to date. + Scaler context is not important here, can use NULL. */ + errCode = setupFTContext(env, scaler, scalerInfo, NULL); + if (errCode) { + return 0; + } + return FT_Get_Char_Index(scalerInfo->face, charCode); } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Tue Mar 24 19:12:02 2009 -0700 @@ -30,6 +30,41 @@ #include "Disposer.h" #include "lcms.h" + +#define ALIGNLONG(x) (((x)+3) & ~(3)) // Aligns to DWORD boundary + +#ifdef USE_BIG_ENDIAN +#define AdjustEndianess32(a) +#else + +static +void AdjustEndianess32(LPBYTE pByte) +{ + BYTE temp1; + BYTE 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 +icInt32Number TransportValue32(icInt32Number Value) +{ + icInt32Number Temp = Value; + + AdjustEndianess32((LPBYTE) &Temp); + return Temp; +} + #define SigMake(a,b,c,d) \ ( ( ((int) ((unsigned char) (a))) << 24) | \ ( ((int) ((unsigned char) (b))) << 16) | \ @@ -182,6 +217,8 @@ sProf.pf = cmsOpenProfileFromMem((LPVOID)dataArray, (DWORD) dataSize); + (*env)->ReleaseByteArrayElements (env, data, dataArray, 0); + if (sProf.pf == NULL) { JNU_ThrowIllegalArgumentException(env, "Invalid profile data"); } @@ -337,6 +374,10 @@ return; } +// Modify data for a tag in a profile +LCMSBOOL LCMSEXPORT _cmsModifyTagData(cmsHPROFILE hProfile, + icTagSignature sig, void *data, size_t size); + /* * Class: sun_java2d_cmm_lcms_LCMS * Method: setTagData @@ -345,7 +386,23 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagData (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data) { - fprintf(stderr, "setTagData operation is not implemented"); + cmsHPROFILE profile; + storeID_t sProf; + jbyte* dataArray; + int tagSize; + + if (tagSig == SigHead) { + J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_setTagData on icSigHead not " + "permitted"); + return; + } + + sProf.j = id; + profile = (cmsHPROFILE) sProf.pf; + dataArray = (*env)->GetByteArrayElements(env, data, 0); + tagSize =(*env)->GetArrayLength(env, data); + _cmsModifyTagData(profile, (icTagSignature) tagSig, dataArray, tagSize); + (*env)->ReleaseByteArrayElements(env, data, dataArray, 0); } void* getILData (JNIEnv *env, jobject img, jint* pDataType, @@ -507,3 +564,174 @@ PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J"); } + +LCMSBOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig, + void *data, size_t size) +{ + LCMSBOOL isNew; + int i, idx, delta, count; + LPBYTE padChars[3] = {0, 0, 0}; + LPBYTE beforeBuf, afterBuf, ptr; + size_t beforeSize, afterSize; + icUInt32Number profileSize, temp; + LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; + + isNew = FALSE; + idx = _cmsSearchTag(Icc, sig, FALSE); + if (idx < 0) { + isNew = TRUE; + idx = Icc->TagCount++; + if (Icc->TagCount >= MAX_TABLE_TAG) { + J2dRlsTraceLn1(J2D_TRACE_ERROR, "_cmsModifyTagData: Too many tags " + "(%d)\n", Icc->TagCount); + Icc->TagCount = MAX_TABLE_TAG-1; + return FALSE; + } + } + + /* Read in size from header */ + Icc->Seek(Icc, 0); + Icc->Read(&profileSize, sizeof(icUInt32Number), 1, Icc); + AdjustEndianess32((LPBYTE) &profileSize); + + /* Compute the change in profile size */ + if (isNew) { + delta = sizeof(icTag) + ALIGNLONG(size); + } else { + delta = ALIGNLONG(size) - ALIGNLONG(Icc->TagSizes[idx]); + } + /* Add tag to internal structures */ + ptr = malloc(size); + if (ptr == NULL) { + if(isNew) { + Icc->TagCount--; + } + J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: ptr == NULL"); + return FALSE; + } + + if (!Icc->Grow(Icc, delta)) { + free(ptr); + if(isNew) { + Icc->TagCount--; + } + J2dRlsTraceLn(J2D_TRACE_ERROR, + "_cmsModifyTagData: Icc->Grow() == FALSE"); + return FALSE; + } + + /* Compute size of tag data before/after the modified tag */ + beforeSize = ((isNew)?profileSize:Icc->TagOffsets[idx]) - + Icc->TagOffsets[0]; + if (Icc->TagCount == (idx + 1)) { + afterSize = 0; + } else { + afterSize = profileSize - Icc->TagOffsets[idx+1]; + } + /* Make copies of the data before/after the modified tag */ + if (beforeSize > 0) { + beforeBuf = malloc(beforeSize); + if (!beforeBuf) { + if(isNew) { + Icc->TagCount--; + } + free(ptr); + J2dRlsTraceLn(J2D_TRACE_ERROR, + "_cmsModifyTagData: beforeBuf == NULL"); + return FALSE; + } + Icc->Seek(Icc, Icc->TagOffsets[0]); + Icc->Read(beforeBuf, beforeSize, 1, Icc); + } + + if (afterSize > 0) { + afterBuf = malloc(afterSize); + if (!afterBuf) { + free(ptr); + if(isNew) { + Icc->TagCount--; + } + if (beforeSize > 0) { + free(beforeBuf); + } + J2dRlsTraceLn(J2D_TRACE_ERROR, + "_cmsModifyTagData: afterBuf == NULL"); + return FALSE; + } + Icc->Seek(Icc, Icc->TagOffsets[idx+1]); + Icc->Read(afterBuf, afterSize, 1, Icc); + } + + CopyMemory(ptr, data, size); + Icc->TagSizes[idx] = size; + Icc->TagNames[idx] = sig; + if (Icc->TagPtrs[idx]) { + free(Icc->TagPtrs[idx]); + } + Icc->TagPtrs[idx] = ptr; + if (isNew) { + Icc->TagOffsets[idx] = profileSize; + } + + + /* Update the profile size in the header */ + profileSize += delta; + Icc->Seek(Icc, 0); + temp = TransportValue32(profileSize); + Icc->Write(Icc, sizeof(icUInt32Number), &temp); + + + /* Adjust tag offsets: if the tag is new, we must account + for the new tag table entry; otherwise, only those tags after + the modified tag are changed (by delta) */ + if (isNew) { + for (i = 0; i < Icc->TagCount; ++i) { + Icc->TagOffsets[i] += sizeof(icTag); + } + } else { + for (i = idx+1; i < Icc->TagCount; ++i) { + Icc->TagOffsets[i] += delta; + } + } + + /* Write out a new tag table */ + count = 0; + for (i = 0; i < Icc->TagCount; ++i) { + if (Icc->TagNames[i] != 0) { + ++count; + } + } + Icc->Seek(Icc, sizeof(icHeader)); + temp = TransportValue32(count); + Icc->Write(Icc, sizeof(icUInt32Number), &temp); + + for (i = 0; i < Icc->TagCount; ++i) { + if (Icc->TagNames[i] != 0) { + icTag tag; + tag.sig = TransportValue32(Icc->TagNames[i]); + tag.offset = TransportValue32((icInt32Number) Icc->TagOffsets[i]); + tag.size = TransportValue32((icInt32Number) Icc->TagSizes[i]); + Icc->Write(Icc, sizeof(icTag), &tag); + } + } + + /* Write unchanged data before the modified tag */ + if (beforeSize > 0) { + Icc->Write(Icc, beforeSize, beforeBuf); + free(beforeBuf); + } + + /* Write modified tag data */ + Icc->Write(Icc, size, data); + if (size % 4) { + Icc->Write(Icc, 4 - (size % 4), padChars); + } + + /* Write unchanged data after the modified tag */ + if (afterSize > 0) { + Icc->Write(Icc, afterSize, afterBuf); + free(afterBuf); + } + + return TRUE; +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -51,7 +51,7 @@ -// CIECAM 02 appearance model +// CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging. #include "lcms.h" @@ -196,6 +196,10 @@ clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1; } } + + clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] + + (clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb; + return clr; } @@ -249,9 +253,6 @@ clr.H = 300 + ((100*((clr.h - 237.53)/1.2)) / temp); } - clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] + - (clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb; - clr.J = 100.0 * pow((clr.A / pMod->adoptedWhite.A), (pMod->c * pMod->z)); @@ -395,7 +396,7 @@ LPcmsCIECAM02 lpMod; - if((lpMod = (LPcmsCIECAM02) malloc(sizeof(cmsCIECAM02))) == NULL) { + if((lpMod = (LPcmsCIECAM02) _cmsMalloc(sizeof(cmsCIECAM02))) == NULL) { return (LCMSHANDLE) NULL; } @@ -449,14 +450,19 @@ lpMod -> z = compute_z(lpMod); lpMod -> Nbb = computeNbb(lpMod); lpMod -> FL = computeFL(lpMod); + + if (lpMod -> D == D_CALCULATE || + lpMod -> D == D_CALCULATE_DISCOUNT) { + lpMod -> D = computeD(lpMod); + } + lpMod -> Ncb = lpMod -> Nbb; lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite); lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod); lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite); lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod); - lpMod -> adoptedWhite = ComputeCorrelates(lpMod -> adoptedWhite, lpMod); return (LCMSHANDLE) lpMod; @@ -465,7 +471,7 @@ void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel) { LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel; - if (lpMod) free(lpMod); + if (lpMod) _cmsFree(lpMod); } @@ -510,3 +516,4 @@ pOut ->Z = clr.XYZ[2]; } + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -174,7 +174,7 @@ LCMSAPI void LCMSEXPORT cmsCIECAM97sDone(LCMSHANDLE hModel) { LPcmsCIECAM97s lpMod = (LPcmsCIECAM97s) (LPSTR) hModel; - if (lpMod) free(lpMod); + if (lpMod) _cmsFree(lpMod); } // Partial discounting for adaptation degree computation @@ -331,7 +331,7 @@ LPcmsCIECAM97s lpMod; VEC3 tmp; - if((lpMod = (LPcmsCIECAM97s) malloc(sizeof(cmsCIECAM97s))) == NULL) { + if((lpMod = (LPcmsCIECAM97s) _cmsMalloc(sizeof(cmsCIECAM97s))) == NULL) { return (LCMSHANDLE) NULL; } @@ -449,7 +449,7 @@ // RGB_subw = [MlamRigg][WP/YWp] #ifdef USE_CIECAM97s2 - MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, (LPVEC3) &lpMod -> WP); + MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &lpMod -> WP); #else VEC3divK(&tmp, (LPVEC3) &lpMod -> WP, lpMod->WP.Y); MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &tmp); diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -65,22 +65,25 @@ // Persistence LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName); LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len); -LCMSAPI BOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName); // Properties LCMSAPI const char* LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type); - -LCMSAPI BOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment); - -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type); + +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment); + +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char* cSubProp, const char *Val); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer); LCMSAPI const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp); LCMSAPI double LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp); -LCMSAPI int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames); +LCMSAPI const char* LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char *cSubProp); +LCMSAPI int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, const char ***PropertyNames); +LCMSAPI int LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char*** SubpropertyNames); // Datasets @@ -89,10 +92,10 @@ LCMSAPI const char* LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col); LCMSAPI double LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int col, int row); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val); LCMSAPI const char* LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample); @@ -100,15 +103,15 @@ LCMSAPI double LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample, const char *Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, const char* cSample, double Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample); LCMSAPI int LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames); LCMSAPI void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter); @@ -126,7 +129,7 @@ // #define STRICT_CGATS 1 #define MAXID 128 // Max lenght of identifier -#define MAXSTR 255 // Max lenght of string +#define MAXSTR 1024 // Max lenght of string #define MAXTABLES 255 // Max Number of tables in a single stream #define MAXINCLUDE 20 // Max number of nested includes @@ -137,6 +140,9 @@ #ifndef NON_WINDOWS #include +#define DIR_CHAR '\\' +#else +#define DIR_CHAR '/' #endif // Symbols @@ -160,6 +166,7 @@ SEND_DATA, SEND_DATA_FORMAT, SKEYWORD, + SDATA_FORMAT_ID, SINCLUDE } SYMBOL; @@ -171,7 +178,8 @@ WRITE_UNCOOKED, WRITE_STRINGIFY, WRITE_HEXADECIMAL, - WRITE_BINARY + WRITE_BINARY, + WRITE_PAIR } WRITEMODE; @@ -181,6 +189,8 @@ struct _KeyVal* Next; char* Keyword; // Name of variable + struct _KeyVal* NextSubkey; // If key is a dictionary, points to the next item + char* Subkey; // If key is a dictionary, points to the subkey name char* Value; // Points to value WRITEMODE WriteAs; // How to write the value @@ -220,7 +230,12 @@ } TABLE, *LPTABLE; - +// File stream being parsed + +typedef struct _FileContext { + char FileName[MAX_PATH]; // File name if being readed from file + FILE* Stream; // File stream or NULL if holded in memory + } FILECTX, *LPFILECTX; // This struct hold all information about an openened // IT8 handler. Only one dataset is allowed. @@ -257,9 +272,9 @@ char* Source; // Points to loc. being parsed int lineno; // line counter for error reporting - char FileName[MAX_PATH]; // File name if being readed from file - FILE* Stream[MAXINCLUDE]; // File stream or NULL if holded in memory + LPFILECTX FileStack[MAXINCLUDE]; // Stack of files being parsed int IncludeSP; // Include Stack Pointer + char* MemoryBlock; // The stream if holded in memory char DoubleFormatter[MAXID]; // Printf-like 'double' formatter @@ -270,14 +285,14 @@ typedef struct { - FILE* stream; // For save-to-file behaviour - - LPBYTE Base; - LPBYTE Ptr; // For save-to-mem behaviour - size_t Used; - size_t Max; - - } SAVESTREAM, FAR* LPSAVESTREAM; + FILE* stream; // For save-to-file behaviour + + LPBYTE Base; + LPBYTE Ptr; // For save-to-mem behaviour + size_t Used; + size_t Max; + + } SAVESTREAM, FAR* LPSAVESTREAM; // ------------------------------------------------------ IT8 parsing routines @@ -298,59 +313,104 @@ {".INCLUDE", SINCLUDE}, {"BEGIN_DATA", SBEGIN_DATA }, {"BEGIN_DATA_FORMAT", SBEGIN_DATA_FORMAT }, + {"DATA_FORMAT_IDENTIFIER", SDATA_FORMAT_ID}, {"END_DATA", SEND_DATA}, {"END_DATA_FORMAT", SEND_DATA_FORMAT}, {"KEYWORD", SKEYWORD} - }; #define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD)) // Predefined properties -static const char* PredefinedProperties[] = { - - "NUMBER_OF_FIELDS", // Required - NUMBER OF FIELDS - "NUMBER_OF_SETS", // Required - NUMBER OF SETS - "ORIGINATOR", // Required - Identifies the specific system, organization or individual that created the data file. - "FILE_DESCRIPTOR", // Required - Describes the purpose or contents of the data file. - "CREATED", // Required - Indicates date of creation of the data file. - "DESCRIPTOR", // Required - Describes the purpose or contents of the data file. - "DIFFUSE_GEOMETRY", // The diffuse geometry used. Allowed values are "sphere" or "opal". - "MANUFACTURER", - "MANUFACTURE", // Some broken Fuji targets does store this value - "PROD_DATE", // Identifies year and month of production of the target in the form yyyy:mm. - "SERIAL", // Uniquely identifies individual physical target. - - "MATERIAL", // Identifies the material on which the target was produced using a code +// A property +typedef struct { + const char *id; + WRITEMODE as; + } PROPERTY; + +static PROPERTY PredefinedProperties[] = { + + {"NUMBER_OF_FIELDS", WRITE_UNCOOKED}, // Required - NUMBER OF FIELDS + {"NUMBER_OF_SETS", WRITE_UNCOOKED}, // Required - NUMBER OF SETS + {"ORIGINATOR", WRITE_STRINGIFY}, // Required - Identifies the specific system, organization or individual that created the data file. + {"FILE_DESCRIPTOR", WRITE_STRINGIFY}, // Required - Describes the purpose or contents of the data file. + {"CREATED", WRITE_STRINGIFY}, // Required - Indicates date of creation of the data file. + {"DESCRIPTOR", WRITE_STRINGIFY}, // Required - Describes the purpose or contents of the data file. + {"DIFFUSE_GEOMETRY", WRITE_STRINGIFY}, // The diffuse geometry used. Allowed values are "sphere" or "opal". + {"MANUFACTURER", WRITE_STRINGIFY}, + {"MANUFACTURE", WRITE_STRINGIFY}, // Some broken Fuji targets does store this value + {"PROD_DATE", WRITE_STRINGIFY}, // Identifies year and month of production of the target in the form yyyy:mm. + {"SERIAL", WRITE_STRINGIFY}, // Uniquely identifies individual physical target. + + {"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code // uniquely identifying th e material. This is intend ed to be used for IT8.7 // physical targets only (i.e . IT8.7/1 a nd IT8.7/2). - "INSTRUMENTATION", // Used to report the specific instrumentation used (manufacturer and + {"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and // model number) to generate the data reported. This data will often // provide more information about the particular data collected than an // extensive list of specific details. This is particularly important for // spectral data or data derived from spectrophotometry. - "MEASUREMENT_SOURCE", // Illumination used for spectral measurements. This data helps provide + {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide // a guide to the potential for issues of paper fluorescence, etc. - "PRINT_CONDITIONS", // Used to define the characteristics of the printed sheet being reported. + {"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported. // Where standard conditions have been defined (e.g., SWOP at nominal) // named conditions may suffice. Otherwise, detailed information is // needed. - "SAMPLE_BACKING", // Identifies the backing material used behind the sample during - // measurement. Allowed values are “black”, “white”, or "na". - - "CHISQ_DOF" // Degrees of freedom associated with the Chi squared statistic + {"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during + // measurement. Allowed values are “black”, “white”, or {"na". + + {"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic + +// new in recent specs: + {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated + // along with details of the geometry and the aperture size and shape. For example, + // for transmission measurements it is important to identify 0/diffuse, diffuse/0, + // opal or integrating sphere, etc. For reflection it is important to identify 0/45, + // 45/0, sphere (specular included or excluded), etc. + + {"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to + // denote the use of filters such as none, D65, Red, Green or Blue. + + {"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed + // values are {"yes”, “white”, “none” or “na”. + + {"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the + // calculation of various data parameters (2 degree and 10 degree), CIE standard + // illuminant functions used in the calculation of various data parameters (e.g., D50, + // D65, etc.), density status response, etc. If used there shall be at least one + // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute + // in the set shall be {"name" and shall identify the particular parameter used. + // The second shall be {"value" and shall provide the value associated with that name. + // For ASCII data, a string containing the Name and Value attribute pairs shall follow + // the weighting function keyword. A semi-colon separates attribute pairs from each + // other and within the attribute the name and value are separated by a comma. + + {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name + // of the calculation, parameter is the name of the parameter used in the calculation + // and value is the value of the parameter. + + {"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc. + + {"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target. + + {"TABLE_DESCRIPTOR", WRITE_STRINGIFY}, // Describes the purpose or contents of a data table. + + {"TABLE_NAME", WRITE_STRINGIFY} // Provides a short name for a data table. }; -#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(char *)) +#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY)) // Predefined sample types on dataset static const char* PredefinedSampleID[] = { + "SAMPLE_ID", // Identifies sample that data represents + "STRING", // Identifies label, or other non-machine readable value. + // Value must begin and end with a " symbol "CMYK_C", // Cyan component of CMYK data expressed as a percentage "CMYK_M", // Magenta component of CMYK data expressed as a percentage @@ -378,7 +438,7 @@ "LAB_B", // b* component of Lab data "LAB_C", // C*ab component of Lab data "LAB_H", // hab component of Lab data - "LAB_DE" // CIE dE + "LAB_DE", // CIE dE "LAB_DE_94", // CIE dE using CIE 94 "LAB_DE_CMC", // dE using CMC "LAB_DE_2000", // CIE dE using CIE DE 2000 @@ -388,7 +448,7 @@ "STDEV_Y", // Standard deviation of Y (tristimulus data) "STDEV_Z", // Standard deviation of Z (tristimulus data) "STDEV_L", // Standard deviation of L* - "STDEV_A" // Standard deviation of a* + "STDEV_A", // Standard deviation of a* "STDEV_B", // Standard deviation of b* "STDEV_DE", // Standard deviation of CIE dE "CHI_SQD_PAR"}; // The average of the standard deviations of L*, a* and b*. It is @@ -397,57 +457,120 @@ #define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *)) +//Forward declaration of some internal functions +static +void* AllocChunk(LPIT8 it8, size_t size); + // Checks if c is a separator static -BOOL isseparator(int c) +LCMSBOOL isseparator(int c) { return (c == ' ') || (c == '\t') || (c == '\r'); } // Checks whatever if c is a valid identifier char - static -BOOL ismiddle(int c) +LCMSBOOL ismiddle(int c) { return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127)); } // Checks whatsever if c is a valid identifier middle char. static -BOOL isidchar(int c) +LCMSBOOL isidchar(int c) { return isalnum(c) || ismiddle(c); } // Checks whatsever if c is a valid identifier first char. static -BOOL isfirstidchar(int c) +LCMSBOOL isfirstidchar(int c) { return !isdigit(c) && ismiddle(c); } +// checks whether the supplied path looks like an absolute path +// NOTE: this function doesn't checks if the path exists or even if it's legal +static +LCMSBOOL isabsolutepath(const char *path) +{ + if(path == NULL) + return FALSE; + + if(path[0] == DIR_CHAR) + return TRUE; + +#ifndef NON_WINDOWS + if(isalpha(path[0]) && path[1] == ':') + return TRUE; +#endif + return FALSE; +} + +// Makes a file path based on a given reference path +// NOTE: buffer is assumed to point to at least MAX_PATH bytes +// NOTE: both relPath and basePath are assumed to be no more than MAX_PATH characters long (including the null terminator!) +// NOTE: this function doesn't check if the path exists or even if it's legal +static +LCMSBOOL _cmsMakePath(const char *relPath, const char *basePath, char *buffer) +{ + if (!isabsolutepath(relPath)) { + + char *tail; + + strncpy(buffer, basePath, MAX_PATH-1); + tail = strrchr(buffer, DIR_CHAR); + if (tail != NULL) { + + size_t len = tail - buffer; + strncpy(tail + 1, relPath, MAX_PATH - len -1); + // TODO: if combined path is longer than MAX_PATH, this should return FALSE! + return TRUE; + } + } + strncpy(buffer, relPath, MAX_PATH - 1); + buffer[MAX_PATH-1] = 0; + return TRUE; +} + + +// Make sure no exploit is being even tried static -BOOL SynError(LPIT8 it8, const char *Txt, ...) +const char* NoMeta(const char* str) +{ + if (strchr(str, '%') != NULL) + return "**** CORRUPTED FORMAT STRING ***"; + + return str; +} + + +// Syntax error +static +LCMSBOOL SynError(LPIT8 it8, const char *Txt, ...) { char Buffer[256], ErrMsg[1024]; va_list args; va_start(args, Txt); - vsprintf(Buffer, Txt, args); + vsnprintf(Buffer, 255, Txt, args); + Buffer[255] = 0; va_end(args); - sprintf(ErrMsg, "%s: Line %d, %s", it8->FileName, it8->lineno, Buffer); + snprintf(ErrMsg, 1023, "%s: Line %d, %s", it8->FileStack[it8 ->IncludeSP]->FileName, it8->lineno, Buffer); + ErrMsg[1023] = 0; it8->sy = SSYNERROR; - cmsSignalError(LCMS_ERRC_ABORTED, ErrMsg); + cmsSignalError(LCMS_ERRC_ABORTED, "%s", ErrMsg); return FALSE; } +// Check if current symbol is same as specified. issue an error else. static -BOOL Check(LPIT8 it8, SYMBOL sy, const char* Err) +LCMSBOOL Check(LPIT8 it8, SYMBOL sy, const char* Err) { if (it8 -> sy != sy) - return SynError(it8, Err); + return SynError(it8, NoMeta(Err)); return TRUE; } @@ -457,15 +580,15 @@ static void NextCh(LPIT8 it8) { - if (it8 -> Stream[it8 ->IncludeSP]) { - - it8 ->ch = fgetc(it8 ->Stream[it8 ->IncludeSP]); - - if (feof(it8 -> Stream[it8 ->IncludeSP])) { + if (it8 -> FileStack[it8 ->IncludeSP]->Stream) { + + it8 ->ch = fgetc(it8 ->FileStack[it8 ->IncludeSP]->Stream); + + if (feof(it8 -> FileStack[it8 ->IncludeSP]->Stream)) { if (it8 ->IncludeSP > 0) { - fclose(it8 ->Stream[it8->IncludeSP--]); + fclose(it8 ->FileStack[it8->IncludeSP--]->Stream); it8 -> ch = ' '; // Whitespace to be ignored } else @@ -476,7 +599,6 @@ } else { - it8->ch = *it8->Source; if (it8->ch) it8->Source++; } @@ -799,18 +921,39 @@ if (it8 -> sy == SINCLUDE) { - FILE* IncludeFile; + LPFILECTX FileNest; + + if(it8 -> IncludeSP >= (MAXINCLUDE-1)) + { + SynError(it8, "Too many recursion levels"); + return; + } InSymbol(it8); if (!Check(it8, SSTRING, "Filename expected")) return; - IncludeFile = fopen(it8 -> str, "rt"); - if (IncludeFile == NULL) { - - SynError(it8, "File %s not found", it8 ->str); + + FileNest = it8 -> FileStack[it8 -> IncludeSP + 1]; + if(FileNest == NULL) + { + FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (LPFILECTX)AllocChunk(it8, sizeof(FILECTX)); + //if(FileNest == NULL) + // TODO: how to manage out-of-memory conditions? + } + + if(_cmsMakePath(it8->str, it8->FileStack[it8->IncludeSP]->FileName, FileNest->FileName) == FALSE) + { + SynError(it8, "File path too long"); + return; + } + + FileNest->Stream = fopen(FileNest->FileName, "rt"); + if (FileNest->Stream == NULL) { + + SynError(it8, "File %s not found", FileNest->FileName); return; } - - it8 -> Stream[++it8 -> IncludeSP] = IncludeFile; + it8->IncludeSP++; + it8 ->ch = ' '; InSymbol(it8); } @@ -819,7 +962,7 @@ // Checks end of line separator static -BOOL CheckEOLN(LPIT8 it8) +LCMSBOOL CheckEOLN(LPIT8 it8) { if (!Check(it8, SEOLN, "Expected separator")) return FALSE; while (it8 -> sy == SEOLN) @@ -850,21 +993,26 @@ // Returns a string holding current value static -BOOL GetVal(LPIT8 it8, char* Buffer, const char* ErrorTitle) +LCMSBOOL GetVal(LPIT8 it8, char* Buffer, size_t max, const char* ErrorTitle) { switch (it8->sy) { - case SIDENT: strncpy(Buffer, it8->id, MAXID-1); break; - case SINUM: sprintf(Buffer, "%d", it8 -> inum); break; - case SDNUM: sprintf(Buffer, it8->DoubleFormatter, it8 -> dnum); break; - case SSTRING: strncpy(Buffer, it8->str, MAXSTR-1); break; + case SIDENT: strncpy(Buffer, it8->id, max); + Buffer[max-1]=0; + break; + case SINUM: snprintf(Buffer, max, "%d", it8 -> inum); break; + case SDNUM: snprintf(Buffer, max, it8->DoubleFormatter, it8 -> dnum); break; + case SSTRING: strncpy(Buffer, it8->str, max); + Buffer[max-1] = 0; + break; default: - return SynError(it8, ErrorTitle); + return SynError(it8, "%s", ErrorTitle); } - return TRUE; + Buffer[max] = 0; + return TRUE; } // ---------------------------------------------------------- Table @@ -872,7 +1020,13 @@ static LPTABLE GetTable(LPIT8 it8) { - return it8 ->Tab + it8 ->nTable; + if ((it8 -> nTable >= it8 ->TablesCount) || (it8 -> nTable < 0)) { + + SynError(it8, "Table %d out of sequence", it8 -> nTable); + return it8 -> Tab; + } + + return it8 ->Tab + it8 ->nTable; } // ---------------------------------------------------------- Memory management @@ -896,15 +1050,15 @@ for (p = it8->MemorySink; p != NULL; p = n) { n = p->Next; - if (p->Ptr) free(p->Ptr); - free(p); + if (p->Ptr) _cmsFree(p->Ptr); + _cmsFree(p); } } if (it8->MemoryBlock) - free(it8->MemoryBlock); - - free(it8); + _cmsFree(it8->MemoryBlock); + + _cmsFree(it8); } @@ -913,16 +1067,16 @@ void* AllocBigBlock(LPIT8 it8, size_t size) { LPOWNEDMEM ptr1; - void* ptr = malloc(size); + void* ptr = _cmsMalloc(size); if (ptr) { ZeroMemory(ptr, size); - ptr1 = (LPOWNEDMEM) malloc(sizeof(OWNEDMEM)); + ptr1 = (LPOWNEDMEM) _cmsMalloc(sizeof(OWNEDMEM)); if (ptr1 == NULL) { - free(ptr); + _cmsFree(ptr); return NULL; } @@ -986,8 +1140,9 @@ // Searches through linked list static -BOOL IsAvailableOnList(LPKEYVALUE p, const char* Key, LPKEYVALUE* LastPtr) +LCMSBOOL IsAvailableOnList(LPKEYVALUE p, const char* Key, const char* Subkey, LPKEYVALUE* LastPtr) { + if (LastPtr) *LastPtr = p; for (; p != NULL; p = p->Next) { @@ -996,8 +1151,22 @@ if (*Key != '#') { // Comments are ignored if (stricmp(Key, p->Keyword) == 0) - return TRUE; + break; + } } + + if (p == NULL) + return FALSE; + + if (Subkey == 0) + return TRUE; + + for (; p != NULL; p = p->NextSubkey) { + + if (LastPtr) *LastPtr = p; + + if (stricmp(Subkey, p->Subkey) == 0) + return TRUE; } return FALSE; @@ -1007,35 +1176,55 @@ // Add a property into a linked list static -BOOL AddToList(LPIT8 it8, LPKEYVALUE* Head, const char *Key, const char* xValue, WRITEMODE WriteAs) +LPKEYVALUE AddToList(LPIT8 it8, LPKEYVALUE* Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs) { LPKEYVALUE p; - LPKEYVALUE last; - // Check if property is already in list (this is an error) - if (IsAvailableOnList(*Head, Key, &last)) { - - // This may work for editing properties - - last->Value = AllocString(it8, xValue); - last->WriteAs = WriteAs; - return TRUE; - - // return SynError(it8, "duplicate key <%s>", Key); + if (IsAvailableOnList(*Head, Key, Subkey, &p)) { + + // This may work for editing properties + + // return SynError(it8, "duplicate key <%s>", Key); } - - // Allocate the container + else { + LPKEYVALUE last = p; + + // Allocate the container p = (LPKEYVALUE) AllocChunk(it8, sizeof(KEYVALUE)); if (p == NULL) { - return SynError(it8, "AddToList: out of memory"); + SynError(it8, "AddToList: out of memory"); + return NULL; } // Store name and value p->Keyword = AllocString(it8, Key); - + p->Subkey = (Subkey == NULL) ? NULL : AllocString(it8, Subkey); + + // Keep the container in our list + if (*Head == NULL) + *Head = p; + else + { + if(Subkey != 0 && last != 0) { + last->NextSubkey = p; + + // If Subkey is not null, then last is the last property with the same key, + // but not necessarily is the last property in the list, so we need to move + // to the actual list end + while(last->Next != 0) + last = last->Next; + } + last->Next = p; + } + + p->Next = NULL; + p->NextSubkey = NULL; + } + + p->WriteAs = WriteAs; if (xValue != NULL) { p->Value = AllocString(it8, xValue); @@ -1044,29 +1233,20 @@ p->Value = NULL; } - p->Next = NULL; - p->WriteAs = WriteAs; - - // Keep the container in our list - if (*Head == NULL) - *Head = p; - else - last->Next = p; - - return TRUE; + return p; } static -BOOL AddAvailableProperty(LPIT8 it8, const char* Key) +LPKEYVALUE AddAvailableProperty(LPIT8 it8, const char* Key, WRITEMODE as) { - return AddToList(it8, &it8->ValidKeywords, Key, NULL, WRITE_UNCOOKED); + return AddToList(it8, &it8->ValidKeywords, Key, NULL, NULL, as); } static -BOOL AddAvailableSampleID(LPIT8 it8, const char* Key) +LPKEYVALUE AddAvailableSampleID(LPIT8 it8, const char* Key) { - return AddToList(it8, &it8->ValidSampleID, Key, NULL, WRITE_UNCOOKED); + return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED); } @@ -1122,8 +1302,6 @@ AllocTable(it8); it8->MemoryBlock = NULL; - it8->Stream[0] = NULL; - it8->IncludeSP = 0; it8->MemorySink = NULL; it8 ->nTable = 0; @@ -1141,6 +1319,8 @@ it8 -> inum = 0; it8 -> dnum = 0.0; + it8->FileStack[0] = (LPFILECTX)AllocChunk(it8, sizeof(FILECTX)); + it8->IncludeSP = 0; it8 -> lineno = 1; strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT); @@ -1149,7 +1329,7 @@ // Initialize predefined properties & data for (i=0; i < NUMPREDEFINEDPROPS; i++) - AddAvailableProperty(it8, PredefinedProperties[i]); + AddAvailableProperty(it8, PredefinedProperties[i].id, PredefinedProperties[i].as); for (i=0; i < NUMPREDEFINEDSAMPLEID; i++) AddAvailableSampleID(it8, PredefinedSampleID[i]); @@ -1167,65 +1347,72 @@ } -BOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type) +LCMSBOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type) { LPIT8 it8 = (LPIT8) hIT8; strncpy(it8 ->SheetType, Type, MAXSTR-1); + it8 ->SheetType[MAXSTR-1] = 0; return TRUE; } -BOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* Val) +LCMSBOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* Val) { LPIT8 it8 = (LPIT8) hIT8; if (!Val) return FALSE; if (!*Val) return FALSE; - return AddToList(it8, &GetTable(it8)->HeaderList, "# ", Val, WRITE_UNCOOKED); + return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL; } // Sets a property -BOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* Key, const char *Val) +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* Key, const char *Val) { LPIT8 it8 = (LPIT8) hIT8; if (!Val) return FALSE; if (!*Val) return FALSE; - return AddToList(it8, &GetTable(it8)->HeaderList, Key, Val, WRITE_STRINGIFY); + return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL; } -BOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val) +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val) { LPIT8 it8 = (LPIT8) hIT8; char Buffer[1024]; sprintf(Buffer, it8->DoubleFormatter, Val); - return AddToList(it8, &GetTable(it8)->HeaderList, cProp, Buffer, WRITE_UNCOOKED); + return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL; } -BOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val) +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val) { LPIT8 it8 = (LPIT8) hIT8; char Buffer[1024]; sprintf(Buffer, "%d", Val); - return AddToList(it8, &GetTable(it8)->HeaderList, cProp, Buffer, WRITE_HEXADECIMAL); + return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL; } -BOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer) +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer) { LPIT8 it8 = (LPIT8) hIT8; - return AddToList(it8, &GetTable(it8)->HeaderList, Key, Buffer, WRITE_UNCOOKED); + return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Buffer, WRITE_UNCOOKED) != NULL; } +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer) +{ + LPIT8 it8 = (LPIT8) hIT8; + + return AddToList(it8, &GetTable(it8)->HeaderList, Key, SubKey, Buffer, WRITE_PAIR) != NULL; +} // Gets a property const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* Key) @@ -1233,7 +1420,7 @@ LPIT8 it8 = (LPIT8) hIT8; LPKEYVALUE p; - if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, &p)) + if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, NULL, &p)) { return p -> Value; } @@ -1249,6 +1436,18 @@ else return 0.0; } +const char* LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* Key, const char *SubKey) +{ + LPIT8 it8 = (LPIT8) hIT8; + LPKEYVALUE p; + + if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, SubKey, &p)) + { + return p -> Value; + } + return NULL; +} + // ----------------------------------------------------------------- Datasets @@ -1287,10 +1486,17 @@ } static -BOOL SetDataFormat(LPIT8 it8, int n, const char *label) +LCMSBOOL SetDataFormat(LPIT8 it8, int n, const char *label) { LPTABLE t = GetTable(it8); +#ifdef STRICT_CGATS + if (!IsAvailableOnList(it8-> ValidSampleID, label, NULL, NULL)) { + SynError(it8, "Invalid data format '%s'.", label); + return FALSE; + } +#endif + if (!t->DataFormat) AllocateDataFormat(it8); @@ -1308,7 +1514,7 @@ } -BOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE h, int n, const char *Sample) +LCMSBOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE h, int n, const char *Sample) { LPIT8 it8 = (LPIT8) h; return SetDataFormat(it8, n, Sample); @@ -1348,7 +1554,7 @@ } static -BOOL SetData(LPIT8 it8, int nSet, int nField, const char *Val) +LCMSBOOL SetData(LPIT8 it8, int nSet, int nField, const char *Val) { LPTABLE t = GetTable(it8); @@ -1383,42 +1589,43 @@ void WriteStr(LPSAVESTREAM f, const char *str) { - size_t len; - - if (str == NULL) - str = " "; - - // Lenghth to write - len = strlen(str); + size_t len; + + if (str == NULL) + str = " "; + + // Lenghth to write + len = strlen(str); f ->Used += len; - if (f ->stream) { // Should I write it to a file? - - fwrite(str, 1, len, f->stream); + if (f ->stream) { // Should I write it to a file? + + fwrite(str, 1, len, f->stream); + + } + else { // Or to a memory block? + + + if (f ->Base) { // Am I just counting the bytes? + + if (f ->Used > f ->Max) { + + cmsSignalError(LCMS_ERRC_ABORTED, "Write to memory overflows in CGATS parser"); + return; + } + + CopyMemory(f ->Ptr, str, len); + f->Ptr += len; } - else { // Or to a memory block? - - - if (f ->Base) { // Am I just counting the bytes? - - if (f ->Used > f ->Max) { - - cmsSignalError(LCMS_ERRC_ABORTED, "Write to memory overflows in CGATS parser"); - return; - } - - CopyMemory(f ->Ptr, str, len); - f->Ptr += len; - - } - - } + + } } -// +// Write formatted + static void Writef(LPSAVESTREAM f, const char* frm, ...) { @@ -1426,7 +1633,8 @@ va_list args; va_start(args, frm); - vsprintf(Buffer, frm, args); + vsnprintf(Buffer, 4095, frm, args); + Buffer[4095] = 0; WriteStr(f, Buffer); va_end(args); @@ -1450,7 +1658,7 @@ for (Pt = p ->Value; *Pt; Pt++) { - Writef(fp, "%c", *Pt); + Writef(fp, "%c", *Pt); if (*Pt == '\n') { WriteStr(fp, "# "); @@ -1462,7 +1670,7 @@ } - if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL)) { + if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL, NULL)) { #ifdef STRICT_CGATS WriteStr(fp, "KEYWORD\t\""); @@ -1470,7 +1678,7 @@ WriteStr(fp, "\"\n"); #endif - AddAvailableProperty(it8, p->Keyword); + AddAvailableProperty(it8, p->Keyword, WRITE_UNCOOKED); } @@ -1495,6 +1703,10 @@ Writef(fp, "\t0x%B", atoi(p ->Value)); break; + case WRITE_PAIR: + Writef(fp, "\t\"%s,%s\"", p->Subkey, p->Value); + break; + default: SynError(it8, "Unknown write mode %d", p ->WriteAs); return; } @@ -1573,13 +1785,13 @@ // Saves whole file -BOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE hIT8, const char* cFileName) +LCMSBOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE hIT8, const char* cFileName) { SAVESTREAM sd; int i; LPIT8 it8 = (LPIT8) hIT8; - ZeroMemory(&sd, sizeof(SAVESTREAM)); + ZeroMemory(&sd, sizeof(SAVESTREAM)); sd.stream = fopen(cFileName, "wt"); if (!sd.stream) return FALSE; @@ -1594,31 +1806,31 @@ WriteData(&sd, it8); } - fclose(sd.stream); + fclose(sd.stream); return TRUE; } // Saves to memory -BOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded) +LCMSBOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded) { SAVESTREAM sd; int i; LPIT8 it8 = (LPIT8) hIT8; - ZeroMemory(&sd, sizeof(SAVESTREAM)); + ZeroMemory(&sd, sizeof(SAVESTREAM)); sd.stream = NULL; - sd.Base = (LPBYTE) MemPtr; - sd.Ptr = sd.Base; - - sd.Used = 0; - - if (sd.Base) - sd.Max = *BytesNeeded; // Write to memory? - else - sd.Max = 0; // Just counting the needed bytes + sd.Base = (LPBYTE) MemPtr; + sd.Ptr = sd.Base; + + sd.Used = 0; + + if (sd.Base) + sd.Max = *BytesNeeded; // Write to memory? + else + sd.Max = 0; // Just counting the needed bytes WriteStr(&sd, it8->SheetType); WriteStr(&sd, "\n"); @@ -1630,12 +1842,12 @@ WriteData(&sd, it8); } - sd.Used++; // The \0 at the very end - - if (sd.Base) - sd.Ptr = 0; - - *BytesNeeded = sd.Used; + sd.Used++; // The \0 at the very end + + if (sd.Base) + sd.Ptr = 0; + + *BytesNeeded = sd.Used; return TRUE; } @@ -1644,7 +1856,7 @@ // -------------------------------------------------------------- Higer level parsing static -BOOL DataFormatSection(LPIT8 it8) +LCMSBOOL DataFormatSection(LPIT8 it8) { int iField = 0; LPTABLE t = GetTable(it8); @@ -1685,16 +1897,19 @@ static -BOOL DataSection (LPIT8 it8) +LCMSBOOL DataSection (LPIT8 it8) { int iField = 0; int iSet = 0; - char Buffer[256]; + char Buffer[MAXSTR]; LPTABLE t = GetTable(it8); InSymbol(it8); // Eats "BEGIN_DATA" CheckEOLN(it8); + if (!t->Data) + AllocateDataSet(it8); + while (it8->sy != SEND_DATA && it8->sy != SEOF) { if (iField >= t -> nSamples) { @@ -1705,7 +1920,7 @@ if (it8->sy != SEND_DATA && it8->sy != SEOF) { - if (!GetVal(it8, Buffer, "Sample data expected")) + if (!GetVal(it8, Buffer, 255, "Sample data expected")) return FALSE; if (!SetData(it8, iSet, iField, Buffer)) @@ -1734,10 +1949,11 @@ static -BOOL HeaderSection(LPIT8 it8) +LCMSBOOL HeaderSection(LPIT8 it8) { char VarName[MAXID]; char Buffer[MAXSTR]; + LPKEYVALUE Key; while (it8->sy != SEOF && it8->sy != SSYNERROR && @@ -1749,30 +1965,79 @@ case SKEYWORD: InSymbol(it8); - if (!GetVal(it8, Buffer, "Keyword expected")) return FALSE; - if (!AddAvailableProperty(it8, Buffer)) return FALSE; + if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE; + if (!AddAvailableProperty(it8, Buffer, WRITE_UNCOOKED)) return FALSE; + InSymbol(it8); + break; + + + case SDATA_FORMAT_ID: + InSymbol(it8); + if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE; + if (!AddAvailableSampleID(it8, Buffer)) return FALSE; InSymbol(it8); break; case SIDENT: strncpy(VarName, it8->id, MAXID-1); - - if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL)) { + VarName[MAXID-1] = 0; + + if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) { #ifdef STRICT_CGATS return SynError(it8, "Undefined keyword '%s'", VarName); #else - if (!AddAvailableProperty(it8, VarName)) return FALSE; + Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED); + if (Key == NULL) return FALSE; #endif } InSymbol(it8); - if (!GetVal(it8, Buffer, "Property data expected")) return FALSE; - - - AddToList(it8, &GetTable(it8)->HeaderList, VarName, Buffer, - (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED); + if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE; + + if(Key->WriteAs != WRITE_PAIR) { + AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer, + (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED); + } + else { + const char *Subkey; + char *Nextkey; + if (it8->sy != SSTRING) + return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName); + + // chop the string as a list of "subkey, value" pairs, using ';' as a separator + for(Subkey = Buffer; Subkey != NULL; Subkey = Nextkey) + { + char *Value, *temp; + + // identify token pair boundary + Nextkey = (char*) strchr(Subkey, ';'); + if(Nextkey) + *Nextkey++ = '\0'; + + // for each pair, split the subkey and the value + Value = (char*) strrchr(Subkey, ','); + if(Value == NULL) + return SynError(it8, "Invalid value for property '%s'.", VarName); + + // gobble the spaces before the coma, and the coma itself + temp = Value++; + do *temp-- = '\0'; while(temp >= Subkey && *temp == ' '); + + // gobble any space at the right + temp = Value + strlen(Value) - 1; + while(*temp == ' ') *temp-- = '\0'; + + // trim the strings from the left + Subkey += strspn(Subkey, " "); + Value += strspn(Value, " "); + + if(Subkey[0] == 0 || Value[0] == 0) + return SynError(it8, "Invalid value for property '%s'.", VarName); + AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR); + } + } InSymbol(it8); break; @@ -1793,22 +2058,23 @@ static -BOOL ParseIT8(LPIT8 it8) +LCMSBOOL ParseIT8(LPIT8 it8, LCMSBOOL nosheet) { - char* SheetTypePtr; + char* SheetTypePtr = it8 ->SheetType; + + if (nosheet == 0) { // First line is a very special case. while (isseparator(it8->ch)) NextCh(it8); - SheetTypePtr = it8 ->SheetType; - while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != -1) { *SheetTypePtr++= (char) it8 ->ch; NextCh(it8); } + } *SheetTypePtr = 0; InSymbol(it8); @@ -1869,6 +2135,12 @@ for (idField = 0; idField < t -> nSamples; idField++) { + if (t ->DataFormat == NULL) { + SynError(it8, "Undefined DATA_FORMAT"); + return; + + } + Fld = t->DataFormat[idField]; if (!Fld) continue; @@ -1884,6 +2156,7 @@ char Buffer[256]; strncpy(Buffer, Data, 255); + Buffer[255] = 0; if (strlen(Buffer) <= strlen(Data)) strcpy(Data, Buffer); @@ -1916,7 +2189,7 @@ LPTABLE Table = it8 ->Tab + k; LPKEYVALUE p; - if (IsAvailableOnList(Table->HeaderList, Label, &p)) { + if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) { // Available, keep type and table char Buffer[256]; @@ -1924,7 +2197,7 @@ char *Type = p ->Value; int nTable = k; - sprintf(Buffer, "%s %d %s", Label, nTable, Type ); + snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type ); SetData(it8, i, idField, Buffer); } @@ -1948,8 +2221,9 @@ // that should be something like some printable characters plus a \n static -BOOL IsMyBlock(LPBYTE Buffer, size_t n) +int IsMyBlock(LPBYTE Buffer, size_t n) { + int cols = 1, space = 0, quot = 0; size_t i; if (n < 10) return FALSE; // Too small @@ -1959,9 +2233,26 @@ for (i = 1; i < n; i++) { - if (Buffer[i] == '\n' || Buffer[i] == '\r' || Buffer[i] == '\t') return TRUE; - if (Buffer[i] < 32) return FALSE; - + switch(Buffer[i]) + { + case '\n': + case '\r': + return quot == 1 || cols > 2 ? 0 : cols; + case '\t': + case ' ': + if(!quot && !space) + space = 1; + break; + case '\"': + quot = !quot; + break; + default: + if (Buffer[i] < 32) return 0; + if (Buffer[i] > 127) return 0; + cols += space; + space = 0; + break; + } } return FALSE; @@ -1970,7 +2261,7 @@ static -BOOL IsMyFile(const char* FileName) +int IsMyFile(const char* FileName) { FILE *fp; size_t Size; @@ -1998,21 +2289,22 @@ LCMSHANDLE hIT8; LPIT8 it8; - if (!IsMyBlock((LPBYTE) Ptr, len)) return NULL; + int type = IsMyBlock((LPBYTE) Ptr, len); + if (type == 0) return NULL; hIT8 = cmsIT8Alloc(); if (!hIT8) return NULL; it8 = (LPIT8) hIT8; - it8 ->MemoryBlock = (char*) malloc(len + 1); + it8 ->MemoryBlock = (char*) _cmsMalloc(len + 1); strncpy(it8 ->MemoryBlock, (const char*) Ptr, len); it8 ->MemoryBlock[len] = 0; - strncpy(it8->FileName, "", MAX_PATH-1); + strncpy(it8->FileStack[0]->FileName, "", MAX_PATH-1); it8-> Source = it8 -> MemoryBlock; - if (!ParseIT8(it8)) { + if (!ParseIT8(it8, type-1)) { cmsIT8Free(hIT8); return FALSE; @@ -2021,7 +2313,7 @@ CookPointers(it8); it8 ->nTable = 0; - free(it8->MemoryBlock); + _cmsFree(it8->MemoryBlock); it8 -> MemoryBlock = NULL; return hIT8; @@ -2036,26 +2328,28 @@ LCMSHANDLE hIT8; LPIT8 it8; - if (!IsMyFile(cFileName)) return NULL; + int type = IsMyFile(cFileName); + if (type == 0) return NULL; hIT8 = cmsIT8Alloc(); it8 = (LPIT8) hIT8; if (!hIT8) return NULL; - it8 ->Stream[0] = fopen(cFileName, "rt"); - - if (!it8 ->Stream[0]) { + it8 ->FileStack[0]->Stream = fopen(cFileName, "rt"); + + if (!it8 ->FileStack[0]->Stream) { cmsIT8Free(hIT8); return NULL; } - strncpy(it8->FileName, cFileName, MAX_PATH-1); - - if (!ParseIT8(it8)) { - - fclose(it8 ->Stream[0]); + strncpy(it8->FileStack[0]->FileName, cFileName, MAX_PATH-1); + it8->FileStack[0]->FileName[MAX_PATH-1] = 0; + + if (!ParseIT8(it8, type-1)) { + + fclose(it8 ->FileStack[0]->Stream); cmsIT8Free(hIT8); return NULL; } @@ -2063,7 +2357,7 @@ CookPointers(it8); it8 ->nTable = 0; - fclose(it8 ->Stream[0]); + fclose(it8 ->FileStack[0]->Stream); return hIT8; } @@ -2078,12 +2372,12 @@ } -int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, char ***PropertyNames) +int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, const char ***PropertyNames) { LPIT8 it8 = (LPIT8) hIT8; LPKEYVALUE p; int n; - char **Props; + const char **Props; LPTABLE t = GetTable(it8); // Pass#1 - count properties @@ -2094,7 +2388,7 @@ } - Props = (char **) AllocChunk(it8, sizeof(char *) * n); + Props = (const char **) AllocChunk(it8, sizeof(char *) * n); // Pass#2 - Fill pointers n = 0; @@ -2106,6 +2400,41 @@ return n; } +int LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char ***SubpropertyNames) +{ + LPIT8 it8 = (LPIT8) hIT8; + LPKEYVALUE p, tmp; + int n; + const char **Props; + LPTABLE t = GetTable(it8); + + if(!IsAvailableOnList(t->HeaderList, cProp, NULL, &p)) { + *SubpropertyNames = 0; + return 0; + } + + // Pass#1 - count properties + + n = 0; + for (tmp = p; tmp != NULL; tmp = tmp->NextSubkey) { + if(tmp->Subkey != NULL) + n++; + } + + + Props = (const char **) AllocChunk(it8, sizeof(char *) * n); + + // Pass#2 - Fill pointers + n = 0; + for (tmp = p; tmp != NULL; tmp = tmp->NextSubkey) { + if(tmp->Subkey != NULL) + Props[n++] = p ->Subkey; + } + + *SubpropertyNames = Props; + return n; +} + static int LocatePatch(LPIT8 it8, const char* cPatch) { @@ -2201,7 +2530,7 @@ } -BOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val) +LCMSBOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val) { LPIT8 it8 = (LPIT8) hIT8; @@ -2209,7 +2538,7 @@ } -BOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val) +LCMSBOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val) { LPIT8 it8 = (LPIT8) hIT8; char Buff[256]; @@ -2260,7 +2589,7 @@ -BOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE hIT8, const char* cPatch, +LCMSBOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE hIT8, const char* cPatch, const char* cSample, const char *Val) { @@ -2305,18 +2634,19 @@ } -BOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, +LCMSBOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, const char* cSample, double Val) { LPIT8 it8 = (LPIT8) hIT8; char Buff[256]; - sprintf(Buff, it8->DoubleFormatter, Val); + snprintf(Buff, 255, it8->DoubleFormatter, Val); return cmsIT8SetData(hIT8, cPatch, cSample, Buff); } +// Buffer should get MAXSTR at least const char* LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer) { @@ -2327,10 +2657,16 @@ if (!Data) return NULL; if (!buffer) return Data; - strcpy(buffer, Data); + strncpy(buffer, Data, MAXSTR-1); + buffer[MAXSTR-1] = 0; return buffer; } +int LCMSEXPORT cmsIT8GetPatchByName(LCMSHANDLE hIT8, const char *cPatch) +{ + return LocatePatch((LPIT8)hIT8, cPatch); +} + int LCMSEXPORT cmsIT8TableCount(LCMSHANDLE hIT8) { LPIT8 it8 = (LPIT8) hIT8; @@ -2356,7 +2692,7 @@ cLabelFld = cmsIT8GetData(hIT8, cSet, cField); if (!cLabelFld) return -1; - if (sscanf(cLabelFld, "%s %d %s", Label, &nTable, Type) != 3) + if (sscanf(cLabelFld, "%255s %d %255s", Label, &nTable, Type) != 3) return -1; if (ExpectedType != NULL && *ExpectedType == 0) @@ -2371,6 +2707,19 @@ } +LCMSBOOL LCMSEXPORT cmsIT8SetIndexColumn(LCMSHANDLE hIT8, const char* cSample) +{ + LPIT8 it8 = (LPIT8) hIT8; + + int pos = LocateSample(it8, cSample); + if(pos == -1) + return FALSE; + + it8->Tab[it8->nTable].SampleID = pos; + return TRUE; +} + + void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE hIT8, const char* Formatter) { LPIT8 it8 = (LPIT8) hIT8; @@ -2380,3 +2729,4 @@ else strcpy(it8->DoubleFormatter, Formatter); } + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -256,7 +256,7 @@ // Return TRUE if both m and of are empy -- "m" being identity and "of" being 0 static -BOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of) +LCMSBOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of) { WVEC3 wv0; @@ -661,3 +661,6 @@ return rc; } + + + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -57,6 +57,7 @@ // errors. void cdecl cmsSignalError(int ErrorCode, const char *ErrorText, ...); + int LCMSEXPORT cmsErrorAction(int lAbort); void LCMSEXPORT cmsSetErrorHandler(cmsErrorHandlerFunction Fn); @@ -96,7 +97,7 @@ char Buffer[1024]; - vsprintf(Buffer, ErrorText, args); + vsnprintf(Buffer, 1023, ErrorText, args); va_end(args); if (UserErrorHandler(ErrorCode, Buffer)) { @@ -118,8 +119,8 @@ char Buffer1[1024]; char Buffer2[256]; - sprintf(Buffer1, "Error #%x; ", ErrorCode); - vsprintf(Buffer2, ErrorText, args); + snprintf(Buffer1, 767, "Error #%x; ", ErrorCode); + vsnprintf(Buffer2, 255, ErrorText, args); strcat(Buffer1, Buffer2); MessageBox(NULL, Buffer1, "Little cms", MB_OK|MB_ICONSTOP|MB_TASKMODAL); diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -63,9 +63,9 @@ LPGAMMATABLE LCMSEXPORT cmsBuildParametricGamma(int nEntries, int Type, double Params[]); LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma); LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints); -BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda); +LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda); -BOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints); +LCMSBOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints); // Sampled curves @@ -74,7 +74,7 @@ void cdecl cmsFreeSampledCurve(LPSAMPLEDCURVE p); void cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max); void cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max); -BOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda); +LCMSBOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda); void cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints); LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints); @@ -84,7 +84,6 @@ // ---------------------------------------------------------------------------------------- -// #define DEBUG 1 #define MAX_KNOTS 4096 typedef float vec[MAX_KNOTS+1]; @@ -144,14 +143,14 @@ LPGAMMATABLE p; size_t size; - if (nEntries > 65530) { - cmsSignalError(LCMS_ERRC_WARNING, "Couldn't create gammatable of more than 65530 entries; 65530 assumed"); - nEntries = 65530; + if (nEntries > 65530 || nEntries <= 0) { + cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't create gammatable of more than 65530 entries"); + return NULL; } size = sizeof(GAMMATABLE) + (sizeof(WORD) * (nEntries-1)); - p = (LPGAMMATABLE) malloc(size); + p = (LPGAMMATABLE) _cmsMalloc(size); if (!p) return NULL; ZeroMemory(p, size); @@ -164,7 +163,7 @@ void LCMSEXPORT cmsFreeGamma(LPGAMMATABLE Gamma) { - if (Gamma) free(Gamma); + if (Gamma) _cmsFree(Gamma); } @@ -278,6 +277,15 @@ LPWORD InPtr; LPGAMMATABLE p; + // Try to reverse it analytically whatever possible + if (InGamma -> Seed.Type > 0 && InGamma -> Seed.Type <= 5 && + _cmsCrc32OfGammaTable(InGamma) == InGamma -> Seed.Crc32) { + + return cmsBuildParametricGamma(nResultSamples, -(InGamma -> Seed.Type), InGamma ->Seed.Params); + } + + + // Nope, reverse the table p = cmsAllocGamma(nResultSamples); if (!p) return NULL; @@ -528,7 +536,7 @@ // Smooths a curve sampled at regular intervals -BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda) +LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda) { vec w, y, z; @@ -640,13 +648,13 @@ { LPSAMPLEDCURVE pOut; - pOut = (LPSAMPLEDCURVE) malloc(sizeof(SAMPLEDCURVE)); + pOut = (LPSAMPLEDCURVE) _cmsMalloc(sizeof(SAMPLEDCURVE)); if (pOut == NULL) return NULL; - if((pOut->Values = (double *) malloc(nItems * sizeof(double))) == NULL) + if((pOut->Values = (double *) _cmsMalloc(nItems * sizeof(double))) == NULL) { - free(pOut); + _cmsFree(pOut); return NULL; } @@ -659,8 +667,8 @@ void cmsFreeSampledCurve(LPSAMPLEDCURVE p) { - free((LPVOID) p -> Values); - free((LPVOID) p); + _cmsFree((LPVOID) p -> Values); + _cmsFree((LPVOID) p); } @@ -731,7 +739,7 @@ // Smooths a curve sampled at regular intervals -BOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda) +LCMSBOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda) { vec w, y, z; int i, nItems; @@ -915,14 +923,11 @@ // Smooth endpoints (used in Black/White compensation) -BOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries) +LCMSBOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries) { vec w, y, z; int i, Zeros, Poles; -#ifdef DEBUG - ASAVE(Table, nEntries, "nonsmt.txt"); -#endif if (cmsIsLinear(Table, nEntries)) return FALSE; // Nothing to do diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -66,7 +66,7 @@ */ -BOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black, +LCMSBOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black, int *nOutputs) { // Only most common spaces @@ -376,7 +376,6 @@ double bs = Lab2 ->b; double Cs = sqrt( Sqr(as) + Sqr(bs) ); - double G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) )); double a_p = (1 + G ) * a1; @@ -390,15 +389,21 @@ double C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps)); double h_ps = atan2deg(a_ps, b_ps); - - double meanC_p =(C_p + C_ps) / 2; - double meanh_p = fabs(h_ps-h_p) <= 180 ? (h_ps + h_p)/2 : (h_ps+h_p-360)/2; + double hps_plus_hp = h_ps + h_p; + double hps_minus_hp = h_ps - h_p; + + double meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 : + (hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 : + (hps_plus_hp - 360)/2; - double delta_h = fabs(h_p - h_ps) <= 180 ? fabs(h_p - h_ps) : 360 - fabs(h_p - h_ps); - double delta_L = fabs(L1 - Ls); - double delta_C = fabs(C_p - C_ps); + double delta_h = (hps_minus_hp) <= -180.000001 ? (hps_minus_hp + 360) : + (hps_minus_hp) > 180 ? (hps_minus_hp - 360) : + (hps_minus_hp); + double delta_L = (Ls - L1); + double delta_C = (C_ps - C_p ); + double delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANES(delta_h) / 2); @@ -1065,7 +1070,7 @@ // Check for monotonicity. static -BOOL IsMonotonic(LPGAMMATABLE t) +LCMSBOOL IsMonotonic(LPGAMMATABLE t) { int n = t -> nEntries; int i, last; @@ -1088,7 +1093,7 @@ // Check for endpoints static -BOOL HasProperEndpoints(LPGAMMATABLE t) +LCMSBOOL HasProperEndpoints(LPGAMMATABLE t) { if (t ->GammaTable[0] != 0) return FALSE; if (t ->GammaTable[t ->nEntries-1] != 0xFFFF) return FALSE; @@ -1109,7 +1114,7 @@ unsigned int t, i, v; int j; WORD In[MAXCHANNELS], Out[MAXCHANNELS]; - BOOL lIsSuitable; + LCMSBOOL lIsSuitable; _LPcmsTRANSFORM InputXForm = (_LPcmsTRANSFORM) h[0]; _LPcmsTRANSFORM OutputXForm = (_LPcmsTRANSFORM) h[nTransforms-1]; @@ -1126,10 +1131,10 @@ } - // Do nothing on all but RGB to RGB transforms + // Do nothing on all but Gray/RGB to Gray/RGB transforms - if ((InputXForm ->EntryColorSpace != icSigRgbData) || - (OutputXForm->ExitColorSpace != icSigRgbData)) return; + if (((InputXForm ->EntryColorSpace != icSigRgbData) && (InputXForm ->EntryColorSpace != icSigGrayData)) || + ((OutputXForm->ExitColorSpace != icSigRgbData) && (OutputXForm->ExitColorSpace != icSigGrayData))) return; for (t = 0; t < Grid -> InputChan; t++) @@ -1169,10 +1174,13 @@ if (!HasProperEndpoints(Trans[t])) lIsSuitable = FALSE; + /* // Exclude if transfer function is not smooth enough // to be modelled as a gamma function, or the gamma is reversed + if (cmsEstimateGamma(Trans[t]) < 1.0) lIsSuitable = FALSE; + */ } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -282,7 +282,7 @@ // Fills optimization parameters void cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan, - BOOL lUseTetrahedral, LPL16PARAMS p) + LCMSBOOL lUseTetrahedral, LPL16PARAMS p) { int clutPoints; @@ -579,7 +579,7 @@ // Identify if value fall downto 0 or FFFF zone if (Value == 0) return 0; - if (Value == 0xFFFF) return 0xFFFF; + // if (Value == 0xFFFF) return 0xFFFF; // else restrict to valid zone @@ -631,7 +631,7 @@ a = (y1 - y0) / (x1 - x0); b = y0 - a * x0; - if (a == 0) return (WORD) x; + if (fabs(a) < 0.01) return (WORD) x; f = ((Value - b) / a); @@ -763,7 +763,7 @@ X0 = p -> opta3 * x0; X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta3); - Y0 = p -> opta2 * y0; + Y0 = p -> opta2 * y0; Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta2); Z0 = p -> opta1 * z0; @@ -942,7 +942,7 @@ X0 = p -> opta3 * x0; X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta3); - Y0 = p -> opta2 * y0; + Y0 = p -> opta2 * y0; Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta2); Z0 = p -> opta1 * z0; @@ -1009,11 +1009,11 @@ Rest = c1 * rx + c2 * ry + c3 * rz; - // There is a lot of math hidden in this expression. The rest is in fixed domain - // and the result in 0..ffff domain. So the complete expression should be - // ROUND_FIXED_TO_INT(ToFixedDomain(Rest)) But that can be optimized as (Rest + 0x7FFF) / 0xFFFF + // There is a lot of math hidden in this expression. The rest is in fixed domain + // and the result in 0..ffff domain. So the complete expression should be + // ROUND_FIXED_TO_INT(ToFixedDomain(Rest)) But that can be optimized as (Rest + 0x7FFF) / 0xFFFF - Output[OutChan] = (WORD) (c0 + ((Rest + 0x7FFF) / 0xFFFF)); + Output[OutChan] = (WORD) (c0 + ((Rest + 0x7FFF) / 0xFFFF)); } @@ -1131,3 +1131,4 @@ } #undef DENS + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -62,7 +62,7 @@ typedef struct { LPBYTE Block; // Points to allocated memory size_t Size; // Size of allocated memory - int Pointer; // Points to current location + size_t Pointer; // Points to current location int FreeBlockOnClose; // As title } FILEMEM; @@ -70,18 +70,19 @@ static LPVOID MemoryOpen(LPBYTE Block, size_t Size, char Mode) { - FILEMEM* fm = (FILEMEM*) malloc(sizeof(FILEMEM)); + FILEMEM* fm = (FILEMEM*) _cmsMalloc(sizeof(FILEMEM)); + if (fm == NULL) return NULL; + ZeroMemory(fm, sizeof(FILEMEM)); if (Mode == 'r') { - fm ->Block = (LPBYTE) malloc(Size); + fm ->Block = (LPBYTE) _cmsMalloc(Size); if (fm ->Block == NULL) { - free(fm); + _cmsFree(fm); return NULL; } - CopyMemory(fm->Block, Block, Size); fm ->FreeBlockOnClose = TRUE; } @@ -103,13 +104,27 @@ FILEMEM* ResData = (FILEMEM*) Icc ->stream; LPBYTE Ptr; size_t len = size * count; + size_t extent = ResData -> Pointer + len; + if (len == 0) { + return 0; + } - if (ResData -> Pointer + len > ResData -> Size){ + if (len / size != count) { + cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with count / size."); + return 0; + } + + if (extent < len || extent < ResData -> Pointer) { + cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with len."); + return 0; + } + + if (ResData -> Pointer + len > ResData -> Size) { len = (ResData -> Size - ResData -> Pointer); - cmsSignalError(LCMS_ERRC_WARNING, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size); - + cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size); + return 0; } Ptr = ResData -> Block; @@ -123,7 +138,7 @@ // SEEK_CUR is assumed static -BOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset) +LCMSBOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset) { FILEMEM* ResData = (FILEMEM*) Icc ->stream; @@ -147,18 +162,19 @@ } -// Writes data to memory, also keeps used space for further reference +// Writes data to memory, also keeps used space for further reference. NO CHECK IS PERFORMED static -BOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr) +LCMSBOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr) { FILEMEM* ResData = (FILEMEM*) Icc ->stream; if (size == 0) return TRUE; if (ResData != NULL) - CopyMemory(ResData ->Block + Icc ->UsedSpace, Ptr, size); + CopyMemory(ResData ->Block + ResData ->Pointer, Ptr, size); + ResData->Pointer += size; Icc->UsedSpace += size; return TRUE; @@ -166,15 +182,37 @@ static -BOOL MemoryClose(struct _lcms_iccprofile_struct* Icc) +LCMSBOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size) +{ + FILEMEM* ResData = (FILEMEM*) Icc->stream; + + void* newBlock = NULL; + + /* Follow same policies as functions in lcms.h */ + if (ResData->Size + size < 0) return NULL; + if (ResData->Size + size > ((size_t)1024*1024*500)) return NULL; + + newBlock = realloc(ResData->Block, ResData->Size + size); + + if (!newBlock) { + return FALSE; + } + ResData->Block = newBlock; + ResData->Size += size; + return TRUE; +} + + +static +LCMSBOOL MemoryClose(struct _lcms_iccprofile_struct* Icc) { FILEMEM* ResData = (FILEMEM*) Icc ->stream; if (ResData ->FreeBlockOnClose) { - if (ResData ->Block) free(ResData ->Block); + if (ResData ->Block) _cmsFree(ResData ->Block); } - free(ResData); + _cmsFree(ResData); return 0; } @@ -192,7 +230,7 @@ { size_t nReaded = fread(buffer, size, count, (FILE*) Icc->stream); if (nReaded != count) { - cmsSignalError(LCMS_ERRC_WARNING, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size); + cmsSignalError(LCMS_ERRC_ABORTED, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size); return 0; } @@ -201,7 +239,7 @@ static -BOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset) +LCMSBOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset) { if (fseek((FILE*) Icc ->stream, (long) offset, SEEK_SET) != 0) { @@ -223,7 +261,7 @@ static -BOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr) +LCMSBOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr) { if (size == 0) return TRUE; @@ -239,7 +277,14 @@ static -BOOL FileClose(struct _lcms_iccprofile_struct* Icc) +LCMSBOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size) +{ + return TRUE; +} + + +static +LCMSBOOL FileClose(struct _lcms_iccprofile_struct* Icc) { return fclose((FILE*) Icc ->stream); } @@ -252,7 +297,7 @@ cmsHPROFILE _cmsCreateProfilePlaceholder(void) { - LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) malloc(sizeof(LCMSICCPROFILE)); + LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) _cmsMalloc(sizeof(LCMSICCPROFILE)); if (Icc == NULL) return NULL; // Empty values @@ -290,7 +335,7 @@ // Search for a specific tag in tag dictionary // Returns position or -1 if tag not found -icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError) +icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError) { icInt32Number i; @@ -311,7 +356,7 @@ // Check existance -BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig) +LCMSBOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; return _cmsSearchTag(Icc, sig, FALSE) >= 0; @@ -330,7 +375,7 @@ if (i >=0) { - if (Icc -> TagPtrs[i]) free(Icc -> TagPtrs[i]); + if (Icc -> TagPtrs[i]) _cmsFree(Icc -> TagPtrs[i]); } else { @@ -341,11 +386,14 @@ cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", MAX_TABLE_TAG); Icc ->TagCount = MAX_TABLE_TAG-1; + return NULL; } } - Ptr = malloc(size); + Ptr = _cmsMalloc(size); + if (Ptr == NULL) return NULL; + CopyMemory(Ptr, Init, size); Icc ->TagNames[i] = sig; @@ -376,12 +424,15 @@ if (NewIcc == NULL) return NULL; strncpy(NewIcc -> PhysicalFile, FileName, MAX_PATH-1); + NewIcc -> PhysicalFile[MAX_PATH-1] = 0; + NewIcc ->stream = ICCfile; NewIcc ->Read = FileRead; NewIcc ->Seek = FileSeek; NewIcc ->Tell = FileTell; NewIcc ->Close = FileClose; + NewIcc ->Grow = FileGrow; NewIcc ->Write = NULL; NewIcc ->IsWrite = FALSE; @@ -419,7 +470,8 @@ NewIcc ->Seek = MemorySeek; NewIcc ->Tell = MemoryTell; NewIcc ->Close = MemoryClose; - NewIcc ->Write = NULL; + NewIcc ->Grow = MemoryGrow; + NewIcc ->Write = MemoryWrite; NewIcc ->IsWrite = FALSE; @@ -476,7 +528,7 @@ -BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; *Dest = Icc -> MediaWhitePoint; @@ -484,14 +536,14 @@ } -BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; *Dest = Icc -> MediaBlackPoint; return TRUE; } -BOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; *Dest = Icc -> Illuminant; @@ -549,7 +601,7 @@ } -BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; CopyMemory(Dest, &Icc ->Created, sizeof(struct tm)); @@ -570,23 +622,18 @@ Icc -> PCS = pcs; } - - icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; return Icc -> ColorSpace; } - - void LCMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, icColorSpaceSignature sig) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; Icc -> ColorSpace = sig; } - icProfileClassSignature LCMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; @@ -599,7 +646,6 @@ return (DWORD) Icc -> Version; } - void LCMSEXPORT cmsSetProfileICCversion(cmsHPROFILE hProfile, DWORD Version) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) hProfile; @@ -638,7 +684,7 @@ // This is tricky, since LUT structs does have pointers -BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut) +LCMSBOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LPLUT Orig, Stored; @@ -666,7 +712,7 @@ } -BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ) +LCMSBOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -675,7 +721,7 @@ } -BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text) +LCMSBOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -683,7 +729,7 @@ return TRUE; } -BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction) +LCMSBOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -692,7 +738,7 @@ } -BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm) +LCMSBOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -701,7 +747,7 @@ } -BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq) +LCMSBOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -711,28 +757,40 @@ } -BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc) +LCMSBOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc); - return FALSE; + return TRUE; } -BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime) +LCMSBOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; _cmsInitTag(Icc, sig, sizeof(struct tm), DateTime); - return FALSE; + return TRUE; } -BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc) +LCMSBOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc); - return FALSE; + return TRUE; } + + +LCMSBOOL LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat) +{ + LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; + + _cmsInitTag(Icc, sig, 3*sizeof(cmsCIEXYZ), mat); + return TRUE; + +} + + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -149,6 +149,7 @@ #endif + // Transports to properly encoded values - note that icc profiles does use // big endian notation. @@ -216,7 +217,8 @@ { icTagBase Base; - Icc -> Read(&Base, sizeof(icTagBase), 1, Icc); + if (Icc -> Read(&Base, sizeof(icTagBase), 1, Icc) != 1) + return (icTagTypeSignature) 0; AdjustEndianess32((LPBYTE) &Base.sig); return Base.sig; @@ -288,13 +290,15 @@ // Read profile header and validate it static -LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, BOOL lIsFromMemory) +LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, LCMSBOOL lIsFromMemory) { icTag Tag; icHeader Header; icInt32Number TagCount, i; - - Icc -> Read(&Header, sizeof(icHeader), 1, Icc); + icUInt32Number extent; + + if (Icc -> Read(&Header, sizeof(icHeader), 1, Icc) != 1) + goto ErrorCleanup; // Convert endian @@ -306,14 +310,13 @@ AdjustEndianess32((LPBYTE) &Header.pcs); AdjustEndianess32((LPBYTE) &Header.magic); AdjustEndianess32((LPBYTE) &Header.flags); - AdjustEndianess32((LPBYTE) &Header.attributes[0]); + AdjustEndianess32((LPBYTE) &Header.attributes[0]); AdjustEndianess32((LPBYTE) &Header.renderingIntent); // Validate it if (Header.magic != icMagicNumber) goto ErrorCleanup; - if (Icc ->Read(&TagCount, sizeof(icInt32Number), 1, Icc) != 1) goto ErrorCleanup; @@ -324,7 +327,7 @@ Icc -> PCS = Header.pcs; Icc -> RenderingIntent = (icRenderingIntent) Header.renderingIntent; Icc -> flags = Header.flags; - Icc -> attributes = Header.attributes[0]; + Icc -> attributes = Header.attributes[0]; Icc -> Illuminant.X = Convert15Fixed16(Header.illuminant.X); Icc -> Illuminant.Y = Convert15Fixed16(Header.illuminant.Y); Icc -> Illuminant.Z = Convert15Fixed16(Header.illuminant.Z); @@ -348,7 +351,7 @@ // Read tag directory - if (TagCount > MAX_TABLE_TAG) { + if (TagCount > MAX_TABLE_TAG || TagCount < 0) { cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", TagCount); goto ErrorCleanup; @@ -357,12 +360,18 @@ Icc -> TagCount = TagCount; for (i=0; i < TagCount; i++) { - Icc ->Read(&Tag, sizeof(icTag), 1, Icc); + if (Icc ->Read(&Tag, sizeof(icTag), 1, Icc) != 1) + goto ErrorCleanup; AdjustEndianess32((LPBYTE) &Tag.offset); AdjustEndianess32((LPBYTE) &Tag.size); AdjustEndianess32((LPBYTE) &Tag.sig); // Signature + // Perform some sanity check. Offset + size should fall inside file. + extent = Tag.offset + Tag.size; + if (extent > Header.size || extent < Tag.offset) + goto ErrorCleanup; + Icc -> TagNames[i] = Tag.sig; Icc -> TagOffsets[i] = Tag.offset; Icc -> TagSizes[i] = Tag.size; @@ -381,13 +390,10 @@ cmsSignalError(LCMS_ERRC_ABORTED, "Corrupted profile: '%s'", Icc->PhysicalFile); - free(Icc); + _cmsFree(Icc); return NULL; } - - - static unsigned int uipow(unsigned int a, unsigned int b) { unsigned int rv = 1; @@ -497,7 +503,7 @@ // The infamous LUT 8 static -void ReadLUT8(LPLCMSICCPROFILE Icc, LPLUT NewLUT, icTagSignature sig) +LCMSBOOL ReadLUT8(LPLCMSICCPROFILE Icc, LPLUT NewLUT, icTagSignature sig) { icLut8 LUT8; LPBYTE Temp; @@ -506,7 +512,7 @@ unsigned int AllLinear; LPWORD PtrW; - Icc ->Read(&LUT8, sizeof(icLut8) - SIZEOF_UINT8_ALIGNED, 1, Icc); + if (Icc ->Read(&LUT8, sizeof(icLut8) - SIZEOF_UINT8_ALIGNED, 1, Icc) != 1) return FALSE; NewLUT -> wFlags = LUT_HASTL1|LUT_HASTL2|LUT_HAS3DGRID; NewLUT -> cLutPoints = LUT8.clutPoints; @@ -515,6 +521,10 @@ NewLUT -> InputEntries = 256; NewLUT -> OutputEntries = 256; + // Do some checking + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } AdjustEndianess32((LPBYTE) &LUT8.e00); AdjustEndianess32((LPBYTE) &LUT8.e01); @@ -550,13 +560,24 @@ // Copy input tables - Temp = (LPBYTE) malloc(256); + Temp = (LPBYTE) _cmsMalloc(256); + if (Temp == NULL) return FALSE; + AllLinear = 0; for (i=0; i < NewLUT -> InputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * 256); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * 256); + if (PtrW == NULL) { + _cmsFree(Temp); + return FALSE; + } + NewLUT -> L1[i] = PtrW; - Icc ->Read(Temp, 1, 256, Icc); + if (Icc ->Read(Temp, 1, 256, Icc) != 256) { + _cmsFree(Temp); + return FALSE; + } + for (j=0; j < 256; j++) PtrW[j] = TO16_TAB(Temp[j]); AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries); @@ -569,7 +590,7 @@ NewLUT -> wFlags &= ~LUT_HASTL1; } - free(Temp); + _cmsFree(Temp); // Copy 3D CLUT @@ -578,9 +599,20 @@ if (nTabSize > 0) { - PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize); - Temp = (LPBYTE) malloc(nTabSize); - Icc ->Read(Temp, 1, nTabSize, Icc); + PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); + if (PtrW == NULL) return FALSE; + + Temp = (LPBYTE) _cmsMalloc(nTabSize); + if (Temp == NULL) { + _cmsFree(PtrW); + return FALSE; + } + + if (Icc ->Read(Temp, 1, nTabSize, Icc) != nTabSize) { + _cmsFree(Temp); + _cmsFree(PtrW); + return FALSE; + } NewLUT -> T = PtrW; NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD)); @@ -589,25 +621,37 @@ *PtrW++ = TO16_TAB(Temp[i]); } - free(Temp); + _cmsFree(Temp); } else { NewLUT ->T = NULL; NewLUT ->Tsize = 0; - NewLUT -> wFlags &= ~LUT_HAS3DGRID; + NewLUT ->wFlags &= ~LUT_HAS3DGRID; } - // Copy output tables - Temp = (LPBYTE) malloc(256); + Temp = (LPBYTE) _cmsMalloc(256); + if (Temp == NULL) { + return FALSE; + } + AllLinear = 0; for (i=0; i < NewLUT -> OutputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * 256); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * 256); + if (PtrW == NULL) { + _cmsFree(Temp); + return FALSE; + } + NewLUT -> L2[i] = PtrW; - Icc ->Read(Temp, 1, 256, Icc); + if (Icc ->Read(Temp, 1, 256, Icc) != 256) { + _cmsFree(Temp); + return FALSE; + } + for (j=0; j < 256; j++) PtrW[j] = TO16_TAB(Temp[j]); AllLinear += cmsIsLinear(NewLUT -> L2[i], 256); @@ -621,7 +665,7 @@ } - free(Temp); + _cmsFree(Temp); cmsCalcL16Params(NewLUT -> InputEntries, &NewLUT -> In16params); cmsCalcL16Params(NewLUT -> OutputEntries, &NewLUT -> Out16params); @@ -646,6 +690,15 @@ // some profiles does claim to do that. Poor lcms will try // to detect such condition and fix up "on the fly". + switch (sig) { + + case icSigBToA0Tag: + case icSigBToA1Tag: + case icSigBToA2Tag: + case icSigGamutTag: + case icSigPreview0Tag: + case icSigPreview1Tag: + case icSigPreview2Tag: { LPWORD WhiteLab, ExpectedWhite; WORD WhiteFixed[MAXCHANNELS], WhiteUnfixed[MAXCHANNELS]; @@ -685,9 +738,13 @@ } } - + break; + + default:; + } } + return TRUE; } @@ -696,7 +753,7 @@ // Case LUT 16 static -void ReadLUT16(LPLCMSICCPROFILE Icc, LPLUT NewLUT) +LCMSBOOL ReadLUT16(LPLCMSICCPROFILE Icc, LPLUT NewLUT) { icLut16 LUT16; size_t nTabSize; @@ -705,7 +762,8 @@ LPWORD PtrW; - Icc ->Read(&LUT16, sizeof(icLut16)- SIZEOF_UINT16_ALIGNED, 1, Icc); + if (Icc ->Read(&LUT16, sizeof(icLut16)- SIZEOF_UINT16_ALIGNED, 1, Icc) != 1) + return FALSE; NewLUT -> wFlags = LUT_HASTL1 | LUT_HASTL2 | LUT_HAS3DGRID; NewLUT -> cLutPoints = LUT16.clutPoints; @@ -718,6 +776,9 @@ NewLUT -> InputEntries = LUT16.inputEnt; NewLUT -> OutputEntries = LUT16.outputEnt; + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } // Matrix handling @@ -754,9 +815,14 @@ AllLinear = 0; for (i=0; i < NewLUT -> InputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> InputEntries); + if (PtrW == NULL) return FALSE; + NewLUT -> L1[i] = PtrW; - Icc ->Read(PtrW, sizeof(WORD), NewLUT -> InputEntries, Icc); + if (Icc ->Read(PtrW, sizeof(WORD), NewLUT -> InputEntries, Icc) != NewLUT -> InputEntries) { + return FALSE; + } + AdjustEndianessArray16(PtrW, NewLUT -> InputEntries); AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries); } @@ -775,12 +841,17 @@ NewLUT->InputChan)); if (nTabSize > 0) { - PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize); + PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); + if (PtrW == NULL) + return FALSE; NewLUT -> T = PtrW; NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD)); - Icc -> Read(PtrW, sizeof(WORD), nTabSize, Icc); + if (Icc -> Read(PtrW, sizeof(WORD), nTabSize, Icc) != nTabSize) { + return FALSE; + } + AdjustEndianessArray16(NewLUT -> T, nTabSize); } else { @@ -794,9 +865,16 @@ AllLinear = 0; for (i=0; i < NewLUT -> OutputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> OutputEntries); + if (PtrW == NULL) { + return FALSE; + } + NewLUT -> L2[i] = PtrW; - Icc ->Read(PtrW, sizeof(WORD), NewLUT -> OutputEntries, Icc); + if (Icc ->Read(PtrW, sizeof(WORD), NewLUT -> OutputEntries, Icc) != NewLUT -> OutputEntries) { + return FALSE; + } + AdjustEndianessArray16(PtrW, NewLUT -> OutputEntries); AllLinear += cmsIsLinear(NewLUT -> L2[i], NewLUT -> OutputEntries); } @@ -814,6 +892,8 @@ cmsCalcCLUT16Params(NewLUT -> cLutPoints, NewLUT -> InputChan, NewLUT -> OutputChan, &NewLUT -> CLut16params); + + return TRUE; } @@ -830,17 +910,15 @@ BaseType = ReadBase(Icc); - switch (BaseType) { - case 0x9478ee00L: // Monaco 2 profiler is BROKEN! + case ((icTagTypeSignature) 0x9478ee00): // Monaco 2 profiler is BROKEN! case icSigCurveType: - Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); + if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL; AdjustEndianess32((LPBYTE) &Count); - switch (Count) { case 0: // Linear. @@ -855,7 +933,7 @@ { WORD SingleGammaFixed; - Icc ->Read(&SingleGammaFixed, sizeof(WORD), 1, Icc); + if (Icc ->Read(&SingleGammaFixed, sizeof(WORD), 1, Icc) != 1) return NULL; AdjustEndianess16((LPBYTE) &SingleGammaFixed); return cmsBuildGamma(4096, Convert8Fixed8(SingleGammaFixed)); } @@ -865,10 +943,9 @@ NewGamma = cmsAllocGamma(Count); if (!NewGamma) return NULL; - Icc ->Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc); - + if (Icc ->Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc) != Count) + return NULL; AdjustEndianessArray16(NewGamma -> GammaTable, Count); - return NewGamma; } } @@ -885,11 +962,11 @@ icUInt16Number Type; int i; - Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc); - Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc); + if (Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc) != 1) return NULL; + if (Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc) != 1) return NULL; AdjustEndianess16((LPBYTE) &Type); - if (Type > 5) { + if (Type > 4) { cmsSignalError(LCMS_ERRC_ABORTED, "Unknown parametric curve type '%d' found.", Type); return NULL; @@ -900,7 +977,7 @@ for (i=0; i < n; i++) { Num = 0; - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); + if (Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc) != 1) return NULL; Params[i] = Convert15Fixed16(Num); } @@ -938,7 +1015,7 @@ case 0x9478ee00L: // Monaco 2 profiler is BROKEN! case icSigCurveType: - Icc -> Read(&Count, sizeof(icUInt32Number), 1, Icc); + if (Icc -> Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL; AdjustEndianess32((LPBYTE) &Count); @@ -948,6 +1025,7 @@ NewGamma = cmsAllocGamma(2); if (!NewGamma) return NULL; + NewGamma -> GammaTable[0] = 0; NewGamma -> GammaTable[1] = 0xFFFF; return NewGamma; @@ -955,7 +1033,7 @@ case 1: { WORD SingleGammaFixed; - Icc -> Read(&SingleGammaFixed, sizeof(WORD), 1, Icc); + if (Icc -> Read(&SingleGammaFixed, sizeof(WORD), 1, Icc) != 1) return NULL; AdjustEndianess16((LPBYTE) &SingleGammaFixed); return cmsBuildGamma(4096, 1./Convert8Fixed8(SingleGammaFixed)); } @@ -965,7 +1043,8 @@ NewGamma = cmsAllocGamma(Count); if (!NewGamma) return NULL; - Icc -> Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc); + if (Icc -> Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc) != Count) + return NULL; AdjustEndianessArray16(NewGamma -> GammaTable, Count); @@ -992,11 +1071,11 @@ int i; - Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc); - Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc); + if (Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc) != 1) return NULL; + if (Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc) != 1) return NULL; AdjustEndianess16((LPBYTE) &Type); - if (Type > 5) { + if (Type > 4) { cmsSignalError(LCMS_ERRC_ABORTED, "Unknown parametric curve type '%d' found.", Type); return NULL; @@ -1006,7 +1085,7 @@ n = ParamsByType[Type]; for (i=0; i < n; i++) { - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); + if (Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc) != 1) return NULL; Params[i] = Convert15Fixed16(Num); } @@ -1028,7 +1107,7 @@ // V4 stuff. Read matrix for LutAtoB and LutBtoA static -BOOL ReadMatrixOffset(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, DWORD dwFlags) +LCMSBOOL ReadMatrixOffset(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, DWORD dwFlags) { icS15Fixed16Number All[12]; @@ -1038,7 +1117,8 @@ if (Icc -> Seek(Icc, Offset)) return FALSE; - Icc ->Read(All, sizeof(icS15Fixed16Number), 12, Icc); + if (Icc ->Read(All, sizeof(icS15Fixed16Number), 12, Icc) != 12) + return FALSE; for (i=0; i < 12; i++) AdjustEndianess32((LPBYTE) &All[i]); @@ -1067,17 +1147,26 @@ // V4 stuff. Read CLUT part for LutAtoB and LutBtoA static -BOOL ReadCLUT(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT) +LCMSBOOL ReadCLUT(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT) { - + unsigned int j; icCLutStruct CLUT; if (Icc -> Seek(Icc, Offset)) return FALSE; - Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc); - - - cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan, - NewLUT ->OutputChan); + if (Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc) != 1) return FALSE; + + + for (j=1; j < NewLUT ->InputChan; j++) { + if (CLUT.gridPoints[0] != CLUT.gridPoints[j]) { + cmsSignalError(LCMS_ERRC_ABORTED, "CLUT with different granulatity is currently unsupported."); + return FALSE; + } + + + } + + if (cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan, + NewLUT ->OutputChan) == NULL) return FALSE; // Precission can be 1 or 2 bytes @@ -1087,7 +1176,7 @@ unsigned int i; for (i=0; i < NewLUT->Tsize / sizeof(WORD); i++) { - Icc ->Read(&v, sizeof(BYTE), 1, Icc); + if (Icc ->Read(&v, sizeof(BYTE), 1, Icc) != 1) return FALSE; NewLUT->T[i] = TO16_TAB(v); } @@ -1095,10 +1184,10 @@ else if (CLUT.prec == 2) { - Icc ->Read(NewLUT ->T, sizeof(WORD), - NewLUT->Tsize / sizeof(WORD), Icc); - - AdjustEndianessArray16(NewLUT ->T, NewLUT->Tsize / sizeof(WORD)); + size_t n = NewLUT->Tsize / sizeof(WORD); + + if (Icc ->Read(NewLUT ->T, sizeof(WORD), n, Icc) != n) return FALSE; + AdjustEndianessArray16(NewLUT ->T, NewLUT->Tsize / sizeof(WORD)); } else { cmsSignalError(LCMS_ERRC_ABORTED, "Unknow precission of '%d'", CLUT.prec); @@ -1110,6 +1199,22 @@ static +void ResampleCurves(LPGAMMATABLE Curves[], int nCurves) +{ + int i; + LPSAMPLEDCURVE sc; + + for (i=0; i < nCurves; i++) { + sc = cmsConvertGammaToSampledCurve(Curves[i], 4096); + cmsFreeGamma(Curves[i]); + Curves[i] = cmsConvertSampledCurveToGamma(sc, 0xFFFF); + cmsFreeSampledCurve(sc); + } + +} + + +static void SkipAlignment(LPLCMSICCPROFILE Icc) { BYTE Buffer[4]; @@ -1121,7 +1226,7 @@ // Read a set of curves from specific offset static -BOOL ReadSetOfCurves(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, int nLocation) +LCMSBOOL ReadSetOfCurves(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, int nLocation) { LPGAMMATABLE Curves[MAXCHANNELS]; unsigned int i, nCurves; @@ -1134,20 +1239,41 @@ else nCurves = NewLUT ->OutputChan; + ZeroMemory(Curves, sizeof(Curves)); for (i=0; i < nCurves; i++) { Curves[i] = ReadCurve(Icc); + if (Curves[i] == NULL) goto Error; SkipAlignment(Icc); - + } + + // March-26'08: some V4 profiles may have different sampling + // rates, in this case resample all curves to maximum + + for (i=1; i < nCurves; i++) { + if (Curves[i]->nEntries != Curves[0]->nEntries) { + ResampleCurves(Curves, nCurves); + break; + } } NewLUT = cmsAllocLinearTable(NewLUT, Curves, nLocation); + if (NewLUT == NULL) goto Error; for (i=0; i < nCurves; i++) cmsFreeGamma(Curves[i]); return TRUE; +Error: + + for (i=0; i < nCurves; i++) + if (Curves[i]) + cmsFreeGamma(Curves[i]); + + return FALSE; + + } // V4 stuff. LutAtoB type @@ -1160,22 +1286,28 @@ // L2 = B curves static -BOOL ReadLUT_A2B(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig) +LCMSBOOL ReadLUT_A2B(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig) { icLutAtoB LUT16; - Icc ->Read(&LUT16, sizeof(icLutAtoB), 1, Icc); + if (Icc ->Read(&LUT16, sizeof(icLutAtoB), 1, Icc) != 1) return FALSE; NewLUT -> InputChan = LUT16.inputChan; NewLUT -> OutputChan = LUT16.outputChan; + // Validate the NewLUT here to avoid excessive number of channels + // (leading to stack-based buffer overflow in ReadSetOfCurves). + // Needs revalidation after table size is filled in. + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } + AdjustEndianess32((LPBYTE) &LUT16.offsetB); AdjustEndianess32((LPBYTE) &LUT16.offsetMat); AdjustEndianess32((LPBYTE) &LUT16.offsetM); AdjustEndianess32((LPBYTE) &LUT16.offsetC); AdjustEndianess32((LPBYTE) &LUT16.offsetA); - if (LUT16.offsetB != 0) ReadSetOfCurves(Icc, BaseOffset + LUT16.offsetB, NewLUT, 2); @@ -1220,15 +1352,22 @@ // V4 stuff. LutBtoA type static -BOOL ReadLUT_B2A(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig) +LCMSBOOL ReadLUT_B2A(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig) { icLutBtoA LUT16; - Icc ->Read(&LUT16, sizeof(icLutBtoA), 1, Icc); + if (Icc ->Read(&LUT16, sizeof(icLutBtoA), 1, Icc) != 1) return FALSE; NewLUT -> InputChan = LUT16.inputChan; NewLUT -> OutputChan = LUT16.outputChan; + // Validate the NewLUT here to avoid excessive number of channels + // (leading to stack-based buffer overflow in ReadSetOfCurves). + // Needs revalidation after table size is filled in. + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } + AdjustEndianess32((LPBYTE) &LUT16.offsetB); AdjustEndianess32((LPBYTE) &LUT16.offsetMat); AdjustEndianess32((LPBYTE) &LUT16.offsetM); @@ -1242,7 +1381,6 @@ if (LUT16.offsetMat != 0) ReadMatrixOffset(Icc, BaseOffset + LUT16.offsetMat, NewLUT, LUT_HASMATRIX3); - if (LUT16.offsetM != 0) ReadSetOfCurves(Icc, BaseOffset + LUT16.offsetM, NewLUT, 3); @@ -1294,7 +1432,7 @@ // If is in memory, the LUT is already there, so throw a copy - if (!Icc -> stream) { + if (Icc -> TagPtrs[n]) { return cmsDupLUT((LPLUT) Icc ->TagPtrs[n]); } @@ -1308,8 +1446,8 @@ NewLUT = cmsAllocLUT(); - if (!NewLUT) - { + if (!NewLUT) { + cmsSignalError(LCMS_ERRC_ABORTED, "cmsAllocLUT() failed"); return NULL; } @@ -1317,11 +1455,29 @@ switch (BaseType) { - case icSigLut8Type: ReadLUT8(Icc, NewLUT, sig); break; - case icSigLut16Type: ReadLUT16(Icc, NewLUT); break; - - case icSiglutAtoBType: ReadLUT_A2B(Icc, NewLUT, offset, sig); break; - case icSiglutBtoAType: ReadLUT_B2A(Icc, NewLUT, offset, sig); break; + case icSigLut8Type: if (!ReadLUT8(Icc, NewLUT, sig)) { + cmsFreeLUT(NewLUT); + return NULL; + } + break; + + case icSigLut16Type: if (!ReadLUT16(Icc, NewLUT)) { + cmsFreeLUT(NewLUT); + return NULL; + } + break; + + case icSiglutAtoBType: if (!ReadLUT_A2B(Icc, NewLUT, offset, sig)) { + cmsFreeLUT(NewLUT); + return NULL; + } + break; + + case icSiglutBtoAType: if (!ReadLUT_B2A(Icc, NewLUT, offset, sig)) { + cmsFreeLUT(NewLUT); + return NULL; + } + break; default: cmsSignalError(LCMS_ERRC_ABORTED, "Bad tag signature %lx found.", BaseType); cmsFreeLUT(NewLUT); @@ -1335,16 +1491,23 @@ // Sets the language & country preferences. Used only in ICC 4.0 profiles -void LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode) +void LCMSEXPORT cmsSetLanguage(const char LanguageCode[4], const char CountryCode[4]) { - GlobalLanguageCode = LanguageCode; - GlobalCountryCode = CountryCode; + + int LanguageCodeInt = *(int *) LanguageCode; + int CountryCodeInt = *(int *) CountryCode; + + AdjustEndianess32((LPBYTE) &LanguageCodeInt); + AdjustEndianess32((LPBYTE) &CountryCodeInt); + + GlobalLanguageCode = LanguageCodeInt; + GlobalCountryCode = CountryCodeInt; } // Some tags (e.g, 'pseq') can have text tags embedded. This function -// handles such special case. +// handles such special case. Returns -1 on error, or the number of bytes left on success. static int ReadEmbeddedTextTag(LPLCMSICCPROFILE Icc, size_t size, char* Name, size_t size_max) @@ -1353,7 +1516,6 @@ BaseType = ReadBase(Icc); - size -= sizeof(icTagBase); switch (BaseType) { @@ -1365,50 +1527,54 @@ icUInt16Number ScriptCodeCode, Dummy; icUInt8Number ScriptCodeCount; - Icc ->Read(&AsciiCount, sizeof(icUInt32Number), 1, Icc); - - if (size < sizeof(icUInt32Number)) return (int) size; + if (Icc ->Read(&AsciiCount, sizeof(icUInt32Number), 1, Icc) != 1) return -1; + + if (size < sizeof(icUInt32Number)) return (int) size; size -= sizeof(icUInt32Number); AdjustEndianess32((LPBYTE) &AsciiCount); Icc ->Read(Name, 1, (AsciiCount >= size_max) ? (size_max-1) : AsciiCount, Icc); - if (size < AsciiCount) return (int) size; + if (size < AsciiCount) return (int) size; size -= AsciiCount; // Skip Unicode code - Icc ->Read(&UnicodeCode, sizeof(icUInt32Number), 1, Icc); - if (size < sizeof(icUInt32Number)) return (int) size; + if (Icc ->Read(&UnicodeCode, sizeof(icUInt32Number), 1, Icc) != 1) return -1; + if (size < sizeof(icUInt32Number)) return (int) size; size -= sizeof(icUInt32Number); - Icc ->Read(&UnicodeCount, sizeof(icUInt32Number), 1, Icc); - if (size < sizeof(icUInt32Number)) return (int) size; + if (Icc ->Read(&UnicodeCount, sizeof(icUInt32Number), 1, Icc) != 1) return -1; + if (size < sizeof(icUInt32Number)) return (int) size; size -= sizeof(icUInt32Number); AdjustEndianess32((LPBYTE) &UnicodeCount); if (UnicodeCount > size) return (int) size; - for (i=0; i < UnicodeCount; i++) - Icc ->Read(&Dummy, sizeof(icUInt16Number), 1, Icc); - - size -= UnicodeCount * sizeof(icUInt16Number); + for (i=0; i < UnicodeCount; i++) { + size_t nread = Icc ->Read(&Dummy, sizeof(icUInt16Number), 1, Icc); + if (nread != 1) return (int) size; + size -= sizeof(icUInt16Number); + } // Skip ScriptCode code - Icc ->Read(&ScriptCodeCode, sizeof(icUInt16Number), 1, Icc); + if (Icc ->Read(&ScriptCodeCode, sizeof(icUInt16Number), 1, Icc) != 1) return -1; size -= sizeof(icUInt16Number); - Icc ->Read(&ScriptCodeCount, sizeof(icUInt8Number), 1, Icc); + if (Icc ->Read(&ScriptCodeCount, sizeof(icUInt8Number), 1, Icc) != 1) return -1; size -= sizeof(icUInt8Number); + // Should remain 67 bytes as filler + if (size < 67) return (int) size; - for (i=0; i < 67; i++) - Icc ->Read(&Dummy, sizeof(icUInt8Number), 1, Icc); - - size -= 67; + for (i=0; i < 67; i++) { + size_t nread = Icc ->Read(&Dummy, sizeof(icUInt8Number), 1, Icc); + if (nread != 1) return (int) size; + size --; + } } break; @@ -1425,7 +1591,7 @@ size = size_max - 1; } - Icc -> Read(Name, 1, size, Icc); + if (Icc -> Read(Name, 1, size, Icc) != size) return -1; for (i=0; i < Missing; i++) Icc -> Read(&Dummy, 1, 1, Icc); @@ -1445,9 +1611,9 @@ wchar_t* wchar = L""; - Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); + if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return -1; AdjustEndianess32((LPBYTE) &Count); - Icc ->Read(&RecLen, sizeof(icUInt32Number), 1, Icc); + if (Icc ->Read(&RecLen, sizeof(icUInt32Number), 1, Icc) != 1) return -1; AdjustEndianess32((LPBYTE) &RecLen); if (RecLen != 12) { @@ -1458,15 +1624,15 @@ for (i=0; i < Count; i++) { - Icc ->Read(&Language, sizeof(icUInt16Number), 1, Icc); + if (Icc ->Read(&Language, sizeof(icUInt16Number), 1, Icc) != 1) return -1; AdjustEndianess16((LPBYTE) &Language); - Icc ->Read(&Country, sizeof(icUInt16Number), 1, Icc); + if (Icc ->Read(&Country, sizeof(icUInt16Number), 1, Icc) != 1) return -1; AdjustEndianess16((LPBYTE) &Country); - Icc ->Read(&ThisLen, sizeof(icUInt32Number), 1, Icc); + if (Icc ->Read(&ThisLen, sizeof(icUInt32Number), 1, Icc) != 1) return -1; AdjustEndianess32((LPBYTE) &ThisLen); - Icc ->Read(&ThisOffset, sizeof(icUInt32Number), 1, Icc); + if (Icc ->Read(&ThisOffset, sizeof(icUInt32Number), 1, Icc) != 1) return -1; AdjustEndianess32((LPBYTE) &ThisOffset); if (Language == GlobalLanguageCode || Offset == 0) { @@ -1492,14 +1658,18 @@ for (i=0; i < Offset; i++) { char Discard; - - Icc ->Read(&Discard, 1, 1, Icc); + if (Icc ->Read(&Discard, 1, 1, Icc) != 1) return -1; } - wchar = (wchar_t*) malloc(Len+2); + + // Bound len + if (Len < 0) Len = 0; + if (Len > 20*1024) Len = 20 * 1024; + + wchar = (wchar_t*) _cmsMalloc(Len*sizeof(wchar_t)+2); if (!wchar) return -1; - Icc ->Read(wchar, 1, Len, Icc); + if (Icc ->Read(wchar, 1, Len, Icc) != Len) return -1; AdjustEndianessArray16((LPWORD) wchar, Len / 2); wchar[Len / 2] = L'\0'; @@ -1509,7 +1679,7 @@ Name[0] = 0; // Error } - free((void*) wchar); + _cmsFree((void*) wchar); } break; @@ -1522,8 +1692,7 @@ } -// Take an ASCII item. Takes at most LCMS_DESC_MAX - +// Take an ASCII item. Takes at most size_max bytes int LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Name, size_t size_max) { @@ -1535,19 +1704,27 @@ if (n < 0) return -1; - if (!Icc -> stream) { - - CopyMemory(Name, Icc -> TagPtrs[n], Icc -> TagSizes[n]); + size = Icc -> TagSizes[n]; + + if (Icc -> TagPtrs[n]) { + + if (size > size_max) + size = size_max; + + CopyMemory(Name, Icc -> TagPtrs[n], size); + return (int) Icc -> TagSizes[n]; } offset = Icc -> TagOffsets[n]; - size = Icc -> TagSizes[n]; + if (Icc -> Seek(Icc, offset)) return -1; - return ReadEmbeddedTextTag(Icc, size, Name, size_max); + if (ReadEmbeddedTextTag(Icc, size, Name, size_max) < 0) return -1; + + return size; } // Keep compatibility with older versions @@ -1561,7 +1738,7 @@ // Take an XYZ item static -int ReadICCXYZ(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIEXYZ Value, BOOL lIsFatal) +int ReadICCXYZ(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIEXYZ Value, LCMSBOOL lIsFatal) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; icTagTypeSignature BaseType; @@ -1573,7 +1750,7 @@ if (n < 0) return -1; - if (!Icc -> stream) { + if (Icc -> TagPtrs[n]) { CopyMemory(Value, Icc -> TagPtrs[n], Icc -> TagSizes[n]); return (int) Icc -> TagSizes[n]; @@ -1628,7 +1805,7 @@ if (n < 0) return -1; // Not found - if (!Icc -> stream) { + if (Icc -> TagPtrs[n]) { CopyMemory(v, Icc -> TagPtrs[n], Icc -> TagSizes[n]); return (int) Icc -> TagSizes[n]; @@ -1677,7 +1854,7 @@ // Primaries are to be in xyY notation -BOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile) { if (ReadICCXYZ(hProfile, icSigRedColorantTag, &Dest -> Red, TRUE) < 0) return FALSE; if (ReadICCXYZ(hProfile, icSigGreenColorantTag, &Dest -> Green, TRUE) < 0) return FALSE; @@ -1687,7 +1864,7 @@ } -BOOL cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile) +LCMSBOOL cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile) { cmsCIEXYZTRIPLE Primaries; @@ -1704,7 +1881,7 @@ // Always return a suitable matrix -BOOL cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile) +LCMSBOOL cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile) { if (ReadICCXYZArray(hProfile, icSigChromaticAdaptationTag, r) < 0) { @@ -1741,7 +1918,7 @@ if (n < 0) return NULL; - if (!Icc -> stream) { + if (Icc -> TagPtrs[n]) { return cmsDupGamma((LPGAMMATABLE) Icc -> TagPtrs[n]); } @@ -1769,7 +1946,7 @@ if (n < 0) return NULL; - if (!Icc -> stream) { + if (Icc -> TagPtrs[n]) { return cmsReverseGamma(256, (LPGAMMATABLE) Icc -> TagPtrs[n]); } @@ -1785,7 +1962,7 @@ // Check Named color header static -BOOL CheckHeader(LPcmsNAMEDCOLORLIST v, icNamedColor2* nc2) +LCMSBOOL CheckHeader(LPcmsNAMEDCOLORLIST v, icNamedColor2* nc2) { if (v ->Prefix[0] == 0 && v ->Suffix[0] == 0 && v ->ColorantCount == 0) return TRUE; @@ -1809,13 +1986,13 @@ if (n < 0) return 0; - if (!Icc -> stream) { + if (Icc -> TagPtrs[n]) { // This replaces actual named color list. size_t size = Icc -> TagSizes[n]; if (v ->NamedColorList) cmsFreeNamedColorList(v ->NamedColorList); - v -> NamedColorList = (LPcmsNAMEDCOLORLIST) malloc(size); + v -> NamedColorList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size); CopyMemory(v -> NamedColorList, Icc ->TagPtrs[n], size); return v ->NamedColorList->nColors; } @@ -1844,7 +2021,7 @@ icNamedColor2 nc2; unsigned int i, j; - Icc -> Read(&nc2, sizeof(icNamedColor2) - SIZEOF_UINT8_ALIGNED, 1, Icc); + if (Icc -> Read(&nc2, sizeof(icNamedColor2) - SIZEOF_UINT8_ALIGNED, 1, Icc) != 1) return 0; AdjustEndianess32((LPBYTE) &nc2.vendorFlag); AdjustEndianess32((LPBYTE) &nc2.count); AdjustEndianess32((LPBYTE) &nc2.nDeviceCoords); @@ -1854,6 +2031,11 @@ return 0; } + if (nc2.nDeviceCoords > MAXCHANNELS) { + cmsSignalError(LCMS_ERRC_WARNING, "Too many device coordinates."); + return 0; + } + strncpy(v ->NamedColorList->Prefix, (const char*) nc2.prefix, 32); strncpy(v ->NamedColorList->Suffix, (const char*) nc2.suffix, 32); v ->NamedColorList->Prefix[32] = v->NamedColorList->Suffix[32] = 0; @@ -1900,7 +2082,8 @@ LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile, icTagSignature sig) { - icInt32Number n, Count, i; + icInt32Number n; + icUInt32Number Count, i; size_t offset; icTagTypeSignature BaseType; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -1910,10 +2093,12 @@ if (n < 0) return NULL; // Not found - if (!Icc -> stream) { + if (Icc -> TagPtrs[n]) { size_t size = Icc -> TagSizes[n]; - void* v = malloc(size); + void* v = _cmsMalloc(size); + + if (v == NULL) return NULL; CopyMemory(v, Icc -> TagPtrs[n], size); return (LPcmsNAMEDCOLORLIST) v; } @@ -1932,13 +2117,17 @@ } - Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); + if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL; AdjustEndianess32((LPBYTE) &Count); + if (Count > MAXCHANNELS) { + cmsSignalError(LCMS_ERRC_ABORTED, "Too many colorants '%lx'", Count); + return NULL; + } + List = cmsAllocNamedColorList(Count); for (i=0; i < Count; i++) { - if (!Icc ->Read(List->List[i].Name, 1, 32 , Icc)) goto Error; if (!Icc ->Read(List->List[i].PCS, sizeof(icUInt16Number), 3, Icc)) goto Error; AdjustEndianessArray16(List->List[i].PCS, 3); @@ -1965,7 +2154,7 @@ if (cmsIsTag(hProfile, icSigDeviceMfgDescTag)) { - cmsReadICCText(hProfile, icSigDeviceMfgDescTag, Manufacturer); + cmsReadICCTextEx(hProfile, icSigDeviceMfgDescTag, Manufacturer, LCMS_DESC_MAX); } return Manufacturer; @@ -1982,7 +2171,7 @@ if (cmsIsTag(hProfile, icSigDeviceModelDescTag)) { - cmsReadICCText(hProfile, icSigDeviceModelDescTag, Model); + cmsReadICCTextEx(hProfile, icSigDeviceModelDescTag, Model, LCMS_DESC_MAX); } return Model; @@ -1995,10 +2184,9 @@ static char Copyright[LCMS_DESC_MAX] = ""; Copyright[0] = 0; - if (cmsIsTag(hProfile, icSigCopyrightTag)) { - cmsReadICCText(hProfile, icSigCopyrightTag, Copyright); + cmsReadICCTextEx(hProfile, icSigCopyrightTag, Copyright, LCMS_DESC_MAX); } return Copyright; @@ -2009,7 +2197,7 @@ const char* LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile) { - static char Name[2048]; + static char Name[LCMS_DESC_MAX*2+4]; char Manufacturer[LCMS_DESC_MAX], Model[LCMS_DESC_MAX]; Name[0] = '\0'; @@ -2017,19 +2205,19 @@ if (cmsIsTag(hProfile, icSigDeviceMfgDescTag)) { - cmsReadICCText(hProfile, icSigDeviceMfgDescTag, Manufacturer); + cmsReadICCTextEx(hProfile, icSigDeviceMfgDescTag, Manufacturer, LCMS_DESC_MAX); } if (cmsIsTag(hProfile, icSigDeviceModelDescTag)) { - cmsReadICCText(hProfile, icSigDeviceModelDescTag, Model); + cmsReadICCTextEx(hProfile, icSigDeviceModelDescTag, Model, LCMS_DESC_MAX); } if (!Manufacturer[0] && !Model[0]) { if (cmsIsTag(hProfile, icSigProfileDescriptionTag)) { - cmsReadICCText(hProfile, icSigProfileDescriptionTag, Name); + cmsReadICCTextEx(hProfile, icSigProfileDescriptionTag, Name, LCMS_DESC_MAX); return Name; } else return "{no name}"; @@ -2129,7 +2317,7 @@ // Extract the target data as a big string. Does not signal if tag is not present. -BOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len) +LCMSBOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; int n; @@ -2142,7 +2330,11 @@ *len = Icc -> TagSizes[n]; - *Data = (char*) malloc(*len + 1); // Plus zero marker + + // Make sure that is reasonable (600K) + if (*len > 600*1024) *len = 600*1024; + + *Data = (char*) _cmsMalloc(*len + 1); // Plus zero marker if (!*Data) { @@ -2162,7 +2354,7 @@ -BOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; int n; @@ -2170,8 +2362,8 @@ n = _cmsSearchTag(Icc, icSigCalibrationDateTimeTag, FALSE); if (n < 0) return FALSE; - if (!Icc ->stream) - { + if (Icc ->TagPtrs[n]) { + CopyMemory(Dest, Icc ->TagPtrs[n], sizeof(struct tm)); } else @@ -2212,9 +2404,10 @@ size = Icc -> TagSizes[n]; if (size < 12) return NULL; - if (!Icc -> stream) { - - OutSeq = (LPcmsSEQ) malloc(size); + if (Icc -> TagPtrs[n]) { + + OutSeq = (LPcmsSEQ) _cmsMalloc(size); + if (OutSeq == NULL) return NULL; CopyMemory(OutSeq, Icc ->TagPtrs[n], size); return OutSeq; } @@ -2231,8 +2424,13 @@ Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); AdjustEndianess32((LPBYTE) &Count); + if (Count > 1000) { + return NULL; + } + size = sizeof(int) + Count * sizeof(cmsPSEQDESC); - OutSeq = (LPcmsSEQ) malloc(size); + OutSeq = (LPcmsSEQ) _cmsMalloc(size); + if (OutSeq == NULL) return NULL; OutSeq ->n = Count; @@ -2268,181 +2466,11 @@ void LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq) { if (pseq) - free(pseq); + _cmsFree(pseq); } -// Extended gamut -- an HP extension - - -LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index) -{ - LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; - size_t size, offset; - icUInt32Number off_samp, off_desc, off_vc; - int n; - icTagTypeSignature BaseType; - icColorSpaceSignature CoordSig; - icUInt16Number Method, Usage; - icUInt32Number GamutCount, SamplesCount; - LPcmsGAMUTEX gex; - size_t Offsets[256]; - size_t i, Actual, Loc; - icS15Fixed16Number Num; - icUInt16Number Surround; - - - n = _cmsSearchTag(Icc, icSigHPGamutDescTag, FALSE); - if (n < 0) return NULL; - - if (!Icc ->stream) return NULL; // In memory is not supported - - // Read the header - - offset = Icc -> TagOffsets[n]; - - if (Icc -> Seek(Icc, offset)) - return NULL; - - // Here is the beginning of tag - Actual = Icc ->Tell(Icc); - - - BaseType = ReadBase(Icc); - - if (BaseType != icSigHPGamutDescType) { - cmsSignalError(LCMS_ERRC_ABORTED, "Bad tag signature '%lx' found.", BaseType); - return NULL; - } - - - // Read the gamut descriptors count - Icc ->Read(&GamutCount, sizeof(icUInt32Number), 1, Icc); - AdjustEndianess32((LPBYTE) &GamutCount); - - - if (GamutCount >= 256) { - cmsSignalError(LCMS_ERRC_ABORTED, "Too many gamut structures '%d'.", GamutCount); - return NULL; - } - - // Read the directory - - for (i=0; i < GamutCount; i++) { - - Icc ->Read(&Offsets[i], sizeof(icUInt32Number), 1, Icc); - AdjustEndianess32((LPBYTE) &Offsets[i]); - } - - - // Is there such element? - if (index >= (int) GamutCount) return NULL; - Loc = Actual + Offsets[index]; - - - // Go to specified index - if (Icc -> Seek(Icc, Loc)) - return NULL; - - - // Read all members - Icc ->Read(&CoordSig, sizeof(icColorSpaceSignature), 1, Icc); - AdjustEndianess32((LPBYTE) &CoordSig); - - Icc ->Read(&Method, sizeof(icUInt16Number), 1, Icc); - AdjustEndianess16((LPBYTE) &Method); - - Icc ->Read(&Usage, sizeof(icUInt16Number), 1, Icc); - AdjustEndianess16((LPBYTE) &Usage); - - Icc ->Read(&SamplesCount, sizeof(icUInt32Number), 1, Icc); - AdjustEndianess32((LPBYTE) &SamplesCount); - - Icc ->Read(&off_samp, sizeof(icUInt32Number), 1, Icc); - AdjustEndianess32((LPBYTE) &off_samp); - - Icc ->Read(&off_desc, sizeof(icUInt32Number), 1, Icc); - AdjustEndianess32((LPBYTE) &off_desc); - - Icc ->Read(&off_vc, sizeof(icUInt32Number), 1, Icc); - AdjustEndianess32((LPBYTE) &off_vc); - - - size = sizeof(cmsGAMUTEX) + (SamplesCount - 1) * sizeof(double); - - gex = (LPcmsGAMUTEX) malloc(size); - if (gex == NULL) return NULL; - - - gex ->CoordSig = CoordSig; - gex ->Method = Method; - gex ->Usage = Usage; - gex ->Count = SamplesCount; - - - // Read data - if (Icc -> Seek(Icc, Loc + off_samp)) - return NULL; - - for (i=0; i < SamplesCount; i++) { - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); - gex ->Data[i] = Convert15Fixed16(Num); - } - - - // Read mluc - if (Icc -> Seek(Icc, Loc + off_desc)) { - - free(gex); - return NULL; - } - - ReadEmbeddedTextTag(Icc, 256, gex ->Description, LCMS_DESC_MAX); - - - // Read viewing conditions - if (Icc -> Seek(Icc, Loc + off_vc)) { - free(gex); - return NULL; - } - - - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); - gex ->Vc.whitePoint.X = Convert15Fixed16(Num); - - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); - gex ->Vc.whitePoint.Y = Convert15Fixed16(Num); - - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); - gex ->Vc.whitePoint.Z = Convert15Fixed16(Num); - - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); - gex ->Vc.La = Convert15Fixed16(Num); - - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); - gex ->Vc.Yb = Convert15Fixed16(Num); - - Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc); - gex ->Vc.D_value = Convert15Fixed16(Num); - - Icc -> Read(&Surround, sizeof(icUInt16Number), 1, Icc); - AdjustEndianess16((LPBYTE) &Surround); - gex ->Vc.surround = Surround; - - - // All OK - return gex; - -} - - - -void LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex) -{ - if (gex) - free(gex); -} // Read a few tags that are hardly required @@ -2564,6 +2592,7 @@ NewIcc = (LPLCMSICCPROFILE) (LPSTR) hEmpty; NewIcc -> IsWrite = TRUE; strncpy(NewIcc ->PhysicalFile, lpFileName, MAX_PATH-1); + NewIcc ->PhysicalFile[MAX_PATH-1] = 0; // Save LUT as 8 bit @@ -2609,14 +2638,14 @@ -BOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; - BOOL rc = TRUE; + LCMSBOOL rc = TRUE; + icInt32Number i; if (!Icc) return FALSE; - // Was open in write mode? if (Icc ->IsWrite) { @@ -2624,21 +2653,15 @@ rc = _cmsSaveProfile(hProfile, Icc ->PhysicalFile); } - - if (Icc -> stream == NULL) { // Was a memory (i.e. not serialized) profile? - - - icInt32Number i; // Yes, free tags - - for (i=0; i < Icc -> TagCount; i++) { + for (i=0; i < Icc -> TagCount; i++) { if (Icc -> TagPtrs[i]) free(Icc -> TagPtrs[i]); - } - } - else Icc -> Close(Icc); // No, close the stream - + + if (Icc -> stream != NULL) { // Was a memory (i.e. not serialized) profile? + Icc -> Close(Icc); // No, close the stream + } free(Icc); // Free placeholder memory @@ -2652,11 +2675,11 @@ static -BOOL SaveWordsTable(int nEntries, LPWORD Tab, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveWordsTable(int nEntries, LPWORD Tab, LPLCMSICCPROFILE Icc) { size_t nTabSize = sizeof(WORD) * nEntries; - LPWORD PtrW = (LPWORD) malloc(nTabSize); - BOOL rc; + LPWORD PtrW = (LPWORD) _cmsMalloc(nTabSize); + LCMSBOOL rc; if (!PtrW) return FALSE; CopyMemory(PtrW, Tab, nTabSize); @@ -2672,7 +2695,7 @@ // Saves profile header static -BOOL SaveHeader(LPLCMSICCPROFILE Icc) +LCMSBOOL SaveHeader(LPLCMSICCPROFILE Icc) { icHeader Header; time_t now = time(NULL); @@ -2727,7 +2750,7 @@ // Setup base marker static -BOOL SetupBase(icTagTypeSignature sig, LPLCMSICCPROFILE Icc) +LCMSBOOL SetupBase(icTagTypeSignature sig, LPLCMSICCPROFILE Icc) { icTagBase Base; @@ -2737,10 +2760,10 @@ } -// Store an XYZ tag +// Store a XYZ tag static -BOOL SaveXYZNumber(LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveXYZNumber(LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc) { icXYZNumber XYZ; @@ -2756,72 +2779,97 @@ } +// Store a XYZ array. + +static +LCMSBOOL SaveXYZArray(int n, LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc) +{ + int i; + icXYZNumber XYZ; + + if (!SetupBase(icSigS15Fixed16ArrayType, Icc)) return FALSE; + + for (i=0; i < n; i++) { + + XYZ.X = TransportValue32(DOUBLE_TO_FIXED(Value -> X)); + XYZ.Y = TransportValue32(DOUBLE_TO_FIXED(Value -> Y)); + XYZ.Z = TransportValue32(DOUBLE_TO_FIXED(Value -> Z)); + + if (!Icc -> Write(Icc, sizeof(icXYZNumber), &XYZ)) return FALSE; + + Value++; + } + + return TRUE; +} + + // Save a gamma structure as a table static -BOOL SaveGammaTable(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveGammaTable(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) { - icInt32Number Count; - - if (!SetupBase(icSigCurveType, Icc)) return FALSE; - - Count = TransportValue32(Gamma->nEntries); - - if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE; - - return SaveWordsTable(Gamma->nEntries, Gamma ->GammaTable, Icc); + icInt32Number Count; + + if (!SetupBase(icSigCurveType, Icc)) return FALSE; + + Count = TransportValue32(Gamma->nEntries); + + if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE; + + return SaveWordsTable(Gamma->nEntries, Gamma ->GammaTable, Icc); } // Save a gamma structure as a one-value static -BOOL SaveGammaOneValue(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveGammaOneValue(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) { - icInt32Number Count; - Fixed32 GammaFixed32; - WORD GammaFixed8; - - if (!SetupBase(icSigCurveType, Icc)) return FALSE; - - Count = TransportValue32(1); - if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE; - - GammaFixed32 = DOUBLE_TO_FIXED(Gamma ->Seed.Params[0]); - GammaFixed8 = (WORD) ((GammaFixed32 >> 8) & 0xFFFF); - GammaFixed8 = TransportValue16(GammaFixed8); - - return Icc ->Write(Icc, sizeof(icInt16Number), &GammaFixed8); + icInt32Number Count; + Fixed32 GammaFixed32; + WORD GammaFixed8; + + if (!SetupBase(icSigCurveType, Icc)) return FALSE; + + Count = TransportValue32(1); + if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE; + + GammaFixed32 = DOUBLE_TO_FIXED(Gamma ->Seed.Params[0]); + GammaFixed8 = (WORD) ((GammaFixed32 >> 8) & 0xFFFF); + GammaFixed8 = TransportValue16(GammaFixed8); + + return Icc ->Write(Icc, sizeof(icInt16Number), &GammaFixed8); } // Save a gamma structure as a parametric gamma static -BOOL SaveGammaParametric(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveGammaParametric(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) { - icUInt16Number Type, Reserved; - int i, nParams; - int ParamsByType[] = { 1, 3, 4, 5, 7 }; - - if (!SetupBase(icSigParametricCurveType, Icc)) return FALSE; - - nParams = ParamsByType[Gamma -> Seed.Type]; - - Type = (icUInt16Number) TransportValue16((WORD) Gamma -> Seed. Type); - Reserved = (icUInt16Number) TransportValue16((WORD) 0); - - Icc -> Write(Icc, sizeof(icInt16Number), &Type); - Icc -> Write(Icc, sizeof(icUInt16Number), &Reserved); - - for (i=0; i < nParams; i++) { - - icInt32Number val = TransportValue32(DOUBLE_TO_FIXED(Gamma -> Seed.Params[i])); - Icc ->Write(Icc, sizeof(icInt32Number), &val); - } - - - return TRUE; + icUInt16Number Type, Reserved; + int i, nParams; + int ParamsByType[] = { 1, 3, 4, 5, 7 }; + + if (!SetupBase(icSigParametricCurveType, Icc)) return FALSE; + + nParams = ParamsByType[Gamma -> Seed.Type]; + + Type = (icUInt16Number) TransportValue16((WORD) Gamma -> Seed. Type); + Reserved = (icUInt16Number) TransportValue16((WORD) 0); + + Icc -> Write(Icc, sizeof(icInt16Number), &Type); + Icc -> Write(Icc, sizeof(icUInt16Number), &Reserved); + + for (i=0; i < nParams; i++) { + + icInt32Number val = TransportValue32(DOUBLE_TO_FIXED(Gamma -> Seed.Params[i])); + Icc ->Write(Icc, sizeof(icInt32Number), &val); + } + + + return TRUE; } @@ -2829,29 +2877,29 @@ // Save a gamma table static -BOOL SaveGamma(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveGamma(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc) { - // Is the gamma curve type supported by ICC format? - - if (Gamma -> Seed.Type < 0 || Gamma -> Seed.Type > 5 || - - // has been modified by user? - - _cmsCrc32OfGammaTable(Gamma) != Gamma -> Seed.Crc32) { - - return SaveGammaTable(Gamma, Icc); - } - - if (Gamma -> Seed.Type == 1) return SaveGammaOneValue(Gamma, Icc); - - // Only v4 profiles are allowed to hold parametric curves - - if (cmsGetProfileICCversion((cmsHPROFILE) Icc) >= 0x4000000) - return SaveGammaParametric(Gamma, Icc); - - // Defaults to save as table - - return SaveGammaTable(Gamma, Icc); + // Is the gamma curve type supported by ICC format? + + if (Gamma -> Seed.Type < 0 || Gamma -> Seed.Type > 5 || + + // has been modified by user? + + _cmsCrc32OfGammaTable(Gamma) != Gamma -> Seed.Crc32) { + + return SaveGammaTable(Gamma, Icc); + } + + if (Gamma -> Seed.Type == 1) return SaveGammaOneValue(Gamma, Icc); + + // Only v4 profiles are allowed to hold parametric curves + + if (cmsGetProfileICCversion((cmsHPROFILE) Icc) >= 0x4000000) + return SaveGammaParametric(Gamma, Icc); + + // Defaults to save as table + + return SaveGammaTable(Gamma, Icc); } @@ -2861,7 +2909,7 @@ // Save an DESC Tag static -BOOL SaveDescription(const char *Text, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveDescription(const char *Text, LPLCMSICCPROFILE Icc) { icUInt32Number len, Count, TotalSize, AlignedSize; @@ -2893,6 +2941,11 @@ if (!Icc ->Write(Icc, len, (LPVOID)Text)) return FALSE; AlignedSize -= len; + if (AlignedSize < 0) + AlignedSize = 0; + if (AlignedSize > 255) + AlignedSize = 255; + ZeroMemory(Filler, AlignedSize); if (!Icc ->Write(Icc, AlignedSize, Filler)) return FALSE; @@ -2902,7 +2955,7 @@ // Save an ASCII Tag static -BOOL SaveText(const char *Text, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveText(const char *Text, LPLCMSICCPROFILE Icc) { size_t len = strlen(Text) + 1; @@ -2915,7 +2968,7 @@ // Save one of these new chromaticity values static -BOOL SaveOneChromaticity(double x, double y, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveOneChromaticity(double x, double y, LPLCMSICCPROFILE Icc) { Fixed32 xf, yf; @@ -2932,7 +2985,7 @@ // New tag added in Addendum II of old spec. static -BOOL SaveChromaticities(LPcmsCIExyYTRIPLE chrm, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveChromaticities(LPcmsCIExyYTRIPLE chrm, LPLCMSICCPROFILE Icc) { WORD nChans, Table; @@ -2952,7 +3005,7 @@ static -BOOL SaveSequenceDescriptionTag(LPcmsSEQ seq, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveSequenceDescriptionTag(LPcmsSEQ seq, LPLCMSICCPROFILE Icc) { icUInt32Number nSeqs; icDescStruct DescStruct; @@ -2989,7 +3042,7 @@ // Saves a timestamp tag static -BOOL SaveDateTimeNumber(const struct tm *DateTime, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveDateTimeNumber(const struct tm *DateTime, LPLCMSICCPROFILE Icc) { icDateTimeNumber Dest; @@ -3003,14 +3056,14 @@ // Saves a named color list into a named color profile static -BOOL SaveNamedColorList(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveNamedColorList(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc) { icUInt32Number vendorFlag; // Bottom 16 bits for IC use icUInt32Number count; // Count of named colors icUInt32Number nDeviceCoords; // Num of device coordinates - icInt8Number prefix[32]; // Prefix for each color name - icInt8Number suffix[32]; // Suffix for each color name + char prefix[32]; // Prefix for each color name + char suffix[32]; // Suffix for each color name int i; if (!SetupBase(icSigNamedColor2Type, Icc)) return FALSE; @@ -3019,8 +3072,10 @@ count = TransportValue32(NamedColorList ->nColors); nDeviceCoords = TransportValue32(NamedColorList ->ColorantCount); - strncpy(prefix, (const char*) NamedColorList->Prefix, 32); - strncpy(suffix, (const char*) NamedColorList->Suffix, 32); + strncpy(prefix, (const char*) NamedColorList->Prefix, 31); + strncpy(suffix, (const char*) NamedColorList->Suffix, 31); + + suffix[31] = prefix[31] = 0; if (!Icc ->Write(Icc, sizeof(icUInt32Number), &vendorFlag)) return FALSE; if (!Icc ->Write(Icc, sizeof(icUInt32Number), &count)) return FALSE; @@ -3030,15 +3085,17 @@ for (i=0; i < NamedColorList ->nColors; i++) { - icUInt16Number PCS[3]; - icUInt16Number Colorant[MAXCHANNELS]; - icInt8Number root[32]; + icUInt16Number PCS[3]; + icUInt16Number Colorant[MAXCHANNELS]; + char root[32]; LPcmsNAMEDCOLOR Color; int j; Color = NamedColorList ->List + i; - strncpy((char*) root, Color ->Name, 32); + strncpy(root, Color ->Name, 32); + Color ->Name[32] = 0; + if (!Icc ->Write(Icc, 32 , root)) return FALSE; for (j=0; j < 3; j++) @@ -3062,7 +3119,7 @@ // Saves a colorant table. It is using the named color structure for simplicity sake static -BOOL SaveColorantTable(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveColorantTable(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc) { icUInt32Number count; // Count of named colors int i; @@ -3076,13 +3133,15 @@ for (i=0; i < NamedColorList ->nColors; i++) { icUInt16Number PCS[3]; - icInt8Number root[32]; + icInt8Number root[33]; LPcmsNAMEDCOLOR Color; int j; Color = NamedColorList ->List + i; strncpy((char*) root, Color ->Name, 32); + root[32] = 0; + if (!Icc ->Write(Icc, 32 , root)) return FALSE; for (j=0; j < 3; j++) @@ -3099,7 +3158,7 @@ // Does serialization of LUT16 and writes it. static -BOOL SaveLUT(const LUT* NewLUT, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveLUT(const LUT* NewLUT, LPLCMSICCPROFILE Icc) { icLut16 LUT16; unsigned int i; @@ -3189,7 +3248,7 @@ // Does serialization of LUT8 and writes it static -BOOL SaveLUT8(const LUT* NewLUT, LPLCMSICCPROFILE Icc) +LCMSBOOL SaveLUT8(const LUT* NewLUT, LPLCMSICCPROFILE Icc) { icLut8 LUT8; unsigned int i, j; @@ -3323,7 +3382,7 @@ // Saves Tag directory static -BOOL SaveTagDirectory(LPLCMSICCPROFILE Icc) +LCMSBOOL SaveTagDirectory(LPLCMSICCPROFILE Icc) { icInt32Number i; icTag Tag; @@ -3356,7 +3415,7 @@ // Dump tag contents static -BOOL SaveTags(LPLCMSICCPROFILE Icc) +LCMSBOOL SaveTags(LPLCMSICCPROFILE Icc, LPLCMSICCPROFILE FileOrig) { LPBYTE Data; @@ -3384,8 +3443,31 @@ Icc -> TagOffsets[i] = Begin = Icc ->UsedSpace; Data = (LPBYTE) Icc -> TagPtrs[i]; - if (!Data) + if (!Data) { + + // Reach here if we are copying a tag from a disk-based ICC profile which has not been modified by user. + // In this case a blind copy of the block data is performed + + if (Icc -> TagOffsets[i]) { + + size_t TagSize = FileOrig -> TagSizes[i]; + size_t TagOffset = FileOrig -> TagOffsets[i]; + void* Mem; + + if (FileOrig ->Seek(FileOrig, TagOffset)) return FALSE; + + Mem = _cmsMalloc(TagSize); + + if (FileOrig ->Read(Mem, TagSize, 1, FileOrig) != 1) return FALSE; + if (!Icc ->Write(Icc, TagSize, Mem)) return FALSE; + + Icc -> TagSizes[i] = (Icc ->UsedSpace - Begin); + free(Mem); + } + continue; + } + switch (Icc -> TagNames[i]) { @@ -3464,6 +3546,10 @@ break; + case icSigChromaticAdaptationTag: + if (!SaveXYZArray(3, (LPcmsCIEXYZ) Data, Icc)) return FALSE; + break; + default: return FALSE; } @@ -3480,9 +3566,9 @@ // Add tags to profile structure -BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* Tag) +LCMSBOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* Tag) { - BOOL rc; + LCMSBOOL rc; switch (sig) { @@ -3543,6 +3629,11 @@ rc = _cmsAddColorantTableTag(hProfile, sig, (LPcmsNAMEDCOLORLIST) Tag); break; + + case icSigChromaticAdaptationTag: + rc = _cmsAddChromaticAdaptationTag(hProfile, sig, (const cmsCIEXYZ*) Tag); + break; + default: cmsSignalError(LCMS_ERRC_ABORTED, "cmsAddTag: Tag '%x' is unsupported", sig); return FALSE; @@ -3568,11 +3659,11 @@ // Low-level save to disk. It closes the profile on exit -BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName) +LCMSBOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; LCMSICCPROFILE Keep; - BOOL rc; + LCMSBOOL rc; CopyMemory(&Keep, Icc, sizeof(LCMSICCPROFILE)); _cmsSetSaveToDisk(Icc, NULL); @@ -3581,7 +3672,7 @@ if (!SaveHeader(Icc)) return FALSE; if (!SaveTagDirectory(Icc)) return FALSE; - if (!SaveTags(Icc)) return FALSE; + if (!SaveTags(Icc, &Keep)) return FALSE; _cmsSetSaveToDisk(Icc, FileName); @@ -3591,7 +3682,7 @@ if (!SaveHeader(Icc)) goto CleanUp; if (!SaveTagDirectory(Icc)) goto CleanUp; - if (!SaveTags(Icc)) goto CleanUp; + if (!SaveTags(Icc, &Keep)) goto CleanUp; rc = (Icc ->Close(Icc) == 0); CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); @@ -3608,7 +3699,7 @@ // Low-level save from open stream -BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, +LCMSBOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, size_t* BytesNeeded) { LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -3623,20 +3714,20 @@ if (!SaveHeader(Icc)) return FALSE; if (!SaveTagDirectory(Icc)) return FALSE; - if (!SaveTags(Icc)) return FALSE; + if (!SaveTags(Icc, &Keep)) return FALSE; if (!MemPtr) { // update BytesSaved so caller knows how many bytes are needed for MemPtr *BytesNeeded = Icc ->UsedSpace; - CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); + CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); return TRUE; } if (*BytesNeeded < Icc ->UsedSpace) { // need at least UsedSpace in MemPtr to continue - CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); + CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); return FALSE; } @@ -3646,7 +3737,7 @@ // Pass #2 does save to file into supplied stream if (!SaveHeader(Icc)) goto CleanUp; if (!SaveTagDirectory(Icc)) goto CleanUp; - if (!SaveTags(Icc)) goto CleanUp; + if (!SaveTags(Icc, &Keep)) goto CleanUp; // update BytesSaved so caller knows how many bytes put into stream *BytesNeeded = Icc ->UsedSpace; @@ -3661,3 +3752,4 @@ CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE)); return FALSE; } + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -118,7 +118,7 @@ { LPLUT NewLUT; - NewLUT = (LPLUT) malloc(sizeof(LUT)); + NewLUT = (LPLUT) _cmsMalloc(sizeof(LUT)); if (NewLUT) ZeroMemory(NewLUT, sizeof(LUT)); @@ -171,9 +171,10 @@ static LPVOID DupBlockTab(LPVOID Org, size_t size) { - LPVOID mem = malloc(size); + LPVOID mem = _cmsMalloc(size); + if (mem != NULL) + CopyMemory(mem, Org, size); - CopyMemory(mem, Org, size); return mem; } @@ -211,6 +212,37 @@ } +LCMSBOOL _cmsValidateLUT(LPLUT NewLUT) +{ + unsigned int calc = 1; + unsigned int oldCalc; + unsigned int power = NewLUT -> InputChan; + + if (NewLUT -> cLutPoints > 100) return FALSE; + if (NewLUT -> InputChan > MAXCHANNELS) return FALSE; + if (NewLUT -> OutputChan > MAXCHANNELS) return FALSE; + + if (NewLUT -> cLutPoints == 0) return TRUE; + + for (; power > 0; power--) { + + oldCalc = calc; + calc *= NewLUT -> cLutPoints; + + if (calc / NewLUT -> cLutPoints != oldCalc) { + return FALSE; + } + } + + oldCalc = calc; + calc *= NewLUT -> OutputChan; + if (NewLUT -> OutputChan && calc / NewLUT -> OutputChan != oldCalc) { + return FALSE; + } + + return TRUE; +} + LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int outputChan) { DWORD nTabSize; @@ -220,12 +252,17 @@ NewLUT -> InputChan = inputChan; NewLUT -> OutputChan = outputChan; + if (!_cmsValidateLUT(NewLUT)) { + return NULL; + } - nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints, - NewLUT->InputChan) - * sizeof(WORD)); + nTabSize = NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints, + NewLUT->InputChan); - NewLUT -> T = (LPWORD) malloc(nTabSize); + NewLUT -> T = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); + nTabSize *= sizeof(WORD); + if (NewLUT -> T == NULL) return NULL; + ZeroMemory(NewLUT -> T, nTabSize); NewLUT ->Tsize = nTabSize; @@ -254,10 +291,12 @@ for (i=0; i < NewLUT -> InputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> InputEntries); + if (PtrW == NULL) return NULL; + NewLUT -> L1[i] = PtrW; CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> InputEntries); - CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); + CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); } @@ -268,10 +307,12 @@ NewLUT -> OutputEntries = Tables[0] -> nEntries; for (i=0; i < NewLUT -> OutputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> OutputEntries); + if (PtrW == NULL) return NULL; + NewLUT -> L2[i] = PtrW; CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> OutputEntries); - CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); + CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); } break; @@ -285,10 +326,12 @@ for (i=0; i < NewLUT -> InputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L3Entries); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L3Entries); + if (PtrW == NULL) return NULL; + NewLUT -> L3[i] = PtrW; CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L3Entries); - CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); + CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); } break; @@ -298,10 +341,12 @@ NewLUT -> L4Entries = Tables[0] -> nEntries; for (i=0; i < NewLUT -> OutputChan; i++) { - PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L4Entries); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L4Entries); + if (PtrW == NULL) return NULL; + NewLUT -> L4[i] = PtrW; CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L4Entries); - CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); + CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS)); } break; @@ -580,7 +625,7 @@ LPL16PARAMS p = &Lut ->CLut16params; - p8 = (LPL8PARAMS) malloc(sizeof(L8PARAMS)); + p8 = (LPL8PARAMS) _cmsMalloc(sizeof(L8PARAMS)); if (p8 == NULL) return NULL; // values comes * 257, so we can safely take first byte (x << 8 + x) @@ -593,8 +638,8 @@ if (Lut ->wFlags & LUT_HASTL1) { for (j=0; j < 3; j++) - StageABC[i] = cmsLinearInterpLUT16(StageABC[i], - Lut -> L1[i], + StageABC[j] = cmsLinearInterpLUT16(StageABC[j], + Lut -> L1[j], &Lut -> In16params); Lut ->wFlags &= ~LUT_HASTL1; } @@ -697,7 +742,7 @@ wIn[3] = FixedK; cmsEvalLUT(Lut, wIn, wOut); - cmsLabEncoded2Float(Out, wOut); + cmsLabEncoded2Float(Out, wOut); } // Builds a Jacobian CMY->Lab @@ -722,9 +767,9 @@ EvalLUTdoubleKLab(Lut, &ColorantD, K, &LabD); - Jacobian->v[0].n[j] = ((LabD.L - Lab.L) / JACOBIAN_EPSILON); - Jacobian->v[1].n[j] = ((LabD.a - Lab.a) / JACOBIAN_EPSILON); - Jacobian->v[2].n[j] = ((LabD.b - Lab.b) / JACOBIAN_EPSILON); + Jacobian->v[0].n[j] = ((LabD.L - Lab.L) / JACOBIAN_EPSILON); + Jacobian->v[1].n[j] = ((LabD.a - Lab.a) / JACOBIAN_EPSILON); + Jacobian->v[2].n[j] = ((LabD.b - Lab.b) / JACOBIAN_EPSILON); } } @@ -797,18 +842,18 @@ // Obtain slope ComputeJacobianLab(Lut, &Jacobian, &x, FixedK); - // Solve system - tmp2.n[0] = fx.L - Goal.L; - tmp2.n[1] = fx.a - Goal.a; - tmp2.n[2] = fx.b - Goal.b; + // Solve system + tmp2.n[0] = fx.L - Goal.L; + tmp2.n[1] = fx.a - Goal.a; + tmp2.n[2] = fx.b - Goal.b; - if (!MAT3solve(&tmp, &Jacobian, &tmp2)) - break; + if (!MAT3solve(&tmp, &Jacobian, &tmp2)) + break; // Move our guess - x.n[0] -= tmp.n[0]; - x.n[1] -= tmp.n[1]; - x.n[2] -= tmp.n[2]; + x.n[0] -= tmp.n[0]; + x.n[1] -= tmp.n[1]; + x.n[2] -= tmp.n[2]; // Some clipping.... VEC3saturate(&x); @@ -822,3 +867,6 @@ return LastError; } + + + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -62,6 +62,7 @@ // data yet in fixed point, so no additional process is required. // Then, we obtain data on 15.16, so we need to shift >> by 1 to // obtain 1.15 PCS format. + // On OUTPUT profiles, things are inverse, we must first expand 1 bit // by shifting left, and then convert result between 0 and 1.000 to // RGB, so FromFixedDomain() must be called before pass values to @@ -71,6 +72,7 @@ // input is encoded from 0 to 0xffff, we must first use the shaper and // then the matrix, an additional FromFixedDomain() must be used to // accomodate output values. + // For a sake of simplicity, I will handle this three behaviours // with different routines, so the flags MATSHAPER_INPUT and MATSHAPER_OUTPUT // can be conbined to signal smelted matrix-shapers @@ -89,7 +91,7 @@ { LPWORD PtrW; - PtrW = (LPWORD) malloc(sizeof(WORD) * p16 -> nSamples); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * p16 -> nSamples); if (PtrW == NULL) return -1; // Signal error @@ -119,7 +121,7 @@ LPMATSHAPER NewMatShaper; int rc; - NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER)); + NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER)); if (NewMatShaper) ZeroMemory(NewMatShaper, sizeof(MATSHAPER)); @@ -171,7 +173,13 @@ LPMATSHAPER NewMatShaper; int i, AllLinear; - NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER)); + if (Matrix == NULL) return NULL; + for (i=0; i < 3; i++) { + + if (Tables[i] == NULL) return NULL; + } + + NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER)); if (NewMatShaper) ZeroMemory(NewMatShaper, sizeof(MATSHAPER)); @@ -187,17 +195,16 @@ NewMatShaper -> dwFlags |= MATSHAPER_HASMATRIX; // Now, on the table characteristics - cmsCalcL16Params(Tables[0] -> nEntries, &NewMatShaper -> p16); // Copy tables AllLinear = 0; - for (i=0; i < 3; i++) - { + for (i=0; i < 3; i++) { + LPWORD PtrW; - PtrW = (LPWORD) malloc(sizeof(WORD) * NewMatShaper -> p16.nSamples); + PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewMatShaper -> p16.nSamples); if (PtrW == NULL) { cmsFreeMatShaper(NewMatShaper); @@ -235,11 +242,11 @@ for (i=0; i < 3; i++) { - if (MatShaper -> L[i]) free(MatShaper ->L[i]); - if (MatShaper -> L2[i]) free(MatShaper ->L2[i]); + if (MatShaper -> L[i]) _cmsFree(MatShaper ->L[i]); + if (MatShaper -> L2[i]) _cmsFree(MatShaper ->L2[i]); } - free(MatShaper); + _cmsFree(MatShaper); } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -71,16 +71,16 @@ double cdecl VEC3distance(LPVEC3 a, LPVEC3 b); -void cdecl MAT3identity(LPMAT3 a); -void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b); -int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b); -BOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b); -double cdecl MAT3det(LPMAT3 m); -void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v); -void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v); -void cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v); -void cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d); -void cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d); +void cdecl MAT3identity(LPMAT3 a); +void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b); +int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b); +LCMSBOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b); +double cdecl MAT3det(LPMAT3 m); +void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v); +void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v); +void cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v); +void cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d); +void cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d); // --------------------- Implementation ---------------------------- @@ -345,13 +345,13 @@ // Check id two vectors are the same, allowing tolerance static -BOOL RangeCheck(double l, double h, double v) +LCMSBOOL RangeCheck(double l, double h, double v) { return (v >= l && v <= h); } -BOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance) +LCMSBOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance) { int i; double c; @@ -367,7 +367,7 @@ return TRUE; } -BOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance) +LCMSBOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance) { int i; double c; @@ -462,7 +462,7 @@ // Check if matrix is Identity. Allow a tolerance as % -BOOL MAT3isIdentity(LPWMAT3 a, double Tolerance) +LCMSBOOL MAT3isIdentity(LPWMAT3 a, double Tolerance) { int i; MAT3 Idd; @@ -545,16 +545,16 @@ // Solve a system in the form Ax = b -BOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b) +LCMSBOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b) { - MAT3 m, a_1; + MAT3 m, a_1; - CopyMemory(&m, a, sizeof(MAT3)); + CopyMemory(&m, a, sizeof(MAT3)); - if (!MAT3inverse(&m, &a_1)) return FALSE; // Singular matrix + if (!MAT3inverse(&m, &a_1)) return FALSE; // Singular matrix - MAT3eval(x, &a_1, b); - return TRUE; + MAT3eval(x, &a_1, b); + return TRUE; } @@ -839,3 +839,7 @@ VEC3scaleAndCut(&r -> v[1], &v -> v[1], d); VEC3scaleAndCut(&r -> v[2], &v -> v[2], d); } + + + + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -74,7 +74,7 @@ NewElements *= 2; size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * NewElements); - TheNewList = (LPcmsNAMEDCOLORLIST) malloc(size); + TheNewList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size); if (TheNewList == NULL) { @@ -86,7 +86,7 @@ CopyMemory(TheNewList, v, sizeof(cmsNAMEDCOLORLIST) + (v ->nColors - 1) * sizeof(cmsNAMEDCOLOR)); TheNewList -> Allocated = NewElements; - free(v); + _cmsFree(v); return TheNewList; } } @@ -99,7 +99,7 @@ { size_t size = sizeof(cmsNAMEDCOLORLIST) + (n - 1) * sizeof(cmsNAMEDCOLOR); - LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) malloc(size); + LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size); if (v == NULL) { @@ -124,10 +124,10 @@ return; } - free(v); + _cmsFree(v); } -BOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]) +LCMSBOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]) { _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform; LPcmsNAMEDCOLORLIST List; @@ -146,6 +146,7 @@ List ->List[List ->nColors].PCS[i] = PCS[i]; strncpy(List ->List[List ->nColors].Name, Name, MAX_PATH-1); + List ->List[List ->nColors].Name[MAX_PATH-1] = 0; List ->nColors++; return TRUE; @@ -164,18 +165,17 @@ } -BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix) +LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix) { _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform; - if (v ->NamedColorList == NULL) return FALSE; if (nColor < 0 || nColor >= cmsNamedColorCount(xform)) return FALSE; - if (Name) strncpy(Name, v ->NamedColorList->List[nColor].Name, 31); - if (Prefix) strncpy(Prefix, v ->NamedColorList->Prefix, 31); - if (Suffix) strncpy(Suffix, v ->NamedColorList->Suffix, 31); + if (Name) { strncpy(Name, v ->NamedColorList->List[nColor].Name, 31); Name[31] = 0; } + if (Prefix) { strncpy(Prefix, v ->NamedColorList->Prefix, 31); Prefix[31] = 0; } + if (Suffix) { strncpy(Suffix, v ->NamedColorList->Suffix, 31); Suffix[31] = 0; } return TRUE; } @@ -196,3 +196,5 @@ return -1; } + + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Tue Mar 24 19:12:02 2009 -0700 @@ -28,7 +28,7 @@ // file: // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -639,9 +639,81 @@ +static +LPBYTE UnrollDouble1Chan(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum) +{ + double* Inks = (double*) accum; + double v; + + + v = floor(Inks[0] * 65535.0 + 0.5); + + if (v > 65535.0) v = 65535.0; + if (v < 0) v = 0; + + + wIn[0] = wIn[1] = wIn[2] = (WORD) v; + + return accum + sizeof(double); +} + + // ----------------------------------------------------------- Packing routines +// Generic N-bytes plus dither 16-to-8 conversion. Currently is just a quick hack + +static int err[MAXCHANNELS]; + +static +LPBYTE PackNBytesDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output) +{ + int nChan = T_CHANNELS(info -> OutputFormat); + register int i; + unsigned int n, pe, pf; + + for (i=0; i < nChan; i++) { + + n = wOut[i] + err[i]; // Value + + pe = (n / 257); // Whole part + pf = (n % 257); // Fractional part + + err[i] = pf; // Store it for next pixel + + *output++ = (BYTE) pe; + } + + return output + T_EXTRA(info ->OutputFormat); +} + + + +static +LPBYTE PackNBytesSwapDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output) +{ + int nChan = T_CHANNELS(info -> OutputFormat); + register int i; + unsigned int n, pe, pf; + + for (i=nChan-1; i >= 0; --i) { + + n = wOut[i] + err[i]; // Value + + pe = (n / 257); // Whole part + pf = (n % 257); // Fractional part + + err[i] = pf; // Store it for next pixel + + *output++ = (BYTE) pe; + } + + + return output + T_EXTRA(info ->OutputFormat); +} + + + // Generic chunky for byte static @@ -1486,7 +1558,10 @@ case PT_HSV: case PT_HLS: case PT_Yxy: - FromInput = UnrollDouble; + if (T_CHANNELS(dwInput) == 1) + FromInput = UnrollDouble1Chan; + else + FromInput = UnrollDouble; break; // Inks (%) 0.0 .. 100.0 @@ -1749,6 +1824,9 @@ switch (T_CHANNELS(dwOutput)) { case 1: + if (T_DITHER(dwOutput)) + ToOutput = PackNBytesDither; + else ToOutput = Pack1Byte; if (T_EXTRA(dwOutput) == 1) { if (T_SWAPFIRST(dwOutput)) @@ -1766,8 +1844,12 @@ else if (T_COLORSPACE(dwOutput) == PT_Lab) ToOutput = Pack3BytesLab; + else { + if (T_DITHER(dwOutput)) + ToOutput = PackNBytesDither; else ToOutput = Pack3Bytes; + } break; case 1: // TODO: ALab8 should be handled here @@ -1793,13 +1875,23 @@ case 4: if (T_EXTRA(dwOutput) == 0) { + if (T_DOSWAP(dwOutput)) { - if (T_SWAPFIRST(dwOutput)) + + if (T_SWAPFIRST(dwOutput)) { ToOutput = Pack4BytesSwapSwapFirst; - else + } + else { + + if (T_DITHER(dwOutput)) { + ToOutput = PackNBytesSwapDither; + } + else { ToOutput = Pack4BytesSwap; } + } + } else { if (T_SWAPFIRST(dwOutput)) ToOutput = Pack4BytesSwapFirst; @@ -1807,11 +1899,15 @@ if (T_FLAVOR(dwOutput)) ToOutput = Pack4BytesReverse; + else { + if (T_DITHER(dwOutput)) + ToOutput = PackNBytesDither; else ToOutput = Pack4Bytes; } } } + } else { if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput)) ToOutput = PackNBytes; @@ -1833,7 +1929,7 @@ } break; - case 2: + case 2: case 5: case 7: case 8: @@ -1849,8 +1945,13 @@ { if (T_DOSWAP(dwOutput)) ToOutput = PackNBytesSwap; + else { + + if (T_DITHER(dwOutput)) + ToOutput = PackNBytesDither; else ToOutput = PackNBytes; + } } break; @@ -1984,7 +2085,7 @@ break; - case 2: + case 2: case 5: case 7: case 8: diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -624,3 +624,7 @@ fXYZ -> Z = XYZ2float(XYZ[2]); } + + + + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -144,6 +144,8 @@ /Table [ p p p [<...>]] /RangeABC [ 0 1 0 1 0 1] /DecodeABC[ ] + /RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ] + % -128/500 1+127/500 0 1 -127/200 1+128/200 /MatrixABC [ 1 1 1 1 0 0 0 0 -1] /WhitePoint [D50] /BlackPoint [BP] @@ -347,7 +349,8 @@ static LPMEMSTREAM CreateMemStream(LPBYTE Buffer, DWORD dwMax, int MaxCols) { - LPMEMSTREAM m = (LPMEMSTREAM) malloc(sizeof(MEMSTREAM)); + LPMEMSTREAM m = (LPMEMSTREAM) _cmsMalloc(sizeof(MEMSTREAM)); + if (m == NULL) return NULL; ZeroMemory(m, sizeof(MEMSTREAM)); @@ -376,9 +379,9 @@ static BYTE L2Byte(WORD w) { - int ww = w + 0x0080; + int ww = w + 0x0080; - if (ww > 0xFFFF) return 0xFF; + if (ww > 0xFFFF) return 0xFF; return (BYTE) ((WORD) (ww >> 8) & 0xFF); } @@ -387,7 +390,6 @@ static void WriteRawByte(LPMEMSTREAM m, BYTE b) { - if (m -> dwUsed + 1 > m -> dwMax) { m -> HasError = 1; } @@ -422,7 +424,7 @@ } -// Does write a formatted string +// Does write a formatted string. Guaranteed to be 2048 bytes at most. static void Writef(LPMEMSTREAM m, const char *frm, ...) { @@ -432,7 +434,7 @@ va_start(args, frm); - vsprintf((char*) Buffer, frm, args); + vsnprintf((char*) Buffer, 2048, frm, args); for (pt = Buffer; *pt; pt++) { @@ -562,7 +564,7 @@ Writef(m, "{255 mul 128 sub 200 div } bind\n"); Writef(m, "]\n"); Writef(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n"); - Writef(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n"); + Writef(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n"); Writef(m, "/DecodeLMN [\n"); Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n"); Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n"); @@ -584,7 +586,11 @@ if (nEntries <= 0) return; // Empty table // Suppress whole if identity - if (cmsIsLinear(Table, nEntries)) return; + if (cmsIsLinear(Table, nEntries)) { + Writef(m, "{} "); + return; + } + // Check if is really an exponential. If so, emit "exp" gamma = cmsEstimateGammaEx(Table, nEntries, 0.001); @@ -646,7 +652,7 @@ // Compare gamma table static -BOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries) +LCMSBOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries) { return memcmp(g1, g2, nEntries* sizeof(WORD)) == 0; } @@ -676,7 +682,7 @@ // Check whatever a profile has CLUT tables (only on input) static -BOOL IsLUTbased(cmsHPROFILE hProfile, int Intent) +LCMSBOOL IsLUTbased(cmsHPROFILE hProfile, int Intent) { icTagSignature Tag; @@ -718,10 +724,10 @@ if (sc -> FixWhite) { - if (In[0] == 0xFFFF) { // Only in L* = 100 + if (In[0] == 0xFFFF) { // Only in L* = 100, ab = [-8..8] - if ((In[1] >= 0x8000 && In[1] <= 0x87FF) || - (In[2] >= 0x8000 && In[2] <= 0x87FF)) { + if ((In[1] >= 0x7800 && In[1] <= 0x8800) && + (In[2] >= 0x7800 && In[2] <= 0x8800)) { WORD* Black; WORD* White; @@ -829,8 +835,8 @@ sc.PreMaj = PreMaj; sc.PostMaj= PostMaj; - sc.PreMin = PreMin; - sc.PostMin= PostMin; + sc.PreMin = PreMin; + sc.PostMin = PostMin; sc.lIsInput = lIsInput; sc.FixWhite = FixWhite; sc.ColorSpace = ColorSpace; @@ -1231,7 +1237,7 @@ if (!WriteNamedColorCSA(mem, hProfile, Intent)) { - free((void*) mem); + _cmsFree((void*) mem); return 0; } } @@ -1246,7 +1252,7 @@ ColorSpace != icSigLabData) { cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space"); - free((void*) mem); + _cmsFree((void*) mem); return 0; } @@ -1256,7 +1262,7 @@ // Yes, so handle as LUT-based if (!WriteInputLUT(mem, hProfile, Intent)) { - free((void*) mem); + _cmsFree((void*) mem); return 0; } } @@ -1266,7 +1272,7 @@ if (!WriteInputMatrixShaper(mem, hProfile)) { - free((void*) mem); // Something went wrong + _cmsFree((void*) mem); // Something went wrong return 0; } } @@ -1277,7 +1283,7 @@ dwBytesUsed = mem ->dwUsed; // Get rid of memory stream - free((void*) mem); + _cmsFree((void*) mem); // Finally, return used byte count return dwBytesUsed; @@ -1350,27 +1356,40 @@ static -void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute) +void EmitPQRStage(LPMEMSTREAM m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute) { + if (lIsAbsolute) { + + // For absolute colorimetric intent, encode back to relative + // and generate a relative LUT + + // Relative encoding is obtained across XYZpcs*(D50/WhitePoint) + + cmsCIEXYZ White; + + cmsTakeMediaWhitePoint(&White, hProfile); + + Writef(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n"); + Writef(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n"); + + Writef(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n" + "/TransformPQR [\n" + "{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n" + "{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n" + "{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n", + White.X, White.Y, White.Z); + return; + } + + Writef(m,"%% Bradford Cone Space\n" "/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n"); Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n"); - if (lIsAbsolute) { - - // For absolute colorimetric intent, do nothing - - Writef(m, "%% Absolute colorimetric -- no transformation\n" - "/TransformPQR [\n" - "{exch pop exch pop exch pop exch pop} bind dup dup]\n"); - return; - } - - // No BPC if (!DoBPC) { @@ -1414,6 +1433,7 @@ static void EmitXYZ2Lab(LPMEMSTREAM m) { + Writef(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n"); Writef(m, "/EncodeLMN [\n"); Writef(m, "{ 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n"); Writef(m, "{ 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n"); @@ -1423,17 +1443,10 @@ Writef(m, "/EncodeABC [\n"); - Writef(m, "{ 116 mul 16 sub 100 div } bind\n"); - Writef(m, "{ 500 mul 128 add 255 div } bind\n"); - Writef(m, "{ 200 mul 128 add 255 div } bind\n"); - + Writef(m, "{ 500 mul 128 add 256 div } bind\n"); + Writef(m, "{ 200 mul 128 add 256 div } bind\n"); - /* - Writef(m, "{ 116 mul 16 sub 256 mul 25700 div } bind\n"); - Writef(m, "{ 500 mul 128 add 256 mul 65535 div } bind\n"); - Writef(m, "{ 200 mul 128 add 256 mul 65535 div } bind\n"); - */ Writef(m, "]\n"); @@ -1458,20 +1471,27 @@ LPLUT DeviceLink; cmsHPROFILE Profiles[3]; cmsCIEXYZ BlackPointAdaptedToD50; - BOOL lFreeDeviceLink = FALSE; - BOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); + LCMSBOOL lFreeDeviceLink = FALSE; + LCMSBOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); + LCMSBOOL lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP); + int RelativeEncodingIntent; - // Trick our v4 profile as it were v2. This prevents the ajusting done - // in perceptual & saturation. We only neew v4 encoding! - hLab = cmsCreateLab4Profile(NULL); - cmsSetProfileICCversion(hLab, 0); + hLab = cmsCreateLabProfile(NULL); ColorSpace = cmsGetColorSpace(hProfile); nChannels = _cmsChannelsOf(ColorSpace); OutputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2); + // For absolute colorimetric, the LUT is encoded as relative + // in order to preserve precission. + + RelativeEncodingIntent = Intent; + if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC) + RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC; + + // Is a devicelink profile? if (cmsGetDeviceClass(hProfile) == icSigLinkClass) { @@ -1479,13 +1499,14 @@ if (ColorSpace == icSigLabData) { - // adjust input to Lab to out v4 + // adjust input to Lab to our v4 Profiles[0] = hLab; Profiles[1] = hProfile; xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL, - OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION); + OutputFormat, RelativeEncodingIntent, + dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION); } else { @@ -1499,7 +1520,7 @@ // This is a normal profile xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile, - OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION); + OutputFormat, RelativeEncodingIntent, dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION); } if (xform == NULL) { @@ -1515,7 +1536,7 @@ if (!DeviceLink) { - DeviceLink = _cmsPrecalculateDeviceLink(xform, 0); + DeviceLink = _cmsPrecalculateDeviceLink(xform, cmsFLAGS_NOPRELINEARIZATION); lFreeDeviceLink = TRUE; } @@ -1527,7 +1548,7 @@ // Emit headers, etc. EmitWhiteBlackD50(m, &BlackPointAdaptedToD50); - EmitPQRStage(m, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC); + EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC); EmitXYZ2Lab(m); if (DeviceLink ->wFlags & LUT_HASTL1) { @@ -1544,10 +1565,13 @@ // zero. This would sacrifice a bit of highlights, but failure to do so would cause // scum dot. Ouch. + if (Intent == INTENT_ABSOLUTE_COLORIMETRIC) + lFixWhite = FALSE; + Writef(m, "/RenderTable "); WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE, - (Intent != INTENT_ABSOLUTE_COLORIMETRIC), ColorSpace); + lFixWhite, ColorSpace); Writef(m, " %d {} bind ", nChannels); @@ -1582,6 +1606,9 @@ int j; Colorant[0] = 0; + if (nColorant > MAXCHANNELS) + nColorant = MAXCHANNELS; + for (j=0; j < nColorant; j++) { sprintf(Buff, "%.3f", Out[j] / 65535.0); @@ -1677,7 +1704,7 @@ if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) { - free((void*) mem); + _cmsFree((void*) mem); return 0; } } @@ -1687,7 +1714,7 @@ if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) { - free((void*) mem); + _cmsFree((void*) mem); return 0; } } @@ -1702,7 +1729,7 @@ dwBytesUsed = mem ->dwUsed; // Get rid of memory stream - free((void*) mem); + _cmsFree((void*) mem); // Finally, return used byte count return dwBytesUsed; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -120,7 +120,7 @@ // This routine does a sweep on whole input space, and calls its callback // function on knots. returns TRUE if all ok, FALSE otherwise. -BOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags) +LCMSBOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags) { int i, t, nTotalPoints, Colorant, index; WORD In[MAXCHANNELS], Out[MAXCHANNELS]; @@ -145,12 +145,16 @@ &Lut -> In16params); } + for (t=0; t < (int) Lut -> OutputChan; t++) + Out[t] = Lut->T[index + t]; - // if (dwFlags & SAMPLER_INSPECT) { + if (dwFlags & SAMPLER_HASTL2) { for (t=0; t < (int) Lut -> OutputChan; t++) - Out[t] = Lut->T[index + t]; - // } + Out[t] = cmsLinearInterpLUT16(Out[t], + Lut -> L2[t], + &Lut -> Out16params); + } if (!Sampler(In, Out, Cargo)) @@ -255,9 +259,11 @@ LPLUT Grid; int nGridPoints; DWORD dwFormatIn, dwFormatOut; + DWORD SaveFormatIn, SaveFormatOut; int ChannelsIn, ChannelsOut; LPLUT SaveGamutLUT; + // Remove any gamut checking SaveGamutLUT = p ->Gamut; p ->Gamut = NULL; @@ -276,8 +282,13 @@ dwFormatIn = (CHANNELS_SH(ChannelsIn)|BYTES_SH(2)); dwFormatOut = (CHANNELS_SH(ChannelsOut)|BYTES_SH(2)); - p -> FromInput = _cmsIdentifyInputFormat(p, dwFormatIn); - p -> ToOutput = _cmsIdentifyOutputFormat(p, dwFormatOut); + SaveFormatIn = p ->InputFormat; + SaveFormatOut = p ->OutputFormat; + + p -> InputFormat = dwFormatIn; + p -> OutputFormat = dwFormatOut; + p -> FromInput = _cmsIdentifyInputFormat(p, dwFormatIn); + p -> ToOutput = _cmsIdentifyOutputFormat(p, dwFormatOut); // Fix gamut & gamma possible mismatches. @@ -289,7 +300,6 @@ _cmsComputePrelinearizationTablesFromXFORM(hOne, 1, Grid); } - // Attention to this typecast! we can take the luxury to // do this since cmsHTRANSFORM is only an alias to a pointer // to the transform struct. @@ -297,11 +307,13 @@ if (!cmsSample3DGrid(Grid, XFormSampler, (LPVOID) p, Grid -> wFlags)) { cmsFreeLUT(Grid); - return NULL; + Grid = NULL; } + p ->Gamut = SaveGamutLUT; + p ->InputFormat = SaveFormatIn; + p ->OutputFormat = SaveFormatOut; - p ->Gamut = SaveGamutLUT; return Grid; } @@ -348,7 +360,7 @@ -// That is our K-preserving callback. +// Preserve all K plane. static int BlackPreservingSampler(register WORD In[], register WORD Out[], register LPVOID Cargo) { @@ -469,6 +481,7 @@ return OldVal; } +#pragma warning(disable: 4550) // Get a pointer to callback on depending of strategy static @@ -504,11 +517,10 @@ if (p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION) LocalFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; - // Fill in cargo struct Cargo.cmyk2cmyk = hCMYK2CMYK; - // Compute tone curve + // Compute tone curve. Cargo.KTone = _cmsBuildKToneCurve(hCMYK2CMYK, 256); if (Cargo.KTone == NULL) return NULL; cmsCalcL16Params(Cargo.KTone ->nEntries, &Cargo.KToneParams); @@ -522,11 +534,11 @@ Cargo.LabK2cmyk = cmsReadICCLut(p->OutputProfile, Device2PCS[p->Intent]); // Is there any table available? - if (Cargo.LabK2cmyk == NULL) { + if (Cargo.LabK2cmyk == NULL) { - Grid = NULL; + Grid = NULL; goto Cleanup; - } + } // Setup a roundtrip on output profile for TAC estimation Cargo.hRoundTrip = cmsCreateTransform(p ->OutputProfile, TYPE_CMYK_16, @@ -654,7 +666,7 @@ -BOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p) +LCMSBOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p) { WORD *WhitePointIn, *WhitePointOut, *BlackPointIn, *BlackPointOut; @@ -682,3 +694,4 @@ return TRUE; } + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -320,7 +320,7 @@ cmsHPROFILE hICC; _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) hTransform; LPLUT Lut; - BOOL MustFreeLUT; + LCMSBOOL MustFreeLUT; LPcmsNAMEDCOLORLIST InputColorant = NULL; LPcmsNAMEDCOLORLIST OutputColorant = NULL; @@ -373,10 +373,8 @@ if (cmsGetDeviceClass(hICC) == icSigOutputClass) { - cmsAddTag(hICC, icSigBToA0Tag, (LPVOID) Lut); } - else cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut); @@ -404,7 +402,7 @@ OutputColorant = cmsReadColorantTable(v ->OutputProfile, icSigColorantTableTag); } - } + } if (InputColorant) cmsAddTag(hICC, icSigColorantTableTag, InputColorant); @@ -446,6 +444,7 @@ // Creates a LUT with prelinearization step only Lut = cmsAllocLUT(); + if (Lut == NULL) return NULL; // Set up channels Lut ->InputChan = Lut ->OutputChan = _cmsChannelsOf(ColorSpace); @@ -548,6 +547,10 @@ // Creates a LUT with 3D grid only Lut = cmsAllocLUT(); + if (Lut == NULL) { + cmsCloseProfile(hICC); + return NULL; + } cmsAlloc3DGrid(Lut, 17, _cmsChannelsOf(ColorSpace), @@ -584,8 +587,9 @@ LPLUT Create3x3EmptyLUT(void) { LPLUT AToB0 = cmsAllocLUT(); + if (AToB0 == NULL) return NULL; + AToB0 -> InputChan = AToB0 -> OutputChan = 3; - return AToB0; } @@ -597,8 +601,8 @@ cmsHPROFILE hProfile; LPLUT Lut; - hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL); + if (hProfile == NULL) return NULL; cmsSetDeviceClass(hProfile, icSigAbstractClass); cmsSetColorSpace(hProfile, icSigLabData); @@ -611,7 +615,10 @@ // An empty LUTs is all we need Lut = Create3x3EmptyLUT(); - if (Lut == NULL) return NULL; + if (Lut == NULL) { + cmsCloseProfile(hProfile); + return NULL; + } cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut); @@ -628,8 +635,8 @@ cmsHPROFILE hProfile; LPLUT Lut; - hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL); + if (hProfile == NULL) return NULL; cmsSetProfileICCversion(hProfile, 0x4000000); @@ -644,7 +651,10 @@ // An empty LUTs is all we need Lut = Create3x3EmptyLUT(); - if (Lut == NULL) return NULL; + if (Lut == NULL) { + cmsCloseProfile(hProfile); + return NULL; + } Lut -> wFlags |= LUT_V4_INPUT_EMULATE_V2; cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); @@ -666,6 +676,7 @@ LPLUT Lut; hProfile = cmsCreateRGBProfile(cmsD50_xyY(), NULL, NULL); + if (hProfile == NULL) return NULL; cmsSetDeviceClass(hProfile, icSigAbstractClass); cmsSetColorSpace(hProfile, icSigXYZData); @@ -677,15 +688,16 @@ // An empty LUTs is all we need Lut = Create3x3EmptyLUT(); - if (Lut == NULL) return NULL; + if (Lut == NULL) { + cmsCloseProfile(hProfile); + return NULL; + } cmsAddTag(hProfile, icSigAToB0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigBToA0Tag, (LPVOID) Lut); cmsAddTag(hProfile, icSigPreview0Tag, (LPVOID) Lut); cmsFreeLUT(Lut); - - return hProfile; } @@ -723,6 +735,7 @@ return cmsBuildParametricGamma(1024, 4, Parameters); } +// Create the ICC virtual profile for sRGB space cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void) { cmsCIExyY D65; @@ -739,6 +752,7 @@ hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma22); cmsFreeGamma(Gamma22[0]); + if (hsRGB == NULL) return NULL; cmsAddTag(hsRGB, icSigDeviceMfgDescTag, (LPVOID) "(lcms internal)"); @@ -750,7 +764,6 @@ - typedef struct { double Brightness; double Contrast; @@ -793,7 +806,6 @@ cmsFloat2LabEncoded(Out, &LabOut); - return TRUE; } @@ -839,7 +851,10 @@ // Creates a LUT with 3D grid only Lut = cmsAllocLUT(); - + if (Lut == NULL) { + cmsCloseProfile(hICC); + return NULL; + } cmsAlloc3DGrid(Lut, nLUTPoints, 3, 3); @@ -890,7 +905,10 @@ // An empty LUTs is all we need Lut = cmsAllocLUT(); - if (Lut == NULL) return NULL; + if (Lut == NULL) { + cmsCloseProfile(hProfile); + return NULL; + } Lut -> InputChan = 3; Lut -> OutputChan = 1; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -51,10 +51,6 @@ #include "lcms.h" -// Uncomment this line if you want lcms to use the black point tag in profile, -// if commented, lcms will compute the black point by its own. -// It is safer to leve it commented out -// #define HONOR_BLACK_POINT_TAG // Conversions @@ -79,10 +75,9 @@ } - // Obtains WhitePoint from Temperature -BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint) +LCMSBOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint) { double x, y; double T, T2, T3; @@ -147,7 +142,7 @@ // - Then, I apply these coeficients to the original matrix -BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt, +LCMSBOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt, LPcmsCIExyYTRIPLE Primrs) { VEC3 WhitePoint, Coef; @@ -169,14 +164,12 @@ // Build Primaries matrix - VEC3init(&Primaries.v[0], xr, xg, xb); VEC3init(&Primaries.v[1], yr, yg, yb); VEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg), (1-xb-yb)); // Result = Primaries ^ (-1) inverse matrix - if (!MAT3inverse(&Primaries, &Result)) return FALSE; @@ -184,11 +177,9 @@ VEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn); // Across inverse primaries ... - MAT3eval(&Coef, &Result, &WhitePoint); // Give us the Coefs, then I build transformation matrix - VEC3init(&r -> v[0], Coef.n[VX]*xr, Coef.n[VY]*xg, Coef.n[VZ]*xb); VEC3init(&r -> v[1], Coef.n[VX]*yr, Coef.n[VY]*yg, Coef.n[VZ]*yb); VEC3init(&r -> v[2], Coef.n[VX]*(1.0-xr-yr), Coef.n[VY]*(1.0-xg-yg), Coef.n[VZ]*(1.0-xb-yb)); @@ -246,7 +237,7 @@ // Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll // The cone matrix can be specified in ConeMatrix. If NULL, Bradford is assumed -BOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll) +LCMSBOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll) { MAT3 LamRigg = {{ // Bradford matrix {{ 0.8951, 0.2664, -0.1614 }}, @@ -265,7 +256,7 @@ // Same as anterior, but assuming D50 destination. White point is given in xyY -BOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt) +LCMSBOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt) { cmsCIEXYZ Dn; MAT3 Bradford; @@ -284,7 +275,7 @@ // Same as anterior, but assuming D50 source. White point is given in xyY -BOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt) +LCMSBOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt) { cmsCIEXYZ Dn; MAT3 Bradford; @@ -304,7 +295,7 @@ // Adapts a color to a given illuminant. Original color is expected to have // a SourceWhitePt white point. -BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, +LCMSBOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, LPcmsCIEXYZ SourceWhitePt, LPcmsCIEXYZ Illuminant, LPcmsCIEXYZ Value) @@ -404,8 +395,6 @@ dj = ((vs - vj) - tj * (us - uj)) / sqrt(1 + tj*tj); - - if ((j!=0) && (di/dj < 0.0)) { Tc = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi)); break; @@ -423,7 +412,7 @@ static -BOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance) +LCMSBOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance) { double dist_x, dist_y; @@ -458,6 +447,7 @@ } +// To be removed in future versions void _cmsIdentifyWhitePoint(char *Buffer, LPcmsCIEXYZ WhitePt) { int i, n; @@ -518,7 +508,6 @@ cmsCIEXYZ BlackXYZ, MediaWhite; // If the profile does not support input direction, assume Black point 0 - if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) { BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; @@ -527,7 +516,6 @@ // Try to get black by using black colorant - Space = cmsGetColorSpace(hInput); if (!_cmsEndPointsBySpace(Space, &White, &Black, &nChannels)) { @@ -576,7 +564,7 @@ // Get a black point of output CMYK profile, discounting any ink-limiting embedded -// in the profile. Fou doing that, use perceptual intent in input direction: +// in the profile. For doing that, use perceptual intent in input direction: // Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab static @@ -651,6 +639,8 @@ D50BlackPoint.X = PERCEPTUAL_BLACK_X; D50BlackPoint.Y = PERCEPTUAL_BLACK_Y; D50BlackPoint.Z = PERCEPTUAL_BLACK_Z; + + // Obtain the absolute XYZ. Adapt perceptual black back from D50 to whatever media white cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &D50BlackPoint); } @@ -662,26 +652,24 @@ // This function shouldn't exist at all -- there is such quantity of broken // profiles on black point tag, that we must somehow fix chromaticity to // avoid huge tint when doing Black point compensation. This function does -// just that. If BP is specified, then forces it to neutral and uses only L -// component. If does not exist, computes it by taking 400% of ink or RGB=0 This -// works well on relative intent and is undefined on perceptual & saturation. -// However, I will support all intents for tricking & trapping. - +// just that. There is a special flag for using black point tag, but turned +// off by default because it is bogus on most profiles. The detection algorithm +// involves to turn BP to neutral and to use only L component. int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent, DWORD dwFlags) { - // v4 + perceptual & saturation intents does have its own black point + // v4 + perceptual & saturation intents does have its own black point, and it is + // well specified enough to use it. if ((cmsGetProfileICCversion(hProfile) >= 0x4000000) && (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) { // Matrix shaper share MRC & perceptual intents - if (_cmsIsMatrixShaper(hProfile)) return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, cmsFLAGS_NOTPRECALC); - // Get fixed value + // CLUT based - Get perceptual black point (fixed value) return GetV4PerceptualBlack(BlackPoint, hProfile, dwFlags); } @@ -701,7 +689,6 @@ cmsTakeMediaWhitePoint(&MediaWhite, hProfile); // Black point is absolute XYZ, so adapt to D50 to get PCS value - cmsAdaptToIlluminant(&UntrustedBlackPoint, &MediaWhite, cmsD50_XYZ(), &BlackXYZ); // Force a=b=0 to get rid of any chroma @@ -713,7 +700,6 @@ cmsLab2XYZ(NULL, &TrustedBlackPoint, &Lab); // Return BP as D50 relative or absolute XYZ (depends on flags) - if (!(dwFlags & LCMS_BPFLAGS_D50_ADAPTED)) cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &TrustedBlackPoint); else @@ -724,15 +710,15 @@ #endif - // If output profile, discount ink-limiting + // That is about v2 profiles. + // If output profile, discount ink-limiting and that's all if (Intent == INTENT_RELATIVE_COLORIMETRIC && (cmsGetDeviceClass(hProfile) == icSigOutputClass) && (cmsGetColorSpace(hProfile) == icSigCmykData)) return BlackPointUsingPerceptualBlack(BlackPoint, hProfile, dwFlags); // Nope, compute BP using current intent. - return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags); } diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -52,7 +52,6 @@ #include "lcms.h" -// #define DEBUG 1 // Transformations stuff // ----------------------------------------------------------------------- @@ -85,7 +84,7 @@ void LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b); void LCMSEXPORT cmsSetAlarmCodes(int r, int g, int b); -BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, +LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection); // ------------------------------------------------------------------------- @@ -343,7 +342,7 @@ p ->DeviceLink ->CLut16params.Interp3D(wIn, wOut, p ->DeviceLink -> T, &p ->DeviceLink -> CLut16params); - } + } else cmsEvalLUT(p -> DeviceLink, wIn, wOut); @@ -414,7 +413,7 @@ register LPBYTE output; WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS]; register unsigned int i, n; - WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS]; + WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS]; accum = (LPBYTE) in; @@ -427,10 +426,10 @@ ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS); - LCMS_READ_LOCK(&p ->rwlock); - CopyMemory(CacheIn, p ->CacheIn, sizeof(WORD) * MAXCHANNELS); - CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS); - LCMS_UNLOCK(&p ->rwlock); + LCMS_READ_LOCK(&p ->rwlock); + CopyMemory(CacheIn, p ->CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); for (i=0; i < n; i++) { @@ -443,14 +442,14 @@ } else { - // Try to speedup things on plain devicelinks - - if (p ->DeviceLink ->wFlags == LUT_HAS3DGRID) { + // Try to speedup things on plain devicelinks + + if (p ->DeviceLink ->wFlags == LUT_HAS3DGRID) { p ->DeviceLink ->CLut16params.Interp3D(wIn, wOut, p ->DeviceLink -> T, &p ->DeviceLink -> CLut16params); - } + } else cmsEvalLUT(p -> DeviceLink, wIn, wOut); @@ -463,10 +462,10 @@ } - LCMS_WRITE_LOCK(&p ->rwlock); - CopyMemory(p->CacheIn, CacheIn, sizeof(WORD) * MAXCHANNELS); - CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS); - LCMS_UNLOCK(&p ->rwlock); + LCMS_WRITE_LOCK(&p ->rwlock); + CopyMemory(p->CacheIn, CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); } @@ -483,7 +482,7 @@ register LPBYTE output; WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS]; register unsigned int i, n; - WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS]; + WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS]; accum = (LPBYTE) in; @@ -495,10 +494,10 @@ ZeroMemory(wIn, sizeof(WORD) * MAXCHANNELS); ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS); - LCMS_READ_LOCK(&p ->rwlock); - CopyMemory(CacheIn, p ->CacheIn, sizeof(WORD) * MAXCHANNELS); - CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS); - LCMS_UNLOCK(&p ->rwlock); + LCMS_READ_LOCK(&p ->rwlock); + CopyMemory(CacheIn, p ->CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); for (i=0; i < n; i++) { @@ -520,10 +519,10 @@ output = p -> ToOutput(p, wOut, output); } - LCMS_WRITE_LOCK(&p ->rwlock); - CopyMemory(p->CacheIn, CacheIn, sizeof(WORD) * MAXCHANNELS); - CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS); - LCMS_UNLOCK(&p ->rwlock); + LCMS_WRITE_LOCK(&p ->rwlock); + CopyMemory(p->CacheIn, CacheIn, sizeof(WORD) * MAXCHANNELS); + CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS); + LCMS_UNLOCK(&p ->rwlock); } @@ -635,6 +634,8 @@ MAT3 Scale; GrayTRC = cmsReadICCGamma(hProfile, icSigGrayTRCTag); // Y + if (GrayTRC == NULL) return NULL; + cmsTakeIluminant(&Illuminant, hProfile); if (cmsGetPCS(hProfile) == icSigLabData) { @@ -789,6 +790,10 @@ InverseShapes[1] = cmsReadICCGammaReversed(OutputProfile, icSigGreenTRCTag); InverseShapes[2] = cmsReadICCGammaReversed(OutputProfile, icSigBlueTRCTag); + if (InverseShapes[0] == NULL || + InverseShapes[1] == NULL || + InverseShapes[2] == NULL) return NULL; + OutMatSh = cmsAllocMatShaper(&DoubleInv, InverseShapes, MATSHAPER_OUTPUT); cmsFreeGammaTriple(InverseShapes); @@ -801,7 +806,7 @@ // This function builds a transform matrix chaining parameters static -BOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) +LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p) { MAT3 From, To, ToInv, Transfer; LPGAMMATABLE In[3], InverseOut[3]; @@ -814,7 +819,6 @@ if (!cmsReadICCMatrixRGB2XYZ(&To, p -> OutputProfile)) return FALSE; - // invert dest if (MAT3inverse(&To, &ToInv) < 0) @@ -838,10 +842,14 @@ InverseOut[1] = cmsReadICCGammaReversed(p -> OutputProfile, icSigGreenTRCTag); InverseOut[2] = cmsReadICCGammaReversed(p -> OutputProfile, icSigBlueTRCTag); + if (!InverseOut[0] || !InverseOut[1] || !InverseOut[2]) { + cmsFreeGammaTriple(In); + return FALSE; + } + p -> SmeltMatShaper = cmsAllocMatShaper2(&Transfer, In, InverseOut, MATSHAPER_ALLSMELTED); cmsFreeGammaTriple(In); - cmsFreeGammaTriple(InverseOut); return (p -> SmeltMatShaper != NULL); @@ -1029,7 +1037,7 @@ // Check colorspace static -BOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, BOOL lUsePCS) +LCMSBOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, LCMSBOOL lUsePCS) { int Space = T_COLORSPACE(dwFormat); @@ -1049,10 +1057,10 @@ { // Allocate needed memory - _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) malloc(sizeof(_cmsTRANSFORM)); + _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) _cmsMalloc(sizeof(_cmsTRANSFORM)); if (!p) { - cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: malloc() failed"); + cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: _cmsMalloc() failed"); return NULL; } @@ -1078,7 +1086,7 @@ p -> ExitColorSpace = (icColorSpaceSignature) 0; p -> AdaptationState = GlobalAdaptationState; - LCMS_CREATE_LOCK(&p->rwlock); + LCMS_CREATE_LOCK(&p->rwlock); return p; } @@ -1269,12 +1277,12 @@ else { // Can we optimize matrix-shaper only transform? - if (*FromTagPtr == 0 && - *ToTagPtr == 0 && - !p->PreviewProfile && - p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC && + if ((*FromTagPtr == 0) && + (*ToTagPtr == 0) && + (!p->PreviewProfile) && + (p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC) && (p -> EntryColorSpace == icSigRgbData) && - (p -> ExitColorSpace == icSigRgbData) && + (p -> ExitColorSpace == icSigRgbData) && !(p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)) { // Yes... try to smelt matrix-shapers @@ -1530,7 +1538,6 @@ TakeConversionRoutines(p, dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); - if (!(p -> dwOriginalFlags & cmsFLAGS_NOTPRECALC)) { LPLUT DeviceLink; @@ -1553,7 +1560,8 @@ DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags); } - if (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK) { + // Allow to specify cmsFLAGS_GAMUTCHECK, even if no proofing profile is given + if ((p ->PreviewProfile != NULL) && (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK)) { GamutCheck = _cmsPrecalculateGamutCheck((cmsHTRANSFORM) p); } @@ -1561,7 +1569,6 @@ // If input colorspace is Rgb, Cmy, then use tetrahedral interpolation // for speed reasons (it only works well on spaces on Luma is diagonal, and // not if luma is in separate channel) - if (p ->EntryColorSpace == icSigRgbData || p ->EntryColorSpace == icSigCmyData) { @@ -1663,12 +1670,12 @@ cmsFreeMatShaper(p -> SmeltMatShaper); if (p ->NamedColorList) cmsFreeNamedColorList(p ->NamedColorList); - if (p -> GamutCheck) - cmsFreeLUT(p -> GamutCheck); - - LCMS_FREE_LOCK(&p->rwlock); - - free((void *) p); + if (p -> GamutCheck) + cmsFreeLUT(p -> GamutCheck); + + LCMS_FREE_LOCK(&p->rwlock); + + _cmsFree((void *) p); } @@ -1704,7 +1711,7 @@ // Returns TRUE if the profile is implemented as matrix-shaper -BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile) +LCMSBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile) { switch (cmsGetColorSpace(hProfile)) { @@ -1728,7 +1735,7 @@ } -BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, +LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection) { @@ -1774,6 +1781,16 @@ } +static +int IsAllowedInSingleXform(icProfileClassSignature aClass) +{ + return (aClass == icSigInputClass) || + (aClass == icSigDisplayClass) || + (aClass == icSigOutputClass) || + (aClass == icSigColorSpaceClass); +} + + // A multiprofile transform does chain several profiles into a single // devicelink. It couls also be used to merge named color profiles into // a single database. @@ -1805,10 +1822,16 @@ // There is a simple case with just two profiles, try to catch it in order of getting // black preservation to work on this function, at least with two profiles. + if (nProfiles == 2) { - if ((cmsGetDeviceClass(hProfiles[0]) != icSigLinkClass) && - (cmsGetDeviceClass(hProfiles[1]) != icSigLinkClass)) + icProfileClassSignature Class1 = cmsGetDeviceClass(hProfiles[0]); + icProfileClassSignature Class2 = cmsGetDeviceClass(hProfiles[1]); + + // Only input, output and display are allowed + + if (IsAllowedInSingleXform(Class1) && + IsAllowedInSingleXform(Class2)) return cmsCreateTransform(hProfiles[0], dwInput, hProfiles[1], dwOutput, Intent, dwFlags); } @@ -1984,6 +2007,14 @@ if (hLab) cmsCloseProfile(hLab); if (hXYZ) cmsCloseProfile(hXYZ); + + if (p ->EntryColorSpace == icSigRgbData || + p ->EntryColorSpace == icSigCmyData) { + + p->DeviceLink -> CLut16params.Interp3D = cmsTetrahedralInterp16; + } + + if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) && !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP)) _cmsFixWhiteMisalignment(p); diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h --- a/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h Tue Mar 24 19:12:02 2009 -0700 @@ -206,6 +206,11 @@ #if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__) +#if defined (__MINGW) || defined(__MINGW32__) +#include +#endif + + typedef uint8_t icUInt8Number; typedef uint16_t icUInt16Number; typedef uint32_t icUInt32Number; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h --- a/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h Tue Mar 24 19:12:02 2009 -0700 @@ -29,7 +29,7 @@ // // // Little cms -// Copyright (C) 1998-2006 Marti Maria +// Copyright (C) 1998-2007 Marti Maria // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -49,8 +49,8 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// Version 1.16 -#undef DEBUG +// Version 1.18 + #ifndef __cms_H // ********** Configuration toggles **************************************** @@ -62,13 +62,8 @@ // virtually any machine. //#define USE_FLOAT 1 -#ifdef _WIN64 -#define USE_C 1 -#undef USE_ASSEMBLER -#else -#undef USE_C +// #define USE_C 1 #define USE_ASSEMBLER 1 -#endif // Define this if you are using this package as a DLL (windows only) @@ -77,15 +72,11 @@ // Uncomment if you are trying the engine in a non-windows environment // like linux, SGI, VAX, FreeBSD, BeOS, etc. -#if !defined(_WIN32) || !defined(_WIN64) #define NON_WINDOWS 1 -#endif // Uncomment this one if you are using big endian machines (only meaningful // when NON_WINDOWS is used) -#ifndef _LITTLE_ENDIAN -#define USE_BIG_ENDIAN 1 -#endif +// #define USE_BIG_ENDIAN 1 // Uncomment this one if your compiler/machine does support the // "long long" type This will speedup fixed point math. (USE_C only) @@ -104,18 +95,24 @@ // Uncomment this line on multithreading environments // #define USE_PTHREADS 1 +// Uncomment this line if you want lcms to use the black point tag in profile, +// if commented, lcms will compute the black point by its own. +// It is safer to leve it commented out +// #define HONOR_BLACK_POINT_TAG 1 + // ********** End of configuration toggles ****************************** -#define LCMS_VERSION 116 +#define LCMS_VERSION 118 // Microsoft VisualC++ // Deal with Microsoft's attempt at deprecating C standard runtime functions - #ifdef _MSC_VER # undef NON_WINDOWS # if (_MSC_VER >= 1400) +# ifndef _CRT_SECURE_NO_DEPRECATE # define _CRT_SECURE_NO_DEPRECATE 1 +# endif # endif #endif @@ -125,7 +122,6 @@ # undef NON_WINDOWS #endif - #include #include #include @@ -134,11 +130,11 @@ #include // Metroworks CodeWarrior - #ifdef __MWERKS__ # define unlink remove # if WIN32 # define USE_CUSTOM_SWAB 1 +# undef NON_WINDOWS # else # define NON_WINDOWS 1 # endif @@ -172,15 +168,21 @@ # define USE_BIG_ENDIAN 1 #endif -#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) || defined(__ppc__) +#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) || defined(__ppc__) || defined(__s390__) || defined(__s390x__) # define USE_BIG_ENDIAN 1 #endif -#ifdef TARGET_CPU_PPC +#if TARGET_CPU_PPC # define USE_BIG_ENDIAN 1 #endif -#ifdef macintosh +#if macintosh +# ifndef __LITTLE_ENDIAN__ +# define USE_BIG_ENDIAN 1 +# endif +#endif + +#ifdef __BIG_ENDIAN__ # define USE_BIG_ENDIAN 1 #endif @@ -217,11 +219,8 @@ typedef unsigned char BYTE, *LPBYTE; typedef unsigned short WORD, *LPWORD; typedef unsigned long DWORD, *LPDWORD; -typedef int BOOL; typedef char *LPSTR; typedef void *LPVOID; -typedef void* LCMSHANDLE; - #define ZeroMemory(p,l) memset((p),0,(l)) #define CopyMemory(d,s,l) memcpy((d),(s),(l)) @@ -263,8 +262,12 @@ #include -typedef HANDLE LCMSHANDLE; - +#ifdef _WIN64 +# ifdef USE_ASSEMBLER +# undef USE_ASSEMBLER +# define USE_C 1 +# endif +#endif #ifdef USE_INT64 # ifndef LCMSULONGLONG @@ -296,6 +299,10 @@ # define LCMS_UNLOCK(x) #endif +// Base types + +typedef int LCMSBOOL; +typedef void* LCMSHANDLE; #include "icc34.h" // ICC header file @@ -322,16 +329,10 @@ #define icSigMCHEData ((icColorSpaceSignature) 0x4d434845L) // MCHE #define icSigMCHFData ((icColorSpaceSignature) 0x4d434846L) // MCHF -#define icSigCAM97JABData ((icColorSpaceSignature) 0x4A616231L) // 'Jab1' H. Zeng -#define icSigCAM02JABData ((icColorSpaceSignature) 0x4A616232L) // 'Jab2' H. Zeng -#define icSigCAM02JCHData ((icColorSpaceSignature) 0x4A636A32L) // 'Jch2' H. Zeng - #define icSigChromaticityTag ((icTagSignature) 0x6368726dL) // As per Addendum 2 to Spec. ICC.1:1998-09 #define icSigChromaticAdaptationTag ((icTagSignature) 0x63686164L) // 'chad' #define icSigColorantTableTag ((icTagSignature) 0x636c7274L) // 'clrt' #define icSigColorantTableOutTag ((icTagSignature) 0x636c6f74L) // 'clot' -#define icSigHPGamutDescTag ((icTagSignature) 0x676D7441L) // 'gmtA' H. Zeng - #define icSigParametricCurveType ((icTagTypeSignature) 0x70617261L) // parametric (ICC 4.0) #define icSigMultiLocalizedUnicodeType ((icTagTypeSignature) 0x6D6C7563L) @@ -340,7 +341,6 @@ #define icSiglutAtoBType ((icTagTypeSignature) 0x6d414220L) // mAB #define icSiglutBtoAType ((icTagTypeSignature) 0x6d424120L) // mBA #define icSigColorantTableType ((icTagTypeSignature) 0x636c7274L) // clrt -#define icSigHPGamutDescType ((icTagTypeSignature) 0x676D7441L) // gmtA H. Zeng typedef struct { @@ -438,9 +438,6 @@ #ifndef itoa # define itoa _itoa #endif -#ifndef filelength -# define filelength _filelength -#endif #ifndef fileno # define fileno _fileno #endif @@ -450,6 +447,14 @@ #ifndef hypot # define hypot _hypot #endif +#ifndef snprintf +# define snprintf _snprintf +#endif +#ifndef vsnprintf +# define vsnprintf _vsnprintf +#endif + + #endif @@ -470,8 +475,9 @@ // Format of pixel is defined by one DWORD, using bit fields as follows // -// TTTTT U Y F P X S EEE CCCC BBB +// D TTTTT U Y F P X S EEE CCCC BBB // +// D: Use dither (8 bits only) // T: Pixeltype // F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla) // P: Planar? 0=Chunky, 1=Planar @@ -483,6 +489,7 @@ // Y: Swap first - changes ABGR to BGRA and KCMY to CMYK +#define DITHER_SH(s) ((s) << 22) #define COLORSPACE_SH(s) ((s) << 16) #define SWAPFIRST_SH(s) ((s) << 14) #define FLAVOR_SH(s) ((s) << 13) @@ -711,20 +718,20 @@ typedef struct { - unsigned int Crc32; // Has my table been touched? - - // Keep initial parameters for further serialization + unsigned int Crc32; // Has my table been touched? + + // Keep initial parameters for further serialization int Type; double Params[10]; - } LCMSGAMMAPARAMS, FAR* LPLCMSGAMMAPARAMS; + } LCMSGAMMAPARAMS, FAR* LPLCMSGAMMAPARAMS; // Gamma tables. typedef struct { - LCMSGAMMAPARAMS Seed; // Parameters used for table creation + LCMSGAMMAPARAMS Seed; // Parameters used for table creation // Table-based representation follows @@ -858,7 +865,7 @@ LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess); LCMSAPI cmsHPROFILE LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize); -LCMSAPI BOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile); +LCMSAPI LCMSBOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile); // Predefined run-time profiles @@ -915,14 +922,14 @@ LCMSAPI void LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin, double bmax, double bmin); -LCMSAPI BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint); - -LCMSAPI BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, +LCMSAPI LCMSBOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint); + +LCMSAPI LCMSBOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result, LPcmsCIEXYZ SourceWhitePt, LPcmsCIEXYZ Illuminant, LPcmsCIEXYZ Value); -LCMSAPI BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, +LCMSAPI LCMSBOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePoint, LPcmsCIExyYTRIPLE Primaries); @@ -976,7 +983,7 @@ LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma); LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma); LCMSAPI LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints); -LCMSAPI BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda); +LCMSAPI LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda); LCMSAPI double LCMSEXPORT cmsEstimateGamma(LPGAMMATABLE t); LCMSAPI double LCMSEXPORT cmsEstimateGammaEx(LPWORD Table, int nEntries, double Thereshold); LCMSAPI LPGAMMATABLE LCMSEXPORT cmsReadICCGamma(cmsHPROFILE hProfile, icTagSignature sig); @@ -984,14 +991,14 @@ // Access to Profile data. -LCMSAPI BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); -LCMSAPI BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); -LCMSAPI BOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); -LCMSAPI BOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile); +LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); +LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); +LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile); +LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile); LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderFlags(cmsHPROFILE hProfile); LCMSAPI DWORD LCMSEXPORT cmsTakeHeaderAttributes(cmsHPROFILE hProfile); -LCMSAPI void LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode); +LCMSAPI void LCMSEXPORT cmsSetLanguage(const char LanguageCode[4], const char CountryCode[4]); LCMSAPI const char* LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile); LCMSAPI const char* LCMSEXPORT cmsTakeProductDesc(cmsHPROFILE hProfile); LCMSAPI const char* LCMSEXPORT cmsTakeProductInfo(cmsHPROFILE hProfile); @@ -1000,13 +1007,13 @@ LCMSAPI const char* LCMSEXPORT cmsTakeCopyright(cmsHPROFILE hProfile); LCMSAPI const BYTE* LCMSEXPORT cmsTakeProfileID(cmsHPROFILE hProfile); -LCMSAPI BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile); -LCMSAPI BOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile); - -LCMSAPI BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig); +LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile); +LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile); + +LCMSAPI LCMSBOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig); LCMSAPI int LCMSEXPORT cmsTakeRenderingIntent(cmsHPROFILE hProfile); -LCMSAPI BOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len); +LCMSAPI LCMSBOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len); LCMSAPI int LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Text, size_t size); LCMSAPI int LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Text); @@ -1038,50 +1045,18 @@ LCMSAPI void LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq); -// Extended gamut tag -- an HP extension - -#define LCMSGAMUTMETHOD_SEGMENTMAXIMA 0 -#define LCMSGAMUTMETHOD_CONVEXHULL 1 -#define LCMSGAMUTMETHOD_ALPHASHAPE 2 - - -#define LCMSGAMUT_PHYSICAL 0 -#define LCMSGAMUT_HP1 1 -#define LCMSGAMUT_HP2 2 - -typedef struct { - - icColorSpaceSignature CoordSig; // Gamut coordinates signature - icUInt16Number Method; // Method used to generate gamut - icUInt16Number Usage; // Gamut usage or intent - - char Description[LCMS_DESC_MAX]; // Textual description - - cmsViewingConditions Vc; // The viewing conditions - - icUInt32Number Count; // Number of entries - double Data[1]; // The current data - - } cmsGAMUTEX, FAR* LPcmsGAMUTEX; - - -LCMSAPI LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index); -LCMSAPI void LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex); - - - - // Translate form/to our notation to ICC LCMSAPI icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation); -LCMSAPI int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace); -LCMSAPI int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace); -LCMSAPI BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile); - +LCMSAPI int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace); +LCMSAPI int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile); + +// How profiles may be used #define LCMS_USED_AS_INPUT 0 #define LCMS_USED_AS_OUTPUT 1 #define LCMS_USED_AS_PROOF 2 -LCMSAPI BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection); LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetPCS(cmsHPROFILE hProfile); LCMSAPI icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile); @@ -1141,7 +1116,7 @@ // CRD special -#define cmsFLAGS_NODEFAULTRESOURCEDEF 0x00010000 +#define cmsFLAGS_NODEFAULTRESOURCEDEF 0x01000000 // Gridpoints @@ -1220,9 +1195,9 @@ // Named color support -LCMSAPI int LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform); -LCMSAPI BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix); -LCMSAPI int LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name); +LCMSAPI int LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform); +LCMSAPI LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix); +LCMSAPI int LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name); // Colorant tables @@ -1230,7 +1205,7 @@ // Profile creation -LCMSAPI BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data); +LCMSAPI LCMSBOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data); // Converts a transform to a devicelink profile LCMSAPI cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD dwFlags); @@ -1240,8 +1215,8 @@ // Save profile -LCMSAPI BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName); -LCMSAPI BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, +LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr, size_t* BytesNeeded); @@ -1286,6 +1261,7 @@ LCMSAPI LPLUT LCMSEXPORT cmsReadICCLut(cmsHPROFILE hProfile, icTagSignature sig); LCMSAPI LPLUT LCMSEXPORT cmsDupLUT(LPLUT Orig); + // LUT Sampling typedef int (* _cmsSAMPLER)(register WORD In[], @@ -1325,35 +1301,37 @@ // Persistence LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName); LCMSAPI LCMSHANDLE LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len); -LCMSAPI BOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName); -LCMSAPI BOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded); // Properties LCMSAPI const char* LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type); - -LCMSAPI BOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment); - -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val); - -LCMSAPI BOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type); + +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment); + +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char* cSubProp, const char *Val); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer); LCMSAPI const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp); LCMSAPI double LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp); -LCMSAPI int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames); +LCMSAPI const char* LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char *cSubProp); +LCMSAPI int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, const char ***PropertyNames); +LCMSAPI int LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char*** SubpropertyNames); // Datasets LCMSAPI const char* LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col); LCMSAPI double LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int row, int col); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val); LCMSAPI const char* LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample); @@ -1361,25 +1339,28 @@ LCMSAPI double LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample, const char *Val); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch, const char* cSample, double Val); LCMSAPI int LCMSEXPORT cmsIT8GetDataFormat(LCMSHANDLE hIT8, const char* cSample); -LCMSAPI BOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample); LCMSAPI int LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames); LCMSAPI const char* LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer); +LCMSAPI int LCMSEXPORT cmsIT8GetPatchByName(LCMSHANDLE hIT8, const char *cSample); // The LABEL extension LCMSAPI int LCMSEXPORT cmsIT8SetTableByLabel(LCMSHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType); +LCMSAPI LCMSBOOL LCMSEXPORT cmsIT8SetIndexColumn(LCMSHANDLE hIT8, const char* cSample); + // Formatter for double LCMSAPI void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter); @@ -1405,15 +1386,16 @@ // Profiling Extensions --- Would be removed from API in future revisions -LCMSAPI BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text); -LCMSAPI BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ); -LCMSAPI BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut); -LCMSAPI BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction); -LCMSAPI BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm); -LCMSAPI BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq); -LCMSAPI BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); -LCMSAPI BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime); -LCMSAPI BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc); +LCMSAPI LCMSBOOL LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat); // --------------------------------------------------------------------------------------------------- Inline functions @@ -1455,6 +1437,38 @@ return (WORD) in; } +#ifndef LCMS_USER_ALLOC + +// Low-level alloc hook + +LCMS_INLINE void* _cmsMalloc(size_t size) +{ + if (size > ((size_t) 1024*1024*500)) return NULL; // Never allow over 500Mb + if (size < 0) return NULL; // Prevent signed size_t exploits + + return (void*) malloc(size); +} + +LCMS_INLINE void* _cmsCalloc(size_t nmemb, size_t size) +{ + size_t alloc = nmemb * size; + + if (size == 0) { + return _cmsMalloc(0); + } + if (alloc / size != nmemb) { + return NULL; + } + return _cmsMalloc(alloc); +} + +LCMS_INLINE void _cmsFree(void *Ptr) +{ + if (Ptr) free(Ptr); +} + +#endif + // ------------------------------------------------------------------------------------------- end of inline functions // Signal error from inside lcms code @@ -1531,36 +1545,36 @@ -void cdecl VEC3init(LPVEC3 r, double x, double y, double z); // double version -void cdecl VEC3initF(LPWVEC3 r, double x, double y, double z); // Fix32 version -void cdecl VEC3toFix(LPWVEC3 r, LPVEC3 v); -void cdecl VEC3fromFix(LPVEC3 r, LPWVEC3 v); -void cdecl VEC3scaleFix(LPWORD r, LPWVEC3 Scale); -void cdecl VEC3swap(LPVEC3 a, LPVEC3 b); -void cdecl VEC3divK(LPVEC3 r, LPVEC3 v, double d); -void cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d); -void cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b); -void cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b); -BOOL cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance); -BOOL cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance); -void cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d); -void cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v); -void cdecl VEC3saturate(LPVEC3 v); -double cdecl VEC3distance(LPVEC3 a, LPVEC3 b); -double cdecl VEC3length(LPVEC3 a); - -void cdecl MAT3identity(LPMAT3 a); -void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b); -void cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d); -int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b); -BOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b); -double cdecl MAT3det(LPMAT3 m); -void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v); -void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v); -void cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v); -void cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v); -BOOL cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance); -void cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d); +void cdecl VEC3init(LPVEC3 r, double x, double y, double z); // double version +void cdecl VEC3initF(LPWVEC3 r, double x, double y, double z); // Fix32 version +void cdecl VEC3toFix(LPWVEC3 r, LPVEC3 v); +void cdecl VEC3fromFix(LPVEC3 r, LPWVEC3 v); +void cdecl VEC3scaleFix(LPWORD r, LPWVEC3 Scale); +void cdecl VEC3swap(LPVEC3 a, LPVEC3 b); +void cdecl VEC3divK(LPVEC3 r, LPVEC3 v, double d); +void cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d); +void cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b); +void cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b); +LCMSBOOL cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance); +LCMSBOOL cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance); +void cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d); +void cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v); +void cdecl VEC3saturate(LPVEC3 v); +double cdecl VEC3distance(LPVEC3 a, LPVEC3 b); +double cdecl VEC3length(LPVEC3 a); + +void cdecl MAT3identity(LPMAT3 a); +void cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b); +void cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d); +int cdecl MAT3inverse(LPMAT3 a, LPMAT3 b); +LCMSBOOL cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b); +double cdecl MAT3det(LPMAT3 m); +void cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v); +void cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v); +void cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v); +void cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v); +LCMSBOOL cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance); +void cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d); // Is a table linear? @@ -1608,7 +1622,7 @@ void cdecl cmsCalcL16Params(int nSamples, LPL16PARAMS p); void cdecl cmsCalcCLUT16Params(int nSamples, int InputChan, int OutputChan, LPL16PARAMS p); void cdecl cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan, - BOOL lUseTetrahedral, LPL16PARAMS p); + LCMSBOOL lUseTetrahedral, LPL16PARAMS p); WORD cdecl cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p); Fixed32 cdecl cmsLinearInterpFixed(WORD Value1, WORD LutTable[], LPL16PARAMS p); @@ -1692,18 +1706,18 @@ // Gray axes fixup. Only on v2 8-bit Lab LUT - BOOL FixGrayAxes; - - - // Parameters used for curve creation - - LCMSGAMMAPARAMS LCurvesSeed[4][MAXCHANNELS]; + LCMSBOOL FixGrayAxes; + + + // Parameters used for curve creation + + LCMSGAMMAPARAMS LCurvesSeed[4][MAXCHANNELS]; }; // LUT, FAR* LPLUT; -BOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries); +LCMSBOOL cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries); // CRC of gamma tables @@ -1721,7 +1735,7 @@ void cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max); void cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max); -BOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda); +LCMSBOOL cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda); void cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints); LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints); @@ -1755,19 +1769,19 @@ void cdecl cmsFreeMatShaper(LPMATSHAPER MatShaper); void cdecl cmsEvalMatShaper(LPMATSHAPER MatShaper, WORD In[], WORD Out[]); -BOOL cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile); - -LPMATSHAPER cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile); -LPMATSHAPER cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile); +LCMSBOOL cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile); + +LPMATSHAPER cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile); +LPMATSHAPER cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile); // White Point & Primary chromas handling -BOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll); -BOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt); -BOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt); - -BOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile); +LCMSBOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll); +LCMSBOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt); +LCMSBOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt); + +LCMSBOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile); // Inter-PCS conversion routines. They assume D50 as white point. void cdecl cmsXYZ2LabEncoded(WORD XYZ[3], WORD Lab[3]); @@ -1782,7 +1796,7 @@ LPcmsNAMEDCOLORLIST cdecl cmsAllocNamedColorList(int n); int cdecl cmsReadICCnamedColorList(cmsHTRANSFORM xform, cmsHPROFILE hProfile, icTagSignature sig); void cdecl cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST List); -BOOL cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]); +LCMSBOOL cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]); // I/O @@ -1804,7 +1818,7 @@ icColorSpaceSignature PCS; icRenderingIntent RenderingIntent; icUInt32Number flags; - icUInt32Number attributes; + icUInt32Number attributes; cmsCIEXYZ Illuminant; // Additions for V4 profiles @@ -1826,22 +1840,23 @@ char PhysicalFile[MAX_PATH]; - BOOL IsWrite; - BOOL SaveAs8Bits; + LCMSBOOL IsWrite; + LCMSBOOL SaveAs8Bits; struct tm Created; // I/O handlers - size_t (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc); - - BOOL (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset); - BOOL (* Close)(struct _lcms_iccprofile_struct* Icc); - size_t (* Tell)(struct _lcms_iccprofile_struct* Icc); + size_t (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc); + + LCMSBOOL (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset); + LCMSBOOL (* Close)(struct _lcms_iccprofile_struct* Icc); + size_t (* Tell)(struct _lcms_iccprofile_struct* Icc); + LCMSBOOL (* Grow)(struct _lcms_iccprofile_struct* Icc, size_t amount); // Writting - BOOL (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr); + LCMSBOOL (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr); size_t UsedSpace; @@ -1853,7 +1868,7 @@ cmsHPROFILE cdecl _cmsCreateProfilePlaceholder(void); // Search into tag dictionary -icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError); +icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError); // Search for a particular tag, replace if found or add new one else LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init); @@ -1869,6 +1884,7 @@ // These macros unpack format specifiers into integers +#define T_DITHER(s) (((s)>>22)&1) #define T_COLORSPACE(s) (((s)>>16)&31) #define T_SWAPFIRST(s) (((s)>>14)&1) #define T_FLAVOR(s) (((s)>>13)&1) @@ -1965,7 +1981,7 @@ // Flag for transform involving v4 profiles - BOOL lInputV4Lab, lOutputV4Lab; + LCMSBOOL lInputV4Lab, lOutputV4Lab; // 1-pixel cache @@ -1975,7 +1991,7 @@ double AdaptationState; // Figure for v4 incomplete state of adaptation - LCMS_RWLOCK_T rwlock; + LCMS_RWLOCK_T rwlock; } _cmsTRANSFORM,FAR *_LPcmsTRANSFORM; @@ -2012,7 +2028,7 @@ // Clamping & Gamut handling -BOOL cdecl _cmsEndPointsBySpace(icColorSpaceSignature Space, +LCMSBOOL cdecl _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black, int *nOutputs); WORD * cdecl _cmsWhiteBySpace(icColorSpaceSignature Space); @@ -2041,7 +2057,7 @@ LPLUT cdecl _cmsPrecalculateGamutCheck(cmsHTRANSFORM h); // Hot fixes bad profiles -BOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p); +LCMSBOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p); // Marks LUT as 8 bit on input LPLUT cdecl _cmsBlessLUT8(LPLUT Lut); @@ -2059,6 +2075,10 @@ // Build a tone curve for K->K' if possible (only works on CMYK) LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints); +// Validates a LUT +LCMSBOOL cdecl _cmsValidateLUT(LPLUT NewLUT); + + // These are two VITAL macros, from converting between 8 and 16 bit // representation. @@ -2076,3 +2096,4 @@ #endif #endif + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/solaris/classes/sun/awt/X11/XFontPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XFontPeer.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/solaris/classes/sun/awt/X11/XFontPeer.java Tue Mar 24 19:12:02 2009 -0700 @@ -27,9 +27,6 @@ import sun.awt.PlatformFont; import java.awt.GraphicsEnvironment; -/* FIX ME */ -import sun.awt.motif.MFontConfiguration; - public class XFontPeer extends PlatformFont { /* @@ -51,10 +48,6 @@ public XFontPeer(String name, int style){ super(name, style); - - if (fontConfig != null){ - xfsname = ((MFontConfiguration) fontConfig).getMotifFontSet(familyName, style); - } } protected char getMissingGlyphCharacter() { diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/solaris/classes/sun/font/FcFontConfiguration.java --- a/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java Tue Mar 24 19:12:02 2009 -0700 @@ -15,7 +15,7 @@ * accompanied this code). * * You should have received a copy of the GNU General Public License version - * along with this work; if not, write to the Free Software Foundation, + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, @@ -87,6 +87,7 @@ return true; } + setFontConfiguration(); readFcInfo(); if (fcCompFonts == null) { fcCompFonts = FontManager.loadFontConfig(); @@ -172,7 +173,7 @@ @Override public FontDescriptor[] getFontDescriptors(String fontName, int style) { - throw new InternalError("Not implemented"); + return new FontDescriptor[0]; } @Override diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/solaris/classes/sun/print/IPPPrintService.java --- a/jdk/src/solaris/classes/sun/print/IPPPrintService.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/solaris/classes/sun/print/IPPPrintService.java Tue Mar 24 19:12:02 2009 -0700 @@ -661,6 +661,12 @@ } } } else if (category == OrientationRequested.class) { + if (flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) || + flavor.equals(DocFlavor.URL.POSTSCRIPT) || + flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT)) { + return null; + } + boolean revPort = false; OrientationRequested[] orientSup = null; diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/solaris/classes/sun/print/UnixPrintJob.java --- a/jdk/src/solaris/classes/sun/print/UnixPrintJob.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/solaris/classes/sun/print/UnixPrintJob.java Tue Mar 24 19:12:02 2009 -0700 @@ -362,10 +362,10 @@ mOptions += " number-up="+nUp.getValue(); } - if (orient == OrientationRequested.LANDSCAPE && + if (orient != OrientationRequested.PORTRAIT && (flavor != null) && !flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)) { - mOptions += " landscape"; + mOptions += " orientation-requested="+orient.getValue(); } if (sides != null) { diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/windows/classes/sun/awt/windows/WFontConfiguration.java --- a/jdk/src/windows/classes/sun/awt/windows/WFontConfiguration.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/src/windows/classes/sun/awt/windows/WFontConfiguration.java Tue Mar 24 19:12:02 2009 -0700 @@ -61,18 +61,10 @@ * been opened and its fonts loaded. * Also note this usage is only enabled if a private flag is set. */ - if ("98".equals(osName) || "Me".equals(osName)) { - localeMap.put("dialoginput.plain.japanese", "\uff2d\uff33 \u660e\u671d"); - localeMap.put("dialoginput.bold.japanese", "\uff2d\uff33 \u660e\u671d"); - localeMap.put("dialoginput.italic.japanese", "\uff2d\uff33 \u660e\u671d"); - localeMap.put("dialoginput.bolditalic.japanese", "\uff2d\uff33 \u660e\u671d"); - } else { - - localeMap.put("dialoginput.plain.japanese", "MS Mincho"); - localeMap.put("dialoginput.bold.japanese", "MS Mincho"); - localeMap.put("dialoginput.italic.japanese", "MS Mincho"); - localeMap.put("dialoginput.bolditalic.japanese", "MS Mincho"); - } + localeMap.put("dialoginput.plain.japanese", "MS Mincho"); + localeMap.put("dialoginput.bold.japanese", "MS Mincho"); + localeMap.put("dialoginput.italic.japanese", "MS Mincho"); + localeMap.put("dialoginput.bolditalic.japanese", "MS Mincho"); } reorderMap = new HashMap(); reorderMap.put("UTF-8.hi", "devanagari"); diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/windows/classes/sun/awt/windows/fontconfig.98.properties --- a/jdk/src/windows/classes/sun/awt/windows/fontconfig.98.properties Wed Jul 05 16:49:29 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,241 +0,0 @@ -# -# -# Copyright 2003-2004 Sun Microsystems, Inc. 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. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the LICENSE file that accompanied this code. -# -# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -# CA 95054 USA or visit www.sun.com if you need additional information or -# have any questions. -# - -# Version - -version=1 - -# Component Font Mappings - -allfonts.chinese-ms936=SimSun -allfonts.dingbats=Wingdings -allfonts.lucida=Lucida Sans Regular -allfonts.symbol=Symbol -allfonts.thai=Lucida Sans Regular - -serif.plain.alphabetic=Times New Roman -serif.plain.chinese-ms950=MingLiU -serif.plain.hebrew=David -serif.plain.japanese=\uff2d\uff33 \u660e\u671d -serif.plain.korean=Batang - -serif.bold.alphabetic=Times New Roman Bold -serif.bold.chinese-ms950=PMingLiU -serif.bold.hebrew=David Bold -serif.bold.japanese=\uff2d\uff33 \u660e\u671d -serif.bold.korean=Batang - -serif.italic.alphabetic=Times New Roman Italic -serif.italic.chinese-ms950=PMingLiU -serif.italic.hebrew=David -serif.italic.japanese=\uff2d\uff33 \u660e\u671d -serif.italic.korean=Batang - -serif.bolditalic.alphabetic=Times New Roman Bold Italic -serif.bolditalic.chinese-ms950=PMingLiU -serif.bolditalic.hebrew=David Bold -serif.bolditalic.japanese=\uff2d\uff33 \u660e\u671d -serif.bolditalic.korean=Batang - -sansserif.plain.alphabetic=Arial -sansserif.plain.chinese-ms950=MingLiU -sansserif.plain.hebrew=David -sansserif.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.plain.korean=Gulim - -sansserif.bold.alphabetic=Arial Bold -sansserif.bold.chinese-ms950=PMingLiU -sansserif.bold.hebrew=David Bold -sansserif.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.bold.korean=Gulim - -sansserif.italic.alphabetic=Arial Italic -sansserif.italic.chinese-ms950=PMingLiU -sansserif.italic.hebrew=David -sansserif.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.italic.korean=Gulim - -sansserif.bolditalic.alphabetic=Arial Bold Italic -sansserif.bolditalic.chinese-ms950=PMingLiU -sansserif.bolditalic.hebrew=David Bold -sansserif.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.bolditalic.korean=Gulim - -monospaced.plain.alphabetic=Courier New -monospaced.plain.chinese-ms950=MingLiU -monospaced.plain.hebrew=David -monospaced.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.plain.korean=GulimChe - -monospaced.bold.alphabetic=Courier New Bold -monospaced.bold.chinese-ms950=PMingLiU -monospaced.bold.hebrew=David Bold -monospaced.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.bold.korean=GulimChe - -monospaced.italic.alphabetic=Courier New Italic -monospaced.italic.chinese-ms950=PMingLiU -monospaced.italic.hebrew=David -monospaced.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.italic.korean=GulimChe - -monospaced.bolditalic.alphabetic=Courier New Bold Italic -monospaced.bolditalic.chinese-ms950=PMingLiU -monospaced.bolditalic.hebrew=David Bold -monospaced.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.bolditalic.korean=GulimChe - -dialog.plain.alphabetic=Arial -dialog.plain.chinese-ms950=MingLiU -dialog.plain.hebrew=David -dialog.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.plain.korean=Gulim - -dialog.bold.alphabetic=Arial Bold -dialog.bold.chinese-ms950=PMingLiU -dialog.bold.hebrew=David Bold -dialog.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.bold.korean=Gulim - -dialog.italic.alphabetic=Arial Italic -dialog.italic.chinese-ms950=PMingLiU -dialog.italic.hebrew=David -dialog.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.italic.korean=Gulim - -dialog.bolditalic.alphabetic=Arial Bold Italic -dialog.bolditalic.chinese-ms950=PMingLiU -dialog.bolditalic.hebrew=David Bold -dialog.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.bolditalic.korean=Gulim - -dialoginput.plain.alphabetic=Courier New -dialoginput.plain.chinese-ms950=MingLiU -dialoginput.plain.hebrew=David -dialoginput.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.plain.korean=Gulim - -dialoginput.bold.alphabetic=Courier New Bold -dialoginput.bold.chinese-ms950=PMingLiU -dialoginput.bold.hebrew=David Bold -dialoginput.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.bold.korean=Gulim - -dialoginput.italic.alphabetic=Courier New Italic -dialoginput.italic.chinese-ms950=PMingLiU -dialoginput.italic.hebrew=David -dialoginput.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.italic.korean=Gulim - -dialoginput.bolditalic.alphabetic=Courier New Bold Italic -dialoginput.bolditalic.chinese-ms950=PMingLiU -dialoginput.bolditalic.hebrew=David Bold -dialoginput.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.bolditalic.korean=Gulim - -# Search Sequences - -sequence.allfonts=alphabetic/default,dingbats,symbol - -sequence.serif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol -sequence.sansserif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol -sequence.monospaced.GBK=chinese-ms936,alphabetic/1252,dingbats,symbol -sequence.dialog.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol -sequence.dialoginput.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol - -sequence.serif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol -sequence.sansserif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol -sequence.monospaced.x-windows-950=chinese-ms950,alphabetic/1252,dingbats,symbol -sequence.dialog.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol -sequence.dialoginput.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol - -sequence.allfonts.windows-1255=hebrew,alphabetic/1252,dingbats,symbol - -sequence.serif.windows-31j=alphabetic/1252,japanese,dingbats,symbol -sequence.sansserif.windows-31j=alphabetic/1252,japanese,dingbats,symbol -sequence.monospaced.windows-31j=japanese,alphabetic/1252,dingbats,symbol -sequence.dialog.windows-31j=alphabetic/1252,japanese,dingbats,symbol -sequence.dialoginput.windows-31j=alphabetic/1252,japanese,dingbats,symbol - -sequence.serif.x-windows-949=alphabetic/1252,korean,dingbats,symbol -sequence.sansserif.x-windows-949=alphabetic/1252,korean,dingbats,symbol -sequence.monospaced.x-windows-949=korean,alphabetic/1252,dingbats,symbol -sequence.dialog.x-windows-949=alphabetic/1252,korean,dingbats,symbol -sequence.dialoginput.x-windows-949=alphabetic/1252,korean,dingbats,symbol - -sequence.allfonts.x-windows-874=alphabetic/1252,thai,dingbats,symbol - -sequence.fallback=lucida - -# Exclusion Ranges - -exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff -exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac - -# Monospaced to Proportional width variant mapping -# (Experimental private syntax) -proportional.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=\uff2d\uff33 \uff30\u30b4\u30b7\u30c3\u30af -proportional.\uff2d\uff33_\u660e\u671d=\uff2d\uff33 \uff30\u660e\u671d -proportional.MingLiU=PMingLiU - -# Font File Names - -filename.Arial=ARIAL.TTF -filename.Arial_Bold=ARIALBD.TTF -filename.Arial_Italic=ARIALI.TTF -filename.Arial_Bold_Italic=ARIALBI.TTF - -filename.Courier_New=COUR.TTF -filename.Courier_New_Bold=COURBD.TTF -filename.Courier_New_Italic=COURI.TTF -filename.Courier_New_Bold_Italic=COURBI.TTF - -filename.Times_New_Roman=TIMES.TTF -filename.Times_New_Roman_Bold=TIMESBD.TTF -filename.Times_New_Roman_Italic=TIMESI.TTF -filename.Times_New_Roman_Bold_Italic=TIMESBI.TTF - -filename.SimSun=SIMSUN.TTF - -filename.MingLiU=MINGLIU.TTC -filename.PMingLiU=MINGLIU.TTC - -filename.David=DAVID.TTF -filename.David_Bold=DAVIDBD.TTF - -filename.\uff2d\uff33_\u660e\u671d=MSMINCHO.TTC -filename.\uff2d\uff33_\uff30\u660e\u671d=MSMINCHO.TTC -filename.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC -filename.\uff2d\uff33_\uff30\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC - -filename.Gulim=gulim.TTC -filename.Batang=batang.TTC -filename.GulimChe=gulim.TTC - -filename.Lucida_Sans_Regular=LucidaSansRegular.ttf -filename.Symbol=SYMBOL.TTF -filename.Wingdings=WINGDING.TTF - diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/src/windows/classes/sun/awt/windows/fontconfig.Me.properties --- a/jdk/src/windows/classes/sun/awt/windows/fontconfig.Me.properties Wed Jul 05 16:49:29 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,241 +0,0 @@ -# -# -# Copyright 2003-2004 Sun Microsystems, Inc. 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. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the LICENSE file that accompanied this code. -# -# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -# CA 95054 USA or visit www.sun.com if you need additional information or -# have any questions. -# - -# Version - -version=1 - -# Component Font Mappings - -allfonts.chinese-ms936=SimSun -allfonts.dingbats=Wingdings -allfonts.lucida=Lucida Sans Regular -allfonts.symbol=Symbol -allfonts.thai=Lucida Sans Regular - -serif.plain.alphabetic=Times New Roman -serif.plain.chinese-ms950=MingLiU -serif.plain.hebrew=David -serif.plain.japanese=\uff2d\uff33 \u660e\u671d -serif.plain.korean=Batang - -serif.bold.alphabetic=Times New Roman Bold -serif.bold.chinese-ms950=PMingLiU -serif.bold.hebrew=David Bold -serif.bold.japanese=\uff2d\uff33 \u660e\u671d -serif.bold.korean=Batang - -serif.italic.alphabetic=Times New Roman Italic -serif.italic.chinese-ms950=PMingLiU -serif.italic.hebrew=David -serif.italic.japanese=\uff2d\uff33 \u660e\u671d -serif.italic.korean=Batang - -serif.bolditalic.alphabetic=Times New Roman Bold Italic -serif.bolditalic.chinese-ms950=PMingLiU -serif.bolditalic.hebrew=David Bold -serif.bolditalic.japanese=\uff2d\uff33 \u660e\u671d -serif.bolditalic.korean=Batang - -sansserif.plain.alphabetic=Arial -sansserif.plain.chinese-ms950=MingLiU -sansserif.plain.hebrew=David -sansserif.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.plain.korean=Gulim - -sansserif.bold.alphabetic=Arial Bold -sansserif.bold.chinese-ms950=PMingLiU -sansserif.bold.hebrew=David Bold -sansserif.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.bold.korean=Gulim - -sansserif.italic.alphabetic=Arial Italic -sansserif.italic.chinese-ms950=PMingLiU -sansserif.italic.hebrew=David -sansserif.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.italic.korean=Gulim - -sansserif.bolditalic.alphabetic=Arial Bold Italic -sansserif.bolditalic.chinese-ms950=PMingLiU -sansserif.bolditalic.hebrew=David Bold -sansserif.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -sansserif.bolditalic.korean=Gulim - -monospaced.plain.alphabetic=Courier New -monospaced.plain.chinese-ms950=MingLiU -monospaced.plain.hebrew=David -monospaced.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.plain.korean=GulimChe - -monospaced.bold.alphabetic=Courier New Bold -monospaced.bold.chinese-ms950=PMingLiU -monospaced.bold.hebrew=David Bold -monospaced.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.bold.korean=GulimChe - -monospaced.italic.alphabetic=Courier New Italic -monospaced.italic.chinese-ms950=PMingLiU -monospaced.italic.hebrew=David -monospaced.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.italic.korean=GulimChe - -monospaced.bolditalic.alphabetic=Courier New Bold Italic -monospaced.bolditalic.chinese-ms950=PMingLiU -monospaced.bolditalic.hebrew=David Bold -monospaced.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -monospaced.bolditalic.korean=GulimChe - -dialog.plain.alphabetic=Arial -dialog.plain.chinese-ms950=MingLiU -dialog.plain.hebrew=David -dialog.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.plain.korean=Gulim - -dialog.bold.alphabetic=Arial Bold -dialog.bold.chinese-ms950=PMingLiU -dialog.bold.hebrew=David Bold -dialog.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.bold.korean=Gulim - -dialog.italic.alphabetic=Arial Italic -dialog.italic.chinese-ms950=PMingLiU -dialog.italic.hebrew=David -dialog.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.italic.korean=Gulim - -dialog.bolditalic.alphabetic=Arial Bold Italic -dialog.bolditalic.chinese-ms950=PMingLiU -dialog.bolditalic.hebrew=David Bold -dialog.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialog.bolditalic.korean=Gulim - -dialoginput.plain.alphabetic=Courier New -dialoginput.plain.chinese-ms950=MingLiU -dialoginput.plain.hebrew=David -dialoginput.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.plain.korean=Gulim - -dialoginput.bold.alphabetic=Courier New Bold -dialoginput.bold.chinese-ms950=PMingLiU -dialoginput.bold.hebrew=David Bold -dialoginput.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.bold.korean=Gulim - -dialoginput.italic.alphabetic=Courier New Italic -dialoginput.italic.chinese-ms950=PMingLiU -dialoginput.italic.hebrew=David -dialoginput.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.italic.korean=Gulim - -dialoginput.bolditalic.alphabetic=Courier New Bold Italic -dialoginput.bolditalic.chinese-ms950=PMingLiU -dialoginput.bolditalic.hebrew=David Bold -dialoginput.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af -dialoginput.bolditalic.korean=Gulim - -# Search Sequences - -sequence.allfonts=alphabetic/default,dingbats,symbol - -sequence.serif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol -sequence.sansserif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol -sequence.monospaced.GBK=chinese-ms936,alphabetic/1252,dingbats,symbol -sequence.dialog.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol -sequence.dialoginput.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol - -sequence.serif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol -sequence.sansserif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol -sequence.monospaced.x-windows-950=chinese-ms950,alphabetic/1252,dingbats,symbol -sequence.dialog.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol -sequence.dialoginput.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol - -sequence.allfonts.windows-1255=hebrew,alphabetic/1252,dingbats,symbol - -sequence.serif.windows-31j=alphabetic/1252,japanese,dingbats,symbol -sequence.sansserif.windows-31j=alphabetic/1252,japanese,dingbats,symbol -sequence.monospaced.windows-31j=japanese,alphabetic/1252,dingbats,symbol -sequence.dialog.windows-31j=alphabetic/1252,japanese,dingbats,symbol -sequence.dialoginput.windows-31j=alphabetic/1252,japanese,dingbats,symbol - -sequence.serif.x-windows-949=alphabetic/1252,korean,dingbats,symbol -sequence.sansserif.x-windows-949=alphabetic/1252,korean,dingbats,symbol -sequence.monospaced.x-windows-949=korean,alphabetic/1252,dingbats,symbol -sequence.dialog.x-windows-949=alphabetic/1252,korean,dingbats,symbol -sequence.dialoginput.x-windows-949=alphabetic/1252,korean,dingbats,symbol - -sequence.allfonts.x-windows-874=alphabetic/1252,thai,dingbats,symbol - -sequence.fallback=lucida - -# Exclusion Ranges - -exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff -exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac - -# Monospaced to Proportional width variant mapping -# (Experimental private syntax) -proportional.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=\uff2d\uff33 \uff30\u30b4\u30b7\u30c3\u30af -proportional.\uff2d\uff33_\u660e\u671d=\uff2d\uff33 \uff30\u660e\u671d -proportional.MingLiU=PMingLiU - -# Font File Names - -filename.Arial=ARIAL.TTF -filename.Arial_Bold=ARIALBD.TTF -filename.Arial_Italic=ARIALI.TTF -filename.Arial_Bold_Italic=ARIALBI.TTF - -filename.Courier_New=COUR.TTF -filename.Courier_New_Bold=COURBD.TTF -filename.Courier_New_Italic=COURI.TTF -filename.Courier_New_Bold_Italic=COURBI.TTF - -filename.Times_New_Roman=TIMES.TTF -filename.Times_New_Roman_Bold=TIMESBD.TTF -filename.Times_New_Roman_Italic=TIMESI.TTF -filename.Times_New_Roman_Bold_Italic=TIMESBI.TTF - -filename.SimSun=SIMSUN.TTF - -filename.MingLiU=MINGLIU.TTC -filename.PMingLiU=MINGLIU.TTC - -filename.David=DAVID.TTF -filename.David_Bold=DAVIDBD.TTF - -filename.\uff2d\uff33_\u660e\u671d=MSMINCHO.TTC -filename.\uff2d\uff33_\uff30\u660e\u671d=MSMINCHO.TTC -filename.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC -filename.\uff2d\uff33_\uff30\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC - -filename.Gulim=gulim.TTC -filename.Batang=batang.TTC -filename.GulimChe=gulim.TTC - -filename.Lucida_Sans_Regular=LucidaSansRegular.ttf -filename.Symbol=SYMBOL.TTF -filename.Wingdings=WINGDING.TTF - diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/java/awt/FontClass/FontAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/FontClass/FontAccess.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6785424 + * @summary Test no SecurityException searching for a font. + * @run main FontAccess + * + * This can only test the specific bug if run on something like + * Windows Citrix Server where SystemDirectory and WindowsDirectory + * are different locations. + */ + +import java.awt.*; +import java.awt.image.*; + +public class FontAccess { + + public static void main(String[] args) { + System.setSecurityManager(new SecurityManager()); + Font f = new Font("Verdana", Font.PLAIN, 12); + BufferedImage bi = new BufferedImage(1,1,1); + Graphics2D g = bi.createGraphics(); + g.setFont(f); + System.out.println(g.getFontMetrics()); + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/java/awt/GraphicsEnvironment/PreferLocaleFonts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/GraphicsEnvironment/PreferLocaleFonts.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6752638 + * @summary Test no NPE calling preferLocaleFonts() on custom GE. + * @run main PreferLocaleFonts + */ + +import java.util.*; +import java.awt.*; +import java.awt.image.*; + +public class PreferLocaleFonts extends GraphicsEnvironment { + + public static void main(String args[]) { +(new PreferLocaleFonts()).preferLocaleFonts(); + } + public PreferLocaleFonts() { + super(); + } + public Graphics2D createGraphics(BufferedImage image) { + return null; + } + public String[] getAvailableFontFamilyNames(Locale locale) { + return null; + } + public String[] getAvailableFontFamilyNames() { + return null; + } + public Font[] getAllFonts() { + return null; + } + public GraphicsDevice getDefaultScreenDevice() throws HeadlessException { + return null; + } + public GraphicsDevice[] getScreenDevices() throws HeadlessException { + return null; + } +} + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/java/awt/font/LineBreakMeasurer/FRCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/font/LineBreakMeasurer/FRCTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,90 @@ +/* + * Copyright 2008-9 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6448405 6519513 6745225 + * @summary static HashMap cache in LineBreakMeasurer can grow wihout bounds + * @run main/othervm/timeout=600 -client -Xms16m -Xmx16m FRCTest + */ +import java.awt.*; +import java.awt.image.*; +import java.awt.font.*; +import java.awt.geom.*; +import java.text.*; +import java.util.Hashtable; + +public class FRCTest { + + static AttributedString vanGogh = new AttributedString( + "Many people believe that Vincent van Gogh painted his best works " + + "during the two-year period he spent in Provence. Here is where he " + + "painted The Starry Night--which some consider to be his greatest " + + "work of all. However, as his artistic brilliance reached new " + + "heights in Provence, his physical and mental health plummeted. ", + new Hashtable()); + + public static void main(String[] args) { + + // First test the behaviour of Graphics2D.getFontRenderContext(); + BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = bi.createGraphics(); + AffineTransform g2dTx = new AffineTransform(2,0,2,0,1,1); + g2d.setTransform(g2dTx); + AffineTransform frcTx = g2d.getFontRenderContext().getTransform(); + AffineTransform frcExpected = new AffineTransform(2,0,2,0,0,0); + if (!frcTx.equals(frcExpected)) { + throw new RuntimeException("FRC Tx may have translate?"); + } + + // Now test that using different translates with LBM is OK + // This test doesn't prove a lot since showing a leak really + // requires a basher test that can run for a long time. + for (int x=0;x<100;x++) { + for (int y=0;y<100;y++) { + AttributedCharacterIterator aci = vanGogh.getIterator(); + AffineTransform tx = AffineTransform.getTranslateInstance(x, y); + FontRenderContext frc = new FontRenderContext(tx, false, false); + LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); + lbm.setPosition(aci.getBeginIndex()); + while (lbm.getPosition() < aci.getEndIndex()) { + lbm.nextLayout(100f); + } + } + } + + for (int x=0;x<25;x++) { + for (int y=0;y<25;y++) { + AttributedCharacterIterator aci = vanGogh.getIterator(); + double rot = Math.random()*.4*Math.PI - .2*Math.PI; + AffineTransform tx = AffineTransform.getRotateInstance(rot); + FontRenderContext frc = new FontRenderContext(tx, false, false); + LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc); + lbm.setPosition(aci.getBeginIndex()); + while (lbm.getPosition() < aci.getEndIndex()) { + lbm.nextLayout(100f); + } + } + } + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/java/util/logging/ClassLoaderLeakTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/logging/ClassLoaderLeakTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,190 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6799583 + * + * @summary Test verifes that LogManager shutdown hook does not cause + * an application classloader leaks. + * + * @run main/othervm ClassLoaderLeakTest + */ + +import java.io.File; +import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.concurrent.CountDownLatch; +import java.util.logging.Logger; +import java.util.logging.Logger; + +public class ClassLoaderLeakTest { + + private static CountDownLatch doneSignal; + private static CountDownLatch launchSignal; + private static ThreadGroup appsThreadGroup; + private static Throwable launchFailure = null; + + public static void main(String[] args) { + appsThreadGroup = new ThreadGroup("MyAppsThreadGroup"); + doneSignal = new CountDownLatch(1); + launchSignal = new CountDownLatch(1); + + Runnable launcher = new Runnable() { + public void run() { + try { + ClassLoader cl = + Thread.currentThread().getContextClassLoader(); + Class appMain = cl.loadClass("AppTest"); + Method launch = + appMain.getDeclaredMethod("launch", doneSignal.getClass()); + + Constructor c = appMain.getConstructor(); + + Object o = c.newInstance(); + + launch.invoke(o, doneSignal); + + } catch (Throwable e) { + launchFailure = e; + } finally { + launchSignal.countDown(); + } + } + }; + + /* prepare test class loader */ + URL pwd = null; + try { + + pwd = new File(System.getProperty("test.classes",".")).toURL(); + } catch (MalformedURLException e) { + throw new RuntimeException("Test failed.", e); + } + URL[] urls = new URL[] { pwd }; + + MyClassLoader appClassLoader = new MyClassLoader(urls, "test0"); + WeakReference ref = + new WeakReference(appClassLoader); + + + Thread appThread = new Thread(appsThreadGroup, launcher, "AppThread-0"); + appThread.setContextClassLoader(appClassLoader); + + appThread.start(); + appClassLoader = null; + launcher = null; + appThread = null; + + /* wait for laucnh completion */ + try { + launchSignal.await(); + } catch (InterruptedException e) { + } + + /* check if launch failed */ + if (launchFailure != null) { + throw new RuntimeException("Test failed.", launchFailure); + } + + /* wait for test app excution completion */ + try { + doneSignal.await(); + } catch (InterruptedException e) { + } + + /* give a chence to GC */ + waitAndGC(5); + + if (ref.get() != null) { + throw new RuntimeException("Test failed: classloader is still alive"); + } + + System.out.println("Test passed."); + } + + private static class MyClassLoader extends URLClassLoader { + + private static boolean verbose = + Boolean.getBoolean("verboseClassLoading"); + private String uniqClassName; + + public MyClassLoader(URL[] urls, String uniq) { + super(urls); + + uniqClassName = uniq; + } + + public Class loadClass(String name) throws ClassNotFoundException { + if (verbose) { + System.out.printf("%s: load class %s\n", uniqClassName, name); + } + if (uniqClassName.equals(name)) { + return Object.class; + } + return super.loadClass(name); + } + + public String toString() { + return "MyClassLoader(" + uniqClassName + ")"; + } + } + + private static void waitAndGC(int sec) { + int cnt = sec; + System.out.print("Wait "); + while (cnt-- > 0) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + // do GC every 3 seconds + if (cnt % 3 == 2) { + System.gc(); + System.out.print("+"); + } else { + System.out.print("."); + } + //checkErrors(); + } + System.out.println(""); + } +} + + +class AppTest { + public AppTest() { + + } + + public void launch(CountDownLatch done) { + Logger log = Logger.getLogger("app_test_logger"); + log.fine("Test app is launched"); + + done.countDown(); + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/metadata/BooleanAttributes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/metadata/BooleanAttributes.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,202 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 5082756 + * @summary ensure that boolean attributes follow ( "TRUE" | "FALSE" ) + * including correct (i.e. upper) case + * + * @run main BooleanAttributes + */ + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.StringReader; +import java.util.Arrays; +import java.util.List; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.stream.MemoryCacheImageInputStream; +import javax.imageio.stream.MemoryCacheImageOutputStream; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class BooleanAttributes { + + private static TransformerFactory transformerFactory = + TransformerFactory.newInstance(); + + private static XPath xpathEngine = XPathFactory.newInstance().newXPath(); + + public static void main(String[] args) throws Exception { + test("image/png", false, "", + "Chroma/BlackIsZero/@value", + "Compression/Lossless/@value"); + + test("image/png", false, + "" + + "" + + "", + "iTXt/iTXtEntry/@compressionFlag"); + + test("image/png", false, + "" + + "" + + "", + "iTXt/iTXtEntry/@compressionFlag"); + + test("image/gif", false, "", + "Chroma/BlackIsZero/@value", + "Compression/Lossless/@value"); + + test("image/gif", false, + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "", + "ImageDescriptor/@interlaceFlag", + "LocalColorTable/@sortFlag", + "GraphicControlExtension/@userInputFlag", + "GraphicControlExtension/@transparentColorFlag"); + + test("image/gif", true, + "" + + "" + + "" + + "" + + "" + + "", + "GlobalColorTable/@sortFlag"); + + test("image/jpeg", false, "", + "Compression/Lossless/@value"); + } + + private static void transform(Source src, Result dst) + throws Exception + { + transformerFactory.newTransformer().transform(src, dst); + } + + private static void verify(Node meta, String[] xpaths, boolean required) + throws Exception + { + for (String xpath: xpaths) { + NodeList list = (NodeList) + xpathEngine.evaluate(xpath, meta, XPathConstants.NODESET); + if (list.getLength() == 0 && required) + throw new AssertionError("Missing value: " + xpath); + for (int i = 0; i < list.getLength(); ++i) { + String value = list.item(i).getNodeValue(); + if (!(value.equals("TRUE") || value.equals("FALSE"))) + throw new AssertionError(xpath + " has value " + value); + } + } + } + + public static void test(String mimeType, boolean useStreamMeta, + String metaXml, String... boolXpaths) + throws Exception + { + BufferedImage img = + new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB); + ImageWriter iw = ImageIO.getImageWritersByMIMEType(mimeType).next(); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ImageOutputStream ios = new MemoryCacheImageOutputStream(os); + iw.setOutput(ios); + ImageWriteParam param = null; + IIOMetadata streamMeta = iw.getDefaultStreamMetadata(param); + IIOMetadata imageMeta = + iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param); + IIOMetadata meta = useStreamMeta ? streamMeta : imageMeta; + Source src = new StreamSource(new StringReader(metaXml)); + DOMResult dst = new DOMResult(); + transform(src, dst); + Document doc = (Document)dst.getNode(); + Element node = doc.getDocumentElement(); + String metaFormat = node.getNodeName(); + + // Verify that the default metadata gets formatted correctly. + verify(meta.getAsTree(metaFormat), boolXpaths, false); + + meta.mergeTree(metaFormat, node); + + // Verify that the merged metadata gets formatte correctly. + verify(meta.getAsTree(metaFormat), boolXpaths, true); + + iw.write(streamMeta, new IIOImage(img, null, imageMeta), param); + iw.dispose(); + ios.close(); + ImageReader ir = ImageIO.getImageReader(iw); + byte[] bytes = os.toByteArray(); + if (bytes.length == 0) + throw new AssertionError("Zero length image file"); + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + ImageInputStream iis = new MemoryCacheImageInputStream(is); + ir.setInput(iis); + if (useStreamMeta) meta = ir.getStreamMetadata(); + else meta = ir.getImageMetadata(0); + + // Verify again after writing and re-reading the image + verify(meta.getAsTree(metaFormat), boolXpaths, true); + } + + public static void xtest(Object... eatAnyArguments) { + System.err.println("Disabled test! Change xtest back into test!"); + } + +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/plugins/gif/EncodeSubImageTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/gif/EncodeSubImageTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,161 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6795544 + * + * @summary Test verifes that Image I/O gif writer correctly handles + * buffered images based on translated reasters (typically + * produced by getSubImage() method). + * + * @run main EncodeSubImageTest gif + */ + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.awt.image.Raster; +import java.io.File; +import java.io.IOException; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; + +public class EncodeSubImageTest { + private static String format = "gif"; + private static ImageWriter writer; + private static String file_suffix; + private static final int subSampleX = 2; + private static final int subSampleY = 2; + + public static void main(String[] args) throws IOException { + if (args.length > 0) { + format = args[0]; + } + + writer = ImageIO.getImageWritersByFormatName(format).next(); + + file_suffix =writer.getOriginatingProvider().getFileSuffixes()[0]; + + BufferedImage src = createTestImage(); + EncodeSubImageTest m1 = new EncodeSubImageTest(src); + m1.doTest("test_src"); + + BufferedImage sub = src.getSubimage(subImageOffset, subImageOffset, + src.getWidth() - 2 * subImageOffset, + src.getHeight() - 2 * subImageOffset); + EncodeSubImageTest m2 = new EncodeSubImageTest(sub); + m2.doTest("test_sub"); + } + + BufferedImage img; + + public EncodeSubImageTest(BufferedImage img) { + this.img = img; + } + + public void doTest(String prefix) throws IOException { + System.out.println(prefix); + File f = new File(prefix + file_suffix); + write(f, false); + verify(f, false); + + System.out.println(prefix + "_subsampled"); + f = new File(prefix + "_subsampled"); + write(f, true); + verify(f, true); + + System.out.println(prefix + ": Test PASSED."); + } + + private static final int subImageOffset = 10; + + private void verify(File f, boolean isSubsampled) { + BufferedImage dst = null; + try { + dst = ImageIO.read(f); + } catch (IOException e) { + throw new RuntimeException("Test FAILED: can't readin test image " + + f.getAbsolutePath(), e); + } + if (dst == null) { + throw new RuntimeException("Test FAILED: no dst image available."); + } + + checkPixel(dst, 0, 0, isSubsampled); + + checkPixel(dst, img.getWidth() / 2, img.getHeight() / 2, isSubsampled); + } + + private void checkPixel(BufferedImage dst, int x, int y, + boolean isSubsampled) + { + int dx = isSubsampled ? x / subSampleX : x; + int dy = isSubsampled ? y / subSampleY : y; + int src_rgb = img.getRGB(x, y); + System.out.printf("src_rgb: %x\n", src_rgb); + + int dst_rgb = dst.getRGB(dx, dy); + System.out.printf("dst_rgb: %x\n", dst_rgb); + + if (src_rgb != dst_rgb) { + throw new RuntimeException("Test FAILED: invalid color in dst"); + } + } + + private static BufferedImage createTestImage() { + int w = 100; + int h = 100; + + BufferedImage src = new BufferedImage(w, h, + BufferedImage.TYPE_BYTE_INDEXED); + Graphics g = src.createGraphics(); + g.setColor(Color.red); + g.fillRect(0, 0, w, h); + g.setColor(Color.green); + g.fillRect(subImageOffset, subImageOffset, + w - 2 * subImageOffset, h - 2* subImageOffset); + g.setColor(Color.blue); + g.fillRect(2 * subImageOffset, 2 * subImageOffset, + w - 4 * subImageOffset, h - 4 * subImageOffset); + g.dispose(); + + return src; + } + + private void write(File f, boolean subsample) throws IOException { + ImageOutputStream ios = ImageIO.createImageOutputStream(f); + + writer.setOutput(ios); + ImageWriteParam p = writer.getDefaultWriteParam(); + if (subsample) { + p.setSourceSubsampling(subSampleX, subSampleY, 0, 0); + } + writer.write(null, new IIOImage(img, null, null), p); + ios.close(); + writer.reset(); + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/plugins/png/ITXtTest.java --- a/jdk/test/javax/imageio/plugins/png/ITXtTest.java Wed Jul 05 16:49:29 2017 +0200 +++ b/jdk/test/javax/imageio/plugins/png/ITXtTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -123,7 +123,7 @@ } t.keyword = e.getAttribute("keyword"); t.isCompressed = - (Integer.valueOf(e.getAttribute("compressionFlag")).intValue() == 1); + Boolean.valueOf(e.getAttribute("compressionFlag")).booleanValue(); t.compression = Integer.valueOf(e.getAttribute("compressionMethod")).intValue(); t.language = e.getAttribute("languageTag"); diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/plugins/png/ItxtUtf8Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/png/ItxtUtf8Test.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,241 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6541476 6782079 + * @summary Write and read a PNG file including an non-latin1 iTXt chunk + * Test also verifies that trunkated png images does not cause + * an OoutOfMemory error. + * + * @run main ItxtUtf8Test + * + * @run main/othervm/timeout=10 -Xmx2m ItxtUtf8Test truncate + */ + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.List; +import javax.imageio.IIOException; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.stream.MemoryCacheImageInputStream; +import javax.imageio.stream.MemoryCacheImageOutputStream; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; + +public class ItxtUtf8Test { + + public static final String + TEXT = "\u24c9\u24d4\u24e7\u24e3" + + "\ud835\udc13\ud835\udc1e\ud835\udc31\ud835\udc2d" + + "\u24c9\u24d4\u24e7\u24e3", // a repetition for compression + VERBATIM = "\u24e5\u24d4\u24e1\u24d1\u24d0\u24e3\u24d8\u24dc", + COMPRESSED = "\u24d2\u24de\u24dc\u24df\u24e1\u24d4\u24e2\u24e2\u24d4\u24d3"; + + public static final byte[] + VBYTES = { + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x56, // chunk length + (byte)0x69, (byte)0x54, (byte)0x58, (byte)0x74, // chunk type "iTXt" + (byte)0x76, (byte)0x65, (byte)0x72, (byte)0x62, + (byte)0x61, (byte)0x74, (byte)0x69, (byte)0x6d, // keyword "verbatim" + (byte)0x00, // separator terminating keyword + (byte)0x00, // compression flag + (byte)0x00, // compression method, must be zero + (byte)0x78, (byte)0x2d, (byte)0x63, (byte)0x69, + (byte)0x72, (byte)0x63, (byte)0x6c, (byte)0x65, + (byte)0x64, // language tag "x-circled" + (byte)0x00, // separator terminating language tag + (byte)0xe2, (byte)0x93, (byte)0xa5, // '\u24e5' + (byte)0xe2, (byte)0x93, (byte)0x94, // '\u24d4' + (byte)0xe2, (byte)0x93, (byte)0xa1, // '\u24e1' + (byte)0xe2, (byte)0x93, (byte)0x91, // '\u24d1' + (byte)0xe2, (byte)0x93, (byte)0x90, // '\u24d0' + (byte)0xe2, (byte)0x93, (byte)0xa3, // '\u24e3' + (byte)0xe2, (byte)0x93, (byte)0x98, // '\u24d8' + (byte)0xe2, (byte)0x93, (byte)0x9c, // '\u24dc' + (byte)0x00, // separator terminating the translated keyword + (byte)0xe2, (byte)0x93, (byte)0x89, // '\u24c9' + (byte)0xe2, (byte)0x93, (byte)0x94, // '\u24d4' + (byte)0xe2, (byte)0x93, (byte)0xa7, // '\u24e7' + (byte)0xe2, (byte)0x93, (byte)0xa3, // '\u24e3' + (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0x93, // '\ud835\udc13' + (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0x9e, // '\ud835\udc1e' + (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0xb1, // '\ud835\udc31' + (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0xad, // '\ud835\udc2d' + (byte)0xe2, (byte)0x93, (byte)0x89, // '\u24c9' + (byte)0xe2, (byte)0x93, (byte)0x94, // '\u24d4' + (byte)0xe2, (byte)0x93, (byte)0xa7, // '\u24e7' + (byte)0xe2, (byte)0x93, (byte)0xa3, // '\u24e3' + (byte)0xb5, (byte)0xcc, (byte)0x97, (byte)0x56 // CRC + }, + CBYTES = { + // we don't want to check the chunk length, + // as this might depend on implementation. + (byte)0x69, (byte)0x54, (byte)0x58, (byte)0x74, // chunk type "iTXt" + (byte)0x63, (byte)0x6f, (byte)0x6d, (byte)0x70, + (byte)0x72, (byte)0x65, (byte)0x73, (byte)0x73, + (byte)0x65, (byte)0x64, // keyword "compressed" + (byte)0x00, // separator terminating keyword + (byte)0x01, // compression flag + (byte)0x00, // compression method, 0=deflate + (byte)0x78, (byte)0x2d, (byte)0x63, (byte)0x69, + (byte)0x72, (byte)0x63, (byte)0x6c, (byte)0x65, + (byte)0x64, // language tag "x-circled" + (byte)0x00, // separator terminating language tag + // we don't want to check the actual compressed data, + // as this might depend on implementation. + }; +/* +*/ + + public static void main(String[] args) throws Exception { + List argList = Arrays.asList(args); + if (argList.contains("truncate")) { + try { + runTest(false, true); + throw new AssertionError("Expect an error for truncated file"); + } + catch (IIOException e) { + // expected an error for a truncated image file. + } + } + else { + runTest(argList.contains("dump"), false); + } + } + + public static void runTest(boolean dump, boolean truncate) + throws Exception + { + String format = "javax_imageio_png_1.0"; + BufferedImage img = + new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB); + ImageWriter iw = ImageIO.getImageWritersByMIMEType("image/png").next(); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ImageOutputStream ios = new MemoryCacheImageOutputStream(os); + iw.setOutput(ios); + IIOMetadata meta = + iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), null); + DOMImplementationRegistry registry; + registry = DOMImplementationRegistry.newInstance(); + DOMImplementation impl = registry.getDOMImplementation("XML 3.0"); + Document doc = impl.createDocument(null, format, null); + Element root, itxt, entry; + root = doc.getDocumentElement(); + root.appendChild(itxt = doc.createElement("iTXt")); + itxt.appendChild(entry = doc.createElement("iTXtEntry")); + entry.setAttribute("keyword", "verbatim"); + entry.setAttribute("compressionFlag", "false"); + entry.setAttribute("compressionMethod", "0"); + entry.setAttribute("languageTag", "x-circled"); + entry.setAttribute("translatedKeyword", VERBATIM); + entry.setAttribute("text", TEXT); + itxt.appendChild(entry = doc.createElement("iTXtEntry")); + entry.setAttribute("keyword", "compressed"); + entry.setAttribute("compressionFlag", "true"); + entry.setAttribute("compressionMethod", "0"); + entry.setAttribute("languageTag", "x-circled"); + entry.setAttribute("translatedKeyword", COMPRESSED); + entry.setAttribute("text", TEXT); + meta.mergeTree(format, root); + iw.write(new IIOImage(img, null, meta)); + iw.dispose(); + + byte[] bytes = os.toByteArray(); + if (dump) + System.out.write(bytes); + if (findBytes(VBYTES, bytes) < 0) + throw new AssertionError("verbatim block not found"); + if (findBytes(CBYTES, bytes) < 0) + throw new AssertionError("compressed block not found"); + int length = bytes.length; + if (truncate) + length = findBytes(VBYTES, bytes) + 32; + + ImageReader ir = ImageIO.getImageReader(iw); + ByteArrayInputStream is = new ByteArrayInputStream(bytes, 0, length); + ImageInputStream iis = new MemoryCacheImageInputStream(is); + ir.setInput(iis); + meta = ir.getImageMetadata(0); + Node node = meta.getAsTree(format); + for (node = node.getFirstChild(); + !"iTXt".equals(node.getNodeName()); + node = node.getNextSibling()); + boolean verbatimSeen = false, compressedSeen = false; + for (node = node.getFirstChild(); + node != null; + node = node.getNextSibling()) { + entry = (Element)node; + String keyword = entry.getAttribute("keyword"); + String translatedKeyword = entry.getAttribute("translatedKeyword"); + String text = entry.getAttribute("text"); + if ("verbatim".equals(keyword)) { + if (verbatimSeen) throw new AssertionError("Duplicate"); + verbatimSeen = true; + if (!VERBATIM.equals(translatedKeyword)) + throw new AssertionError("Wrong translated keyword"); + if (!TEXT.equals(text)) + throw new AssertionError("Wrong text"); + } + else if ("compressed".equals(keyword)) { + if (compressedSeen) throw new AssertionError("Duplicate"); + compressedSeen = true; + if (!COMPRESSED.equals(translatedKeyword)) + throw new AssertionError("Wrong translated keyword"); + if (!TEXT.equals(text)) + throw new AssertionError("Wrong text"); + } + else { + throw new AssertionError("Unexpected keyword"); + } + } + if (!(verbatimSeen && compressedSeen)) + throw new AssertionError("Missing chunk"); + } + + private static final int findBytes(byte[] needle, byte[] haystack) { + HAYSTACK: for (int h = 0; h <= haystack.length - needle.length; ++h) { + for (int n = 0; n < needle.length; ++n) { + if (needle[n] != haystack[h + n]) { + continue HAYSTACK; + } + } + return h; + } + return -1; + } + +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/plugins/png/MergeStdCommentTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/png/MergeStdCommentTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,64 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 5106550 + * @summary Merge a comment using the standard metdata format + * and only a minimal set of attributes + */ + +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; + +public class MergeStdCommentTest { + + public static void main(String[] args) throws Exception { + String format = "javax_imageio_1.0"; + BufferedImage img = + new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB); + ImageWriter iw = ImageIO.getImageWritersByMIMEType("image/png").next(); + IIOMetadata meta = + iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), null); + DOMImplementationRegistry registry; + registry = DOMImplementationRegistry.newInstance(); + DOMImplementation impl = registry.getDOMImplementation("XML 3.0"); + Document doc = impl.createDocument(null, format, null); + Element root, text, entry; + root = doc.getDocumentElement(); + root.appendChild(text = doc.createElement("Text")); + text.appendChild(entry = doc.createElement("TextEntry")); + // keyword isn't #REQUIRED by the standard metadata format. + // However, it is required by the PNG format, so we include it here. + entry.setAttribute("keyword", "Comment"); + entry.setAttribute("value", "Some demo comment"); + meta.mergeTree(format, root); + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,205 @@ +#!/bin/ksh -p +# +# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# +# @test +# @bug 6788096 +# @summary Test simulates the case of multiple applets executed in +# the same VM and verifies that ImageIO shutdown hook +# StreamCloser does not cause a leak of classloaders. +# +# @build test.Main +# @build testapp.Main +# @run shell run_test.sh + +# There are several resources which need to be present before many +# shell scripts can run. Following are examples of how to check for +# many common ones. +# +# Note that the shell used is the Korn Shell, KSH +# +# Also note, it is recommended that make files NOT be used. Rather, +# put the individual commands directly into this file. That way, +# it is possible to use command line arguments and other shell tech- +# niques to find the compiler, etc on different systems. For example, +# a different path could be used depending on whether this were a +# Solaris or Win32 machine, which is more difficult (if even possible) +# in a make file. + + +# Beginning of subroutines: +status=1 + +#Call this from anywhere to fail the test with an error message +# usage: fail "reason why the test failed" +fail() + { echo "The test failed :-(" + echo "$*" 1>&2 + echo "exit status was $status" + exit $status + } #end of fail() + +#Call this from anywhere to pass the test with a message +# usage: pass "reason why the test passed if applicable" +pass() + { echo "The test passed!!!" + echo "$*" 1>&2 + exit 0 + } #end of pass() + +# end of subroutines + + +# The beginning of the script proper + +# Checking for proper OS +OS=`uname -s` +case "$OS" in + SunOS ) + VAR="One value for Sun" + DEFAULT_JDK=/usr/local/java/jdk1.2/solaris + FILESEP="/" + PATHSEP=":" + TMP="/tmp" + ;; + + Linux ) + VAR="A different value for Linux" + DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386 + FILESEP="/" + PATHSEP=":" + TMP="/tmp" + ;; + + Windows_95 | Windows_98 | Windows_NT | Windows_ME ) + VAR="A different value for Win32" + DEFAULT_JDK=/usr/local/java/jdk1.2/win32 + FILESEP="\\" + PATHSEP=";" + TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}` + ;; + + # catch all other OSs + * ) + echo "Unrecognized system! $OS" + fail "Unrecognized system! $OS" + ;; +esac + +# Want this test to run standalone as well as in the harness, so do the +# following to copy the test's directory into the harness's scratch directory +# and set all appropriate variables: + +if [ -z "${TESTJAVA}" ] ; then + # TESTJAVA is not set, so the test is running stand-alone. + # TESTJAVA holds the path to the root directory of the build of the JDK + # to be tested. That is, any java files run explicitly in this shell + # should use TESTJAVA in the path to the java interpreter. + # So, we'll set this to the JDK spec'd on the command line. If none + # is given on the command line, tell the user that and use a cheesy + # default. + # THIS IS THE JDK BEING TESTED. + if [ -n "$1" ] ; + then TESTJAVA=$1 + else echo "no JDK specified on command line so using default!" + TESTJAVA=$DEFAULT_JDK + fi + TESTSRC=. + TESTCLASSES=. + STANDALONE=1; +fi +echo "JDK under test is: $TESTJAVA" + + +############### YOUR TEST CODE HERE!!!!!!! ############# + +#All files required for the test should be in the same directory with +# this file. If converting a standalone test to run with the harness, +# as long as all files are in the same directory and it returns 0 for +# pass, you should be able to cut and paste it into here and it will +# run with the test harness. + +# This is an example of running something -- test +# The stuff below catches the exit status of test then passes or fails +# this shell test as appropriate ( 0 status is considered a pass here ) + +echo "Create TestApp.jar..." + +if [ -f TestApp.jar ] ; then + rm -f TestApp.jar +fi + +${TESTJAVA}/bin/jar -cvf TestApp.jar -C ${TESTCLASSES} testapp + +if [ $? -ne "0" ] ; then + fail "Failed to create TestApp.jar" +fi + +echo "Create Test.jar..." +if [ -f Test.jar ] ; then + rm -f Test.jar +fi + +${TESTJAVA}/bin/jar -cvf Test.jar -C ${TESTCLASSES} test + +if [ $? -ne 0 ] ; then + fail "Failed to create Test.jar" +fi + +# Prepare temp dir for cahce files +mkdir ./tmp +if [ $? -ne 0 ] ; then + fail "Unable to create temp directory." +fi + +# Verify that all classoladers are destroyed +${TESTJAVA}/bin/java -cp Test.jar test.Main +if [ $? -ne 0 ] ; then + fail "Test FAILED: some classloaders weren't destroyed." +fi + + +# Verify that ImageIO shutdown hook works correcly +${TESTJAVA}/bin/java -cp Test.jar -DforgetSomeStreams=true test.Main +if [ $? -ne 0 ] ; then + fail "Test FAILED: some classloaders weren't destroyed of shutdown hook failed." +fi + +# sanity check: verify that all cache files were deleted +cache_files=`ls tmp` + +if [ "x${cache_files}" != "x" ] ; then + echo "WARNING: some cache files was not deleted: ${cache_files}" +fi + +echo "Test done." + +status=$? + +if [ $status -eq "0" ] ; then + pass "" +else + fail "Test failed due to test plugin was not found." +fi + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/stream/StreamCloserLeak/test/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/stream/StreamCloserLeak/test/Main.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,284 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package test; + +import java.io.File; +import java.io.IOException; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CountDownLatch; +import javax.imageio.stream.ImageInputStream; +import sun.awt.AppContext; +import sun.awt.SunToolkit; + +public class Main { + + private static ThreadGroup appsThreadGroup; + + private static WeakHashMap refs = + new WeakHashMap(); + + /** Collection to simulate forgrotten streams **/ + private static HashMap strongRefs = + new HashMap(); + + private static ConcurrentLinkedQueue problems = + new ConcurrentLinkedQueue(); + + private static AppContext mainAppContext = null; + + private static CountDownLatch doneSignal; + + private static final int gcTimeout = + Integer.getInteger("gcTimeout", 10).intValue(); + + private static boolean forgetSomeStreams = + Boolean.getBoolean("forgetSomeStreams"); + + public static void main(String[] args) throws IOException { + mainAppContext = SunToolkit.createNewAppContext(); + System.out.println("Current context class loader: " + + Thread.currentThread().getContextClassLoader()); + + appsThreadGroup = new ThreadGroup("MyAppsThreadGroup"); + + File jar = new File("TestApp.jar"); + if (!jar.exists()) { + System.out.println(jar.getAbsolutePath() + " was not found!\n" + + "Please install the jar with test application correctly!"); + throw new RuntimeException("Test failed: no TestApp.jar"); + } + + URL[] urls = new URL[]{jar.toURL()}; + + int numApps = Integer.getInteger("numApps", 20).intValue(); + + doneSignal = new CountDownLatch(numApps); + int cnt = 0; + while (cnt++ < numApps) { + launch(urls, "testapp.Main", "launch"); + + checkErrors(); + } + + System.out.println("Wait for apps completion...."); + + try { + doneSignal.await(); + } catch (InterruptedException e) { + } + + System.out.println("All apps finished."); + + System.gc(); + + System.out.flush(); + + System.out.println("Enumerate strong refs:"); + for (String is : strongRefs.keySet()) { + System.out.println("-> " + is); + } + + System.out.println("======================="); + + // wait few seconds + waitAndGC(gcTimeout); + + doneSignal = new CountDownLatch(1); + + Runnable workaround = new Runnable() { + + public void run() { + AppContext ctx = null; + try { + ctx = SunToolkit.createNewAppContext(); + } catch (Throwable e) { + // ignore... + } finally { + doneSignal.countDown(); + } + } + }; + + Thread wt = new Thread(appsThreadGroup, workaround, "Workaround"); + wt.setContextClassLoader(new MyClassLoader(urls, "workaround")); + wt.start(); + wt = null; + workaround = null; + + System.out.println("Wait for workaround completion..."); + + try { + doneSignal.await(); + } catch (InterruptedException e) { + } + + // give a chance to GC + waitAndGC(gcTimeout); + + if (!refs.isEmpty()) { + System.out.println("Classloaders still alive:"); + + for (MyClassLoader l : refs.keySet()) { + String val = refs.get(l); + + if (val == null) { + throw new RuntimeException("Test FAILED: Invalid classloader name"); + } + System.out.println("->" + val + (strongRefs.get(val) != null ? + " (has strong ref)" : "")); + if (strongRefs.get(val) == null) { + throw new RuntimeException("Test FAILED: exta class loader is detected! "); + } + } + } else { + System.out.println("No alive class loaders!!"); + } + System.out.println("Test PASSED."); + } + + private static void waitAndGC(int sec) { + int cnt = sec; + System.out.print("Wait "); + while (cnt-- > 0) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + // do GC every 3 seconds + if (cnt % 3 == 2) { + System.gc(); + System.out.print("+"); + } else { + System.out.print("."); + } + checkErrors(); + } + System.out.println(""); + } + + private static void checkErrors() { + while (!problems.isEmpty()) { + Throwable theProblem = problems.poll(); + System.out.println("Test FAILED!"); + do { + theProblem.printStackTrace(System.out); + theProblem = theProblem.getCause(); + } while (theProblem != null); + throw new RuntimeException("Test FAILED"); + } + } + static int counter = 0; + + private static void launch(URL[] urls, final String className, + final String methodName) + { + final String uniqClassName = "testapp/Uniq" + counter; + final boolean saveStrongRef = forgetSomeStreams ? (counter % 5 == 4) : false; + + System.out.printf("%s: launch the app\n", uniqClassName); + Runnable launchIt = new Runnable() { + public void run() { + AppContext ctx = SunToolkit.createNewAppContext(); + + try { + Class appMain = + ctx.getContextClassLoader().loadClass(className); + Method launch = appMain.getDeclaredMethod(methodName, + strongRefs.getClass()); + + Constructor c = appMain.getConstructor(String.class, + problems.getClass()); + + Object o = c.newInstance(uniqClassName, problems); + + if (saveStrongRef) { + System.out.printf("%s: force strong ref\n", + uniqClassName); + launch.invoke(o, strongRefs); + } else { + HashMap empty = null; + launch.invoke(o, empty); + } + + ctx = null; + } catch (Throwable e) { + problems.add(e); + } finally { + doneSignal.countDown(); + } + } + }; + + MyClassLoader appClassLoader = new MyClassLoader(urls, uniqClassName); + + refs.put(appClassLoader, uniqClassName); + + Thread appThread = new Thread(appsThreadGroup, launchIt, + "AppThread" + counter++); + appThread.setContextClassLoader(appClassLoader); + + appThread.start(); + launchIt = null; + appThread = null; + appClassLoader = null; + } + + private static class MyClassLoader extends URLClassLoader { + + private static boolean verbose = + Boolean.getBoolean("verboseClassLoading"); + private String uniqClassName; + + public MyClassLoader(URL[] urls, String uniq) { + super(urls); + + uniqClassName = uniq; + } + + public Class loadClass(String name) throws ClassNotFoundException { + if (verbose) { + System.out.printf("%s: load class %s\n", uniqClassName, name); + } + if (uniqClassName.equals(name)) { + return Object.class; + } + return super.loadClass(name); + } + + public String toString() { + return "MyClassLoader(" + uniqClassName + ")"; + } + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/javax/imageio/stream/StreamCloserLeak/testapp/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/stream/StreamCloserLeak/testapp/Main.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,109 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package testapp; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import javax.imageio.stream.FileCacheImageInputStream; +import javax.imageio.stream.ImageInputStream; + +public class Main { + + public static void main(String[] args) { + Main o = new Main("testapp.some.class", null); + o.launch(null); + } + + private final String uniqClassName; + private final ConcurrentLinkedQueue problems; + + public Main(String uniq, ConcurrentLinkedQueue p) { + uniqClassName = uniq; + problems = p; + } + + public void launch(HashMap refs) { + System.out.printf("%s: current context class loader: %s\n", + uniqClassName, + Thread.currentThread().getContextClassLoader()); + try { + byte[] data = new byte[1024]; + ByteArrayInputStream bais = new ByteArrayInputStream(data); + MyImageInputStream iis = new MyImageInputStream(bais, + uniqClassName, + problems); + if (refs != null) { + System.out.printf("%s: added to strong store\n", + uniqClassName); + refs.put(uniqClassName, iis); + } + iis.read(); + //leave stream open : let's shutdown hook work! + } catch (IOException e) { + problems.add(e); + } + } + + private static class MyImageInputStream extends FileCacheImageInputStream { + private final String uniqClassName; + private ConcurrentLinkedQueue problems; + public MyImageInputStream(InputStream is, String uniq, + ConcurrentLinkedQueue p) throws IOException + { + super(is, new File("tmp")); + uniqClassName = uniq; + problems = p; + } + + @Override + public void close() throws IOException { + Test t = new Test(); + try { + t.doTest(uniqClassName); + } catch (Throwable e) { + problems.add(e); + } + + super.close(); + + problems = null; + } + } +} + +class Test { + public void doTest(String uniqClassName) throws ClassNotFoundException { + System.out.printf("%s: Current thread: %s\n", uniqClassName, + Thread.currentThread()); + + ClassLoader thisCL = this.getClass().getClassLoader(); + Class uniq = thisCL.loadClass(uniqClassName); + + System.out.printf("%s: test is done!\n",uniqClassName); + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/sun/awt/image/DrawByteBinary.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/awt/image/DrawByteBinary.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,75 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6800846 + * + * @summary Test verifes that images with short palette are rendered + * withourt artifacts. + * + * @run main DrawByteBinary + */ + + +import java.awt.*; +import java.awt.color.*; +import java.awt.image.*; +import static java.awt.image.BufferedImage.*; + + +public class DrawByteBinary { + + public static void main(String args[]) { + int w = 100, h = 30; + int x = 10; + byte[] arr = {(byte)0xff, (byte)0x0, (byte)0x00}; + + IndexColorModel newCM = new IndexColorModel(1, 2, arr, arr, arr); + BufferedImage orig = new BufferedImage(w, h, TYPE_BYTE_BINARY, newCM); + Graphics2D g2d = orig.createGraphics(); + g2d.setColor(Color.white); + g2d.fillRect(0, 0, w, h); + g2d.setColor(Color.black); + g2d.drawLine(x, 0, x, h); + g2d.dispose(); + + IndexColorModel origCM = (IndexColorModel)orig.getColorModel(); + BufferedImage test = new BufferedImage(w, h, TYPE_BYTE_BINARY,origCM); + g2d = test.createGraphics(); + g2d.drawImage(orig, 0, 0, null); + g2d.dispose(); + + int y = h / 2; + + // we expect white color outside the line + if (test.getRGB(x - 1, y) != 0xffffffff) { + throw new RuntimeException("Invalid color outside the line."); + } + + // we expect black color on the line + if (test.getRGB(x, y) != 0xff000000) { + throw new RuntimeException("Invalid color on the line."); + } + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,120 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6476665 6523403 6733501 + * @summary Verifies reading and writing profiles and tags of the standard color + * spaces + * @run main ReadWriteProfileTest + */ +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; +import java.util.*; +import java.nio.*; +import java.util.Hashtable; + +public class ReadWriteProfileTest implements Runnable { + /* Location of the tag sig counter in 4-byte words */ + final static int TAG_COUNT_OFFSET = 32; + + /* Location of the tag sig table in 4-byte words */ + final static int TAG_ELEM_OFFSET = 33; + + static byte[][] profiles; + static int [][] tagSigs; + static Hashtable [] tags; + + static int [] cspaces = {ColorSpace.CS_sRGB, ColorSpace.CS_PYCC, + ColorSpace.CS_LINEAR_RGB, ColorSpace.CS_CIEXYZ, + ColorSpace.CS_GRAY}; + + static String [] csNames = {"sRGB", "PYCC", "LINEAR_RGB", "CIEXYZ", "GRAY"}; + + static void getProfileTags(byte [] data, Hashtable tags) { + ByteBuffer byteBuf = ByteBuffer.wrap(data); + IntBuffer intBuf = byteBuf.asIntBuffer(); + int tagCount = intBuf.get(TAG_COUNT_OFFSET); + intBuf.position(TAG_ELEM_OFFSET); + for (int i = 0; i < tagCount; i++) { + int tagSig = intBuf.get(); + int tagDataOff = intBuf.get(); + int tagSize = intBuf.get(); + + byte [] tagData = new byte[tagSize]; + byteBuf.position(tagDataOff); + byteBuf.get(tagData); + tags.put(tagSig, tagData); + } + } + + static { + profiles = new byte[cspaces.length][]; + tags = new Hashtable[cspaces.length]; + + for (int i = 0; i < cspaces.length; i++) { + ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]); + profiles[i] = pf.getData(); + tags[i] = new Hashtable(); + getProfileTags(profiles[i], tags[i]); + } + } + + public void run() { + for (int i = 0; i < cspaces.length; i++) { + ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]); + byte [] data = pf.getData(); + pf = ICC_Profile.getInstance(data); + if (!Arrays.equals(data, profiles[i])) { + System.err.println("Incorrect result of getData() " + "with " + + csNames[i] + " profile"); + throw new RuntimeException("Incorrect result of getData()"); + } + + for (int tagSig : tags[i].keySet()) { + byte [] tagData = pf.getData(tagSig); + byte [] empty = new byte[tagData.length]; + pf.setData(tagSig, empty); + pf.setData(tagSig, tagData); + + byte [] tagData1 = pf.getData(tagSig); + + if (!Arrays.equals(tagData1, tags[i].get(tagSig))) + { + System.err.println("Incorrect result of getData(int) with" + + " tag " + + Integer.toHexString(tagSig) + + " of " + csNames[i] + " profile"); + + throw new RuntimeException("Incorrect result of " + + "getData(int)"); + } + } + } + } + + public static void main(String [] args) { + ReadWriteProfileTest test = new ReadWriteProfileTest(); + test.run(); + } +} diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/sun/pisces/DashStrokeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/pisces/DashStrokeTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,86 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @summary verify that first element is a dash + * @bug 6793344 + */ + +import java.awt.*; +import java.awt.image.*; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +public class DashStrokeTest extends Component { + + static BufferedImage bi; + static boolean printed = false; + + public Dimension getPreferredSize() { + return new Dimension(200,200); + } + + public static void drawGui() { + bi = new BufferedImage(200, 20, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = bi.createGraphics(); + BasicStroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND, 1.0f, new float[] { 0.0f, 200 }, + 1.0f); + + g2d.setStroke(dashStroke); + g2d.setColor(Color.RED); + g2d.drawLine(5,10, 100,10); + printed =true; + } + + public static void main(String[] args) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + drawGui(); + } + + }); + } catch (Exception e) { + } + + if (printed) { + checkBI(bi, Color.RED); + } + } + + static void checkBI(BufferedImage bi, Color badColor) { + int badrgb = badColor.getRGB(); + + int col = bi.getRGB(6, 9); + if (col == badrgb) { + throw new RuntimeException("A pixel was turned on. "); + } + } +} + diff -r 7a90e89e36d1 -r d8b1468ef554 jdk/test/sun/pisces/JoinMiterTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/pisces/JoinMiterTest.java Tue Mar 24 19:12:02 2009 -0700 @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @summary Pass if no RuntimeException. + * @bug 6812600 + */ +import java.awt.*; +import java.awt.image.BufferedImage; + +public class JoinMiterTest { + + public static void main(String[] args) throws Exception { + BufferedImage image = new BufferedImage(200, 200, +BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + g.setPaint(Color.WHITE); + g.fill(new Rectangle(image.getWidth(), image.getHeight())); + g.translate(25, 100); + g.setPaint(Color.BLACK); + g.setStroke(new BasicStroke(20, BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER)); + g.draw(new Polygon(new int[] {0, 150, 0}, new int[] {75, 0, -75}, 3)); + if (image.getRGB(16, 10) == Color.WHITE.getRGB()) { + throw new RuntimeException("Miter is not rendered."); + } + } +}