--- a/jdk/make/sun/awt/Makefile Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/make/sun/awt/Makefile Tue Apr 07 14:02:54 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 =
--- a/jdk/make/sun/xawt/mapfile-vers Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/make/sun/xawt/mapfile-vers Tue Apr 07 14:02:54 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;
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadata.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadata.java Tue Apr 07 14:02:54 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",
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java Tue Apr 07 14:02:54 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,
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java Tue Apr 07 14:02:54 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'!");
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java Tue Apr 07 14:02:54 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
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java Tue Apr 07 14:02:54 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,
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Tue Apr 07 14:02:54 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;
+ }
}
}
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Tue Apr 07 14:02:54 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");
}
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java Tue Apr 07 14:02:54 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";
}
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Tue Apr 07 14:02:54 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 {
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java Tue Apr 07 14:02:54 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;
}
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Tue Apr 07 14:02:54 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
--- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Tue Apr 07 14:02:54 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<InputStream> {
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<InputStream> e = new PNGImageDataEnumeration(stream);
InputStream is = new SequenceInputStream(e);
/* InflaterInputStream uses an Inflater instance which consumes
--- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java Tue Apr 07 14:02:54 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();
}
}
--- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Tue Apr 07 14:02:54 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<String> tEXt_keyword = new ArrayList<String>(); // 1-79 characters
+ public ArrayList<String> tEXt_text = new ArrayList<String>();
// 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<String> zTXt_keyword = new ArrayList<String>();
+ public ArrayList<Integer> zTXt_compressionMethod = new ArrayList<Integer>();
+ public ArrayList<String> zTXt_text = new ArrayList<String>();
// Unknown chunks
- public ArrayList unknownChunkType = new ArrayList(); // Strings
- public ArrayList unknownChunkData = new ArrayList(); // byte arrays
+ public ArrayList<String> unknownChunkType = new ArrayList<String>();
+ public ArrayList<byte[]> unknownChunkData = new ArrayList<byte[]>();
public PNGMetadata() {
super(true,
@@ -426,21 +426,14 @@
return false;
}
- private ArrayList cloneBytesArrayList(ArrayList in) {
+ private ArrayList<byte[]> cloneBytesArrayList(ArrayList<byte[]> 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<byte[]> list = new ArrayList<byte[]>(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<String>();
+ tEXt_text = new ArrayList<String>();
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<String>();
+ zTXt_compressionMethod = new ArrayList<Integer>();
+ zTXt_text = new ArrayList<String>();
+ unknownChunkType = new ArrayList<String>();
+ unknownChunkData = new ArrayList<byte[]>();
}
}
--- a/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java Tue Apr 07 14:02:54 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;
}
--- a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java Tue Apr 07 14:02:54 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();
}
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java Tue Apr 07 14:02:54 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;
}
}
--- a/jdk/src/share/classes/java/util/logging/LogManager.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java Tue Apr 07 14:02:54 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.<clinit> is completed
// before synchronized block. Otherwise deadlocks are possible.
--- a/jdk/src/share/classes/javax/imageio/ImageTypeSpecifier.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/javax/imageio/ImageTypeSpecifier.java Tue Apr 07 14:02:54 2009 -0700
@@ -67,126 +67,13 @@
* <code>BufferedImage</code> 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!");
+ }
+ }
+
}
--- a/jdk/src/share/classes/javax/imageio/metadata/IIOMetadataFormat.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/javax/imageio/metadata/IIOMetadataFormat.java Tue Apr 07 14:02:54 2009 -0700
@@ -242,8 +242,12 @@
/**
* A constant returned by <code>getAttributeDataType</code>
- * 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;
--- a/jdk/src/share/classes/sun/awt/FontConfiguration.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/awt/FontConfiguration.java Tue Apr 07 14:02:54 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 //
//////////////////////////////////////////////////////////////////////
--- a/jdk/src/share/classes/sun/font/FileFontStrike.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/font/FileFontStrike.java Tue Apr 07 14:02:54 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<ConcurrentHashMap<Integer,GeneralPath>> outlineMapRef;
+
GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
- return fileFont.getGlyphOutline(pScalerContext, glyphCode, x, y);
+
+ GeneralPath gp = null;
+ ConcurrentHashMap<Integer, GeneralPath> 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<Integer, GeneralPath>();
+ outlineMapRef =
+ new WeakReference
+ <ConcurrentHashMap<Integer,GeneralPath>>(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) {
--- a/jdk/src/share/classes/sun/font/FontManager.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/font/FontManager.java Tue Apr 07 14:02:54 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<pathDirs.length; p++) {
- f = new File(pathDirs[p] + File.separator + s);
- if (f.exists()) {
- return f.getAbsolutePath();
- }
+ String path = java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<String>() {
+ public String run() {
+ for (int p=0; p<pathDirs.length; p++) {
+ File f = new File(pathDirs[p] +File.separator+ s);
+ if (f.exists()) {
+ return f.getAbsolutePath();
+ }
+ }
+ return null;
+ }
+ });
+ if (path != null) {
+ return path;
}
}
return s; // shouldn't happen, but harmless
--- a/jdk/src/share/classes/sun/font/GlyphLayout.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/font/GlyphLayout.java Tue Apr 07 14:02:54 2009 -0700
@@ -338,6 +338,8 @@
cache = new ConcurrentHashMap<SDKey, SDCache>(10);
cacheRef = new
SoftReference<ConcurrentHashMap<SDKey, SDCache>>(cache);
+ } else if (cache.size() >= 512) {
+ cache.clear();
}
cache.put(key, res);
}
--- a/jdk/src/share/classes/sun/font/StrikeCache.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/font/StrikeCache.java Tue Apr 07 14:02:54 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);
+ }
}
}
--- a/jdk/src/share/classes/sun/java2d/cmm/ProfileActivator.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/java2d/cmm/ProfileActivator.java Tue Apr 07 14:02:54 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;
}
--- a/jdk/src/share/classes/sun/java2d/cmm/ProfileDeferralMgr.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/java2d/cmm/ProfileDeferralMgr.java Tue Apr 07 14:02:54 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<ProfileActivator> 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<ProfileActivator>(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;
--- a/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/java2d/pisces/Dasher.java Tue Apr 07 14:02:54 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;
--- a/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java Tue Apr 07 14:02:54 2009 -0700
@@ -245,6 +245,7 @@
FloatToS15_16(coords[1]));
break;
case PathIterator.SEG_CLOSE:
+ lsink.lineJoin();
lsink.close();
break;
default:
--- a/jdk/src/share/classes/sun/print/ServiceDialog.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/classes/sun/print/ServiceDialog.java Tue Apr 07 14:02:54 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);
}
}
}
--- a/jdk/src/share/native/sun/awt/image/dither.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/awt/image/dither.c Tue Apr 07 14:02:54 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)) {
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Tue Apr 07 14:02:54 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");
}
--- a/jdk/src/share/native/sun/font/freetypeScaler.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/font/freetypeScaler.c Tue Apr 07 14:02:54 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);
}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Tue Apr 07 14:02:54 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;
+}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Tue Apr 07 14:02:54 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];
}
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam97.c Tue Apr 07 14:02:54 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);
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Tue Apr 07 14:02:54 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 <io.h>
+#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);
}
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Tue Apr 07 14:02:54 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;
}
+
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Tue Apr 07 14:02:54 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);
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Tue Apr 07 14:02:54 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
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Tue Apr 07 14:02:54 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;
+ */
}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Tue Apr 07 14:02:54 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
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Tue Apr 07 14:02:54 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;
+
+}
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Tue Apr 07 14:02:54 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;
}
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Tue Apr 07 14:02:54 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;
}
+
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c Tue Apr 07 14:02:54 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);
}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Tue Apr 07 14:02:54 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);
}
+
+
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Tue Apr 07 14:02:54 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;
}
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Tue Apr 07 14:02:54 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:
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Tue Apr 07 14:02:54 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]);
}
+
+
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Tue Apr 07 14:02:54 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[ <postlinearization> ]
+ /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;
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Tue Apr 07 14:02:54 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;
}
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Tue Apr 07 14:02:54 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;
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Tue Apr 07 14:02:54 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);
}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Tue Apr 07 14:02:54 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);
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/icc34.h Tue Apr 07 14:02:54 2009 -0700
@@ -206,6 +206,11 @@
#if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__)
+#if defined (__MINGW) || defined(__MINGW32__)
+#include <stdint.h>
+#endif
+
+
typedef uint8_t icUInt8Number;
typedef uint16_t icUInt16Number;
typedef uint32_t icUInt32Number;
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/lcms.h Tue Apr 07 14:02:54 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 <stdio.h>
#include <stdlib.h>
#include <math.h>
@@ -134,11 +130,11 @@
#include <time.h>
// 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 <windows.h>
-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
+
--- a/jdk/src/solaris/classes/sun/awt/X11/XFontPeer.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XFontPeer.java Tue Apr 07 14:02:54 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() {
--- a/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java Tue Apr 07 14:02:54 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
--- a/jdk/src/solaris/classes/sun/print/IPPPrintService.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/solaris/classes/sun/print/IPPPrintService.java Tue Apr 07 14:02:54 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;
--- a/jdk/src/solaris/classes/sun/print/UnixPrintJob.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/solaris/classes/sun/print/UnixPrintJob.java Tue Apr 07 14:02:54 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) {
--- a/jdk/src/windows/classes/sun/awt/windows/WFontConfiguration.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WFontConfiguration.java Tue Apr 07 14:02:54 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");
--- a/jdk/src/windows/classes/sun/awt/windows/fontconfig.98.properties Tue Apr 07 11:43:20 2009 -0700
+++ /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
-
--- a/jdk/src/windows/classes/sun/awt/windows/fontconfig.Me.properties Tue Apr 07 11:43:20 2009 -0700
+++ /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
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FontClass/FontAccess.java Tue Apr 07 14:02:54 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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/GraphicsEnvironment/PreferLocaleFonts.java Tue Apr 07 14:02:54 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;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/LineBreakMeasurer/FRCTest.java Tue Apr 07 14:02:54 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);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/ClassLoaderLeakTest.java Tue Apr 07 14:02:54 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<MyClassLoader> ref =
+ new WeakReference<MyClassLoader>(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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/metadata/BooleanAttributes.java Tue Apr 07 14:02:54 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, "<javax_imageio_1.0 />",
+ "Chroma/BlackIsZero/@value",
+ "Compression/Lossless/@value");
+
+ test("image/png", false,
+ "<javax_imageio_png_1.0>" +
+ "<iTXt><iTXtEntry keyword='Comment' compressionFlag='TRUE' " +
+ "compressionMethod='0' languageTag='en' " +
+ "translatedKeyword='comment' text='foo'/></iTXt>" +
+ "</javax_imageio_png_1.0>",
+ "iTXt/iTXtEntry/@compressionFlag");
+
+ test("image/png", false,
+ "<javax_imageio_png_1.0>" +
+ "<iTXt><iTXtEntry keyword='Comment' compressionFlag='FALSE' " +
+ "compressionMethod='0' languageTag='en' " +
+ "translatedKeyword='comment' text='foo'/></iTXt>" +
+ "</javax_imageio_png_1.0>",
+ "iTXt/iTXtEntry/@compressionFlag");
+
+ test("image/gif", false, "<javax_imageio_1.0 />",
+ "Chroma/BlackIsZero/@value",
+ "Compression/Lossless/@value");
+
+ test("image/gif", false,
+ "<javax_imageio_gif_image_1.0>" +
+ "<ImageDescriptor imageLeftPosition='0' imageTopPosition='0' " +
+ "imageWidth='16' imageHeight='16' interlaceFlag='TRUE' />" +
+ "<LocalColorTable sizeOfLocalColorTable='2' " +
+ "backgroundColorIndex='1' sortFlag='TRUE'>" +
+ "<ColorTableEntry index='0' red='0' green='0' blue='0' />" +
+ "<ColorTableEntry index='1' red='255' green='255' blue='255' />" +
+ "</LocalColorTable>" +
+ "<GraphicControlExtension disposalMethod='doNotDispose' " +
+ "userInputFlag='FALSE' transparentColorFlag='TRUE' " +
+ "delayTime='100' transparentColorIndex='1' />" +
+ "</javax_imageio_gif_image_1.0>",
+ "ImageDescriptor/@interlaceFlag",
+ "LocalColorTable/@sortFlag",
+ "GraphicControlExtension/@userInputFlag",
+ "GraphicControlExtension/@transparentColorFlag");
+
+ test("image/gif", true,
+ "<javax_imageio_gif_stream_1.0>" +
+ "<GlobalColorTable sizeOfGlobalColorTable='2' " +
+ "backgroundColorIndex='1' sortFlag='TRUE'>" +
+ "<ColorTableEntry index='0' red='0' green='0' blue='0' />" +
+ "<ColorTableEntry index='1' red='255' green='255' blue='255' />" +
+ "</GlobalColorTable>" +
+ "</javax_imageio_gif_stream_1.0>",
+ "GlobalColorTable/@sortFlag");
+
+ test("image/jpeg", false, "<javax_imageio_1.0 />",
+ "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!");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/gif/EncodeSubImageTest.java Tue Apr 07 14:02:54 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();
+ }
+}
--- a/jdk/test/javax/imageio/plugins/png/ITXtTest.java Tue Apr 07 11:43:20 2009 -0700
+++ b/jdk/test/javax/imageio/plugins/png/ITXtTest.java Tue Apr 07 14:02:54 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");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/png/ItxtUtf8Test.java Tue Apr 07 14:02:54 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;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/png/MergeStdCommentTest.java Tue Apr 07 14:02:54 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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Tue Apr 07 14:02:54 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/stream/StreamCloserLeak/test/Main.java Tue Apr 07 14:02:54 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<MyClassLoader, String> refs =
+ new WeakHashMap<MyClassLoader, String>();
+
+ /** Collection to simulate forgrotten streams **/
+ private static HashMap<String, ImageInputStream> strongRefs =
+ new HashMap<String, ImageInputStream>();
+
+ private static ConcurrentLinkedQueue<Throwable> problems =
+ new ConcurrentLinkedQueue<Throwable>();
+
+ 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<String, ImageInputStream> 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 + ")";
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/stream/StreamCloserLeak/testapp/Main.java Tue Apr 07 14:02:54 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<Throwable> problems;
+
+ public Main(String uniq, ConcurrentLinkedQueue<Throwable> p) {
+ uniqClassName = uniq;
+ problems = p;
+ }
+
+ public void launch(HashMap<String, ImageInputStream> 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<Throwable> problems;
+ public MyImageInputStream(InputStream is, String uniq,
+ ConcurrentLinkedQueue<Throwable> 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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/awt/image/DrawByteBinary.java Tue Apr 07 14:02:54 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.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java Tue Apr 07 14:02:54 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<Integer,byte[]> [] 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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/pisces/DashStrokeTest.java Tue Apr 07 14:02:54 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. ");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/pisces/JoinMiterTest.java Tue Apr 07 14:02:54 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.");
+ }
+ }
+}