Merge jdk7-b54
authorxdono
Tue, 07 Apr 2009 14:02:54 -0700
changeset 1016d1c43d1f5676
parent 1015 f3381dd0f7cd
parent 1005 6ee1e2a1a833
child 1017 a43b2c9dad6f
child 1071 c5f1721eebb2
child 1096 ffc29fac1330
child 1180 e3b4eb55a696
Merge
src/windows/classes/sun/awt/windows/fontconfig.98.properties
src/windows/classes/sun/awt/windows/fontconfig.Me.properties
     1.1 --- a/make/sun/awt/Makefile	Tue Apr 07 11:43:20 2009 -0700
     1.2 +++ b/make/sun/awt/Makefile	Tue Apr 07 14:02:54 2009 -0700
     1.3 @@ -339,8 +339,7 @@
     1.4  
     1.5  FONTCONFIGS_SRC = $(PLATFORM_SRC)/classes/sun/awt/windows
     1.6  _FONTCONFIGS = \
     1.7 -        fontconfig.properties \
     1.8 -        fontconfig.98.properties 
     1.9 +        fontconfig.properties
    1.10  
    1.11  FONTCONFIGS_SRC_PREFIX =
    1.12  
     2.1 --- a/make/sun/xawt/mapfile-vers	Tue Apr 07 11:43:20 2009 -0700
     2.2 +++ b/make/sun/xawt/mapfile-vers	Tue Apr 07 14:02:54 2009 -0700
     2.3 @@ -304,12 +304,14 @@
     2.4          Java_java_awt_FileDialog_initIDs;
     2.5          Java_sun_awt_X11_XWindow_initIDs;
     2.6  
     2.7 +        Java_sun_java2d_opengl_OGLContext_getOGLIdString;
     2.8          Java_sun_java2d_opengl_OGLMaskFill_maskFill;
     2.9          Java_sun_java2d_opengl_OGLRenderer_drawPoly;
    2.10          Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer;
    2.11          Java_sun_java2d_opengl_OGLSurfaceData_initTexture;
    2.12          Java_sun_java2d_opengl_OGLSurfaceData_initFBObject;
    2.13          Java_sun_java2d_opengl_OGLSurfaceData_initFlipBackbuffer;
    2.14 +        Java_sun_java2d_opengl_OGLSurfaceData_getTextureID;
    2.15          Java_sun_java2d_opengl_OGLSurfaceData_getTextureTarget;
    2.16          Java_sun_java2d_opengl_OGLTextRenderer_drawGlyphList;
    2.17          Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo;
     3.1 --- a/src/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadata.java	Tue Apr 07 11:43:20 2009 -0700
     3.2 +++ b/src/share/classes/com/sun/imageio/plugins/gif/GIFImageMetadata.java	Tue Apr 07 14:02:54 2009 -0700
     3.3 @@ -153,7 +153,7 @@
     3.4          node.setAttribute("imageWidth", Integer.toString(imageWidth));
     3.5          node.setAttribute("imageHeight", Integer.toString(imageHeight));
     3.6          node.setAttribute("interlaceFlag",
     3.7 -                          interlaceFlag ? "true" : "false");
     3.8 +                          interlaceFlag ? "TRUE" : "FALSE");
     3.9          root.appendChild(node);
    3.10  
    3.11          // Local color table
    3.12 @@ -185,9 +185,9 @@
    3.13          node.setAttribute("disposalMethod",
    3.14                            disposalMethodNames[disposalMethod]);
    3.15          node.setAttribute("userInputFlag",
    3.16 -                          userInputFlag ? "true" : "false");
    3.17 +                          userInputFlag ? "TRUE" : "FALSE");
    3.18          node.setAttribute("transparentColorFlag",
    3.19 -                          transparentColorFlag ? "true" : "false");
    3.20 +                          transparentColorFlag ? "TRUE" : "FALSE");
    3.21          node.setAttribute("delayTime",
    3.22                            Integer.toString(delayTime));
    3.23          node.setAttribute("transparentColorIndex",
     4.1 --- a/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java	Tue Apr 07 11:43:20 2009 -0700
     4.2 +++ b/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java	Tue Apr 07 14:02:54 2009 -0700
     4.3 @@ -55,6 +55,7 @@
     4.4  import org.w3c.dom.NodeList;
     4.5  import com.sun.imageio.plugins.common.LZWCompressor;
     4.6  import com.sun.imageio.plugins.common.PaletteBuilder;
     4.7 +import sun.awt.image.ByteComponentRaster;
     4.8  
     4.9  public class GIFImageWriter extends ImageWriter {
    4.10      private static final boolean DEBUG = false; // XXX false for release!
    4.11 @@ -905,10 +906,18 @@
    4.12          LZWCompressor compressor =
    4.13              new LZWCompressor(stream, initCodeSize, false);
    4.14  
    4.15 +        /* At this moment we know that input image is indexed image.
    4.16 +         * We can directly copy data iff:
    4.17 +         *   - no subsampling required (periodX = 1, periodY = 0)
    4.18 +         *   - we can access data directly (image is non-tiled,
    4.19 +         *     i.e. image data are in single block)
    4.20 +         *   - we can calculate offset in data buffer (next 3 lines)
    4.21 +         */
    4.22          boolean isOptimizedCase =
    4.23              periodX == 1 && periodY == 1 &&
    4.24 +            image.getNumXTiles() == 1 && image.getNumYTiles() == 1 &&
    4.25              sampleModel instanceof ComponentSampleModel &&
    4.26 -            image.getNumXTiles() == 1 && image.getNumYTiles() == 1 &&
    4.27 +            image.getTile(0, 0) instanceof ByteComponentRaster &&
    4.28              image.getTile(0, 0).getDataBuffer() instanceof DataBufferByte;
    4.29  
    4.30          int numRowsWritten = 0;
    4.31 @@ -921,11 +930,14 @@
    4.32              if (DEBUG) System.out.println("Writing interlaced");
    4.33  
    4.34              if (isOptimizedCase) {
    4.35 -                Raster tile = image.getTile(0, 0);
    4.36 +                ByteComponentRaster tile =
    4.37 +                    (ByteComponentRaster)image.getTile(0, 0);
    4.38                  byte[] data = ((DataBufferByte)tile.getDataBuffer()).getData();
    4.39                  ComponentSampleModel csm =
    4.40                      (ComponentSampleModel)tile.getSampleModel();
    4.41                  int offset = csm.getOffset(sourceXOffset, sourceYOffset, 0);
    4.42 +                // take into account the raster data offset
    4.43 +                offset += tile.getDataOffset(0);
    4.44                  int lineStride = csm.getScanlineStride();
    4.45  
    4.46                  writeRowsOpt(data, offset, lineStride, compressor,
     5.1 --- a/src/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java	Tue Apr 07 11:43:20 2009 -0700
     5.2 +++ b/src/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java	Tue Apr 07 14:02:54 2009 -0700
     5.3 @@ -158,13 +158,10 @@
     5.4              }
     5.5          }
     5.6          String value = attr.getNodeValue();
     5.7 -        // XXX Should be able to use equals() here instead of
     5.8 -        // equalsIgnoreCase() but some boolean attributes are incorrectly
     5.9 -        // set to "true" or "false" by the J2SE core metadata classes
    5.10 -        // getAsTree() method (which are duplicated above). See bug 5082756.
    5.11 -        if (value.equalsIgnoreCase("TRUE")) {
    5.12 +        // Allow lower case booleans for backward compatibility, #5082756
    5.13 +        if (value.equals("TRUE") || value.equals("true")) {
    5.14              return true;
    5.15 -        } else if (value.equalsIgnoreCase("FALSE")) {
    5.16 +        } else if (value.equals("FALSE") || value.equals("false")) {
    5.17              return false;
    5.18          } else {
    5.19              fatal(node, "Attribute " + name + " must be 'TRUE' or 'FALSE'!");
     6.1 --- a/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java	Tue Apr 07 11:43:20 2009 -0700
     6.2 +++ b/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java	Tue Apr 07 14:02:54 2009 -0700
     6.3 @@ -202,7 +202,7 @@
     6.4          compression_node.appendChild(node);
     6.5  
     6.6          node = new IIOMetadataNode("Lossless");
     6.7 -        node.setAttribute("value", "true");
     6.8 +        node.setAttribute("value", "TRUE");
     6.9          compression_node.appendChild(node);
    6.10  
    6.11          // NumProgressiveScans not in stream
     7.1 --- a/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java	Tue Apr 07 11:43:20 2009 -0700
     7.2 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java	Tue Apr 07 14:02:54 2009 -0700
     7.3 @@ -1003,7 +1003,7 @@
     7.4                                                 3,
     7.5                                                 new int [] {0, 1, 2},
     7.6                                                 null);
     7.7 -            ColorModel cm = new ComponentColorModel(JPEG.sRGB,
     7.8 +            ColorModel cm = new ComponentColorModel(JPEG.JCS.sRGB,
     7.9                                                      false,
    7.10                                                      false,
    7.11                                                      ColorModel.OPAQUE,
     8.1 --- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java	Tue Apr 07 11:43:20 2009 -0700
     8.2 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java	Tue Apr 07 14:02:54 2009 -0700
     8.3 @@ -208,15 +208,24 @@
     8.4  
     8.5      public static final int [] bOffsRGB = { 2, 1, 0 };
     8.6  
     8.7 -    protected static final ColorSpace sRGB =
     8.8 -        ColorSpace.getInstance(ColorSpace.CS_sRGB);
     8.9 -    protected static ColorSpace YCC = null;  // Can't be final
    8.10 +    /* These are kept in the inner class to avoid static initialization
    8.11 +     * of the CMM class until someone actually needs it.
    8.12 +     * (e.g. do not init CMM on the request for jpeg mime types)
    8.13 +     */
    8.14 +    public static class JCS {
    8.15 +        public static final ColorSpace sRGB =
    8.16 +            ColorSpace.getInstance(ColorSpace.CS_sRGB);
    8.17 +        public static final ColorSpace YCC;
    8.18  
    8.19 -    static {
    8.20 -        try {
    8.21 -            YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC);
    8.22 -        } catch (IllegalArgumentException e) {
    8.23 -            // PYCC.pf may not always be installed
    8.24 +        static {
    8.25 +            ColorSpace cs = null;
    8.26 +            try {
    8.27 +                cs = ColorSpace.getInstance(ColorSpace.CS_PYCC);
    8.28 +            } catch (IllegalArgumentException e) {
    8.29 +                // PYCC.pf may not always be installed
    8.30 +            } finally {
    8.31 +                YCC = cs;
    8.32 +            }
    8.33          }
    8.34      }
    8.35  
     9.1 --- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Tue Apr 07 11:43:20 2009 -0700
     9.2 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Tue Apr 07 14:02:54 2009 -0700
     9.3 @@ -228,31 +228,31 @@
     9.4              (BufferedImage.TYPE_BYTE_GRAY);
     9.5          defaultTypes[JPEG.JCS_RGB] =
     9.6              ImageTypeSpecifier.createInterleaved
     9.7 -            (JPEG.sRGB,
     9.8 +            (JPEG.JCS.sRGB,
     9.9               JPEG.bOffsRGB,
    9.10               DataBuffer.TYPE_BYTE,
    9.11               false,
    9.12               false);
    9.13          defaultTypes[JPEG.JCS_RGBA] =
    9.14              ImageTypeSpecifier.createPacked
    9.15 -            (JPEG.sRGB,
    9.16 +            (JPEG.JCS.sRGB,
    9.17               0xff000000,
    9.18               0x00ff0000,
    9.19               0x0000ff00,
    9.20               0x000000ff,
    9.21               DataBuffer.TYPE_INT,
    9.22               false);
    9.23 -        if (JPEG.YCC != null) {
    9.24 +        if (JPEG.JCS.YCC != null) {
    9.25              defaultTypes[JPEG.JCS_YCC] =
    9.26                  ImageTypeSpecifier.createInterleaved
    9.27 -                (JPEG.YCC,
    9.28 +                (JPEG.JCS.YCC,
    9.29                   JPEG.bandOffsets[2],
    9.30                   DataBuffer.TYPE_BYTE,
    9.31                   false,
    9.32                   false);
    9.33              defaultTypes[JPEG.JCS_YCCA] =
    9.34                  ImageTypeSpecifier.createInterleaved
    9.35 -                (JPEG.YCC,
    9.36 +                (JPEG.JCS.YCC,
    9.37                   JPEG.bandOffsets[3],
    9.38                   DataBuffer.TYPE_BYTE,
    9.39                   true,
    9.40 @@ -774,7 +774,7 @@
    9.41          case JPEG.JCS_RGB:
    9.42              list.add(raw);
    9.43              list.add(getImageType(JPEG.JCS_GRAYSCALE));
    9.44 -            if (JPEG.YCC != null) {
    9.45 +            if (JPEG.JCS.YCC != null) {
    9.46                  list.add(getImageType(JPEG.JCS_YCC));
    9.47              }
    9.48              break;
    9.49 @@ -811,7 +811,7 @@
    9.50              }
    9.51  
    9.52              list.add(getImageType(JPEG.JCS_GRAYSCALE));
    9.53 -            if (JPEG.YCC != null) { // Might be null if PYCC.pf not installed
    9.54 +            if (JPEG.JCS.YCC != null) { // Might be null if PYCC.pf not installed
    9.55                  list.add(getImageType(JPEG.JCS_YCC));
    9.56              }
    9.57              break;
    9.58 @@ -893,7 +893,7 @@
    9.59                         (!cs.isCS_sRGB()) &&
    9.60                         (cm.getNumComponents() == numComponents)) {
    9.61                  // Target isn't sRGB, so convert from sRGB to the target
    9.62 -                convert = new ColorConvertOp(JPEG.sRGB, cs, null);
    9.63 +                convert = new ColorConvertOp(JPEG.JCS.sRGB, cs, null);
    9.64              } else if (csType != ColorSpace.TYPE_RGB) {
    9.65                  throw new IIOException("Incompatible color conversion");
    9.66              }
    9.67 @@ -906,18 +906,18 @@
    9.68              }
    9.69              break;
    9.70          case JPEG.JCS_YCC:
    9.71 -            if (JPEG.YCC == null) { // We can't do YCC at all
    9.72 +            if (JPEG.JCS.YCC == null) { // We can't do YCC at all
    9.73                  throw new IIOException("Incompatible color conversion");
    9.74              }
    9.75 -            if ((cs != JPEG.YCC) &&
    9.76 +            if ((cs != JPEG.JCS.YCC) &&
    9.77                  (cm.getNumComponents() == numComponents)) {
    9.78 -                convert = new ColorConvertOp(JPEG.YCC, cs, null);
    9.79 +                convert = new ColorConvertOp(JPEG.JCS.YCC, cs, null);
    9.80              }
    9.81              break;
    9.82          case JPEG.JCS_YCCA:
    9.83              // No conversions available; image must be YCCA
    9.84 -            if ((JPEG.YCC == null) || // We can't do YCC at all
    9.85 -                (cs != JPEG.YCC) ||
    9.86 +            if ((JPEG.JCS.YCC == null) || // We can't do YCC at all
    9.87 +                (cs != JPEG.JCS.YCC) ||
    9.88                  (cm.getNumComponents() != numComponents)) {
    9.89                  throw new IIOException("Incompatible color conversion");
    9.90              }
    10.1 --- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java	Tue Apr 07 11:43:20 2009 -0700
    10.2 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java	Tue Apr 07 14:02:54 2009 -0700
    10.3 @@ -39,8 +39,6 @@
    10.4      private static String [] writerSpiNames =
    10.5          {"com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi"};
    10.6  
    10.7 -    private boolean registered = false;
    10.8 -
    10.9      public JPEGImageReaderSpi() {
   10.10          super(JPEG.vendor,
   10.11                JPEG.version,
   10.12 @@ -61,26 +59,6 @@
   10.13                );
   10.14      }
   10.15  
   10.16 -    public void onRegistration(ServiceRegistry registry,
   10.17 -                               Class<?> category) {
   10.18 -        if (registered) {
   10.19 -            return;
   10.20 -        }
   10.21 -        try {
   10.22 -            java.security.AccessController.doPrivileged(
   10.23 -                new sun.security.action.LoadLibraryAction("jpeg"));
   10.24 -            // Stuff it all into one lib for first pass
   10.25 -            //java.security.AccessController.doPrivileged(
   10.26 -            //new sun.security.action.LoadLibraryAction("imageioIJG"));
   10.27 -        } catch (Throwable e) { // Fail on any Throwable
   10.28 -            // if it can't be loaded, deregister and return
   10.29 -            registry.deregisterServiceProvider(this);
   10.30 -            return;
   10.31 -        }
   10.32 -
   10.33 -        registered = true;
   10.34 -    }
   10.35 -
   10.36      public String getDescription(Locale locale) {
   10.37          return "Standard JPEG Image Reader";
   10.38      }
    11.1 --- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Tue Apr 07 11:43:20 2009 -0700
    11.2 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Tue Apr 07 14:02:54 2009 -0700
    11.3 @@ -812,13 +812,13 @@
    11.4                              }
    11.5                              break;
    11.6                          case ColorSpace.TYPE_3CLR:
    11.7 -                            if (cs == JPEG.YCC) {
    11.8 +                            if (cs == JPEG.JCS.YCC) {
    11.9                                  if (!alpha) {
   11.10                                      if (jfif != null) {
   11.11                                          convertTosRGB = true;
   11.12                                          convertOp =
   11.13                                          new ColorConvertOp(cs,
   11.14 -                                                           JPEG.sRGB,
   11.15 +                                                           JPEG.JCS.sRGB,
   11.16                                                             null);
   11.17                                          outCsType = JPEG.JCS_YCbCr;
   11.18                                      } else if (adobe != null) {
   11.19 @@ -1494,7 +1494,7 @@
   11.20                  }
   11.21                  break;
   11.22              case ColorSpace.TYPE_3CLR:
   11.23 -                if (cs == JPEG.YCC) {
   11.24 +                if (cs == JPEG.JCS.YCC) {
   11.25                      if (alpha) {
   11.26                          retval = JPEG.JCS_YCCA;
   11.27                      } else {
   11.28 @@ -1533,7 +1533,7 @@
   11.29                  }
   11.30                  break;
   11.31              case ColorSpace.TYPE_3CLR:
   11.32 -                if (cs == JPEG.YCC) {
   11.33 +                if (cs == JPEG.JCS.YCC) {
   11.34                      if (alpha) {
   11.35                          retval = JPEG.JCS_YCCA;
   11.36                      } else {
   11.37 @@ -1579,7 +1579,7 @@
   11.38                  }
   11.39                  break;
   11.40              case ColorSpace.TYPE_3CLR:
   11.41 -                if (cs == JPEG.YCC) {
   11.42 +                if (cs == JPEG.JCS.YCC) {
   11.43                      if (alpha) {
   11.44                          retval = JPEG.JCS_YCCA;
   11.45                      } else {
    12.1 --- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java	Tue Apr 07 11:43:20 2009 -0700
    12.2 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java	Tue Apr 07 14:02:54 2009 -0700
    12.3 @@ -42,8 +42,6 @@
    12.4      private static String [] readerSpiNames =
    12.5          {"com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi"};
    12.6  
    12.7 -    private boolean registered = false;
    12.8 -
    12.9      public JPEGImageWriterSpi() {
   12.10          super(JPEG.vendor,
   12.11                JPEG.version,
   12.12 @@ -68,23 +66,6 @@
   12.13          return "Standard JPEG Image Writer";
   12.14      }
   12.15  
   12.16 -    public void onRegistration(ServiceRegistry registry,
   12.17 -                               Class<?> category) {
   12.18 -        if (registered) {
   12.19 -            return;
   12.20 -        }
   12.21 -        try {
   12.22 -            java.security.AccessController.doPrivileged(
   12.23 -                new sun.security.action.LoadLibraryAction("jpeg"));
   12.24 -        } catch (Throwable e) { // Fail on any Throwable
   12.25 -            // if it can't be loaded, deregister and return
   12.26 -            registry.deregisterServiceProvider(this);
   12.27 -            return;
   12.28 -        }
   12.29 -
   12.30 -        registered = true;
   12.31 -    }
   12.32 -
   12.33      public boolean isFormatLossless() {
   12.34          return false;
   12.35      }
    13.1 --- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java	Tue Apr 07 11:43:20 2009 -0700
    13.2 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java	Tue Apr 07 14:02:54 2009 -0700
    13.3 @@ -490,7 +490,7 @@
    13.4                  }
    13.5                  break;
    13.6              case ColorSpace.TYPE_3CLR:
    13.7 -                if (cs == JPEG.YCC) {
    13.8 +                if (cs == JPEG.JCS.YCC) {
    13.9                      wantJFIF = false;
   13.10                      componentIDs[0] = (byte) 'Y';
   13.11                      componentIDs[1] = (byte) 'C';
   13.12 @@ -955,7 +955,7 @@
   13.13  
   13.14          // Lossless - false
   13.15          IIOMetadataNode lossless = new IIOMetadataNode("Lossless");
   13.16 -        lossless.setAttribute("value", "false");
   13.17 +        lossless.setAttribute("value", "FALSE");
   13.18          compression.appendChild(lossless);
   13.19  
   13.20          // NumProgressiveScans - count sos segments
    14.1 --- a/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java	Tue Apr 07 11:43:20 2009 -0700
    14.2 +++ b/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java	Tue Apr 07 14:02:54 2009 -0700
    14.3 @@ -37,6 +37,7 @@
    14.4  import java.io.BufferedInputStream;
    14.5  import java.io.ByteArrayInputStream;
    14.6  import java.io.DataInputStream;
    14.7 +import java.io.EOFException;
    14.8  import java.io.InputStream;
    14.9  import java.io.IOException;
   14.10  import java.io.SequenceInputStream;
   14.11 @@ -59,7 +60,7 @@
   14.12  import java.io.ByteArrayOutputStream;
   14.13  import sun.awt.image.ByteInterleavedRaster;
   14.14  
   14.15 -class PNGImageDataEnumeration implements Enumeration {
   14.16 +class PNGImageDataEnumeration implements Enumeration<InputStream> {
   14.17  
   14.18      boolean firstTime = true;
   14.19      ImageInputStream stream;
   14.20 @@ -72,7 +73,7 @@
   14.21          int type = stream.readInt(); // skip chunk type
   14.22      }
   14.23  
   14.24 -    public Object nextElement() {
   14.25 +    public InputStream nextElement() {
   14.26          try {
   14.27              firstTime = false;
   14.28              ImageInputStream iis = new SubImageInputStream(stream, length);
   14.29 @@ -207,25 +208,17 @@
   14.30          resetStreamSettings();
   14.31      }
   14.32  
   14.33 -    private String readNullTerminatedString(String charset) throws IOException {
   14.34 +    private String readNullTerminatedString(String charset, int maxLen) throws IOException {
   14.35          ByteArrayOutputStream baos = new ByteArrayOutputStream();
   14.36          int b;
   14.37 -        while ((b = stream.read()) != 0) {
   14.38 +        int count = 0;
   14.39 +        while ((maxLen > count++) && ((b = stream.read()) != 0)) {
   14.40 +            if (b == -1) throw new EOFException();
   14.41              baos.write(b);
   14.42          }
   14.43          return new String(baos.toByteArray(), charset);
   14.44      }
   14.45  
   14.46 -    private String readNullTerminatedString() throws IOException {
   14.47 -        StringBuilder b = new StringBuilder();
   14.48 -        int c;
   14.49 -
   14.50 -        while ((c = stream.read()) != 0) {
   14.51 -            b.append((char)c);
   14.52 -        }
   14.53 -        return b.toString();
   14.54 -    }
   14.55 -
   14.56      private void readHeader() throws IIOException {
   14.57          if (gotHeader) {
   14.58              return;
   14.59 @@ -434,7 +427,7 @@
   14.60      }
   14.61  
   14.62      private void parse_iCCP_chunk(int chunkLength) throws IOException {
   14.63 -        String keyword = readNullTerminatedString();
   14.64 +        String keyword = readNullTerminatedString("ISO-8859-1", 80);
   14.65          metadata.iCCP_profileName = keyword;
   14.66  
   14.67          metadata.iCCP_compressionMethod = stream.readUnsignedByte();
   14.68 @@ -450,7 +443,7 @@
   14.69      private void parse_iTXt_chunk(int chunkLength) throws IOException {
   14.70          long chunkStart = stream.getStreamPosition();
   14.71  
   14.72 -        String keyword = readNullTerminatedString();
   14.73 +        String keyword = readNullTerminatedString("ISO-8859-1", 80);
   14.74          metadata.iTXt_keyword.add(keyword);
   14.75  
   14.76          int compressionFlag = stream.readUnsignedByte();
   14.77 @@ -459,15 +452,17 @@
   14.78          int compressionMethod = stream.readUnsignedByte();
   14.79          metadata.iTXt_compressionMethod.add(Integer.valueOf(compressionMethod));
   14.80  
   14.81 -        String languageTag = readNullTerminatedString("UTF8");
   14.82 +        String languageTag = readNullTerminatedString("UTF8", 80);
   14.83          metadata.iTXt_languageTag.add(languageTag);
   14.84  
   14.85 +        long pos = stream.getStreamPosition();
   14.86 +        int maxLen = (int)(chunkStart + chunkLength - pos);
   14.87          String translatedKeyword =
   14.88 -            readNullTerminatedString("UTF8");
   14.89 +            readNullTerminatedString("UTF8", maxLen);
   14.90          metadata.iTXt_translatedKeyword.add(translatedKeyword);
   14.91  
   14.92          String text;
   14.93 -        long pos = stream.getStreamPosition();
   14.94 +        pos = stream.getStreamPosition();
   14.95          byte[] b = new byte[(int)(chunkStart + chunkLength - pos)];
   14.96          stream.readFully(b);
   14.97  
   14.98 @@ -511,7 +506,7 @@
   14.99  
  14.100      private void parse_sPLT_chunk(int chunkLength)
  14.101          throws IOException, IIOException {
  14.102 -        metadata.sPLT_paletteName = readNullTerminatedString();
  14.103 +        metadata.sPLT_paletteName = readNullTerminatedString("ISO-8859-1", 80);
  14.104          chunkLength -= metadata.sPLT_paletteName.length() + 1;
  14.105  
  14.106          int sampleDepth = stream.readUnsignedByte();
  14.107 @@ -554,12 +549,12 @@
  14.108      }
  14.109  
  14.110      private void parse_tEXt_chunk(int chunkLength) throws IOException {
  14.111 -        String keyword = readNullTerminatedString();
  14.112 +        String keyword = readNullTerminatedString("ISO-8859-1", 80);
  14.113          metadata.tEXt_keyword.add(keyword);
  14.114  
  14.115          byte[] b = new byte[chunkLength - keyword.length() - 1];
  14.116          stream.readFully(b);
  14.117 -        metadata.tEXt_text.add(new String(b));
  14.118 +        metadata.tEXt_text.add(new String(b, "ISO-8859-1"));
  14.119      }
  14.120  
  14.121      private void parse_tIME_chunk() throws IOException {
  14.122 @@ -640,7 +635,7 @@
  14.123      }
  14.124  
  14.125      private void parse_zTXt_chunk(int chunkLength) throws IOException {
  14.126 -        String keyword = readNullTerminatedString();
  14.127 +        String keyword = readNullTerminatedString("ISO-8859-1", 80);
  14.128          metadata.zTXt_keyword.add(keyword);
  14.129  
  14.130          int method = stream.readUnsignedByte();
  14.131 @@ -648,7 +643,7 @@
  14.132  
  14.133          byte[] b = new byte[chunkLength - keyword.length() - 2];
  14.134          stream.readFully(b);
  14.135 -        metadata.zTXt_text.add(new String(inflate(b)));
  14.136 +        metadata.zTXt_text.add(new String(inflate(b), "ISO-8859-1"));
  14.137      }
  14.138  
  14.139      private void readMetadata() throws IIOException {
  14.140 @@ -1263,7 +1258,7 @@
  14.141          try {
  14.142              stream.seek(imageStartPosition);
  14.143  
  14.144 -            Enumeration e = new PNGImageDataEnumeration(stream);
  14.145 +            Enumeration<InputStream> e = new PNGImageDataEnumeration(stream);
  14.146              InputStream is = new SequenceInputStream(e);
  14.147  
  14.148             /* InflaterInputStream uses an Inflater instance which consumes
    15.1 --- a/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java	Tue Apr 07 11:43:20 2009 -0700
    15.2 +++ b/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java	Tue Apr 07 14:02:54 2009 -0700
    15.3 @@ -674,13 +674,8 @@
    15.4      private byte[] deflate(byte[] b) throws IOException {
    15.5          ByteArrayOutputStream baos = new ByteArrayOutputStream();
    15.6          DeflaterOutputStream dos = new DeflaterOutputStream(baos);
    15.7 -
    15.8 -        int len = b.length;
    15.9 -        for (int i = 0; i < len; i++) {
   15.10 -            dos.write((int)(0xff & b[i]));
   15.11 -        }
   15.12 +        dos.write(b);
   15.13          dos.close();
   15.14 -
   15.15          return baos.toByteArray();
   15.16      }
   15.17  
   15.18 @@ -736,7 +731,7 @@
   15.19              cs.writeByte(compressionMethod);
   15.20  
   15.21              String text = (String)textIter.next();
   15.22 -            cs.write(deflate(text.getBytes()));
   15.23 +            cs.write(deflate(text.getBytes("ISO-8859-1")));
   15.24              cs.finish();
   15.25          }
   15.26      }
    16.1 --- a/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java	Tue Apr 07 11:43:20 2009 -0700
    16.2 +++ b/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java	Tue Apr 07 14:02:54 2009 -0700
    16.3 @@ -211,8 +211,8 @@
    16.4      public int sRGB_renderingIntent;
    16.5  
    16.6      // tEXt chunk
    16.7 -    public ArrayList tEXt_keyword = new ArrayList(); // 1-79 char Strings
    16.8 -    public ArrayList tEXt_text = new ArrayList(); // Strings
    16.9 +    public ArrayList<String> tEXt_keyword = new ArrayList<String>(); // 1-79 characters
   16.10 +    public ArrayList<String> tEXt_text = new ArrayList<String>();
   16.11  
   16.12      // tIME chunk
   16.13      public boolean tIME_present;
   16.14 @@ -235,13 +235,13 @@
   16.15      public int tRNS_blue;
   16.16  
   16.17      // zTXt chunk
   16.18 -    public ArrayList zTXt_keyword = new ArrayList(); // Strings
   16.19 -    public ArrayList zTXt_compressionMethod = new ArrayList(); // Integers
   16.20 -    public ArrayList zTXt_text = new ArrayList(); // Strings
   16.21 +    public ArrayList<String> zTXt_keyword = new ArrayList<String>();
   16.22 +    public ArrayList<Integer> zTXt_compressionMethod = new ArrayList<Integer>();
   16.23 +    public ArrayList<String> zTXt_text = new ArrayList<String>();
   16.24  
   16.25      // Unknown chunks
   16.26 -    public ArrayList unknownChunkType = new ArrayList(); // Strings
   16.27 -    public ArrayList unknownChunkData = new ArrayList(); // byte arrays
   16.28 +    public ArrayList<String> unknownChunkType = new ArrayList<String>();
   16.29 +    public ArrayList<byte[]> unknownChunkData = new ArrayList<byte[]>();
   16.30  
   16.31      public PNGMetadata() {
   16.32          super(true,
   16.33 @@ -426,21 +426,14 @@
   16.34          return false;
   16.35      }
   16.36  
   16.37 -    private ArrayList cloneBytesArrayList(ArrayList in) {
   16.38 +    private ArrayList<byte[]> cloneBytesArrayList(ArrayList<byte[]> in) {
   16.39          if (in == null) {
   16.40              return null;
   16.41          } else {
   16.42 -            ArrayList list = new ArrayList(in.size());
   16.43 -            Iterator iter = in.iterator();
   16.44 -            while (iter.hasNext()) {
   16.45 -                Object o = iter.next();
   16.46 -                if (o == null) {
   16.47 -                    list.add(null);
   16.48 -                } else {
   16.49 -                    list.add(((byte[])o).clone());
   16.50 -                }
   16.51 +            ArrayList<byte[]> list = new ArrayList<byte[]>(in.size());
   16.52 +            for (byte[] b: in) {
   16.53 +                list.add((b == null) ? null : (byte[])b.clone());
   16.54              }
   16.55 -
   16.56              return list;
   16.57          }
   16.58      }
   16.59 @@ -600,7 +593,7 @@
   16.60                  IIOMetadataNode iTXt_node = new IIOMetadataNode("iTXtEntry");
   16.61                  iTXt_node.setAttribute("keyword", iTXt_keyword.get(i));
   16.62                  iTXt_node.setAttribute("compressionFlag",
   16.63 -                        iTXt_compressionFlag.get(i) ? "1" : "0");
   16.64 +                        iTXt_compressionFlag.get(i) ? "TRUE" : "FALSE");
   16.65                  iTXt_node.setAttribute("compressionMethod",
   16.66                          iTXt_compressionMethod.get(i).toString());
   16.67                  iTXt_node.setAttribute("languageTag",
   16.68 @@ -832,7 +825,7 @@
   16.69          }
   16.70  
   16.71          node = new IIOMetadataNode("BlackIsZero");
   16.72 -        node.setAttribute("value", "true");
   16.73 +        node.setAttribute("value", "TRUE");
   16.74          chroma_node.appendChild(node);
   16.75  
   16.76          if (PLTE_present) {
   16.77 @@ -894,7 +887,7 @@
   16.78          compression_node.appendChild(node);
   16.79  
   16.80          node = new IIOMetadataNode("Lossless");
   16.81 -        node.setAttribute("value", "true");
   16.82 +        node.setAttribute("value", "TRUE");
   16.83          compression_node.appendChild(node);
   16.84  
   16.85          node = new IIOMetadataNode("NumProgressiveScans");
   16.86 @@ -1040,7 +1033,7 @@
   16.87              node.setAttribute("language",
   16.88                                iTXt_languageTag.get(i));
   16.89              if (iTXt_compressionFlag.get(i)) {
   16.90 -                node.setAttribute("compression", "deflate");
   16.91 +                node.setAttribute("compression", "zip");
   16.92              } else {
   16.93                  node.setAttribute("compression", "none");
   16.94              }
   16.95 @@ -1052,7 +1045,7 @@
   16.96              node = new IIOMetadataNode("TextEntry");
   16.97              node.setAttribute("keyword", (String)zTXt_keyword.get(i));
   16.98              node.setAttribute("value", (String)zTXt_text.get(i));
   16.99 -            node.setAttribute("compression", "deflate");
  16.100 +            node.setAttribute("compression", "zip");
  16.101  
  16.102              text_node.appendChild(node);
  16.103          }
  16.104 @@ -1162,12 +1155,13 @@
  16.105              }
  16.106          }
  16.107          String value = attr.getNodeValue();
  16.108 -        if (value.equals("true")) {
  16.109 +        // Allow lower case booleans for backward compatibility, #5082756
  16.110 +        if (value.equals("TRUE") || value.equals("true")) {
  16.111              return true;
  16.112 -        } else if (value.equals("false")) {
  16.113 +        } else if (value.equals("FALSE") || value.equals("false")) {
  16.114              return false;
  16.115          } else {
  16.116 -            fatal(node, "Attribute " + name + " must be 'true' or 'false'!");
  16.117 +            fatal(node, "Attribute " + name + " must be 'TRUE' or 'FALSE'!");
  16.118              return false;
  16.119          }
  16.120      }
  16.121 @@ -1421,26 +1415,30 @@
  16.122                      }
  16.123  
  16.124                      String keyword = getAttribute(iTXt_node, "keyword");
  16.125 -                    iTXt_keyword.add(keyword);
  16.126 +                    if (isValidKeyword(keyword)) {
  16.127 +                        iTXt_keyword.add(keyword);
  16.128  
  16.129 -                    boolean compressionFlag =
  16.130 -                        getBooleanAttribute(iTXt_node, "compressionFlag");
  16.131 -                    iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag));
  16.132 +                        boolean compressionFlag =
  16.133 +                            getBooleanAttribute(iTXt_node, "compressionFlag");
  16.134 +                        iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag));
  16.135  
  16.136 -                    String compressionMethod =
  16.137 -                        getAttribute(iTXt_node, "compressionMethod");
  16.138 -                    iTXt_compressionMethod.add(Integer.valueOf(compressionMethod));
  16.139 +                        String compressionMethod =
  16.140 +                            getAttribute(iTXt_node, "compressionMethod");
  16.141 +                        iTXt_compressionMethod.add(Integer.valueOf(compressionMethod));
  16.142  
  16.143 -                    String languageTag =
  16.144 -                        getAttribute(iTXt_node, "languageTag");
  16.145 -                    iTXt_languageTag.add(languageTag);
  16.146 +                        String languageTag =
  16.147 +                            getAttribute(iTXt_node, "languageTag");
  16.148 +                        iTXt_languageTag.add(languageTag);
  16.149  
  16.150 -                    String translatedKeyword =
  16.151 -                        getAttribute(iTXt_node, "translatedKeyword");
  16.152 -                    iTXt_translatedKeyword.add(translatedKeyword);
  16.153 +                        String translatedKeyword =
  16.154 +                            getAttribute(iTXt_node, "translatedKeyword");
  16.155 +                        iTXt_translatedKeyword.add(translatedKeyword);
  16.156  
  16.157 -                    String text = getAttribute(iTXt_node, "text");
  16.158 -                    iTXt_text.add(text);
  16.159 +                        String text = getAttribute(iTXt_node, "text");
  16.160 +                        iTXt_text.add(text);
  16.161 +
  16.162 +                    }
  16.163 +                    // silently skip invalid text entry
  16.164  
  16.165                      iTXt_node = iTXt_node.getNextSibling();
  16.166                  }
  16.167 @@ -1692,11 +1690,45 @@
  16.168          }
  16.169      }
  16.170  
  16.171 -    private boolean isISOLatin(String s) {
  16.172 +    /*
  16.173 +     * Accrding to PNG spec, keywords are restricted to 1 to 79 bytes
  16.174 +     * in length. Keywords shall contain only printable Latin-1 characters
  16.175 +     * and spaces; To reduce the chances for human misreading of a keyword,
  16.176 +     * leading spaces, trailing spaces, and consecutive spaces are not
  16.177 +     * permitted in keywords.
  16.178 +     *
  16.179 +     * See: http://www.w3.org/TR/PNG/#11keywords
  16.180 +     */
  16.181 +    private boolean isValidKeyword(String s) {
  16.182 +        int len = s.length();
  16.183 +        if (len < 1 || len >= 80) {
  16.184 +            return false;
  16.185 +        }
  16.186 +        if (s.startsWith(" ") || s.endsWith(" ") || s.contains("  ")) {
  16.187 +            return false;
  16.188 +        }
  16.189 +        return isISOLatin(s, false);
  16.190 +    }
  16.191 +
  16.192 +    /*
  16.193 +     * According to PNG spec, keyword shall contain only printable
  16.194 +     * Latin-1 [ISO-8859-1] characters and spaces; that is, only
  16.195 +     * character codes 32-126 and 161-255 decimal are allowed.
  16.196 +     * For Latin-1 value fields the 0x10 (linefeed) control
  16.197 +     * character is aloowed too.
  16.198 +     *
  16.199 +     * See: http://www.w3.org/TR/PNG/#11keywords
  16.200 +     */
  16.201 +    private boolean isISOLatin(String s, boolean isLineFeedAllowed) {
  16.202          int len = s.length();
  16.203          for (int i = 0; i < len; i++) {
  16.204 -            if (s.charAt(i) > 255) {
  16.205 -                return false;
  16.206 +            char c = s.charAt(i);
  16.207 +            if (c < 32 || c > 255 || (c > 126 && c < 161)) {
  16.208 +                // not printable. Check whether this is an allowed
  16.209 +                // control char
  16.210 +                if (!isLineFeedAllowed || c != 0x10) {
  16.211 +                    return false;
  16.212 +                }
  16.213              }
  16.214          }
  16.215          return true;
  16.216 @@ -1929,19 +1961,22 @@
  16.217                  while (child != null) {
  16.218                      String childName = child.getNodeName();
  16.219                      if (childName.equals("TextEntry")) {
  16.220 -                        String keyword = getAttribute(child, "keyword");
  16.221 +                        String keyword =
  16.222 +                            getAttribute(child, "keyword", "", false);
  16.223                          String value = getAttribute(child, "value");
  16.224 -                        String encoding = getAttribute(child, "encoding");
  16.225 -                        String language = getAttribute(child, "language");
  16.226 +                        String language =
  16.227 +                            getAttribute(child, "language", "", false);
  16.228                          String compression =
  16.229 -                            getAttribute(child, "compression");
  16.230 +                            getAttribute(child, "compression", "none", false);
  16.231  
  16.232 -                        if (isISOLatin(value)) {
  16.233 +                        if (!isValidKeyword(keyword)) {
  16.234 +                            // Just ignore this node, PNG requires keywords
  16.235 +                        } else if (isISOLatin(value, true)) {
  16.236                              if (compression.equals("zip")) {
  16.237                                  // Use a zTXt node
  16.238                                  zTXt_keyword.add(keyword);
  16.239                                  zTXt_text.add(value);
  16.240 -                                zTXt_compressionMethod.add(new Integer(0));
  16.241 +                                zTXt_compressionMethod.add(Integer.valueOf(0));
  16.242                              } else {
  16.243                                  // Use a tEXt node
  16.244                                  tEXt_keyword.add(keyword);
  16.245 @@ -1998,14 +2033,14 @@
  16.246          sBIT_present = false;
  16.247          sPLT_present = false;
  16.248          sRGB_present = false;
  16.249 -        tEXt_keyword = new ArrayList();
  16.250 -        tEXt_text = new ArrayList();
  16.251 +        tEXt_keyword = new ArrayList<String>();
  16.252 +        tEXt_text = new ArrayList<String>();
  16.253          tIME_present = false;
  16.254          tRNS_present = false;
  16.255 -        zTXt_keyword = new ArrayList();
  16.256 -        zTXt_compressionMethod = new ArrayList();
  16.257 -        zTXt_text = new ArrayList();
  16.258 -        unknownChunkType = new ArrayList();
  16.259 -        unknownChunkData = new ArrayList();
  16.260 +        zTXt_keyword = new ArrayList<String>();
  16.261 +        zTXt_compressionMethod = new ArrayList<Integer>();
  16.262 +        zTXt_text = new ArrayList<String>();
  16.263 +        unknownChunkType = new ArrayList<String>();
  16.264 +        unknownChunkData = new ArrayList<byte[]>();
  16.265      }
  16.266  }
    17.1 --- a/src/share/classes/com/sun/imageio/stream/StreamCloser.java	Tue Apr 07 11:43:20 2009 -0700
    17.2 +++ b/src/share/classes/com/sun/imageio/stream/StreamCloser.java	Tue Apr 07 14:02:54 2009 -0700
    17.3 @@ -94,6 +94,10 @@
    17.4                                   tgn != null;
    17.5                                   tg = tgn, tgn = tg.getParent());
    17.6                              streamCloser = new Thread(tg, streamCloserRunnable);
    17.7 +                            /* Set context class loader to null in order to avoid
    17.8 +                             * keeping a strong reference to an application classloader.
    17.9 +                             */
   17.10 +                            streamCloser.setContextClassLoader(null);
   17.11                              Runtime.getRuntime().addShutdownHook(streamCloser);
   17.12                              return null;
   17.13                          }
    18.1 --- a/src/share/classes/java/awt/GraphicsEnvironment.java	Tue Apr 07 11:43:20 2009 -0700
    18.2 +++ b/src/share/classes/java/awt/GraphicsEnvironment.java	Tue Apr 07 14:02:54 2009 -0700
    18.3 @@ -356,6 +356,9 @@
    18.4       * @since 1.5
    18.5       */
    18.6      public void preferLocaleFonts() {
    18.7 +        if (!(this instanceof SunGraphicsEnvironment)) {
    18.8 +            return;
    18.9 +        }
   18.10          sun.font.FontManager.preferLocaleFonts();
   18.11      }
   18.12  
   18.13 @@ -376,6 +379,9 @@
   18.14       * @since 1.5
   18.15       */
   18.16      public void preferProportionalFonts() {
   18.17 +        if (!(this instanceof SunGraphicsEnvironment)) {
   18.18 +            return;
   18.19 +        }
   18.20          sun.font.FontManager.preferProportionalFonts();
   18.21      }
   18.22  
    19.1 --- a/src/share/classes/java/awt/color/ICC_Profile.java	Tue Apr 07 11:43:20 2009 -0700
    19.2 +++ b/src/share/classes/java/awt/color/ICC_Profile.java	Tue Apr 07 14:02:54 2009 -0700
    19.3 @@ -737,7 +737,7 @@
    19.4      ICC_Profile(ProfileDeferralInfo pdi) {
    19.5          this.deferralInfo = pdi;
    19.6          this.profileActivator = new ProfileActivator() {
    19.7 -            public void activate() {
    19.8 +            public void activate() throws ProfileDataException {
    19.9                  activateDeferredProfile();
   19.10              }
   19.11          };
   19.12 @@ -830,20 +830,16 @@
   19.13          case ColorSpace.CS_sRGB:
   19.14              synchronized(ICC_Profile.class) {
   19.15                  if (sRGBprofile == null) {
   19.16 -                    try {
   19.17 -                        /*
   19.18 -                         * Deferral is only used for standard profiles.
   19.19 -                         * Enabling the appropriate access privileges is handled
   19.20 -                         * at a lower level.
   19.21 -                         */
   19.22 -                        sRGBprofile = getDeferredInstance(
   19.23 -                            new ProfileDeferralInfo("sRGB.pf",
   19.24 -                                                    ColorSpace.TYPE_RGB,
   19.25 -                                                    3, CLASS_DISPLAY));
   19.26 -                    } catch (IOException e) {
   19.27 -                        throw new IllegalArgumentException(
   19.28 -                              "Can't load standard profile: sRGB.pf");
   19.29 -                    }
   19.30 +                    /*
   19.31 +                     * Deferral is only used for standard profiles.
   19.32 +                     * Enabling the appropriate access privileges is handled
   19.33 +                     * at a lower level.
   19.34 +                     */
   19.35 +                    ProfileDeferralInfo pInfo =
   19.36 +                        new ProfileDeferralInfo("sRGB.pf",
   19.37 +                                                ColorSpace.TYPE_RGB, 3,
   19.38 +                                                CLASS_DISPLAY);
   19.39 +                    sRGBprofile = getDeferredInstance(pInfo);
   19.40                  }
   19.41                  thisProfile = sRGBprofile;
   19.42              }
   19.43 @@ -853,7 +849,11 @@
   19.44          case ColorSpace.CS_CIEXYZ:
   19.45              synchronized(ICC_Profile.class) {
   19.46                  if (XYZprofile == null) {
   19.47 -                    XYZprofile = getStandardProfile("CIEXYZ.pf");
   19.48 +                    ProfileDeferralInfo pInfo =
   19.49 +                        new ProfileDeferralInfo("CIEXYZ.pf",
   19.50 +                                                ColorSpace.TYPE_XYZ, 3,
   19.51 +                                                CLASS_DISPLAY);
   19.52 +                    XYZprofile = getDeferredInstance(pInfo);
   19.53                  }
   19.54                  thisProfile = XYZprofile;
   19.55              }
   19.56 @@ -863,7 +863,11 @@
   19.57          case ColorSpace.CS_PYCC:
   19.58              synchronized(ICC_Profile.class) {
   19.59                  if (PYCCprofile == null) {
   19.60 -                    PYCCprofile = getStandardProfile("PYCC.pf");
   19.61 +                    ProfileDeferralInfo pInfo =
   19.62 +                        new ProfileDeferralInfo("PYCC.pf",
   19.63 +                                                ColorSpace.TYPE_3CLR, 3,
   19.64 +                                                CLASS_DISPLAY);
   19.65 +                    PYCCprofile = getDeferredInstance(pInfo);
   19.66                  }
   19.67                  thisProfile = PYCCprofile;
   19.68              }
   19.69 @@ -873,7 +877,11 @@
   19.70          case ColorSpace.CS_GRAY:
   19.71              synchronized(ICC_Profile.class) {
   19.72                  if (GRAYprofile == null) {
   19.73 -                    GRAYprofile = getStandardProfile("GRAY.pf");
   19.74 +                    ProfileDeferralInfo pInfo =
   19.75 +                        new ProfileDeferralInfo("GRAY.pf",
   19.76 +                                                ColorSpace.TYPE_GRAY, 1,
   19.77 +                                                CLASS_DISPLAY);
   19.78 +                    GRAYprofile = getDeferredInstance(pInfo);
   19.79                  }
   19.80                  thisProfile = GRAYprofile;
   19.81              }
   19.82 @@ -883,7 +891,11 @@
   19.83          case ColorSpace.CS_LINEAR_RGB:
   19.84              synchronized(ICC_Profile.class) {
   19.85                  if (LINEAR_RGBprofile == null) {
   19.86 -                    LINEAR_RGBprofile = getStandardProfile("LINEAR_RGB.pf");
   19.87 +                    ProfileDeferralInfo pInfo =
   19.88 +                        new ProfileDeferralInfo("LINEAR_RGB.pf",
   19.89 +                                                ColorSpace.TYPE_RGB, 3,
   19.90 +                                                CLASS_DISPLAY);
   19.91 +                    LINEAR_RGBprofile = getDeferredInstance(pInfo);
   19.92                  }
   19.93                  thisProfile = LINEAR_RGBprofile;
   19.94              }
   19.95 @@ -1047,9 +1059,7 @@
   19.96       * code will take care of access privileges.
   19.97       * @see activateDeferredProfile()
   19.98       */
   19.99 -    static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi)
  19.100 -        throws IOException {
  19.101 -
  19.102 +    static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi) {
  19.103          if (!ProfileDeferralMgr.deferring) {
  19.104              return getStandardProfile(pdi.filename);
  19.105          }
  19.106 @@ -1063,33 +1073,37 @@
  19.107      }
  19.108  
  19.109  
  19.110 -    void activateDeferredProfile() {
  19.111 -    byte profileData[];
  19.112 -    FileInputStream fis;
  19.113 -    String fileName = deferralInfo.filename;
  19.114 +    void activateDeferredProfile() throws ProfileDataException {
  19.115 +        byte profileData[];
  19.116 +        FileInputStream fis;
  19.117 +        String fileName = deferralInfo.filename;
  19.118  
  19.119          profileActivator = null;
  19.120          deferralInfo = null;
  19.121          if ((fis = openProfile(fileName)) == null) {
  19.122 -            throw new IllegalArgumentException("Cannot open file " + fileName);
  19.123 +            throw new ProfileDataException("Cannot open file " + fileName);
  19.124          }
  19.125          try {
  19.126              profileData = getProfileDataFromStream(fis);
  19.127              fis.close();    /* close the file */
  19.128          }
  19.129          catch (IOException e) {
  19.130 -            throw new IllegalArgumentException("Invalid ICC Profile Data" +
  19.131 -                fileName);
  19.132 +            ProfileDataException pde = new
  19.133 +                ProfileDataException("Invalid ICC Profile Data" + fileName);
  19.134 +            pde.initCause(e);
  19.135 +            throw pde;
  19.136          }
  19.137          if (profileData == null) {
  19.138 -            throw new IllegalArgumentException("Invalid ICC Profile Data" +
  19.139 +            throw new ProfileDataException("Invalid ICC Profile Data" +
  19.140                  fileName);
  19.141          }
  19.142          try {
  19.143              ID = CMSManager.getModule().loadProfile(profileData);
  19.144          } catch (CMMException c) {
  19.145 -            throw new IllegalArgumentException("Invalid ICC Profile Data" +
  19.146 -                fileName);
  19.147 +            ProfileDataException pde = new
  19.148 +                ProfileDataException("Invalid ICC Profile Data" + fileName);
  19.149 +            pde.initCause(c);
  19.150 +            throw pde;
  19.151          }
  19.152      }
  19.153  
    20.1 --- a/src/share/classes/java/util/logging/LogManager.java	Tue Apr 07 11:43:20 2009 -0700
    20.2 +++ b/src/share/classes/java/util/logging/LogManager.java	Tue Apr 07 14:02:54 2009 -0700
    20.3 @@ -215,6 +215,14 @@
    20.4      // This private class is used as a shutdown hook.
    20.5      // It does a "reset" to close all open handlers.
    20.6      private class Cleaner extends Thread {
    20.7 +
    20.8 +        private Cleaner() {
    20.9 +            /* Set context class loader to null in order to avoid
   20.10 +             * keeping a strong reference to an application classloader.
   20.11 +             */
   20.12 +            this.setContextClassLoader(null);
   20.13 +        }
   20.14 +
   20.15          public void run() {
   20.16              // This is to ensure the LogManager.<clinit> is completed
   20.17              // before synchronized block. Otherwise deadlocks are possible.
    21.1 --- a/src/share/classes/javax/imageio/ImageTypeSpecifier.java	Tue Apr 07 11:43:20 2009 -0700
    21.2 +++ b/src/share/classes/javax/imageio/ImageTypeSpecifier.java	Tue Apr 07 14:02:54 2009 -0700
    21.3 @@ -67,126 +67,13 @@
    21.4       * <code>BufferedImage</code> types.
    21.5       */
    21.6      private static ImageTypeSpecifier[] BISpecifier;
    21.7 -
    21.8 +    private static ColorSpace sRGB;
    21.9      // Initialize the standard specifiers
   21.10      static {
   21.11 -        ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
   21.12 +        sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
   21.13  
   21.14          BISpecifier =
   21.15              new ImageTypeSpecifier[BufferedImage.TYPE_BYTE_INDEXED + 1];
   21.16 -
   21.17 -        BISpecifier[BufferedImage.TYPE_CUSTOM] = null;
   21.18 -
   21.19 -        BISpecifier[BufferedImage.TYPE_INT_RGB] =
   21.20 -            createPacked(sRGB,
   21.21 -                         0x00ff0000,
   21.22 -                         0x0000ff00,
   21.23 -                         0x000000ff,
   21.24 -                         0x0,
   21.25 -                         DataBuffer.TYPE_INT,
   21.26 -                         false);
   21.27 -
   21.28 -        BISpecifier[BufferedImage.TYPE_INT_ARGB] =
   21.29 -            createPacked(sRGB,
   21.30 -                         0x00ff0000,
   21.31 -                         0x0000ff00,
   21.32 -                         0x000000ff,
   21.33 -                         0xff000000,
   21.34 -                         DataBuffer.TYPE_INT,
   21.35 -                         false);
   21.36 -
   21.37 -        BISpecifier[BufferedImage.TYPE_INT_ARGB_PRE] =
   21.38 -            createPacked(sRGB,
   21.39 -                         0x00ff0000,
   21.40 -                         0x0000ff00,
   21.41 -                         0x000000ff,
   21.42 -                         0xff000000,
   21.43 -                         DataBuffer.TYPE_INT,
   21.44 -                         true);
   21.45 -
   21.46 -        BISpecifier[BufferedImage.TYPE_INT_BGR] =
   21.47 -            createPacked(sRGB,
   21.48 -                         0x000000ff,
   21.49 -                         0x0000ff00,
   21.50 -                         0x00ff0000,
   21.51 -                         0x0,
   21.52 -                         DataBuffer.TYPE_INT,
   21.53 -                         false);
   21.54 -
   21.55 -        int[] bOffsRGB = { 2, 1, 0 };
   21.56 -        BISpecifier[BufferedImage.TYPE_3BYTE_BGR] =
   21.57 -            createInterleaved(sRGB,
   21.58 -                              bOffsRGB,
   21.59 -                              DataBuffer.TYPE_BYTE,
   21.60 -                              false,
   21.61 -                              false);
   21.62 -
   21.63 -        int[] bOffsABGR = { 3, 2, 1, 0 };
   21.64 -        BISpecifier[BufferedImage.TYPE_4BYTE_ABGR] =
   21.65 -            createInterleaved(sRGB,
   21.66 -                              bOffsABGR,
   21.67 -                              DataBuffer.TYPE_BYTE,
   21.68 -                              true,
   21.69 -                              false);
   21.70 -
   21.71 -        BISpecifier[BufferedImage.TYPE_4BYTE_ABGR_PRE] =
   21.72 -            createInterleaved(sRGB,
   21.73 -                              bOffsABGR,
   21.74 -                              DataBuffer.TYPE_BYTE,
   21.75 -                              true,
   21.76 -                              true);
   21.77 -
   21.78 -        BISpecifier[BufferedImage.TYPE_USHORT_565_RGB] =
   21.79 -            createPacked(sRGB,
   21.80 -                         0xF800,
   21.81 -                         0x07E0,
   21.82 -                         0x001F,
   21.83 -                         0x0,
   21.84 -                         DataBuffer.TYPE_USHORT,
   21.85 -                         false);
   21.86 -
   21.87 -        BISpecifier[BufferedImage.TYPE_USHORT_555_RGB] =
   21.88 -            createPacked(sRGB,
   21.89 -                         0x7C00,
   21.90 -                         0x03E0,
   21.91 -                         0x001F,
   21.92 -                         0x0,
   21.93 -                         DataBuffer.TYPE_USHORT,
   21.94 -                         false);
   21.95 -
   21.96 -        BISpecifier[BufferedImage.TYPE_BYTE_GRAY] =
   21.97 -            createGrayscale(8,
   21.98 -                            DataBuffer.TYPE_BYTE,
   21.99 -                            false);
  21.100 -
  21.101 -        BISpecifier[BufferedImage.TYPE_USHORT_GRAY] =
  21.102 -            createGrayscale(16,
  21.103 -                            DataBuffer.TYPE_USHORT,
  21.104 -                            false);
  21.105 -
  21.106 -        BISpecifier[BufferedImage.TYPE_BYTE_BINARY] =
  21.107 -            createGrayscale(1,
  21.108 -                            DataBuffer.TYPE_BYTE,
  21.109 -                            false);
  21.110 -
  21.111 -        BufferedImage bi =
  21.112 -            new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED);
  21.113 -        IndexColorModel icm = (IndexColorModel)bi.getColorModel();
  21.114 -        int mapSize = icm.getMapSize();
  21.115 -        byte[] redLUT = new byte[mapSize];
  21.116 -        byte[] greenLUT = new byte[mapSize];
  21.117 -        byte[] blueLUT = new byte[mapSize];
  21.118 -        byte[] alphaLUT = new byte[mapSize];
  21.119 -
  21.120 -        icm.getReds(redLUT);
  21.121 -        icm.getGreens(greenLUT);
  21.122 -        icm.getBlues(blueLUT);
  21.123 -        icm.getAlphas(alphaLUT);
  21.124 -
  21.125 -        BISpecifier[BufferedImage.TYPE_BYTE_INDEXED] =
  21.126 -            createIndexed(redLUT, greenLUT, blueLUT, alphaLUT,
  21.127 -                          8,
  21.128 -                          DataBuffer.TYPE_BYTE);
  21.129      }
  21.130  
  21.131      /**
  21.132 @@ -1011,7 +898,7 @@
  21.133          ImageTypeSpecifier createFromBufferedImageType(int bufferedImageType) {
  21.134          if (bufferedImageType >= BufferedImage.TYPE_INT_RGB &&
  21.135              bufferedImageType <= BufferedImage.TYPE_BYTE_INDEXED) {
  21.136 -            return BISpecifier[bufferedImageType];
  21.137 +            return getSpecifier(bufferedImageType);
  21.138          } else if (bufferedImageType == BufferedImage.TYPE_CUSTOM) {
  21.139              throw new IllegalArgumentException("Cannot create from TYPE_CUSTOM!");
  21.140          } else {
  21.141 @@ -1041,7 +928,7 @@
  21.142          if (image instanceof BufferedImage) {
  21.143              int bufferedImageType = ((BufferedImage)image).getType();
  21.144              if (bufferedImageType != BufferedImage.TYPE_CUSTOM) {
  21.145 -                return BISpecifier[bufferedImageType];
  21.146 +                return getSpecifier(bufferedImageType);
  21.147              }
  21.148          }
  21.149  
  21.150 @@ -1225,4 +1112,130 @@
  21.151      public int hashCode() {
  21.152          return (9 * colorModel.hashCode()) + (14 * sampleModel.hashCode());
  21.153      }
  21.154 +
  21.155 +    private static ImageTypeSpecifier getSpecifier(int type) {
  21.156 +        if (BISpecifier[type] == null) {
  21.157 +            BISpecifier[type] = createSpecifier(type);
  21.158 +        }
  21.159 +        return BISpecifier[type];
  21.160 +    }
  21.161 +
  21.162 +    private static ImageTypeSpecifier createSpecifier(int type) {
  21.163 +        switch(type) {
  21.164 +          case BufferedImage.TYPE_INT_RGB:
  21.165 +              return createPacked(sRGB,
  21.166 +                                  0x00ff0000,
  21.167 +                                  0x0000ff00,
  21.168 +                                  0x000000ff,
  21.169 +                                  0x0,
  21.170 +                                  DataBuffer.TYPE_INT,
  21.171 +                                  false);
  21.172 +
  21.173 +          case BufferedImage.TYPE_INT_ARGB:
  21.174 +              return createPacked(sRGB,
  21.175 +                                  0x00ff0000,
  21.176 +                                  0x0000ff00,
  21.177 +                                  0x000000ff,
  21.178 +                                  0xff000000,
  21.179 +                                  DataBuffer.TYPE_INT,
  21.180 +                                  false);
  21.181 +
  21.182 +          case BufferedImage.TYPE_INT_ARGB_PRE:
  21.183 +              return createPacked(sRGB,
  21.184 +                                  0x00ff0000,
  21.185 +                                  0x0000ff00,
  21.186 +                                  0x000000ff,
  21.187 +                                  0xff000000,
  21.188 +                                  DataBuffer.TYPE_INT,
  21.189 +                                  true);
  21.190 +
  21.191 +          case BufferedImage.TYPE_INT_BGR:
  21.192 +              return createPacked(sRGB,
  21.193 +                                  0x000000ff,
  21.194 +                                  0x0000ff00,
  21.195 +                                  0x00ff0000,
  21.196 +                                  0x0,
  21.197 +                                  DataBuffer.TYPE_INT,
  21.198 +                                  false);
  21.199 +
  21.200 +          case BufferedImage.TYPE_3BYTE_BGR:
  21.201 +              return createInterleaved(sRGB,
  21.202 +                                       new int[] { 2, 1, 0 },
  21.203 +                                       DataBuffer.TYPE_BYTE,
  21.204 +                                       false,
  21.205 +                                       false);
  21.206 +
  21.207 +          case BufferedImage.TYPE_4BYTE_ABGR:
  21.208 +              return createInterleaved(sRGB,
  21.209 +                                       new int[] { 3, 2, 1, 0 },
  21.210 +                                       DataBuffer.TYPE_BYTE,
  21.211 +                                       true,
  21.212 +                                       false);
  21.213 +
  21.214 +          case BufferedImage.TYPE_4BYTE_ABGR_PRE:
  21.215 +              return createInterleaved(sRGB,
  21.216 +                                       new int[] { 3, 2, 1, 0 },
  21.217 +                                       DataBuffer.TYPE_BYTE,
  21.218 +                                       true,
  21.219 +                                       true);
  21.220 +
  21.221 +          case BufferedImage.TYPE_USHORT_565_RGB:
  21.222 +              return createPacked(sRGB,
  21.223 +                                  0xF800,
  21.224 +                                  0x07E0,
  21.225 +                                  0x001F,
  21.226 +                                  0x0,
  21.227 +                                  DataBuffer.TYPE_USHORT,
  21.228 +                                  false);
  21.229 +
  21.230 +          case BufferedImage.TYPE_USHORT_555_RGB:
  21.231 +              return createPacked(sRGB,
  21.232 +                                  0x7C00,
  21.233 +                                  0x03E0,
  21.234 +                                  0x001F,
  21.235 +                                  0x0,
  21.236 +                                  DataBuffer.TYPE_USHORT,
  21.237 +                                  false);
  21.238 +
  21.239 +          case BufferedImage.TYPE_BYTE_GRAY:
  21.240 +            return createGrayscale(8,
  21.241 +                                   DataBuffer.TYPE_BYTE,
  21.242 +                                   false);
  21.243 +
  21.244 +          case BufferedImage.TYPE_USHORT_GRAY:
  21.245 +            return createGrayscale(16,
  21.246 +                                   DataBuffer.TYPE_USHORT,
  21.247 +                                   false);
  21.248 +
  21.249 +          case BufferedImage.TYPE_BYTE_BINARY:
  21.250 +              return createGrayscale(1,
  21.251 +                                     DataBuffer.TYPE_BYTE,
  21.252 +                                     false);
  21.253 +
  21.254 +          case BufferedImage.TYPE_BYTE_INDEXED:
  21.255 +          {
  21.256 +
  21.257 +              BufferedImage bi =
  21.258 +                  new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED);
  21.259 +              IndexColorModel icm = (IndexColorModel)bi.getColorModel();
  21.260 +              int mapSize = icm.getMapSize();
  21.261 +              byte[] redLUT = new byte[mapSize];
  21.262 +              byte[] greenLUT = new byte[mapSize];
  21.263 +              byte[] blueLUT = new byte[mapSize];
  21.264 +              byte[] alphaLUT = new byte[mapSize];
  21.265 +
  21.266 +              icm.getReds(redLUT);
  21.267 +              icm.getGreens(greenLUT);
  21.268 +              icm.getBlues(blueLUT);
  21.269 +              icm.getAlphas(alphaLUT);
  21.270 +
  21.271 +              return createIndexed(redLUT, greenLUT, blueLUT, alphaLUT,
  21.272 +                                   8,
  21.273 +                                   DataBuffer.TYPE_BYTE);
  21.274 +          }
  21.275 +          default:
  21.276 +              throw new IllegalArgumentException("Invalid BufferedImage type!");
  21.277 +        }
  21.278 +    }
  21.279 +
  21.280  }
    22.1 --- a/src/share/classes/javax/imageio/metadata/IIOMetadataFormat.java	Tue Apr 07 11:43:20 2009 -0700
    22.2 +++ b/src/share/classes/javax/imageio/metadata/IIOMetadataFormat.java	Tue Apr 07 14:02:54 2009 -0700
    22.3 @@ -242,8 +242,12 @@
    22.4  
    22.5      /**
    22.6       * A constant returned by <code>getAttributeDataType</code>
    22.7 -     * indicating that the value of an attribute is one of 'true' or
    22.8 -     * 'false'.
    22.9 +     * indicating that the value of an attribute is one of the boolean
   22.10 +     * values 'true' or 'false'.
   22.11 +     * Attribute values of type DATATYPE_BOOLEAN should be marked as
   22.12 +     * enumerations, and the permitted values should be the string
   22.13 +     * literal values "TRUE" or "FALSE", although a plugin may also
   22.14 +     * recognise lower or mixed case equivalents.
   22.15       */
   22.16      int DATATYPE_BOOLEAN = 1;
   22.17  
    23.1 --- a/src/share/classes/sun/awt/FontConfiguration.java	Tue Apr 07 11:43:20 2009 -0700
    23.2 +++ b/src/share/classes/sun/awt/FontConfiguration.java	Tue Apr 07 14:02:54 2009 -0700
    23.3 @@ -98,7 +98,7 @@
    23.4          if (!inited) {
    23.5              this.preferLocaleFonts = false;
    23.6              this.preferPropFonts = false;
    23.7 -            fontConfig = this;      /* static initialization */
    23.8 +            setFontConfiguration();
    23.9              readFontConfigFile(fontConfigFile);
   23.10              initFontConfig();
   23.11              inited = true;
   23.12 @@ -1244,6 +1244,10 @@
   23.13          return fontConfig;
   23.14      }
   23.15  
   23.16 +    protected void setFontConfiguration() {
   23.17 +        fontConfig = this;      /* static initialization */
   23.18 +    }
   23.19 +
   23.20      //////////////////////////////////////////////////////////////////////
   23.21      // FontConfig data tables and the index constants in binary file    //
   23.22      //////////////////////////////////////////////////////////////////////
    24.1 --- a/src/share/classes/sun/font/FileFontStrike.java	Tue Apr 07 11:43:20 2009 -0700
    24.2 +++ b/src/share/classes/sun/font/FileFontStrike.java	Tue Apr 07 14:02:54 2009 -0700
    24.3 @@ -26,6 +26,7 @@
    24.4  package sun.font;
    24.5  
    24.6  import java.lang.ref.SoftReference;
    24.7 +import java.lang.ref.WeakReference;
    24.8  import java.awt.Font;
    24.9  import java.awt.GraphicsEnvironment;
   24.10  import java.awt.Rectangle;
   24.11 @@ -842,8 +843,36 @@
   24.12          return fileFont.getGlyphOutlineBounds(pScalerContext, glyphCode);
   24.13      }
   24.14  
   24.15 +    private
   24.16 +        WeakReference<ConcurrentHashMap<Integer,GeneralPath>> outlineMapRef;
   24.17 +
   24.18      GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
   24.19 -        return fileFont.getGlyphOutline(pScalerContext, glyphCode, x, y);
   24.20 +
   24.21 +        GeneralPath gp = null;
   24.22 +        ConcurrentHashMap<Integer, GeneralPath> outlineMap = null;
   24.23 +
   24.24 +        if (outlineMapRef != null) {
   24.25 +            outlineMap = outlineMapRef.get();
   24.26 +            if (outlineMap != null) {
   24.27 +                gp = (GeneralPath)outlineMap.get(glyphCode);
   24.28 +            }
   24.29 +        }
   24.30 +
   24.31 +        if (gp == null) {
   24.32 +            gp = fileFont.getGlyphOutline(pScalerContext, glyphCode, 0, 0);
   24.33 +            if (outlineMap == null) {
   24.34 +                outlineMap = new ConcurrentHashMap<Integer, GeneralPath>();
   24.35 +                outlineMapRef =
   24.36 +                   new WeakReference
   24.37 +                       <ConcurrentHashMap<Integer,GeneralPath>>(outlineMap);
   24.38 +            }
   24.39 +            outlineMap.put(glyphCode, gp);
   24.40 +        }
   24.41 +        gp = (GeneralPath)gp.clone(); // mutable!
   24.42 +        if (x != 0f || y != 0f) {
   24.43 +            gp.transform(AffineTransform.getTranslateInstance(x, y));
   24.44 +        }
   24.45 +        return gp;
   24.46      }
   24.47  
   24.48      GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
    25.1 --- a/src/share/classes/sun/font/FontManager.java	Tue Apr 07 11:43:20 2009 -0700
    25.2 +++ b/src/share/classes/sun/font/FontManager.java	Tue Apr 07 14:02:54 2009 -0700
    25.3 @@ -1601,18 +1601,27 @@
    25.4      /* Path may be absolute or a base file name relative to one of
    25.5       * the platform font directories
    25.6       */
    25.7 -    private static String getPathName(String s) {
    25.8 +    private static String getPathName(final String s) {
    25.9          File f = new File(s);
   25.10          if (f.isAbsolute()) {
   25.11              return s;
   25.12          } else if (pathDirs.length==1) {
   25.13              return pathDirs[0] + File.separator + s;
   25.14          } else {
   25.15 -            for (int p=0; p<pathDirs.length; p++) {
   25.16 -                f = new File(pathDirs[p] + File.separator + s);
   25.17 -                if (f.exists()) {
   25.18 -                    return f.getAbsolutePath();
   25.19 -                }
   25.20 +            String path = java.security.AccessController.doPrivileged(
   25.21 +                 new java.security.PrivilegedAction<String>() {
   25.22 +                     public String run() {
   25.23 +                         for (int p=0; p<pathDirs.length; p++) {
   25.24 +                             File f = new File(pathDirs[p] +File.separator+ s);
   25.25 +                             if (f.exists()) {
   25.26 +                                 return f.getAbsolutePath();
   25.27 +                             }
   25.28 +                         }
   25.29 +                         return null;
   25.30 +                     }
   25.31 +                });
   25.32 +            if (path != null) {
   25.33 +                return path;
   25.34              }
   25.35          }
   25.36          return s; // shouldn't happen, but harmless
    26.1 --- a/src/share/classes/sun/font/GlyphLayout.java	Tue Apr 07 11:43:20 2009 -0700
    26.2 +++ b/src/share/classes/sun/font/GlyphLayout.java	Tue Apr 07 14:02:54 2009 -0700
    26.3 @@ -338,6 +338,8 @@
    26.4                      cache = new ConcurrentHashMap<SDKey, SDCache>(10);
    26.5                      cacheRef = new
    26.6                         SoftReference<ConcurrentHashMap<SDKey, SDCache>>(cache);
    26.7 +                } else if (cache.size() >= 512) {
    26.8 +                    cache.clear();
    26.9                  }
   26.10                  cache.put(key, res);
   26.11              }
    27.1 --- a/src/share/classes/sun/font/StrikeCache.java	Tue Apr 07 11:43:20 2009 -0700
    27.2 +++ b/src/share/classes/sun/font/StrikeCache.java	Tue Apr 07 14:02:54 2009 -0700
    27.3 @@ -232,6 +232,16 @@
    27.4              if (disposer.pScalerContext != 0L) {
    27.5                  freeLongMemory(new long[0], disposer.pScalerContext);
    27.6              }
    27.7 +        } else if (disposer.pScalerContext != 0L) {
    27.8 +            /* Rarely a strike may have been created that never cached
    27.9 +             * any glyphs. In this case we still want to free the scaler
   27.10 +             * context.
   27.11 +             */
   27.12 +            if (FontManager.longAddresses) {
   27.13 +                freeLongMemory(new long[0], disposer.pScalerContext);
   27.14 +            } else {
   27.15 +                freeIntMemory(new int[0], disposer.pScalerContext);
   27.16 +            }
   27.17          }
   27.18      }
   27.19  
    28.1 --- a/src/share/classes/sun/java2d/cmm/ProfileActivator.java	Tue Apr 07 11:43:20 2009 -0700
    28.2 +++ b/src/share/classes/sun/java2d/cmm/ProfileActivator.java	Tue Apr 07 14:02:54 2009 -0700
    28.3 @@ -25,6 +25,7 @@
    28.4  
    28.5  package sun.java2d.cmm;
    28.6  
    28.7 +import java.awt.color.ProfileDataException;
    28.8  
    28.9  /**
   28.10   * An interface to allow the ProfileDeferralMgr to activate a
   28.11 @@ -35,6 +36,6 @@
   28.12      /**
   28.13       * Activate a previously deferred ICC_Profile object.
   28.14       */
   28.15 -    public void activate();
   28.16 +    public void activate() throws ProfileDataException;
   28.17  
   28.18  }
    29.1 --- a/src/share/classes/sun/java2d/cmm/ProfileDeferralMgr.java	Tue Apr 07 11:43:20 2009 -0700
    29.2 +++ b/src/share/classes/sun/java2d/cmm/ProfileDeferralMgr.java	Tue Apr 07 14:02:54 2009 -0700
    29.3 @@ -25,6 +25,7 @@
    29.4  
    29.5  package sun.java2d.cmm;
    29.6  
    29.7 +import java.awt.color.ProfileDataException;
    29.8  import java.util.Vector;
    29.9  
   29.10  
   29.11 @@ -39,7 +40,7 @@
   29.12  public class ProfileDeferralMgr {
   29.13  
   29.14      public static boolean deferring = true;
   29.15 -    private static Vector aVector;
   29.16 +    private static Vector<ProfileActivator> aVector;
   29.17  
   29.18      /**
   29.19       * Records a ProfileActivator object whose activate method will
   29.20 @@ -51,7 +52,7 @@
   29.21              return;
   29.22          }
   29.23          if (aVector == null) {
   29.24 -            aVector = new Vector(3, 3);
   29.25 +            aVector = new Vector<ProfileActivator>(3, 3);
   29.26          }
   29.27          aVector.addElement(pa);
   29.28          return;
   29.29 @@ -89,8 +90,26 @@
   29.30              return;
   29.31          }
   29.32          n = aVector.size();
   29.33 -        for (i = 0; i < n; i++) {
   29.34 -            ((ProfileActivator) aVector.get(i)).activate();
   29.35 +        for (ProfileActivator pa : aVector) {
   29.36 +            try {
   29.37 +                pa.activate();
   29.38 +            } catch (ProfileDataException e) {
   29.39 +                /*
   29.40 +                 * Ignore profile activation error for now:
   29.41 +                 * such exception is pssible due to absence
   29.42 +                 * or corruption of standard color profile.
   29.43 +                 * As for now we expect all profiles should
   29.44 +                 * be shiped with jre and presence of this
   29.45 +                 * exception is indication of some configuration
   29.46 +                 * problem in jre installation.
   29.47 +                 *
   29.48 +                 * NB: we still are greedy loading deferred profiles
   29.49 +                 * and load them all if any of them is needed.
   29.50 +                 * Therefore broken profile (if any) might be never used.
   29.51 +                 * If there will be attempt to use broken profile then
   29.52 +                 * it will result in CMMException.
   29.53 +                 */
   29.54 +            }
   29.55          }
   29.56          aVector.removeAllElements();
   29.57          aVector = null;
    30.1 --- a/src/share/classes/sun/java2d/pisces/Dasher.java	Tue Apr 07 11:43:20 2009 -0700
    30.2 +++ b/src/share/classes/sun/java2d/pisces/Dasher.java	Tue Apr 07 14:02:54 2009 -0700
    30.3 @@ -120,7 +120,7 @@
    30.4  
    30.5          // Normalize so 0 <= phase < dash[0]
    30.6          int idx = 0;
    30.7 -        dashOn = false;
    30.8 +        dashOn = true;
    30.9          int d;
   30.10          while (phase >= (d = dash[idx])) {
   30.11              phase -= d;
    31.1 --- a/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Tue Apr 07 11:43:20 2009 -0700
    31.2 +++ b/src/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java	Tue Apr 07 14:02:54 2009 -0700
    31.3 @@ -245,6 +245,7 @@
    31.4                               FloatToS15_16(coords[1]));
    31.5                  break;
    31.6              case PathIterator.SEG_CLOSE:
    31.7 +                lsink.lineJoin();
    31.8                  lsink.close();
    31.9                  break;
   31.10              default:
    32.1 --- a/src/share/classes/sun/print/ServiceDialog.java	Tue Apr 07 11:43:20 2009 -0700
    32.2 +++ b/src/share/classes/sun/print/ServiceDialog.java	Tue Apr 07 14:02:54 2009 -0700
    32.3 @@ -2149,55 +2149,51 @@
    32.4                          }
    32.5                      }
    32.6                  }
    32.7 -
    32.8 -                rbPortrait.setEnabled(pSupported);
    32.9 -                rbLandscape.setEnabled(lSupported);
   32.10 -                rbRevPortrait.setEnabled(rpSupported);
   32.11 -                rbRevLandscape.setEnabled(rlSupported);
   32.12 -
   32.13 -                OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
   32.14 -                if (or == null ||
   32.15 -                    !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
   32.16 -
   32.17 -                    or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
   32.18 -                    // need to validate if default is not supported
   32.19 -                    if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
   32.20 -                        or = null;
   32.21 -                        values =
   32.22 -                            psCurrent.getSupportedAttributeValues(orCategory,
   32.23 -                                                                  docFlavor,
   32.24 -                                                                  asCurrent);
   32.25 -                        if (values instanceof OrientationRequested[]) {
   32.26 -                            OrientationRequested[] orValues =
   32.27 -                                                (OrientationRequested[])values;
   32.28 -                            if (orValues.length > 1) {
   32.29 -                                // get the first in the list
   32.30 -                                or = orValues[0];
   32.31 -                            }
   32.32 +            }
   32.33 +
   32.34 +
   32.35 +            rbPortrait.setEnabled(pSupported);
   32.36 +            rbLandscape.setEnabled(lSupported);
   32.37 +            rbRevPortrait.setEnabled(rpSupported);
   32.38 +            rbRevLandscape.setEnabled(rlSupported);
   32.39 +
   32.40 +            OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
   32.41 +            if (or == null ||
   32.42 +                !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
   32.43 +
   32.44 +                or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
   32.45 +                // need to validate if default is not supported
   32.46 +                if ((or != null) &&
   32.47 +                   !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
   32.48 +                    or = null;
   32.49 +                    Object values =
   32.50 +                        psCurrent.getSupportedAttributeValues(orCategory,
   32.51 +                                                              docFlavor,
   32.52 +                                                              asCurrent);
   32.53 +                    if (values instanceof OrientationRequested[]) {
   32.54 +                        OrientationRequested[] orValues =
   32.55 +                                            (OrientationRequested[])values;
   32.56 +                        if (orValues.length > 1) {
   32.57 +                            // get the first in the list
   32.58 +                            or = orValues[0];
   32.59                          }
   32.60                      }
   32.61 -
   32.62 -                    if (or == null) {
   32.63 -                        or = OrientationRequested.PORTRAIT;
   32.64 -                    }
   32.65 -                    asCurrent.add(or);
   32.66                  }
   32.67  
   32.68 -                if (or == OrientationRequested.PORTRAIT) {
   32.69 -                    rbPortrait.setSelected(true);
   32.70 -                } else if (or == OrientationRequested.LANDSCAPE) {
   32.71 -                    rbLandscape.setSelected(true);
   32.72 -                } else if (or == OrientationRequested.REVERSE_PORTRAIT) {
   32.73 -                    rbRevPortrait.setSelected(true);
   32.74 -                } else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
   32.75 -                    rbRevLandscape.setSelected(true);
   32.76 +                if (or == null) {
   32.77 +                    or = OrientationRequested.PORTRAIT;
   32.78                  }
   32.79 -                } else {
   32.80 -                rbPortrait.setEnabled(pSupported);
   32.81 -                rbLandscape.setEnabled(lSupported);
   32.82 -                rbRevPortrait.setEnabled(rpSupported);
   32.83 -                rbRevLandscape.setEnabled(rlSupported);
   32.84 -
   32.85 +                asCurrent.add(or);
   32.86 +            }
   32.87 +
   32.88 +            if (or == OrientationRequested.PORTRAIT) {
   32.89 +                rbPortrait.setSelected(true);
   32.90 +            } else if (or == OrientationRequested.LANDSCAPE) {
   32.91 +                rbLandscape.setSelected(true);
   32.92 +            } else if (or == OrientationRequested.REVERSE_PORTRAIT) {
   32.93 +                rbRevPortrait.setSelected(true);
   32.94 +            } else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
   32.95 +                rbRevLandscape.setSelected(true);
   32.96              }
   32.97          }
   32.98      }
    33.1 --- a/src/share/native/sun/awt/image/dither.c	Tue Apr 07 11:43:20 2009 -0700
    33.2 +++ b/src/share/native/sun/awt/image/dither.c	Tue Apr 07 14:02:54 2009 -0700
    33.3 @@ -169,6 +169,7 @@
    33.4      int cubesize = cube_dim * cube_dim * cube_dim;
    33.5      unsigned char *useFlags;
    33.6      unsigned char *newILut = (unsigned char*)malloc(cubesize);
    33.7 +    int cmap_mid = (cmap_len >> 1) + (cmap_len & 0x1);
    33.8      if (newILut) {
    33.9  
   33.10        useFlags = (unsigned char *)calloc(cubesize, 1);
   33.11 @@ -188,7 +189,7 @@
   33.12          currentState.iLUT           = newILut;
   33.13  
   33.14          currentState.rgb = (unsigned short *)
   33.15 -                                malloc(256 * sizeof(unsigned short));
   33.16 +                                malloc(cmap_len * sizeof(unsigned short));
   33.17          if (currentState.rgb == NULL) {
   33.18              free(newILut);
   33.19              free(useFlags);
   33.20 @@ -199,7 +200,7 @@
   33.21          }
   33.22  
   33.23          currentState.indices = (unsigned char *)
   33.24 -                                malloc(256 * sizeof(unsigned char));
   33.25 +                                malloc(cmap_len * sizeof(unsigned char));
   33.26          if (currentState.indices == NULL) {
   33.27              free(currentState.rgb);
   33.28              free(newILut);
   33.29 @@ -210,18 +211,18 @@
   33.30              return NULL;
   33.31          }
   33.32  
   33.33 -        for (i = 0; i < 128; i++) {
   33.34 +        for (i = 0; i < cmap_mid; i++) {
   33.35              unsigned short rgb;
   33.36              int pixel = cmap[i];
   33.37              rgb = (pixel & 0x00f80000) >> 9;
   33.38              rgb |= (pixel & 0x0000f800) >> 6;
   33.39              rgb |=  (pixel & 0xf8) >> 3;
   33.40              INSERTNEW(currentState, rgb, i);
   33.41 -            pixel = cmap[255-i];
   33.42 +            pixel = cmap[cmap_len - i - 1];
   33.43              rgb = (pixel & 0x00f80000) >> 9;
   33.44              rgb |= (pixel & 0x0000f800) >> 6;
   33.45              rgb |=  (pixel & 0xf8) >> 3;
   33.46 -            INSERTNEW(currentState, rgb, 255-i);
   33.47 +            INSERTNEW(currentState, rgb, cmap_len - i - 1);
   33.48          }
   33.49  
   33.50          if (!recurseLevel(&currentState)) {
    34.1 --- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Tue Apr 07 11:43:20 2009 -0700
    34.2 +++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Tue Apr 07 14:02:54 2009 -0700
    34.3 @@ -396,7 +396,7 @@
    34.4      data->jpegObj = cinfo;
    34.5      cinfo->client_data = data;
    34.6  
    34.7 -#ifdef DEBUG
    34.8 +#ifdef DEBUG_IIO_JPEG
    34.9      printf("new structures: data is %p, cinfo is %p\n", data, cinfo);
   34.10  #endif
   34.11  
   34.12 @@ -673,7 +673,7 @@
   34.13      j_decompress_ptr decomp;
   34.14  
   34.15      qlen = (*env)->GetArrayLength(env, qtables);
   34.16 -#ifdef DEBUG
   34.17 +#ifdef DEBUG_IIO_JPEG
   34.18      printf("in setQTables, qlen = %d, write is %d\n", qlen, write);
   34.19  #endif
   34.20      for (i = 0; i < qlen; i++) {
   34.21 @@ -876,7 +876,7 @@
   34.22          return FALSE;
   34.23      }
   34.24  
   34.25 -#ifdef DEBUG
   34.26 +#ifdef DEBUG_IIO_JPEG
   34.27      printf("Filling input buffer, remaining skip is %ld, ",
   34.28             sb->remaining_skip);
   34.29      printf("Buffer length is %d\n", sb->bufferLength);
   34.30 @@ -906,7 +906,7 @@
   34.31              cinfo->err->error_exit((j_common_ptr) cinfo);
   34.32      }
   34.33  
   34.34 -#ifdef DEBUG
   34.35 +#ifdef DEBUG_IIO_JPEG
   34.36        printf("Buffer filled. ret = %d\n", ret);
   34.37  #endif
   34.38      /*
   34.39 @@ -917,7 +917,7 @@
   34.40       */
   34.41      if (ret <= 0) {
   34.42          jobject reader = data->imageIOobj;
   34.43 -#ifdef DEBUG
   34.44 +#ifdef DEBUG_IIO_JPEG
   34.45        printf("YO! Early EOI! ret = %d\n", ret);
   34.46  #endif
   34.47          RELEASE_ARRAYS(env, data, src->next_input_byte);
   34.48 @@ -1216,21 +1216,24 @@
   34.49  {
   34.50      jpeg_saved_marker_ptr marker;
   34.51      int num_markers = 0;
   34.52 +    int num_found_markers = 0;
   34.53      int seq_no;
   34.54      JOCTET *icc_data;
   34.55 +    JOCTET *dst_ptr;
   34.56      unsigned int total_length;
   34.57  #define MAX_SEQ_NO  255         // sufficient since marker numbers are bytes
   34.58 -    char marker_present[MAX_SEQ_NO+1];    // 1 if marker found
   34.59 -    unsigned int data_length[MAX_SEQ_NO+1]; // size of profile data in marker
   34.60 -    unsigned int data_offset[MAX_SEQ_NO+1]; // offset for data in marker
   34.61 +    jpeg_saved_marker_ptr icc_markers[MAX_SEQ_NO + 1];
   34.62 +    int first;         // index of the first marker in the icc_markers array
   34.63 +    int last;          // index of the last marker in the icc_markers array
   34.64      jbyteArray data = NULL;
   34.65  
   34.66      /* This first pass over the saved markers discovers whether there are
   34.67       * any ICC markers and verifies the consistency of the marker numbering.
   34.68       */
   34.69  
   34.70 -    for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
   34.71 -        marker_present[seq_no] = 0;
   34.72 +    for (seq_no = 0; seq_no <= MAX_SEQ_NO; seq_no++)
   34.73 +        icc_markers[seq_no] = NULL;
   34.74 +
   34.75  
   34.76      for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
   34.77          if (marker_is_icc(marker)) {
   34.78 @@ -1242,37 +1245,58 @@
   34.79                  return NULL;
   34.80              }
   34.81              seq_no = GETJOCTET(marker->data[12]);
   34.82 -            if (seq_no <= 0 || seq_no > num_markers) {
   34.83 +
   34.84 +            /* Some third-party tools produce images with profile chunk
   34.85 +             * numeration started from zero. It is inconsistent with ICC
   34.86 +             * spec, but seems to be recognized by majority of image
   34.87 +             * processing tools, so we should be more tolerant to this
   34.88 +             * departure from the spec.
   34.89 +             */
   34.90 +            if (seq_no < 0 || seq_no > num_markers) {
   34.91                  JNU_ThrowByName(env, "javax/imageio/IIOException",
   34.92                       "Invalid icc profile: bad sequence number");
   34.93                  return NULL;
   34.94              }
   34.95 -            if (marker_present[seq_no]) {
   34.96 +            if (icc_markers[seq_no] != NULL) {
   34.97                  JNU_ThrowByName(env, "javax/imageio/IIOException",
   34.98                       "Invalid icc profile: duplicate sequence numbers");
   34.99                  return NULL;
  34.100              }
  34.101 -            marker_present[seq_no] = 1;
  34.102 -            data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
  34.103 +            icc_markers[seq_no] = marker;
  34.104 +            num_found_markers ++;
  34.105          }
  34.106      }
  34.107  
  34.108      if (num_markers == 0)
  34.109          return NULL;  // There is no profile
  34.110  
  34.111 -    /* Check for missing markers, count total space needed,
  34.112 -     * compute offset of each marker's part of the data.
  34.113 +    if (num_markers != num_found_markers) {
  34.114 +        JNU_ThrowByName(env, "javax/imageio/IIOException",
  34.115 +                        "Invalid icc profile: invalid number of icc markers");
  34.116 +        return NULL;
  34.117 +    }
  34.118 +
  34.119 +    first = icc_markers[0] ? 0 : 1;
  34.120 +    last = num_found_markers + first;
  34.121 +
  34.122 +    /* Check for missing markers, count total space needed.
  34.123       */
  34.124 -
  34.125      total_length = 0;
  34.126 -    for (seq_no = 1; seq_no <= num_markers; seq_no++) {
  34.127 -        if (marker_present[seq_no] == 0) {
  34.128 +    for (seq_no = first; seq_no < last; seq_no++) {
  34.129 +        unsigned int length;
  34.130 +        if (icc_markers[seq_no] == NULL) {
  34.131              JNU_ThrowByName(env, "javax/imageio/IIOException",
  34.132                   "Invalid icc profile: missing sequence number");
  34.133              return NULL;
  34.134          }
  34.135 -        data_offset[seq_no] = total_length;
  34.136 -        total_length += data_length[seq_no];
  34.137 +        /* check the data length correctness */
  34.138 +        length = icc_markers[seq_no]->data_length;
  34.139 +        if (ICC_OVERHEAD_LEN > length || length > MAX_BYTES_IN_MARKER) {
  34.140 +            JNU_ThrowByName(env, "javax/imageio/IIOException",
  34.141 +                 "Invalid icc profile: invalid data length");
  34.142 +            return NULL;
  34.143 +        }
  34.144 +        total_length += (length - ICC_OVERHEAD_LEN);
  34.145      }
  34.146  
  34.147      if (total_length <= 0) {
  34.148 @@ -1301,19 +1325,14 @@
  34.149      }
  34.150  
  34.151      /* and fill it in */
  34.152 -    for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
  34.153 -        if (marker_is_icc(marker)) {
  34.154 -            JOCTET FAR *src_ptr;
  34.155 -            JOCTET *dst_ptr;
  34.156 -            unsigned int length;
  34.157 -            seq_no = GETJOCTET(marker->data[12]);
  34.158 -            dst_ptr = icc_data + data_offset[seq_no];
  34.159 -            src_ptr = marker->data + ICC_OVERHEAD_LEN;
  34.160 -            length = data_length[seq_no];
  34.161 -            while (length--) {
  34.162 -                *dst_ptr++ = *src_ptr++;
  34.163 -            }
  34.164 -        }
  34.165 +    dst_ptr = icc_data;
  34.166 +    for (seq_no = first; seq_no < last; seq_no++) {
  34.167 +        JOCTET FAR *src_ptr = icc_markers[seq_no]->data + ICC_OVERHEAD_LEN;
  34.168 +        unsigned int length =
  34.169 +            icc_markers[seq_no]->data_length - ICC_OVERHEAD_LEN;
  34.170 +
  34.171 +        memcpy(dst_ptr, src_ptr, length);
  34.172 +        dst_ptr += length;
  34.173      }
  34.174  
  34.175      /* finally, unpin the array */
  34.176 @@ -1530,6 +1549,7 @@
  34.177      j_decompress_ptr cinfo;
  34.178      struct jpeg_source_mgr *src;
  34.179      sun_jpeg_error_ptr jerr;
  34.180 +    jbyteArray profileData = NULL;
  34.181  
  34.182      if (data == NULL) {
  34.183          JNU_ThrowByName(env,
  34.184 @@ -1557,7 +1577,7 @@
  34.185          return retval;
  34.186      }
  34.187  
  34.188 -#ifdef DEBUG
  34.189 +#ifdef DEBUG_IIO_JPEG
  34.190      printf("In readImageHeader, data is %p cinfo is %p\n", data, cinfo);
  34.191      printf("clearFirst is %d\n", clearFirst);
  34.192  #endif
  34.193 @@ -1584,7 +1604,7 @@
  34.194      if (ret == JPEG_HEADER_TABLES_ONLY) {
  34.195          retval = JNI_TRUE;
  34.196          imageio_term_source(cinfo);  // Pushback remaining buffer contents
  34.197 -#ifdef DEBUG
  34.198 +#ifdef DEBUG_IIO_JPEG
  34.199          printf("just read tables-only image; q table 0 at %p\n",
  34.200                 cinfo->quant_tbl_ptrs[0]);
  34.201  #endif
  34.202 @@ -1691,6 +1711,14 @@
  34.203              }
  34.204          }
  34.205          RELEASE_ARRAYS(env, data, src->next_input_byte);
  34.206 +
  34.207 +        /* read icc profile data */
  34.208 +        profileData = read_icc_profile(env, cinfo);
  34.209 +
  34.210 +        if ((*env)->ExceptionCheck(env)) {
  34.211 +            return retval;
  34.212 +        }
  34.213 +
  34.214          (*env)->CallVoidMethod(env, this,
  34.215                                 JPEGImageReader_setImageDataID,
  34.216                                 cinfo->image_width,
  34.217 @@ -1698,7 +1726,7 @@
  34.218                                 cinfo->jpeg_color_space,
  34.219                                 cinfo->out_color_space,
  34.220                                 cinfo->num_components,
  34.221 -                               read_icc_profile(env, cinfo));
  34.222 +                               profileData);
  34.223          if (reset) {
  34.224              jpeg_abort_decompress(cinfo);
  34.225          }
  34.226 @@ -1827,7 +1855,7 @@
  34.227  
  34.228      (*env)->ReleaseIntArrayElements(env, srcBands, body, JNI_ABORT);
  34.229  
  34.230 -#ifdef DEBUG
  34.231 +#ifdef DEBUG_IIO_JPEG
  34.232      printf("---- in reader.read ----\n");
  34.233      printf("numBands is %d\n", numBands);
  34.234      printf("bands array: ");
  34.235 @@ -2487,7 +2515,7 @@
  34.236  
  34.237      data->streamBuf.suspendable = FALSE;
  34.238      if (qtables != NULL) {
  34.239 -#ifdef DEBUG
  34.240 +#ifdef DEBUG_IIO_JPEG
  34.241          printf("in writeTables: qtables not NULL\n");
  34.242  #endif
  34.243          setQTables(env, (j_common_ptr) cinfo, qtables, TRUE);
  34.244 @@ -2763,7 +2791,7 @@
  34.245  
  34.246      cinfo->restart_interval = restartInterval;
  34.247  
  34.248 -#ifdef DEBUG
  34.249 +#ifdef DEBUG_IIO_JPEG
  34.250      printf("writer setup complete, starting compressor\n");
  34.251  #endif
  34.252  
  34.253 @@ -2812,13 +2840,13 @@
  34.254              for (i = 0; i < numBands; i++) {
  34.255                  if (scale !=NULL && scale[i] != NULL) {
  34.256                      *out++ = scale[i][*(in+i)];
  34.257 -#ifdef DEBUG
  34.258 +#ifdef DEBUG_IIO_JPEG
  34.259                      if (in == data->pixelBuf.buf.bp){ // Just the first pixel
  34.260                          printf("in %d -> out %d, ", *(in+i), *(out-i-1));
  34.261                      }
  34.262  #endif
  34.263  
  34.264 -#ifdef DEBUG
  34.265 +#ifdef DEBUG_IIO_JPEG
  34.266                      if (in == data->pixelBuf.buf.bp){ // Just the first pixel
  34.267                          printf("\n");
  34.268                      }
    35.1 --- a/src/share/native/sun/font/freetypeScaler.c	Tue Apr 07 11:43:20 2009 -0700
    35.2 +++ b/src/share/native/sun/font/freetypeScaler.c	Tue Apr 07 14:02:54 2009 -0700
    35.3 @@ -394,12 +394,14 @@
    35.4      scalerInfo->env = env;
    35.5      scalerInfo->font2D = font2D;
    35.6  
    35.7 -    FT_Set_Transform(scalerInfo->face, &context->transform, NULL);
    35.8 +    if (context != NULL) {
    35.9 +        FT_Set_Transform(scalerInfo->face, &context->transform, NULL);
   35.10  
   35.11 -    errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72);
   35.12 +        errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72);
   35.13  
   35.14 -    if (errCode == 0) {
   35.15 -        errCode = FT_Activate_Size(scalerInfo->face->size);
   35.16 +        if (errCode == 0) {
   35.17 +            errCode = FT_Activate_Size(scalerInfo->face->size);
   35.18 +        }
   35.19      }
   35.20  
   35.21      return errCode;
   35.22 @@ -885,6 +887,14 @@
   35.23          JNIEnv *env, jobject scaler, jlong pScaler) {
   35.24      FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler);
   35.25  
   35.26 +    /* Freetype functions *may* cause callback to java
   35.27 +       that can use cached values. Make sure our cache is up to date.
   35.28 +       NB: scaler context is not important at this point, can use NULL. */
   35.29 +    int errCode = setupFTContext(env, scaler, scalerInfo, NULL);
   35.30 +    if (errCode) {
   35.31 +        return;
   35.32 +    }
   35.33 +
   35.34      freeNativeResources(env, scalerInfo);
   35.35  }
   35.36  
   35.37 @@ -932,12 +942,21 @@
   35.38          JNIEnv *env, jobject scaler, jlong pScaler, jchar charCode) {
   35.39  
   35.40      FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler);
   35.41 +    int errCode;
   35.42  
   35.43      if (scaler == NULL || scalerInfo->face == NULL) { /* bad/null scaler */
   35.44          invalidateJavaScaler(env, scaler, scalerInfo);
   35.45          return 0;
   35.46      }
   35.47  
   35.48 +    /* Freetype functions *may* cause callback to java
   35.49 +       that can use cached values. Make sure our cache is up to date.
   35.50 +       Scaler context is not important here, can use NULL. */
   35.51 +    errCode = setupFTContext(env, scaler, scalerInfo, NULL);
   35.52 +    if (errCode) {
   35.53 +        return 0;
   35.54 +    }
   35.55 +
   35.56      return FT_Get_Char_Index(scalerInfo->face, charCode);
   35.57  }
   35.58  
    36.1 --- a/src/share/native/sun/java2d/cmm/lcms/LCMS.c	Tue Apr 07 11:43:20 2009 -0700
    36.2 +++ b/src/share/native/sun/java2d/cmm/lcms/LCMS.c	Tue Apr 07 14:02:54 2009 -0700
    36.3 @@ -30,6 +30,41 @@
    36.4  #include "Disposer.h"
    36.5  #include "lcms.h"
    36.6  
    36.7 +
    36.8 +#define ALIGNLONG(x) (((x)+3) & ~(3))         // Aligns to DWORD boundary
    36.9 +
   36.10 +#ifdef USE_BIG_ENDIAN
   36.11 +#define AdjustEndianess32(a)
   36.12 +#else
   36.13 +
   36.14 +static
   36.15 +void AdjustEndianess32(LPBYTE pByte)
   36.16 +{
   36.17 +    BYTE temp1;
   36.18 +    BYTE temp2;
   36.19 +
   36.20 +    temp1 = *pByte++;
   36.21 +    temp2 = *pByte++;
   36.22 +    *(pByte-1) = *pByte;
   36.23 +    *pByte++ = temp2;
   36.24 +    *(pByte-3) = *pByte;
   36.25 +    *pByte = temp1;
   36.26 +}
   36.27 +
   36.28 +#endif
   36.29 +
   36.30 +// Transports to properly encoded values - note that icc profiles does use
   36.31 +// big endian notation.
   36.32 +
   36.33 +static
   36.34 +icInt32Number TransportValue32(icInt32Number Value)
   36.35 +{
   36.36 +    icInt32Number Temp = Value;
   36.37 +
   36.38 +    AdjustEndianess32((LPBYTE) &Temp);
   36.39 +    return Temp;
   36.40 +}
   36.41 +
   36.42  #define SigMake(a,b,c,d) \
   36.43                      ( ( ((int) ((unsigned char) (a))) << 24) | \
   36.44                        ( ((int) ((unsigned char) (b))) << 16) | \
   36.45 @@ -182,6 +217,8 @@
   36.46  
   36.47      sProf.pf = cmsOpenProfileFromMem((LPVOID)dataArray, (DWORD) dataSize);
   36.48  
   36.49 +    (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
   36.50 +
   36.51      if (sProf.pf == NULL) {
   36.52          JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
   36.53      }
   36.54 @@ -337,6 +374,10 @@
   36.55      return;
   36.56  }
   36.57  
   36.58 +// Modify data for a tag in a profile
   36.59 +LCMSBOOL LCMSEXPORT _cmsModifyTagData(cmsHPROFILE hProfile,
   36.60 +                                 icTagSignature sig, void *data, size_t size);
   36.61 +
   36.62  /*
   36.63   * Class:     sun_java2d_cmm_lcms_LCMS
   36.64   * Method:    setTagData
   36.65 @@ -345,7 +386,23 @@
   36.66  JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagData
   36.67    (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
   36.68  {
   36.69 -    fprintf(stderr, "setTagData operation is not implemented");
   36.70 +    cmsHPROFILE profile;
   36.71 +    storeID_t sProf;
   36.72 +    jbyte* dataArray;
   36.73 +    int tagSize;
   36.74 +
   36.75 +    if (tagSig == SigHead) {
   36.76 +        J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_setTagData on icSigHead not "
   36.77 +                      "permitted");
   36.78 +        return;
   36.79 +    }
   36.80 +
   36.81 +    sProf.j = id;
   36.82 +    profile = (cmsHPROFILE) sProf.pf;
   36.83 +    dataArray = (*env)->GetByteArrayElements(env, data, 0);
   36.84 +    tagSize =(*env)->GetArrayLength(env, data);
   36.85 +    _cmsModifyTagData(profile, (icTagSignature) tagSig, dataArray, tagSize);
   36.86 +    (*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
   36.87  }
   36.88  
   36.89  void* getILData (JNIEnv *env, jobject img, jint* pDataType,
   36.90 @@ -507,3 +564,174 @@
   36.91  
   36.92      PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
   36.93  }
   36.94 +
   36.95 +LCMSBOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig,
   36.96 +                       void *data, size_t size)
   36.97 +{
   36.98 +    LCMSBOOL isNew;
   36.99 +    int i, idx, delta, count;
  36.100 +    LPBYTE padChars[3] = {0, 0, 0};
  36.101 +    LPBYTE beforeBuf, afterBuf, ptr;
  36.102 +    size_t beforeSize, afterSize;
  36.103 +    icUInt32Number profileSize, temp;
  36.104 +    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  36.105 +
  36.106 +    isNew = FALSE;
  36.107 +    idx = _cmsSearchTag(Icc, sig, FALSE);
  36.108 +    if (idx < 0) {
  36.109 +        isNew = TRUE;
  36.110 +        idx = Icc->TagCount++;
  36.111 +        if (Icc->TagCount >= MAX_TABLE_TAG) {
  36.112 +            J2dRlsTraceLn1(J2D_TRACE_ERROR, "_cmsModifyTagData: Too many tags "
  36.113 +                           "(%d)\n", Icc->TagCount);
  36.114 +            Icc->TagCount = MAX_TABLE_TAG-1;
  36.115 +            return FALSE;
  36.116 +        }
  36.117 +    }
  36.118 +
  36.119 +    /* Read in size from header */
  36.120 +    Icc->Seek(Icc, 0);
  36.121 +    Icc->Read(&profileSize, sizeof(icUInt32Number), 1, Icc);
  36.122 +    AdjustEndianess32((LPBYTE) &profileSize);
  36.123 +
  36.124 +    /* Compute the change in profile size */
  36.125 +    if (isNew) {
  36.126 +        delta = sizeof(icTag) + ALIGNLONG(size);
  36.127 +    } else {
  36.128 +        delta = ALIGNLONG(size) - ALIGNLONG(Icc->TagSizes[idx]);
  36.129 +    }
  36.130 +    /* Add tag to internal structures */
  36.131 +    ptr = malloc(size);
  36.132 +    if (ptr == NULL) {
  36.133 +        if(isNew) {
  36.134 +            Icc->TagCount--;
  36.135 +        }
  36.136 +        J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: ptr == NULL");
  36.137 +        return FALSE;
  36.138 +    }
  36.139 +
  36.140 +    if (!Icc->Grow(Icc, delta)) {
  36.141 +        free(ptr);
  36.142 +        if(isNew) {
  36.143 +            Icc->TagCount--;
  36.144 +        }
  36.145 +        J2dRlsTraceLn(J2D_TRACE_ERROR,
  36.146 +                      "_cmsModifyTagData: Icc->Grow() == FALSE");
  36.147 +        return FALSE;
  36.148 +    }
  36.149 +
  36.150 +    /* Compute size of tag data before/after the modified tag */
  36.151 +    beforeSize = ((isNew)?profileSize:Icc->TagOffsets[idx]) -
  36.152 +                 Icc->TagOffsets[0];
  36.153 +    if (Icc->TagCount == (idx + 1)) {
  36.154 +        afterSize = 0;
  36.155 +    } else {
  36.156 +        afterSize = profileSize - Icc->TagOffsets[idx+1];
  36.157 +    }
  36.158 +    /* Make copies of the data before/after the modified tag */
  36.159 +    if (beforeSize > 0) {
  36.160 +        beforeBuf = malloc(beforeSize);
  36.161 +        if (!beforeBuf) {
  36.162 +            if(isNew) {
  36.163 +                Icc->TagCount--;
  36.164 +            }
  36.165 +            free(ptr);
  36.166 +            J2dRlsTraceLn(J2D_TRACE_ERROR,
  36.167 +                          "_cmsModifyTagData: beforeBuf == NULL");
  36.168 +            return FALSE;
  36.169 +        }
  36.170 +        Icc->Seek(Icc, Icc->TagOffsets[0]);
  36.171 +        Icc->Read(beforeBuf, beforeSize, 1, Icc);
  36.172 +    }
  36.173 +
  36.174 +    if (afterSize > 0) {
  36.175 +        afterBuf = malloc(afterSize);
  36.176 +        if (!afterBuf) {
  36.177 +            free(ptr);
  36.178 +            if(isNew) {
  36.179 +                Icc->TagCount--;
  36.180 +            }
  36.181 +            if (beforeSize > 0) {
  36.182 +                free(beforeBuf);
  36.183 +            }
  36.184 +            J2dRlsTraceLn(J2D_TRACE_ERROR,
  36.185 +                          "_cmsModifyTagData: afterBuf == NULL");
  36.186 +            return FALSE;
  36.187 +        }
  36.188 +        Icc->Seek(Icc, Icc->TagOffsets[idx+1]);
  36.189 +        Icc->Read(afterBuf, afterSize, 1, Icc);
  36.190 +    }
  36.191 +
  36.192 +    CopyMemory(ptr, data, size);
  36.193 +    Icc->TagSizes[idx] = size;
  36.194 +    Icc->TagNames[idx] = sig;
  36.195 +    if (Icc->TagPtrs[idx]) {
  36.196 +        free(Icc->TagPtrs[idx]);
  36.197 +    }
  36.198 +    Icc->TagPtrs[idx] = ptr;
  36.199 +    if (isNew) {
  36.200 +        Icc->TagOffsets[idx] = profileSize;
  36.201 +    }
  36.202 +
  36.203 +
  36.204 +    /* Update the profile size in the header */
  36.205 +    profileSize += delta;
  36.206 +    Icc->Seek(Icc, 0);
  36.207 +    temp = TransportValue32(profileSize);
  36.208 +    Icc->Write(Icc, sizeof(icUInt32Number), &temp);
  36.209 +
  36.210 +
  36.211 +    /* Adjust tag offsets: if the tag is new, we must account
  36.212 +       for the new tag table entry; otherwise, only those tags after
  36.213 +       the modified tag are changed (by delta) */
  36.214 +    if (isNew) {
  36.215 +        for (i = 0; i < Icc->TagCount; ++i) {
  36.216 +            Icc->TagOffsets[i] += sizeof(icTag);
  36.217 +        }
  36.218 +    } else {
  36.219 +        for (i = idx+1; i < Icc->TagCount; ++i) {
  36.220 +            Icc->TagOffsets[i] += delta;
  36.221 +        }
  36.222 +    }
  36.223 +
  36.224 +    /* Write out a new tag table */
  36.225 +    count = 0;
  36.226 +    for (i = 0; i < Icc->TagCount; ++i) {
  36.227 +        if (Icc->TagNames[i] != 0) {
  36.228 +            ++count;
  36.229 +        }
  36.230 +    }
  36.231 +    Icc->Seek(Icc, sizeof(icHeader));
  36.232 +    temp = TransportValue32(count);
  36.233 +    Icc->Write(Icc, sizeof(icUInt32Number), &temp);
  36.234 +
  36.235 +    for (i = 0; i < Icc->TagCount; ++i) {
  36.236 +        if (Icc->TagNames[i] != 0) {
  36.237 +            icTag tag;
  36.238 +            tag.sig = TransportValue32(Icc->TagNames[i]);
  36.239 +            tag.offset = TransportValue32((icInt32Number) Icc->TagOffsets[i]);
  36.240 +            tag.size = TransportValue32((icInt32Number) Icc->TagSizes[i]);
  36.241 +            Icc->Write(Icc, sizeof(icTag), &tag);
  36.242 +        }
  36.243 +    }
  36.244 +
  36.245 +    /* Write unchanged data before the modified tag */
  36.246 +    if (beforeSize > 0) {
  36.247 +        Icc->Write(Icc, beforeSize, beforeBuf);
  36.248 +        free(beforeBuf);
  36.249 +    }
  36.250 +
  36.251 +    /* Write modified tag data */
  36.252 +    Icc->Write(Icc, size, data);
  36.253 +    if (size % 4) {
  36.254 +        Icc->Write(Icc, 4 - (size % 4), padChars);
  36.255 +    }
  36.256 +
  36.257 +    /* Write unchanged data after the modified tag */
  36.258 +    if (afterSize > 0) {
  36.259 +        Icc->Write(Icc, afterSize, afterBuf);
  36.260 +        free(afterBuf);
  36.261 +    }
  36.262 +
  36.263 +    return TRUE;
  36.264 +}
    37.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmscam02.c	Tue Apr 07 11:43:20 2009 -0700
    37.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmscam02.c	Tue Apr 07 14:02:54 2009 -0700
    37.3 @@ -29,7 +29,7 @@
    37.4  //
    37.5  //
    37.6  //  Little cms
    37.7 -//  Copyright (C) 1998-2006 Marti Maria
    37.8 +//  Copyright (C) 1998-2007 Marti Maria
    37.9  //
   37.10  // Permission is hereby granted, free of charge, to any person obtaining
   37.11  // a copy of this software and associated documentation files (the "Software"),
   37.12 @@ -51,7 +51,7 @@
   37.13  
   37.14  
   37.15  
   37.16 -// CIECAM 02 appearance model
   37.17 +// CIECAM 02 appearance model. Many thanks to Jordi Vilar for the debugging.
   37.18  
   37.19  #include "lcms.h"
   37.20  
   37.21 @@ -196,6 +196,10 @@
   37.22              clr.RGBpa[i] = (400.0 * temp) / (temp + 27.13) + 0.1;
   37.23          }
   37.24      }
   37.25 +
   37.26 +    clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] +
   37.27 +        (clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb;
   37.28 +
   37.29      return clr;
   37.30  }
   37.31  
   37.32 @@ -249,9 +253,6 @@
   37.33          clr.H = 300 + ((100*((clr.h - 237.53)/1.2)) / temp);
   37.34      }
   37.35  
   37.36 -    clr.A = (((2.0 * clr.RGBpa[0]) + clr.RGBpa[1] +
   37.37 -        (clr.RGBpa[2] / 20.0)) - 0.305) * pMod->Nbb;
   37.38 -
   37.39      clr.J = 100.0 * pow((clr.A / pMod->adoptedWhite.A),
   37.40          (pMod->c * pMod->z));
   37.41  
   37.42 @@ -395,7 +396,7 @@
   37.43      LPcmsCIECAM02 lpMod;
   37.44  
   37.45  
   37.46 -   if((lpMod = (LPcmsCIECAM02) malloc(sizeof(cmsCIECAM02))) == NULL) {
   37.47 +   if((lpMod = (LPcmsCIECAM02) _cmsMalloc(sizeof(cmsCIECAM02))) == NULL) {
   37.48          return (LCMSHANDLE) NULL;
   37.49      }
   37.50  
   37.51 @@ -449,14 +450,19 @@
   37.52      lpMod -> z   = compute_z(lpMod);
   37.53      lpMod -> Nbb = computeNbb(lpMod);
   37.54      lpMod -> FL  = computeFL(lpMod);
   37.55 +
   37.56 +    if (lpMod -> D == D_CALCULATE ||
   37.57 +        lpMod -> D == D_CALCULATE_DISCOUNT) {
   37.58 +
   37.59      lpMod -> D   = computeD(lpMod);
   37.60 +    }
   37.61 +
   37.62      lpMod -> Ncb = lpMod -> Nbb;
   37.63  
   37.64      lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite);
   37.65      lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod);
   37.66      lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite);
   37.67      lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod);
   37.68 -    lpMod -> adoptedWhite = ComputeCorrelates(lpMod -> adoptedWhite, lpMod);
   37.69  
   37.70      return (LCMSHANDLE) lpMod;
   37.71  
   37.72 @@ -465,7 +471,7 @@
   37.73  void LCMSEXPORT cmsCIECAM02Done(LCMSHANDLE hModel)
   37.74  {
   37.75      LPcmsCIECAM02 lpMod = (LPcmsCIECAM02) (LPSTR) hModel;
   37.76 -    if (lpMod) free(lpMod);
   37.77 +    if (lpMod) _cmsFree(lpMod);
   37.78  }
   37.79  
   37.80  
   37.81 @@ -510,3 +516,4 @@
   37.82      pOut ->Z = clr.XYZ[2];
   37.83  
   37.84  }
   37.85 +
    38.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmscam97.c	Tue Apr 07 11:43:20 2009 -0700
    38.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmscam97.c	Tue Apr 07 14:02:54 2009 -0700
    38.3 @@ -29,7 +29,7 @@
    38.4  //
    38.5  //
    38.6  //  Little cms
    38.7 -//  Copyright (C) 1998-2006 Marti Maria
    38.8 +//  Copyright (C) 1998-2007 Marti Maria
    38.9  //
   38.10  // Permission is hereby granted, free of charge, to any person obtaining
   38.11  // a copy of this software and associated documentation files (the "Software"),
   38.12 @@ -174,7 +174,7 @@
   38.13  LCMSAPI void LCMSEXPORT cmsCIECAM97sDone(LCMSHANDLE hModel)
   38.14  {
   38.15      LPcmsCIECAM97s lpMod = (LPcmsCIECAM97s) (LPSTR) hModel;
   38.16 -    if (lpMod) free(lpMod);
   38.17 +    if (lpMod) _cmsFree(lpMod);
   38.18  }
   38.19  
   38.20  // Partial discounting for adaptation degree computation
   38.21 @@ -331,7 +331,7 @@
   38.22      LPcmsCIECAM97s lpMod;
   38.23      VEC3 tmp;
   38.24  
   38.25 -    if((lpMod = (LPcmsCIECAM97s) malloc(sizeof(cmsCIECAM97s))) == NULL) {
   38.26 +    if((lpMod = (LPcmsCIECAM97s) _cmsMalloc(sizeof(cmsCIECAM97s))) == NULL) {
   38.27          return (LCMSHANDLE) NULL;
   38.28      }
   38.29  
   38.30 @@ -449,7 +449,7 @@
   38.31  
   38.32      // RGB_subw = [MlamRigg][WP/YWp]
   38.33  #ifdef USE_CIECAM97s2
   38.34 -    MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, (LPVEC3) &lpMod -> WP);
   38.35 +    MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &lpMod -> WP);
   38.36  #else
   38.37      VEC3divK(&tmp, (LPVEC3) &lpMod -> WP, lpMod->WP.Y);
   38.38      MAT3eval(&lpMod -> RGB_subw, &lpMod -> MlamRigg, &tmp);
    39.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmscgats.c	Tue Apr 07 11:43:20 2009 -0700
    39.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmscgats.c	Tue Apr 07 14:02:54 2009 -0700
    39.3 @@ -29,7 +29,7 @@
    39.4  //
    39.5  //
    39.6  //  Little cms
    39.7 -//  Copyright (C) 1998-2006 Marti Maria
    39.8 +//  Copyright (C) 1998-2007 Marti Maria
    39.9  //
   39.10  // Permission is hereby granted, free of charge, to any person obtaining
   39.11  // a copy of this software and associated documentation files (the "Software"),
   39.12 @@ -65,22 +65,25 @@
   39.13  // Persistence
   39.14  LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName);
   39.15  LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len);
   39.16 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
   39.17 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
   39.18  
   39.19  // Properties
   39.20  LCMSAPI const char*     LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8);
   39.21 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
   39.22 -
   39.23 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
   39.24 -
   39.25 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
   39.26 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
   39.27 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
   39.28 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
   39.29 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
   39.30 +
   39.31 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
   39.32 +
   39.33 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
   39.34 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
   39.35 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
   39.36 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char* cSubProp, const char *Val);
   39.37 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
   39.38  
   39.39  LCMSAPI const char*     LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp);
   39.40  LCMSAPI double          LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp);
   39.41 -LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames);
   39.42 +LCMSAPI const char*     LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char *cSubProp);
   39.43 +LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, const char ***PropertyNames);
   39.44 +LCMSAPI int             LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char*** SubpropertyNames);
   39.45  
   39.46  // Datasets
   39.47  
   39.48 @@ -89,10 +92,10 @@
   39.49  LCMSAPI const char*     LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col);
   39.50  LCMSAPI double          LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int col, int row);
   39.51  
   39.52 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col,
   39.53 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col,
   39.54                                                  const char* Val);
   39.55  
   39.56 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col,
   39.57 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col,
   39.58                                                  double Val);
   39.59  
   39.60  LCMSAPI const char*     LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
   39.61 @@ -100,15 +103,15 @@
   39.62  
   39.63  LCMSAPI double          LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
   39.64  
   39.65 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
   39.66 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
   39.67                                                  const char* cSample,
   39.68                                                  const char *Val);
   39.69  
   39.70 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
   39.71 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
   39.72                                                  const char* cSample,
   39.73                                                  double Val);
   39.74  
   39.75 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
   39.76 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
   39.77  LCMSAPI int             LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames);
   39.78  
   39.79  LCMSAPI void            LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter);
   39.80 @@ -126,7 +129,7 @@
   39.81  // #define STRICT_CGATS  1
   39.82  
   39.83  #define MAXID       128     // Max lenght of identifier
   39.84 -#define MAXSTR      255     // Max lenght of string
   39.85 +#define MAXSTR      1024     // Max lenght of string
   39.86  #define MAXTABLES   255     // Max Number of tables in a single stream
   39.87  #define MAXINCLUDE   20     // Max number of nested includes
   39.88  
   39.89 @@ -137,6 +140,9 @@
   39.90  
   39.91  #ifndef NON_WINDOWS
   39.92  #include <io.h>
   39.93 +#define DIR_CHAR    '\\'
   39.94 +#else
   39.95 +#define DIR_CHAR    '/'
   39.96  #endif
   39.97  
   39.98  // Symbols
   39.99 @@ -160,6 +166,7 @@
  39.100          SEND_DATA,
  39.101          SEND_DATA_FORMAT,
  39.102          SKEYWORD,
  39.103 +        SDATA_FORMAT_ID,
  39.104          SINCLUDE
  39.105  
  39.106      } SYMBOL;
  39.107 @@ -171,7 +178,8 @@
  39.108          WRITE_UNCOOKED,
  39.109          WRITE_STRINGIFY,
  39.110          WRITE_HEXADECIMAL,
  39.111 -        WRITE_BINARY
  39.112 +        WRITE_BINARY,
  39.113 +        WRITE_PAIR
  39.114  
  39.115      } WRITEMODE;
  39.116  
  39.117 @@ -181,6 +189,8 @@
  39.118  
  39.119          struct _KeyVal*  Next;
  39.120          char*            Keyword;       // Name of variable
  39.121 +        struct _KeyVal*  NextSubkey;    // If key is a dictionary, points to the next item
  39.122 +        char*            Subkey;        // If key is a dictionary, points to the subkey name
  39.123          char*            Value;         // Points to value
  39.124          WRITEMODE        WriteAs;       // How to write the value
  39.125  
  39.126 @@ -220,7 +230,12 @@
  39.127  
  39.128      } TABLE, *LPTABLE;
  39.129  
  39.130 -
  39.131 +// File stream being parsed
  39.132 +
  39.133 +typedef struct _FileContext {
  39.134 +        char           FileName[MAX_PATH];    // File name if being readed from file
  39.135 +        FILE*          Stream;                // File stream or NULL if holded in memory
  39.136 +    } FILECTX, *LPFILECTX;
  39.137  
  39.138  // This struct hold all information about an openened
  39.139  // IT8 handler. Only one dataset is allowed.
  39.140 @@ -257,9 +272,9 @@
  39.141          char*          Source;                // Points to loc. being parsed
  39.142          int            lineno;                // line counter for error reporting
  39.143  
  39.144 -        char           FileName[MAX_PATH];    // File name if being readed from file
  39.145 -        FILE*          Stream[MAXINCLUDE];    // File stream or NULL if holded in memory
  39.146 +        LPFILECTX      FileStack[MAXINCLUDE]; // Stack of files being parsed
  39.147          int            IncludeSP;             // Include Stack Pointer
  39.148 +
  39.149          char*          MemoryBlock;           // The stream if holded in memory
  39.150  
  39.151          char           DoubleFormatter[MAXID];   // Printf-like 'double' formatter
  39.152 @@ -270,14 +285,14 @@
  39.153  
  39.154  typedef struct {
  39.155  
  39.156 -                FILE* stream;   // For save-to-file behaviour
  39.157 -
  39.158 -                LPBYTE Base;
  39.159 -                LPBYTE Ptr;             // For save-to-mem behaviour
  39.160 -                size_t Used;
  39.161 -                size_t Max;
  39.162 -
  39.163 -        } SAVESTREAM, FAR* LPSAVESTREAM;
  39.164 +        FILE* stream;   // For save-to-file behaviour
  39.165 +
  39.166 +        LPBYTE Base;
  39.167 +        LPBYTE Ptr;     // For save-to-mem behaviour
  39.168 +        size_t Used;
  39.169 +        size_t Max;
  39.170 +
  39.171 +    } SAVESTREAM, FAR* LPSAVESTREAM;
  39.172  
  39.173  
  39.174  // ------------------------------------------------------ IT8 parsing routines
  39.175 @@ -298,59 +313,104 @@
  39.176          {".INCLUDE",            SINCLUDE},
  39.177          {"BEGIN_DATA",          SBEGIN_DATA },
  39.178          {"BEGIN_DATA_FORMAT",   SBEGIN_DATA_FORMAT },
  39.179 +        {"DATA_FORMAT_IDENTIFIER", SDATA_FORMAT_ID},
  39.180          {"END_DATA",            SEND_DATA},
  39.181          {"END_DATA_FORMAT",     SEND_DATA_FORMAT},
  39.182          {"KEYWORD",             SKEYWORD}
  39.183 -
  39.184          };
  39.185  
  39.186  #define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD))
  39.187  
  39.188  // Predefined properties
  39.189  
  39.190 -static const char* PredefinedProperties[] = {
  39.191 -
  39.192 -        "NUMBER_OF_FIELDS",    // Required - NUMBER OF FIELDS
  39.193 -        "NUMBER_OF_SETS",      // Required - NUMBER OF SETS
  39.194 -        "ORIGINATOR",          // Required - Identifies the specific system, organization or individual that created the data file.
  39.195 -        "FILE_DESCRIPTOR",     // Required - Describes the purpose or contents of the data file.
  39.196 -        "CREATED",             // Required - Indicates date of creation of the data file.
  39.197 -        "DESCRIPTOR",          // Required  - Describes the purpose or contents of the data file.
  39.198 -        "DIFFUSE_GEOMETRY",    // The diffuse geometry used. Allowed values are "sphere" or "opal".
  39.199 -        "MANUFACTURER",
  39.200 -        "MANUFACTURE",         // Some broken Fuji targets does store this value
  39.201 -        "PROD_DATE",           // Identifies year and month of production of the target in the form yyyy:mm.
  39.202 -        "SERIAL",              // Uniquely identifies individual physical target.
  39.203 -
  39.204 -        "MATERIAL",            // Identifies the material on which the target was produced using a code
  39.205 +// A property
  39.206 +typedef struct {
  39.207 +        const char *id;
  39.208 +        WRITEMODE as;
  39.209 +    } PROPERTY;
  39.210 +
  39.211 +static PROPERTY PredefinedProperties[] = {
  39.212 +
  39.213 +        {"NUMBER_OF_FIELDS", WRITE_UNCOOKED},    // Required - NUMBER OF FIELDS
  39.214 +        {"NUMBER_OF_SETS",   WRITE_UNCOOKED},    // Required - NUMBER OF SETS
  39.215 +        {"ORIGINATOR",       WRITE_STRINGIFY},   // Required - Identifies the specific system, organization or individual that created the data file.
  39.216 +        {"FILE_DESCRIPTOR",  WRITE_STRINGIFY},   // Required - Describes the purpose or contents of the data file.
  39.217 +        {"CREATED",          WRITE_STRINGIFY},   // Required - Indicates date of creation of the data file.
  39.218 +        {"DESCRIPTOR",       WRITE_STRINGIFY},   // Required  - Describes the purpose or contents of the data file.
  39.219 +        {"DIFFUSE_GEOMETRY", WRITE_STRINGIFY},   // The diffuse geometry used. Allowed values are "sphere" or "opal".
  39.220 +        {"MANUFACTURER",     WRITE_STRINGIFY},
  39.221 +        {"MANUFACTURE",      WRITE_STRINGIFY},   // Some broken Fuji targets does store this value
  39.222 +        {"PROD_DATE",        WRITE_STRINGIFY},   // Identifies year and month of production of the target in the form yyyy:mm.
  39.223 +        {"SERIAL",           WRITE_STRINGIFY},   // Uniquely identifies individual physical target.
  39.224 +
  39.225 +        {"MATERIAL",         WRITE_STRINGIFY},   // Identifies the material on which the target was produced using a code
  39.226                                 // uniquely identifying th e material. This is intend ed to be used for IT8.7
  39.227                                 // physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
  39.228  
  39.229 -        "INSTRUMENTATION",     // Used to report the specific instrumentation used (manufacturer and
  39.230 +        {"INSTRUMENTATION",  WRITE_STRINGIFY},   // Used to report the specific instrumentation used (manufacturer and
  39.231                                 // model number) to generate the data reported. This data will often
  39.232                                 // provide more information about the particular data collected than an
  39.233                                 // extensive list of specific details. This is particularly important for
  39.234                                 // spectral data or data derived from spectrophotometry.
  39.235  
  39.236 -        "MEASUREMENT_SOURCE",  // Illumination used for spectral measurements. This data helps provide
  39.237 +        {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
  39.238                                 // a guide to the potential for issues of paper fluorescence, etc.
  39.239  
  39.240 -        "PRINT_CONDITIONS",    // Used to define the characteristics of the printed sheet being reported.
  39.241 +        {"PRINT_CONDITIONS", WRITE_STRINGIFY},   // Used to define the characteristics of the printed sheet being reported.
  39.242                                 // Where standard conditions have been defined (e.g., SWOP at nominal)
  39.243                                 // named conditions may suffice. Otherwise, detailed information is
  39.244                                 // needed.
  39.245  
  39.246 -        "SAMPLE_BACKING",      // Identifies the backing material used behind the sample during
  39.247 -                               // measurement. Allowed values are “black”, “white”, or "na".
  39.248 -
  39.249 -        "CHISQ_DOF"            // Degrees of freedom associated with the Chi squared statistic
  39.250 +        {"SAMPLE_BACKING",   WRITE_STRINGIFY},   // Identifies the backing material used behind the sample during
  39.251 +                               // measurement. Allowed values are “black”, “white”, or {"na".
  39.252 +
  39.253 +        {"CHISQ_DOF",        WRITE_STRINGIFY},   // Degrees of freedom associated with the Chi squared statistic
  39.254 +
  39.255 +//    new in recent specs:
  39.256 +        {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated
  39.257 +                               // along with details of the geometry and the aperture size and shape. For example,
  39.258 +                               // for transmission measurements it is important to identify 0/diffuse, diffuse/0,
  39.259 +                               // opal or integrating sphere, etc. For reflection it is important to identify 0/45,
  39.260 +                               // 45/0, sphere (specular included or excluded), etc.
  39.261 +
  39.262 +       {"FILTER",            WRITE_STRINGIFY},   // Identifies the use of physical filter(s) during measurement. Typically used to
  39.263 +                               // denote the use of filters such as none, D65, Red, Green or Blue.
  39.264 +
  39.265 +       {"POLARIZATION",      WRITE_STRINGIFY},   // Identifies the use of a physical polarization filter during measurement. Allowed
  39.266 +                               // values are {"yes”, “white”, “none” or “na”.
  39.267 +
  39.268 +       {"WEIGHTING_FUNCTION", WRITE_PAIR},   // Indicates such functions as: the CIE standard observer functions used in the
  39.269 +                               // calculation of various data parameters (2 degree and 10 degree), CIE standard
  39.270 +                               // illuminant functions used in the calculation of various data parameters (e.g., D50,
  39.271 +                               // D65, etc.), density status response, etc. If used there shall be at least one
  39.272 +                               // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute
  39.273 +                               // in the set shall be {"name" and shall identify the particular parameter used.
  39.274 +                               // The second shall be {"value" and shall provide the value associated with that name.
  39.275 +                               // For ASCII data, a string containing the Name and Value attribute pairs shall follow
  39.276 +                               // the weighting function keyword. A semi-colon separates attribute pairs from each
  39.277 +                               // other and within the attribute the name and value are separated by a comma.
  39.278 +
  39.279 +       {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name
  39.280 +                               // of the calculation, parameter is the name of the parameter used in the calculation
  39.281 +                               // and value is the value of the parameter.
  39.282 +
  39.283 +       {"TARGET_TYPE",        WRITE_STRINGIFY},  // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
  39.284 +
  39.285 +       {"COLORANT",           WRITE_STRINGIFY},  // Identifies the colorant(s) used in creating the target.
  39.286 +
  39.287 +       {"TABLE_DESCRIPTOR",   WRITE_STRINGIFY},  // Describes the purpose or contents of a data table.
  39.288 +
  39.289 +       {"TABLE_NAME",         WRITE_STRINGIFY}   // Provides a short name for a data table.
  39.290  };
  39.291  
  39.292 -#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(char *))
  39.293 +#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY))
  39.294  
  39.295  
  39.296  // Predefined sample types on dataset
  39.297  static const char* PredefinedSampleID[] = {
  39.298 +        "SAMPLE_ID",      // Identifies sample that data represents
  39.299 +        "STRING",         // Identifies label, or other non-machine readable value.
  39.300 +                          // Value must begin and end with a " symbol
  39.301  
  39.302          "CMYK_C",         // Cyan component of CMYK data expressed as a percentage
  39.303          "CMYK_M",         // Magenta component of CMYK data expressed as a percentage
  39.304 @@ -378,7 +438,7 @@
  39.305          "LAB_B",          // b* component of Lab data
  39.306          "LAB_C",          // C*ab component of Lab data
  39.307          "LAB_H",          // hab component of Lab data
  39.308 -        "LAB_DE"          //  CIE dE
  39.309 +        "LAB_DE",         //  CIE dE
  39.310          "LAB_DE_94",      //  CIE dE using CIE 94
  39.311          "LAB_DE_CMC",     //  dE using CMC
  39.312          "LAB_DE_2000",    // CIE dE using CIE DE 2000
  39.313 @@ -388,7 +448,7 @@
  39.314          "STDEV_Y",        // Standard deviation of Y (tristimulus data)
  39.315          "STDEV_Z",        // Standard deviation of Z (tristimulus data)
  39.316          "STDEV_L",        // Standard deviation of L*
  39.317 -        "STDEV_A"         // Standard deviation of a*
  39.318 +        "STDEV_A",        // Standard deviation of a*
  39.319          "STDEV_B",        // Standard deviation of b*
  39.320          "STDEV_DE",       // Standard deviation of CIE dE
  39.321          "CHI_SQD_PAR"};   // The average of the standard deviations of L*, a* and b*. It is
  39.322 @@ -397,57 +457,120 @@
  39.323  
  39.324  #define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *))
  39.325  
  39.326 +//Forward declaration of some internal functions
  39.327 +static
  39.328 +void* AllocChunk(LPIT8 it8, size_t size);
  39.329 +
  39.330  // Checks if c is a separator
  39.331  static
  39.332 -BOOL isseparator(int c)
  39.333 +LCMSBOOL isseparator(int c)
  39.334  {
  39.335          return (c == ' ') || (c == '\t') || (c == '\r');
  39.336  }
  39.337  
  39.338  // Checks whatever if c is a valid identifier char
  39.339 -
  39.340  static
  39.341 -BOOL ismiddle(int c)
  39.342 +LCMSBOOL ismiddle(int c)
  39.343  {
  39.344     return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127));
  39.345  }
  39.346  
  39.347  // Checks whatsever if c is a valid identifier middle char.
  39.348  static
  39.349 -BOOL isidchar(int c)
  39.350 +LCMSBOOL isidchar(int c)
  39.351  {
  39.352     return isalnum(c) || ismiddle(c);
  39.353  }
  39.354  
  39.355  // Checks whatsever if c is a valid identifier first char.
  39.356  static
  39.357 -BOOL isfirstidchar(int c)
  39.358 +LCMSBOOL isfirstidchar(int c)
  39.359  {
  39.360       return !isdigit(c) && ismiddle(c);
  39.361  }
  39.362  
  39.363 -
  39.364 +// checks whether the supplied path looks like an absolute path
  39.365 +// NOTE: this function doesn't checks if the path exists or even if it's legal
  39.366  static
  39.367 -BOOL SynError(LPIT8 it8, const char *Txt, ...)
  39.368 +LCMSBOOL isabsolutepath(const char *path)
  39.369 +{
  39.370 +    if(path == NULL)
  39.371 +        return FALSE;
  39.372 +
  39.373 +    if(path[0] == DIR_CHAR)
  39.374 +        return TRUE;
  39.375 +
  39.376 +#ifndef NON_WINDOWS
  39.377 +    if(isalpha(path[0]) && path[1] == ':')
  39.378 +        return TRUE;
  39.379 +#endif
  39.380 +    return FALSE;
  39.381 +}
  39.382 +
  39.383 +// Makes a file path based on a given reference path
  39.384 +// NOTE: buffer is assumed to point to at least MAX_PATH bytes
  39.385 +// NOTE: both relPath and basePath are assumed to be no more than MAX_PATH characters long (including the null terminator!)
  39.386 +// NOTE: this function doesn't check if the path exists or even if it's legal
  39.387 +static
  39.388 +LCMSBOOL _cmsMakePath(const char *relPath, const char *basePath, char *buffer)
  39.389 +{
  39.390 +    if (!isabsolutepath(relPath)) {
  39.391 +
  39.392 +        char *tail;
  39.393 +
  39.394 +        strncpy(buffer, basePath, MAX_PATH-1);
  39.395 +        tail = strrchr(buffer, DIR_CHAR);
  39.396 +        if (tail != NULL) {
  39.397 +
  39.398 +            size_t len = tail - buffer;
  39.399 +            strncpy(tail + 1, relPath, MAX_PATH - len -1);
  39.400 +            //  TODO: if combined path is longer than MAX_PATH, this should return FALSE!
  39.401 +            return TRUE;
  39.402 +        }
  39.403 +    }
  39.404 +    strncpy(buffer, relPath, MAX_PATH - 1);
  39.405 +        buffer[MAX_PATH-1] = 0;
  39.406 +    return TRUE;
  39.407 +}
  39.408 +
  39.409 +
  39.410 +// Make sure no exploit is being even tried
  39.411 +
  39.412 +static
  39.413 +const char* NoMeta(const char* str)
  39.414 +{
  39.415 +    if (strchr(str, '%') != NULL)
  39.416 +        return "**** CORRUPTED FORMAT STRING ***";
  39.417 +
  39.418 +    return str;
  39.419 +}
  39.420 +
  39.421 +
  39.422 +// Syntax error
  39.423 +static
  39.424 +LCMSBOOL SynError(LPIT8 it8, const char *Txt, ...)
  39.425  {
  39.426          char Buffer[256], ErrMsg[1024];
  39.427          va_list args;
  39.428  
  39.429          va_start(args, Txt);
  39.430 -        vsprintf(Buffer, Txt, args);
  39.431 +        vsnprintf(Buffer, 255, Txt, args);
  39.432 +        Buffer[255] = 0;
  39.433          va_end(args);
  39.434  
  39.435 -        sprintf(ErrMsg, "%s: Line %d, %s", it8->FileName, it8->lineno, Buffer);
  39.436 +        snprintf(ErrMsg, 1023, "%s: Line %d, %s", it8->FileStack[it8 ->IncludeSP]->FileName, it8->lineno, Buffer);
  39.437 +        ErrMsg[1023] = 0;
  39.438          it8->sy = SSYNERROR;
  39.439 -        cmsSignalError(LCMS_ERRC_ABORTED, ErrMsg);
  39.440 +        cmsSignalError(LCMS_ERRC_ABORTED, "%s", ErrMsg);
  39.441          return FALSE;
  39.442  }
  39.443  
  39.444 +// Check if current symbol is same as specified. issue an error else.
  39.445  static
  39.446 -BOOL Check(LPIT8 it8, SYMBOL sy, const char* Err)
  39.447 +LCMSBOOL Check(LPIT8 it8, SYMBOL sy, const char* Err)
  39.448  {
  39.449          if (it8 -> sy != sy)
  39.450 -                return SynError(it8, Err);
  39.451 +                return SynError(it8, NoMeta(Err));
  39.452          return TRUE;
  39.453  }
  39.454  
  39.455 @@ -457,15 +580,15 @@
  39.456  static
  39.457  void NextCh(LPIT8 it8)
  39.458  {
  39.459 -    if (it8 -> Stream[it8 ->IncludeSP]) {
  39.460 -
  39.461 -        it8 ->ch = fgetc(it8 ->Stream[it8 ->IncludeSP]);
  39.462 -
  39.463 -        if (feof(it8 -> Stream[it8 ->IncludeSP]))  {
  39.464 +    if (it8 -> FileStack[it8 ->IncludeSP]->Stream) {
  39.465 +
  39.466 +        it8 ->ch = fgetc(it8 ->FileStack[it8 ->IncludeSP]->Stream);
  39.467 +
  39.468 +        if (feof(it8 -> FileStack[it8 ->IncludeSP]->Stream))  {
  39.469  
  39.470              if (it8 ->IncludeSP > 0) {
  39.471  
  39.472 -                fclose(it8 ->Stream[it8->IncludeSP--]);
  39.473 +                fclose(it8 ->FileStack[it8->IncludeSP--]->Stream);
  39.474                  it8 -> ch = ' ';                            // Whitespace to be ignored
  39.475  
  39.476              } else
  39.477 @@ -476,7 +599,6 @@
  39.478  
  39.479      }
  39.480      else {
  39.481 -
  39.482          it8->ch = *it8->Source;
  39.483          if (it8->ch) it8->Source++;
  39.484      }
  39.485 @@ -799,18 +921,39 @@
  39.486  
  39.487      if (it8 -> sy == SINCLUDE) {
  39.488  
  39.489 -                FILE* IncludeFile;
  39.490 +                LPFILECTX FileNest;
  39.491 +
  39.492 +                if(it8 -> IncludeSP >= (MAXINCLUDE-1))
  39.493 +                {
  39.494 +                    SynError(it8, "Too many recursion levels");
  39.495 +                    return;
  39.496 +                }
  39.497  
  39.498                  InSymbol(it8);
  39.499                  if (!Check(it8, SSTRING, "Filename expected")) return;
  39.500 -                IncludeFile = fopen(it8 -> str, "rt");
  39.501 -                if (IncludeFile == NULL) {
  39.502 -
  39.503 -                        SynError(it8, "File %s not found", it8 ->str);
  39.504 +
  39.505 +                FileNest = it8 -> FileStack[it8 -> IncludeSP + 1];
  39.506 +                if(FileNest == NULL)
  39.507 +                {
  39.508 +                    FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (LPFILECTX)AllocChunk(it8, sizeof(FILECTX));
  39.509 +                    //if(FileNest == NULL)
  39.510 +                        //  TODO: how to manage out-of-memory conditions?
  39.511 +                }
  39.512 +
  39.513 +                if(_cmsMakePath(it8->str, it8->FileStack[it8->IncludeSP]->FileName, FileNest->FileName) == FALSE)
  39.514 +                {
  39.515 +                    SynError(it8, "File path too long");
  39.516 +                    return;
  39.517 +                }
  39.518 +
  39.519 +                FileNest->Stream = fopen(FileNest->FileName, "rt");
  39.520 +                if (FileNest->Stream == NULL) {
  39.521 +
  39.522 +                        SynError(it8, "File %s not found", FileNest->FileName);
  39.523                          return;
  39.524                  }
  39.525 -
  39.526 -                it8 -> Stream[++it8 -> IncludeSP] = IncludeFile;
  39.527 +                it8->IncludeSP++;
  39.528 +
  39.529                  it8 ->ch = ' ';
  39.530                  InSymbol(it8);
  39.531      }
  39.532 @@ -819,7 +962,7 @@
  39.533  
  39.534  // Checks end of line separator
  39.535  static
  39.536 -BOOL CheckEOLN(LPIT8 it8)
  39.537 +LCMSBOOL CheckEOLN(LPIT8 it8)
  39.538  {
  39.539          if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
  39.540          while (it8 -> sy == SEOLN)
  39.541 @@ -850,21 +993,26 @@
  39.542  
  39.543  // Returns a string holding current value
  39.544  static
  39.545 -BOOL GetVal(LPIT8 it8, char* Buffer, const char* ErrorTitle)
  39.546 +LCMSBOOL GetVal(LPIT8 it8, char* Buffer, size_t max, const char* ErrorTitle)
  39.547  {
  39.548      switch (it8->sy) {
  39.549  
  39.550 -    case SIDENT:  strncpy(Buffer, it8->id, MAXID-1); break;
  39.551 -    case SINUM:   sprintf(Buffer, "%d", it8 -> inum); break;
  39.552 -    case SDNUM:   sprintf(Buffer, it8->DoubleFormatter, it8 -> dnum); break;
  39.553 -    case SSTRING: strncpy(Buffer, it8->str, MAXSTR-1); break;
  39.554 +    case SIDENT:  strncpy(Buffer, it8->id, max);
  39.555 +                  Buffer[max-1]=0;
  39.556 +                  break;
  39.557 +    case SINUM:   snprintf(Buffer, max, "%d", it8 -> inum); break;
  39.558 +    case SDNUM:   snprintf(Buffer, max, it8->DoubleFormatter, it8 -> dnum); break;
  39.559 +    case SSTRING: strncpy(Buffer, it8->str, max);
  39.560 +                  Buffer[max-1] = 0;
  39.561 +                  break;
  39.562  
  39.563  
  39.564      default:
  39.565 -         return SynError(it8, ErrorTitle);
  39.566 +         return SynError(it8, "%s", ErrorTitle);
  39.567      }
  39.568  
  39.569 -     return TRUE;
  39.570 +    Buffer[max] = 0;
  39.571 +    return TRUE;
  39.572  }
  39.573  
  39.574  // ---------------------------------------------------------- Table
  39.575 @@ -872,7 +1020,13 @@
  39.576  static
  39.577  LPTABLE GetTable(LPIT8 it8)
  39.578  {
  39.579 -    return it8 ->Tab + it8 ->nTable;
  39.580 +   if ((it8 -> nTable >= it8 ->TablesCount) || (it8 -> nTable < 0)) {
  39.581 +
  39.582 +           SynError(it8, "Table %d out of sequence", it8 -> nTable);
  39.583 +           return it8 -> Tab;
  39.584 +   }
  39.585 +
  39.586 +   return it8 ->Tab + it8 ->nTable;
  39.587  }
  39.588  
  39.589  // ---------------------------------------------------------- Memory management
  39.590 @@ -896,15 +1050,15 @@
  39.591          for (p = it8->MemorySink; p != NULL; p = n) {
  39.592  
  39.593              n = p->Next;
  39.594 -            if (p->Ptr) free(p->Ptr);
  39.595 -            free(p);
  39.596 +            if (p->Ptr) _cmsFree(p->Ptr);
  39.597 +            _cmsFree(p);
  39.598          }
  39.599      }
  39.600  
  39.601      if (it8->MemoryBlock)
  39.602 -        free(it8->MemoryBlock);
  39.603 -
  39.604 -    free(it8);
  39.605 +        _cmsFree(it8->MemoryBlock);
  39.606 +
  39.607 +     _cmsFree(it8);
  39.608  }
  39.609  
  39.610  
  39.611 @@ -913,16 +1067,16 @@
  39.612  void* AllocBigBlock(LPIT8 it8, size_t size)
  39.613  {
  39.614     LPOWNEDMEM ptr1;
  39.615 -   void* ptr = malloc(size);
  39.616 +   void* ptr = _cmsMalloc(size);
  39.617  
  39.618          if (ptr) {
  39.619  
  39.620                  ZeroMemory(ptr, size);
  39.621 -                ptr1 = (LPOWNEDMEM) malloc(sizeof(OWNEDMEM));
  39.622 +                ptr1 = (LPOWNEDMEM) _cmsMalloc(sizeof(OWNEDMEM));
  39.623  
  39.624                  if (ptr1 == NULL) {
  39.625  
  39.626 -                    free(ptr);
  39.627 +                     _cmsFree(ptr);
  39.628                      return NULL;
  39.629                  }
  39.630  
  39.631 @@ -986,8 +1140,9 @@
  39.632  // Searches through linked list
  39.633  
  39.634  static
  39.635 -BOOL IsAvailableOnList(LPKEYVALUE p, const char* Key, LPKEYVALUE* LastPtr)
  39.636 +LCMSBOOL IsAvailableOnList(LPKEYVALUE p, const char* Key, const char* Subkey, LPKEYVALUE* LastPtr)
  39.637  {
  39.638 +    if (LastPtr) *LastPtr = p;
  39.639  
  39.640      for (;  p != NULL; p = p->Next) {
  39.641  
  39.642 @@ -996,8 +1151,22 @@
  39.643          if (*Key != '#') { // Comments are ignored
  39.644  
  39.645              if (stricmp(Key, p->Keyword) == 0)
  39.646 -                    return TRUE;
  39.647 +                    break;
  39.648          }
  39.649 +        }
  39.650 +
  39.651 +    if (p == NULL)
  39.652 +        return FALSE;
  39.653 +
  39.654 +    if (Subkey == 0)
  39.655 +        return TRUE;
  39.656 +
  39.657 +    for (; p != NULL; p = p->NextSubkey) {
  39.658 +
  39.659 +        if (LastPtr) *LastPtr = p;
  39.660 +
  39.661 +        if (stricmp(Subkey, p->Subkey) == 0)
  39.662 +            return TRUE;
  39.663      }
  39.664  
  39.665      return FALSE;
  39.666 @@ -1007,35 +1176,55 @@
  39.667  
  39.668  // Add a property into a linked list
  39.669  static
  39.670 -BOOL AddToList(LPIT8 it8, LPKEYVALUE* Head, const char *Key, const char* xValue, WRITEMODE WriteAs)
  39.671 +LPKEYVALUE AddToList(LPIT8 it8, LPKEYVALUE* Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs)
  39.672  {
  39.673      LPKEYVALUE p;
  39.674 -    LPKEYVALUE last;
  39.675 -
  39.676  
  39.677      // Check if property is already in list (this is an error)
  39.678  
  39.679 -    if (IsAvailableOnList(*Head, Key, &last)) {
  39.680 -
  39.681 -                        // This may work for editing properties
  39.682 -
  39.683 -                         last->Value   = AllocString(it8, xValue);
  39.684 -                         last->WriteAs = WriteAs;
  39.685 -                         return TRUE;
  39.686 -
  39.687 -             // return SynError(it8, "duplicate key <%s>", Key);
  39.688 +    if (IsAvailableOnList(*Head, Key, Subkey, &p)) {
  39.689 +
  39.690 +            // This may work for editing properties
  39.691 +
  39.692 +        //     return SynError(it8, "duplicate key <%s>", Key);
  39.693      }
  39.694 -
  39.695 -        // Allocate the container
  39.696 +    else {
  39.697 +        LPKEYVALUE last = p;
  39.698 +
  39.699 +    // Allocate the container
  39.700      p = (LPKEYVALUE) AllocChunk(it8, sizeof(KEYVALUE));
  39.701      if (p == NULL)
  39.702      {
  39.703 -        return SynError(it8, "AddToList: out of memory");
  39.704 +            SynError(it8, "AddToList: out of memory");
  39.705 +            return NULL;
  39.706      }
  39.707  
  39.708      // Store name and value
  39.709      p->Keyword = AllocString(it8, Key);
  39.710 -
  39.711 +        p->Subkey = (Subkey == NULL) ? NULL : AllocString(it8, Subkey);
  39.712 +
  39.713 +        // Keep the container in our list
  39.714 +        if (*Head == NULL)
  39.715 +            *Head = p;
  39.716 +        else
  39.717 +        {
  39.718 +            if(Subkey != 0 && last != 0) {
  39.719 +                last->NextSubkey = p;
  39.720 +
  39.721 +                // If Subkey is not null, then last is the last property with the same key,
  39.722 +                // but not necessarily is the last property in the list, so we need to move
  39.723 +                // to the actual list end
  39.724 +                while(last->Next != 0)
  39.725 +                    last = last->Next;
  39.726 +    }
  39.727 +            last->Next = p;
  39.728 +    }
  39.729 +
  39.730 +    p->Next    = NULL;
  39.731 +        p->NextSubkey = NULL;
  39.732 +    }
  39.733 +
  39.734 +    p->WriteAs = WriteAs;
  39.735      if (xValue != NULL) {
  39.736  
  39.737          p->Value   = AllocString(it8, xValue);
  39.738 @@ -1044,29 +1233,20 @@
  39.739          p->Value   = NULL;
  39.740      }
  39.741  
  39.742 -    p->Next    = NULL;
  39.743 -    p->WriteAs = WriteAs;
  39.744 -
  39.745 -    // Keep the container in our list
  39.746 -    if (*Head == NULL)
  39.747 -        *Head = p;
  39.748 -    else
  39.749 -        last->Next = p;
  39.750 -
  39.751 -    return TRUE;
  39.752 +    return p;
  39.753  }
  39.754  
  39.755  static
  39.756 -BOOL AddAvailableProperty(LPIT8 it8, const char* Key)
  39.757 +LPKEYVALUE AddAvailableProperty(LPIT8 it8, const char* Key, WRITEMODE as)
  39.758  {
  39.759 -        return AddToList(it8, &it8->ValidKeywords, Key, NULL, WRITE_UNCOOKED);
  39.760 +        return AddToList(it8, &it8->ValidKeywords, Key, NULL, NULL, as);
  39.761  }
  39.762  
  39.763  
  39.764  static
  39.765 -BOOL AddAvailableSampleID(LPIT8 it8, const char* Key)
  39.766 +LPKEYVALUE AddAvailableSampleID(LPIT8 it8, const char* Key)
  39.767  {
  39.768 -        return AddToList(it8, &it8->ValidSampleID, Key, NULL, WRITE_UNCOOKED);
  39.769 +        return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED);
  39.770  }
  39.771  
  39.772  
  39.773 @@ -1122,8 +1302,6 @@
  39.774      AllocTable(it8);
  39.775  
  39.776      it8->MemoryBlock = NULL;
  39.777 -    it8->Stream[0]   = NULL;
  39.778 -    it8->IncludeSP   = 0;
  39.779      it8->MemorySink  = NULL;
  39.780  
  39.781      it8 ->nTable = 0;
  39.782 @@ -1141,6 +1319,8 @@
  39.783      it8 -> inum = 0;
  39.784      it8 -> dnum = 0.0;
  39.785  
  39.786 +    it8->FileStack[0] = (LPFILECTX)AllocChunk(it8, sizeof(FILECTX));
  39.787 +    it8->IncludeSP   = 0;
  39.788      it8 -> lineno = 1;
  39.789  
  39.790      strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
  39.791 @@ -1149,7 +1329,7 @@
  39.792      // Initialize predefined properties & data
  39.793  
  39.794      for (i=0; i < NUMPREDEFINEDPROPS; i++)
  39.795 -            AddAvailableProperty(it8, PredefinedProperties[i]);
  39.796 +            AddAvailableProperty(it8, PredefinedProperties[i].id, PredefinedProperties[i].as);
  39.797  
  39.798      for (i=0; i < NUMPREDEFINEDSAMPLEID; i++)
  39.799              AddAvailableSampleID(it8, PredefinedSampleID[i]);
  39.800 @@ -1167,65 +1347,72 @@
  39.801  
  39.802  }
  39.803  
  39.804 -BOOL  LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type)
  39.805 +LCMSBOOL  LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type)
  39.806  {
  39.807          LPIT8 it8 = (LPIT8) hIT8;
  39.808  
  39.809          strncpy(it8 ->SheetType, Type, MAXSTR-1);
  39.810 +        it8 ->SheetType[MAXSTR-1] = 0;
  39.811          return TRUE;
  39.812  }
  39.813  
  39.814 -BOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* Val)
  39.815 +LCMSBOOL LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* Val)
  39.816  {
  39.817      LPIT8 it8 = (LPIT8) hIT8;
  39.818  
  39.819      if (!Val) return FALSE;
  39.820      if (!*Val) return FALSE;
  39.821  
  39.822 -    return AddToList(it8, &GetTable(it8)->HeaderList, "# ", Val, WRITE_UNCOOKED);
  39.823 +    return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL;
  39.824  }
  39.825  
  39.826  
  39.827  
  39.828  // Sets a property
  39.829 -BOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* Key, const char *Val)
  39.830 +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* Key, const char *Val)
  39.831  {
  39.832      LPIT8 it8 = (LPIT8) hIT8;
  39.833  
  39.834      if (!Val) return FALSE;
  39.835      if (!*Val) return FALSE;
  39.836  
  39.837 -    return AddToList(it8, &GetTable(it8)->HeaderList, Key, Val, WRITE_STRINGIFY);
  39.838 +    return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL;
  39.839  }
  39.840  
  39.841  
  39.842 -BOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val)
  39.843 +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val)
  39.844  {
  39.845      LPIT8 it8 = (LPIT8) hIT8;
  39.846      char Buffer[1024];
  39.847  
  39.848      sprintf(Buffer, it8->DoubleFormatter, Val);
  39.849  
  39.850 -    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, Buffer, WRITE_UNCOOKED);
  39.851 +    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
  39.852  }
  39.853  
  39.854 -BOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val)
  39.855 +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val)
  39.856  {
  39.857      LPIT8 it8 = (LPIT8) hIT8;
  39.858      char Buffer[1024];
  39.859  
  39.860      sprintf(Buffer, "%d", Val);
  39.861  
  39.862 -    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, Buffer, WRITE_HEXADECIMAL);
  39.863 +    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
  39.864  }
  39.865  
  39.866 -BOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer)
  39.867 +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer)
  39.868  {
  39.869      LPIT8 it8 = (LPIT8) hIT8;
  39.870  
  39.871 -    return AddToList(it8, &GetTable(it8)->HeaderList, Key, Buffer, WRITE_UNCOOKED);
  39.872 +    return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Buffer, WRITE_UNCOOKED) != NULL;
  39.873  }
  39.874  
  39.875 +LCMSBOOL LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer)
  39.876 +{
  39.877 +    LPIT8 it8 = (LPIT8) hIT8;
  39.878 +
  39.879 +    return AddToList(it8, &GetTable(it8)->HeaderList, Key, SubKey, Buffer, WRITE_PAIR) != NULL;
  39.880 +}
  39.881  
  39.882  // Gets a property
  39.883  const char* LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* Key)
  39.884 @@ -1233,7 +1420,7 @@
  39.885      LPIT8 it8 = (LPIT8) hIT8;
  39.886      LPKEYVALUE p;
  39.887  
  39.888 -    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, &p))
  39.889 +    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, NULL, &p))
  39.890      {
  39.891          return p -> Value;
  39.892      }
  39.893 @@ -1249,6 +1436,18 @@
  39.894      else return 0.0;
  39.895  }
  39.896  
  39.897 +const char* LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* Key, const char *SubKey)
  39.898 +{
  39.899 +    LPIT8 it8 = (LPIT8) hIT8;
  39.900 +    LPKEYVALUE p;
  39.901 +
  39.902 +    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, SubKey, &p))
  39.903 +    {
  39.904 +        return p -> Value;
  39.905 +    }
  39.906 +    return NULL;
  39.907 +}
  39.908 +
  39.909  // ----------------------------------------------------------------- Datasets
  39.910  
  39.911  
  39.912 @@ -1287,10 +1486,17 @@
  39.913  }
  39.914  
  39.915  static
  39.916 -BOOL SetDataFormat(LPIT8 it8, int n, const char *label)
  39.917 +LCMSBOOL SetDataFormat(LPIT8 it8, int n, const char *label)
  39.918  {
  39.919      LPTABLE t = GetTable(it8);
  39.920  
  39.921 +#ifdef  STRICT_CGATS
  39.922 +    if (!IsAvailableOnList(it8-> ValidSampleID, label, NULL, NULL)) {
  39.923 +        SynError(it8, "Invalid data format '%s'.", label);
  39.924 +        return FALSE;
  39.925 +    }
  39.926 +#endif
  39.927 +
  39.928      if (!t->DataFormat)
  39.929          AllocateDataFormat(it8);
  39.930  
  39.931 @@ -1308,7 +1514,7 @@
  39.932  }
  39.933  
  39.934  
  39.935 -BOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE h, int n, const char *Sample)
  39.936 +LCMSBOOL LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE h, int n, const char *Sample)
  39.937  {
  39.938          LPIT8 it8 = (LPIT8) h;
  39.939          return SetDataFormat(it8, n, Sample);
  39.940 @@ -1348,7 +1554,7 @@
  39.941  }
  39.942  
  39.943  static
  39.944 -BOOL SetData(LPIT8 it8, int nSet, int nField, const char *Val)
  39.945 +LCMSBOOL SetData(LPIT8 it8, int nSet, int nField, const char *Val)
  39.946  {
  39.947      LPTABLE t = GetTable(it8);
  39.948  
  39.949 @@ -1383,42 +1589,43 @@
  39.950  void WriteStr(LPSAVESTREAM f, const char *str)
  39.951  {
  39.952  
  39.953 -        size_t len;
  39.954 -
  39.955 -        if (str == NULL)
  39.956 -                str = " ";
  39.957 -
  39.958 -        // Lenghth to write
  39.959 -        len = strlen(str);
  39.960 +    size_t len;
  39.961 +
  39.962 +    if (str == NULL)
  39.963 +        str = " ";
  39.964 +
  39.965 +    // Lenghth to write
  39.966 +    len = strlen(str);
  39.967      f ->Used += len;
  39.968  
  39.969  
  39.970 -        if (f ->stream) {       // Should I write it to a file?
  39.971 -
  39.972 -                fwrite(str, 1, len, f->stream);
  39.973 +    if (f ->stream) {   // Should I write it to a file?
  39.974 +
  39.975 +        fwrite(str, 1, len, f->stream);
  39.976 +
  39.977 +    }
  39.978 +    else {  // Or to a memory block?
  39.979 +
  39.980 +
  39.981 +        if (f ->Base) {   // Am I just counting the bytes?
  39.982 +
  39.983 +            if (f ->Used > f ->Max) {
  39.984 +
  39.985 +                cmsSignalError(LCMS_ERRC_ABORTED, "Write to memory overflows in CGATS parser");
  39.986 +                return;
  39.987 +            }
  39.988 +
  39.989 +            CopyMemory(f ->Ptr, str, len);
  39.990 +            f->Ptr += len;
  39.991  
  39.992          }
  39.993 -        else {  // Or to a memory block?
  39.994 -
  39.995 -
  39.996 -                if (f ->Base) {   // Am I just counting the bytes?
  39.997 -
  39.998 -                        if (f ->Used > f ->Max) {
  39.999 -
 39.1000 -                                cmsSignalError(LCMS_ERRC_ABORTED, "Write to memory overflows in CGATS parser");
 39.1001 -                                return;
 39.1002 -                        }
 39.1003 -
 39.1004 -                        CopyMemory(f ->Ptr, str, len);
 39.1005 -                        f->Ptr += len;
 39.1006 -
 39.1007 -                }
 39.1008 -
 39.1009 -        }
 39.1010 +
 39.1011 +    }
 39.1012  }
 39.1013  
 39.1014  
 39.1015 -//
 39.1016 +// Write formatted
 39.1017 +
 39.1018  static
 39.1019  void Writef(LPSAVESTREAM f, const char* frm, ...)
 39.1020  {
 39.1021 @@ -1426,7 +1633,8 @@
 39.1022      va_list args;
 39.1023  
 39.1024      va_start(args, frm);
 39.1025 -    vsprintf(Buffer, frm, args);
 39.1026 +    vsnprintf(Buffer, 4095, frm, args);
 39.1027 +    Buffer[4095] = 0;
 39.1028      WriteStr(f, Buffer);
 39.1029      va_end(args);
 39.1030  
 39.1031 @@ -1450,7 +1658,7 @@
 39.1032              for (Pt = p ->Value; *Pt; Pt++) {
 39.1033  
 39.1034  
 39.1035 -                                Writef(fp, "%c", *Pt);
 39.1036 +                Writef(fp, "%c", *Pt);
 39.1037  
 39.1038                  if (*Pt == '\n') {
 39.1039                      WriteStr(fp, "# ");
 39.1040 @@ -1462,7 +1670,7 @@
 39.1041          }
 39.1042  
 39.1043  
 39.1044 -        if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL)) {
 39.1045 +        if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL, NULL)) {
 39.1046  
 39.1047  #ifdef STRICT_CGATS
 39.1048              WriteStr(fp, "KEYWORD\t\"");
 39.1049 @@ -1470,7 +1678,7 @@
 39.1050              WriteStr(fp, "\"\n");
 39.1051  #endif
 39.1052  
 39.1053 -            AddAvailableProperty(it8, p->Keyword);
 39.1054 +            AddAvailableProperty(it8, p->Keyword, WRITE_UNCOOKED);
 39.1055  
 39.1056          }
 39.1057  
 39.1058 @@ -1495,6 +1703,10 @@
 39.1059                      Writef(fp, "\t0x%B", atoi(p ->Value));
 39.1060                      break;
 39.1061  
 39.1062 +            case WRITE_PAIR:
 39.1063 +                    Writef(fp, "\t\"%s,%s\"", p->Subkey, p->Value);
 39.1064 +                    break;
 39.1065 +
 39.1066              default: SynError(it8, "Unknown write mode %d", p ->WriteAs);
 39.1067                       return;
 39.1068              }
 39.1069 @@ -1573,13 +1785,13 @@
 39.1070  
 39.1071  
 39.1072  // Saves whole file
 39.1073 -BOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE hIT8, const char* cFileName)
 39.1074 +LCMSBOOL LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE hIT8, const char* cFileName)
 39.1075  {
 39.1076      SAVESTREAM sd;
 39.1077      int i;
 39.1078      LPIT8 it8 = (LPIT8) hIT8;
 39.1079  
 39.1080 -        ZeroMemory(&sd, sizeof(SAVESTREAM));
 39.1081 +    ZeroMemory(&sd, sizeof(SAVESTREAM));
 39.1082  
 39.1083      sd.stream = fopen(cFileName, "wt");
 39.1084      if (!sd.stream) return FALSE;
 39.1085 @@ -1594,31 +1806,31 @@
 39.1086              WriteData(&sd, it8);
 39.1087      }
 39.1088  
 39.1089 -        fclose(sd.stream);
 39.1090 +    fclose(sd.stream);
 39.1091  
 39.1092      return TRUE;
 39.1093  }
 39.1094  
 39.1095  
 39.1096  // Saves to memory
 39.1097 -BOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded)
 39.1098 +LCMSBOOL LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded)
 39.1099  {
 39.1100      SAVESTREAM sd;
 39.1101      int i;
 39.1102      LPIT8 it8 = (LPIT8) hIT8;
 39.1103  
 39.1104 -        ZeroMemory(&sd, sizeof(SAVESTREAM));
 39.1105 +    ZeroMemory(&sd, sizeof(SAVESTREAM));
 39.1106  
 39.1107      sd.stream = NULL;
 39.1108 -        sd.Base   = (LPBYTE) MemPtr;
 39.1109 -        sd.Ptr    = sd.Base;
 39.1110 -
 39.1111 -        sd.Used = 0;
 39.1112 -
 39.1113 -        if (sd.Base)
 39.1114 -                sd.Max  = *BytesNeeded;         // Write to memory?
 39.1115 -        else
 39.1116 -                sd.Max  = 0;                            // Just counting the needed bytes
 39.1117 +    sd.Base   = (LPBYTE) MemPtr;
 39.1118 +    sd.Ptr    = sd.Base;
 39.1119 +
 39.1120 +    sd.Used = 0;
 39.1121 +
 39.1122 +    if (sd.Base)
 39.1123 +        sd.Max  = *BytesNeeded;     // Write to memory?
 39.1124 +    else
 39.1125 +        sd.Max  = 0;                // Just counting the needed bytes
 39.1126  
 39.1127      WriteStr(&sd, it8->SheetType);
 39.1128      WriteStr(&sd, "\n");
 39.1129 @@ -1630,12 +1842,12 @@
 39.1130              WriteData(&sd, it8);
 39.1131      }
 39.1132  
 39.1133 -        sd.Used++;      // The \0 at the very end
 39.1134 -
 39.1135 -        if (sd.Base)
 39.1136 -                sd.Ptr = 0;
 39.1137 -
 39.1138 -        *BytesNeeded = sd.Used;
 39.1139 +    sd.Used++;  // The \0 at the very end
 39.1140 +
 39.1141 +    if (sd.Base)
 39.1142 +        sd.Ptr = 0;
 39.1143 +
 39.1144 +    *BytesNeeded = sd.Used;
 39.1145  
 39.1146      return TRUE;
 39.1147  }
 39.1148 @@ -1644,7 +1856,7 @@
 39.1149  // -------------------------------------------------------------- Higer level parsing
 39.1150  
 39.1151  static
 39.1152 -BOOL DataFormatSection(LPIT8 it8)
 39.1153 +LCMSBOOL DataFormatSection(LPIT8 it8)
 39.1154  {
 39.1155      int iField = 0;
 39.1156      LPTABLE t = GetTable(it8);
 39.1157 @@ -1685,16 +1897,19 @@
 39.1158  
 39.1159  
 39.1160  static
 39.1161 -BOOL DataSection (LPIT8 it8)
 39.1162 +LCMSBOOL DataSection (LPIT8 it8)
 39.1163  {
 39.1164      int  iField = 0;
 39.1165      int  iSet   = 0;
 39.1166 -    char Buffer[256];
 39.1167 +    char Buffer[MAXSTR];
 39.1168      LPTABLE t = GetTable(it8);
 39.1169  
 39.1170      InSymbol(it8);   // Eats "BEGIN_DATA"
 39.1171      CheckEOLN(it8);
 39.1172  
 39.1173 +    if (!t->Data)
 39.1174 +        AllocateDataSet(it8);
 39.1175 +
 39.1176      while (it8->sy != SEND_DATA && it8->sy != SEOF)
 39.1177      {
 39.1178          if (iField >= t -> nSamples) {
 39.1179 @@ -1705,7 +1920,7 @@
 39.1180  
 39.1181          if (it8->sy != SEND_DATA && it8->sy != SEOF) {
 39.1182  
 39.1183 -            if (!GetVal(it8, Buffer, "Sample data expected"))
 39.1184 +            if (!GetVal(it8, Buffer, 255, "Sample data expected"))
 39.1185                  return FALSE;
 39.1186  
 39.1187              if (!SetData(it8, iSet, iField, Buffer))
 39.1188 @@ -1734,10 +1949,11 @@
 39.1189  
 39.1190  
 39.1191  static
 39.1192 -BOOL HeaderSection(LPIT8 it8)
 39.1193 +LCMSBOOL HeaderSection(LPIT8 it8)
 39.1194  {
 39.1195      char VarName[MAXID];
 39.1196      char Buffer[MAXSTR];
 39.1197 +    LPKEYVALUE Key;
 39.1198  
 39.1199          while (it8->sy != SEOF &&
 39.1200                 it8->sy != SSYNERROR &&
 39.1201 @@ -1749,30 +1965,79 @@
 39.1202  
 39.1203          case SKEYWORD:
 39.1204                  InSymbol(it8);
 39.1205 -                if (!GetVal(it8, Buffer, "Keyword expected")) return FALSE;
 39.1206 -                if (!AddAvailableProperty(it8, Buffer)) return FALSE;
 39.1207 +                if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;
 39.1208 +                if (!AddAvailableProperty(it8, Buffer, WRITE_UNCOOKED)) return FALSE;
 39.1209                  InSymbol(it8);
 39.1210                  break;
 39.1211  
 39.1212  
 39.1213 +        case SDATA_FORMAT_ID:
 39.1214 +                InSymbol(it8);
 39.1215 +                if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;
 39.1216 +                if (!AddAvailableSampleID(it8, Buffer)) return FALSE;
 39.1217 +                InSymbol(it8);
 39.1218 +                break;
 39.1219 +
 39.1220 +
 39.1221          case SIDENT:
 39.1222                  strncpy(VarName, it8->id, MAXID-1);
 39.1223 -
 39.1224 -                if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL)) {
 39.1225 +                VarName[MAXID-1] = 0;
 39.1226 +
 39.1227 +                if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) {
 39.1228  
 39.1229  #ifdef STRICT_CGATS
 39.1230                   return SynError(it8, "Undefined keyword '%s'", VarName);
 39.1231  #else
 39.1232 -                if (!AddAvailableProperty(it8, VarName)) return FALSE;
 39.1233 +                    Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
 39.1234 +                    if (Key == NULL) return FALSE;
 39.1235  #endif
 39.1236                  }
 39.1237  
 39.1238                  InSymbol(it8);
 39.1239 -                if (!GetVal(it8, Buffer, "Property data expected")) return FALSE;
 39.1240 -
 39.1241 -
 39.1242 -                AddToList(it8, &GetTable(it8)->HeaderList, VarName, Buffer,
 39.1243 -                                                                (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
 39.1244 +                if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE;
 39.1245 +
 39.1246 +                if(Key->WriteAs != WRITE_PAIR) {
 39.1247 +                    AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
 39.1248 +                                (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
 39.1249 +                }
 39.1250 +                else {
 39.1251 +                    const char *Subkey;
 39.1252 +                    char *Nextkey;
 39.1253 +                    if (it8->sy != SSTRING)
 39.1254 +                        return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
 39.1255 +
 39.1256 +                    // chop the string as a list of "subkey, value" pairs, using ';' as a separator
 39.1257 +                    for(Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
 39.1258 +                    {
 39.1259 +                        char *Value, *temp;
 39.1260 +
 39.1261 +                        //  identify token pair boundary
 39.1262 +                        Nextkey = (char*) strchr(Subkey, ';');
 39.1263 +                        if(Nextkey)
 39.1264 +                            *Nextkey++ = '\0';
 39.1265 +
 39.1266 +                        // for each pair, split the subkey and the value
 39.1267 +                        Value = (char*) strrchr(Subkey, ',');
 39.1268 +                        if(Value == NULL)
 39.1269 +                            return SynError(it8, "Invalid value for property '%s'.", VarName);
 39.1270 +
 39.1271 +                        // gobble the spaces before the coma, and the coma itself
 39.1272 +                        temp = Value++;
 39.1273 +                        do *temp-- = '\0'; while(temp >= Subkey && *temp == ' ');
 39.1274 +
 39.1275 +                        // gobble any space at the right
 39.1276 +                        temp = Value + strlen(Value) - 1;
 39.1277 +                        while(*temp == ' ') *temp-- = '\0';
 39.1278 +
 39.1279 +                        // trim the strings from the left
 39.1280 +                        Subkey += strspn(Subkey, " ");
 39.1281 +                        Value += strspn(Value, " ");
 39.1282 +
 39.1283 +                        if(Subkey[0] == 0 || Value[0] == 0)
 39.1284 +                            return SynError(it8, "Invalid value for property '%s'.", VarName);
 39.1285 +                        AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
 39.1286 +                    }
 39.1287 +                }
 39.1288  
 39.1289                  InSymbol(it8);
 39.1290                  break;
 39.1291 @@ -1793,22 +2058,23 @@
 39.1292  
 39.1293  
 39.1294  static
 39.1295 -BOOL ParseIT8(LPIT8 it8)
 39.1296 +LCMSBOOL ParseIT8(LPIT8 it8, LCMSBOOL nosheet)
 39.1297  {
 39.1298 -    char* SheetTypePtr;
 39.1299 +    char* SheetTypePtr = it8 ->SheetType;
 39.1300 +
 39.1301 +    if (nosheet == 0) {
 39.1302  
 39.1303      // First line is a very special case.
 39.1304  
 39.1305      while (isseparator(it8->ch))
 39.1306              NextCh(it8);
 39.1307  
 39.1308 -    SheetTypePtr = it8 ->SheetType;
 39.1309 -
 39.1310      while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != -1) {
 39.1311  
 39.1312          *SheetTypePtr++= (char) it8 ->ch;
 39.1313          NextCh(it8);
 39.1314      }
 39.1315 +    }
 39.1316  
 39.1317      *SheetTypePtr = 0;
 39.1318      InSymbol(it8);
 39.1319 @@ -1869,6 +2135,12 @@
 39.1320  
 39.1321      for (idField = 0; idField < t -> nSamples; idField++)
 39.1322      {
 39.1323 +        if (t ->DataFormat == NULL) {
 39.1324 +             SynError(it8, "Undefined DATA_FORMAT");
 39.1325 +             return;
 39.1326 +
 39.1327 +        }
 39.1328 +
 39.1329          Fld = t->DataFormat[idField];
 39.1330          if (!Fld) continue;
 39.1331  
 39.1332 @@ -1884,6 +2156,7 @@
 39.1333                      char Buffer[256];
 39.1334  
 39.1335                      strncpy(Buffer, Data, 255);
 39.1336 +                    Buffer[255] = 0;
 39.1337  
 39.1338                      if (strlen(Buffer) <= strlen(Data))
 39.1339                          strcpy(Data, Buffer);
 39.1340 @@ -1916,7 +2189,7 @@
 39.1341                                      LPTABLE Table = it8 ->Tab + k;
 39.1342                                      LPKEYVALUE p;
 39.1343  
 39.1344 -                                    if (IsAvailableOnList(Table->HeaderList, Label, &p)) {
 39.1345 +                                    if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
 39.1346  
 39.1347                                          // Available, keep type and table
 39.1348                                          char Buffer[256];
 39.1349 @@ -1924,7 +2197,7 @@
 39.1350                                          char *Type  = p ->Value;
 39.1351                                          int  nTable = k;
 39.1352  
 39.1353 -                                        sprintf(Buffer, "%s %d %s", Label, nTable, Type );
 39.1354 +                                        snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type );
 39.1355  
 39.1356                                          SetData(it8, i, idField, Buffer);
 39.1357                                      }
 39.1358 @@ -1948,8 +2221,9 @@
 39.1359  // that should be something like some printable characters plus a \n
 39.1360  
 39.1361  static
 39.1362 -BOOL IsMyBlock(LPBYTE Buffer, size_t n)
 39.1363 +int IsMyBlock(LPBYTE Buffer, size_t n)
 39.1364  {
 39.1365 +    int cols = 1, space = 0, quot = 0;
 39.1366      size_t i;
 39.1367  
 39.1368      if (n < 10) return FALSE;   // Too small
 39.1369 @@ -1959,9 +2233,26 @@
 39.1370  
 39.1371      for (i = 1; i < n; i++) {
 39.1372  
 39.1373 -        if (Buffer[i] == '\n' || Buffer[i] == '\r' || Buffer[i] == '\t') return TRUE;
 39.1374 -        if (Buffer[i] < 32) return FALSE;
 39.1375 -
 39.1376 +        switch(Buffer[i])
 39.1377 +        {
 39.1378 +        case '\n':
 39.1379 +        case '\r':
 39.1380 +            return quot == 1 || cols > 2 ? 0 : cols;
 39.1381 +        case '\t':
 39.1382 +        case ' ':
 39.1383 +            if(!quot && !space)
 39.1384 +                space = 1;
 39.1385 +            break;
 39.1386 +        case '\"':
 39.1387 +            quot = !quot;
 39.1388 +            break;
 39.1389 +        default:
 39.1390 +            if (Buffer[i] < 32) return 0;
 39.1391 +            if (Buffer[i] > 127) return 0;
 39.1392 +            cols += space;
 39.1393 +            space = 0;
 39.1394 +            break;
 39.1395 +        }
 39.1396      }
 39.1397  
 39.1398      return FALSE;
 39.1399 @@ -1970,7 +2261,7 @@
 39.1400  
 39.1401  
 39.1402  static
 39.1403 -BOOL IsMyFile(const char* FileName)
 39.1404 +int IsMyFile(const char* FileName)
 39.1405  {
 39.1406     FILE *fp;
 39.1407     size_t Size;
 39.1408 @@ -1998,21 +2289,22 @@
 39.1409      LCMSHANDLE hIT8;
 39.1410      LPIT8  it8;
 39.1411  
 39.1412 -    if (!IsMyBlock((LPBYTE) Ptr, len)) return NULL;
 39.1413 +    int type = IsMyBlock((LPBYTE) Ptr, len);
 39.1414 +    if (type == 0) return NULL;
 39.1415  
 39.1416      hIT8 = cmsIT8Alloc();
 39.1417      if (!hIT8) return NULL;
 39.1418  
 39.1419      it8 = (LPIT8) hIT8;
 39.1420 -    it8 ->MemoryBlock = (char*) malloc(len + 1);
 39.1421 +    it8 ->MemoryBlock = (char*) _cmsMalloc(len + 1);
 39.1422  
 39.1423      strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
 39.1424      it8 ->MemoryBlock[len] = 0;
 39.1425  
 39.1426 -    strncpy(it8->FileName, "", MAX_PATH-1);
 39.1427 +    strncpy(it8->FileStack[0]->FileName, "", MAX_PATH-1);
 39.1428      it8-> Source = it8 -> MemoryBlock;
 39.1429  
 39.1430 -    if (!ParseIT8(it8)) {
 39.1431 +    if (!ParseIT8(it8, type-1)) {
 39.1432  
 39.1433          cmsIT8Free(hIT8);
 39.1434          return FALSE;
 39.1435 @@ -2021,7 +2313,7 @@
 39.1436      CookPointers(it8);
 39.1437      it8 ->nTable = 0;
 39.1438  
 39.1439 -    free(it8->MemoryBlock);
 39.1440 +     _cmsFree(it8->MemoryBlock);
 39.1441      it8 -> MemoryBlock = NULL;
 39.1442  
 39.1443      return hIT8;
 39.1444 @@ -2036,26 +2328,28 @@
 39.1445       LCMSHANDLE hIT8;
 39.1446       LPIT8  it8;
 39.1447  
 39.1448 -     if (!IsMyFile(cFileName)) return NULL;
 39.1449 +     int type = IsMyFile(cFileName);
 39.1450 +     if (type == 0) return NULL;
 39.1451  
 39.1452       hIT8 = cmsIT8Alloc();
 39.1453       it8 = (LPIT8) hIT8;
 39.1454       if (!hIT8) return NULL;
 39.1455  
 39.1456  
 39.1457 -     it8 ->Stream[0] = fopen(cFileName, "rt");
 39.1458 -
 39.1459 -     if (!it8 ->Stream[0]) {
 39.1460 +     it8 ->FileStack[0]->Stream = fopen(cFileName, "rt");
 39.1461 +
 39.1462 +     if (!it8 ->FileStack[0]->Stream) {
 39.1463           cmsIT8Free(hIT8);
 39.1464           return NULL;
 39.1465       }
 39.1466  
 39.1467  
 39.1468 -    strncpy(it8->FileName, cFileName, MAX_PATH-1);
 39.1469 -
 39.1470 -    if (!ParseIT8(it8)) {
 39.1471 -
 39.1472 -            fclose(it8 ->Stream[0]);
 39.1473 +    strncpy(it8->FileStack[0]->FileName, cFileName, MAX_PATH-1);
 39.1474 +    it8->FileStack[0]->FileName[MAX_PATH-1] = 0;
 39.1475 +
 39.1476 +    if (!ParseIT8(it8, type-1)) {
 39.1477 +
 39.1478 +            fclose(it8 ->FileStack[0]->Stream);
 39.1479              cmsIT8Free(hIT8);
 39.1480              return NULL;
 39.1481      }
 39.1482 @@ -2063,7 +2357,7 @@
 39.1483      CookPointers(it8);
 39.1484      it8 ->nTable = 0;
 39.1485  
 39.1486 -    fclose(it8 ->Stream[0]);
 39.1487 +    fclose(it8 ->FileStack[0]->Stream);
 39.1488      return hIT8;
 39.1489  
 39.1490  }
 39.1491 @@ -2078,12 +2372,12 @@
 39.1492  }
 39.1493  
 39.1494  
 39.1495 -int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, char ***PropertyNames)
 39.1496 +int LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, const char ***PropertyNames)
 39.1497  {
 39.1498      LPIT8 it8 = (LPIT8) hIT8;
 39.1499      LPKEYVALUE p;
 39.1500      int n;
 39.1501 -    char **Props;
 39.1502 +    const char **Props;
 39.1503      LPTABLE t = GetTable(it8);
 39.1504  
 39.1505      // Pass#1 - count properties
 39.1506 @@ -2094,7 +2388,7 @@
 39.1507      }
 39.1508  
 39.1509  
 39.1510 -    Props = (char **) AllocChunk(it8, sizeof(char *) * n);
 39.1511 +    Props = (const char **) AllocChunk(it8, sizeof(char *) * n);
 39.1512  
 39.1513      // Pass#2 - Fill pointers
 39.1514      n = 0;
 39.1515 @@ -2106,6 +2400,41 @@
 39.1516      return n;
 39.1517  }
 39.1518  
 39.1519 +int LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char ***SubpropertyNames)
 39.1520 +{
 39.1521 +    LPIT8 it8 = (LPIT8) hIT8;
 39.1522 +    LPKEYVALUE p, tmp;
 39.1523 +    int n;
 39.1524 +    const char **Props;
 39.1525 +    LPTABLE t = GetTable(it8);
 39.1526 +
 39.1527 +    if(!IsAvailableOnList(t->HeaderList, cProp, NULL, &p)) {
 39.1528 +        *SubpropertyNames = 0;
 39.1529 +        return 0;
 39.1530 +    }
 39.1531 +
 39.1532 +    // Pass#1 - count properties
 39.1533 +
 39.1534 +    n = 0;
 39.1535 +    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
 39.1536 +        if(tmp->Subkey != NULL)
 39.1537 +            n++;
 39.1538 +    }
 39.1539 +
 39.1540 +
 39.1541 +    Props = (const char **) AllocChunk(it8, sizeof(char *) * n);
 39.1542 +
 39.1543 +    // Pass#2 - Fill pointers
 39.1544 +    n = 0;
 39.1545 +    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
 39.1546 +        if(tmp->Subkey != NULL)
 39.1547 +            Props[n++] = p ->Subkey;
 39.1548 +    }
 39.1549 +
 39.1550 +    *SubpropertyNames = Props;
 39.1551 +    return n;
 39.1552 +}
 39.1553 +
 39.1554  static
 39.1555  int LocatePatch(LPIT8 it8, const char* cPatch)
 39.1556  {
 39.1557 @@ -2201,7 +2530,7 @@
 39.1558  }
 39.1559  
 39.1560  
 39.1561 -BOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val)
 39.1562 +LCMSBOOL LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col, const char* Val)
 39.1563  {
 39.1564      LPIT8 it8 = (LPIT8) hIT8;
 39.1565  
 39.1566 @@ -2209,7 +2538,7 @@
 39.1567  }
 39.1568  
 39.1569  
 39.1570 -BOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val)
 39.1571 +LCMSBOOL LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col, double Val)
 39.1572  {
 39.1573      LPIT8 it8 = (LPIT8) hIT8;
 39.1574      char Buff[256];
 39.1575 @@ -2260,7 +2589,7 @@
 39.1576  
 39.1577  
 39.1578  
 39.1579 -BOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE hIT8, const char* cPatch,
 39.1580 +LCMSBOOL LCMSEXPORT cmsIT8SetData(LCMSHANDLE hIT8, const char* cPatch,
 39.1581                          const char* cSample,
 39.1582                          const char *Val)
 39.1583  {
 39.1584 @@ -2305,18 +2634,19 @@
 39.1585  }
 39.1586  
 39.1587  
 39.1588 -BOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
 39.1589 +LCMSBOOL LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
 39.1590                          const char* cSample,
 39.1591                          double Val)
 39.1592  {
 39.1593      LPIT8 it8 = (LPIT8) hIT8;
 39.1594      char Buff[256];
 39.1595  
 39.1596 -        sprintf(Buff, it8->DoubleFormatter, Val);
 39.1597 +        snprintf(Buff, 255, it8->DoubleFormatter, Val);
 39.1598          return cmsIT8SetData(hIT8, cPatch, cSample, Buff);
 39.1599  
 39.1600  }
 39.1601  
 39.1602 +// Buffer should get MAXSTR at least
 39.1603  
 39.1604  const char* LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer)
 39.1605  {
 39.1606 @@ -2327,10 +2657,16 @@
 39.1607          if (!Data) return NULL;
 39.1608          if (!buffer) return Data;
 39.1609  
 39.1610 -        strcpy(buffer, Data);
 39.1611 +        strncpy(buffer, Data, MAXSTR-1);
 39.1612 +        buffer[MAXSTR-1] = 0;
 39.1613          return buffer;
 39.1614  }
 39.1615  
 39.1616 +int LCMSEXPORT cmsIT8GetPatchByName(LCMSHANDLE hIT8, const char *cPatch)
 39.1617 +{
 39.1618 +    return LocatePatch((LPIT8)hIT8, cPatch);
 39.1619 +}
 39.1620 +
 39.1621  int LCMSEXPORT cmsIT8TableCount(LCMSHANDLE hIT8)
 39.1622  {
 39.1623          LPIT8 it8 = (LPIT8) hIT8;
 39.1624 @@ -2356,7 +2692,7 @@
 39.1625      cLabelFld = cmsIT8GetData(hIT8, cSet, cField);
 39.1626      if (!cLabelFld) return -1;
 39.1627  
 39.1628 -    if (sscanf(cLabelFld, "%s %d %s", Label, &nTable, Type) != 3)
 39.1629 +    if (sscanf(cLabelFld, "%255s %d %255s", Label, &nTable, Type) != 3)
 39.1630              return -1;
 39.1631  
 39.1632      if (ExpectedType != NULL && *ExpectedType == 0)
 39.1633 @@ -2371,6 +2707,19 @@
 39.1634  }
 39.1635  
 39.1636  
 39.1637 +LCMSBOOL LCMSEXPORT cmsIT8SetIndexColumn(LCMSHANDLE hIT8, const char* cSample)
 39.1638 +{
 39.1639 +    LPIT8 it8 = (LPIT8) hIT8;
 39.1640 +
 39.1641 +    int pos = LocateSample(it8, cSample);
 39.1642 +    if(pos == -1)
 39.1643 +        return FALSE;
 39.1644 +
 39.1645 +    it8->Tab[it8->nTable].SampleID = pos;
 39.1646 +    return TRUE;
 39.1647 +}
 39.1648 +
 39.1649 +
 39.1650  void LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE hIT8, const char* Formatter)
 39.1651  {
 39.1652      LPIT8 it8 = (LPIT8) hIT8;
 39.1653 @@ -2380,3 +2729,4 @@
 39.1654      else
 39.1655          strcpy(it8->DoubleFormatter, Formatter);
 39.1656  }
 39.1657 +
    40.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c	Tue Apr 07 11:43:20 2009 -0700
    40.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c	Tue Apr 07 14:02:54 2009 -0700
    40.3 @@ -29,7 +29,7 @@
    40.4  //
    40.5  //
    40.6  //  Little cms
    40.7 -//  Copyright (C) 1998-2006 Marti Maria
    40.8 +//  Copyright (C) 1998-2007 Marti Maria
    40.9  //
   40.10  // Permission is hereby granted, free of charge, to any person obtaining
   40.11  // a copy of this software and associated documentation files (the "Software"),
   40.12 @@ -256,7 +256,7 @@
   40.13  // Return TRUE if both m and of are empy -- "m" being identity and "of" being 0
   40.14  
   40.15  static
   40.16 -BOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of)
   40.17 +LCMSBOOL IdentityParameters(LPWMAT3 m, LPWVEC3 of)
   40.18  {
   40.19      WVEC3 wv0;
   40.20  
   40.21 @@ -661,3 +661,6 @@
   40.22  
   40.23         return rc;
   40.24  }
   40.25 +
   40.26 +
   40.27 +
    41.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmserr.c	Tue Apr 07 11:43:20 2009 -0700
    41.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmserr.c	Tue Apr 07 14:02:54 2009 -0700
    41.3 @@ -29,7 +29,7 @@
    41.4  //
    41.5  //
    41.6  //  Little cms
    41.7 -//  Copyright (C) 1998-2006 Marti Maria
    41.8 +//  Copyright (C) 1998-2007 Marti Maria
    41.9  //
   41.10  // Permission is hereby granted, free of charge, to any person obtaining
   41.11  // a copy of this software and associated documentation files (the "Software"),
   41.12 @@ -57,6 +57,7 @@
   41.13  // errors.
   41.14  
   41.15  void cdecl cmsSignalError(int ErrorCode, const char *ErrorText, ...);
   41.16 +
   41.17  int  LCMSEXPORT cmsErrorAction(int lAbort);
   41.18  void LCMSEXPORT cmsSetErrorHandler(cmsErrorHandlerFunction Fn);
   41.19  
   41.20 @@ -96,7 +97,7 @@
   41.21  
   41.22              char Buffer[1024];
   41.23  
   41.24 -            vsprintf(Buffer, ErrorText, args);
   41.25 +            vsnprintf(Buffer, 1023, ErrorText, args);
   41.26              va_end(args);
   41.27  
   41.28              if (UserErrorHandler(ErrorCode, Buffer)) {
   41.29 @@ -118,8 +119,8 @@
   41.30                char Buffer1[1024];
   41.31                char Buffer2[256];
   41.32  
   41.33 -              sprintf(Buffer1, "Error #%x; ", ErrorCode);
   41.34 -              vsprintf(Buffer2, ErrorText, args);
   41.35 +              snprintf(Buffer1,  767, "Error #%x; ", ErrorCode);
   41.36 +              vsnprintf(Buffer2, 255, ErrorText, args);
   41.37                strcat(Buffer1, Buffer2);
   41.38                MessageBox(NULL, Buffer1, "Little cms",
   41.39                                            MB_OK|MB_ICONSTOP|MB_TASKMODAL);
    42.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c	Tue Apr 07 11:43:20 2009 -0700
    42.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c	Tue Apr 07 14:02:54 2009 -0700
    42.3 @@ -29,7 +29,7 @@
    42.4  //
    42.5  //
    42.6  //  Little cms
    42.7 -//  Copyright (C) 1998-2006 Marti Maria
    42.8 +//  Copyright (C) 1998-2007 Marti Maria
    42.9  //
   42.10  // Permission is hereby granted, free of charge, to any person obtaining
   42.11  // a copy of this software and associated documentation files (the "Software"),
   42.12 @@ -63,9 +63,9 @@
   42.13  LPGAMMATABLE LCMSEXPORT cmsBuildParametricGamma(int nEntries, int Type, double Params[]);
   42.14  LPGAMMATABLE LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma);
   42.15  LPGAMMATABLE LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma, int nPoints);
   42.16 -BOOL         LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
   42.17 +LCMSBOOL         LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
   42.18  
   42.19 -BOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints);
   42.20 +LCMSBOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nPoints);
   42.21  
   42.22  
   42.23  // Sampled curves
   42.24 @@ -74,7 +74,7 @@
   42.25  void           cdecl cmsFreeSampledCurve(LPSAMPLEDCURVE p);
   42.26  void           cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max);
   42.27  void           cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max);
   42.28 -BOOL           cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
   42.29 +LCMSBOOL       cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
   42.30  void           cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints);
   42.31  
   42.32  LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints);
   42.33 @@ -84,7 +84,6 @@
   42.34  
   42.35  // ----------------------------------------------------------------------------------------
   42.36  
   42.37 -// #define DEBUG 1
   42.38  
   42.39  #define MAX_KNOTS   4096
   42.40  typedef float vec[MAX_KNOTS+1];
   42.41 @@ -144,14 +143,14 @@
   42.42         LPGAMMATABLE p;
   42.43         size_t size;
   42.44  
   42.45 -       if (nEntries > 65530) {
   42.46 -                cmsSignalError(LCMS_ERRC_WARNING, "Couldn't create gammatable of more than 65530 entries; 65530 assumed");
   42.47 -                nEntries = 65530;
   42.48 +       if (nEntries > 65530 || nEntries <= 0) {
   42.49 +                cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't create gammatable of more than 65530 entries");
   42.50 +                return NULL;
   42.51         }
   42.52  
   42.53         size = sizeof(GAMMATABLE) + (sizeof(WORD) * (nEntries-1));
   42.54  
   42.55 -       p = (LPGAMMATABLE) malloc(size);
   42.56 +       p = (LPGAMMATABLE) _cmsMalloc(size);
   42.57         if (!p) return NULL;
   42.58  
   42.59         ZeroMemory(p, size);
   42.60 @@ -164,7 +163,7 @@
   42.61  
   42.62  void LCMSEXPORT cmsFreeGamma(LPGAMMATABLE Gamma)
   42.63  {
   42.64 -       if (Gamma) free(Gamma);
   42.65 +       if (Gamma)  _cmsFree(Gamma);
   42.66  }
   42.67  
   42.68  
   42.69 @@ -278,6 +277,15 @@
   42.70         LPWORD InPtr;
   42.71         LPGAMMATABLE p;
   42.72  
   42.73 +       // Try to reverse it analytically whatever possible
   42.74 +       if (InGamma -> Seed.Type > 0 && InGamma -> Seed.Type <= 5 &&
   42.75 +            _cmsCrc32OfGammaTable(InGamma) == InGamma -> Seed.Crc32) {
   42.76 +
   42.77 +                return cmsBuildParametricGamma(nResultSamples, -(InGamma -> Seed.Type), InGamma ->Seed.Params);
   42.78 +       }
   42.79 +
   42.80 +
   42.81 +       // Nope, reverse the table
   42.82         p = cmsAllocGamma(nResultSamples);
   42.83         if (!p) return NULL;
   42.84  
   42.85 @@ -528,7 +536,7 @@
   42.86  
   42.87  // Smooths a curve sampled at regular intervals
   42.88  
   42.89 -BOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda)
   42.90 +LCMSBOOL LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda)
   42.91  
   42.92  {
   42.93      vec w, y, z;
   42.94 @@ -640,13 +648,13 @@
   42.95  {
   42.96      LPSAMPLEDCURVE pOut;
   42.97  
   42.98 -    pOut = (LPSAMPLEDCURVE) malloc(sizeof(SAMPLEDCURVE));
   42.99 +    pOut = (LPSAMPLEDCURVE) _cmsMalloc(sizeof(SAMPLEDCURVE));
  42.100      if (pOut == NULL)
  42.101              return NULL;
  42.102  
  42.103 -    if((pOut->Values = (double *) malloc(nItems * sizeof(double))) == NULL)
  42.104 +    if((pOut->Values = (double *) _cmsMalloc(nItems * sizeof(double))) == NULL)
  42.105      {
  42.106 -        free(pOut);
  42.107 +         _cmsFree(pOut);
  42.108          return NULL;
  42.109      }
  42.110  
  42.111 @@ -659,8 +667,8 @@
  42.112  
  42.113  void cmsFreeSampledCurve(LPSAMPLEDCURVE p)
  42.114  {
  42.115 -    free((LPVOID) p -> Values);
  42.116 -    free((LPVOID) p);
  42.117 +     _cmsFree((LPVOID) p -> Values);
  42.118 +     _cmsFree((LPVOID) p);
  42.119  }
  42.120  
  42.121  
  42.122 @@ -731,7 +739,7 @@
  42.123  
  42.124  // Smooths a curve sampled at regular intervals
  42.125  
  42.126 -BOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda)
  42.127 +LCMSBOOL cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double lambda)
  42.128  {
  42.129      vec w, y, z;
  42.130      int i, nItems;
  42.131 @@ -915,14 +923,11 @@
  42.132  
  42.133  // Smooth endpoints (used in Black/White compensation)
  42.134  
  42.135 -BOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries)
  42.136 +LCMSBOOL _cmsSmoothEndpoints(LPWORD Table, int nEntries)
  42.137  {
  42.138      vec w, y, z;
  42.139      int i, Zeros, Poles;
  42.140  
  42.141 -#ifdef DEBUG
  42.142 -        ASAVE(Table, nEntries, "nonsmt.txt");
  42.143 -#endif
  42.144  
  42.145  
  42.146      if (cmsIsLinear(Table, nEntries)) return FALSE; // Nothing to do
    43.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c	Tue Apr 07 11:43:20 2009 -0700
    43.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c	Tue Apr 07 14:02:54 2009 -0700
    43.3 @@ -29,7 +29,7 @@
    43.4  //
    43.5  //
    43.6  //  Little cms
    43.7 -//  Copyright (C) 1998-2006 Marti Maria
    43.8 +//  Copyright (C) 1998-2007 Marti Maria
    43.9  //
   43.10  // Permission is hereby granted, free of charge, to any person obtaining
   43.11  // a copy of this software and associated documentation files (the "Software"),
   43.12 @@ -66,7 +66,7 @@
   43.13  */
   43.14  
   43.15  
   43.16 -BOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black,
   43.17 +LCMSBOOL _cmsEndPointsBySpace(icColorSpaceSignature Space, WORD **White, WORD **Black,
   43.18                              int *nOutputs)
   43.19  {
   43.20         // Only most common spaces
   43.21 @@ -376,7 +376,6 @@
   43.22      double bs = Lab2 ->b;
   43.23      double Cs = sqrt( Sqr(as) + Sqr(bs) );
   43.24  
   43.25 -
   43.26      double G = 0.5 * ( 1 - sqrt(pow((C + Cs) / 2 , 7.0) / (pow((C + Cs) / 2, 7.0) + pow(25.0, 7.0) ) ));
   43.27  
   43.28      double a_p = (1 + G ) * a1;
   43.29 @@ -390,15 +389,21 @@
   43.30      double C_ps = sqrt(Sqr(a_ps) + Sqr(b_ps));
   43.31      double h_ps = atan2deg(a_ps, b_ps);
   43.32  
   43.33 -
   43.34 -
   43.35      double meanC_p =(C_p + C_ps) / 2;
   43.36  
   43.37 -    double meanh_p = fabs(h_ps-h_p) <= 180 ? (h_ps + h_p)/2 : (h_ps+h_p-360)/2;
   43.38 +    double hps_plus_hp  = h_ps + h_p;
   43.39 +    double hps_minus_hp = h_ps - h_p;
   43.40  
   43.41 -    double delta_h = fabs(h_p - h_ps) <= 180 ? fabs(h_p - h_ps) : 360 - fabs(h_p - h_ps);
   43.42 -    double delta_L = fabs(L1 - Ls);
   43.43 -    double delta_C = fabs(C_p - C_ps);
   43.44 +    double meanh_p = fabs(hps_minus_hp) <= 180.000001 ? (hps_plus_hp)/2 :
   43.45 +                            (hps_plus_hp) < 360 ? (hps_plus_hp + 360)/2 :
   43.46 +                                                 (hps_plus_hp - 360)/2;
   43.47 +
   43.48 +    double delta_h = (hps_minus_hp) <= -180.000001 ?  (hps_minus_hp + 360) :
   43.49 +                            (hps_minus_hp) > 180 ? (hps_minus_hp - 360) :
   43.50 +                                                    (hps_minus_hp);
   43.51 +    double delta_L = (Ls - L1);
   43.52 +    double delta_C = (C_ps - C_p );
   43.53 +
   43.54  
   43.55      double delta_H =2 * sqrt(C_ps*C_p) * sin(RADIANES(delta_h) / 2);
   43.56  
   43.57 @@ -1065,7 +1070,7 @@
   43.58  // Check for monotonicity.
   43.59  
   43.60  static
   43.61 -BOOL IsMonotonic(LPGAMMATABLE t)
   43.62 +LCMSBOOL IsMonotonic(LPGAMMATABLE t)
   43.63  {
   43.64      int n = t -> nEntries;
   43.65      int i, last;
   43.66 @@ -1088,7 +1093,7 @@
   43.67  // Check for endpoints
   43.68  
   43.69  static
   43.70 -BOOL HasProperEndpoints(LPGAMMATABLE t)
   43.71 +LCMSBOOL HasProperEndpoints(LPGAMMATABLE t)
   43.72  {
   43.73      if (t ->GammaTable[0] != 0) return FALSE;
   43.74      if (t ->GammaTable[t ->nEntries-1] != 0xFFFF) return FALSE;
   43.75 @@ -1109,7 +1114,7 @@
   43.76      unsigned int t, i, v;
   43.77      int j;
   43.78      WORD In[MAXCHANNELS], Out[MAXCHANNELS];
   43.79 -    BOOL lIsSuitable;
   43.80 +    LCMSBOOL lIsSuitable;
   43.81      _LPcmsTRANSFORM InputXForm   = (_LPcmsTRANSFORM) h[0];
   43.82      _LPcmsTRANSFORM OutputXForm  = (_LPcmsTRANSFORM) h[nTransforms-1];
   43.83  
   43.84 @@ -1126,10 +1131,10 @@
   43.85      }
   43.86  
   43.87  
   43.88 -    // Do nothing on all but RGB to RGB transforms
   43.89 +    // Do nothing on all but Gray/RGB to Gray/RGB transforms
   43.90  
   43.91 -    if ((InputXForm ->EntryColorSpace != icSigRgbData) ||
   43.92 -        (OutputXForm->ExitColorSpace  != icSigRgbData)) return;
   43.93 +    if (((InputXForm ->EntryColorSpace != icSigRgbData) && (InputXForm ->EntryColorSpace != icSigGrayData)) ||
   43.94 +        ((OutputXForm->ExitColorSpace  != icSigRgbData) && (OutputXForm->ExitColorSpace  != icSigGrayData))) return;
   43.95  
   43.96  
   43.97      for (t = 0; t < Grid -> InputChan; t++)
   43.98 @@ -1169,10 +1174,13 @@
   43.99          if (!HasProperEndpoints(Trans[t]))
  43.100                      lIsSuitable = FALSE;
  43.101  
  43.102 +        /*
  43.103          // Exclude if transfer function is not smooth enough
  43.104          // to be modelled as a gamma function, or the gamma is reversed
  43.105 +
  43.106          if (cmsEstimateGamma(Trans[t]) < 1.0)
  43.107                      lIsSuitable = FALSE;
  43.108 +        */
  43.109  
  43.110      }
  43.111  
    44.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c	Tue Apr 07 11:43:20 2009 -0700
    44.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c	Tue Apr 07 14:02:54 2009 -0700
    44.3 @@ -29,7 +29,7 @@
    44.4  //
    44.5  //
    44.6  //  Little cms
    44.7 -//  Copyright (C) 1998-2006 Marti Maria
    44.8 +//  Copyright (C) 1998-2007 Marti Maria
    44.9  //
   44.10  // Permission is hereby granted, free of charge, to any person obtaining
   44.11  // a copy of this software and associated documentation files (the "Software"),
   44.12 @@ -282,7 +282,7 @@
   44.13  // Fills optimization parameters
   44.14  
   44.15  void cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan,
   44.16 -                                            BOOL lUseTetrahedral, LPL16PARAMS p)
   44.17 +                                            LCMSBOOL lUseTetrahedral, LPL16PARAMS p)
   44.18  {
   44.19         int clutPoints;
   44.20  
   44.21 @@ -579,7 +579,7 @@
   44.22  
   44.23                  // Identify if value fall downto 0 or FFFF zone
   44.24                  if (Value == 0) return 0;
   44.25 -                if (Value == 0xFFFF) return 0xFFFF;
   44.26 +               // if (Value == 0xFFFF) return 0xFFFF;
   44.27  
   44.28                  // else restrict to valid zone
   44.29  
   44.30 @@ -631,7 +631,7 @@
   44.31          a = (y1 - y0) / (x1 - x0);
   44.32          b = y0 - a * x0;
   44.33  
   44.34 -        if (a == 0) return (WORD) x;
   44.35 +        if (fabs(a) < 0.01) return (WORD) x;
   44.36  
   44.37          f = ((Value - b) / a);
   44.38  
   44.39 @@ -763,7 +763,7 @@
   44.40      X0 = p -> opta3 * x0;
   44.41      X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta3);
   44.42  
   44.43 -        Y0 = p -> opta2 * y0;
   44.44 +    Y0 = p -> opta2 * y0;
   44.45      Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta2);
   44.46  
   44.47      Z0 = p -> opta1 * z0;
   44.48 @@ -942,7 +942,7 @@
   44.49      X0 = p -> opta3 * x0;
   44.50      X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta3);
   44.51  
   44.52 -        Y0 = p -> opta2 * y0;
   44.53 +    Y0 = p -> opta2 * y0;
   44.54      Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta2);
   44.55  
   44.56      Z0 = p -> opta1 * z0;
   44.57 @@ -1009,11 +1009,11 @@
   44.58  
   44.59          Rest = c1 * rx + c2 * ry + c3 * rz;
   44.60  
   44.61 -                // There is a lot of math hidden in this expression. The rest is in fixed domain
   44.62 -                // and the result in 0..ffff domain. So the complete expression should be
   44.63 -                // ROUND_FIXED_TO_INT(ToFixedDomain(Rest)) But that can be optimized as (Rest + 0x7FFF) / 0xFFFF
   44.64 +        // There is a lot of math hidden in this expression. The rest is in fixed domain
   44.65 +        // and the result in 0..ffff domain. So the complete expression should be
   44.66 +        // ROUND_FIXED_TO_INT(ToFixedDomain(Rest)) But that can be optimized as (Rest + 0x7FFF) / 0xFFFF
   44.67  
   44.68 -                Output[OutChan] = (WORD) (c0 + ((Rest + 0x7FFF) / 0xFFFF));
   44.69 +        Output[OutChan] = (WORD) (c0 + ((Rest + 0x7FFF) / 0xFFFF));
   44.70  
   44.71      }
   44.72  
   44.73 @@ -1131,3 +1131,4 @@
   44.74  }
   44.75  
   44.76  #undef DENS
   44.77 +
    45.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsio0.c	Tue Apr 07 11:43:20 2009 -0700
    45.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsio0.c	Tue Apr 07 14:02:54 2009 -0700
    45.3 @@ -29,7 +29,7 @@
    45.4  //
    45.5  //
    45.6  //  Little cms
    45.7 -//  Copyright (C) 1998-2006 Marti Maria
    45.8 +//  Copyright (C) 1998-2007 Marti Maria
    45.9  //
   45.10  // Permission is hereby granted, free of charge, to any person obtaining
   45.11  // a copy of this software and associated documentation files (the "Software"),
   45.12 @@ -62,7 +62,7 @@
   45.13  typedef struct {
   45.14                  LPBYTE Block;           // Points to allocated memory
   45.15                  size_t Size;            // Size of allocated memory
   45.16 -                int Pointer;            // Points to current location
   45.17 +                size_t Pointer;         // Points to current location
   45.18                  int FreeBlockOnClose;   // As title
   45.19  
   45.20                  } FILEMEM;
   45.21 @@ -70,18 +70,19 @@
   45.22  static
   45.23  LPVOID MemoryOpen(LPBYTE Block, size_t Size, char Mode)
   45.24  {
   45.25 -    FILEMEM* fm = (FILEMEM*) malloc(sizeof(FILEMEM));
   45.26 +    FILEMEM* fm = (FILEMEM*) _cmsMalloc(sizeof(FILEMEM));
   45.27 +    if (fm == NULL) return NULL;
   45.28 +
   45.29      ZeroMemory(fm, sizeof(FILEMEM));
   45.30  
   45.31      if (Mode == 'r') {
   45.32  
   45.33 -        fm ->Block   = (LPBYTE) malloc(Size);
   45.34 +        fm ->Block   = (LPBYTE) _cmsMalloc(Size);
   45.35          if (fm ->Block == NULL) {
   45.36 -            free(fm);
   45.37 +             _cmsFree(fm);
   45.38              return NULL;
   45.39          }
   45.40  
   45.41 -
   45.42          CopyMemory(fm->Block, Block, Size);
   45.43          fm ->FreeBlockOnClose = TRUE;
   45.44      }
   45.45 @@ -103,13 +104,27 @@
   45.46       FILEMEM* ResData = (FILEMEM*) Icc ->stream;
   45.47       LPBYTE Ptr;
   45.48       size_t len = size * count;
   45.49 +     size_t extent = ResData -> Pointer + len;
   45.50  
   45.51 +        if (len == 0) {
   45.52 +                return 0;
   45.53 +        }
   45.54  
   45.55 -     if (ResData -> Pointer + len > ResData -> Size){
   45.56 +        if (len / size != count) {
   45.57 +          cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with count / size.");
   45.58 +          return 0;
   45.59 +      }
   45.60 +
   45.61 +      if (extent < len || extent < ResData -> Pointer) {
   45.62 +          cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with len.");
   45.63 +          return 0;
   45.64 +      }
   45.65 +
   45.66 +      if (ResData -> Pointer + len > ResData -> Size) {
   45.67  
   45.68           len = (ResData -> Size - ResData -> Pointer);
   45.69 -         cmsSignalError(LCMS_ERRC_WARNING, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size);
   45.70 -
   45.71 +         cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Got %d bytes, block should be of %d bytes", len * size, count * size);
   45.72 +         return 0;
   45.73       }
   45.74  
   45.75      Ptr  = ResData -> Block;
   45.76 @@ -123,7 +138,7 @@
   45.77  // SEEK_CUR is assumed
   45.78  
   45.79  static
   45.80 -BOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
   45.81 +LCMSBOOL MemorySeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
   45.82  {
   45.83      FILEMEM* ResData = (FILEMEM*) Icc ->stream;
   45.84  
   45.85 @@ -147,18 +162,19 @@
   45.86  }
   45.87  
   45.88  
   45.89 -// Writes data to memory, also keeps used space for further reference
   45.90 +// Writes data to memory, also keeps used space for further reference. NO CHECK IS PERFORMED
   45.91  
   45.92  static
   45.93 -BOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
   45.94 +LCMSBOOL MemoryWrite(struct _lcms_iccprofile_struct* Icc, size_t size, void *Ptr)
   45.95  {
   45.96          FILEMEM* ResData = (FILEMEM*) Icc ->stream;
   45.97  
   45.98         if (size == 0) return TRUE;
   45.99  
  45.100         if (ResData != NULL)
  45.101 -           CopyMemory(ResData ->Block + Icc ->UsedSpace, Ptr, size);
  45.102 +           CopyMemory(ResData ->Block + ResData ->Pointer, Ptr, size);
  45.103  
  45.104 +       ResData->Pointer += size;
  45.105         Icc->UsedSpace += size;
  45.106  
  45.107         return TRUE;
  45.108 @@ -166,15 +182,37 @@
  45.109  
  45.110  
  45.111  static
  45.112 -BOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
  45.113 +LCMSBOOL MemoryGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
  45.114 +{
  45.115 +    FILEMEM* ResData = (FILEMEM*) Icc->stream;
  45.116 +
  45.117 +    void* newBlock = NULL;
  45.118 +
  45.119 +    /* Follow same policies as functions in lcms.h  */
  45.120 +    if (ResData->Size + size < 0) return NULL;
  45.121 +    if (ResData->Size + size > ((size_t)1024*1024*500)) return NULL;
  45.122 +
  45.123 +    newBlock = realloc(ResData->Block, ResData->Size + size);
  45.124 +
  45.125 +    if (!newBlock) {
  45.126 +        return FALSE;
  45.127 +    }
  45.128 +    ResData->Block = newBlock;
  45.129 +    ResData->Size += size;
  45.130 +    return TRUE;
  45.131 +}
  45.132 +
  45.133 +
  45.134 +static
  45.135 +LCMSBOOL MemoryClose(struct _lcms_iccprofile_struct* Icc)
  45.136  {
  45.137      FILEMEM* ResData = (FILEMEM*) Icc ->stream;
  45.138  
  45.139      if (ResData ->FreeBlockOnClose) {
  45.140  
  45.141 -        if (ResData ->Block) free(ResData ->Block);
  45.142 +        if (ResData ->Block)  _cmsFree(ResData ->Block);
  45.143      }
  45.144 -    free(ResData);
  45.145 +     _cmsFree(ResData);
  45.146      return 0;
  45.147  }
  45.148  
  45.149 @@ -192,7 +230,7 @@
  45.150  {
  45.151      size_t nReaded = fread(buffer, size, count, (FILE*) Icc->stream);
  45.152      if (nReaded != count) {
  45.153 -            cmsSignalError(LCMS_ERRC_WARNING, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size);
  45.154 +            cmsSignalError(LCMS_ERRC_ABORTED, "Read error. Got %d bytes, block should be of %d bytes", nReaded * size, count * size);
  45.155              return 0;
  45.156      }
  45.157  
  45.158 @@ -201,7 +239,7 @@
  45.159  
  45.160  
  45.161  static
  45.162 -BOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
  45.163 +LCMSBOOL FileSeek(struct _lcms_iccprofile_struct* Icc, size_t offset)
  45.164  {
  45.165      if (fseek((FILE*) Icc ->stream, (long) offset, SEEK_SET) != 0) {
  45.166  
  45.167 @@ -223,7 +261,7 @@
  45.168  
  45.169  
  45.170  static
  45.171 -BOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
  45.172 +LCMSBOOL FileWrite(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr)
  45.173  {
  45.174         if (size == 0) return TRUE;
  45.175  
  45.176 @@ -239,7 +277,14 @@
  45.177  
  45.178  
  45.179  static
  45.180 -BOOL FileClose(struct _lcms_iccprofile_struct* Icc)
  45.181 +LCMSBOOL FileGrow(struct _lcms_iccprofile_struct* Icc, size_t size)
  45.182 +{
  45.183 +  return TRUE;
  45.184 +}
  45.185 +
  45.186 +
  45.187 +static
  45.188 +LCMSBOOL FileClose(struct _lcms_iccprofile_struct* Icc)
  45.189  {
  45.190      return fclose((FILE*) Icc ->stream);
  45.191  }
  45.192 @@ -252,7 +297,7 @@
  45.193  cmsHPROFILE _cmsCreateProfilePlaceholder(void)
  45.194  {
  45.195  
  45.196 -    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) malloc(sizeof(LCMSICCPROFILE));
  45.197 +    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) _cmsMalloc(sizeof(LCMSICCPROFILE));
  45.198      if (Icc == NULL) return NULL;
  45.199  
  45.200      // Empty values
  45.201 @@ -290,7 +335,7 @@
  45.202  // Search for a specific tag in tag dictionary
  45.203  // Returns position or -1 if tag not found
  45.204  
  45.205 -icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError)
  45.206 +icInt32Number _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError)
  45.207  {
  45.208         icInt32Number i;
  45.209  
  45.210 @@ -311,7 +356,7 @@
  45.211  
  45.212  // Check existance
  45.213  
  45.214 -BOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
  45.215 +LCMSBOOL LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig)
  45.216  {
  45.217         LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.218         return _cmsSearchTag(Icc, sig, FALSE) >= 0;
  45.219 @@ -330,7 +375,7 @@
  45.220  
  45.221      if (i >=0) {
  45.222  
  45.223 -        if (Icc -> TagPtrs[i]) free(Icc -> TagPtrs[i]);
  45.224 +        if (Icc -> TagPtrs[i]) _cmsFree(Icc -> TagPtrs[i]);
  45.225      }
  45.226      else  {
  45.227  
  45.228 @@ -341,11 +386,14 @@
  45.229  
  45.230              cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", MAX_TABLE_TAG);
  45.231              Icc ->TagCount = MAX_TABLE_TAG-1;
  45.232 +            return NULL;
  45.233          }
  45.234      }
  45.235  
  45.236  
  45.237 -    Ptr = malloc(size);
  45.238 +    Ptr = _cmsMalloc(size);
  45.239 +    if (Ptr == NULL) return NULL;
  45.240 +
  45.241      CopyMemory(Ptr, Init, size);
  45.242  
  45.243      Icc ->TagNames[i] = sig;
  45.244 @@ -376,12 +424,15 @@
  45.245      if (NewIcc == NULL) return NULL;
  45.246  
  45.247      strncpy(NewIcc -> PhysicalFile, FileName, MAX_PATH-1);
  45.248 +    NewIcc -> PhysicalFile[MAX_PATH-1] = 0;
  45.249 +
  45.250      NewIcc ->stream = ICCfile;
  45.251  
  45.252      NewIcc ->Read  = FileRead;
  45.253      NewIcc ->Seek  = FileSeek;
  45.254      NewIcc ->Tell  = FileTell;
  45.255      NewIcc ->Close = FileClose;
  45.256 +    NewIcc ->Grow  = FileGrow;
  45.257      NewIcc ->Write = NULL;
  45.258  
  45.259      NewIcc ->IsWrite = FALSE;
  45.260 @@ -419,7 +470,8 @@
  45.261      NewIcc ->Seek  = MemorySeek;
  45.262      NewIcc ->Tell  = MemoryTell;
  45.263      NewIcc ->Close = MemoryClose;
  45.264 -    NewIcc ->Write = NULL;
  45.265 +    NewIcc ->Grow  = MemoryGrow;
  45.266 +    NewIcc ->Write = MemoryWrite;
  45.267  
  45.268      NewIcc ->IsWrite = FALSE;
  45.269  
  45.270 @@ -476,7 +528,7 @@
  45.271  
  45.272  
  45.273  
  45.274 -BOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
  45.275 +LCMSBOOL LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
  45.276  {
  45.277       LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) hProfile;
  45.278       *Dest = Icc -> MediaWhitePoint;
  45.279 @@ -484,14 +536,14 @@
  45.280  }
  45.281  
  45.282  
  45.283 -BOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
  45.284 +LCMSBOOL LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
  45.285  {
  45.286        LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) hProfile;
  45.287        *Dest = Icc -> MediaBlackPoint;
  45.288        return TRUE;
  45.289  }
  45.290  
  45.291 -BOOL  LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
  45.292 +LCMSBOOL  LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile)
  45.293  {
  45.294         LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
  45.295         *Dest = Icc -> Illuminant;
  45.296 @@ -549,7 +601,7 @@
  45.297  }
  45.298  
  45.299  
  45.300 -BOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
  45.301 +LCMSBOOL LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
  45.302  {
  45.303      LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.304      CopyMemory(Dest, &Icc ->Created, sizeof(struct tm));
  45.305 @@ -570,23 +622,18 @@
  45.306         Icc -> PCS = pcs;
  45.307  }
  45.308  
  45.309 -
  45.310 -
  45.311  icColorSpaceSignature LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile)
  45.312  {
  45.313         LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
  45.314         return Icc -> ColorSpace;
  45.315  }
  45.316  
  45.317 -
  45.318 -
  45.319  void LCMSEXPORT cmsSetColorSpace(cmsHPROFILE hProfile, icColorSpaceSignature sig)
  45.320  {
  45.321         LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
  45.322         Icc -> ColorSpace = sig;
  45.323  }
  45.324  
  45.325 -
  45.326  icProfileClassSignature LCMSEXPORT cmsGetDeviceClass(cmsHPROFILE hProfile)
  45.327  {
  45.328         LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
  45.329 @@ -599,7 +646,6 @@
  45.330         return (DWORD) Icc -> Version;
  45.331  }
  45.332  
  45.333 -
  45.334  void LCMSEXPORT cmsSetProfileICCversion(cmsHPROFILE hProfile, DWORD Version)
  45.335  {
  45.336     LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) hProfile;
  45.337 @@ -638,7 +684,7 @@
  45.338  
  45.339  // This is tricky, since LUT structs does have pointers
  45.340  
  45.341 -BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut)
  45.342 +LCMSBOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile, icTagSignature sig, const void* lut)
  45.343  {
  45.344         LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.345         LPLUT Orig, Stored;
  45.346 @@ -666,7 +712,7 @@
  45.347  }
  45.348  
  45.349  
  45.350 -BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ)
  45.351 +LCMSBOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* XYZ)
  45.352  {
  45.353         LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.354  
  45.355 @@ -675,7 +721,7 @@
  45.356  }
  45.357  
  45.358  
  45.359 -BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text)
  45.360 +LCMSBOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile, icTagSignature sig, const char* Text)
  45.361  {
  45.362         LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.363  
  45.364 @@ -683,7 +729,7 @@
  45.365         return TRUE;
  45.366  }
  45.367  
  45.368 -BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction)
  45.369 +LCMSBOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction)
  45.370  {
  45.371      LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.372  
  45.373 @@ -692,7 +738,7 @@
  45.374  }
  45.375  
  45.376  
  45.377 -BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm)
  45.378 +LCMSBOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm)
  45.379  {
  45.380      LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.381  
  45.382 @@ -701,7 +747,7 @@
  45.383  }
  45.384  
  45.385  
  45.386 -BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq)
  45.387 +LCMSBOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ pseq)
  45.388  {
  45.389      LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.390  
  45.391 @@ -711,28 +757,40 @@
  45.392  }
  45.393  
  45.394  
  45.395 -BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
  45.396 +LCMSBOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
  45.397  {
  45.398      LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.399  
  45.400      _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
  45.401 -    return FALSE;
  45.402 +    return TRUE;
  45.403  }
  45.404  
  45.405  
  45.406 -BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime)
  45.407 +LCMSBOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime)
  45.408  {
  45.409      LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.410  
  45.411      _cmsInitTag(Icc, sig, sizeof(struct tm), DateTime);
  45.412 -    return FALSE;
  45.413 +    return TRUE;
  45.414  }
  45.415  
  45.416  
  45.417 -BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
  45.418 +LCMSBOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc)
  45.419  {
  45.420      LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.421  
  45.422      _cmsInitTag(Icc, sig, sizeof(cmsNAMEDCOLORLIST) + (nc ->nColors - 1) * sizeof(cmsNAMEDCOLOR), nc);
  45.423 -    return FALSE;
  45.424 +    return TRUE;
  45.425  }
  45.426 +
  45.427 +
  45.428 +LCMSBOOL LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat)
  45.429 +{
  45.430 +    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
  45.431 +
  45.432 +    _cmsInitTag(Icc, sig, 3*sizeof(cmsCIEXYZ), mat);
  45.433 +    return TRUE;
  45.434 +
  45.435 +}
  45.436 +
  45.437 +
    46.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsio1.c	Tue Apr 07 11:43:20 2009 -0700
    46.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsio1.c	Tue Apr 07 14:02:54 2009 -0700
    46.3 @@ -29,7 +29,7 @@
    46.4  //
    46.5  //
    46.6  //  Little cms
    46.7 -//  Copyright (C) 1998-2006 Marti Maria
    46.8 +//  Copyright (C) 1998-2007 Marti Maria
    46.9  //
   46.10  // Permission is hereby granted, free of charge, to any person obtaining
   46.11  // a copy of this software and associated documentation files (the "Software"),
   46.12 @@ -149,6 +149,7 @@
   46.13  
   46.14  #endif
   46.15  
   46.16 +
   46.17  // Transports to properly encoded values - note that icc profiles does use
   46.18  // big endian notation.
   46.19  
   46.20 @@ -216,7 +217,8 @@
   46.21  {
   46.22      icTagBase Base;
   46.23  
   46.24 -    Icc -> Read(&Base, sizeof(icTagBase), 1, Icc);
   46.25 +    if (Icc -> Read(&Base, sizeof(icTagBase), 1, Icc) != 1)
   46.26 +                return (icTagTypeSignature) 0;
   46.27      AdjustEndianess32((LPBYTE) &Base.sig);
   46.28  
   46.29      return Base.sig;
   46.30 @@ -288,13 +290,15 @@
   46.31  // Read profile header and validate it
   46.32  
   46.33  static
   46.34 -LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, BOOL lIsFromMemory)
   46.35 +LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, LCMSBOOL lIsFromMemory)
   46.36  {
   46.37       icTag Tag;
   46.38       icHeader Header;
   46.39       icInt32Number TagCount, i;
   46.40 -
   46.41 -     Icc -> Read(&Header, sizeof(icHeader), 1, Icc);
   46.42 +     icUInt32Number extent;
   46.43 +
   46.44 +       if (Icc -> Read(&Header, sizeof(icHeader), 1, Icc) != 1)
   46.45 +                      goto ErrorCleanup;
   46.46  
   46.47         // Convert endian
   46.48  
   46.49 @@ -306,14 +310,13 @@
   46.50         AdjustEndianess32((LPBYTE) &Header.pcs);
   46.51         AdjustEndianess32((LPBYTE) &Header.magic);
   46.52         AdjustEndianess32((LPBYTE) &Header.flags);
   46.53 -           AdjustEndianess32((LPBYTE) &Header.attributes[0]);
   46.54 +       AdjustEndianess32((LPBYTE) &Header.attributes[0]);
   46.55         AdjustEndianess32((LPBYTE) &Header.renderingIntent);
   46.56  
   46.57         // Validate it
   46.58  
   46.59         if (Header.magic != icMagicNumber) goto ErrorCleanup;
   46.60  
   46.61 -
   46.62         if (Icc ->Read(&TagCount, sizeof(icInt32Number), 1, Icc) != 1)
   46.63                       goto ErrorCleanup;
   46.64  
   46.65 @@ -324,7 +327,7 @@
   46.66         Icc -> PCS             = Header.pcs;
   46.67         Icc -> RenderingIntent = (icRenderingIntent) Header.renderingIntent;
   46.68         Icc -> flags           = Header.flags;
   46.69 -           Icc -> attributes      = Header.attributes[0];
   46.70 +       Icc -> attributes      = Header.attributes[0];
   46.71         Icc -> Illuminant.X    = Convert15Fixed16(Header.illuminant.X);
   46.72         Icc -> Illuminant.Y    = Convert15Fixed16(Header.illuminant.Y);
   46.73         Icc -> Illuminant.Z    = Convert15Fixed16(Header.illuminant.Z);
   46.74 @@ -348,7 +351,7 @@
   46.75  
   46.76         // Read tag directory
   46.77  
   46.78 -       if (TagCount > MAX_TABLE_TAG) {
   46.79 +       if (TagCount > MAX_TABLE_TAG || TagCount < 0) {
   46.80  
   46.81             cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", TagCount);
   46.82             goto ErrorCleanup;
   46.83 @@ -357,12 +360,18 @@
   46.84         Icc -> TagCount = TagCount;
   46.85         for (i=0; i < TagCount; i++) {
   46.86  
   46.87 -              Icc ->Read(&Tag, sizeof(icTag), 1, Icc);
   46.88 +              if (Icc ->Read(&Tag, sizeof(icTag), 1, Icc) != 1)
   46.89 +                  goto ErrorCleanup;
   46.90  
   46.91                AdjustEndianess32((LPBYTE) &Tag.offset);
   46.92                AdjustEndianess32((LPBYTE) &Tag.size);
   46.93                AdjustEndianess32((LPBYTE) &Tag.sig);            // Signature
   46.94  
   46.95 +              // Perform some sanity check. Offset + size should fall inside file.
   46.96 +              extent = Tag.offset + Tag.size;
   46.97 +              if (extent > Header.size || extent < Tag.offset)
   46.98 +                  goto ErrorCleanup;
   46.99 +
  46.100                Icc -> TagNames[i]   = Tag.sig;
  46.101                Icc -> TagOffsets[i] = Tag.offset;
  46.102                Icc -> TagSizes[i]   = Tag.size;
  46.103 @@ -381,13 +390,10 @@
  46.104               cmsSignalError(LCMS_ERRC_ABORTED, "Corrupted profile: '%s'", Icc->PhysicalFile);
  46.105  
  46.106  
  46.107 -       free(Icc);
  46.108 +        _cmsFree(Icc);
  46.109         return NULL;
  46.110  }
  46.111  
  46.112 -
  46.113 -
  46.114 -
  46.115  static
  46.116  unsigned int uipow(unsigned int a, unsigned int b) {
  46.117          unsigned int rv = 1;
  46.118 @@ -497,7 +503,7 @@
  46.119  // The infamous LUT 8
  46.120  
  46.121  static
  46.122 -void ReadLUT8(LPLCMSICCPROFILE Icc, LPLUT NewLUT, icTagSignature sig)
  46.123 +LCMSBOOL ReadLUT8(LPLCMSICCPROFILE Icc, LPLUT NewLUT, icTagSignature sig)
  46.124  {
  46.125      icLut8 LUT8;
  46.126      LPBYTE Temp;
  46.127 @@ -506,7 +512,7 @@
  46.128      unsigned int AllLinear;
  46.129      LPWORD PtrW;
  46.130  
  46.131 -       Icc ->Read(&LUT8, sizeof(icLut8) - SIZEOF_UINT8_ALIGNED, 1, Icc);
  46.132 +       if (Icc ->Read(&LUT8, sizeof(icLut8) - SIZEOF_UINT8_ALIGNED, 1, Icc) != 1) return FALSE;
  46.133  
  46.134         NewLUT -> wFlags        = LUT_HASTL1|LUT_HASTL2|LUT_HAS3DGRID;
  46.135         NewLUT -> cLutPoints    = LUT8.clutPoints;
  46.136 @@ -515,6 +521,10 @@
  46.137         NewLUT -> InputEntries  = 256;
  46.138         NewLUT -> OutputEntries = 256;
  46.139  
  46.140 +       // Do some checking
  46.141 +       if (!_cmsValidateLUT(NewLUT)) {
  46.142 +          return FALSE;
  46.143 +       }
  46.144  
  46.145         AdjustEndianess32((LPBYTE) &LUT8.e00);
  46.146         AdjustEndianess32((LPBYTE) &LUT8.e01);
  46.147 @@ -550,13 +560,24 @@
  46.148  
  46.149         // Copy input tables
  46.150  
  46.151 -       Temp = (LPBYTE) malloc(256);
  46.152 +       Temp = (LPBYTE) _cmsMalloc(256);
  46.153 +       if (Temp == NULL) return FALSE;
  46.154 +
  46.155         AllLinear = 0;
  46.156         for (i=0; i < NewLUT -> InputChan; i++) {
  46.157  
  46.158 -              PtrW = (LPWORD) malloc(sizeof(WORD) * 256);
  46.159 +              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * 256);
  46.160 +              if (PtrW == NULL) {
  46.161 +                   _cmsFree(Temp);
  46.162 +                  return FALSE;
  46.163 +                  }
  46.164 +
  46.165                NewLUT -> L1[i] = PtrW;
  46.166 -              Icc ->Read(Temp, 1, 256, Icc);
  46.167 +              if (Icc ->Read(Temp, 1, 256, Icc) != 256) {
  46.168 +                   _cmsFree(Temp);
  46.169 +                  return FALSE;
  46.170 +                  }
  46.171 +
  46.172                for (j=0; j < 256; j++)
  46.173                       PtrW[j] = TO16_TAB(Temp[j]);
  46.174                       AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries);
  46.175 @@ -569,7 +590,7 @@
  46.176                NewLUT -> wFlags &= ~LUT_HASTL1;
  46.177         }
  46.178  
  46.179 -       free(Temp);
  46.180 +        _cmsFree(Temp);
  46.181  
  46.182         // Copy 3D CLUT
  46.183  
  46.184 @@ -578,9 +599,20 @@
  46.185  
  46.186         if (nTabSize > 0) {
  46.187  
  46.188 -            PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize);
  46.189 -            Temp = (LPBYTE) malloc(nTabSize);
  46.190 -            Icc ->Read(Temp, 1, nTabSize, Icc);
  46.191 +            PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize);
  46.192 +            if (PtrW == NULL) return FALSE;
  46.193 +
  46.194 +            Temp = (LPBYTE) _cmsMalloc(nTabSize);
  46.195 +            if (Temp == NULL) {
  46.196 +                 _cmsFree(PtrW);
  46.197 +                return FALSE;
  46.198 +                }
  46.199 +
  46.200 +            if (Icc ->Read(Temp, 1, nTabSize, Icc) != nTabSize) {
  46.201 +                 _cmsFree(Temp);
  46.202 +                _cmsFree(PtrW);
  46.203 +                return FALSE;
  46.204 +                }
  46.205  
  46.206              NewLUT -> T = PtrW;
  46.207              NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD));
  46.208 @@ -589,25 +621,37 @@
  46.209  
  46.210                       *PtrW++ = TO16_TAB(Temp[i]);
  46.211              }
  46.212 -            free(Temp);
  46.213 +            _cmsFree(Temp);
  46.214         }
  46.215         else {
  46.216             NewLUT ->T = NULL;
  46.217             NewLUT ->Tsize = 0;
  46.218 -           NewLUT -> wFlags &= ~LUT_HAS3DGRID;
  46.219 +           NewLUT ->wFlags &= ~LUT_HAS3DGRID;
  46.220         }
  46.221  
  46.222  
  46.223 -
  46.224         // Copy output tables
  46.225  
  46.226 -       Temp = (LPBYTE) malloc(256);
  46.227 +       Temp = (LPBYTE) _cmsMalloc(256);
  46.228 +       if (Temp == NULL) {
  46.229 +           return FALSE;
  46.230 +           }
  46.231 +
  46.232         AllLinear = 0;
  46.233         for (i=0; i < NewLUT -> OutputChan; i++) {
  46.234  
  46.235 -              PtrW = (LPWORD) malloc(sizeof(WORD) * 256);
  46.236 +              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * 256);
  46.237 +              if (PtrW == NULL) {
  46.238 +                  _cmsFree(Temp);
  46.239 +                  return FALSE;
  46.240 +                  }
  46.241 +
  46.242                NewLUT -> L2[i] = PtrW;
  46.243 -              Icc ->Read(Temp, 1, 256, Icc);
  46.244 +              if (Icc ->Read(Temp, 1, 256, Icc) != 256) {
  46.245 +                  _cmsFree(Temp);
  46.246 +                  return FALSE;
  46.247 +                  }
  46.248 +
  46.249                for (j=0; j < 256; j++)
  46.250                       PtrW[j] = TO16_TAB(Temp[j]);
  46.251                       AllLinear += cmsIsLinear(NewLUT -> L2[i], 256);
  46.252 @@ -621,7 +665,7 @@
  46.253         }
  46.254  
  46.255  
  46.256 -       free(Temp);
  46.257 +       _cmsFree(Temp);
  46.258  
  46.259         cmsCalcL16Params(NewLUT -> InputEntries,  &NewLUT -> In16params);
  46.260         cmsCalcL16Params(NewLUT -> OutputEntries, &NewLUT -> Out16params);
  46.261 @@ -646,6 +690,15 @@
  46.262             // some profiles does claim to do that. Poor lcms will try
  46.263             // to detect such condition and fix up "on the fly".
  46.264  
  46.265 +           switch (sig) {
  46.266 +
  46.267 +            case icSigBToA0Tag:
  46.268 +            case icSigBToA1Tag:
  46.269 +            case icSigBToA2Tag:
  46.270 +            case icSigGamutTag:
  46.271 +            case icSigPreview0Tag:
  46.272 +            case icSigPreview1Tag:
  46.273 +            case icSigPreview2Tag:
  46.274             {
  46.275                 LPWORD WhiteLab, ExpectedWhite;
  46.276                 WORD WhiteFixed[MAXCHANNELS], WhiteUnfixed[MAXCHANNELS];
  46.277 @@ -685,9 +738,13 @@
  46.278                 }
  46.279  
  46.280             }
  46.281 -
  46.282 +           break;
  46.283 +
  46.284 +        default:;
  46.285 +        }
  46.286         }
  46.287  
  46.288 +       return TRUE;
  46.289  }
  46.290  
  46.291  
  46.292 @@ -696,7 +753,7 @@
  46.293  // Case LUT 16
  46.294  
  46.295  static
  46.296 -void ReadLUT16(LPLCMSICCPROFILE Icc, LPLUT NewLUT)
  46.297 +LCMSBOOL ReadLUT16(LPLCMSICCPROFILE Icc, LPLUT NewLUT)
  46.298  {
  46.299      icLut16 LUT16;
  46.300      size_t nTabSize;
  46.301 @@ -705,7 +762,8 @@
  46.302      LPWORD PtrW;
  46.303  
  46.304  
  46.305 -       Icc ->Read(&LUT16, sizeof(icLut16)- SIZEOF_UINT16_ALIGNED, 1, Icc);
  46.306 +       if (Icc ->Read(&LUT16, sizeof(icLut16)- SIZEOF_UINT16_ALIGNED, 1, Icc) != 1)
  46.307 +            return FALSE;
  46.308  
  46.309         NewLUT -> wFlags        = LUT_HASTL1 | LUT_HASTL2 | LUT_HAS3DGRID;
  46.310         NewLUT -> cLutPoints    = LUT16.clutPoints;
  46.311 @@ -718,6 +776,9 @@
  46.312         NewLUT -> InputEntries  = LUT16.inputEnt;
  46.313         NewLUT -> OutputEntries = LUT16.outputEnt;
  46.314  
  46.315 +       if (!_cmsValidateLUT(NewLUT)) {
  46.316 +         return FALSE;
  46.317 +       }
  46.318  
  46.319         // Matrix handling
  46.320  
  46.321 @@ -754,9 +815,14 @@
  46.322         AllLinear = 0;
  46.323         for (i=0; i < NewLUT -> InputChan; i++) {
  46.324  
  46.325 -              PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries);
  46.326 +              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> InputEntries);
  46.327 +              if (PtrW == NULL) return FALSE;
  46.328 +
  46.329                NewLUT -> L1[i] = PtrW;
  46.330 -              Icc ->Read(PtrW, sizeof(WORD), NewLUT -> InputEntries, Icc);
  46.331 +              if (Icc ->Read(PtrW, sizeof(WORD), NewLUT -> InputEntries, Icc) != NewLUT -> InputEntries) {
  46.332 +                  return FALSE;
  46.333 +                  }
  46.334 +
  46.335                AdjustEndianessArray16(PtrW, NewLUT -> InputEntries);
  46.336                AllLinear += cmsIsLinear(NewLUT -> L1[i], NewLUT -> InputEntries);
  46.337                }
  46.338 @@ -775,12 +841,17 @@
  46.339                                                  NewLUT->InputChan));
  46.340         if (nTabSize > 0) {
  46.341  
  46.342 -           PtrW = (LPWORD) malloc(sizeof(WORD) * nTabSize);
  46.343 +           PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize);
  46.344 +           if (PtrW == NULL)
  46.345 +               return FALSE;
  46.346  
  46.347             NewLUT -> T = PtrW;
  46.348             NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD));
  46.349  
  46.350 -           Icc -> Read(PtrW, sizeof(WORD), nTabSize, Icc);
  46.351 +           if (Icc -> Read(PtrW, sizeof(WORD), nTabSize, Icc) != nTabSize) {
  46.352 +               return FALSE;
  46.353 +           }
  46.354 +
  46.355             AdjustEndianessArray16(NewLUT -> T, nTabSize);
  46.356         }
  46.357         else {
  46.358 @@ -794,9 +865,16 @@
  46.359         AllLinear = 0;
  46.360         for (i=0; i < NewLUT -> OutputChan; i++) {
  46.361  
  46.362 -              PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries);
  46.363 +              PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> OutputEntries);
  46.364 +              if (PtrW == NULL) {
  46.365 +                  return FALSE;
  46.366 +                  }
  46.367 +
  46.368                NewLUT -> L2[i] = PtrW;
  46.369 -              Icc ->Read(PtrW, sizeof(WORD), NewLUT -> OutputEntries, Icc);
  46.370 +              if (Icc ->Read(PtrW, sizeof(WORD), NewLUT -> OutputEntries, Icc) != NewLUT -> OutputEntries) {
  46.371 +                  return FALSE;
  46.372 +                  }
  46.373 +
  46.374                AdjustEndianessArray16(PtrW, NewLUT -> OutputEntries);
  46.375                AllLinear += cmsIsLinear(NewLUT -> L2[i], NewLUT -> OutputEntries);
  46.376                }
  46.377 @@ -814,6 +892,8 @@
  46.378         cmsCalcCLUT16Params(NewLUT -> cLutPoints,  NewLUT -> InputChan,
  46.379                                                    NewLUT -> OutputChan,
  46.380                                                    &NewLUT -> CLut16params);
  46.381 +
  46.382 +       return TRUE;
  46.383  }
  46.384  
  46.385  
  46.386 @@ -830,17 +910,15 @@
  46.387  
  46.388  
  46.389         BaseType = ReadBase(Icc);
  46.390 -
  46.391         switch (BaseType) {
  46.392  
  46.393  
  46.394 -       case 0x9478ee00L:    // Monaco 2 profiler is BROKEN!
  46.395 +       case ((icTagTypeSignature) 0x9478ee00):    // Monaco 2 profiler is BROKEN!
  46.396         case icSigCurveType:
  46.397  
  46.398 -           Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
  46.399 +           if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL;
  46.400             AdjustEndianess32((LPBYTE) &Count);
  46.401  
  46.402 -
  46.403             switch (Count) {
  46.404  
  46.405             case 0:   // Linear.
  46.406 @@ -855,7 +933,7 @@
  46.407                      {
  46.408                       WORD SingleGammaFixed;
  46.409  
  46.410 -                     Icc ->Read(&SingleGammaFixed, sizeof(WORD), 1, Icc);
  46.411 +                     if (Icc ->Read(&SingleGammaFixed, sizeof(WORD), 1, Icc) != 1) return NULL;
  46.412                       AdjustEndianess16((LPBYTE) &SingleGammaFixed);
  46.413                       return cmsBuildGamma(4096, Convert8Fixed8(SingleGammaFixed));
  46.414                       }
  46.415 @@ -865,10 +943,9 @@
  46.416                       NewGamma = cmsAllocGamma(Count);
  46.417                       if (!NewGamma) return NULL;
  46.418  
  46.419 -                     Icc ->Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc);
  46.420 -
  46.421 +                     if (Icc ->Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc) != Count)
  46.422 +                         return NULL;
  46.423                       AdjustEndianessArray16(NewGamma -> GammaTable, Count);
  46.424 -
  46.425                       return NewGamma;
  46.426                      }
  46.427                }
  46.428 @@ -885,11 +962,11 @@
  46.429             icUInt16Number   Type;
  46.430             int i;
  46.431  
  46.432 -           Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc);
  46.433 -           Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc);
  46.434 +           if (Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
  46.435 +           if (Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
  46.436  
  46.437             AdjustEndianess16((LPBYTE) &Type);
  46.438 -           if (Type > 5) {
  46.439 +           if (Type > 4) {
  46.440  
  46.441                  cmsSignalError(LCMS_ERRC_ABORTED, "Unknown parametric curve type '%d' found.", Type);
  46.442                  return NULL;
  46.443 @@ -900,7 +977,7 @@
  46.444  
  46.445            for (i=0; i < n; i++) {
  46.446                  Num = 0;
  46.447 -                Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
  46.448 +                if (Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc) != 1) return NULL;
  46.449                  Params[i] = Convert15Fixed16(Num);
  46.450            }
  46.451  
  46.452 @@ -938,7 +1015,7 @@
  46.453         case 0x9478ee00L:    // Monaco 2 profiler is BROKEN!
  46.454         case icSigCurveType:
  46.455  
  46.456 -           Icc -> Read(&Count, sizeof(icUInt32Number), 1, Icc);
  46.457 +           if (Icc -> Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL;
  46.458             AdjustEndianess32((LPBYTE) &Count);
  46.459  
  46.460  
  46.461 @@ -948,6 +1025,7 @@
  46.462  
  46.463                       NewGamma = cmsAllocGamma(2);
  46.464                       if (!NewGamma) return NULL;
  46.465 +
  46.466                       NewGamma -> GammaTable[0] = 0;
  46.467                       NewGamma -> GammaTable[1] = 0xFFFF;
  46.468                       return NewGamma;
  46.469 @@ -955,7 +1033,7 @@
  46.470             case 1:  {
  46.471                       WORD SingleGammaFixed;
  46.472  
  46.473 -                     Icc -> Read(&SingleGammaFixed, sizeof(WORD), 1, Icc);
  46.474 +                     if (Icc -> Read(&SingleGammaFixed, sizeof(WORD), 1, Icc) != 1) return NULL;
  46.475                       AdjustEndianess16((LPBYTE) &SingleGammaFixed);
  46.476                       return cmsBuildGamma(4096, 1./Convert8Fixed8(SingleGammaFixed));
  46.477                       }
  46.478 @@ -965,7 +1043,8 @@
  46.479                       NewGamma = cmsAllocGamma(Count);
  46.480                       if (!NewGamma) return NULL;
  46.481  
  46.482 -                     Icc -> Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc);
  46.483 +                     if (Icc -> Read(NewGamma -> GammaTable, sizeof(WORD), Count, Icc) != Count)
  46.484 +                         return NULL;
  46.485  
  46.486                       AdjustEndianessArray16(NewGamma -> GammaTable, Count);
  46.487  
  46.488 @@ -992,11 +1071,11 @@
  46.489             int i;
  46.490  
  46.491  
  46.492 -           Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc);
  46.493 -           Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc);
  46.494 +           if (Icc -> Read(&Type, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
  46.495 +           if (Icc -> Read(&Reserved, sizeof(icUInt16Number), 1, Icc) != 1) return NULL;
  46.496  
  46.497             AdjustEndianess16((LPBYTE) &Type);
  46.498 -           if (Type > 5) {
  46.499 +           if (Type > 4) {
  46.500  
  46.501                  cmsSignalError(LCMS_ERRC_ABORTED, "Unknown parametric curve type '%d' found.", Type);
  46.502                  return NULL;
  46.503 @@ -1006,7 +1085,7 @@
  46.504            n = ParamsByType[Type];
  46.505  
  46.506            for (i=0; i < n; i++) {
  46.507 -                Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
  46.508 +                if (Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc) != 1) return NULL;
  46.509                  Params[i] = Convert15Fixed16(Num);
  46.510            }
  46.511  
  46.512 @@ -1028,7 +1107,7 @@
  46.513  // V4 stuff. Read matrix for LutAtoB and LutBtoA
  46.514  
  46.515  static
  46.516 -BOOL ReadMatrixOffset(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, DWORD dwFlags)
  46.517 +LCMSBOOL ReadMatrixOffset(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, DWORD dwFlags)
  46.518  {
  46.519  
  46.520      icS15Fixed16Number All[12];
  46.521 @@ -1038,7 +1117,8 @@
  46.522  
  46.523      if (Icc -> Seek(Icc, Offset)) return FALSE;
  46.524  
  46.525 -    Icc ->Read(All, sizeof(icS15Fixed16Number), 12, Icc);
  46.526 +    if (Icc ->Read(All, sizeof(icS15Fixed16Number), 12, Icc) != 12)
  46.527 +        return FALSE;
  46.528  
  46.529      for (i=0; i < 12;  i++)
  46.530                AdjustEndianess32((LPBYTE) &All[i]);
  46.531 @@ -1067,17 +1147,26 @@
  46.532  //  V4 stuff. Read CLUT part for LutAtoB and LutBtoA
  46.533  
  46.534  static
  46.535 -BOOL ReadCLUT(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT)
  46.536 +LCMSBOOL ReadCLUT(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT)
  46.537  {
  46.538 -
  46.539 +    unsigned int j;
  46.540      icCLutStruct CLUT;
  46.541  
  46.542      if (Icc -> Seek(Icc, Offset)) return FALSE;
  46.543 -    Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc);
  46.544 -
  46.545 -
  46.546 -    cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan,
  46.547 -                                               NewLUT ->OutputChan);
  46.548 +    if (Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc) != 1) return FALSE;
  46.549 +
  46.550 +
  46.551 +    for (j=1; j < NewLUT ->InputChan; j++) {
  46.552 +        if (CLUT.gridPoints[0] != CLUT.gridPoints[j]) {
  46.553 +            cmsSignalError(LCMS_ERRC_ABORTED, "CLUT with different granulatity is currently unsupported.");
  46.554 +            return FALSE;
  46.555 +        }
  46.556 +
  46.557 +
  46.558 +    }
  46.559 +
  46.560 +    if (cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan,
  46.561 +                                               NewLUT ->OutputChan) == NULL) return FALSE;
  46.562  
  46.563      // Precission can be 1 or 2 bytes
  46.564  
  46.565 @@ -1087,7 +1176,7 @@
  46.566          unsigned int i;
  46.567  
  46.568          for (i=0; i < NewLUT->Tsize / sizeof(WORD); i++) {
  46.569 -                Icc ->Read(&v, sizeof(BYTE), 1, Icc);
  46.570 +                if (Icc ->Read(&v, sizeof(BYTE), 1, Icc) != 1) return FALSE;
  46.571                  NewLUT->T[i] = TO16_TAB(v);
  46.572          }
  46.573  
  46.574 @@ -1095,10 +1184,10 @@
  46.575      else
  46.576          if (CLUT.prec == 2) {
  46.577  
  46.578 -         Icc ->Read(NewLUT ->T, sizeof(WORD),
  46.579 -                    NewLUT->Tsize / sizeof(WORD), Icc);
  46.580 -
  46.581 -        AdjustEndianessArray16(NewLUT ->T, NewLUT->Tsize / sizeof(WORD));
  46.582 +         size_t n = NewLUT->Tsize / sizeof(WORD);
  46.583 +
  46.584 +         if (Icc ->Read(NewLUT ->T, sizeof(WORD), n, Icc) != n) return FALSE;
  46.585 +         AdjustEndianessArray16(NewLUT ->T, NewLUT->Tsize / sizeof(WORD));
  46.586      }
  46.587      else {
  46.588          cmsSignalError(LCMS_ERRC_ABORTED, "Unknow precission of '%d'", CLUT.prec);
  46.589 @@ -1110,6 +1199,22 @@
  46.590  
  46.591  
  46.592  static
  46.593 +void ResampleCurves(LPGAMMATABLE Curves[], int nCurves)
  46.594 +{
  46.595 +    int i;
  46.596 +    LPSAMPLEDCURVE sc;
  46.597 +
  46.598 +    for (i=0; i < nCurves; i++) {
  46.599 +        sc = cmsConvertGammaToSampledCurve(Curves[i], 4096);
  46.600 +        cmsFreeGamma(Curves[i]);
  46.601 +        Curves[i] = cmsConvertSampledCurveToGamma(sc, 0xFFFF);
  46.602 +        cmsFreeSampledCurve(sc);
  46.603 +    }
  46.604 +
  46.605 +}
  46.606 +
  46.607 +
  46.608 +static
  46.609  void SkipAlignment(LPLCMSICCPROFILE Icc)
  46.610  {
  46.611      BYTE Buffer[4];
  46.612 @@ -1121,7 +1226,7 @@
  46.613  
  46.614  // Read a set of curves from specific offset
  46.615  static
  46.616 -BOOL ReadSetOfCurves(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, int nLocation)
  46.617 +LCMSBOOL ReadSetOfCurves(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT, int nLocation)
  46.618  {
  46.619      LPGAMMATABLE Curves[MAXCHANNELS];
  46.620      unsigned int i, nCurves;
  46.621 @@ -1134,20 +1239,41 @@
  46.622      else
  46.623          nCurves = NewLUT ->OutputChan;
  46.624  
  46.625 +    ZeroMemory(Curves, sizeof(Curves));
  46.626      for (i=0; i < nCurves; i++) {
  46.627  
  46.628          Curves[i] = ReadCurve(Icc);
  46.629 +        if (Curves[i] == NULL) goto Error;
  46.630          SkipAlignment(Icc);
  46.631 -
  46.632      }
  46.633  
  46.634 +    // March-26'08: some V4 profiles may have different sampling
  46.635 +    // rates, in this case resample all curves to maximum
  46.636 +
  46.637 +    for (i=1; i < nCurves; i++) {
  46.638 +        if (Curves[i]->nEntries != Curves[0]->nEntries) {
  46.639 +            ResampleCurves(Curves, nCurves);
  46.640 +        break;
  46.641 +        }
  46.642 +    }
  46.643 +
  46.644      NewLUT = cmsAllocLinearTable(NewLUT, Curves, nLocation);
  46.645 +    if (NewLUT == NULL) goto Error;
  46.646  
  46.647      for (i=0; i < nCurves; i++)
  46.648          cmsFreeGamma(Curves[i]);
  46.649  
  46.650      return TRUE;
  46.651  
  46.652 +Error:
  46.653 +
  46.654 +    for (i=0; i < nCurves; i++)
  46.655 +        if (Curves[i])
  46.656 +            cmsFreeGamma(Curves[i]);
  46.657 +
  46.658 +    return FALSE;
  46.659 +
  46.660 +
  46.661  }
  46.662  
  46.663  // V4 stuff. LutAtoB type
  46.664 @@ -1160,22 +1286,28 @@
  46.665  //   L2 = B curves
  46.666  
  46.667  static
  46.668 -BOOL ReadLUT_A2B(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig)
  46.669 +LCMSBOOL ReadLUT_A2B(LPLCMSICCPROFILE Icc, LPLUT NewLUT, size_t BaseOffset, icTagSignature sig)
  46.670  {
  46.671      icLutAtoB LUT16;
  46.672  
  46.673 -       Icc ->Read(&LUT16, sizeof(icLutAtoB), 1, Icc);
  46.674 +       if (Icc ->Read(&LUT16, sizeof(icLutAtoB), 1, Icc) != 1) return FALSE;
  46.675  
  46.676         NewLUT -> InputChan     = LUT16.inputChan;
  46.677         NewLUT -> OutputChan    = LUT16.outputChan;
  46.678  
  46.679 +       // Validate the NewLUT here to avoid excessive number of channels
  46.680 +       // (leading to stack-based buffer overflow in ReadSetOfCurves).
  46.681 +       // Needs revalidation after table size is filled in.
  46.682 +       if (!_cmsValidateLUT(NewLUT)) {
  46.683 +           return FALSE;
  46.684 +       }
  46.685 +
  46.686         AdjustEndianess32((LPBYTE) &LUT16.offsetB);
  46.687         AdjustEndianess32((LPBYTE) &LUT16.offsetMat);
  46.688         AdjustEndianess32((LPBYTE) &LUT16.offsetM);
  46.689         AdjustEndianess32((LPBYTE) &LUT16.offsetC);
  46.690         AdjustEndianess32((LPBYTE) &LUT16.offsetA);
  46.691  
  46.692 -
  46.693         if (LUT16.offsetB != 0)
  46.694                  ReadSetOfCurves(Icc, BaseOffset + LUT16.offsetB, NewLUT, 2);
  46.695  
  46.696 @@ -1220,15 +1352,22 @@
  46.697  // V4 stuff. LutBtoA type
  46.698  
  46.699  static
  46.700 -BOOL ReadLUT_B2A(LPLCMSICCPROFILE Icc, LPLUT NewLUT,  size_t BaseOffset, icTagSignature sig)
  46.701 +LCMSBOOL ReadLUT_B2A(LPLCMSICCPROFILE Icc, LPLUT NewLUT,  size_t BaseOffset, icTagSignature sig)
  46.702  {
  46.703    icLutBtoA LUT16;
  46.704  
  46.705 -       Icc ->Read(&LUT16, sizeof(icLutBtoA), 1, Icc);
  46.706 +       if (Icc ->Read(&LUT16, sizeof(icLutBtoA), 1, Icc) != 1) return FALSE;
  46.707  
  46.708         NewLUT -> InputChan     = LUT16.inputChan;
  46.709         NewLUT -> OutputChan    = LUT16.outputChan;
  46.710  
  46.711 +       // Validate the NewLUT here to avoid excessive number of channels
  46.712 +       // (leading to stack-based buffer overflow in ReadSetOfCurves).
  46.713 +       // Needs revalidation after table size is filled in.
  46.714 +       if (!_cmsValidateLUT(NewLUT)) {
  46.715 +           return FALSE;
  46.716 +       }
  46.717 +
  46.718         AdjustEndianess32((LPBYTE) &LUT16.offsetB);
  46.719         AdjustEndianess32((LPBYTE) &LUT16.offsetMat);
  46.720         AdjustEndianess32((LPBYTE) &LUT16.offsetM);
  46.721 @@ -1242,7 +1381,6 @@
  46.722         if (LUT16.offsetMat != 0)
  46.723              ReadMatrixOffset(Icc, BaseOffset + LUT16.offsetMat, NewLUT, LUT_HASMATRIX3);
  46.724  
  46.725 -
  46.726         if (LUT16.offsetM != 0)
  46.727                  ReadSetOfCurves(Icc, BaseOffset + LUT16.offsetM, NewLUT, 3);
  46.728  
  46.729 @@ -1294,7 +1432,7 @@
  46.730  
  46.731  
  46.732      // If is in memory, the LUT is already there, so throw a copy
  46.733 -    if (!Icc -> stream) {
  46.734 +    if (Icc -> TagPtrs[n]) {
  46.735  
  46.736          return cmsDupLUT((LPLUT) Icc ->TagPtrs[n]);
  46.737      }
  46.738 @@ -1308,8 +1446,8 @@
  46.739  
  46.740  
  46.741      NewLUT = cmsAllocLUT();
  46.742 -    if (!NewLUT)
  46.743 -    {
  46.744 +    if (!NewLUT) {
  46.745 +
  46.746         cmsSignalError(LCMS_ERRC_ABORTED, "cmsAllocLUT() failed");
  46.747         return NULL;
  46.748      }
  46.749 @@ -1317,11 +1455,29 @@
  46.750  
  46.751      switch (BaseType) {
  46.752  
  46.753 -    case icSigLut8Type:    ReadLUT8(Icc, NewLUT, sig); break;
  46.754 -    case icSigLut16Type:   ReadLUT16(Icc, NewLUT);     break;
  46.755 -
  46.756 -    case icSiglutAtoBType: ReadLUT_A2B(Icc, NewLUT, offset, sig); break;
  46.757 -    case icSiglutBtoAType: ReadLUT_B2A(Icc, NewLUT, offset, sig); break;
  46.758 +    case icSigLut8Type:    if (!ReadLUT8(Icc, NewLUT, sig)) {
  46.759 +                                cmsFreeLUT(NewLUT);
  46.760 +                                return NULL;
  46.761 +                           }
  46.762 +                           break;
  46.763 +
  46.764 +    case icSigLut16Type:   if (!ReadLUT16(Icc, NewLUT)) {
  46.765 +                                cmsFreeLUT(NewLUT);
  46.766 +                                return NULL;
  46.767 +                           }
  46.768 +                           break;
  46.769 +
  46.770 +    case icSiglutAtoBType: if (!ReadLUT_A2B(Icc, NewLUT, offset, sig)) {
  46.771 +                                cmsFreeLUT(NewLUT);
  46.772 +                                return NULL;
  46.773 +                           }
  46.774 +                           break;
  46.775 +
  46.776 +    case icSiglutBtoAType: if (!ReadLUT_B2A(Icc, NewLUT, offset, sig)) {
  46.777 +                                cmsFreeLUT(NewLUT);
  46.778 +                                return NULL;
  46.779 +                           }
  46.780 +                           break;
  46.781  
  46.782      default:  cmsSignalError(LCMS_ERRC_ABORTED, "Bad tag signature %lx found.", BaseType);
  46.783                cmsFreeLUT(NewLUT);
  46.784 @@ -1335,16 +1491,23 @@
  46.785  
  46.786  // Sets the language & country preferences. Used only in ICC 4.0 profiles
  46.787  
  46.788 -void LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode)
  46.789 +void LCMSEXPORT cmsSetLanguage(const char LanguageCode[4], const char CountryCode[4])
  46.790  {
  46.791 -    GlobalLanguageCode = LanguageCode;
  46.792 -    GlobalCountryCode  = CountryCode;
  46.793 +
  46.794 +    int LanguageCodeInt = *(int *) LanguageCode;
  46.795 +    int CountryCodeInt  = *(int *) CountryCode;
  46.796 +
  46.797 +    AdjustEndianess32((LPBYTE) &LanguageCodeInt);
  46.798 +    AdjustEndianess32((LPBYTE) &CountryCodeInt);
  46.799 +
  46.800 +    GlobalLanguageCode = LanguageCodeInt;
  46.801 +    GlobalCountryCode  = CountryCodeInt;
  46.802  }
  46.803  
  46.804  
  46.805  
  46.806  // Some tags (e.g, 'pseq') can have text tags embedded. This function
  46.807 -// handles such special case.
  46.808 +// handles such special case. Returns -1 on error, or the number of bytes left on success.
  46.809  
  46.810  static
  46.811  int ReadEmbeddedTextTag(LPLCMSICCPROFILE Icc, size_t size, char* Name, size_t size_max)
  46.812 @@ -1353,7 +1516,6 @@
  46.813  
  46.814  
  46.815      BaseType = ReadBase(Icc);
  46.816 -
  46.817      size -= sizeof(icTagBase);
  46.818  
  46.819      switch (BaseType) {
  46.820 @@ -1365,50 +1527,54 @@
  46.821             icUInt16Number  ScriptCodeCode, Dummy;
  46.822             icUInt8Number   ScriptCodeCount;
  46.823  
  46.824 -           Icc ->Read(&AsciiCount, sizeof(icUInt32Number), 1, Icc);
  46.825 -
  46.826 -                   if (size < sizeof(icUInt32Number)) return (int) size;
  46.827 +           if (Icc ->Read(&AsciiCount, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
  46.828 +
  46.829 +           if (size < sizeof(icUInt32Number)) return (int) size;
  46.830             size -= sizeof(icUInt32Number);
  46.831  
  46.832             AdjustEndianess32((LPBYTE) &AsciiCount);
  46.833             Icc ->Read(Name, 1,
  46.834                  (AsciiCount >= size_max) ? (size_max-1) : AsciiCount, Icc);
  46.835  
  46.836 -                   if (size < AsciiCount) return (int) size;
  46.837 +           if (size < AsciiCount) return (int) size;
  46.838             size -= AsciiCount;
  46.839  
  46.840             // Skip Unicode code
  46.841  
  46.842 -           Icc ->Read(&UnicodeCode,  sizeof(icUInt32Number), 1, Icc);
  46.843 -                   if (size < sizeof(icUInt32Number)) return (int) size;
  46.844 +           if (Icc ->Read(&UnicodeCode,  sizeof(icUInt32Number), 1, Icc) != 1) return -1;
  46.845 +           if (size < sizeof(icUInt32Number)) return (int) size;
  46.846             size -= sizeof(icUInt32Number);
  46.847  
  46.848 -           Icc ->Read(&UnicodeCount, sizeof(icUInt32Number), 1, Icc);
  46.849 -                   if (size < sizeof(icUInt32Number)) return (int) size;
  46.850 +           if (Icc ->Read(&UnicodeCount, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
  46.851 +           if (size < sizeof(icUInt32Number)) return (int) size;
  46.852             size -= sizeof(icUInt32Number);
  46.853  
  46.854             AdjustEndianess32((LPBYTE) &UnicodeCount);
  46.855  
  46.856             if (UnicodeCount > size) return (int) size;
  46.857  
  46.858 -           for (i=0; i < UnicodeCount; i++)
  46.859 -                Icc ->Read(&Dummy, sizeof(icUInt16Number), 1, Icc);
  46.860 -
  46.861 -           size -= UnicodeCount * sizeof(icUInt16Number);
  46.862 +           for (i=0; i < UnicodeCount; i++) {
  46.863 +                size_t nread = Icc ->Read(&Dummy, sizeof(icUInt16Number), 1, Icc);
  46.864 +                if (nread != 1) return (int) size;
  46.865 +                size -= sizeof(icUInt16Number);
  46.866 +           }
  46.867  
  46.868            // Skip ScriptCode code
  46.869  
  46.870 -           Icc ->Read(&ScriptCodeCode,  sizeof(icUInt16Number), 1, Icc);
  46.871 +           if (Icc ->Read(&ScriptCodeCode,  sizeof(icUInt16Number), 1, Icc) != 1) return -1;
  46.872             size -= sizeof(icUInt16Number);
  46.873 -           Icc ->Read(&ScriptCodeCount, sizeof(icUInt8Number), 1, Icc);
  46.874 +           if (Icc ->Read(&ScriptCodeCount, sizeof(icUInt8Number), 1, Icc) != 1) return -1;
  46.875             size -= sizeof(icUInt8Number);
  46.876  
  46.877 +           // Should remain 67 bytes as filler
  46.878 +
  46.879             if (size < 67) return (int) size;
  46.880  
  46.881 -           for (i=0; i < 67; i++)
  46.882 -                Icc ->Read(&Dummy, sizeof(icUInt8Number), 1, Icc);
  46.883 -
  46.884 -           size -= 67;
  46.885 +           for (i=0; i < 67; i++) {
  46.886 +                size_t nread = Icc ->Read(&Dummy, sizeof(icUInt8Number), 1, Icc);
  46.887 +                if (nread != 1) return (int) size;
  46.888 +                size --;
  46.889 +               }
  46.890             }
  46.891             break;
  46.892  
  46.893 @@ -1425,7 +1591,7 @@
  46.894               size = size_max - 1;
  46.895           }
  46.896  
  46.897 -         Icc -> Read(Name, 1, size, Icc);
  46.898 +         if (Icc -> Read(Name, 1, size, Icc) != size) return -1;
  46.899  
  46.900           for (i=0; i < Missing; i++)
  46.901               Icc -> Read(&Dummy, 1, 1, Icc);
  46.902 @@ -1445,9 +1611,9 @@
  46.903          wchar_t*       wchar  = L"";
  46.904  
  46.905  
  46.906 -            Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
  46.907 +            if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
  46.908              AdjustEndianess32((LPBYTE) &Count);
  46.909 -            Icc ->Read(&RecLen, sizeof(icUInt32Number), 1, Icc);
  46.910 +            if (Icc ->Read(&RecLen, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
  46.911              AdjustEndianess32((LPBYTE) &RecLen);
  46.912  
  46.913              if (RecLen != 12) {
  46.914 @@ -1458,15 +1624,15 @@
  46.915  
  46.916              for (i=0; i < Count; i++) {
  46.917  
  46.918 -                Icc ->Read(&Language, sizeof(icUInt16Number), 1, Icc);
  46.919 +                if (Icc ->Read(&Language, sizeof(icUInt16Number), 1, Icc) != 1) return -1;
  46.920                  AdjustEndianess16((LPBYTE) &Language);
  46.921 -                Icc ->Read(&Country, sizeof(icUInt16Number), 1, Icc);
  46.922 +                if (Icc ->Read(&Country, sizeof(icUInt16Number), 1, Icc) != 1) return -1;
  46.923                  AdjustEndianess16((LPBYTE) &Country);
  46.924  
  46.925 -                Icc ->Read(&ThisLen, sizeof(icUInt32Number), 1, Icc);
  46.926 +                if (Icc ->Read(&ThisLen, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
  46.927                  AdjustEndianess32((LPBYTE) &ThisLen);
  46.928  
  46.929 -                Icc ->Read(&ThisOffset, sizeof(icUInt32Number), 1, Icc);
  46.930 +                if (Icc ->Read(&ThisOffset, sizeof(icUInt32Number), 1, Icc) != 1) return -1;
  46.931                  AdjustEndianess32((LPBYTE) &ThisOffset);
  46.932  
  46.933                  if (Language == GlobalLanguageCode || Offset == 0) {
  46.934 @@ -1492,14 +1658,18 @@
  46.935              for (i=0; i < Offset; i++) {
  46.936  
  46.937                      char Discard;
  46.938 -
  46.939 -                    Icc ->Read(&Discard, 1, 1, Icc);
  46.940 +                    if (Icc ->Read(&Discard, 1, 1, Icc) != 1) return -1;
  46.941              }
  46.942  
  46.943 -            wchar = (wchar_t*) malloc(Len+2);
  46.944 +
  46.945 +            // Bound len
  46.946 +            if (Len < 0) Len = 0;
  46.947 +            if (Len > 20*1024) Len = 20 * 1024;
  46.948 +
  46.949 +            wchar = (wchar_t*) _cmsMalloc(Len*sizeof(wchar_t)+2);
  46.950              if (!wchar) return -1;
  46.951  
  46.952 -            Icc ->Read(wchar, 1, Len, Icc);
  46.953 +            if (Icc ->Read(wchar, 1, Len, Icc) != Len) return -1;
  46.954              AdjustEndianessArray16((LPWORD) wchar, Len / 2);
  46.955  
  46.956              wchar[Len / 2] = L'\0';
  46.957 @@ -1509,7 +1679,7 @@
  46.958                  Name[0] = 0;    // Error
  46.959              }
  46.960  
  46.961 -            free((void*) wchar);
  46.962 +            _cmsFree((void*) wchar);
  46.963              }
  46.964              break;
  46.965  
  46.966 @@ -1522,8 +1692,7 @@
  46.967  }
  46.968  
  46.969  
  46.970 -// Take an ASCII item. Takes at most LCMS_DESC_MAX
  46.971 -
  46.972 +// Take an ASCII item. Takes at most size_max bytes
  46.973  
  46.974  int LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Name, size_t size_max)
  46.975  {
  46.976 @@ -1535,19 +1704,27 @@
  46.977      if (n < 0)
  46.978          return -1;
  46.979  
  46.980 -    if (!Icc -> stream) {
  46.981 -
  46.982 -        CopyMemory(Name, Icc -> TagPtrs[n], Icc -> TagSizes[n]);
  46.983 +     size   = Icc -> TagSizes[n];
  46.984 +
  46.985 +    if (Icc -> TagPtrs[n]) {
  46.986 +
  46.987 +        if (size > size_max)
  46.988 +            size = size_max;
  46.989 +
  46.990 +        CopyMemory(Name, Icc -> TagPtrs[n], size);
  46.991 +
  46.992          return (int) Icc -> TagSizes[n];
  46.993      }
  46.994  
  46.995      offset = Icc -> TagOffsets[n];
  46.996 -    size   = Icc -> TagSizes[n];
  46.997 +
  46.998  
  46.999      if (Icc -> Seek(Icc, offset))
 46.1000              return -1;
 46.1001  
 46.1002 -    return ReadEmbeddedTextTag(Icc, size, Name, size_max);
 46.1003 +    if (ReadEmbeddedTextTag(Icc, size, Name, size_max) < 0) return -1;
 46.1004 +
 46.1005 +        return size;
 46.1006  }
 46.1007  
 46.1008  // Keep compatibility with older versions
 46.1009 @@ -1561,7 +1738,7 @@
 46.1010  // Take an XYZ item
 46.1011  
 46.1012  static
 46.1013 -int ReadICCXYZ(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIEXYZ Value, BOOL lIsFatal)
 46.1014 +int ReadICCXYZ(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIEXYZ Value, LCMSBOOL lIsFatal)
 46.1015  {
 46.1016      LPLCMSICCPROFILE    Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.1017      icTagTypeSignature  BaseType;
 46.1018 @@ -1573,7 +1750,7 @@
 46.1019      if (n < 0)
 46.1020              return -1;
 46.1021  
 46.1022 -    if (!Icc -> stream) {
 46.1023 +    if (Icc -> TagPtrs[n]) {
 46.1024  
 46.1025           CopyMemory(Value, Icc -> TagPtrs[n], Icc -> TagSizes[n]);
 46.1026           return (int) Icc -> TagSizes[n];
 46.1027 @@ -1628,7 +1805,7 @@
 46.1028      if (n < 0)
 46.1029              return -1; // Not found
 46.1030  
 46.1031 -    if (!Icc -> stream) {
 46.1032 +    if (Icc -> TagPtrs[n]) {
 46.1033  
 46.1034              CopyMemory(v, Icc -> TagPtrs[n], Icc -> TagSizes[n]);
 46.1035              return (int) Icc -> TagSizes[n];
 46.1036 @@ -1677,7 +1854,7 @@
 46.1037  
 46.1038  // Primaries are to be in xyY notation
 46.1039  
 46.1040 -BOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile)
 46.1041 +LCMSBOOL LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile)
 46.1042  {
 46.1043         if (ReadICCXYZ(hProfile, icSigRedColorantTag, &Dest -> Red, TRUE) < 0) return FALSE;
 46.1044         if (ReadICCXYZ(hProfile, icSigGreenColorantTag, &Dest -> Green, TRUE) < 0) return FALSE;
 46.1045 @@ -1687,7 +1864,7 @@
 46.1046  }
 46.1047  
 46.1048  
 46.1049 -BOOL cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile)
 46.1050 +LCMSBOOL cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile)
 46.1051  {
 46.1052         cmsCIEXYZTRIPLE Primaries;
 46.1053  
 46.1054 @@ -1704,7 +1881,7 @@
 46.1055  
 46.1056  // Always return a suitable matrix
 46.1057  
 46.1058 -BOOL cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile)
 46.1059 +LCMSBOOL cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile)
 46.1060  {
 46.1061  
 46.1062      if (ReadICCXYZArray(hProfile, icSigChromaticAdaptationTag, r) < 0) {
 46.1063 @@ -1741,7 +1918,7 @@
 46.1064         if (n < 0)
 46.1065             return NULL;
 46.1066  
 46.1067 -       if (!Icc -> stream) {
 46.1068 +       if (Icc -> TagPtrs[n]) {
 46.1069  
 46.1070              return cmsDupGamma((LPGAMMATABLE) Icc -> TagPtrs[n]);
 46.1071         }
 46.1072 @@ -1769,7 +1946,7 @@
 46.1073         if (n < 0)
 46.1074              return NULL;
 46.1075  
 46.1076 -       if (!Icc -> stream) {
 46.1077 +       if (Icc -> TagPtrs[n]) {
 46.1078  
 46.1079              return cmsReverseGamma(256, (LPGAMMATABLE) Icc -> TagPtrs[n]);
 46.1080         }
 46.1081 @@ -1785,7 +1962,7 @@
 46.1082  // Check Named color header
 46.1083  
 46.1084  static
 46.1085 -BOOL CheckHeader(LPcmsNAMEDCOLORLIST v, icNamedColor2* nc2)
 46.1086 +LCMSBOOL CheckHeader(LPcmsNAMEDCOLORLIST v, icNamedColor2* nc2)
 46.1087  {
 46.1088      if (v ->Prefix[0] == 0 && v ->Suffix[0] == 0 && v ->ColorantCount == 0) return TRUE;
 46.1089  
 46.1090 @@ -1809,13 +1986,13 @@
 46.1091         if (n < 0)
 46.1092              return 0;
 46.1093  
 46.1094 -       if (!Icc -> stream) {
 46.1095 +       if (Icc -> TagPtrs[n]) {
 46.1096  
 46.1097              // This replaces actual named color list.
 46.1098              size_t size   = Icc -> TagSizes[n];
 46.1099  
 46.1100              if (v ->NamedColorList) cmsFreeNamedColorList(v ->NamedColorList);
 46.1101 -            v -> NamedColorList = (LPcmsNAMEDCOLORLIST) malloc(size);
 46.1102 +            v -> NamedColorList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
 46.1103              CopyMemory(v -> NamedColorList, Icc ->TagPtrs[n], size);
 46.1104              return v ->NamedColorList->nColors;
 46.1105         }
 46.1106 @@ -1844,7 +2021,7 @@
 46.1107                  icNamedColor2 nc2;
 46.1108                  unsigned int i, j;
 46.1109  
 46.1110 -                Icc -> Read(&nc2, sizeof(icNamedColor2) - SIZEOF_UINT8_ALIGNED, 1, Icc);
 46.1111 +                if (Icc -> Read(&nc2, sizeof(icNamedColor2) - SIZEOF_UINT8_ALIGNED, 1, Icc) != 1) return 0;
 46.1112                  AdjustEndianess32((LPBYTE) &nc2.vendorFlag);
 46.1113                  AdjustEndianess32((LPBYTE) &nc2.count);
 46.1114                  AdjustEndianess32((LPBYTE) &nc2.nDeviceCoords);
 46.1115 @@ -1854,6 +2031,11 @@
 46.1116                       return 0;
 46.1117                  }
 46.1118  
 46.1119 +                if (nc2.nDeviceCoords > MAXCHANNELS) {
 46.1120 +                          cmsSignalError(LCMS_ERRC_WARNING, "Too many device coordinates.");
 46.1121 +                          return 0;
 46.1122 +                }
 46.1123 +
 46.1124                  strncpy(v ->NamedColorList->Prefix, (const char*) nc2.prefix, 32);
 46.1125                  strncpy(v ->NamedColorList->Suffix, (const char*) nc2.suffix, 32);
 46.1126                  v ->NamedColorList->Prefix[32] = v->NamedColorList->Suffix[32] = 0;
 46.1127 @@ -1900,7 +2082,8 @@
 46.1128  
 46.1129  LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile, icTagSignature sig)
 46.1130  {
 46.1131 -    icInt32Number n, Count, i;
 46.1132 +    icInt32Number n;
 46.1133 +    icUInt32Number Count, i;
 46.1134      size_t offset;
 46.1135      icTagTypeSignature  BaseType;
 46.1136      LPLCMSICCPROFILE   Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.1137 @@ -1910,10 +2093,12 @@
 46.1138      if (n < 0)
 46.1139              return NULL; // Not found
 46.1140  
 46.1141 -    if (!Icc -> stream) {
 46.1142 +    if (Icc -> TagPtrs[n]) {
 46.1143  
 46.1144              size_t size   = Icc -> TagSizes[n];
 46.1145 -            void* v = malloc(size);
 46.1146 +            void* v = _cmsMalloc(size);
 46.1147 +
 46.1148 +            if (v == NULL) return NULL;
 46.1149              CopyMemory(v, Icc -> TagPtrs[n], size);
 46.1150              return (LPcmsNAMEDCOLORLIST) v;
 46.1151      }
 46.1152 @@ -1932,13 +2117,17 @@
 46.1153      }
 46.1154  
 46.1155  
 46.1156 -    Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
 46.1157 +    if (Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc) != 1) return NULL;
 46.1158      AdjustEndianess32((LPBYTE) &Count);
 46.1159  
 46.1160 +    if (Count > MAXCHANNELS) {
 46.1161 +        cmsSignalError(LCMS_ERRC_ABORTED, "Too many colorants '%lx'", Count);
 46.1162 +        return NULL;
 46.1163 +    }
 46.1164 +
 46.1165      List = cmsAllocNamedColorList(Count);
 46.1166      for (i=0; i < Count; i++) {
 46.1167  
 46.1168 -
 46.1169          if (!Icc ->Read(List->List[i].Name, 1, 32 , Icc)) goto Error;
 46.1170          if (!Icc ->Read(List->List[i].PCS, sizeof(icUInt16Number), 3, Icc)) goto Error;
 46.1171          AdjustEndianessArray16(List->List[i].PCS, 3);
 46.1172 @@ -1965,7 +2154,7 @@
 46.1173  
 46.1174         if (cmsIsTag(hProfile, icSigDeviceMfgDescTag)) {
 46.1175  
 46.1176 -            cmsReadICCText(hProfile, icSigDeviceMfgDescTag, Manufacturer);
 46.1177 +            cmsReadICCTextEx(hProfile, icSigDeviceMfgDescTag, Manufacturer, LCMS_DESC_MAX);
 46.1178         }
 46.1179  
 46.1180      return Manufacturer;
 46.1181 @@ -1982,7 +2171,7 @@
 46.1182  
 46.1183         if (cmsIsTag(hProfile, icSigDeviceModelDescTag)) {
 46.1184  
 46.1185 -            cmsReadICCText(hProfile, icSigDeviceModelDescTag, Model);
 46.1186 +            cmsReadICCTextEx(hProfile, icSigDeviceModelDescTag, Model, LCMS_DESC_MAX);
 46.1187         }
 46.1188  
 46.1189      return Model;
 46.1190 @@ -1995,10 +2184,9 @@
 46.1191      static char Copyright[LCMS_DESC_MAX] = "";
 46.1192  
 46.1193         Copyright[0] = 0;
 46.1194 -
 46.1195         if (cmsIsTag(hProfile, icSigCopyrightTag)) {
 46.1196  
 46.1197 -            cmsReadICCText(hProfile, icSigCopyrightTag, Copyright);
 46.1198 +            cmsReadICCTextEx(hProfile, icSigCopyrightTag, Copyright, LCMS_DESC_MAX);
 46.1199         }
 46.1200  
 46.1201      return Copyright;
 46.1202 @@ -2009,7 +2197,7 @@
 46.1203  
 46.1204  const char*  LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile)
 46.1205  {
 46.1206 -    static char Name[2048];
 46.1207 +    static char Name[LCMS_DESC_MAX*2+4];
 46.1208      char Manufacturer[LCMS_DESC_MAX], Model[LCMS_DESC_MAX];
 46.1209  
 46.1210      Name[0] = '\0';
 46.1211 @@ -2017,19 +2205,19 @@
 46.1212  
 46.1213      if (cmsIsTag(hProfile, icSigDeviceMfgDescTag)) {
 46.1214  
 46.1215 -        cmsReadICCText(hProfile, icSigDeviceMfgDescTag, Manufacturer);
 46.1216 +        cmsReadICCTextEx(hProfile, icSigDeviceMfgDescTag, Manufacturer, LCMS_DESC_MAX);
 46.1217      }
 46.1218  
 46.1219      if (cmsIsTag(hProfile, icSigDeviceModelDescTag)) {
 46.1220  
 46.1221 -        cmsReadICCText(hProfile, icSigDeviceModelDescTag, Model);
 46.1222 +        cmsReadICCTextEx(hProfile, icSigDeviceModelDescTag, Model, LCMS_DESC_MAX);
 46.1223      }
 46.1224  
 46.1225      if (!Manufacturer[0] && !Model[0]) {
 46.1226  
 46.1227          if (cmsIsTag(hProfile, icSigProfileDescriptionTag)) {
 46.1228  
 46.1229 -            cmsReadICCText(hProfile, icSigProfileDescriptionTag, Name);
 46.1230 +            cmsReadICCTextEx(hProfile, icSigProfileDescriptionTag, Name, LCMS_DESC_MAX);
 46.1231              return Name;
 46.1232          }
 46.1233          else return "{no name}";
 46.1234 @@ -2129,7 +2317,7 @@
 46.1235  
 46.1236  // Extract the target data as a big string. Does not signal if tag is not present.
 46.1237  
 46.1238 -BOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len)
 46.1239 +LCMSBOOL LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len)
 46.1240  {
 46.1241      LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.1242      int n;
 46.1243 @@ -2142,7 +2330,11 @@
 46.1244  
 46.1245  
 46.1246      *len =  Icc -> TagSizes[n];
 46.1247 -    *Data = (char*) malloc(*len + 1);  // Plus zero marker
 46.1248 +
 46.1249 +    // Make sure that is reasonable (600K)
 46.1250 +    if (*len > 600*1024) *len = 600*1024;
 46.1251 +
 46.1252 +    *Data = (char*) _cmsMalloc(*len + 1);  // Plus zero marker
 46.1253  
 46.1254      if (!*Data) {
 46.1255  
 46.1256 @@ -2162,7 +2354,7 @@
 46.1257  
 46.1258  
 46.1259  
 46.1260 -BOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
 46.1261 +LCMSBOOL LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile)
 46.1262  {
 46.1263      LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.1264      int n;
 46.1265 @@ -2170,8 +2362,8 @@
 46.1266      n = _cmsSearchTag(Icc, icSigCalibrationDateTimeTag, FALSE);
 46.1267      if (n < 0) return FALSE;
 46.1268  
 46.1269 -    if (!Icc ->stream)
 46.1270 -    {
 46.1271 +    if (Icc ->TagPtrs[n]) {
 46.1272 +
 46.1273          CopyMemory(Dest, Icc ->TagPtrs[n],  sizeof(struct tm));
 46.1274      }
 46.1275      else
 46.1276 @@ -2212,9 +2404,10 @@
 46.1277      size   = Icc -> TagSizes[n];
 46.1278      if (size < 12)  return NULL;
 46.1279  
 46.1280 -    if (!Icc -> stream) {
 46.1281 -
 46.1282 -            OutSeq = (LPcmsSEQ) malloc(size);
 46.1283 +    if (Icc -> TagPtrs[n]) {
 46.1284 +
 46.1285 +            OutSeq = (LPcmsSEQ) _cmsMalloc(size);
 46.1286 +            if (OutSeq == NULL) return NULL;
 46.1287              CopyMemory(OutSeq, Icc ->TagPtrs[n], size);
 46.1288              return OutSeq;
 46.1289      }
 46.1290 @@ -2231,8 +2424,13 @@
 46.1291      Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc);
 46.1292      AdjustEndianess32((LPBYTE) &Count);
 46.1293  
 46.1294 +    if (Count > 1000) {
 46.1295 +         return NULL;
 46.1296 +    }
 46.1297 +
 46.1298      size = sizeof(int) + Count * sizeof(cmsPSEQDESC);
 46.1299 -    OutSeq = (LPcmsSEQ) malloc(size);
 46.1300 +    OutSeq = (LPcmsSEQ) _cmsMalloc(size);
 46.1301 +    if (OutSeq == NULL) return NULL;
 46.1302  
 46.1303      OutSeq ->n = Count;
 46.1304  
 46.1305 @@ -2268,181 +2466,11 @@
 46.1306  void LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq)
 46.1307  {
 46.1308      if (pseq)
 46.1309 -        free(pseq);
 46.1310 +        _cmsFree(pseq);
 46.1311  }
 46.1312  
 46.1313  
 46.1314  
 46.1315 -// Extended gamut -- an HP extension
 46.1316 -
 46.1317 -
 46.1318 -LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index)
 46.1319 -{
 46.1320 -    LPLCMSICCPROFILE  Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.1321 -    size_t size, offset;
 46.1322 -    icUInt32Number off_samp, off_desc, off_vc;
 46.1323 -    int n;
 46.1324 -    icTagTypeSignature     BaseType;
 46.1325 -    icColorSpaceSignature  CoordSig;
 46.1326 -    icUInt16Number         Method, Usage;
 46.1327 -    icUInt32Number         GamutCount, SamplesCount;
 46.1328 -    LPcmsGAMUTEX gex;
 46.1329 -    size_t                 Offsets[256];
 46.1330 -    size_t                 i, Actual, Loc;
 46.1331 -    icS15Fixed16Number     Num;
 46.1332 -    icUInt16Number         Surround;
 46.1333 -
 46.1334 -
 46.1335 -    n = _cmsSearchTag(Icc, icSigHPGamutDescTag, FALSE);
 46.1336 -    if (n < 0) return NULL;
 46.1337 -
 46.1338 -    if (!Icc ->stream) return NULL;     // In memory is not supported
 46.1339 -
 46.1340 -    // Read the header
 46.1341 -
 46.1342 -    offset = Icc -> TagOffsets[n];
 46.1343 -
 46.1344 -    if (Icc -> Seek(Icc, offset))
 46.1345 -            return NULL;
 46.1346 -
 46.1347 -    // Here is the beginning of tag
 46.1348 -    Actual   = Icc ->Tell(Icc);
 46.1349 -
 46.1350 -
 46.1351 -    BaseType = ReadBase(Icc);
 46.1352 -
 46.1353 -    if (BaseType != icSigHPGamutDescType) {
 46.1354 -            cmsSignalError(LCMS_ERRC_ABORTED, "Bad tag signature '%lx' found.", BaseType);
 46.1355 -            return NULL;
 46.1356 -    }
 46.1357 -
 46.1358 -
 46.1359 -    // Read the gamut descriptors count
 46.1360 -    Icc ->Read(&GamutCount, sizeof(icUInt32Number), 1, Icc);
 46.1361 -    AdjustEndianess32((LPBYTE) &GamutCount);
 46.1362 -
 46.1363 -
 46.1364 -    if (GamutCount >= 256) {
 46.1365 -            cmsSignalError(LCMS_ERRC_ABORTED, "Too many gamut structures '%d'.", GamutCount);
 46.1366 -            return NULL;
 46.1367 -    }
 46.1368 -
 46.1369 -    // Read the directory
 46.1370 -
 46.1371 -    for (i=0; i < GamutCount; i++) {
 46.1372 -
 46.1373 -        Icc ->Read(&Offsets[i], sizeof(icUInt32Number), 1, Icc);
 46.1374 -        AdjustEndianess32((LPBYTE) &Offsets[i]);
 46.1375 -    }
 46.1376 -
 46.1377 -
 46.1378 -    // Is there such element?
 46.1379 -    if (index >= (int) GamutCount) return NULL;
 46.1380 -    Loc = Actual + Offsets[index];
 46.1381 -
 46.1382 -
 46.1383 -    // Go to specified index
 46.1384 -    if (Icc -> Seek(Icc, Loc))
 46.1385 -            return NULL;
 46.1386 -
 46.1387 -
 46.1388 -    // Read all members
 46.1389 -    Icc ->Read(&CoordSig, sizeof(icColorSpaceSignature), 1, Icc);
 46.1390 -    AdjustEndianess32((LPBYTE) &CoordSig);
 46.1391 -
 46.1392 -    Icc ->Read(&Method, sizeof(icUInt16Number), 1, Icc);
 46.1393 -    AdjustEndianess16((LPBYTE) &Method);
 46.1394 -
 46.1395 -    Icc ->Read(&Usage, sizeof(icUInt16Number), 1, Icc);
 46.1396 -    AdjustEndianess16((LPBYTE) &Usage);
 46.1397 -
 46.1398 -    Icc ->Read(&SamplesCount, sizeof(icUInt32Number), 1, Icc);
 46.1399 -    AdjustEndianess32((LPBYTE) &SamplesCount);
 46.1400 -
 46.1401 -    Icc ->Read(&off_samp, sizeof(icUInt32Number), 1, Icc);
 46.1402 -    AdjustEndianess32((LPBYTE) &off_samp);
 46.1403 -
 46.1404 -    Icc ->Read(&off_desc, sizeof(icUInt32Number), 1, Icc);
 46.1405 -    AdjustEndianess32((LPBYTE) &off_desc);
 46.1406 -
 46.1407 -    Icc ->Read(&off_vc, sizeof(icUInt32Number), 1, Icc);
 46.1408 -    AdjustEndianess32((LPBYTE) &off_vc);
 46.1409 -
 46.1410 -
 46.1411 -    size = sizeof(cmsGAMUTEX) + (SamplesCount - 1) * sizeof(double);
 46.1412 -
 46.1413 -    gex = (LPcmsGAMUTEX) malloc(size);
 46.1414 -        if (gex == NULL) return NULL;
 46.1415 -
 46.1416 -
 46.1417 -    gex ->CoordSig = CoordSig;
 46.1418 -    gex ->Method   = Method;
 46.1419 -    gex ->Usage    = Usage;
 46.1420 -        gex ->Count    = SamplesCount;
 46.1421 -
 46.1422 -
 46.1423 -    // Read data
 46.1424 -    if (Icc -> Seek(Icc, Loc + off_samp))
 46.1425 -            return NULL;
 46.1426 -
 46.1427 -    for (i=0; i < SamplesCount; i++) {
 46.1428 -                Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
 46.1429 -                gex ->Data[i] = Convert15Fixed16(Num);
 46.1430 -    }
 46.1431 -
 46.1432 -
 46.1433 -    // Read mluc
 46.1434 -    if (Icc -> Seek(Icc, Loc + off_desc)) {
 46.1435 -
 46.1436 -                        free(gex);
 46.1437 -            return NULL;
 46.1438 -        }
 46.1439 -
 46.1440 -    ReadEmbeddedTextTag(Icc, 256, gex ->Description, LCMS_DESC_MAX);
 46.1441 -
 46.1442 -
 46.1443 -    // Read viewing conditions
 46.1444 -    if (Icc -> Seek(Icc, Loc + off_vc)) {
 46.1445 -                        free(gex);
 46.1446 -            return NULL;
 46.1447 -        }
 46.1448 -
 46.1449 -
 46.1450 -    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
 46.1451 -    gex ->Vc.whitePoint.X = Convert15Fixed16(Num);
 46.1452 -
 46.1453 -    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
 46.1454 -    gex ->Vc.whitePoint.Y = Convert15Fixed16(Num);
 46.1455 -
 46.1456 -    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
 46.1457 -    gex ->Vc.whitePoint.Z = Convert15Fixed16(Num);
 46.1458 -
 46.1459 -    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
 46.1460 -    gex ->Vc.La = Convert15Fixed16(Num);
 46.1461 -
 46.1462 -    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
 46.1463 -    gex ->Vc.Yb = Convert15Fixed16(Num);
 46.1464 -
 46.1465 -    Icc -> Read(&Num, sizeof(icS15Fixed16Number), 1, Icc);
 46.1466 -    gex ->Vc.D_value = Convert15Fixed16(Num);
 46.1467 -
 46.1468 -    Icc -> Read(&Surround, sizeof(icUInt16Number), 1, Icc);
 46.1469 -    AdjustEndianess16((LPBYTE) &Surround);
 46.1470 -    gex ->Vc.surround = Surround;
 46.1471 -
 46.1472 -
 46.1473 -    // All OK
 46.1474 -    return gex;
 46.1475 -
 46.1476 -}
 46.1477 -
 46.1478 -
 46.1479 -
 46.1480 -void LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex)
 46.1481 -{
 46.1482 -    if (gex)
 46.1483 -        free(gex);
 46.1484 -}
 46.1485  
 46.1486  
 46.1487  // Read a few tags that are hardly required
 46.1488 @@ -2564,6 +2592,7 @@
 46.1489             NewIcc = (LPLCMSICCPROFILE) (LPSTR) hEmpty;
 46.1490             NewIcc -> IsWrite = TRUE;
 46.1491             strncpy(NewIcc ->PhysicalFile, lpFileName, MAX_PATH-1);
 46.1492 +           NewIcc ->PhysicalFile[MAX_PATH-1] = 0;
 46.1493  
 46.1494             // Save LUT as 8 bit
 46.1495  
 46.1496 @@ -2609,14 +2638,14 @@
 46.1497  
 46.1498  
 46.1499  
 46.1500 -BOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile)
 46.1501 +LCMSBOOL LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile)
 46.1502  {
 46.1503         LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.1504 -       BOOL rc = TRUE;
 46.1505 +       LCMSBOOL rc = TRUE;
 46.1506 +       icInt32Number i;
 46.1507  
 46.1508         if (!Icc) return FALSE;
 46.1509  
 46.1510 -
 46.1511         // Was open in write mode?
 46.1512         if (Icc ->IsWrite) {
 46.1513  
 46.1514 @@ -2624,21 +2653,15 @@
 46.1515             rc = _cmsSaveProfile(hProfile, Icc ->PhysicalFile);
 46.1516         }
 46.1517  
 46.1518 -
 46.1519 -       if (Icc -> stream == NULL) {     // Was a memory (i.e. not serialized) profile?
 46.1520 -
 46.1521 -
 46.1522 -              icInt32Number i;          // Yes, free tags
 46.1523 -
 46.1524 -              for (i=0; i < Icc -> TagCount; i++) {
 46.1525 +       for (i=0; i < Icc -> TagCount; i++) {
 46.1526  
 46.1527                    if (Icc -> TagPtrs[i])
 46.1528                              free(Icc -> TagPtrs[i]);
 46.1529 -              }
 46.1530 -
 46.1531         }
 46.1532 -       else   Icc -> Close(Icc);    // No, close the stream
 46.1533 -
 46.1534 +
 46.1535 +       if (Icc -> stream != NULL) {     // Was a memory (i.e. not serialized) profile?
 46.1536 +                 Icc -> Close(Icc);     // No, close the stream
 46.1537 +       }
 46.1538  
 46.1539         free(Icc);   // Free placeholder memory
 46.1540  
 46.1541 @@ -2652,11 +2675,11 @@
 46.1542  
 46.1543  
 46.1544  static
 46.1545 -BOOL SaveWordsTable(int nEntries, LPWORD Tab, LPLCMSICCPROFILE Icc)
 46.1546 +LCMSBOOL SaveWordsTable(int nEntries, LPWORD Tab, LPLCMSICCPROFILE Icc)
 46.1547  {
 46.1548     size_t nTabSize = sizeof(WORD) * nEntries;
 46.1549 -   LPWORD PtrW = (LPWORD) malloc(nTabSize);
 46.1550 -   BOOL rc;
 46.1551 +   LPWORD PtrW = (LPWORD) _cmsMalloc(nTabSize);
 46.1552 +   LCMSBOOL rc;
 46.1553  
 46.1554     if (!PtrW) return FALSE;
 46.1555     CopyMemory(PtrW, Tab, nTabSize);
 46.1556 @@ -2672,7 +2695,7 @@
 46.1557  // Saves profile header
 46.1558  
 46.1559  static
 46.1560 -BOOL SaveHeader(LPLCMSICCPROFILE Icc)
 46.1561 +LCMSBOOL SaveHeader(LPLCMSICCPROFILE Icc)
 46.1562  {
 46.1563    icHeader Header;
 46.1564    time_t now = time(NULL);
 46.1565 @@ -2727,7 +2750,7 @@
 46.1566  // Setup base marker
 46.1567  
 46.1568  static
 46.1569 -BOOL SetupBase(icTagTypeSignature sig, LPLCMSICCPROFILE Icc)
 46.1570 +LCMSBOOL SetupBase(icTagTypeSignature sig, LPLCMSICCPROFILE Icc)
 46.1571  {
 46.1572      icTagBase  Base;
 46.1573  
 46.1574 @@ -2737,10 +2760,10 @@
 46.1575  }
 46.1576  
 46.1577  
 46.1578 -// Store an XYZ tag
 46.1579 +// Store a XYZ tag
 46.1580  
 46.1581  static
 46.1582 -BOOL SaveXYZNumber(LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc)
 46.1583 +LCMSBOOL SaveXYZNumber(LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc)
 46.1584  {
 46.1585  
 46.1586      icXYZNumber XYZ;
 46.1587 @@ -2756,112 +2779,137 @@
 46.1588  }
 46.1589  
 46.1590  
 46.1591 +// Store a XYZ array.
 46.1592 +
 46.1593 +static
 46.1594 +LCMSBOOL SaveXYZArray(int n, LPcmsCIEXYZ Value, LPLCMSICCPROFILE Icc)
 46.1595 +{
 46.1596 +    int i;
 46.1597 +    icXYZNumber XYZ;
 46.1598 +
 46.1599 +    if (!SetupBase(icSigS15Fixed16ArrayType, Icc)) return FALSE;
 46.1600 +
 46.1601 +    for (i=0; i < n; i++) {
 46.1602 +
 46.1603 +        XYZ.X = TransportValue32(DOUBLE_TO_FIXED(Value -> X));
 46.1604 +        XYZ.Y = TransportValue32(DOUBLE_TO_FIXED(Value -> Y));
 46.1605 +        XYZ.Z = TransportValue32(DOUBLE_TO_FIXED(Value -> Z));
 46.1606 +
 46.1607 +        if (!Icc -> Write(Icc, sizeof(icXYZNumber), &XYZ)) return FALSE;
 46.1608 +
 46.1609 +        Value++;
 46.1610 +    }
 46.1611 +
 46.1612 +    return TRUE;
 46.1613 +}
 46.1614 +
 46.1615 +
 46.1616  
 46.1617  // Save a gamma structure as a table
 46.1618  
 46.1619  static
 46.1620 -BOOL SaveGammaTable(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1621 +LCMSBOOL SaveGammaTable(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1622  {
 46.1623 -        icInt32Number Count;
 46.1624 -
 46.1625 -                if (!SetupBase(icSigCurveType, Icc)) return FALSE;
 46.1626 -
 46.1627 -                Count = TransportValue32(Gamma->nEntries);
 46.1628 -
 46.1629 -                if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE;
 46.1630 -
 46.1631 -                return SaveWordsTable(Gamma->nEntries, Gamma ->GammaTable, Icc);
 46.1632 +    icInt32Number Count;
 46.1633 +
 46.1634 +        if (!SetupBase(icSigCurveType, Icc)) return FALSE;
 46.1635 +
 46.1636 +        Count = TransportValue32(Gamma->nEntries);
 46.1637 +
 46.1638 +        if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE;
 46.1639 +
 46.1640 +        return SaveWordsTable(Gamma->nEntries, Gamma ->GammaTable, Icc);
 46.1641  }
 46.1642  
 46.1643  
 46.1644  // Save a gamma structure as a one-value
 46.1645  
 46.1646  static
 46.1647 -BOOL SaveGammaOneValue(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1648 +LCMSBOOL SaveGammaOneValue(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1649  {
 46.1650 -        icInt32Number Count;
 46.1651 -        Fixed32 GammaFixed32;
 46.1652 -        WORD    GammaFixed8;
 46.1653 -
 46.1654 -                if (!SetupBase(icSigCurveType, Icc)) return FALSE;
 46.1655 -
 46.1656 -                Count = TransportValue32(1);
 46.1657 -                if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE;
 46.1658 -
 46.1659 -                GammaFixed32 = DOUBLE_TO_FIXED(Gamma ->Seed.Params[0]);
 46.1660 -                GammaFixed8  = (WORD) ((GammaFixed32 >> 8) & 0xFFFF);
 46.1661 -                GammaFixed8  = TransportValue16(GammaFixed8);
 46.1662 -
 46.1663 -                return Icc ->Write(Icc, sizeof(icInt16Number), &GammaFixed8);
 46.1664 +    icInt32Number Count;
 46.1665 +    Fixed32 GammaFixed32;
 46.1666 +    WORD    GammaFixed8;
 46.1667 +
 46.1668 +        if (!SetupBase(icSigCurveType, Icc)) return FALSE;
 46.1669 +
 46.1670 +        Count = TransportValue32(1);
 46.1671 +        if (!Icc ->Write(Icc, sizeof(icInt32Number), &Count)) return FALSE;
 46.1672 +
 46.1673 +        GammaFixed32 = DOUBLE_TO_FIXED(Gamma ->Seed.Params[0]);
 46.1674 +        GammaFixed8  = (WORD) ((GammaFixed32 >> 8) & 0xFFFF);
 46.1675 +        GammaFixed8  = TransportValue16(GammaFixed8);
 46.1676 +
 46.1677 +        return Icc ->Write(Icc, sizeof(icInt16Number), &GammaFixed8);
 46.1678  }
 46.1679  
 46.1680  // Save a gamma structure as a parametric gamma
 46.1681  
 46.1682  static
 46.1683 -BOOL SaveGammaParametric(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1684 +LCMSBOOL SaveGammaParametric(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1685  {
 46.1686 -        icUInt16Number Type, Reserved;
 46.1687 -        int i, nParams;
 46.1688 -        int ParamsByType[] = { 1, 3, 4, 5, 7 };
 46.1689 -
 46.1690 -        if (!SetupBase(icSigParametricCurveType, Icc)) return FALSE;
 46.1691 -
 46.1692 -        nParams = ParamsByType[Gamma -> Seed.Type];
 46.1693 -
 46.1694 -        Type      = (icUInt16Number) TransportValue16((WORD) Gamma -> Seed. Type);
 46.1695 -        Reserved  = (icUInt16Number) TransportValue16((WORD) 0);
 46.1696 -
 46.1697 -        Icc -> Write(Icc, sizeof(icInt16Number),  &Type);
 46.1698 -        Icc -> Write(Icc, sizeof(icUInt16Number), &Reserved);
 46.1699 -
 46.1700 -        for (i=0; i < nParams; i++) {
 46.1701 -
 46.1702 -                icInt32Number val = TransportValue32(DOUBLE_TO_FIXED(Gamma -> Seed.Params[i]));
 46.1703 -                Icc ->Write(Icc, sizeof(icInt32Number), &val);
 46.1704 +    icUInt16Number Type, Reserved;
 46.1705 +    int i, nParams;
 46.1706 +    int ParamsByType[] = { 1, 3, 4, 5, 7 };
 46.1707 +
 46.1708 +    if (!SetupBase(icSigParametricCurveType, Icc)) return FALSE;
 46.1709 +
 46.1710 +    nParams = ParamsByType[Gamma -> Seed.Type];
 46.1711 +
 46.1712 +    Type      = (icUInt16Number) TransportValue16((WORD) Gamma -> Seed. Type);
 46.1713 +    Reserved  = (icUInt16Number) TransportValue16((WORD) 0);
 46.1714 +
 46.1715 +    Icc -> Write(Icc, sizeof(icInt16Number),  &Type);
 46.1716 +    Icc -> Write(Icc, sizeof(icUInt16Number), &Reserved);
 46.1717 +
 46.1718 +    for (i=0; i < nParams; i++) {
 46.1719 +
 46.1720 +        icInt32Number val = TransportValue32(DOUBLE_TO_FIXED(Gamma -> Seed.Params[i]));
 46.1721 +        Icc ->Write(Icc, sizeof(icInt32Number), &val);
 46.1722 +    }
 46.1723 +
 46.1724 +
 46.1725 +    return TRUE;
 46.1726 +
 46.1727 +}
 46.1728 +
 46.1729 +
 46.1730 +// Save a gamma table
 46.1731 +
 46.1732 +static
 46.1733 +LCMSBOOL SaveGamma(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1734 +{
 46.1735 +        // Is the gamma curve type supported by ICC format?
 46.1736 +
 46.1737 +        if (Gamma -> Seed.Type < 0 || Gamma -> Seed.Type > 5 ||
 46.1738 +
 46.1739 +            // has been modified by user?
 46.1740 +
 46.1741 +            _cmsCrc32OfGammaTable(Gamma) != Gamma -> Seed.Crc32) {
 46.1742 +
 46.1743 +            return SaveGammaTable(Gamma, Icc);
 46.1744          }
 46.1745  
 46.1746 -
 46.1747 -        return TRUE;
 46.1748 +        if (Gamma -> Seed.Type == 1) return SaveGammaOneValue(Gamma, Icc);
 46.1749 +
 46.1750 +        // Only v4 profiles are allowed to hold parametric curves
 46.1751 +
 46.1752 +        if (cmsGetProfileICCversion((cmsHPROFILE) Icc) >= 0x4000000)
 46.1753 +                return SaveGammaParametric(Gamma, Icc);
 46.1754 +
 46.1755 +        // Defaults to save as table
 46.1756 +
 46.1757 +        return SaveGammaTable(Gamma, Icc);
 46.1758  
 46.1759  }
 46.1760  
 46.1761  
 46.1762 -// Save a gamma table
 46.1763 +
 46.1764 +
 46.1765 +// Save an DESC Tag
 46.1766  
 46.1767  static
 46.1768 -BOOL SaveGamma(LPGAMMATABLE Gamma, LPLCMSICCPROFILE Icc)
 46.1769 -{
 46.1770 -                // Is the gamma curve type supported by ICC format?
 46.1771 -
 46.1772 -                if (Gamma -> Seed.Type < 0 || Gamma -> Seed.Type > 5 ||
 46.1773 -
 46.1774 -                        // has been modified by user?
 46.1775 -
 46.1776 -                        _cmsCrc32OfGammaTable(Gamma) != Gamma -> Seed.Crc32) {
 46.1777 -
 46.1778 -                        return SaveGammaTable(Gamma, Icc);
 46.1779 -                }
 46.1780 -
 46.1781 -                if (Gamma -> Seed.Type == 1) return SaveGammaOneValue(Gamma, Icc);
 46.1782 -
 46.1783 -                // Only v4 profiles are allowed to hold parametric curves
 46.1784 -
 46.1785 -                if (cmsGetProfileICCversion((cmsHPROFILE) Icc) >= 0x4000000)
 46.1786 -                                return SaveGammaParametric(Gamma, Icc);
 46.1787 -
 46.1788 -                // Defaults to save as table
 46.1789 -
 46.1790 -                return SaveGammaTable(Gamma, Icc);
 46.1791 -
 46.1792 -}
 46.1793 -
 46.1794 -
 46.1795 -
 46.1796 -
 46.1797 -// Save an DESC Tag
 46.1798 -
 46.1799 -static
 46.1800 -BOOL SaveDescription(const char *Text, LPLCMSICCPROFILE Icc)
 46.1801 +LCMSBOOL SaveDescription(const char *Text, LPLCMSICCPROFILE Icc)
 46.1802  {
 46.1803  
 46.1804      icUInt32Number len, Count, TotalSize, AlignedSize;
 46.1805 @@ -2893,6 +2941,11 @@
 46.1806      if (!Icc ->Write(Icc, len, (LPVOID)Text)) return FALSE;
 46.1807      AlignedSize -= len;
 46.1808  
 46.1809 +    if (AlignedSize < 0)
 46.1810 +            AlignedSize = 0;
 46.1811 +    if (AlignedSize > 255)
 46.1812 +            AlignedSize = 255;
 46.1813 +
 46.1814      ZeroMemory(Filler, AlignedSize);
 46.1815      if (!Icc ->Write(Icc, AlignedSize, Filler)) return FALSE;
 46.1816  
 46.1817 @@ -2902,7 +2955,7 @@
 46.1818  // Save an ASCII Tag
 46.1819  
 46.1820  static
 46.1821 -BOOL SaveText(const char *Text, LPLCMSICCPROFILE Icc)
 46.1822 +LCMSBOOL SaveText(const char *Text, LPLCMSICCPROFILE Icc)
 46.1823  {
 46.1824      size_t len = strlen(Text) + 1;
 46.1825  
 46.1826 @@ -2915,7 +2968,7 @@
 46.1827  // Save one of these new chromaticity values
 46.1828  
 46.1829  static
 46.1830 -BOOL SaveOneChromaticity(double x, double y, LPLCMSICCPROFILE Icc)
 46.1831 +LCMSBOOL SaveOneChromaticity(double x, double y, LPLCMSICCPROFILE Icc)
 46.1832  {
 46.1833         Fixed32 xf, yf;
 46.1834  
 46.1835 @@ -2932,7 +2985,7 @@
 46.1836  // New tag added in Addendum II of old spec.
 46.1837  
 46.1838  static
 46.1839 -BOOL SaveChromaticities(LPcmsCIExyYTRIPLE chrm, LPLCMSICCPROFILE Icc)
 46.1840 +LCMSBOOL SaveChromaticities(LPcmsCIExyYTRIPLE chrm, LPLCMSICCPROFILE Icc)
 46.1841  {
 46.1842         WORD nChans, Table;
 46.1843  
 46.1844 @@ -2952,7 +3005,7 @@
 46.1845  
 46.1846  
 46.1847  static
 46.1848 -BOOL SaveSequenceDescriptionTag(LPcmsSEQ seq, LPLCMSICCPROFILE Icc)
 46.1849 +LCMSBOOL SaveSequenceDescriptionTag(LPcmsSEQ seq, LPLCMSICCPROFILE Icc)
 46.1850  {
 46.1851      icUInt32Number nSeqs;
 46.1852      icDescStruct   DescStruct;
 46.1853 @@ -2989,7 +3042,7 @@
 46.1854  // Saves a timestamp tag
 46.1855  
 46.1856  static
 46.1857 -BOOL SaveDateTimeNumber(const struct tm *DateTime, LPLCMSICCPROFILE Icc)
 46.1858 +LCMSBOOL SaveDateTimeNumber(const struct tm *DateTime, LPLCMSICCPROFILE Icc)
 46.1859  {
 46.1860      icDateTimeNumber Dest;
 46.1861  
 46.1862 @@ -3003,14 +3056,14 @@
 46.1863  
 46.1864  // Saves a named color list into a named color profile
 46.1865  static
 46.1866 -BOOL SaveNamedColorList(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
 46.1867 +LCMSBOOL SaveNamedColorList(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
 46.1868  {
 46.1869  
 46.1870      icUInt32Number      vendorFlag;     // Bottom 16 bits for IC use
 46.1871      icUInt32Number      count;          // Count of named colors
 46.1872      icUInt32Number      nDeviceCoords;  // Num of device coordinates
 46.1873 -    icInt8Number        prefix[32];     // Prefix for each color name
 46.1874 -    icInt8Number        suffix[32];     // Suffix for each color name
 46.1875 +    char                prefix[32];     // Prefix for each color name
 46.1876 +    char                suffix[32];     // Suffix for each color name
 46.1877      int i;
 46.1878  
 46.1879      if (!SetupBase(icSigNamedColor2Type, Icc)) return FALSE;
 46.1880 @@ -3019,8 +3072,10 @@
 46.1881      count         = TransportValue32(NamedColorList ->nColors);
 46.1882      nDeviceCoords = TransportValue32(NamedColorList ->ColorantCount);
 46.1883  
 46.1884 -    strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
 46.1885 -    strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
 46.1886 +    strncpy(prefix, (const char*) NamedColorList->Prefix, 31);
 46.1887 +    strncpy(suffix, (const char*) NamedColorList->Suffix, 31);
 46.1888 +
 46.1889 +    suffix[31] = prefix[31] = 0;
 46.1890  
 46.1891      if (!Icc ->Write(Icc, sizeof(icUInt32Number), &vendorFlag)) return FALSE;
 46.1892      if (!Icc ->Write(Icc, sizeof(icUInt32Number), &count)) return FALSE;
 46.1893 @@ -3030,15 +3085,17 @@
 46.1894  
 46.1895      for (i=0; i < NamedColorList ->nColors; i++) {
 46.1896  
 46.1897 -          icUInt16Number PCS[3];
 46.1898 -          icUInt16Number Colorant[MAXCHANNELS];
 46.1899 -          icInt8Number root[32];
 46.1900 +          icUInt16Number  PCS[3];
 46.1901 +          icUInt16Number  Colorant[MAXCHANNELS];
 46.1902 +          char            root[32];
 46.1903            LPcmsNAMEDCOLOR Color;
 46.1904            int j;
 46.1905  
 46.1906                      Color = NamedColorList ->List + i;
 46.1907  
 46.1908 -                    strncpy((char*) root, Color ->Name, 32);
 46.1909 +                    strncpy(root, Color ->Name, 32);
 46.1910 +                    Color ->Name[32] = 0;
 46.1911 +
 46.1912                      if (!Icc ->Write(Icc, 32 , root)) return FALSE;
 46.1913  
 46.1914                      for (j=0; j < 3; j++)
 46.1915 @@ -3062,7 +3119,7 @@
 46.1916  // Saves a colorant table. It is using the named color structure for simplicity sake
 46.1917  
 46.1918  static
 46.1919 -BOOL SaveColorantTable(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
 46.1920 +LCMSBOOL SaveColorantTable(LPcmsNAMEDCOLORLIST NamedColorList, LPLCMSICCPROFILE Icc)
 46.1921  {
 46.1922       icUInt32Number count;  // Count of named colors
 46.1923       int i;
 46.1924 @@ -3076,13 +3133,15 @@
 46.1925       for (i=0; i < NamedColorList ->nColors; i++) {
 46.1926  
 46.1927        icUInt16Number PCS[3];
 46.1928 -      icInt8Number root[32];
 46.1929 +      icInt8Number root[33];
 46.1930        LPcmsNAMEDCOLOR Color;
 46.1931        int j;
 46.1932  
 46.1933              Color = NamedColorList ->List + i;
 46.1934  
 46.1935              strncpy((char*) root, Color ->Name, 32);
 46.1936 +            root[32] = 0;
 46.1937 +
 46.1938              if (!Icc ->Write(Icc, 32 , root)) return FALSE;
 46.1939  
 46.1940              for (j=0; j < 3; j++)
 46.1941 @@ -3099,7 +3158,7 @@
 46.1942  // Does serialization of LUT16 and writes it.
 46.1943  
 46.1944  static
 46.1945 -BOOL SaveLUT(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
 46.1946 +LCMSBOOL SaveLUT(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
 46.1947  {
 46.1948         icLut16 LUT16;
 46.1949         unsigned int i;
 46.1950 @@ -3189,7 +3248,7 @@
 46.1951  // Does serialization of LUT8 and writes it
 46.1952  
 46.1953  static
 46.1954 -BOOL SaveLUT8(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
 46.1955 +LCMSBOOL SaveLUT8(const LUT* NewLUT, LPLCMSICCPROFILE Icc)
 46.1956  {
 46.1957         icLut8 LUT8;
 46.1958         unsigned int i, j;
 46.1959 @@ -3323,7 +3382,7 @@
 46.1960  // Saves Tag directory
 46.1961  
 46.1962  static
 46.1963 -BOOL SaveTagDirectory(LPLCMSICCPROFILE Icc)
 46.1964 +LCMSBOOL SaveTagDirectory(LPLCMSICCPROFILE Icc)
 46.1965  {
 46.1966         icInt32Number i;
 46.1967         icTag Tag;
 46.1968 @@ -3356,7 +3415,7 @@
 46.1969  // Dump tag contents
 46.1970  
 46.1971  static
 46.1972 -BOOL SaveTags(LPLCMSICCPROFILE Icc)
 46.1973 +LCMSBOOL SaveTags(LPLCMSICCPROFILE Icc, LPLCMSICCPROFILE FileOrig)
 46.1974  {
 46.1975  
 46.1976      LPBYTE Data;
 46.1977 @@ -3384,8 +3443,31 @@
 46.1978  
 46.1979         Icc -> TagOffsets[i] = Begin = Icc ->UsedSpace;
 46.1980         Data = (LPBYTE) Icc -> TagPtrs[i];
 46.1981 -       if (!Data)
 46.1982 +       if (!Data) {
 46.1983 +
 46.1984 +           // Reach here if we are copying a tag from a disk-based ICC profile which has not been modified by user.
 46.1985 +           // In this case a blind copy of the block data is performed
 46.1986 +
 46.1987 +           if (Icc -> TagOffsets[i]) {
 46.1988 +
 46.1989 +                    size_t TagSize   = FileOrig -> TagSizes[i];
 46.1990 +                    size_t TagOffset = FileOrig -> TagOffsets[i];
 46.1991 +                    void* Mem;
 46.1992 +
 46.1993 +                    if (FileOrig ->Seek(FileOrig, TagOffset)) return FALSE;
 46.1994 +
 46.1995 +                    Mem = _cmsMalloc(TagSize);
 46.1996 +
 46.1997 +                    if (FileOrig ->Read(Mem, TagSize, 1, FileOrig) != 1) return FALSE;
 46.1998 +                    if (!Icc ->Write(Icc, TagSize, Mem)) return FALSE;
 46.1999 +
 46.2000 +                    Icc -> TagSizes[i] = (Icc ->UsedSpace - Begin);
 46.2001 +                    free(Mem);
 46.2002 +           }
 46.2003 +
 46.2004                continue;
 46.2005 +       }
 46.2006 +
 46.2007  
 46.2008         switch (Icc -> TagNames[i]) {
 46.2009  
 46.2010 @@ -3464,6 +3546,10 @@
 46.2011               break;
 46.2012  
 46.2013  
 46.2014 +       case icSigChromaticAdaptationTag:
 46.2015 +              if (!SaveXYZArray(3, (LPcmsCIEXYZ) Data, Icc)) return FALSE;
 46.2016 +              break;
 46.2017 +
 46.2018         default:
 46.2019                return FALSE;
 46.2020         }
 46.2021 @@ -3480,9 +3566,9 @@
 46.2022  
 46.2023  // Add tags to profile structure
 46.2024  
 46.2025 -BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* Tag)
 46.2026 +LCMSBOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* Tag)
 46.2027  {
 46.2028 -   BOOL rc;
 46.2029 +   LCMSBOOL rc;
 46.2030  
 46.2031     switch (sig) {
 46.2032  
 46.2033 @@ -3543,6 +3629,11 @@
 46.2034                rc = _cmsAddColorantTableTag(hProfile, sig, (LPcmsNAMEDCOLORLIST) Tag);
 46.2035                break;
 46.2036  
 46.2037 +
 46.2038 +       case icSigChromaticAdaptationTag:
 46.2039 +              rc = _cmsAddChromaticAdaptationTag(hProfile, sig, (const cmsCIEXYZ*) Tag);
 46.2040 +              break;
 46.2041 +
 46.2042         default:
 46.2043              cmsSignalError(LCMS_ERRC_ABORTED, "cmsAddTag: Tag '%x' is unsupported", sig);
 46.2044              return FALSE;
 46.2045 @@ -3568,11 +3659,11 @@
 46.2046  
 46.2047  // Low-level save to disk. It closes the profile on exit
 46.2048  
 46.2049 -BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName)
 46.2050 +LCMSBOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName)
 46.2051  {
 46.2052         LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.2053         LCMSICCPROFILE Keep;
 46.2054 -       BOOL rc;
 46.2055 +       LCMSBOOL rc;
 46.2056  
 46.2057          CopyMemory(&Keep, Icc, sizeof(LCMSICCPROFILE));
 46.2058         _cmsSetSaveToDisk(Icc, NULL);
 46.2059 @@ -3581,7 +3672,7 @@
 46.2060  
 46.2061         if (!SaveHeader(Icc)) return FALSE;
 46.2062         if (!SaveTagDirectory(Icc)) return FALSE;
 46.2063 -       if (!SaveTags(Icc)) return FALSE;
 46.2064 +       if (!SaveTags(Icc, &Keep)) return FALSE;
 46.2065  
 46.2066  
 46.2067         _cmsSetSaveToDisk(Icc, FileName);
 46.2068 @@ -3591,7 +3682,7 @@
 46.2069  
 46.2070         if (!SaveHeader(Icc)) goto CleanUp;
 46.2071         if (!SaveTagDirectory(Icc)) goto CleanUp;
 46.2072 -       if (!SaveTags(Icc)) goto CleanUp;
 46.2073 +       if (!SaveTags(Icc, &Keep)) goto CleanUp;
 46.2074  
 46.2075         rc = (Icc ->Close(Icc) == 0);
 46.2076         CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE));
 46.2077 @@ -3608,7 +3699,7 @@
 46.2078  
 46.2079  
 46.2080  // Low-level save from open stream
 46.2081 -BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr,
 46.2082 +LCMSBOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr,
 46.2083                                                             size_t* BytesNeeded)
 46.2084  {
 46.2085      LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;
 46.2086 @@ -3623,20 +3714,20 @@
 46.2087  
 46.2088      if (!SaveHeader(Icc)) return FALSE;
 46.2089      if (!SaveTagDirectory(Icc)) return FALSE;
 46.2090 -    if (!SaveTags(Icc)) return FALSE;
 46.2091 +    if (!SaveTags(Icc, &Keep)) return FALSE;
 46.2092  
 46.2093      if (!MemPtr) {
 46.2094  
 46.2095          // update BytesSaved so caller knows how many bytes are needed for MemPtr
 46.2096          *BytesNeeded = Icc ->UsedSpace;
 46.2097 -                CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE));
 46.2098 +        CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE));
 46.2099          return TRUE;
 46.2100      }
 46.2101  
 46.2102      if (*BytesNeeded < Icc ->UsedSpace) {
 46.2103  
 46.2104          // need at least UsedSpace in MemPtr to continue
 46.2105 -                CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE));
 46.2106 +        CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE));
 46.2107          return FALSE;
 46.2108      }
 46.2109  
 46.2110 @@ -3646,7 +3737,7 @@
 46.2111      // Pass #2 does save to file into supplied stream
 46.2112      if (!SaveHeader(Icc)) goto CleanUp;
 46.2113      if (!SaveTagDirectory(Icc)) goto CleanUp;
 46.2114 -    if (!SaveTags(Icc)) goto CleanUp;
 46.2115 +    if (!SaveTags(Icc, &Keep)) goto CleanUp;
 46.2116  
 46.2117      // update BytesSaved so caller knows how many bytes put into stream
 46.2118      *BytesNeeded = Icc ->UsedSpace;
 46.2119 @@ -3661,3 +3752,4 @@
 46.2120      CopyMemory(Icc, &Keep, sizeof(LCMSICCPROFILE));
 46.2121      return FALSE;
 46.2122  }
 46.2123 +
    47.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmslut.c	Tue Apr 07 11:43:20 2009 -0700
    47.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmslut.c	Tue Apr 07 14:02:54 2009 -0700
    47.3 @@ -29,7 +29,7 @@
    47.4  //
    47.5  //
    47.6  //  Little cms
    47.7 -//  Copyright (C) 1998-2006 Marti Maria
    47.8 +//  Copyright (C) 1998-2007 Marti Maria
    47.9  //
   47.10  // Permission is hereby granted, free of charge, to any person obtaining
   47.11  // a copy of this software and associated documentation files (the "Software"),
   47.12 @@ -118,7 +118,7 @@
   47.13  {
   47.14         LPLUT NewLUT;
   47.15  
   47.16 -       NewLUT = (LPLUT) malloc(sizeof(LUT));
   47.17 +       NewLUT = (LPLUT) _cmsMalloc(sizeof(LUT));
   47.18         if (NewLUT)
   47.19                ZeroMemory(NewLUT, sizeof(LUT));
   47.20  
   47.21 @@ -171,9 +171,10 @@
   47.22  static
   47.23  LPVOID DupBlockTab(LPVOID Org, size_t size)
   47.24  {
   47.25 -    LPVOID mem = malloc(size);
   47.26 +    LPVOID mem = _cmsMalloc(size);
   47.27 +    if (mem != NULL)
   47.28 +        CopyMemory(mem, Org, size);
   47.29  
   47.30 -    CopyMemory(mem, Org, size);
   47.31      return mem;
   47.32  }
   47.33  
   47.34 @@ -211,6 +212,37 @@
   47.35  }
   47.36  
   47.37  
   47.38 +LCMSBOOL _cmsValidateLUT(LPLUT NewLUT)
   47.39 +{
   47.40 +    unsigned int calc = 1;
   47.41 +    unsigned int oldCalc;
   47.42 +    unsigned int power = NewLUT -> InputChan;
   47.43 +
   47.44 +    if (NewLUT -> cLutPoints > 100) return FALSE;
   47.45 +    if (NewLUT -> InputChan > MAXCHANNELS)  return FALSE;
   47.46 +    if (NewLUT -> OutputChan > MAXCHANNELS) return FALSE;
   47.47 +
   47.48 +    if (NewLUT -> cLutPoints == 0) return TRUE;
   47.49 +
   47.50 +    for (; power > 0; power--) {
   47.51 +
   47.52 +      oldCalc = calc;
   47.53 +      calc *= NewLUT -> cLutPoints;
   47.54 +
   47.55 +      if (calc / NewLUT -> cLutPoints != oldCalc) {
   47.56 +        return FALSE;
   47.57 +      }
   47.58 +    }
   47.59 +
   47.60 +    oldCalc = calc;
   47.61 +    calc *= NewLUT -> OutputChan;
   47.62 +    if (NewLUT -> OutputChan && calc / NewLUT -> OutputChan != oldCalc) {
   47.63 +      return FALSE;
   47.64 +    }
   47.65 +
   47.66 +    return TRUE;
   47.67 +}
   47.68 +
   47.69  LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int outputChan)
   47.70  {
   47.71      DWORD nTabSize;
   47.72 @@ -220,12 +252,17 @@
   47.73         NewLUT -> InputChan     = inputChan;
   47.74         NewLUT -> OutputChan    = outputChan;
   47.75  
   47.76 +       if (!_cmsValidateLUT(NewLUT)) {
   47.77 +         return NULL;
   47.78 +       }
   47.79  
   47.80 -       nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
   47.81 -                                                NewLUT->InputChan)
   47.82 -                                                * sizeof(WORD));
   47.83 +       nTabSize = NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints,
   47.84 +                                               NewLUT->InputChan);
   47.85  
   47.86 -       NewLUT -> T = (LPWORD) malloc(nTabSize);
   47.87 +       NewLUT -> T = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize);
   47.88 +       nTabSize *= sizeof(WORD);
   47.89 +       if (NewLUT -> T == NULL) return NULL;
   47.90 +
   47.91         ZeroMemory(NewLUT -> T, nTabSize);
   47.92         NewLUT ->Tsize = nTabSize;
   47.93  
   47.94 @@ -254,10 +291,12 @@
   47.95  
   47.96                 for (i=0; i < NewLUT -> InputChan; i++) {
   47.97  
   47.98 -                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> InputEntries);
   47.99 +                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> InputEntries);
  47.100 +                     if (PtrW == NULL) return NULL;
  47.101 +
  47.102                       NewLUT -> L1[i] = PtrW;
  47.103                       CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> InputEntries);
  47.104 -                                         CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.105 +                     CopyMemory(&NewLUT -> LCurvesSeed[0][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.106                 }
  47.107  
  47.108  
  47.109 @@ -268,10 +307,12 @@
  47.110                 NewLUT -> OutputEntries = Tables[0] -> nEntries;
  47.111                 for (i=0; i < NewLUT -> OutputChan; i++) {
  47.112  
  47.113 -                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> OutputEntries);
  47.114 +                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> OutputEntries);
  47.115 +                     if (PtrW == NULL) return NULL;
  47.116 +
  47.117                       NewLUT -> L2[i] = PtrW;
  47.118                       CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> OutputEntries);
  47.119 -                                         CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.120 +                     CopyMemory(&NewLUT -> LCurvesSeed[1][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.121                 }
  47.122                 break;
  47.123  
  47.124 @@ -285,10 +326,12 @@
  47.125  
  47.126                 for (i=0; i < NewLUT -> InputChan; i++) {
  47.127  
  47.128 -                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L3Entries);
  47.129 +                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L3Entries);
  47.130 +                     if (PtrW == NULL) return NULL;
  47.131 +
  47.132                       NewLUT -> L3[i] = PtrW;
  47.133                       CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L3Entries);
  47.134 -                                         CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.135 +                     CopyMemory(&NewLUT -> LCurvesSeed[2][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.136                 }
  47.137                 break;
  47.138  
  47.139 @@ -298,10 +341,12 @@
  47.140                 NewLUT -> L4Entries = Tables[0] -> nEntries;
  47.141                 for (i=0; i < NewLUT -> OutputChan; i++) {
  47.142  
  47.143 -                     PtrW = (LPWORD) malloc(sizeof(WORD) * NewLUT -> L4Entries);
  47.144 +                     PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewLUT -> L4Entries);
  47.145 +                     if (PtrW == NULL) return NULL;
  47.146 +
  47.147                       NewLUT -> L4[i] = PtrW;
  47.148                       CopyMemory(PtrW, Tables[i]->GammaTable, sizeof(WORD) * NewLUT -> L4Entries);
  47.149 -                                         CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.150 +                     CopyMemory(&NewLUT -> LCurvesSeed[3][i], &Tables[i] -> Seed, sizeof(LCMSGAMMAPARAMS));
  47.151                 }
  47.152                 break;
  47.153  
  47.154 @@ -580,7 +625,7 @@
  47.155     LPL16PARAMS p = &Lut ->CLut16params;
  47.156  
  47.157  
  47.158 -   p8 = (LPL8PARAMS) malloc(sizeof(L8PARAMS));
  47.159 +   p8 = (LPL8PARAMS) _cmsMalloc(sizeof(L8PARAMS));
  47.160     if (p8 == NULL) return NULL;
  47.161  
  47.162    // values comes * 257, so we can safely take first byte (x << 8 + x)
  47.163 @@ -593,8 +638,8 @@
  47.164             if (Lut ->wFlags & LUT_HASTL1) {
  47.165  
  47.166                for (j=0; j < 3; j++)
  47.167 -                     StageABC[i] = cmsLinearInterpLUT16(StageABC[i],
  47.168 -                                                        Lut -> L1[i],
  47.169 +                     StageABC[j] = cmsLinearInterpLUT16(StageABC[j],
  47.170 +                                                        Lut -> L1[j],
  47.171                                                         &Lut -> In16params);
  47.172                Lut ->wFlags &= ~LUT_HASTL1;
  47.173             }
  47.174 @@ -697,7 +742,7 @@
  47.175      wIn[3] = FixedK;
  47.176  
  47.177      cmsEvalLUT(Lut, wIn, wOut);
  47.178 -        cmsLabEncoded2Float(Out, wOut);
  47.179 +    cmsLabEncoded2Float(Out, wOut);
  47.180  }
  47.181  
  47.182  // Builds a Jacobian CMY->Lab
  47.183 @@ -722,9 +767,9 @@
  47.184  
  47.185          EvalLUTdoubleKLab(Lut, &ColorantD, K, &LabD);
  47.186  
  47.187 -                Jacobian->v[0].n[j] = ((LabD.L - Lab.L) / JACOBIAN_EPSILON);
  47.188 -                Jacobian->v[1].n[j] = ((LabD.a - Lab.a) / JACOBIAN_EPSILON);
  47.189 -                Jacobian->v[2].n[j] = ((LabD.b - Lab.b) / JACOBIAN_EPSILON);
  47.190 +        Jacobian->v[0].n[j] = ((LabD.L - Lab.L) / JACOBIAN_EPSILON);
  47.191 +        Jacobian->v[1].n[j] = ((LabD.a - Lab.a) / JACOBIAN_EPSILON);
  47.192 +        Jacobian->v[2].n[j] = ((LabD.b - Lab.b) / JACOBIAN_EPSILON);
  47.193  
  47.194      }
  47.195  }
  47.196 @@ -797,18 +842,18 @@
  47.197          // Obtain slope
  47.198          ComputeJacobianLab(Lut, &Jacobian, &x, FixedK);
  47.199  
  47.200 -                // Solve system
  47.201 -                tmp2.n[0] = fx.L - Goal.L;
  47.202 -                tmp2.n[1] = fx.a - Goal.a;
  47.203 -                tmp2.n[2] = fx.b - Goal.b;
  47.204 +        // Solve system
  47.205 +        tmp2.n[0] = fx.L - Goal.L;
  47.206 +        tmp2.n[1] = fx.a - Goal.a;
  47.207 +        tmp2.n[2] = fx.b - Goal.b;
  47.208  
  47.209 -                if (!MAT3solve(&tmp, &Jacobian, &tmp2))
  47.210 -                        break;
  47.211 +        if (!MAT3solve(&tmp, &Jacobian, &tmp2))
  47.212 +            break;
  47.213  
  47.214          // Move our guess
  47.215 -                x.n[0] -= tmp.n[0];
  47.216 -            x.n[1] -= tmp.n[1];
  47.217 -                x.n[2] -= tmp.n[2];
  47.218 +        x.n[0] -= tmp.n[0];
  47.219 +        x.n[1] -= tmp.n[1];
  47.220 +        x.n[2] -= tmp.n[2];
  47.221  
  47.222          // Some clipping....
  47.223          VEC3saturate(&x);
  47.224 @@ -822,3 +867,6 @@
  47.225      return LastError;
  47.226  
  47.227  }
  47.228 +
  47.229 +
  47.230 +
    48.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c	Tue Apr 07 11:43:20 2009 -0700
    48.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsmatsh.c	Tue Apr 07 14:02:54 2009 -0700
    48.3 @@ -29,7 +29,7 @@
    48.4  //
    48.5  //
    48.6  //  Little cms
    48.7 -//  Copyright (C) 1998-2006 Marti Maria
    48.8 +//  Copyright (C) 1998-2007 Marti Maria
    48.9  //
   48.10  // Permission is hereby granted, free of charge, to any person obtaining
   48.11  // a copy of this software and associated documentation files (the "Software"),
   48.12 @@ -62,6 +62,7 @@
   48.13  // data yet in fixed point, so no additional process is required.
   48.14  // Then, we obtain data on 15.16, so we need to shift >> by 1 to
   48.15  // obtain 1.15 PCS format.
   48.16 +
   48.17  // On OUTPUT profiles, things are inverse, we must first expand 1 bit
   48.18  // by shifting left, and then convert result between 0 and 1.000 to
   48.19  // RGB, so FromFixedDomain() must be called before pass values to
   48.20 @@ -71,6 +72,7 @@
   48.21  // input is encoded from 0 to 0xffff, we must first use the shaper and
   48.22  // then the matrix, an additional FromFixedDomain() must be used to
   48.23  // accomodate output values.
   48.24 +
   48.25  // For a sake of simplicity, I will handle this three behaviours
   48.26  // with different routines, so the flags MATSHAPER_INPUT and MATSHAPER_OUTPUT
   48.27  // can be conbined to signal smelted matrix-shapers
   48.28 @@ -89,7 +91,7 @@
   48.29         {
   48.30          LPWORD PtrW;
   48.31  
   48.32 -        PtrW = (LPWORD) malloc(sizeof(WORD) * p16 -> nSamples);
   48.33 +        PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * p16 -> nSamples);
   48.34  
   48.35          if (PtrW == NULL) return -1;  // Signal error
   48.36  
   48.37 @@ -119,7 +121,7 @@
   48.38         LPMATSHAPER NewMatShaper;
   48.39         int rc;
   48.40  
   48.41 -       NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER));
   48.42 +       NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER));
   48.43         if (NewMatShaper)
   48.44                ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
   48.45  
   48.46 @@ -171,7 +173,13 @@
   48.47         LPMATSHAPER NewMatShaper;
   48.48         int i, AllLinear;
   48.49  
   48.50 -       NewMatShaper = (LPMATSHAPER) malloc(sizeof(MATSHAPER));
   48.51 +           if (Matrix == NULL) return NULL;
   48.52 +           for (i=0; i < 3; i++) {
   48.53 +
   48.54 +                   if (Tables[i] == NULL) return NULL;
   48.55 +           }
   48.56 +
   48.57 +       NewMatShaper = (LPMATSHAPER) _cmsMalloc(sizeof(MATSHAPER));
   48.58         if (NewMatShaper)
   48.59                ZeroMemory(NewMatShaper, sizeof(MATSHAPER));
   48.60  
   48.61 @@ -187,17 +195,16 @@
   48.62                       NewMatShaper -> dwFlags |= MATSHAPER_HASMATRIX;
   48.63  
   48.64         // Now, on the table characteristics
   48.65 -
   48.66         cmsCalcL16Params(Tables[0] -> nEntries, &NewMatShaper -> p16);
   48.67  
   48.68         // Copy tables
   48.69  
   48.70         AllLinear = 0;
   48.71 -       for (i=0; i < 3; i++)
   48.72 -       {
   48.73 +       for (i=0; i < 3; i++) {
   48.74 +
   48.75          LPWORD PtrW;
   48.76  
   48.77 -        PtrW = (LPWORD) malloc(sizeof(WORD) * NewMatShaper -> p16.nSamples);
   48.78 +        PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * NewMatShaper -> p16.nSamples);
   48.79  
   48.80          if (PtrW == NULL) {
   48.81                cmsFreeMatShaper(NewMatShaper);
   48.82 @@ -235,11 +242,11 @@
   48.83  
   48.84         for (i=0; i < 3; i++)
   48.85         {
   48.86 -              if (MatShaper -> L[i]) free(MatShaper ->L[i]);
   48.87 -              if (MatShaper -> L2[i]) free(MatShaper ->L2[i]);
   48.88 +              if (MatShaper -> L[i]) _cmsFree(MatShaper ->L[i]);
   48.89 +              if (MatShaper -> L2[i]) _cmsFree(MatShaper ->L2[i]);
   48.90         }
   48.91  
   48.92 -       free(MatShaper);
   48.93 +       _cmsFree(MatShaper);
   48.94  }
   48.95  
   48.96  
    49.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c	Tue Apr 07 11:43:20 2009 -0700
    49.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c	Tue Apr 07 14:02:54 2009 -0700
    49.3 @@ -29,7 +29,7 @@
    49.4  //
    49.5  //
    49.6  //  Little cms
    49.7 -//  Copyright (C) 1998-2006 Marti Maria
    49.8 +//  Copyright (C) 1998-2007 Marti Maria
    49.9  //
   49.10  // Permission is hereby granted, free of charge, to any person obtaining
   49.11  // a copy of this software and associated documentation files (the "Software"),
   49.12 @@ -71,16 +71,16 @@
   49.13  double cdecl VEC3distance(LPVEC3 a, LPVEC3 b);
   49.14  
   49.15  
   49.16 -void   cdecl MAT3identity(LPMAT3 a);
   49.17 -void   cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
   49.18 -int    cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
   49.19 -BOOL   cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
   49.20 -double cdecl MAT3det(LPMAT3 m);
   49.21 -void   cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
   49.22 -void   cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
   49.23 -void   cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v);
   49.24 -void   cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d);
   49.25 -void   cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d);
   49.26 +void      cdecl MAT3identity(LPMAT3 a);
   49.27 +void      cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
   49.28 +int       cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
   49.29 +LCMSBOOL  cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
   49.30 +double    cdecl MAT3det(LPMAT3 m);
   49.31 +void      cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
   49.32 +void      cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
   49.33 +void      cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v);
   49.34 +void      cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d);
   49.35 +void      cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d);
   49.36  
   49.37  // --------------------- Implementation ----------------------------
   49.38  
   49.39 @@ -345,13 +345,13 @@
   49.40  // Check id two vectors are the same, allowing tolerance
   49.41  
   49.42  static
   49.43 -BOOL RangeCheck(double l, double h, double v)
   49.44 +LCMSBOOL RangeCheck(double l, double h, double v)
   49.45  {
   49.46         return (v >= l && v <= h);
   49.47  }
   49.48  
   49.49  
   49.50 -BOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
   49.51 +LCMSBOOL VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance)
   49.52  {
   49.53         int i;
   49.54         double c;
   49.55 @@ -367,7 +367,7 @@
   49.56         return TRUE;
   49.57  }
   49.58  
   49.59 -BOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance)
   49.60 +LCMSBOOL VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance)
   49.61  {
   49.62         int i;
   49.63         double c;
   49.64 @@ -462,7 +462,7 @@
   49.65  
   49.66  // Check if matrix is Identity. Allow a tolerance as %
   49.67  
   49.68 -BOOL MAT3isIdentity(LPWMAT3 a, double Tolerance)
   49.69 +LCMSBOOL MAT3isIdentity(LPWMAT3 a, double Tolerance)
   49.70  {
   49.71         int i;
   49.72         MAT3 Idd;
   49.73 @@ -545,16 +545,16 @@
   49.74  
   49.75  // Solve a system in the form Ax = b
   49.76  
   49.77 -BOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b)
   49.78 +LCMSBOOL MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b)
   49.79  {
   49.80 -        MAT3 m, a_1;
   49.81 +    MAT3 m, a_1;
   49.82  
   49.83 -        CopyMemory(&m, a, sizeof(MAT3));
   49.84 +    CopyMemory(&m, a, sizeof(MAT3));
   49.85  
   49.86 -        if (!MAT3inverse(&m, &a_1)) return FALSE;  // Singular matrix
   49.87 +    if (!MAT3inverse(&m, &a_1)) return FALSE;  // Singular matrix
   49.88  
   49.89 -        MAT3eval(x, &a_1, b);
   49.90 -        return TRUE;
   49.91 +    MAT3eval(x, &a_1, b);
   49.92 +    return TRUE;
   49.93  }
   49.94  
   49.95  
   49.96 @@ -839,3 +839,7 @@
   49.97         VEC3scaleAndCut(&r -> v[1], &v -> v[1], d);
   49.98         VEC3scaleAndCut(&r -> v[2], &v -> v[2], d);
   49.99  }
  49.100 +
  49.101 +
  49.102 +
  49.103 +
    50.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c	Tue Apr 07 11:43:20 2009 -0700
    50.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c	Tue Apr 07 14:02:54 2009 -0700
    50.3 @@ -29,7 +29,7 @@
    50.4  //
    50.5  //
    50.6  //  Little cms
    50.7 -//  Copyright (C) 1998-2006 Marti Maria
    50.8 +//  Copyright (C) 1998-2007 Marti Maria
    50.9  //
   50.10  // Permission is hereby granted, free of charge, to any person obtaining
   50.11  // a copy of this software and associated documentation files (the "Software"),
   50.12 @@ -74,7 +74,7 @@
   50.13                  NewElements *= 2;
   50.14  
   50.15          size = sizeof(cmsNAMEDCOLORLIST) + (sizeof(cmsNAMEDCOLOR) * NewElements);
   50.16 -        TheNewList = (LPcmsNAMEDCOLORLIST) malloc(size);
   50.17 +        TheNewList = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
   50.18  
   50.19  
   50.20          if (TheNewList == NULL) {
   50.21 @@ -86,7 +86,7 @@
   50.22                CopyMemory(TheNewList, v, sizeof(cmsNAMEDCOLORLIST) + (v ->nColors - 1) * sizeof(cmsNAMEDCOLOR));
   50.23                TheNewList -> Allocated = NewElements;
   50.24  
   50.25 -              free(v);
   50.26 +              _cmsFree(v);
   50.27                return TheNewList;
   50.28          }
   50.29      }
   50.30 @@ -99,7 +99,7 @@
   50.31  {
   50.32      size_t size = sizeof(cmsNAMEDCOLORLIST) + (n - 1) * sizeof(cmsNAMEDCOLOR);
   50.33  
   50.34 -    LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) malloc(size);
   50.35 +    LPcmsNAMEDCOLORLIST v = (LPcmsNAMEDCOLORLIST) _cmsMalloc(size);
   50.36  
   50.37  
   50.38      if (v == NULL) {
   50.39 @@ -124,10 +124,10 @@
   50.40          return;
   50.41      }
   50.42  
   50.43 -    free(v);
   50.44 +    _cmsFree(v);
   50.45  }
   50.46  
   50.47 -BOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS])
   50.48 +LCMSBOOL cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS])
   50.49  {
   50.50      _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
   50.51      LPcmsNAMEDCOLORLIST List;
   50.52 @@ -146,6 +146,7 @@
   50.53          List ->List[List ->nColors].PCS[i] = PCS[i];
   50.54  
   50.55      strncpy(List ->List[List ->nColors].Name, Name, MAX_PATH-1);
   50.56 +    List ->List[List ->nColors].Name[MAX_PATH-1] = 0;
   50.57  
   50.58      List ->nColors++;
   50.59      return TRUE;
   50.60 @@ -164,18 +165,17 @@
   50.61  }
   50.62  
   50.63  
   50.64 -BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix)
   50.65 +LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix)
   50.66  {
   50.67      _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
   50.68  
   50.69 -
   50.70       if (v ->NamedColorList == NULL) return FALSE;
   50.71  
   50.72       if (nColor < 0 || nColor >= cmsNamedColorCount(xform)) return FALSE;
   50.73  
   50.74 -     if (Name) strncpy(Name, v ->NamedColorList->List[nColor].Name, 31);
   50.75 -     if (Prefix) strncpy(Prefix, v ->NamedColorList->Prefix, 31);
   50.76 -     if (Suffix) strncpy(Suffix, v ->NamedColorList->Suffix, 31);
   50.77 +         if (Name)   { strncpy(Name, v ->NamedColorList->List[nColor].Name, 31); Name[31] = 0; }
   50.78 +         if (Prefix) { strncpy(Prefix, v ->NamedColorList->Prefix, 31); Prefix[31] = 0; }
   50.79 +         if (Suffix) { strncpy(Suffix, v ->NamedColorList->Suffix, 31); Suffix[31] = 0; }
   50.80  
   50.81       return TRUE;
   50.82  }
   50.83 @@ -196,3 +196,5 @@
   50.84  
   50.85          return -1;
   50.86  }
   50.87 +
   50.88 +
    51.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmspack.c	Tue Apr 07 11:43:20 2009 -0700
    51.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmspack.c	Tue Apr 07 14:02:54 2009 -0700
    51.3 @@ -28,7 +28,7 @@
    51.4  // file:
    51.5  //
    51.6  //  Little cms
    51.7 -//  Copyright (C) 1998-2006 Marti Maria
    51.8 +//  Copyright (C) 1998-2007 Marti Maria
    51.9  //
   51.10  // Permission is hereby granted, free of charge, to any person obtaining
   51.11  // a copy of this software and associated documentation files (the "Software"),
   51.12 @@ -639,9 +639,81 @@
   51.13  
   51.14  
   51.15  
   51.16 +static
   51.17 +LPBYTE UnrollDouble1Chan(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
   51.18 +{
   51.19 +    double* Inks = (double*) accum;
   51.20 +    double v;
   51.21 +
   51.22 +
   51.23 +    v = floor(Inks[0] * 65535.0 + 0.5);
   51.24 +
   51.25 +    if (v > 65535.0) v = 65535.0;
   51.26 +    if (v < 0) v = 0;
   51.27 +
   51.28 +
   51.29 +    wIn[0] = wIn[1] = wIn[2] = (WORD) v;
   51.30 +
   51.31 +    return accum + sizeof(double);
   51.32 +}
   51.33 +
   51.34 +
   51.35  // ----------------------------------------------------------- Packing routines
   51.36  
   51.37  
   51.38 +// Generic N-bytes plus dither 16-to-8 conversion. Currently is just a quick hack
   51.39 +
   51.40 +static int err[MAXCHANNELS];
   51.41 +
   51.42 +static
   51.43 +LPBYTE PackNBytesDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
   51.44 +{
   51.45 +       int nChan  = T_CHANNELS(info -> OutputFormat);
   51.46 +       register int i;
   51.47 +       unsigned int n, pe, pf;
   51.48 +
   51.49 +       for (i=0; i < nChan;  i++) {
   51.50 +
   51.51 +              n = wOut[i] + err[i]; // Value
   51.52 +
   51.53 +              pe = (n / 257);       // Whole part
   51.54 +              pf = (n % 257);       // Fractional part
   51.55 +
   51.56 +              err[i] = pf;          // Store it for next pixel
   51.57 +
   51.58 +              *output++ = (BYTE) pe;
   51.59 +       }
   51.60 +
   51.61 +       return output + T_EXTRA(info ->OutputFormat);
   51.62 +}
   51.63 +
   51.64 +
   51.65 +
   51.66 +static
   51.67 +LPBYTE PackNBytesSwapDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
   51.68 +{
   51.69 +       int nChan  = T_CHANNELS(info -> OutputFormat);
   51.70 +       register int i;
   51.71 +       unsigned int n, pe, pf;
   51.72 +
   51.73 +       for (i=nChan-1; i >= 0;  --i) {
   51.74 +
   51.75 +              n = wOut[i] + err[i];     // Value
   51.76 +
   51.77 +              pe = (n / 257);           // Whole part
   51.78 +              pf = (n % 257);           // Fractional part
   51.79 +
   51.80 +              err[i] = pf;              // Store it for next pixel
   51.81 +
   51.82 +              *output++ = (BYTE) pe;
   51.83 +       }
   51.84 +
   51.85 +
   51.86 +       return output + T_EXTRA(info ->OutputFormat);
   51.87 +}
   51.88 +
   51.89 +
   51.90 +
   51.91  // Generic chunky for byte
   51.92  
   51.93  static
   51.94 @@ -1486,7 +1558,10 @@
   51.95             case PT_HSV:
   51.96             case PT_HLS:
   51.97             case PT_Yxy:
   51.98 -                    FromInput = UnrollDouble;
   51.99 +                    if (T_CHANNELS(dwInput) == 1)
  51.100 +                        FromInput = UnrollDouble1Chan;
  51.101 +                    else
  51.102 +                        FromInput = UnrollDouble;
  51.103                      break;
  51.104  
  51.105              // Inks (%) 0.0 .. 100.0
  51.106 @@ -1749,6 +1824,9 @@
  51.107                       switch (T_CHANNELS(dwOutput))
  51.108                       {
  51.109                       case 1:
  51.110 +                            if (T_DITHER(dwOutput))
  51.111 +                                    ToOutput = PackNBytesDither;
  51.112 +                            else
  51.113                              ToOutput = Pack1Byte;
  51.114                              if (T_EXTRA(dwOutput) == 1) {
  51.115                                  if (T_SWAPFIRST(dwOutput))
  51.116 @@ -1766,8 +1844,12 @@
  51.117                                   else
  51.118                                       if (T_COLORSPACE(dwOutput) == PT_Lab)
  51.119                                          ToOutput = Pack3BytesLab;
  51.120 +                                     else {
  51.121 +                                         if (T_DITHER(dwOutput))
  51.122 +                                                 ToOutput = PackNBytesDither;
  51.123                                       else
  51.124                                          ToOutput = Pack3Bytes;
  51.125 +                                     }
  51.126                               break;
  51.127  
  51.128                           case 1:    // TODO: ALab8 should be handled here
  51.129 @@ -1793,13 +1875,23 @@
  51.130  
  51.131                       case 4: if (T_EXTRA(dwOutput) == 0) {
  51.132  
  51.133 +
  51.134                                  if (T_DOSWAP(dwOutput)) {
  51.135  
  51.136 -                                     if (T_SWAPFIRST(dwOutput))
  51.137 +
  51.138 +                                     if (T_SWAPFIRST(dwOutput)) {
  51.139                                           ToOutput = Pack4BytesSwapSwapFirst;
  51.140 -                                     else
  51.141 +                                     }
  51.142 +                                     else {
  51.143 +
  51.144 +                                           if (T_DITHER(dwOutput)) {
  51.145 +                                                  ToOutput = PackNBytesSwapDither;
  51.146 +                                           }
  51.147 +                                           else {
  51.148                                           ToOutput = Pack4BytesSwap;
  51.149                                   }
  51.150 +                                     }
  51.151 +                                 }
  51.152                                   else {
  51.153                                       if (T_SWAPFIRST(dwOutput))
  51.154                                           ToOutput = Pack4BytesSwapFirst;
  51.155 @@ -1807,11 +1899,15 @@
  51.156  
  51.157                                           if (T_FLAVOR(dwOutput))
  51.158                                               ToOutput = Pack4BytesReverse;
  51.159 +                                         else {
  51.160 +                                             if (T_DITHER(dwOutput))
  51.161 +                                                 ToOutput = PackNBytesDither;
  51.162                                           else
  51.163                                               ToOutput = Pack4Bytes;
  51.164                                       }
  51.165                                   }
  51.166                               }
  51.167 +                             }
  51.168                              else {
  51.169                                      if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
  51.170                                               ToOutput = PackNBytes;
  51.171 @@ -1833,7 +1929,7 @@
  51.172                              }
  51.173                              break;
  51.174  
  51.175 -                                         case 2:
  51.176 +                     case 2:
  51.177                       case 5:
  51.178                       case 7:
  51.179                       case 8:
  51.180 @@ -1849,8 +1945,13 @@
  51.181                              {
  51.182                                     if (T_DOSWAP(dwOutput))
  51.183                                            ToOutput = PackNBytesSwap;
  51.184 +                                   else {
  51.185 +
  51.186 +                                       if (T_DITHER(dwOutput))
  51.187 +                                                 ToOutput = PackNBytesDither;
  51.188                                     else
  51.189                                            ToOutput = PackNBytes;
  51.190 +                                   }
  51.191                              }
  51.192                              break;
  51.193  
  51.194 @@ -1984,7 +2085,7 @@
  51.195                              break;
  51.196  
  51.197  
  51.198 -                                         case 2:
  51.199 +                     case 2:
  51.200                       case 5:
  51.201                       case 7:
  51.202                       case 8:
    52.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmspcs.c	Tue Apr 07 11:43:20 2009 -0700
    52.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmspcs.c	Tue Apr 07 14:02:54 2009 -0700
    52.3 @@ -29,7 +29,7 @@
    52.4  //
    52.5  //
    52.6  //  Little cms
    52.7 -//  Copyright (C) 1998-2006 Marti Maria
    52.8 +//  Copyright (C) 1998-2007 Marti Maria
    52.9  //
   52.10  // Permission is hereby granted, free of charge, to any person obtaining
   52.11  // a copy of this software and associated documentation files (the "Software"),
   52.12 @@ -624,3 +624,7 @@
   52.13      fXYZ -> Z = XYZ2float(XYZ[2]);
   52.14  
   52.15  }
   52.16 +
   52.17 +
   52.18 +
   52.19 +
    53.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsps2.c	Tue Apr 07 11:43:20 2009 -0700
    53.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsps2.c	Tue Apr 07 14:02:54 2009 -0700
    53.3 @@ -29,7 +29,7 @@
    53.4  //
    53.5  //
    53.6  //  Little cms
    53.7 -//  Copyright (C) 1998-2006 Marti Maria
    53.8 +//  Copyright (C) 1998-2007 Marti Maria
    53.9  //
   53.10  // Permission is hereby granted, free of charge, to any person obtaining
   53.11  // a copy of this software and associated documentation files (the "Software"),
   53.12 @@ -144,6 +144,8 @@
   53.13              /Table [ p p p [<...>]]
   53.14              /RangeABC [ 0 1 0 1 0 1]
   53.15              /DecodeABC[ <postlinearization> ]
   53.16 +            /RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]
   53.17 +               % -128/500 1+127/500 0 1  -127/200 1+128/200
   53.18              /MatrixABC [ 1 1 1 1 0 0 0 0 -1]
   53.19              /WhitePoint [D50]
   53.20              /BlackPoint [BP]
   53.21 @@ -347,7 +349,8 @@
   53.22  static
   53.23  LPMEMSTREAM CreateMemStream(LPBYTE Buffer, DWORD dwMax, int MaxCols)
   53.24  {
   53.25 -    LPMEMSTREAM m = (LPMEMSTREAM) malloc(sizeof(MEMSTREAM));
   53.26 +    LPMEMSTREAM m = (LPMEMSTREAM) _cmsMalloc(sizeof(MEMSTREAM));
   53.27 +    if (m == NULL) return NULL;
   53.28  
   53.29      ZeroMemory(m, sizeof(MEMSTREAM));
   53.30  
   53.31 @@ -376,9 +379,9 @@
   53.32  static
   53.33  BYTE L2Byte(WORD w)
   53.34  {
   53.35 -        int ww = w + 0x0080;
   53.36 +    int ww = w + 0x0080;
   53.37  
   53.38 -        if (ww > 0xFFFF) return 0xFF;
   53.39 +    if (ww > 0xFFFF) return 0xFF;
   53.40  
   53.41      return (BYTE) ((WORD) (ww >> 8) & 0xFF);
   53.42  }
   53.43 @@ -387,7 +390,6 @@
   53.44  static
   53.45  void WriteRawByte(LPMEMSTREAM m, BYTE b)
   53.46  {
   53.47 -
   53.48      if (m -> dwUsed + 1 > m -> dwMax) {
   53.49          m -> HasError = 1;
   53.50      }
   53.51 @@ -422,7 +424,7 @@
   53.52  
   53.53  }
   53.54  
   53.55 -// Does write a formatted string
   53.56 +// Does write a formatted string. Guaranteed to be 2048 bytes at most.
   53.57  static
   53.58  void Writef(LPMEMSTREAM m, const char *frm, ...)
   53.59  {
   53.60 @@ -432,7 +434,7 @@
   53.61  
   53.62          va_start(args, frm);
   53.63  
   53.64 -        vsprintf((char*) Buffer, frm, args);
   53.65 +        vsnprintf((char*) Buffer, 2048, frm, args);
   53.66  
   53.67          for (pt = Buffer; *pt; pt++)  {
   53.68  
   53.69 @@ -562,7 +564,7 @@
   53.70      Writef(m, "{255 mul 128 sub 200 div } bind\n");
   53.71      Writef(m, "]\n");
   53.72      Writef(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n");
   53.73 -        Writef(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
   53.74 +    Writef(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n");
   53.75      Writef(m, "/DecodeLMN [\n");
   53.76      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");
   53.77      Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n");
   53.78 @@ -584,7 +586,11 @@
   53.79      if (nEntries <= 0) return;  // Empty table
   53.80  
   53.81      // Suppress whole if identity
   53.82 -    if (cmsIsLinear(Table, nEntries)) return;
   53.83 +    if (cmsIsLinear(Table, nEntries)) {
   53.84 +            Writef(m, "{} ");
   53.85 +            return;
   53.86 +    }
   53.87 +
   53.88  
   53.89      // Check if is really an exponential. If so, emit "exp"
   53.90       gamma = cmsEstimateGammaEx(Table, nEntries, 0.001);
   53.91 @@ -646,7 +652,7 @@
   53.92  // Compare gamma table
   53.93  
   53.94  static
   53.95 -BOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries)
   53.96 +LCMSBOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries)
   53.97  {
   53.98      return memcmp(g1, g2, nEntries* sizeof(WORD)) == 0;
   53.99  }
  53.100 @@ -676,7 +682,7 @@
  53.101  // Check whatever a profile has CLUT tables (only on input)
  53.102  
  53.103  static
  53.104 -BOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
  53.105 +LCMSBOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
  53.106  {
  53.107      icTagSignature Tag;
  53.108  
  53.109 @@ -718,10 +724,10 @@
  53.110  
  53.111      if (sc -> FixWhite) {
  53.112  
  53.113 -        if (In[0] == 0xFFFF) {  // Only in L* = 100
  53.114 +        if (In[0] == 0xFFFF) {  // Only in L* = 100, ab = [-8..8]
  53.115  
  53.116 -            if ((In[1] >= 0x8000 && In[1] <= 0x87FF) ||
  53.117 -                (In[2] >= 0x8000 && In[2] <= 0x87FF)) {
  53.118 +            if ((In[1] >= 0x7800 && In[1] <= 0x8800) &&
  53.119 +                (In[2] >= 0x7800 && In[2] <= 0x8800)) {
  53.120  
  53.121                  WORD* Black;
  53.122                  WORD* White;
  53.123 @@ -829,8 +835,8 @@
  53.124      sc.PreMaj = PreMaj;
  53.125      sc.PostMaj= PostMaj;
  53.126  
  53.127 -    sc.PreMin = PreMin;
  53.128 -    sc.PostMin= PostMin;
  53.129 +    sc.PreMin   = PreMin;
  53.130 +    sc.PostMin  = PostMin;
  53.131      sc.lIsInput = lIsInput;
  53.132      sc.FixWhite = FixWhite;
  53.133      sc.ColorSpace = ColorSpace;
  53.134 @@ -1231,7 +1237,7 @@
  53.135  
  53.136          if (!WriteNamedColorCSA(mem, hProfile, Intent)) {
  53.137  
  53.138 -                    free((void*) mem);
  53.139 +                    _cmsFree((void*) mem);
  53.140                      return 0;
  53.141          }
  53.142      }
  53.143 @@ -1246,7 +1252,7 @@
  53.144          ColorSpace != icSigLabData) {
  53.145  
  53.146              cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space");
  53.147 -            free((void*) mem);
  53.148 +            _cmsFree((void*) mem);
  53.149              return 0;
  53.150      }
  53.151  
  53.152 @@ -1256,7 +1262,7 @@
  53.153          // Yes, so handle as LUT-based
  53.154          if (!WriteInputLUT(mem, hProfile, Intent)) {
  53.155  
  53.156 -                    free((void*) mem);
  53.157 +                    _cmsFree((void*) mem);
  53.158                      return 0;
  53.159          }
  53.160      }
  53.161 @@ -1266,7 +1272,7 @@
  53.162  
  53.163          if (!WriteInputMatrixShaper(mem, hProfile)) {
  53.164  
  53.165 -                    free((void*) mem);  // Something went wrong
  53.166 +                    _cmsFree((void*) mem);  // Something went wrong
  53.167                      return 0;
  53.168          }
  53.169      }
  53.170 @@ -1277,7 +1283,7 @@
  53.171      dwBytesUsed = mem ->dwUsed;
  53.172  
  53.173      // Get rid of memory stream
  53.174 -    free((void*) mem);
  53.175 +    _cmsFree((void*) mem);
  53.176  
  53.177      // Finally, return used byte count
  53.178      return dwBytesUsed;
  53.179 @@ -1350,27 +1356,40 @@
  53.180  
  53.181  
  53.182  static
  53.183 -void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute)
  53.184 +void EmitPQRStage(LPMEMSTREAM m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute)
  53.185  {
  53.186  
  53.187  
  53.188 +        if (lIsAbsolute) {
  53.189 +
  53.190 +            // For absolute colorimetric intent, encode back to relative
  53.191 +            // and generate a relative LUT
  53.192 +
  53.193 +            // Relative encoding is obtained across XYZpcs*(D50/WhitePoint)
  53.194 +
  53.195 +            cmsCIEXYZ White;
  53.196 +
  53.197 +            cmsTakeMediaWhitePoint(&White, hProfile);
  53.198 +
  53.199 +            Writef(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n");
  53.200 +            Writef(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
  53.201 +
  53.202 +            Writef(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n"
  53.203 +                      "/TransformPQR [\n"
  53.204 +                      "{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n"
  53.205 +                      "{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n"
  53.206 +                      "{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n",
  53.207 +                      White.X, White.Y, White.Z);
  53.208 +            return;
  53.209 +        }
  53.210 +
  53.211 +
  53.212          Writef(m,"%% Bradford Cone Space\n"
  53.213                   "/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n");
  53.214  
  53.215          Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
  53.216  
  53.217  
  53.218 -        if (lIsAbsolute) {
  53.219 -
  53.220 -            // For absolute colorimetric intent, do nothing
  53.221 -
  53.222 -            Writef(m, "%% Absolute colorimetric -- no transformation\n"
  53.223 -                      "/TransformPQR [\n"
  53.224 -                      "{exch pop exch pop exch pop exch pop} bind dup dup]\n");
  53.225 -            return;
  53.226 -        }
  53.227 -
  53.228 -
  53.229          // No BPC
  53.230  
  53.231          if (!DoBPC) {
  53.232 @@ -1414,6 +1433,7 @@
  53.233  static
  53.234  void EmitXYZ2Lab(LPMEMSTREAM m)
  53.235  {
  53.236 +    Writef(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n");
  53.237      Writef(m, "/EncodeLMN [\n");
  53.238      Writef(m, "{ 0.964200  div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
  53.239      Writef(m, "{ 1.000000  div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
  53.240 @@ -1423,17 +1443,10 @@
  53.241      Writef(m, "/EncodeABC [\n");
  53.242  
  53.243  
  53.244 +    Writef(m, "{ 116 mul  16 sub 100 div  } bind\n");
  53.245 +    Writef(m, "{ 500 mul 128 add 256 div  } bind\n");
  53.246 +    Writef(m, "{ 200 mul 128 add 256 div  } bind\n");
  53.247  
  53.248 -    Writef(m, "{ 116 mul  16 sub 100 div  } bind\n");
  53.249 -    Writef(m, "{ 500 mul 128 add 255 div  } bind\n");
  53.250 -    Writef(m, "{ 200 mul 128 add 255 div  } bind\n");
  53.251 -
  53.252 -
  53.253 -    /*
  53.254 -    Writef(m, "{ 116 mul  16 sub 256 mul 25700 div  } bind\n");
  53.255 -    Writef(m, "{ 500 mul 128 add 256 mul 65535 div  } bind\n");
  53.256 -    Writef(m, "{ 200 mul 128 add 256 mul 65535 div  } bind\n");
  53.257 -    */
  53.258  
  53.259      Writef(m, "]\n");
  53.260  
  53.261 @@ -1458,20 +1471,27 @@
  53.262      LPLUT DeviceLink;
  53.263      cmsHPROFILE Profiles[3];
  53.264      cmsCIEXYZ BlackPointAdaptedToD50;
  53.265 -    BOOL lFreeDeviceLink = FALSE;
  53.266 -    BOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
  53.267 +    LCMSBOOL lFreeDeviceLink = FALSE;
  53.268 +    LCMSBOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
  53.269 +    LCMSBOOL lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
  53.270 +    int RelativeEncodingIntent;
  53.271  
  53.272  
  53.273 -    // Trick our v4 profile as it were v2. This prevents the ajusting done
  53.274 -    // in perceptual & saturation. We only neew v4 encoding!
  53.275  
  53.276 -    hLab         = cmsCreateLab4Profile(NULL);
  53.277 -    cmsSetProfileICCversion(hLab, 0);
  53.278 +    hLab = cmsCreateLabProfile(NULL);
  53.279  
  53.280      ColorSpace  =  cmsGetColorSpace(hProfile);
  53.281      nChannels   = _cmsChannelsOf(ColorSpace);
  53.282      OutputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2);
  53.283  
  53.284 +    // For absolute colorimetric, the LUT is encoded as relative
  53.285 +    // in order to preserve precission.
  53.286 +
  53.287 +    RelativeEncodingIntent = Intent;
  53.288 +    if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC)
  53.289 +        RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC;
  53.290 +
  53.291 +
  53.292      // Is a devicelink profile?
  53.293      if (cmsGetDeviceClass(hProfile) == icSigLinkClass) {
  53.294  
  53.295 @@ -1479,13 +1499,14 @@
  53.296  
  53.297          if (ColorSpace == icSigLabData) {
  53.298  
  53.299 -              // adjust input to Lab to out v4
  53.300 +              // adjust input to Lab to our v4
  53.301  
  53.302              Profiles[0] = hLab;
  53.303              Profiles[1] = hProfile;
  53.304  
  53.305              xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL,
  53.306 -                                                        OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION);
  53.307 +                                                        OutputFormat, RelativeEncodingIntent,
  53.308 +                                                        dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
  53.309  
  53.310          }
  53.311          else {
  53.312 @@ -1499,7 +1520,7 @@
  53.313  
  53.314          // This is a normal profile
  53.315          xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile,
  53.316 -                            OutputFormat, Intent, cmsFLAGS_NOPRELINEARIZATION);
  53.317 +                            OutputFormat, RelativeEncodingIntent, dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
  53.318      }
  53.319  
  53.320      if (xform == NULL) {
  53.321 @@ -1515,7 +1536,7 @@
  53.322  
  53.323      if (!DeviceLink) {
  53.324  
  53.325 -        DeviceLink = _cmsPrecalculateDeviceLink(xform, 0);
  53.326 +        DeviceLink = _cmsPrecalculateDeviceLink(xform, cmsFLAGS_NOPRELINEARIZATION);
  53.327          lFreeDeviceLink = TRUE;
  53.328      }
  53.329  
  53.330 @@ -1527,7 +1548,7 @@
  53.331  
  53.332      // Emit headers, etc.
  53.333      EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
  53.334 -    EmitPQRStage(m, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
  53.335 +    EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
  53.336      EmitXYZ2Lab(m);
  53.337  
  53.338      if (DeviceLink ->wFlags & LUT_HASTL1) {
  53.339 @@ -1544,10 +1565,13 @@
  53.340      // zero. This would sacrifice a bit of highlights, but failure to do so would cause
  53.341      // scum dot. Ouch.
  53.342  
  53.343 +    if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
  53.344 +            lFixWhite = FALSE;
  53.345 +
  53.346      Writef(m, "/RenderTable ");
  53.347  
  53.348      WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE,
  53.349 -                (Intent != INTENT_ABSOLUTE_COLORIMETRIC), ColorSpace);
  53.350 +                lFixWhite, ColorSpace);
  53.351  
  53.352      Writef(m, " %d {} bind ", nChannels);
  53.353  
  53.354 @@ -1582,6 +1606,9 @@
  53.355      int j;
  53.356  
  53.357      Colorant[0] = 0;
  53.358 +    if (nColorant > MAXCHANNELS)
  53.359 +        nColorant = MAXCHANNELS;
  53.360 +
  53.361      for (j=0; j < nColorant; j++) {
  53.362  
  53.363                  sprintf(Buff, "%.3f", Out[j] / 65535.0);
  53.364 @@ -1677,7 +1704,7 @@
  53.365  
  53.366          if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) {
  53.367  
  53.368 -                    free((void*) mem);
  53.369 +                    _cmsFree((void*) mem);
  53.370                      return 0;
  53.371          }
  53.372      }
  53.373 @@ -1687,7 +1714,7 @@
  53.374  
  53.375  
  53.376      if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
  53.377 -        free((void*) mem);
  53.378 +        _cmsFree((void*) mem);
  53.379          return 0;
  53.380      }
  53.381      }
  53.382 @@ -1702,7 +1729,7 @@
  53.383      dwBytesUsed = mem ->dwUsed;
  53.384  
  53.385      // Get rid of memory stream
  53.386 -    free((void*) mem);
  53.387 +    _cmsFree((void*) mem);
  53.388  
  53.389      // Finally, return used byte count
  53.390      return dwBytesUsed;
    54.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmssamp.c	Tue Apr 07 11:43:20 2009 -0700
    54.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmssamp.c	Tue Apr 07 14:02:54 2009 -0700
    54.3 @@ -29,7 +29,7 @@
    54.4  //
    54.5  //
    54.6  //  Little cms
    54.7 -//  Copyright (C) 1998-2006 Marti Maria
    54.8 +//  Copyright (C) 1998-2007 Marti Maria
    54.9  //
   54.10  // Permission is hereby granted, free of charge, to any person obtaining
   54.11  // a copy of this software and associated documentation files (the "Software"),
   54.12 @@ -120,7 +120,7 @@
   54.13  // This routine does a sweep on whole input space, and calls its callback
   54.14  // function on knots. returns TRUE if all ok, FALSE otherwise.
   54.15  
   54.16 -BOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags)
   54.17 +LCMSBOOL LCMSEXPORT cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags)
   54.18  {
   54.19     int i, t, nTotalPoints, Colorant, index;
   54.20     WORD In[MAXCHANNELS], Out[MAXCHANNELS];
   54.21 @@ -145,12 +145,16 @@
   54.22                                                  &Lut -> In16params);
   54.23          }
   54.24  
   54.25 +        for (t=0; t < (int) Lut -> OutputChan; t++)
   54.26 +                     Out[t] = Lut->T[index + t];
   54.27  
   54.28 -        // if (dwFlags & SAMPLER_INSPECT) {
   54.29 +        if (dwFlags & SAMPLER_HASTL2) {
   54.30  
   54.31               for (t=0; t < (int) Lut -> OutputChan; t++)
   54.32 -                        Out[t] = Lut->T[index + t];
   54.33 -        // }
   54.34 +                     Out[t] = cmsLinearInterpLUT16(Out[t],
   54.35 +                                                   Lut -> L2[t],
   54.36 +                                                   &Lut -> Out16params);
   54.37 +        }
   54.38  
   54.39  
   54.40          if (!Sampler(In, Out, Cargo))
   54.41 @@ -255,9 +259,11 @@
   54.42         LPLUT Grid;
   54.43         int nGridPoints;
   54.44         DWORD dwFormatIn, dwFormatOut;
   54.45 +       DWORD SaveFormatIn, SaveFormatOut;
   54.46         int ChannelsIn, ChannelsOut;
   54.47         LPLUT SaveGamutLUT;
   54.48  
   54.49 +
   54.50         // Remove any gamut checking
   54.51         SaveGamutLUT = p ->Gamut;
   54.52         p ->Gamut = NULL;
   54.53 @@ -276,8 +282,13 @@
   54.54         dwFormatIn   = (CHANNELS_SH(ChannelsIn)|BYTES_SH(2));
   54.55         dwFormatOut  = (CHANNELS_SH(ChannelsOut)|BYTES_SH(2));
   54.56  
   54.57 -       p -> FromInput = _cmsIdentifyInputFormat(p, dwFormatIn);
   54.58 -       p -> ToOutput  = _cmsIdentifyOutputFormat(p, dwFormatOut);
   54.59 +       SaveFormatIn  = p ->InputFormat;
   54.60 +       SaveFormatOut = p ->OutputFormat;
   54.61 +
   54.62 +       p -> InputFormat  = dwFormatIn;
   54.63 +       p -> OutputFormat = dwFormatOut;
   54.64 +       p -> FromInput    = _cmsIdentifyInputFormat(p, dwFormatIn);
   54.65 +       p -> ToOutput     = _cmsIdentifyOutputFormat(p, dwFormatOut);
   54.66  
   54.67         // Fix gamut & gamma possible mismatches.
   54.68  
   54.69 @@ -289,7 +300,6 @@
   54.70             _cmsComputePrelinearizationTablesFromXFORM(hOne, 1, Grid);
   54.71         }
   54.72  
   54.73 -
   54.74         // Attention to this typecast! we can take the luxury to
   54.75         // do this since cmsHTRANSFORM is only an alias to a pointer
   54.76         // to the transform struct.
   54.77 @@ -297,11 +307,13 @@
   54.78         if (!cmsSample3DGrid(Grid, XFormSampler, (LPVOID) p, Grid -> wFlags)) {
   54.79  
   54.80                  cmsFreeLUT(Grid);
   54.81 -                return NULL;
   54.82 +                Grid = NULL;
   54.83         }
   54.84  
   54.85 +       p ->Gamut        = SaveGamutLUT;
   54.86 +       p ->InputFormat  = SaveFormatIn;
   54.87 +       p ->OutputFormat = SaveFormatOut;
   54.88  
   54.89 -       p ->Gamut = SaveGamutLUT;
   54.90         return Grid;
   54.91  }
   54.92  
   54.93 @@ -348,7 +360,7 @@
   54.94  
   54.95  
   54.96  
   54.97 -// That is our K-preserving callback.
   54.98 +// Preserve all K plane.
   54.99  static
  54.100  int BlackPreservingSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
  54.101  {
  54.102 @@ -469,6 +481,7 @@
  54.103      return OldVal;
  54.104  }
  54.105  
  54.106 +#pragma warning(disable: 4550)
  54.107  
  54.108  // Get a pointer to callback on depending of strategy
  54.109  static
  54.110 @@ -504,11 +517,10 @@
  54.111         if (p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)
  54.112             LocalFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
  54.113  
  54.114 -
  54.115         // Fill in cargo struct
  54.116         Cargo.cmyk2cmyk = hCMYK2CMYK;
  54.117  
  54.118 -       // Compute tone curve
  54.119 +       // Compute tone curve.
  54.120         Cargo.KTone  =  _cmsBuildKToneCurve(hCMYK2CMYK, 256);
  54.121         if (Cargo.KTone == NULL) return NULL;
  54.122         cmsCalcL16Params(Cargo.KTone ->nEntries, &Cargo.KToneParams);
  54.123 @@ -522,11 +534,11 @@
  54.124         Cargo.LabK2cmyk = cmsReadICCLut(p->OutputProfile, Device2PCS[p->Intent]);
  54.125  
  54.126         // Is there any table available?
  54.127 -           if (Cargo.LabK2cmyk == NULL) {
  54.128 +       if (Cargo.LabK2cmyk == NULL) {
  54.129  
  54.130 -                   Grid = NULL;
  54.131 +           Grid = NULL;
  54.132             goto Cleanup;
  54.133 -           }
  54.134 +       }
  54.135  
  54.136         // Setup a roundtrip on output profile for TAC estimation
  54.137         Cargo.hRoundTrip = cmsCreateTransform(p ->OutputProfile, TYPE_CMYK_16,
  54.138 @@ -654,7 +666,7 @@
  54.139  
  54.140  
  54.141  
  54.142 -BOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p)
  54.143 +LCMSBOOL _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p)
  54.144  {
  54.145  
  54.146         WORD *WhitePointIn, *WhitePointOut, *BlackPointIn, *BlackPointOut;
  54.147 @@ -682,3 +694,4 @@
  54.148  
  54.149         return TRUE;
  54.150  }
  54.151 +
    55.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c	Tue Apr 07 11:43:20 2009 -0700
    55.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c	Tue Apr 07 14:02:54 2009 -0700
    55.3 @@ -29,7 +29,7 @@
    55.4  //
    55.5  //
    55.6  //  Little cms
    55.7 -//  Copyright (C) 1998-2006 Marti Maria
    55.8 +//  Copyright (C) 1998-2007 Marti Maria
    55.9  //
   55.10  // Permission is hereby granted, free of charge, to any person obtaining
   55.11  // a copy of this software and associated documentation files (the "Software"),
   55.12 @@ -320,7 +320,7 @@
   55.13      cmsHPROFILE hICC;
   55.14      _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) hTransform;
   55.15      LPLUT Lut;
   55.16 -    BOOL MustFreeLUT;
   55.17 +    LCMSBOOL MustFreeLUT;
   55.18      LPcmsNAMEDCOLORLIST InputColorant = NULL;
   55.19      LPcmsNAMEDCOLORLIST OutputColorant = NULL;
   55.20  
   55.21 @@ -373,10 +373,8 @@
   55.22  
   55.23      if (cmsGetDeviceClass(hICC) == icSigOutputClass) {
   55.24  
   55.25 -
   55.26          cmsAddTag(hICC, icSigBToA0Tag, (LPVOID) Lut);
   55.27      }
   55.28 -
   55.29      else
   55.30          cmsAddTag(hICC, icSigAToB0Tag, (LPVOID) Lut);
   55.31  
   55.32 @@ -404,7 +402,7 @@
   55.33  
   55.34              OutputColorant = cmsReadColorantTable(v ->OutputProfile, icSigColorantTableTag);
   55.35          }
   55.36 -        }
   55.37 +    }
   55.38  
   55.39      if (InputColorant)
   55.40             cmsAddTag(hICC, icSigColorantTableTag, InputColorant);
   55.41 @@ -446,6 +444,7 @@
   55.42  
   55.43         // Creates a LUT with prelinearization step only
   55.44         Lut = cmsAllocLUT();
   55.45 +       if (Lut == NULL) return NULL;
   55.46  
   55.47         // Set up channels
   55.48         Lut ->InputChan = Lut ->OutputChan = _cmsChannelsOf(ColorSpace);
   55.49 @@ -548,6 +547,10 @@
   55.50  
   55.51         // Creates a LUT with 3D grid only
   55.52         Lut = cmsAllocLUT();
   55.53 +       if (Lut == NULL) {
   55.54 +           cmsCloseProfile(hICC);
   55.55 +           return NULL;
   55.56 +           }
   55.57  
   55.58  
   55.59         cmsAlloc3DGrid(Lut, 17, _cmsChannelsOf(ColorSpace),
   55.60 @@ -584,8 +587,9 @@
   55.61  LPLUT Create3x3EmptyLUT(void)
   55.62  {
   55.63          LPLUT AToB0 = cmsAllocLUT();
   55.64 +        if (AToB0 == NULL) return NULL;
   55.65 +
   55.66          AToB0 -> InputChan = AToB0 -> OutputChan = 3;
   55.67 -
   55.68          return AToB0;
   55.69  }
   55.70  
   55.71 @@ -597,8 +601,8 @@
   55.72          cmsHPROFILE hProfile;
   55.73          LPLUT Lut;
   55.74  
   55.75 -
   55.76          hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
   55.77 +        if (hProfile == NULL) return NULL;
   55.78  
   55.79          cmsSetDeviceClass(hProfile, icSigAbstractClass);
   55.80          cmsSetColorSpace(hProfile,  icSigLabData);
   55.81 @@ -611,7 +615,10 @@
   55.82  
   55.83         // An empty LUTs is all we need
   55.84         Lut = Create3x3EmptyLUT();
   55.85 -       if (Lut == NULL) return NULL;
   55.86 +       if (Lut == NULL) {
   55.87 +           cmsCloseProfile(hProfile);
   55.88 +           return NULL;
   55.89 +           }
   55.90  
   55.91         cmsAddTag(hProfile, icSigAToB0Tag,    (LPVOID) Lut);
   55.92         cmsAddTag(hProfile, icSigBToA0Tag,    (LPVOID) Lut);
   55.93 @@ -628,8 +635,8 @@
   55.94          cmsHPROFILE hProfile;
   55.95          LPLUT Lut;
   55.96  
   55.97 -
   55.98          hProfile = cmsCreateRGBProfile(WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
   55.99 +        if (hProfile == NULL) return NULL;
  55.100  
  55.101          cmsSetProfileICCversion(hProfile, 0x4000000);
  55.102  
  55.103 @@ -644,7 +651,10 @@
  55.104  
  55.105         // An empty LUTs is all we need
  55.106         Lut = Create3x3EmptyLUT();
  55.107 -       if (Lut == NULL) return NULL;
  55.108 +       if (Lut == NULL) {
  55.109 +           cmsCloseProfile(hProfile);
  55.110 +           return NULL;
  55.111 +           }
  55.112  
  55.113         Lut -> wFlags |= LUT_V4_INPUT_EMULATE_V2;
  55.114         cmsAddTag(hProfile, icSigAToB0Tag,    (LPVOID) Lut);
  55.115 @@ -666,6 +676,7 @@
  55.116          LPLUT Lut;
  55.117  
  55.118          hProfile = cmsCreateRGBProfile(cmsD50_xyY(), NULL, NULL);
  55.119 +        if (hProfile == NULL) return NULL;
  55.120  
  55.121          cmsSetDeviceClass(hProfile, icSigAbstractClass);
  55.122          cmsSetColorSpace(hProfile, icSigXYZData);
  55.123 @@ -677,15 +688,16 @@
  55.124  
  55.125         // An empty LUTs is all we need
  55.126         Lut = Create3x3EmptyLUT();
  55.127 -       if (Lut == NULL) return NULL;
  55.128 +       if (Lut == NULL) {
  55.129 +           cmsCloseProfile(hProfile);
  55.130 +           return NULL;
  55.131 +           }
  55.132  
  55.133         cmsAddTag(hProfile, icSigAToB0Tag,    (LPVOID) Lut);
  55.134         cmsAddTag(hProfile, icSigBToA0Tag,    (LPVOID) Lut);
  55.135         cmsAddTag(hProfile, icSigPreview0Tag, (LPVOID) Lut);
  55.136  
  55.137         cmsFreeLUT(Lut);
  55.138 -
  55.139 -
  55.140         return hProfile;
  55.141  }
  55.142  
  55.143 @@ -723,6 +735,7 @@
  55.144      return cmsBuildParametricGamma(1024, 4, Parameters);
  55.145  }
  55.146  
  55.147 +// Create the ICC virtual profile for sRGB space
  55.148  cmsHPROFILE LCMSEXPORT cmsCreate_sRGBProfile(void)
  55.149  {
  55.150         cmsCIExyY       D65;
  55.151 @@ -739,6 +752,7 @@
  55.152  
  55.153         hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma22);
  55.154         cmsFreeGamma(Gamma22[0]);
  55.155 +       if (hsRGB == NULL) return NULL;
  55.156  
  55.157  
  55.158         cmsAddTag(hsRGB, icSigDeviceMfgDescTag,      (LPVOID) "(lcms internal)");
  55.159 @@ -750,7 +764,6 @@
  55.160  
  55.161  
  55.162  
  55.163 -
  55.164  typedef struct {
  55.165                  double Brightness;
  55.166                  double Contrast;
  55.167 @@ -793,7 +806,6 @@
  55.168  
  55.169      cmsFloat2LabEncoded(Out, &LabOut);
  55.170  
  55.171 -
  55.172      return TRUE;
  55.173  }
  55.174  
  55.175 @@ -839,7 +851,10 @@
  55.176  
  55.177         // Creates a LUT with 3D grid only
  55.178         Lut = cmsAllocLUT();
  55.179 -
  55.180 +       if (Lut == NULL) {
  55.181 +           cmsCloseProfile(hICC);
  55.182 +           return NULL;
  55.183 +           }
  55.184  
  55.185         cmsAlloc3DGrid(Lut, nLUTPoints, 3, 3);
  55.186  
  55.187 @@ -890,7 +905,10 @@
  55.188  
  55.189         // An empty LUTs is all we need
  55.190         Lut = cmsAllocLUT();
  55.191 -       if (Lut == NULL) return NULL;
  55.192 +       if (Lut == NULL) {
  55.193 +           cmsCloseProfile(hProfile);
  55.194 +           return NULL;
  55.195 +           }
  55.196  
  55.197         Lut -> InputChan = 3;
  55.198         Lut -> OutputChan = 1;
    56.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c	Tue Apr 07 11:43:20 2009 -0700
    56.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c	Tue Apr 07 14:02:54 2009 -0700
    56.3 @@ -29,7 +29,7 @@
    56.4  //
    56.5  //
    56.6  //  Little cms
    56.7 -//  Copyright (C) 1998-2006 Marti Maria
    56.8 +//  Copyright (C) 1998-2007 Marti Maria
    56.9  //
   56.10  // Permission is hereby granted, free of charge, to any person obtaining
   56.11  // a copy of this software and associated documentation files (the "Software"),
   56.12 @@ -51,10 +51,6 @@
   56.13  
   56.14  #include "lcms.h"
   56.15  
   56.16 -// Uncomment this line if you want lcms to use the black point tag in profile,
   56.17 -// if commented, lcms will compute the black point by its own.
   56.18 -// It is safer to leve it commented out
   56.19 -// #define HONOR_BLACK_POINT_TAG
   56.20  
   56.21  // Conversions
   56.22  
   56.23 @@ -79,10 +75,9 @@
   56.24  }
   56.25  
   56.26  
   56.27 -
   56.28  // Obtains WhitePoint from Temperature
   56.29  
   56.30 -BOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint)
   56.31 +LCMSBOOL LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint)
   56.32  {
   56.33         double x, y;
   56.34         double T, T2, T3;
   56.35 @@ -147,7 +142,7 @@
   56.36  //            - Then, I apply these coeficients to the original matrix
   56.37  
   56.38  
   56.39 -BOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
   56.40 +LCMSBOOL LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r, LPcmsCIExyY WhitePt,
   56.41                                              LPcmsCIExyYTRIPLE Primrs)
   56.42  {
   56.43          VEC3 WhitePoint, Coef;
   56.44 @@ -169,14 +164,12 @@
   56.45  
   56.46  
   56.47          // Build Primaries matrix
   56.48 -
   56.49          VEC3init(&Primaries.v[0], xr,        xg,         xb);
   56.50          VEC3init(&Primaries.v[1], yr,        yg,         yb);
   56.51          VEC3init(&Primaries.v[2], (1-xr-yr), (1-xg-yg),  (1-xb-yb));
   56.52  
   56.53  
   56.54          // Result = Primaries ^ (-1) inverse matrix
   56.55 -
   56.56          if (!MAT3inverse(&Primaries, &Result))
   56.57                          return FALSE;
   56.58  
   56.59 @@ -184,11 +177,9 @@
   56.60          VEC3init(&WhitePoint, xn/yn, 1.0, (1.0-xn-yn)/yn);
   56.61  
   56.62          // Across inverse primaries ...
   56.63 -
   56.64          MAT3eval(&Coef, &Result, &WhitePoint);
   56.65  
   56.66          // Give us the Coefs, then I build transformation matrix
   56.67 -
   56.68          VEC3init(&r -> v[0], Coef.n[VX]*xr,          Coef.n[VY]*xg,          Coef.n[VZ]*xb);
   56.69          VEC3init(&r -> v[1], Coef.n[VX]*yr,          Coef.n[VY]*yg,          Coef.n[VZ]*yb);
   56.70          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));
   56.71 @@ -246,7 +237,7 @@
   56.72  // Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll
   56.73  // The cone matrix can be specified in ConeMatrix. If NULL, Bradford is assumed
   56.74  
   56.75 -BOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll)
   56.76 +LCMSBOOL cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll)
   56.77  {
   56.78       MAT3 LamRigg   = {{ // Bradford matrix
   56.79                        {{  0.8951,  0.2664, -0.1614 }},
   56.80 @@ -265,7 +256,7 @@
   56.81  
   56.82  // Same as anterior, but assuming D50 destination. White point is given in xyY
   56.83  
   56.84 -BOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt)
   56.85 +LCMSBOOL cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt)
   56.86  {
   56.87          cmsCIEXYZ Dn;
   56.88          MAT3 Bradford;
   56.89 @@ -284,7 +275,7 @@
   56.90  
   56.91  // Same as anterior, but assuming D50 source. White point is given in xyY
   56.92  
   56.93 -BOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt)
   56.94 +LCMSBOOL cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt)
   56.95  {
   56.96          cmsCIEXYZ Dn;
   56.97          MAT3 Bradford;
   56.98 @@ -304,7 +295,7 @@
   56.99  // Adapts a color to a given illuminant. Original color is expected to have
  56.100  // a SourceWhitePt white point.
  56.101  
  56.102 -BOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
  56.103 +LCMSBOOL LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
  56.104                                       LPcmsCIEXYZ SourceWhitePt,
  56.105                                       LPcmsCIEXYZ Illuminant,
  56.106                                       LPcmsCIEXYZ Value)
  56.107 @@ -404,8 +395,6 @@
  56.108  
  56.109          dj = ((vs - vj) - tj * (us - uj)) / sqrt(1 + tj*tj);
  56.110  
  56.111 -
  56.112 -
  56.113          if ((j!=0) && (di/dj < 0.0)) {
  56.114              Tc = 1000000.0 / (mi + (di / (di - dj)) * (mj - mi));
  56.115              break;
  56.116 @@ -423,7 +412,7 @@
  56.117  
  56.118  
  56.119  static
  56.120 -BOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance)
  56.121 +LCMSBOOL InRange(LPcmsCIExyY a, LPcmsCIExyY b, double tolerance)
  56.122  {
  56.123         double dist_x, dist_y;
  56.124  
  56.125 @@ -458,6 +447,7 @@
  56.126  }
  56.127  
  56.128  
  56.129 +// To be removed in future versions
  56.130  void _cmsIdentifyWhitePoint(char *Buffer, LPcmsCIEXYZ WhitePt)
  56.131  {
  56.132         int i, n;
  56.133 @@ -518,7 +508,6 @@
  56.134      cmsCIEXYZ  BlackXYZ, MediaWhite;
  56.135  
  56.136      // If the profile does not support input direction, assume Black point 0
  56.137 -
  56.138      if (!cmsIsIntentSupported(hInput, Intent, LCMS_USED_AS_INPUT)) {
  56.139  
  56.140          BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
  56.141 @@ -527,7 +516,6 @@
  56.142  
  56.143  
  56.144      // Try to get black by using black colorant
  56.145 -
  56.146      Space = cmsGetColorSpace(hInput);
  56.147  
  56.148      if (!_cmsEndPointsBySpace(Space, &White, &Black, &nChannels)) {
  56.149 @@ -576,7 +564,7 @@
  56.150  
  56.151  
  56.152  // Get a black point of output CMYK profile, discounting any ink-limiting embedded
  56.153 -// in the profile. Fou doing that, use perceptual intent in input direction:
  56.154 +// in the profile. For doing that, use perceptual intent in input direction:
  56.155  // Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab
  56.156  
  56.157  static
  56.158 @@ -651,6 +639,8 @@
  56.159              D50BlackPoint.X = PERCEPTUAL_BLACK_X;
  56.160              D50BlackPoint.Y = PERCEPTUAL_BLACK_Y;
  56.161              D50BlackPoint.Z = PERCEPTUAL_BLACK_Z;
  56.162 +
  56.163 +            // Obtain the absolute XYZ. Adapt perceptual black back from D50 to whatever media white
  56.164              cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &D50BlackPoint);
  56.165          }
  56.166  
  56.167 @@ -662,26 +652,24 @@
  56.168  // This function shouldn't exist at all -- there is such quantity of broken
  56.169  // profiles on black point tag, that we must somehow fix chromaticity to
  56.170  // avoid huge tint when doing Black point compensation. This function does
  56.171 -// just that. If BP is specified, then forces it to neutral and uses only L
  56.172 -// component. If does not exist, computes it by taking 400% of ink or RGB=0 This
  56.173 -// works well on relative intent and is undefined on perceptual & saturation.
  56.174 -// However, I will support all intents for tricking & trapping.
  56.175 -
  56.176 +// just that. There is a special flag for using black point tag, but turned
  56.177 +// off by default because it is bogus on most profiles. The detection algorithm
  56.178 +// involves to turn BP to neutral and to use only L component.
  56.179  
  56.180  int cmsDetectBlackPoint(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, int Intent, DWORD dwFlags)
  56.181  {
  56.182  
  56.183 -    // v4 + perceptual & saturation intents does have its own black point
  56.184 +    // v4 + perceptual & saturation intents does have its own black point, and it is
  56.185 +    // well specified enough to use it.
  56.186  
  56.187      if ((cmsGetProfileICCversion(hProfile) >= 0x4000000) &&
  56.188          (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) {
  56.189  
  56.190         // Matrix shaper share MRC & perceptual intents
  56.191 -
  56.192         if (_cmsIsMatrixShaper(hProfile))
  56.193             return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, cmsFLAGS_NOTPRECALC);
  56.194  
  56.195 -       // Get fixed value
  56.196 +       // CLUT based - Get perceptual black point (fixed value)
  56.197         return GetV4PerceptualBlack(BlackPoint, hProfile, dwFlags);
  56.198      }
  56.199  
  56.200 @@ -701,7 +689,6 @@
  56.201               cmsTakeMediaWhitePoint(&MediaWhite, hProfile);
  56.202  
  56.203               // Black point is absolute XYZ, so adapt to D50 to get PCS value
  56.204 -
  56.205               cmsAdaptToIlluminant(&UntrustedBlackPoint, &MediaWhite, cmsD50_XYZ(), &BlackXYZ);
  56.206  
  56.207               // Force a=b=0 to get rid of any chroma
  56.208 @@ -713,7 +700,6 @@
  56.209               cmsLab2XYZ(NULL, &TrustedBlackPoint, &Lab);
  56.210  
  56.211               // Return BP as D50 relative or absolute XYZ (depends on flags)
  56.212 -
  56.213               if (!(dwFlags & LCMS_BPFLAGS_D50_ADAPTED))
  56.214                      cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &TrustedBlackPoint);
  56.215               else
  56.216 @@ -724,15 +710,15 @@
  56.217  
  56.218  #endif
  56.219  
  56.220 -    // If output profile, discount ink-limiting
  56.221 +    // That is about v2 profiles.
  56.222  
  56.223 +    // If output profile, discount ink-limiting and that's all
  56.224      if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
  56.225              (cmsGetDeviceClass(hProfile) == icSigOutputClass) &&
  56.226              (cmsGetColorSpace(hProfile) == icSigCmykData))
  56.227                  return BlackPointUsingPerceptualBlack(BlackPoint, hProfile, dwFlags);
  56.228  
  56.229      // Nope, compute BP using current intent.
  56.230 -
  56.231      return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags);
  56.232  
  56.233  }
    57.1 --- a/src/share/native/sun/java2d/cmm/lcms/cmsxform.c	Tue Apr 07 11:43:20 2009 -0700
    57.2 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsxform.c	Tue Apr 07 14:02:54 2009 -0700
    57.3 @@ -29,7 +29,7 @@
    57.4  //
    57.5  //
    57.6  //  Little cms
    57.7 -//  Copyright (C) 1998-2006 Marti Maria
    57.8 +//  Copyright (C) 1998-2007 Marti Maria
    57.9  //
   57.10  // Permission is hereby granted, free of charge, to any person obtaining
   57.11  // a copy of this software and associated documentation files (the "Software"),
   57.12 @@ -52,7 +52,6 @@
   57.13  
   57.14  #include "lcms.h"
   57.15  
   57.16 -// #define DEBUG 1
   57.17  
   57.18  // Transformations stuff
   57.19  // -----------------------------------------------------------------------
   57.20 @@ -85,7 +84,7 @@
   57.21  
   57.22  void         LCMSEXPORT cmsGetAlarmCodes(int *r, int *g, int *b);
   57.23  void         LCMSEXPORT cmsSetAlarmCodes(int r, int g, int b);
   57.24 -BOOL         LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
   57.25 +LCMSBOOL     LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
   57.26                                                  int Intent, int UsedDirection);
   57.27  
   57.28  // -------------------------------------------------------------------------
   57.29 @@ -343,7 +342,7 @@
   57.30             p ->DeviceLink ->CLut16params.Interp3D(wIn, wOut,
   57.31                                      p ->DeviceLink -> T,
   57.32                                      &p ->DeviceLink -> CLut16params);
   57.33 -                 }
   57.34 +         }
   57.35           else
   57.36              cmsEvalLUT(p -> DeviceLink, wIn, wOut);
   57.37  
   57.38 @@ -414,7 +413,7 @@
   57.39         register LPBYTE output;
   57.40         WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS];
   57.41         register unsigned int i, n;
   57.42 -           WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS];
   57.43 +       WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS];
   57.44  
   57.45  
   57.46         accum  = (LPBYTE) in;
   57.47 @@ -427,10 +426,10 @@
   57.48         ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS);
   57.49  
   57.50  
   57.51 -           LCMS_READ_LOCK(&p ->rwlock);
   57.52 -               CopyMemory(CacheIn,  p ->CacheIn, sizeof(WORD) * MAXCHANNELS);
   57.53 -               CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS);
   57.54 -           LCMS_UNLOCK(&p ->rwlock);
   57.55 +       LCMS_READ_LOCK(&p ->rwlock);
   57.56 +           CopyMemory(CacheIn,  p ->CacheIn, sizeof(WORD) * MAXCHANNELS);
   57.57 +           CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS);
   57.58 +       LCMS_UNLOCK(&p ->rwlock);
   57.59  
   57.60         for (i=0; i < n; i++) {
   57.61  
   57.62 @@ -443,14 +442,14 @@
   57.63         }
   57.64         else {
   57.65  
   57.66 -                        // Try to speedup things on plain devicelinks
   57.67 -
   57.68 -                         if (p ->DeviceLink ->wFlags == LUT_HAS3DGRID) {
   57.69 +            // Try to speedup things on plain devicelinks
   57.70 +
   57.71 +             if (p ->DeviceLink ->wFlags == LUT_HAS3DGRID) {
   57.72  
   57.73               p ->DeviceLink ->CLut16params.Interp3D(wIn, wOut,
   57.74                                      p ->DeviceLink -> T,
   57.75                                      &p ->DeviceLink -> CLut16params);
   57.76 -                     }
   57.77 +             }
   57.78               else
   57.79                    cmsEvalLUT(p -> DeviceLink, wIn, wOut);
   57.80  
   57.81 @@ -463,10 +462,10 @@
   57.82         }
   57.83  
   57.84  
   57.85 -           LCMS_WRITE_LOCK(&p ->rwlock);
   57.86 -               CopyMemory(p->CacheIn,  CacheIn, sizeof(WORD) * MAXCHANNELS);
   57.87 -               CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS);
   57.88 -           LCMS_UNLOCK(&p ->rwlock);
   57.89 +       LCMS_WRITE_LOCK(&p ->rwlock);
   57.90 +           CopyMemory(p->CacheIn,  CacheIn, sizeof(WORD) * MAXCHANNELS);
   57.91 +           CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS);
   57.92 +       LCMS_UNLOCK(&p ->rwlock);
   57.93  
   57.94  }
   57.95  
   57.96 @@ -483,7 +482,7 @@
   57.97         register LPBYTE output;
   57.98         WORD wIn[MAXCHANNELS], wOut[MAXCHANNELS];
   57.99         register unsigned int i, n;
  57.100 -           WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS];
  57.101 +       WORD CacheIn[MAXCHANNELS], CacheOut[MAXCHANNELS];
  57.102  
  57.103  
  57.104         accum  = (LPBYTE) in;
  57.105 @@ -495,10 +494,10 @@
  57.106         ZeroMemory(wIn,  sizeof(WORD) * MAXCHANNELS);
  57.107         ZeroMemory(wOut, sizeof(WORD) * MAXCHANNELS);
  57.108  
  57.109 -           LCMS_READ_LOCK(&p ->rwlock);
  57.110 -               CopyMemory(CacheIn,  p ->CacheIn, sizeof(WORD) * MAXCHANNELS);
  57.111 -               CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS);
  57.112 -           LCMS_UNLOCK(&p ->rwlock);
  57.113 +       LCMS_READ_LOCK(&p ->rwlock);
  57.114 +           CopyMemory(CacheIn,  p ->CacheIn, sizeof(WORD) * MAXCHANNELS);
  57.115 +           CopyMemory(CacheOut, p ->CacheOut, sizeof(WORD) * MAXCHANNELS);
  57.116 +       LCMS_UNLOCK(&p ->rwlock);
  57.117  
  57.118  
  57.119         for (i=0; i < n; i++) {
  57.120 @@ -520,10 +519,10 @@
  57.121         output = p -> ToOutput(p, wOut, output);
  57.122         }
  57.123  
  57.124 -            LCMS_WRITE_LOCK(&p ->rwlock);
  57.125 -               CopyMemory(p->CacheIn,  CacheIn, sizeof(WORD) * MAXCHANNELS);
  57.126 -               CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS);
  57.127 -            LCMS_UNLOCK(&p ->rwlock);
  57.128 +        LCMS_WRITE_LOCK(&p ->rwlock);
  57.129 +           CopyMemory(p->CacheIn,  CacheIn, sizeof(WORD) * MAXCHANNELS);
  57.130 +           CopyMemory(p->CacheOut, CacheOut, sizeof(WORD) * MAXCHANNELS);
  57.131 +        LCMS_UNLOCK(&p ->rwlock);
  57.132  }
  57.133  
  57.134  
  57.135 @@ -635,6 +634,8 @@
  57.136         MAT3 Scale;
  57.137  
  57.138         GrayTRC = cmsReadICCGamma(hProfile, icSigGrayTRCTag);        // Y
  57.139 +       if (GrayTRC == NULL) return NULL;
  57.140 +
  57.141         cmsTakeIluminant(&Illuminant, hProfile);
  57.142  
  57.143         if (cmsGetPCS(hProfile) == icSigLabData) {
  57.144 @@ -789,6 +790,10 @@
  57.145         InverseShapes[1] = cmsReadICCGammaReversed(OutputProfile, icSigGreenTRCTag);
  57.146         InverseShapes[2] = cmsReadICCGammaReversed(OutputProfile, icSigBlueTRCTag);
  57.147  
  57.148 +       if (InverseShapes[0] == NULL ||
  57.149 +           InverseShapes[1] == NULL ||
  57.150 +           InverseShapes[2] == NULL) return NULL;
  57.151 +
  57.152         OutMatSh = cmsAllocMatShaper(&DoubleInv, InverseShapes, MATSHAPER_OUTPUT);
  57.153  
  57.154         cmsFreeGammaTriple(InverseShapes);
  57.155 @@ -801,7 +806,7 @@
  57.156  // This function builds a transform matrix chaining parameters
  57.157  
  57.158  static
  57.159 -BOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p)
  57.160 +LCMSBOOL cmsBuildSmeltMatShaper(_LPcmsTRANSFORM p)
  57.161  {
  57.162         MAT3 From, To, ToInv, Transfer;
  57.163         LPGAMMATABLE In[3], InverseOut[3];
  57.164 @@ -814,7 +819,6 @@
  57.165         if (!cmsReadICCMatrixRGB2XYZ(&To, p -> OutputProfile))
  57.166                       return FALSE;
  57.167  
  57.168 -
  57.169         // invert dest
  57.170  
  57.171         if (MAT3inverse(&To, &ToInv) < 0)
  57.172 @@ -838,10 +842,14 @@
  57.173          InverseOut[1] = cmsReadICCGammaReversed(p -> OutputProfile, icSigGreenTRCTag);
  57.174          InverseOut[2] = cmsReadICCGammaReversed(p -> OutputProfile, icSigBlueTRCTag);
  57.175  
  57.176 +        if (!InverseOut[0] || !InverseOut[1] || !InverseOut[2]) {
  57.177 +                     cmsFreeGammaTriple(In);
  57.178 +                     return FALSE;
  57.179 +        }
  57.180 +
  57.181          p -> SmeltMatShaper = cmsAllocMatShaper2(&Transfer, In, InverseOut, MATSHAPER_ALLSMELTED);
  57.182  
  57.183          cmsFreeGammaTriple(In);
  57.184 -
  57.185          cmsFreeGammaTriple(InverseOut);
  57.186  
  57.187          return (p -> SmeltMatShaper != NULL);
  57.188 @@ -1029,7 +1037,7 @@
  57.189  // Check colorspace
  57.190  
  57.191  static
  57.192 -BOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, BOOL lUsePCS)
  57.193 +LCMSBOOL IsProperColorSpace(cmsHPROFILE hProfile, DWORD dwFormat, LCMSBOOL lUsePCS)
  57.194  {
  57.195         int Space = T_COLORSPACE(dwFormat);
  57.196  
  57.197 @@ -1049,10 +1057,10 @@
  57.198  {
  57.199      // Allocate needed memory
  57.200  
  57.201 -    _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) malloc(sizeof(_cmsTRANSFORM));
  57.202 +    _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) _cmsMalloc(sizeof(_cmsTRANSFORM));
  57.203      if (!p) {
  57.204  
  57.205 -          cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: malloc() failed");
  57.206 +          cmsSignalError(LCMS_ERRC_ABORTED, "cmsCreateTransform: _cmsMalloc() failed");
  57.207            return NULL;
  57.208      }
  57.209  
  57.210 @@ -1078,7 +1086,7 @@
  57.211      p -> ExitColorSpace  = (icColorSpaceSignature) 0;
  57.212      p -> AdaptationState = GlobalAdaptationState;
  57.213  
  57.214 -        LCMS_CREATE_LOCK(&p->rwlock);
  57.215 +    LCMS_CREATE_LOCK(&p->rwlock);
  57.216  
  57.217      return p;
  57.218  }
  57.219 @@ -1269,12 +1277,12 @@
  57.220          else {
  57.221                  // Can we optimize matrix-shaper only transform?
  57.222  
  57.223 -                   if (*FromTagPtr == 0 &&
  57.224 -                       *ToTagPtr == 0 &&
  57.225 -                       !p->PreviewProfile  &&
  57.226 -                       p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC &&
  57.227 +                   if ((*FromTagPtr == 0) &&
  57.228 +                       (*ToTagPtr == 0) &&
  57.229 +                       (!p->PreviewProfile) &&
  57.230 +                       (p -> Intent != INTENT_ABSOLUTE_COLORIMETRIC) &&
  57.231                         (p -> EntryColorSpace == icSigRgbData) &&
  57.232 -                       (p -> ExitColorSpace == icSigRgbData) &&
  57.233 +                       (p -> ExitColorSpace == icSigRgbData)  &&
  57.234                         !(p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)) {
  57.235  
  57.236                            // Yes... try to smelt matrix-shapers
  57.237 @@ -1530,7 +1538,6 @@
  57.238  
  57.239         TakeConversionRoutines(p, dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
  57.240  
  57.241 -
  57.242         if (!(p -> dwOriginalFlags & cmsFLAGS_NOTPRECALC)) {
  57.243  
  57.244                 LPLUT DeviceLink;
  57.245 @@ -1553,7 +1560,8 @@
  57.246                      DeviceLink = _cmsPrecalculateDeviceLink((cmsHTRANSFORM) p, dwFlags);
  57.247                 }
  57.248  
  57.249 -               if (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK) {
  57.250 +               // Allow to specify cmsFLAGS_GAMUTCHECK, even if no proofing profile is given
  57.251 +               if ((p ->PreviewProfile != NULL) && (p -> dwOriginalFlags & cmsFLAGS_GAMUTCHECK)) {
  57.252  
  57.253                     GamutCheck = _cmsPrecalculateGamutCheck((cmsHTRANSFORM) p);
  57.254                 }
  57.255 @@ -1561,7 +1569,6 @@
  57.256                 // If input colorspace is Rgb, Cmy, then use tetrahedral interpolation
  57.257                 // for speed reasons (it only works well on spaces on Luma is diagonal, and
  57.258                 // not if luma is in separate channel)
  57.259 -
  57.260                 if (p ->EntryColorSpace == icSigRgbData ||
  57.261                     p ->EntryColorSpace == icSigCmyData) {
  57.262  
  57.263 @@ -1663,12 +1670,12 @@
  57.264                cmsFreeMatShaper(p -> SmeltMatShaper);
  57.265         if (p ->NamedColorList)
  57.266                cmsFreeNamedColorList(p ->NamedColorList);
  57.267 -           if (p -> GamutCheck)
  57.268 -                        cmsFreeLUT(p -> GamutCheck);
  57.269 -
  57.270 -           LCMS_FREE_LOCK(&p->rwlock);
  57.271 -
  57.272 -       free((void *) p);
  57.273 +       if (p -> GamutCheck)
  57.274 +            cmsFreeLUT(p -> GamutCheck);
  57.275 +
  57.276 +       LCMS_FREE_LOCK(&p->rwlock);
  57.277 +
  57.278 +       _cmsFree((void *) p);
  57.279  }
  57.280  
  57.281  
  57.282 @@ -1704,7 +1711,7 @@
  57.283  
  57.284  // Returns TRUE if the profile is implemented as matrix-shaper
  57.285  
  57.286 -BOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile)
  57.287 +LCMSBOOL LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile)
  57.288  {
  57.289      switch (cmsGetColorSpace(hProfile)) {
  57.290  
  57.291 @@ -1728,7 +1735,7 @@
  57.292  }
  57.293  
  57.294  
  57.295 -BOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
  57.296 +LCMSBOOL LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
  57.297                                                  int Intent, int UsedDirection)
  57.298  {
  57.299  
  57.300 @@ -1774,6 +1781,16 @@
  57.301  }
  57.302  
  57.303  
  57.304 +static
  57.305 +int IsAllowedInSingleXform(icProfileClassSignature aClass)
  57.306 +{
  57.307 +    return (aClass == icSigInputClass) ||
  57.308 +           (aClass == icSigDisplayClass) ||
  57.309 +           (aClass == icSigOutputClass) ||
  57.310 +           (aClass == icSigColorSpaceClass);
  57.311 +}
  57.312 +
  57.313 +
  57.314  // A multiprofile transform does chain several profiles into a single
  57.315  // devicelink. It couls also be used to merge named color profiles into
  57.316  // a single database.
  57.317 @@ -1805,10 +1822,16 @@
  57.318      // There is a simple case with just two profiles, try to catch it in order of getting
  57.319      // black preservation to work on this function, at least with two profiles.
  57.320  
  57.321 +
  57.322      if (nProfiles == 2) {
  57.323  
  57.324 -        if ((cmsGetDeviceClass(hProfiles[0]) != icSigLinkClass) &&
  57.325 -            (cmsGetDeviceClass(hProfiles[1]) != icSigLinkClass))
  57.326 +        icProfileClassSignature Class1 = cmsGetDeviceClass(hProfiles[0]);
  57.327 +        icProfileClassSignature Class2 = cmsGetDeviceClass(hProfiles[1]);
  57.328 +
  57.329 +        // Only input, output and display are allowed
  57.330 +
  57.331 +        if (IsAllowedInSingleXform(Class1) &&
  57.332 +            IsAllowedInSingleXform(Class2))
  57.333                     return cmsCreateTransform(hProfiles[0], dwInput, hProfiles[1], dwOutput, Intent, dwFlags);
  57.334      }
  57.335  
  57.336 @@ -1984,6 +2007,14 @@
  57.337      if (hLab) cmsCloseProfile(hLab);
  57.338      if (hXYZ) cmsCloseProfile(hXYZ);
  57.339  
  57.340 +
  57.341 +    if (p ->EntryColorSpace == icSigRgbData ||
  57.342 +        p ->EntryColorSpace == icSigCmyData) {
  57.343 +
  57.344 +                    p->DeviceLink -> CLut16params.Interp3D = cmsTetrahedralInterp16;
  57.345 +    }
  57.346 +
  57.347 +
  57.348      if ((Intent != INTENT_ABSOLUTE_COLORIMETRIC) &&
  57.349          !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP))
  57.350                              _cmsFixWhiteMisalignment(p);
    58.1 --- a/src/share/native/sun/java2d/cmm/lcms/icc34.h	Tue Apr 07 11:43:20 2009 -0700
    58.2 +++ b/src/share/native/sun/java2d/cmm/lcms/icc34.h	Tue Apr 07 14:02:54 2009 -0700
    58.3 @@ -206,6 +206,11 @@
    58.4  
    58.5  #if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__)
    58.6  
    58.7 +#if defined (__MINGW) || defined(__MINGW32__)
    58.8 +#include <stdint.h>
    58.9 +#endif
   58.10 +
   58.11 +
   58.12  typedef uint8_t   icUInt8Number;
   58.13  typedef uint16_t  icUInt16Number;
   58.14  typedef uint32_t  icUInt32Number;
    59.1 --- a/src/share/native/sun/java2d/cmm/lcms/lcms.h	Tue Apr 07 11:43:20 2009 -0700
    59.2 +++ b/src/share/native/sun/java2d/cmm/lcms/lcms.h	Tue Apr 07 14:02:54 2009 -0700
    59.3 @@ -29,7 +29,7 @@
    59.4  //
    59.5  //
    59.6  //  Little cms
    59.7 -//  Copyright (C) 1998-2006 Marti Maria
    59.8 +//  Copyright (C) 1998-2007 Marti Maria
    59.9  //
   59.10  // Permission is hereby granted, free of charge, to any person obtaining
   59.11  // a copy of this software and associated documentation files (the "Software"),
   59.12 @@ -49,8 +49,8 @@
   59.13  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
   59.14  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   59.15  
   59.16 -// Version 1.16
   59.17 -#undef DEBUG
   59.18 +// Version 1.18
   59.19 +
   59.20  #ifndef __cms_H
   59.21  
   59.22  // ********** Configuration toggles ****************************************
   59.23 @@ -62,13 +62,8 @@
   59.24  // virtually any machine.
   59.25  
   59.26  //#define USE_FLOAT        1
   59.27 -#ifdef _WIN64
   59.28 -#define USE_C            1
   59.29 -#undef USE_ASSEMBLER
   59.30 -#else
   59.31 -#undef USE_C
   59.32 +// #define USE_C            1
   59.33  #define USE_ASSEMBLER    1
   59.34 -#endif
   59.35  
   59.36  // Define this if you are using this package as a DLL (windows only)
   59.37  
   59.38 @@ -77,15 +72,11 @@
   59.39  
   59.40  // Uncomment if you are trying the engine in a non-windows environment
   59.41  // like linux, SGI, VAX, FreeBSD, BeOS, etc.
   59.42 -#if !defined(_WIN32) || !defined(_WIN64)
   59.43  #define NON_WINDOWS  1
   59.44 -#endif
   59.45  
   59.46  // Uncomment this one if you are using big endian machines (only meaningful
   59.47  // when NON_WINDOWS is used)
   59.48 -#ifndef _LITTLE_ENDIAN
   59.49 -#define USE_BIG_ENDIAN   1
   59.50 -#endif
   59.51 +// #define USE_BIG_ENDIAN   1
   59.52  
   59.53  // Uncomment this one if your compiler/machine does support the
   59.54  // "long long" type This will speedup fixed point math. (USE_C only)
   59.55 @@ -104,18 +95,24 @@
   59.56  // Uncomment this line on multithreading environments
   59.57  // #define USE_PTHREADS    1
   59.58  
   59.59 +// Uncomment this line if you want lcms to use the black point tag in profile,
   59.60 +// if commented, lcms will compute the black point by its own.
   59.61 +// It is safer to leve it commented out
   59.62 +// #define HONOR_BLACK_POINT_TAG    1
   59.63 +
   59.64  // ********** End of configuration toggles ******************************
   59.65  
   59.66 -#define LCMS_VERSION        116
   59.67 +#define LCMS_VERSION        118
   59.68  
   59.69  // Microsoft VisualC++
   59.70  
   59.71  // Deal with Microsoft's attempt at deprecating C standard runtime functions
   59.72 -
   59.73  #ifdef _MSC_VER
   59.74  #    undef NON_WINDOWS
   59.75  #    if (_MSC_VER >= 1400)
   59.76 +#      ifndef _CRT_SECURE_NO_DEPRECATE
   59.77  #        define _CRT_SECURE_NO_DEPRECATE 1
   59.78 +#      endif
   59.79  #    endif
   59.80  #endif
   59.81  
   59.82 @@ -125,7 +122,6 @@
   59.83  #    undef NON_WINDOWS
   59.84  #endif
   59.85  
   59.86 -
   59.87  #include <stdio.h>
   59.88  #include <stdlib.h>
   59.89  #include <math.h>
   59.90 @@ -134,11 +130,11 @@
   59.91  #include <time.h>
   59.92  
   59.93  // Metroworks CodeWarrior
   59.94 -
   59.95  #ifdef __MWERKS__
   59.96  #   define unlink remove
   59.97  #   if WIN32
   59.98  #       define USE_CUSTOM_SWAB 1
   59.99 +#       undef  NON_WINDOWS
  59.100  #   else
  59.101  #       define NON_WINDOWS   1
  59.102  #   endif
  59.103 @@ -172,15 +168,21 @@
  59.104  #   define USE_BIG_ENDIAN      1
  59.105  #endif
  59.106  
  59.107 -#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) || defined(__ppc__)
  59.108 +#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc) || defined(__ppc__) || defined(__s390__) || defined(__s390x__)
  59.109  #   define USE_BIG_ENDIAN      1
  59.110  #endif
  59.111  
  59.112 -#ifdef TARGET_CPU_PPC
  59.113 +#if TARGET_CPU_PPC
  59.114  #   define USE_BIG_ENDIAN   1
  59.115  #endif
  59.116  
  59.117 -#ifdef macintosh
  59.118 +#if macintosh
  59.119 +# ifndef __LITTLE_ENDIAN__
  59.120 +#   define USE_BIG_ENDIAN      1
  59.121 +# endif
  59.122 +#endif
  59.123 +
  59.124 +#ifdef __BIG_ENDIAN__
  59.125  #   define USE_BIG_ENDIAN      1
  59.126  #endif
  59.127  
  59.128 @@ -217,11 +219,8 @@
  59.129  typedef unsigned char BYTE, *LPBYTE;
  59.130  typedef unsigned short WORD, *LPWORD;
  59.131  typedef unsigned long DWORD, *LPDWORD;
  59.132 -typedef int BOOL;
  59.133  typedef char *LPSTR;
  59.134  typedef void *LPVOID;
  59.135 -typedef void* LCMSHANDLE;
  59.136 -
  59.137  
  59.138  #define ZeroMemory(p,l)     memset((p),0,(l))
  59.139  #define CopyMemory(d,s,l)   memcpy((d),(s),(l))
  59.140 @@ -263,8 +262,12 @@
  59.141  
  59.142  #include <windows.h>
  59.143  
  59.144 -typedef HANDLE LCMSHANDLE;
  59.145 -
  59.146 +#ifdef _WIN64
  59.147 +# ifdef USE_ASSEMBLER
  59.148 +#    undef  USE_ASSEMBLER
  59.149 +#    define USE_C           1
  59.150 +# endif
  59.151 +#endif
  59.152  
  59.153  #ifdef  USE_INT64
  59.154  #  ifndef LCMSULONGLONG
  59.155 @@ -296,6 +299,10 @@
  59.156  #   define LCMS_UNLOCK(x)
  59.157  #endif
  59.158  
  59.159 +// Base types
  59.160 +
  59.161 +typedef int   LCMSBOOL;
  59.162 +typedef void* LCMSHANDLE;
  59.163  
  59.164  #include "icc34.h"          // ICC header file
  59.165  
  59.166 @@ -322,16 +329,10 @@
  59.167  #define icSigMCHEData                  ((icColorSpaceSignature) 0x4d434845L)  // MCHE
  59.168  #define icSigMCHFData                  ((icColorSpaceSignature) 0x4d434846L)  // MCHF
  59.169  
  59.170 -#define icSigCAM97JABData              ((icColorSpaceSignature) 0x4A616231L)  // 'Jab1' H. Zeng
  59.171 -#define icSigCAM02JABData              ((icColorSpaceSignature) 0x4A616232L)  // 'Jab2' H. Zeng
  59.172 -#define icSigCAM02JCHData              ((icColorSpaceSignature) 0x4A636A32L)  // 'Jch2' H. Zeng
  59.173 -
  59.174  #define icSigChromaticityTag            ((icTagSignature) 0x6368726dL) // As per Addendum 2 to Spec. ICC.1:1998-09
  59.175  #define icSigChromaticAdaptationTag     ((icTagSignature) 0x63686164L) // 'chad'
  59.176  #define icSigColorantTableTag           ((icTagSignature) 0x636c7274L) // 'clrt'
  59.177  #define icSigColorantTableOutTag        ((icTagSignature) 0x636c6f74L) // 'clot'
  59.178 -#define icSigHPGamutDescTag             ((icTagSignature) 0x676D7441L) // 'gmtA' H. Zeng
  59.179 -
  59.180  
  59.181  #define icSigParametricCurveType        ((icTagTypeSignature) 0x70617261L)  // parametric (ICC 4.0)
  59.182  #define icSigMultiLocalizedUnicodeType  ((icTagTypeSignature) 0x6D6C7563L)
  59.183 @@ -340,7 +341,6 @@
  59.184  #define icSiglutAtoBType                ((icTagTypeSignature) 0x6d414220L)  // mAB
  59.185  #define icSiglutBtoAType                ((icTagTypeSignature) 0x6d424120L)  // mBA
  59.186  #define icSigColorantTableType          ((icTagTypeSignature) 0x636c7274L)  // clrt
  59.187 -#define icSigHPGamutDescType            ((icTagTypeSignature) 0x676D7441L)  // gmtA H. Zeng
  59.188  
  59.189  
  59.190  typedef struct {
  59.191 @@ -438,9 +438,6 @@
  59.192  #ifndef itoa
  59.193  #       define itoa   _itoa
  59.194  #endif
  59.195 -#ifndef filelength
  59.196 -#       define filelength _filelength
  59.197 -#endif
  59.198  #ifndef fileno
  59.199  #       define fileno   _fileno
  59.200  #endif
  59.201 @@ -450,6 +447,14 @@
  59.202  #ifndef hypot
  59.203  #       define hypot    _hypot
  59.204  #endif
  59.205 +#ifndef snprintf
  59.206 +#       define snprintf  _snprintf
  59.207 +#endif
  59.208 +#ifndef vsnprintf
  59.209 +#       define vsnprintf  _vsnprintf
  59.210 +#endif
  59.211 +
  59.212 +
  59.213  #endif
  59.214  
  59.215  
  59.216 @@ -470,8 +475,9 @@
  59.217  
  59.218  // Format of pixel is defined by one DWORD, using bit fields as follows
  59.219  //
  59.220 -//            TTTTT U Y F P X S EEE CCCC BBB
  59.221 +//            D TTTTT U Y F P X S EEE CCCC BBB
  59.222  //
  59.223 +//            D: Use dither (8 bits only)
  59.224  //            T: Pixeltype
  59.225  //            F: Flavor  0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla)
  59.226  //            P: Planar? 0=Chunky, 1=Planar
  59.227 @@ -483,6 +489,7 @@
  59.228  //            Y: Swap first - changes ABGR to BGRA and KCMY to CMYK
  59.229  
  59.230  
  59.231 +#define DITHER_SH(s)           ((s) << 22)
  59.232  #define COLORSPACE_SH(s)       ((s) << 16)
  59.233  #define SWAPFIRST_SH(s)        ((s) << 14)
  59.234  #define FLAVOR_SH(s)           ((s) << 13)
  59.235 @@ -711,20 +718,20 @@
  59.236  
  59.237  typedef struct {
  59.238  
  59.239 -        unsigned int Crc32;  // Has my table been touched?
  59.240 -
  59.241 -        // Keep initial parameters for further serialization
  59.242 +    unsigned int Crc32;  // Has my table been touched?
  59.243 +
  59.244 +    // Keep initial parameters for further serialization
  59.245  
  59.246      int          Type;
  59.247      double       Params[10];
  59.248  
  59.249 -        }  LCMSGAMMAPARAMS, FAR* LPLCMSGAMMAPARAMS;
  59.250 +    }  LCMSGAMMAPARAMS, FAR* LPLCMSGAMMAPARAMS;
  59.251  
  59.252  // Gamma tables.
  59.253  
  59.254  typedef struct {
  59.255  
  59.256 -        LCMSGAMMAPARAMS Seed;   // Parameters used for table creation
  59.257 +    LCMSGAMMAPARAMS Seed;       // Parameters used for table creation
  59.258  
  59.259      // Table-based representation follows
  59.260  
  59.261 @@ -858,7 +865,7 @@
  59.262  
  59.263  LCMSAPI cmsHPROFILE   LCMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess);
  59.264  LCMSAPI cmsHPROFILE   LCMSEXPORT cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize);
  59.265 -LCMSAPI BOOL          LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
  59.266 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
  59.267  
  59.268  // Predefined run-time profiles
  59.269  
  59.270 @@ -915,14 +922,14 @@
  59.271  
  59.272  LCMSAPI void          LCMSEXPORT cmsClampLab(LPcmsCIELab Lab, double amax, double amin, double bmax, double bmin);
  59.273  
  59.274 -LCMSAPI BOOL          LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint);
  59.275 -
  59.276 -LCMSAPI BOOL          LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
  59.277 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint);
  59.278 +
  59.279 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
  59.280                                                          LPcmsCIEXYZ SourceWhitePt,
  59.281                                                          LPcmsCIEXYZ Illuminant,
  59.282                                                          LPcmsCIEXYZ Value);
  59.283  
  59.284 -LCMSAPI BOOL          LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r,
  59.285 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsBuildRGB2XYZtransferMatrix(LPMAT3 r,
  59.286                                                          LPcmsCIExyY WhitePoint,
  59.287                                                          LPcmsCIExyYTRIPLE Primaries);
  59.288  
  59.289 @@ -976,7 +983,7 @@
  59.290  LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma);
  59.291  LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsJoinGamma(LPGAMMATABLE InGamma,  LPGAMMATABLE OutGamma);
  59.292  LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsJoinGammaEx(LPGAMMATABLE InGamma,  LPGAMMATABLE OutGamma, int nPoints);
  59.293 -LCMSAPI BOOL          LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
  59.294 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsSmoothGamma(LPGAMMATABLE Tab, double lambda);
  59.295  LCMSAPI double        LCMSEXPORT cmsEstimateGamma(LPGAMMATABLE t);
  59.296  LCMSAPI double        LCMSEXPORT cmsEstimateGammaEx(LPWORD Table, int nEntries, double Thereshold);
  59.297  LCMSAPI LPGAMMATABLE  LCMSEXPORT cmsReadICCGamma(cmsHPROFILE hProfile, icTagSignature sig);
  59.298 @@ -984,14 +991,14 @@
  59.299  
  59.300  // Access to Profile data.
  59.301  
  59.302 -LCMSAPI BOOL          LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
  59.303 -LCMSAPI BOOL          LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
  59.304 -LCMSAPI BOOL          LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
  59.305 -LCMSAPI BOOL          LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile);
  59.306 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
  59.307 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
  59.308 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
  59.309 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile);
  59.310  LCMSAPI DWORD         LCMSEXPORT cmsTakeHeaderFlags(cmsHPROFILE hProfile);
  59.311  LCMSAPI DWORD         LCMSEXPORT cmsTakeHeaderAttributes(cmsHPROFILE hProfile);
  59.312  
  59.313 -LCMSAPI void          LCMSEXPORT cmsSetLanguage(int LanguageCode, int CountryCode);
  59.314 +LCMSAPI void          LCMSEXPORT cmsSetLanguage(const char LanguageCode[4], const char CountryCode[4]);
  59.315  LCMSAPI const char*   LCMSEXPORT cmsTakeProductName(cmsHPROFILE hProfile);
  59.316  LCMSAPI const char*   LCMSEXPORT cmsTakeProductDesc(cmsHPROFILE hProfile);
  59.317  LCMSAPI const char*   LCMSEXPORT cmsTakeProductInfo(cmsHPROFILE hProfile);
  59.318 @@ -1000,13 +1007,13 @@
  59.319  LCMSAPI const char*   LCMSEXPORT cmsTakeCopyright(cmsHPROFILE hProfile);
  59.320  LCMSAPI const BYTE*   LCMSEXPORT cmsTakeProfileID(cmsHPROFILE hProfile);
  59.321  
  59.322 -LCMSAPI BOOL          LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
  59.323 -LCMSAPI BOOL          LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
  59.324 -
  59.325 -LCMSAPI BOOL          LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig);
  59.326 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeCreationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
  59.327 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeCalibrationDateTime(struct tm *Dest, cmsHPROFILE hProfile);
  59.328 +
  59.329 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig);
  59.330  LCMSAPI int           LCMSEXPORT cmsTakeRenderingIntent(cmsHPROFILE hProfile);
  59.331  
  59.332 -LCMSAPI BOOL          LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len);
  59.333 +LCMSAPI LCMSBOOL      LCMSEXPORT cmsTakeCharTargetData(cmsHPROFILE hProfile, char** Data, size_t* len);
  59.334  
  59.335  LCMSAPI int           LCMSEXPORT cmsReadICCTextEx(cmsHPROFILE hProfile, icTagSignature sig, char *Text, size_t size);
  59.336  LCMSAPI int           LCMSEXPORT cmsReadICCText(cmsHPROFILE hProfile, icTagSignature sig, char *Text);
  59.337 @@ -1038,50 +1045,18 @@
  59.338  LCMSAPI void          LCMSEXPORT cmsFreeProfileSequenceDescription(LPcmsSEQ pseq);
  59.339  
  59.340  
  59.341 -// Extended gamut tag -- an HP extension
  59.342 -
  59.343 -#define LCMSGAMUTMETHOD_SEGMENTMAXIMA   0
  59.344 -#define LCMSGAMUTMETHOD_CONVEXHULL      1
  59.345 -#define LCMSGAMUTMETHOD_ALPHASHAPE      2
  59.346 -
  59.347 -
  59.348 -#define LCMSGAMUT_PHYSICAL                              0
  59.349 -#define LCMSGAMUT_HP1                                   1
  59.350 -#define LCMSGAMUT_HP2                                   2
  59.351 -
  59.352 -typedef struct {
  59.353 -
  59.354 -                        icColorSpaceSignature  CoordSig;        // Gamut coordinates signature
  59.355 -                        icUInt16Number         Method;          // Method used to generate gamut
  59.356 -                        icUInt16Number         Usage;       // Gamut usage or intent
  59.357 -
  59.358 -                        char Description[LCMS_DESC_MAX];        // Textual description
  59.359 -
  59.360 -                        cmsViewingConditions   Vc;                      // The viewing conditions
  59.361 -
  59.362 -                        icUInt32Number         Count;           // Number of entries
  59.363 -                        double                             Data[1];         // The current data
  59.364 -
  59.365 -        } cmsGAMUTEX, FAR* LPcmsGAMUTEX;
  59.366 -
  59.367 -
  59.368 -LCMSAPI LPcmsGAMUTEX LCMSEXPORT cmsReadExtendedGamut(cmsHPROFILE hProfile, int index);
  59.369 -LCMSAPI void         LCMSEXPORT cmsFreeExtendedGamut(LPcmsGAMUTEX gex);
  59.370 -
  59.371 -
  59.372 -
  59.373 -
  59.374  // Translate form/to our notation to ICC
  59.375  LCMSAPI icColorSpaceSignature LCMSEXPORT _cmsICCcolorSpace(int OurNotation);
  59.376 -LCMSAPI                   int LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace);
  59.377 -LCMSAPI                   int LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace);
  59.378 -LCMSAPI BOOL                  LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile);
  59.379 -
  59.380 +LCMSAPI int                   LCMSEXPORT _cmsLCMScolorSpace(icColorSpaceSignature ProfileSpace);
  59.381 +LCMSAPI int                   LCMSEXPORT _cmsChannelsOf(icColorSpaceSignature ColorSpace);
  59.382 +LCMSAPI LCMSBOOL              LCMSEXPORT _cmsIsMatrixShaper(cmsHPROFILE hProfile);
  59.383 +
  59.384 +// How profiles may be used
  59.385  #define LCMS_USED_AS_INPUT      0
  59.386  #define LCMS_USED_AS_OUTPUT     1
  59.387  #define LCMS_USED_AS_PROOF      2
  59.388  
  59.389 -LCMSAPI BOOL         LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection);
  59.390 +LCMSAPI LCMSBOOL                LCMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, int Intent, int UsedDirection);
  59.391  
  59.392  LCMSAPI icColorSpaceSignature   LCMSEXPORT cmsGetPCS(cmsHPROFILE hProfile);
  59.393  LCMSAPI icColorSpaceSignature   LCMSEXPORT cmsGetColorSpace(cmsHPROFILE hProfile);
  59.394 @@ -1141,7 +1116,7 @@
  59.395  
  59.396  // CRD special
  59.397  
  59.398 -#define cmsFLAGS_NODEFAULTRESOURCEDEF     0x00010000
  59.399 +#define cmsFLAGS_NODEFAULTRESOURCEDEF     0x01000000
  59.400  
  59.401  // Gridpoints
  59.402  
  59.403 @@ -1220,9 +1195,9 @@
  59.404  
  59.405  // Named color support
  59.406  
  59.407 -LCMSAPI int  LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform);
  59.408 -LCMSAPI BOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix);
  59.409 -LCMSAPI int  LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name);
  59.410 +LCMSAPI int      LCMSEXPORT cmsNamedColorCount(cmsHTRANSFORM xform);
  59.411 +LCMSAPI LCMSBOOL LCMSEXPORT cmsNamedColorInfo(cmsHTRANSFORM xform, int nColor, char* Name, char* Prefix, char* Suffix);
  59.412 +LCMSAPI int      LCMSEXPORT cmsNamedColorIndex(cmsHTRANSFORM xform, const char* Name);
  59.413  
  59.414  // Colorant tables
  59.415  
  59.416 @@ -1230,7 +1205,7 @@
  59.417  
  59.418  // Profile creation
  59.419  
  59.420 -LCMSAPI BOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data);
  59.421 +LCMSAPI LCMSBOOL LCMSEXPORT cmsAddTag(cmsHPROFILE hProfile, icTagSignature sig, const void* data);
  59.422  
  59.423  // Converts a transform to a devicelink profile
  59.424  LCMSAPI cmsHPROFILE LCMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, DWORD dwFlags);
  59.425 @@ -1240,8 +1215,8 @@
  59.426  
  59.427  
  59.428  // Save profile
  59.429 -LCMSAPI BOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName);
  59.430 -LCMSAPI BOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr,
  59.431 +LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfile(cmsHPROFILE hProfile, const char* FileName);
  59.432 +LCMSAPI LCMSBOOL LCMSEXPORT _cmsSaveProfileToMem(cmsHPROFILE hProfile, void *MemPtr,
  59.433                                                                  size_t* BytesNeeded);
  59.434  
  59.435  
  59.436 @@ -1286,6 +1261,7 @@
  59.437  LCMSAPI LPLUT  LCMSEXPORT cmsReadICCLut(cmsHPROFILE hProfile, icTagSignature sig);
  59.438  LCMSAPI LPLUT  LCMSEXPORT cmsDupLUT(LPLUT Orig);
  59.439  
  59.440 +
  59.441  // LUT Sampling
  59.442  
  59.443  typedef int (* _cmsSAMPLER)(register WORD In[],
  59.444 @@ -1325,35 +1301,37 @@
  59.445  // Persistence
  59.446  LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromFile(const char* cFileName);
  59.447  LCMSAPI LCMSHANDLE      LCMSEXPORT cmsIT8LoadFromMem(void *Ptr, size_t len);
  59.448 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
  59.449 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded);
  59.450 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SaveToFile(LCMSHANDLE IT8, const char* cFileName);
  59.451 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SaveToMem(LCMSHANDLE hIT8, void *MemPtr, size_t* BytesNeeded);
  59.452  
  59.453  // Properties
  59.454  LCMSAPI const char*     LCMSEXPORT cmsIT8GetSheetType(LCMSHANDLE hIT8);
  59.455 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
  59.456 -
  59.457 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
  59.458 -
  59.459 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
  59.460 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
  59.461 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
  59.462 -
  59.463 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
  59.464 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetSheetType(LCMSHANDLE hIT8, const char* Type);
  59.465 +
  59.466 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetComment(LCMSHANDLE hIT8, const char* cComment);
  59.467 +
  59.468 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyStr(LCMSHANDLE hIT8, const char* cProp, const char *Str);
  59.469 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyDbl(LCMSHANDLE hIT8, const char* cProp, double Val);
  59.470 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyHex(LCMSHANDLE hIT8, const char* cProp, int Val);
  59.471 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char* cSubProp, const char *Val);
  59.472 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetPropertyUncooked(LCMSHANDLE hIT8, const char* Key, const char* Buffer);
  59.473  
  59.474  
  59.475  LCMSAPI const char*     LCMSEXPORT cmsIT8GetProperty(LCMSHANDLE hIT8, const char* cProp);
  59.476  LCMSAPI double          LCMSEXPORT cmsIT8GetPropertyDbl(LCMSHANDLE hIT8, const char* cProp);
  59.477 -LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE IT8, char ***PropertyNames);
  59.478 +LCMSAPI const char*     LCMSEXPORT cmsIT8GetPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char *cSubProp);
  59.479 +LCMSAPI int             LCMSEXPORT cmsIT8EnumProperties(LCMSHANDLE hIT8, const char ***PropertyNames);
  59.480 +LCMSAPI int             LCMSEXPORT cmsIT8EnumPropertyMulti(LCMSHANDLE hIT8, const char* cProp, const char*** SubpropertyNames);
  59.481  
  59.482  // Datasets
  59.483  
  59.484  LCMSAPI const char*     LCMSEXPORT cmsIT8GetDataRowCol(LCMSHANDLE IT8, int row, int col);
  59.485  LCMSAPI double          LCMSEXPORT cmsIT8GetDataRowColDbl(LCMSHANDLE IT8, int row, int col);
  59.486  
  59.487 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col,
  59.488 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowCol(LCMSHANDLE hIT8, int row, int col,
  59.489                                                  const char* Val);
  59.490  
  59.491 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col,
  59.492 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataRowColDbl(LCMSHANDLE hIT8, int row, int col,
  59.493                                                  double Val);
  59.494  
  59.495  LCMSAPI const char*     LCMSEXPORT cmsIT8GetData(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
  59.496 @@ -1361,25 +1339,28 @@
  59.497  
  59.498  LCMSAPI double          LCMSEXPORT cmsIT8GetDataDbl(LCMSHANDLE IT8, const char* cPatch, const char* cSample);
  59.499  
  59.500 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
  59.501 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetData(LCMSHANDLE IT8, const char* cPatch,
  59.502                                                  const char* cSample,
  59.503                                                  const char *Val);
  59.504  
  59.505 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
  59.506 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataDbl(LCMSHANDLE hIT8, const char* cPatch,
  59.507                                                  const char* cSample,
  59.508                                                  double Val);
  59.509  
  59.510  LCMSAPI int             LCMSEXPORT cmsIT8GetDataFormat(LCMSHANDLE hIT8, const char* cSample);
  59.511 -LCMSAPI BOOL            LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
  59.512 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetDataFormat(LCMSHANDLE IT8, int n, const char *Sample);
  59.513  LCMSAPI int             LCMSEXPORT cmsIT8EnumDataFormat(LCMSHANDLE IT8, char ***SampleNames);
  59.514  
  59.515  
  59.516  LCMSAPI const char*     LCMSEXPORT cmsIT8GetPatchName(LCMSHANDLE hIT8, int nPatch, char* buffer);
  59.517 +LCMSAPI int             LCMSEXPORT cmsIT8GetPatchByName(LCMSHANDLE hIT8, const char *cSample);
  59.518  
  59.519  // The LABEL extension
  59.520  
  59.521  LCMSAPI int             LCMSEXPORT cmsIT8SetTableByLabel(LCMSHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType);
  59.522  
  59.523 +LCMSAPI LCMSBOOL        LCMSEXPORT cmsIT8SetIndexColumn(LCMSHANDLE hIT8, const char* cSample);
  59.524 +
  59.525  // Formatter for double
  59.526  LCMSAPI void            LCMSEXPORT cmsIT8DefineDblFormat(LCMSHANDLE IT8, const char* Formatter);
  59.527  
  59.528 @@ -1405,15 +1386,16 @@
  59.529  
  59.530  // Profiling Extensions --- Would be removed from API in future revisions
  59.531  
  59.532 -LCMSAPI BOOL LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile,  icTagSignature sig, const char* Text);
  59.533 -LCMSAPI BOOL LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile,   icTagSignature sig, const cmsCIEXYZ* XYZ);
  59.534 -LCMSAPI BOOL LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile,   icTagSignature sig, const void* lut);
  59.535 -LCMSAPI BOOL LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction);
  59.536 -LCMSAPI BOOL LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm);
  59.537 -LCMSAPI BOOL LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq);
  59.538 -LCMSAPI BOOL LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
  59.539 -LCMSAPI BOOL LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime);
  59.540 -LCMSAPI BOOL LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
  59.541 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddTextTag(cmsHPROFILE hProfile,  icTagSignature sig, const char* Text);
  59.542 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddXYZTag(cmsHPROFILE hProfile,   icTagSignature sig, const cmsCIEXYZ* XYZ);
  59.543 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddLUTTag(cmsHPROFILE hProfile,   icTagSignature sig, const void* lut);
  59.544 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddGammaTag(cmsHPROFILE hProfile, icTagSignature sig, LPGAMMATABLE TransferFunction);
  59.545 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddChromaticityTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsCIExyYTRIPLE Chrm);
  59.546 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddSequenceDescriptionTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsSEQ PSeq);
  59.547 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddNamedColorTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
  59.548 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddDateTimeTag(cmsHPROFILE hProfile, icTagSignature sig, struct tm *DateTime);
  59.549 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddColorantTableTag(cmsHPROFILE hProfile, icTagSignature sig, LPcmsNAMEDCOLORLIST nc);
  59.550 +LCMSAPI LCMSBOOL      LCMSEXPORT _cmsAddChromaticAdaptationTag(cmsHPROFILE hProfile, icTagSignature sig, const cmsCIEXYZ* mat);
  59.551  
  59.552  // --------------------------------------------------------------------------------------------------- Inline functions
  59.553  
  59.554 @@ -1455,6 +1437,38 @@
  59.555         return (WORD) in;
  59.556  }
  59.557  
  59.558 +#ifndef LCMS_USER_ALLOC
  59.559 +
  59.560 +// Low-level alloc hook
  59.561 +
  59.562 +LCMS_INLINE void* _cmsMalloc(size_t size)
  59.563 +{
  59.564 +    if (size > ((size_t) 1024*1024*500)) return NULL;  // Never allow over 500Mb
  59.565 +    if (size < 0) return NULL;              // Prevent signed size_t exploits
  59.566 +
  59.567 +    return (void*) malloc(size);
  59.568 +}
  59.569 +
  59.570 +LCMS_INLINE void* _cmsCalloc(size_t nmemb, size_t size)
  59.571 +{
  59.572 +    size_t alloc = nmemb * size;
  59.573 +
  59.574 +        if (size == 0) {
  59.575 +                return _cmsMalloc(0);
  59.576 +        }
  59.577 +        if (alloc / size != nmemb) {
  59.578 +        return NULL;
  59.579 +    }
  59.580 +    return _cmsMalloc(alloc);
  59.581 +}
  59.582 +
  59.583 +LCMS_INLINE void _cmsFree(void *Ptr)
  59.584 +{
  59.585 +    if (Ptr) free(Ptr);
  59.586 +}
  59.587 +
  59.588 +#endif
  59.589 +
  59.590  // ------------------------------------------------------------------------------------------- end of inline functions
  59.591  
  59.592  // Signal error from inside lcms code
  59.593 @@ -1531,36 +1545,36 @@
  59.594  
  59.595  
  59.596  
  59.597 -void   cdecl VEC3init(LPVEC3 r, double x, double y, double z);   // double version
  59.598 -void   cdecl VEC3initF(LPWVEC3 r, double x, double y, double z); // Fix32 version
  59.599 -void   cdecl VEC3toFix(LPWVEC3 r, LPVEC3 v);
  59.600 -void   cdecl VEC3fromFix(LPVEC3 r, LPWVEC3 v);
  59.601 -void   cdecl VEC3scaleFix(LPWORD r, LPWVEC3 Scale);
  59.602 -void   cdecl VEC3swap(LPVEC3 a, LPVEC3 b);
  59.603 -void   cdecl VEC3divK(LPVEC3 r, LPVEC3 v, double d);
  59.604 -void   cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d);
  59.605 -void   cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b);
  59.606 -void   cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b);
  59.607 -BOOL   cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance);
  59.608 -BOOL   cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance);
  59.609 -void   cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d);
  59.610 -void   cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v);
  59.611 -void   cdecl VEC3saturate(LPVEC3 v);
  59.612 -double cdecl VEC3distance(LPVEC3 a, LPVEC3 b);
  59.613 -double cdecl VEC3length(LPVEC3 a);
  59.614 -
  59.615 -void   cdecl MAT3identity(LPMAT3 a);
  59.616 -void   cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
  59.617 -void   cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d);
  59.618 -int    cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
  59.619 -BOOL   cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
  59.620 -double cdecl MAT3det(LPMAT3 m);
  59.621 -void   cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
  59.622 -void   cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
  59.623 -void   cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v);
  59.624 -void   cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v);
  59.625 -BOOL   cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance);
  59.626 -void   cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d);
  59.627 +void      cdecl VEC3init(LPVEC3 r, double x, double y, double z);   // double version
  59.628 +void      cdecl VEC3initF(LPWVEC3 r, double x, double y, double z); // Fix32 version
  59.629 +void      cdecl VEC3toFix(LPWVEC3 r, LPVEC3 v);
  59.630 +void      cdecl VEC3fromFix(LPVEC3 r, LPWVEC3 v);
  59.631 +void      cdecl VEC3scaleFix(LPWORD r, LPWVEC3 Scale);
  59.632 +void      cdecl VEC3swap(LPVEC3 a, LPVEC3 b);
  59.633 +void      cdecl VEC3divK(LPVEC3 r, LPVEC3 v, double d);
  59.634 +void      cdecl VEC3perK(LPVEC3 r, LPVEC3 v, double d);
  59.635 +void      cdecl VEC3minus(LPVEC3 r, LPVEC3 a, LPVEC3 b);
  59.636 +void      cdecl VEC3perComp(LPVEC3 r, LPVEC3 a, LPVEC3 b);
  59.637 +LCMSBOOL  cdecl VEC3equal(LPWVEC3 a, LPWVEC3 b, double Tolerance);
  59.638 +LCMSBOOL  cdecl VEC3equalF(LPVEC3 a, LPVEC3 b, double Tolerance);
  59.639 +void      cdecl VEC3scaleAndCut(LPWVEC3 r, LPVEC3 v, double d);
  59.640 +void      cdecl VEC3cross(LPVEC3 r, LPVEC3 u, LPVEC3 v);
  59.641 +void      cdecl VEC3saturate(LPVEC3 v);
  59.642 +double    cdecl VEC3distance(LPVEC3 a, LPVEC3 b);
  59.643 +double    cdecl VEC3length(LPVEC3 a);
  59.644 +
  59.645 +void      cdecl MAT3identity(LPMAT3 a);
  59.646 +void      cdecl MAT3per(LPMAT3 r, LPMAT3 a, LPMAT3 b);
  59.647 +void      cdecl MAT3perK(LPMAT3 r, LPMAT3 v, double d);
  59.648 +int       cdecl MAT3inverse(LPMAT3 a, LPMAT3 b);
  59.649 +LCMSBOOL  cdecl MAT3solve(LPVEC3 x, LPMAT3 a, LPVEC3 b);
  59.650 +double    cdecl MAT3det(LPMAT3 m);
  59.651 +void      cdecl MAT3eval(LPVEC3 r, LPMAT3 a, LPVEC3 v);
  59.652 +void      cdecl MAT3toFix(LPWMAT3 r, LPMAT3 v);
  59.653 +void      cdecl MAT3fromFix(LPMAT3 r, LPWMAT3 v);
  59.654 +void      cdecl MAT3evalW(LPWVEC3 r, LPWMAT3 a, LPWVEC3 v);
  59.655 +LCMSBOOL  cdecl MAT3isIdentity(LPWMAT3 a, double Tolerance);
  59.656 +void      cdecl MAT3scaleAndCut(LPWMAT3 r, LPMAT3 v, double d);
  59.657  
  59.658  // Is a table linear?
  59.659  
  59.660 @@ -1608,7 +1622,7 @@
  59.661  void    cdecl cmsCalcL16Params(int nSamples, LPL16PARAMS p);
  59.662  void    cdecl cmsCalcCLUT16Params(int nSamples, int InputChan, int OutputChan, LPL16PARAMS p);
  59.663  void    cdecl cmsCalcCLUT16ParamsEx(int nSamples, int InputChan, int OutputChan,
  59.664 -                                            BOOL lUseTetrahedral, LPL16PARAMS p);
  59.665 +                                            LCMSBOOL lUseTetrahedral, LPL16PARAMS p);
  59.666  
  59.667  WORD    cdecl cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p);
  59.668  Fixed32 cdecl cmsLinearInterpFixed(WORD Value1, WORD LutTable[], LPL16PARAMS p);
  59.669 @@ -1692,18 +1706,18 @@
  59.670  
  59.671                 // Gray axes fixup. Only on v2 8-bit Lab LUT
  59.672  
  59.673 -               BOOL FixGrayAxes;
  59.674 -
  59.675 -
  59.676 -                           // Parameters used for curve creation
  59.677 -
  59.678 -                           LCMSGAMMAPARAMS LCurvesSeed[4][MAXCHANNELS];
  59.679 +               LCMSBOOL FixGrayAxes;
  59.680 +
  59.681 +
  59.682 +               // Parameters used for curve creation
  59.683 +
  59.684 +               LCMSGAMMAPARAMS LCurvesSeed[4][MAXCHANNELS];
  59.685  
  59.686  
  59.687                 }; // LUT, FAR* LPLUT;
  59.688  
  59.689  
  59.690 -BOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries);
  59.691 +LCMSBOOL         cdecl _cmsSmoothEndpoints(LPWORD Table, int nEntries);
  59.692  
  59.693  
  59.694  // CRC of gamma tables
  59.695 @@ -1721,7 +1735,7 @@
  59.696  
  59.697  void           cdecl cmsEndpointsOfSampledCurve(LPSAMPLEDCURVE p, double* Min, double* Max);
  59.698  void           cdecl cmsClampSampledCurve(LPSAMPLEDCURVE p, double Min, double Max);
  59.699 -BOOL           cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
  59.700 +LCMSBOOL       cdecl cmsSmoothSampledCurve(LPSAMPLEDCURVE Tab, double SmoothingLambda);
  59.701  void           cdecl cmsRescaleSampledCurve(LPSAMPLEDCURVE p, double Min, double Max, int nPoints);
  59.702  
  59.703  LPSAMPLEDCURVE cdecl cmsJoinSampledCurves(LPSAMPLEDCURVE X, LPSAMPLEDCURVE Y, int nResultingPoints);
  59.704 @@ -1755,19 +1769,19 @@
  59.705  void        cdecl cmsFreeMatShaper(LPMATSHAPER MatShaper);
  59.706  void        cdecl cmsEvalMatShaper(LPMATSHAPER MatShaper, WORD In[], WORD Out[]);
  59.707  
  59.708 -BOOL         cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile);
  59.709 -
  59.710 -LPMATSHAPER  cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile);
  59.711 -LPMATSHAPER  cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile);
  59.712 +LCMSBOOL    cdecl cmsReadICCMatrixRGB2XYZ(LPMAT3 r, cmsHPROFILE hProfile);
  59.713 +
  59.714 +LPMATSHAPER cdecl cmsBuildInputMatrixShaper(cmsHPROFILE InputProfile);
  59.715 +LPMATSHAPER cdecl cmsBuildOutputMatrixShaper(cmsHPROFILE OutputProfile);
  59.716  
  59.717  
  59.718  
  59.719  // White Point & Primary chromas handling
  59.720 -BOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll);
  59.721 -BOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt);
  59.722 -BOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt);
  59.723 -
  59.724 -BOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile);
  59.725 +LCMSBOOL cdecl cmsAdaptationMatrix(LPMAT3 r, LPMAT3 ConeMatrix, LPcmsCIEXYZ FromIll, LPcmsCIEXYZ ToIll);
  59.726 +LCMSBOOL cdecl cmsAdaptMatrixToD50(LPMAT3 r, LPcmsCIExyY SourceWhitePt);
  59.727 +LCMSBOOL cdecl cmsAdaptMatrixFromD50(LPMAT3 r, LPcmsCIExyY DestWhitePt);
  59.728 +
  59.729 +LCMSBOOL cdecl cmsReadChromaticAdaptationMatrix(LPMAT3 r, cmsHPROFILE hProfile);
  59.730  
  59.731  // Inter-PCS conversion routines. They assume D50 as white point.
  59.732  void cdecl cmsXYZ2LabEncoded(WORD XYZ[3], WORD Lab[3]);
  59.733 @@ -1782,7 +1796,7 @@
  59.734  LPcmsNAMEDCOLORLIST  cdecl cmsAllocNamedColorList(int n);
  59.735  int                  cdecl cmsReadICCnamedColorList(cmsHTRANSFORM xform, cmsHPROFILE hProfile, icTagSignature sig);
  59.736  void                 cdecl cmsFreeNamedColorList(LPcmsNAMEDCOLORLIST List);
  59.737 -BOOL                 cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]);
  59.738 +LCMSBOOL             cdecl cmsAppendNamedColor(cmsHTRANSFORM xform, const char* Name, WORD PCS[3], WORD Colorant[MAXCHANNELS]);
  59.739  
  59.740  
  59.741  // I/O
  59.742 @@ -1804,7 +1818,7 @@
  59.743                 icColorSpaceSignature   PCS;
  59.744                 icRenderingIntent       RenderingIntent;
  59.745                 icUInt32Number          flags;
  59.746 -                           icUInt32Number          attributes;
  59.747 +               icUInt32Number          attributes;
  59.748                 cmsCIEXYZ               Illuminant;
  59.749  
  59.750                 // Additions for V4 profiles
  59.751 @@ -1826,22 +1840,23 @@
  59.752  
  59.753                 char                    PhysicalFile[MAX_PATH];
  59.754  
  59.755 -               BOOL                    IsWrite;
  59.756 -               BOOL                    SaveAs8Bits;
  59.757 +               LCMSBOOL                IsWrite;
  59.758 +               LCMSBOOL                SaveAs8Bits;
  59.759  
  59.760                 struct tm               Created;
  59.761  
  59.762                 // I/O handlers
  59.763  
  59.764 -               size_t (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc);
  59.765 -
  59.766 -               BOOL   (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset);
  59.767 -               BOOL   (* Close)(struct _lcms_iccprofile_struct* Icc);
  59.768 -               size_t (* Tell)(struct _lcms_iccprofile_struct* Icc);
  59.769 +               size_t   (* Read)(void *buffer, size_t size, size_t count, struct _lcms_iccprofile_struct* Icc);
  59.770 +
  59.771 +               LCMSBOOL (* Seek)(struct _lcms_iccprofile_struct* Icc, size_t offset);
  59.772 +               LCMSBOOL (* Close)(struct _lcms_iccprofile_struct* Icc);
  59.773 +               size_t   (* Tell)(struct _lcms_iccprofile_struct* Icc);
  59.774 +               LCMSBOOL  (* Grow)(struct _lcms_iccprofile_struct* Icc, size_t amount);
  59.775  
  59.776                 // Writting
  59.777  
  59.778 -               BOOL   (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr);
  59.779 +               LCMSBOOL (* Write)(struct _lcms_iccprofile_struct* Icc, size_t size, LPVOID Ptr);
  59.780  
  59.781                 size_t UsedSpace;
  59.782  
  59.783 @@ -1853,7 +1868,7 @@
  59.784  cmsHPROFILE cdecl _cmsCreateProfilePlaceholder(void);
  59.785  
  59.786  // Search into tag dictionary
  59.787 -icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, BOOL lSignalError);
  59.788 +icInt32Number cdecl _cmsSearchTag(LPLCMSICCPROFILE Profile, icTagSignature sig, LCMSBOOL lSignalError);
  59.789  
  59.790  // Search for a particular tag, replace if found or add new one else
  59.791  LPVOID _cmsInitTag(LPLCMSICCPROFILE Icc, icTagSignature sig, size_t size, const void* Init);
  59.792 @@ -1869,6 +1884,7 @@
  59.793  
  59.794  // These macros unpack format specifiers into integers
  59.795  
  59.796 +#define T_DITHER(s)           (((s)>>22)&1)
  59.797  #define T_COLORSPACE(s)       (((s)>>16)&31)
  59.798  #define T_SWAPFIRST(s)        (((s)>>14)&1)
  59.799  #define T_FLAVOR(s)           (((s)>>13)&1)
  59.800 @@ -1965,7 +1981,7 @@
  59.801  
  59.802                      // Flag for transform involving v4 profiles
  59.803  
  59.804 -                    BOOL lInputV4Lab, lOutputV4Lab;
  59.805 +                    LCMSBOOL lInputV4Lab, lOutputV4Lab;
  59.806  
  59.807  
  59.808                      // 1-pixel cache
  59.809 @@ -1975,7 +1991,7 @@
  59.810  
  59.811                      double AdaptationState; // Figure for v4 incomplete state of adaptation
  59.812  
  59.813 -                                        LCMS_RWLOCK_T rwlock;
  59.814 +                    LCMS_RWLOCK_T rwlock;
  59.815  
  59.816                     } _cmsTRANSFORM,FAR *_LPcmsTRANSFORM;
  59.817  
  59.818 @@ -2012,7 +2028,7 @@
  59.819  
  59.820  // Clamping & Gamut handling
  59.821  
  59.822 -BOOL cdecl   _cmsEndPointsBySpace(icColorSpaceSignature Space,
  59.823 +LCMSBOOL cdecl   _cmsEndPointsBySpace(icColorSpaceSignature Space,
  59.824                              WORD **White, WORD **Black, int *nOutputs);
  59.825  
  59.826  WORD * cdecl _cmsWhiteBySpace(icColorSpaceSignature Space);
  59.827 @@ -2041,7 +2057,7 @@
  59.828  LPLUT cdecl _cmsPrecalculateGamutCheck(cmsHTRANSFORM h);
  59.829  
  59.830  // Hot fixes bad profiles
  59.831 -BOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p);
  59.832 +LCMSBOOL cdecl _cmsFixWhiteMisalignment(_LPcmsTRANSFORM p);
  59.833  
  59.834  // Marks LUT as 8 bit on input
  59.835  LPLUT cdecl _cmsBlessLUT8(LPLUT Lut);
  59.836 @@ -2059,6 +2075,10 @@
  59.837  // Build a tone curve for K->K' if possible (only works on CMYK)
  59.838  LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints);
  59.839  
  59.840 +// Validates a LUT
  59.841 +LCMSBOOL cdecl _cmsValidateLUT(LPLUT NewLUT);
  59.842 +
  59.843 +
  59.844  // These are two VITAL macros, from converting between 8 and 16 bit
  59.845  // representation.
  59.846  
  59.847 @@ -2076,3 +2096,4 @@
  59.848  #endif
  59.849  
  59.850  #endif
  59.851 +
    60.1 --- a/src/solaris/classes/sun/awt/X11/XFontPeer.java	Tue Apr 07 11:43:20 2009 -0700
    60.2 +++ b/src/solaris/classes/sun/awt/X11/XFontPeer.java	Tue Apr 07 14:02:54 2009 -0700
    60.3 @@ -27,9 +27,6 @@
    60.4  import sun.awt.PlatformFont;
    60.5  import java.awt.GraphicsEnvironment;
    60.6  
    60.7 -/* FIX ME */
    60.8 -import sun.awt.motif.MFontConfiguration;
    60.9 -
   60.10  public class XFontPeer extends PlatformFont {
   60.11  
   60.12      /*
   60.13 @@ -51,10 +48,6 @@
   60.14  
   60.15      public XFontPeer(String name, int style){
   60.16          super(name, style);
   60.17 -
   60.18 -        if (fontConfig != null){
   60.19 -            xfsname = ((MFontConfiguration) fontConfig).getMotifFontSet(familyName, style);
   60.20 -        }
   60.21      }
   60.22  
   60.23      protected char getMissingGlyphCharacter() {
    61.1 --- a/src/solaris/classes/sun/font/FcFontConfiguration.java	Tue Apr 07 11:43:20 2009 -0700
    61.2 +++ b/src/solaris/classes/sun/font/FcFontConfiguration.java	Tue Apr 07 14:02:54 2009 -0700
    61.3 @@ -15,7 +15,7 @@
    61.4   * accompanied this code).
    61.5   *
    61.6   * You should have received a copy of the GNU General Public License version
    61.7 - * along with this work; if not, write to the Free Software Foundation,
    61.8 + * 2 along with this work; if not, write to the Free Software Foundation,
    61.9   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   61.10   *
   61.11   * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   61.12 @@ -87,6 +87,7 @@
   61.13              return true;
   61.14          }
   61.15  
   61.16 +        setFontConfiguration();
   61.17          readFcInfo();
   61.18          if (fcCompFonts == null) {
   61.19              fcCompFonts = FontManager.loadFontConfig();
   61.20 @@ -172,7 +173,7 @@
   61.21  
   61.22      @Override
   61.23      public FontDescriptor[] getFontDescriptors(String fontName, int style) {
   61.24 -        throw new InternalError("Not implemented");
   61.25 +        return new FontDescriptor[0];
   61.26      }
   61.27  
   61.28      @Override
    62.1 --- a/src/solaris/classes/sun/print/IPPPrintService.java	Tue Apr 07 11:43:20 2009 -0700
    62.2 +++ b/src/solaris/classes/sun/print/IPPPrintService.java	Tue Apr 07 14:02:54 2009 -0700
    62.3 @@ -661,6 +661,12 @@
    62.4                  }
    62.5              }
    62.6          } else if (category == OrientationRequested.class) {
    62.7 +            if (flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||
    62.8 +                flavor.equals(DocFlavor.URL.POSTSCRIPT) ||
    62.9 +                flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT)) {
   62.10 +                return null;
   62.11 +            }
   62.12 +
   62.13              boolean revPort = false;
   62.14              OrientationRequested[] orientSup = null;
   62.15  
    63.1 --- a/src/solaris/classes/sun/print/UnixPrintJob.java	Tue Apr 07 11:43:20 2009 -0700
    63.2 +++ b/src/solaris/classes/sun/print/UnixPrintJob.java	Tue Apr 07 14:02:54 2009 -0700
    63.3 @@ -362,10 +362,10 @@
    63.4                   mOptions += " number-up="+nUp.getValue();
    63.5               }
    63.6  
    63.7 -             if (orient == OrientationRequested.LANDSCAPE &&
    63.8 +             if (orient != OrientationRequested.PORTRAIT &&
    63.9                   (flavor != null) &&
   63.10                   !flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)) {
   63.11 -                 mOptions += " landscape";
   63.12 +                 mOptions += " orientation-requested="+orient.getValue();
   63.13               }
   63.14  
   63.15               if (sides != null) {
    64.1 --- a/src/windows/classes/sun/awt/windows/WFontConfiguration.java	Tue Apr 07 11:43:20 2009 -0700
    64.2 +++ b/src/windows/classes/sun/awt/windows/WFontConfiguration.java	Tue Apr 07 14:02:54 2009 -0700
    64.3 @@ -61,18 +61,10 @@
    64.4               * been opened and its fonts loaded.
    64.5               * Also note this usage is only enabled if a private flag is set.
    64.6               */
    64.7 -            if ("98".equals(osName) || "Me".equals(osName)) {
    64.8 -                localeMap.put("dialoginput.plain.japanese", "\uff2d\uff33 \u660e\u671d");
    64.9 -                localeMap.put("dialoginput.bold.japanese", "\uff2d\uff33 \u660e\u671d");
   64.10 -                localeMap.put("dialoginput.italic.japanese", "\uff2d\uff33 \u660e\u671d");
   64.11 -                localeMap.put("dialoginput.bolditalic.japanese", "\uff2d\uff33 \u660e\u671d");
   64.12 -            } else {
   64.13 -
   64.14 -                localeMap.put("dialoginput.plain.japanese", "MS Mincho");
   64.15 -                localeMap.put("dialoginput.bold.japanese", "MS Mincho");
   64.16 -                localeMap.put("dialoginput.italic.japanese", "MS Mincho");
   64.17 -                localeMap.put("dialoginput.bolditalic.japanese", "MS Mincho");
   64.18 -            }
   64.19 +            localeMap.put("dialoginput.plain.japanese", "MS Mincho");
   64.20 +            localeMap.put("dialoginput.bold.japanese", "MS Mincho");
   64.21 +            localeMap.put("dialoginput.italic.japanese", "MS Mincho");
   64.22 +            localeMap.put("dialoginput.bolditalic.japanese", "MS Mincho");
   64.23          }
   64.24          reorderMap = new HashMap();
   64.25          reorderMap.put("UTF-8.hi", "devanagari");
    65.1 --- a/src/windows/classes/sun/awt/windows/fontconfig.98.properties	Tue Apr 07 11:43:20 2009 -0700
    65.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.3 @@ -1,241 +0,0 @@
    65.4 -#
    65.5 -# 
    65.6 -# Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
    65.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    65.8 -#
    65.9 -# This code is free software; you can redistribute it and/or modify it
   65.10 -# under the terms of the GNU General Public License version 2 only, as
   65.11 -# published by the Free Software Foundation.  Sun designates this
   65.12 -# particular file as subject to the "Classpath" exception as provided
   65.13 -# by Sun in the LICENSE file that accompanied this code.
   65.14 -#
   65.15 -# This code is distributed in the hope that it will be useful, but WITHOUT
   65.16 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   65.17 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   65.18 -# version 2 for more details (a copy is included in the LICENSE file that
   65.19 -# accompanied this code).
   65.20 -#
   65.21 -# You should have received a copy of the GNU General Public License version
   65.22 -# 2 along with this work; if not, write to the Free Software Foundation,
   65.23 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   65.24 -#
   65.25 -# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   65.26 -# CA 95054 USA or visit www.sun.com if you need additional information or
   65.27 -# have any questions.
   65.28 -#
   65.29 -
   65.30 -# Version
   65.31 -
   65.32 -version=1
   65.33 -
   65.34 -# Component Font Mappings
   65.35 -
   65.36 -allfonts.chinese-ms936=SimSun
   65.37 -allfonts.dingbats=Wingdings
   65.38 -allfonts.lucida=Lucida Sans Regular
   65.39 -allfonts.symbol=Symbol
   65.40 -allfonts.thai=Lucida Sans Regular
   65.41 -
   65.42 -serif.plain.alphabetic=Times New Roman
   65.43 -serif.plain.chinese-ms950=MingLiU
   65.44 -serif.plain.hebrew=David
   65.45 -serif.plain.japanese=\uff2d\uff33 \u660e\u671d
   65.46 -serif.plain.korean=Batang
   65.47 -
   65.48 -serif.bold.alphabetic=Times New Roman Bold
   65.49 -serif.bold.chinese-ms950=PMingLiU
   65.50 -serif.bold.hebrew=David Bold
   65.51 -serif.bold.japanese=\uff2d\uff33 \u660e\u671d
   65.52 -serif.bold.korean=Batang
   65.53 -
   65.54 -serif.italic.alphabetic=Times New Roman Italic
   65.55 -serif.italic.chinese-ms950=PMingLiU
   65.56 -serif.italic.hebrew=David
   65.57 -serif.italic.japanese=\uff2d\uff33 \u660e\u671d
   65.58 -serif.italic.korean=Batang
   65.59 -
   65.60 -serif.bolditalic.alphabetic=Times New Roman Bold Italic
   65.61 -serif.bolditalic.chinese-ms950=PMingLiU
   65.62 -serif.bolditalic.hebrew=David Bold
   65.63 -serif.bolditalic.japanese=\uff2d\uff33 \u660e\u671d
   65.64 -serif.bolditalic.korean=Batang
   65.65 -
   65.66 -sansserif.plain.alphabetic=Arial
   65.67 -sansserif.plain.chinese-ms950=MingLiU
   65.68 -sansserif.plain.hebrew=David
   65.69 -sansserif.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   65.70 -sansserif.plain.korean=Gulim
   65.71 -
   65.72 -sansserif.bold.alphabetic=Arial Bold
   65.73 -sansserif.bold.chinese-ms950=PMingLiU
   65.74 -sansserif.bold.hebrew=David Bold
   65.75 -sansserif.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   65.76 -sansserif.bold.korean=Gulim
   65.77 -
   65.78 -sansserif.italic.alphabetic=Arial Italic
   65.79 -sansserif.italic.chinese-ms950=PMingLiU
   65.80 -sansserif.italic.hebrew=David
   65.81 -sansserif.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   65.82 -sansserif.italic.korean=Gulim
   65.83 -
   65.84 -sansserif.bolditalic.alphabetic=Arial Bold Italic
   65.85 -sansserif.bolditalic.chinese-ms950=PMingLiU
   65.86 -sansserif.bolditalic.hebrew=David Bold
   65.87 -sansserif.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   65.88 -sansserif.bolditalic.korean=Gulim
   65.89 -
   65.90 -monospaced.plain.alphabetic=Courier New
   65.91 -monospaced.plain.chinese-ms950=MingLiU
   65.92 -monospaced.plain.hebrew=David
   65.93 -monospaced.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   65.94 -monospaced.plain.korean=GulimChe
   65.95 -
   65.96 -monospaced.bold.alphabetic=Courier New Bold
   65.97 -monospaced.bold.chinese-ms950=PMingLiU
   65.98 -monospaced.bold.hebrew=David Bold
   65.99 -monospaced.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.100 -monospaced.bold.korean=GulimChe
  65.101 -
  65.102 -monospaced.italic.alphabetic=Courier New Italic
  65.103 -monospaced.italic.chinese-ms950=PMingLiU
  65.104 -monospaced.italic.hebrew=David
  65.105 -monospaced.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.106 -monospaced.italic.korean=GulimChe
  65.107 -
  65.108 -monospaced.bolditalic.alphabetic=Courier New Bold Italic
  65.109 -monospaced.bolditalic.chinese-ms950=PMingLiU
  65.110 -monospaced.bolditalic.hebrew=David Bold
  65.111 -monospaced.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.112 -monospaced.bolditalic.korean=GulimChe
  65.113 -
  65.114 -dialog.plain.alphabetic=Arial
  65.115 -dialog.plain.chinese-ms950=MingLiU
  65.116 -dialog.plain.hebrew=David
  65.117 -dialog.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.118 -dialog.plain.korean=Gulim
  65.119 -
  65.120 -dialog.bold.alphabetic=Arial Bold
  65.121 -dialog.bold.chinese-ms950=PMingLiU
  65.122 -dialog.bold.hebrew=David Bold
  65.123 -dialog.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.124 -dialog.bold.korean=Gulim
  65.125 -
  65.126 -dialog.italic.alphabetic=Arial Italic
  65.127 -dialog.italic.chinese-ms950=PMingLiU
  65.128 -dialog.italic.hebrew=David
  65.129 -dialog.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.130 -dialog.italic.korean=Gulim
  65.131 -
  65.132 -dialog.bolditalic.alphabetic=Arial Bold Italic
  65.133 -dialog.bolditalic.chinese-ms950=PMingLiU
  65.134 -dialog.bolditalic.hebrew=David Bold
  65.135 -dialog.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.136 -dialog.bolditalic.korean=Gulim
  65.137 -
  65.138 -dialoginput.plain.alphabetic=Courier New
  65.139 -dialoginput.plain.chinese-ms950=MingLiU
  65.140 -dialoginput.plain.hebrew=David
  65.141 -dialoginput.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.142 -dialoginput.plain.korean=Gulim
  65.143 -
  65.144 -dialoginput.bold.alphabetic=Courier New Bold
  65.145 -dialoginput.bold.chinese-ms950=PMingLiU
  65.146 -dialoginput.bold.hebrew=David Bold
  65.147 -dialoginput.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.148 -dialoginput.bold.korean=Gulim
  65.149 -
  65.150 -dialoginput.italic.alphabetic=Courier New Italic
  65.151 -dialoginput.italic.chinese-ms950=PMingLiU
  65.152 -dialoginput.italic.hebrew=David
  65.153 -dialoginput.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.154 -dialoginput.italic.korean=Gulim
  65.155 -
  65.156 -dialoginput.bolditalic.alphabetic=Courier New Bold Italic
  65.157 -dialoginput.bolditalic.chinese-ms950=PMingLiU
  65.158 -dialoginput.bolditalic.hebrew=David Bold
  65.159 -dialoginput.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  65.160 -dialoginput.bolditalic.korean=Gulim
  65.161 -
  65.162 -# Search Sequences
  65.163 -
  65.164 -sequence.allfonts=alphabetic/default,dingbats,symbol
  65.165 -
  65.166 -sequence.serif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  65.167 -sequence.sansserif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  65.168 -sequence.monospaced.GBK=chinese-ms936,alphabetic/1252,dingbats,symbol
  65.169 -sequence.dialog.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  65.170 -sequence.dialoginput.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  65.171 -
  65.172 -sequence.serif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  65.173 -sequence.sansserif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  65.174 -sequence.monospaced.x-windows-950=chinese-ms950,alphabetic/1252,dingbats,symbol
  65.175 -sequence.dialog.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  65.176 -sequence.dialoginput.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  65.177 -
  65.178 -sequence.allfonts.windows-1255=hebrew,alphabetic/1252,dingbats,symbol
  65.179 -
  65.180 -sequence.serif.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  65.181 -sequence.sansserif.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  65.182 -sequence.monospaced.windows-31j=japanese,alphabetic/1252,dingbats,symbol
  65.183 -sequence.dialog.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  65.184 -sequence.dialoginput.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  65.185 -
  65.186 -sequence.serif.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  65.187 -sequence.sansserif.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  65.188 -sequence.monospaced.x-windows-949=korean,alphabetic/1252,dingbats,symbol
  65.189 -sequence.dialog.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  65.190 -sequence.dialoginput.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  65.191 -
  65.192 -sequence.allfonts.x-windows-874=alphabetic/1252,thai,dingbats,symbol
  65.193 -
  65.194 -sequence.fallback=lucida
  65.195 -
  65.196 -# Exclusion Ranges
  65.197 -
  65.198 -exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff
  65.199 -exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac
  65.200 -
  65.201 -# Monospaced to Proportional width variant mapping
  65.202 -# (Experimental private syntax)
  65.203 -proportional.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=\uff2d\uff33 \uff30\u30b4\u30b7\u30c3\u30af
  65.204 -proportional.\uff2d\uff33_\u660e\u671d=\uff2d\uff33 \uff30\u660e\u671d
  65.205 -proportional.MingLiU=PMingLiU
  65.206 -
  65.207 -# Font File Names
  65.208 -
  65.209 -filename.Arial=ARIAL.TTF
  65.210 -filename.Arial_Bold=ARIALBD.TTF
  65.211 -filename.Arial_Italic=ARIALI.TTF
  65.212 -filename.Arial_Bold_Italic=ARIALBI.TTF
  65.213 -
  65.214 -filename.Courier_New=COUR.TTF
  65.215 -filename.Courier_New_Bold=COURBD.TTF
  65.216 -filename.Courier_New_Italic=COURI.TTF
  65.217 -filename.Courier_New_Bold_Italic=COURBI.TTF
  65.218 -
  65.219 -filename.Times_New_Roman=TIMES.TTF
  65.220 -filename.Times_New_Roman_Bold=TIMESBD.TTF
  65.221 -filename.Times_New_Roman_Italic=TIMESI.TTF
  65.222 -filename.Times_New_Roman_Bold_Italic=TIMESBI.TTF
  65.223 -
  65.224 -filename.SimSun=SIMSUN.TTF
  65.225 -
  65.226 -filename.MingLiU=MINGLIU.TTC
  65.227 -filename.PMingLiU=MINGLIU.TTC
  65.228 -
  65.229 -filename.David=DAVID.TTF
  65.230 -filename.David_Bold=DAVIDBD.TTF
  65.231 -
  65.232 -filename.\uff2d\uff33_\u660e\u671d=MSMINCHO.TTC
  65.233 -filename.\uff2d\uff33_\uff30\u660e\u671d=MSMINCHO.TTC
  65.234 -filename.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC
  65.235 -filename.\uff2d\uff33_\uff30\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC
  65.236 -
  65.237 -filename.Gulim=gulim.TTC
  65.238 -filename.Batang=batang.TTC
  65.239 -filename.GulimChe=gulim.TTC
  65.240 -
  65.241 -filename.Lucida_Sans_Regular=LucidaSansRegular.ttf
  65.242 -filename.Symbol=SYMBOL.TTF
  65.243 -filename.Wingdings=WINGDING.TTF
  65.244 -
    66.1 --- a/src/windows/classes/sun/awt/windows/fontconfig.Me.properties	Tue Apr 07 11:43:20 2009 -0700
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,241 +0,0 @@
    66.4 -#
    66.5 -# 
    66.6 -# Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
    66.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    66.8 -#
    66.9 -# This code is free software; you can redistribute it and/or modify it
   66.10 -# under the terms of the GNU General Public License version 2 only, as
   66.11 -# published by the Free Software Foundation.  Sun designates this
   66.12 -# particular file as subject to the "Classpath" exception as provided
   66.13 -# by Sun in the LICENSE file that accompanied this code.
   66.14 -#
   66.15 -# This code is distributed in the hope that it will be useful, but WITHOUT
   66.16 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   66.17 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   66.18 -# version 2 for more details (a copy is included in the LICENSE file that
   66.19 -# accompanied this code).
   66.20 -#
   66.21 -# You should have received a copy of the GNU General Public License version
   66.22 -# 2 along with this work; if not, write to the Free Software Foundation,
   66.23 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   66.24 -#
   66.25 -# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   66.26 -# CA 95054 USA or visit www.sun.com if you need additional information or
   66.27 -# have any questions.
   66.28 -#
   66.29 -
   66.30 -# Version
   66.31 -
   66.32 -version=1
   66.33 -
   66.34 -# Component Font Mappings
   66.35 -
   66.36 -allfonts.chinese-ms936=SimSun
   66.37 -allfonts.dingbats=Wingdings
   66.38 -allfonts.lucida=Lucida Sans Regular
   66.39 -allfonts.symbol=Symbol
   66.40 -allfonts.thai=Lucida Sans Regular
   66.41 -
   66.42 -serif.plain.alphabetic=Times New Roman
   66.43 -serif.plain.chinese-ms950=MingLiU
   66.44 -serif.plain.hebrew=David
   66.45 -serif.plain.japanese=\uff2d\uff33 \u660e\u671d
   66.46 -serif.plain.korean=Batang
   66.47 -
   66.48 -serif.bold.alphabetic=Times New Roman Bold
   66.49 -serif.bold.chinese-ms950=PMingLiU
   66.50 -serif.bold.hebrew=David Bold
   66.51 -serif.bold.japanese=\uff2d\uff33 \u660e\u671d
   66.52 -serif.bold.korean=Batang
   66.53 -
   66.54 -serif.italic.alphabetic=Times New Roman Italic
   66.55 -serif.italic.chinese-ms950=PMingLiU
   66.56 -serif.italic.hebrew=David
   66.57 -serif.italic.japanese=\uff2d\uff33 \u660e\u671d
   66.58 -serif.italic.korean=Batang
   66.59 -
   66.60 -serif.bolditalic.alphabetic=Times New Roman Bold Italic
   66.61 -serif.bolditalic.chinese-ms950=PMingLiU
   66.62 -serif.bolditalic.hebrew=David Bold
   66.63 -serif.bolditalic.japanese=\uff2d\uff33 \u660e\u671d
   66.64 -serif.bolditalic.korean=Batang
   66.65 -
   66.66 -sansserif.plain.alphabetic=Arial
   66.67 -sansserif.plain.chinese-ms950=MingLiU
   66.68 -sansserif.plain.hebrew=David
   66.69 -sansserif.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   66.70 -sansserif.plain.korean=Gulim
   66.71 -
   66.72 -sansserif.bold.alphabetic=Arial Bold
   66.73 -sansserif.bold.chinese-ms950=PMingLiU
   66.74 -sansserif.bold.hebrew=David Bold
   66.75 -sansserif.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   66.76 -sansserif.bold.korean=Gulim
   66.77 -
   66.78 -sansserif.italic.alphabetic=Arial Italic
   66.79 -sansserif.italic.chinese-ms950=PMingLiU
   66.80 -sansserif.italic.hebrew=David
   66.81 -sansserif.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   66.82 -sansserif.italic.korean=Gulim
   66.83 -
   66.84 -sansserif.bolditalic.alphabetic=Arial Bold Italic
   66.85 -sansserif.bolditalic.chinese-ms950=PMingLiU
   66.86 -sansserif.bolditalic.hebrew=David Bold
   66.87 -sansserif.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   66.88 -sansserif.bolditalic.korean=Gulim
   66.89 -
   66.90 -monospaced.plain.alphabetic=Courier New
   66.91 -monospaced.plain.chinese-ms950=MingLiU
   66.92 -monospaced.plain.hebrew=David
   66.93 -monospaced.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
   66.94 -monospaced.plain.korean=GulimChe
   66.95 -
   66.96 -monospaced.bold.alphabetic=Courier New Bold
   66.97 -monospaced.bold.chinese-ms950=PMingLiU
   66.98 -monospaced.bold.hebrew=David Bold
   66.99 -monospaced.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.100 -monospaced.bold.korean=GulimChe
  66.101 -
  66.102 -monospaced.italic.alphabetic=Courier New Italic
  66.103 -monospaced.italic.chinese-ms950=PMingLiU
  66.104 -monospaced.italic.hebrew=David
  66.105 -monospaced.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.106 -monospaced.italic.korean=GulimChe
  66.107 -
  66.108 -monospaced.bolditalic.alphabetic=Courier New Bold Italic
  66.109 -monospaced.bolditalic.chinese-ms950=PMingLiU
  66.110 -monospaced.bolditalic.hebrew=David Bold
  66.111 -monospaced.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.112 -monospaced.bolditalic.korean=GulimChe
  66.113 -
  66.114 -dialog.plain.alphabetic=Arial
  66.115 -dialog.plain.chinese-ms950=MingLiU
  66.116 -dialog.plain.hebrew=David
  66.117 -dialog.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.118 -dialog.plain.korean=Gulim
  66.119 -
  66.120 -dialog.bold.alphabetic=Arial Bold
  66.121 -dialog.bold.chinese-ms950=PMingLiU
  66.122 -dialog.bold.hebrew=David Bold
  66.123 -dialog.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.124 -dialog.bold.korean=Gulim
  66.125 -
  66.126 -dialog.italic.alphabetic=Arial Italic
  66.127 -dialog.italic.chinese-ms950=PMingLiU
  66.128 -dialog.italic.hebrew=David
  66.129 -dialog.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.130 -dialog.italic.korean=Gulim
  66.131 -
  66.132 -dialog.bolditalic.alphabetic=Arial Bold Italic
  66.133 -dialog.bolditalic.chinese-ms950=PMingLiU
  66.134 -dialog.bolditalic.hebrew=David Bold
  66.135 -dialog.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.136 -dialog.bolditalic.korean=Gulim
  66.137 -
  66.138 -dialoginput.plain.alphabetic=Courier New
  66.139 -dialoginput.plain.chinese-ms950=MingLiU
  66.140 -dialoginput.plain.hebrew=David
  66.141 -dialoginput.plain.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.142 -dialoginput.plain.korean=Gulim
  66.143 -
  66.144 -dialoginput.bold.alphabetic=Courier New Bold
  66.145 -dialoginput.bold.chinese-ms950=PMingLiU
  66.146 -dialoginput.bold.hebrew=David Bold
  66.147 -dialoginput.bold.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.148 -dialoginput.bold.korean=Gulim
  66.149 -
  66.150 -dialoginput.italic.alphabetic=Courier New Italic
  66.151 -dialoginput.italic.chinese-ms950=PMingLiU
  66.152 -dialoginput.italic.hebrew=David
  66.153 -dialoginput.italic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.154 -dialoginput.italic.korean=Gulim
  66.155 -
  66.156 -dialoginput.bolditalic.alphabetic=Courier New Bold Italic
  66.157 -dialoginput.bolditalic.chinese-ms950=PMingLiU
  66.158 -dialoginput.bolditalic.hebrew=David Bold
  66.159 -dialoginput.bolditalic.japanese=\uff2d\uff33 \u30b4\u30b7\u30c3\u30af
  66.160 -dialoginput.bolditalic.korean=Gulim
  66.161 -
  66.162 -# Search Sequences
  66.163 -
  66.164 -sequence.allfonts=alphabetic/default,dingbats,symbol
  66.165 -
  66.166 -sequence.serif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  66.167 -sequence.sansserif.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  66.168 -sequence.monospaced.GBK=chinese-ms936,alphabetic/1252,dingbats,symbol
  66.169 -sequence.dialog.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  66.170 -sequence.dialoginput.GBK=alphabetic/1252,chinese-ms936,dingbats,symbol
  66.171 -
  66.172 -sequence.serif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  66.173 -sequence.sansserif.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  66.174 -sequence.monospaced.x-windows-950=chinese-ms950,alphabetic/1252,dingbats,symbol
  66.175 -sequence.dialog.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  66.176 -sequence.dialoginput.x-windows-950=alphabetic/1252,chinese-ms950,dingbats,symbol
  66.177 -
  66.178 -sequence.allfonts.windows-1255=hebrew,alphabetic/1252,dingbats,symbol
  66.179 -
  66.180 -sequence.serif.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  66.181 -sequence.sansserif.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  66.182 -sequence.monospaced.windows-31j=japanese,alphabetic/1252,dingbats,symbol
  66.183 -sequence.dialog.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  66.184 -sequence.dialoginput.windows-31j=alphabetic/1252,japanese,dingbats,symbol
  66.185 -
  66.186 -sequence.serif.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  66.187 -sequence.sansserif.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  66.188 -sequence.monospaced.x-windows-949=korean,alphabetic/1252,dingbats,symbol
  66.189 -sequence.dialog.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  66.190 -sequence.dialoginput.x-windows-949=alphabetic/1252,korean,dingbats,symbol
  66.191 -
  66.192 -sequence.allfonts.x-windows-874=alphabetic/1252,thai,dingbats,symbol
  66.193 -
  66.194 -sequence.fallback=lucida
  66.195 -
  66.196 -# Exclusion Ranges
  66.197 -
  66.198 -exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff
  66.199 -exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac
  66.200 -
  66.201 -# Monospaced to Proportional width variant mapping
  66.202 -# (Experimental private syntax)
  66.203 -proportional.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=\uff2d\uff33 \uff30\u30b4\u30b7\u30c3\u30af
  66.204 -proportional.\uff2d\uff33_\u660e\u671d=\uff2d\uff33 \uff30\u660e\u671d
  66.205 -proportional.MingLiU=PMingLiU
  66.206 -
  66.207 -# Font File Names
  66.208 -
  66.209 -filename.Arial=ARIAL.TTF
  66.210 -filename.Arial_Bold=ARIALBD.TTF
  66.211 -filename.Arial_Italic=ARIALI.TTF
  66.212 -filename.Arial_Bold_Italic=ARIALBI.TTF
  66.213 -
  66.214 -filename.Courier_New=COUR.TTF
  66.215 -filename.Courier_New_Bold=COURBD.TTF
  66.216 -filename.Courier_New_Italic=COURI.TTF
  66.217 -filename.Courier_New_Bold_Italic=COURBI.TTF
  66.218 -
  66.219 -filename.Times_New_Roman=TIMES.TTF
  66.220 -filename.Times_New_Roman_Bold=TIMESBD.TTF
  66.221 -filename.Times_New_Roman_Italic=TIMESI.TTF
  66.222 -filename.Times_New_Roman_Bold_Italic=TIMESBI.TTF
  66.223 -
  66.224 -filename.SimSun=SIMSUN.TTF
  66.225 -
  66.226 -filename.MingLiU=MINGLIU.TTC
  66.227 -filename.PMingLiU=MINGLIU.TTC
  66.228 -
  66.229 -filename.David=DAVID.TTF
  66.230 -filename.David_Bold=DAVIDBD.TTF
  66.231 -
  66.232 -filename.\uff2d\uff33_\u660e\u671d=MSMINCHO.TTC
  66.233 -filename.\uff2d\uff33_\uff30\u660e\u671d=MSMINCHO.TTC
  66.234 -filename.\uff2d\uff33_\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC
  66.235 -filename.\uff2d\uff33_\uff30\u30b4\u30b7\u30c3\u30af=MSGOTHIC.TTC
  66.236 -
  66.237 -filename.Gulim=gulim.TTC
  66.238 -filename.Batang=batang.TTC
  66.239 -filename.GulimChe=gulim.TTC
  66.240 -
  66.241 -filename.Lucida_Sans_Regular=LucidaSansRegular.ttf
  66.242 -filename.Symbol=SYMBOL.TTF
  66.243 -filename.Wingdings=WINGDING.TTF
  66.244 -
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/test/java/awt/FontClass/FontAccess.java	Tue Apr 07 14:02:54 2009 -0700
    67.3 @@ -0,0 +1,48 @@
    67.4 +/*
    67.5 + * Copyright (c) 2009 Sun Microsystems, Inc.  All Rights Reserved.
    67.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    67.7 + *
    67.8 + * This code is free software; you can redistribute it and/or modify it
    67.9 + * under the terms of the GNU General Public License version 2 only, as
   67.10 + * published by the Free Software Foundation.
   67.11 + *
   67.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   67.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   67.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   67.15 + * version 2 for more details (a copy is included in the LICENSE file that
   67.16 + * accompanied this code).
   67.17 + *
   67.18 + * You should have received a copy of the GNU General Public License version
   67.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   67.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   67.21 + *
   67.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   67.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   67.24 + * have any questions.
   67.25 + */
   67.26 +
   67.27 +/*
   67.28 + * @test
   67.29 + * @bug 6785424
   67.30 + * @summary Test no SecurityException searching for a font.
   67.31 + * @run main FontAccess
   67.32 + *
   67.33 + * This can only test the specific bug if run on something like
   67.34 + * Windows Citrix Server where SystemDirectory and WindowsDirectory
   67.35 + * are different locations.
   67.36 + */
   67.37 +
   67.38 +import java.awt.*;
   67.39 +import java.awt.image.*;
   67.40 +
   67.41 +public class FontAccess {
   67.42 +
   67.43 +     public static void main(String[] args) {
   67.44 +        System.setSecurityManager(new SecurityManager());
   67.45 +        Font f = new Font("Verdana", Font.PLAIN, 12);
   67.46 +        BufferedImage bi = new BufferedImage(1,1,1);
   67.47 +        Graphics2D g = bi.createGraphics();
   67.48 +        g.setFont(f);
   67.49 +        System.out.println(g.getFontMetrics());
   67.50 +     }
   67.51 +}
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/test/java/awt/GraphicsEnvironment/PreferLocaleFonts.java	Tue Apr 07 14:02:54 2009 -0700
    68.3 @@ -0,0 +1,62 @@
    68.4 +/*
    68.5 + * Copyright (c) 2008 Sun Microsystems, Inc.  All Rights Reserved.
    68.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    68.7 + *
    68.8 + * This code is free software; you can redistribute it and/or modify it
    68.9 + * under the terms of the GNU General Public License version 2 only, as
   68.10 + * published by the Free Software Foundation.
   68.11 + *
   68.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   68.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   68.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   68.15 + * version 2 for more details (a copy is included in the LICENSE file that
   68.16 + * accompanied this code).
   68.17 + *
   68.18 + * You should have received a copy of the GNU General Public License version
   68.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   68.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   68.21 + *
   68.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   68.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   68.24 + * have any questions.
   68.25 + */
   68.26 +
   68.27 +/*
   68.28 + * @test
   68.29 + * @bug 6752638
   68.30 + * @summary Test no NPE calling preferLocaleFonts() on custom GE.
   68.31 + * @run main PreferLocaleFonts
   68.32 + */
   68.33 +
   68.34 +import java.util.*;
   68.35 +import java.awt.*;
   68.36 +import java.awt.image.*;
   68.37 +
   68.38 +public class PreferLocaleFonts extends GraphicsEnvironment {
   68.39 +
   68.40 +    public static void main(String args[]) {
   68.41 +(new PreferLocaleFonts()).preferLocaleFonts();
   68.42 +    }
   68.43 +    public PreferLocaleFonts() {
   68.44 +        super();
   68.45 +    }
   68.46 +    public Graphics2D createGraphics(BufferedImage image) {
   68.47 +        return null;
   68.48 +    }
   68.49 +    public String[] getAvailableFontFamilyNames(Locale locale) {
   68.50 +        return null;
   68.51 +    }
   68.52 +    public String[] getAvailableFontFamilyNames() {
   68.53 +        return null;
   68.54 +    }
   68.55 +    public Font[] getAllFonts() {
   68.56 +        return null;
   68.57 +    }
   68.58 +    public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
   68.59 +        return null;
   68.60 +    }
   68.61 +    public GraphicsDevice[] getScreenDevices() throws HeadlessException {
   68.62 +        return null;
   68.63 +    }
   68.64 +}
   68.65 +
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/test/java/awt/font/LineBreakMeasurer/FRCTest.java	Tue Apr 07 14:02:54 2009 -0700
    69.3 @@ -0,0 +1,90 @@
    69.4 +/*
    69.5 + * Copyright 2008-9 Sun Microsystems, Inc.  All Rights Reserved.
    69.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    69.7 + *
    69.8 + * This code is free software; you can redistribute it and/or modify it
    69.9 + * under the terms of the GNU General Public License version 2 only, as
   69.10 + * published by the Free Software Foundation.
   69.11 + *
   69.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   69.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   69.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   69.15 + * version 2 for more details (a copy is included in the LICENSE file that
   69.16 + * accompanied this code).
   69.17 + *
   69.18 + * You should have received a copy of the GNU General Public License version
   69.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   69.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   69.21 + *
   69.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   69.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   69.24 + * have any questions.
   69.25 + */
   69.26 +
   69.27 +/*
   69.28 + * @test
   69.29 + * @bug 6448405 6519513 6745225
   69.30 + * @summary static HashMap cache in LineBreakMeasurer can grow wihout bounds
   69.31 + * @run main/othervm/timeout=600 -client -Xms16m -Xmx16m FRCTest
   69.32 + */
   69.33 +import java.awt.*;
   69.34 +import java.awt.image.*;
   69.35 +import java.awt.font.*;
   69.36 +import java.awt.geom.*;
   69.37 +import java.text.*;
   69.38 +import java.util.Hashtable;
   69.39 +
   69.40 +public class FRCTest {
   69.41 +
   69.42 +    static AttributedString vanGogh = new AttributedString(
   69.43 +        "Many people believe that Vincent van Gogh painted his best works " +
   69.44 +        "during the two-year period he spent in Provence. Here is where he " +
   69.45 +        "painted The Starry Night--which some consider to be his greatest " +
   69.46 +        "work of all. However, as his artistic brilliance reached new " +
   69.47 +        "heights in Provence, his physical and mental health plummeted. ",
   69.48 +        new Hashtable());
   69.49 +
   69.50 +    public static void main(String[] args) {
   69.51 +
   69.52 +        // First test the behaviour of Graphics2D.getFontRenderContext();
   69.53 +        BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
   69.54 +        Graphics2D g2d = bi.createGraphics();
   69.55 +        AffineTransform g2dTx = new AffineTransform(2,0,2,0,1,1);
   69.56 +        g2d.setTransform(g2dTx);
   69.57 +        AffineTransform frcTx = g2d.getFontRenderContext().getTransform();
   69.58 +        AffineTransform frcExpected = new AffineTransform(2,0,2,0,0,0);
   69.59 +        if (!frcTx.equals(frcExpected)) {
   69.60 +            throw new RuntimeException("FRC Tx may have translate?");
   69.61 +        }
   69.62 +
   69.63 +        // Now test that using different translates with LBM is OK
   69.64 +        // This test doesn't prove a lot since showing a leak really
   69.65 +        // requires a basher test that can run for a long time.
   69.66 +        for (int x=0;x<100;x++) {
   69.67 +            for (int y=0;y<100;y++) {
   69.68 +                AttributedCharacterIterator aci = vanGogh.getIterator();
   69.69 +                AffineTransform tx = AffineTransform.getTranslateInstance(x, y);
   69.70 +                FontRenderContext frc = new FontRenderContext(tx, false, false);
   69.71 +                LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
   69.72 +                lbm.setPosition(aci.getBeginIndex());
   69.73 +                while (lbm.getPosition() < aci.getEndIndex()) {
   69.74 +                    lbm.nextLayout(100f);
   69.75 +                }
   69.76 +            }
   69.77 +        }
   69.78 +
   69.79 +        for (int x=0;x<25;x++) {
   69.80 +            for (int y=0;y<25;y++) {
   69.81 +                AttributedCharacterIterator aci = vanGogh.getIterator();
   69.82 +                double rot = Math.random()*.4*Math.PI - .2*Math.PI;
   69.83 +                AffineTransform tx = AffineTransform.getRotateInstance(rot);
   69.84 +                FontRenderContext frc = new FontRenderContext(tx, false, false);
   69.85 +                LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
   69.86 +                lbm.setPosition(aci.getBeginIndex());
   69.87 +                while (lbm.getPosition() < aci.getEndIndex()) {
   69.88 +                    lbm.nextLayout(100f);
   69.89 +                }
   69.90 +            }
   69.91 +        }
   69.92 +    }
   69.93 +}
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/test/java/util/logging/ClassLoaderLeakTest.java	Tue Apr 07 14:02:54 2009 -0700
    70.3 @@ -0,0 +1,190 @@
    70.4 +/*
    70.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    70.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    70.7 + *
    70.8 + * This code is free software; you can redistribute it and/or modify it
    70.9 + * under the terms of the GNU General Public License version 2 only, as
   70.10 + * published by the Free Software Foundation.
   70.11 + *
   70.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   70.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   70.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   70.15 + * version 2 for more details (a copy is included in the LICENSE file that
   70.16 + * accompanied this code).
   70.17 + *
   70.18 + * You should have received a copy of the GNU General Public License version
   70.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   70.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   70.21 + *
   70.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   70.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   70.24 + * have any questions.
   70.25 + */
   70.26 +
   70.27 +/**
   70.28 + * @test
   70.29 + * @bug     6799583
   70.30 + *
   70.31 + * @summary Test verifes that LogManager shutdown hook does not cause
   70.32 + *          an application classloader leaks.
   70.33 + *
   70.34 + * @run     main/othervm ClassLoaderLeakTest
   70.35 + */
   70.36 +
   70.37 +import java.io.File;
   70.38 +import java.lang.ref.WeakReference;
   70.39 +import java.lang.reflect.Constructor;
   70.40 +import java.lang.reflect.Method;
   70.41 +import java.net.MalformedURLException;
   70.42 +import java.net.URL;
   70.43 +import java.net.URLClassLoader;
   70.44 +import java.util.concurrent.CountDownLatch;
   70.45 +import java.util.logging.Logger;
   70.46 +import java.util.logging.Logger;
   70.47 +
   70.48 +public class ClassLoaderLeakTest {
   70.49 +
   70.50 +    private static CountDownLatch doneSignal;
   70.51 +    private static CountDownLatch launchSignal;
   70.52 +    private static ThreadGroup appsThreadGroup;
   70.53 +    private static Throwable launchFailure = null;
   70.54 +
   70.55 +    public static void main(String[] args) {
   70.56 +        appsThreadGroup = new ThreadGroup("MyAppsThreadGroup");
   70.57 +        doneSignal = new CountDownLatch(1);
   70.58 +        launchSignal = new CountDownLatch(1);
   70.59 +
   70.60 +        Runnable launcher = new Runnable() {
   70.61 +            public void run() {
   70.62 +                try {
   70.63 +                    ClassLoader cl =
   70.64 +                        Thread.currentThread().getContextClassLoader();
   70.65 +                    Class appMain = cl.loadClass("AppTest");
   70.66 +                    Method launch =
   70.67 +                        appMain.getDeclaredMethod("launch", doneSignal.getClass());
   70.68 +
   70.69 +                    Constructor c = appMain.getConstructor();
   70.70 +
   70.71 +                    Object o = c.newInstance();
   70.72 +
   70.73 +                    launch.invoke(o, doneSignal);
   70.74 +
   70.75 +                } catch (Throwable e) {
   70.76 +                    launchFailure = e;
   70.77 +                } finally {
   70.78 +                    launchSignal.countDown();
   70.79 +                }
   70.80 +            }
   70.81 +        };
   70.82 +
   70.83 +        /* prepare test  class loader */
   70.84 +        URL pwd = null;
   70.85 +        try {
   70.86 +
   70.87 +            pwd = new File(System.getProperty("test.classes",".")).toURL();
   70.88 +        } catch (MalformedURLException e) {
   70.89 +            throw new RuntimeException("Test failed.", e);
   70.90 +        }
   70.91 +        URL[] urls = new URL[] { pwd };
   70.92 +
   70.93 +         MyClassLoader appClassLoader = new MyClassLoader(urls, "test0");
   70.94 +         WeakReference<MyClassLoader> ref =
   70.95 +                 new WeakReference<MyClassLoader>(appClassLoader);
   70.96 +
   70.97 +
   70.98 +         Thread appThread = new Thread(appsThreadGroup, launcher, "AppThread-0");
   70.99 +         appThread.setContextClassLoader(appClassLoader);
  70.100 +
  70.101 +         appThread.start();
  70.102 +         appClassLoader = null;
  70.103 +         launcher = null;
  70.104 +         appThread = null;
  70.105 +
  70.106 +         /* wait for laucnh completion */
  70.107 +         try {
  70.108 +             launchSignal.await();
  70.109 +         } catch (InterruptedException e) {
  70.110 +         }
  70.111 +
  70.112 +         /* check if launch failed */
  70.113 +         if (launchFailure != null) {
  70.114 +             throw new RuntimeException("Test failed.", launchFailure);
  70.115 +         }
  70.116 +
  70.117 +         /* wait for test app excution completion */
  70.118 +         try {
  70.119 +             doneSignal.await();
  70.120 +         } catch (InterruptedException e) {
  70.121 +         }
  70.122 +
  70.123 +         /* give a chence to GC */
  70.124 +         waitAndGC(5);
  70.125 +
  70.126 +         if (ref.get() != null) {
  70.127 +             throw new RuntimeException("Test failed: classloader is still alive");
  70.128 +         }
  70.129 +
  70.130 +         System.out.println("Test passed.");
  70.131 +    }
  70.132 +
  70.133 +    private static class MyClassLoader extends URLClassLoader {
  70.134 +
  70.135 +        private static boolean verbose =
  70.136 +            Boolean.getBoolean("verboseClassLoading");
  70.137 +        private String uniqClassName;
  70.138 +
  70.139 +        public MyClassLoader(URL[] urls, String uniq) {
  70.140 +            super(urls);
  70.141 +
  70.142 +            uniqClassName = uniq;
  70.143 +        }
  70.144 +
  70.145 +        public Class loadClass(String name) throws ClassNotFoundException {
  70.146 +            if (verbose) {
  70.147 +                System.out.printf("%s: load class %s\n", uniqClassName, name);
  70.148 +            }
  70.149 +            if (uniqClassName.equals(name)) {
  70.150 +                return Object.class;
  70.151 +            }
  70.152 +            return super.loadClass(name);
  70.153 +        }
  70.154 +
  70.155 +        public String toString() {
  70.156 +            return "MyClassLoader(" + uniqClassName + ")";
  70.157 +        }
  70.158 +    }
  70.159 +
  70.160 +    private static void waitAndGC(int sec) {
  70.161 +        int cnt = sec;
  70.162 +        System.out.print("Wait ");
  70.163 +        while (cnt-- > 0) {
  70.164 +            try {
  70.165 +                Thread.sleep(1000);
  70.166 +            } catch (InterruptedException e) {
  70.167 +            }
  70.168 +            // do GC every 3 seconds
  70.169 +            if (cnt % 3 == 2) {
  70.170 +                System.gc();
  70.171 +                System.out.print("+");
  70.172 +            } else {
  70.173 +                System.out.print(".");
  70.174 +            }
  70.175 +            //checkErrors();
  70.176 +        }
  70.177 +        System.out.println("");
  70.178 +    }
  70.179 +}
  70.180 +
  70.181 +
  70.182 +class AppTest {
  70.183 +    public AppTest() {
  70.184 +
  70.185 +    }
  70.186 +
  70.187 +    public void launch(CountDownLatch done) {
  70.188 +        Logger log = Logger.getLogger("app_test_logger");
  70.189 +        log.fine("Test app is launched");
  70.190 +
  70.191 +        done.countDown();
  70.192 +    }
  70.193 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/test/javax/imageio/metadata/BooleanAttributes.java	Tue Apr 07 14:02:54 2009 -0700
    71.3 @@ -0,0 +1,202 @@
    71.4 +/*
    71.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    71.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    71.7 + *
    71.8 + * This code is free software; you can redistribute it and/or modify it
    71.9 + * under the terms of the GNU General Public License version 2 only, as
   71.10 + * published by the Free Software Foundation.  Sun designates this
   71.11 + * particular file as subject to the "Classpath" exception as provided
   71.12 + * by Sun in the LICENSE file that accompanied this code.
   71.13 + *
   71.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   71.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   71.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   71.17 + * version 2 for more details (a copy is included in the LICENSE file that
   71.18 + * accompanied this code).
   71.19 + *
   71.20 + * You should have received a copy of the GNU General Public License version
   71.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   71.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   71.23 + *
   71.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   71.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
   71.26 + * have any questions.
   71.27 + */
   71.28 +
   71.29 +/**
   71.30 + * @test
   71.31 + * @bug 5082756
   71.32 + * @summary ensure that boolean attributes follow ( "TRUE" | "FALSE" )
   71.33 + *          including correct (i.e. upper) case
   71.34 + *
   71.35 + * @run main BooleanAttributes
   71.36 + */
   71.37 +
   71.38 +import java.awt.image.BufferedImage;
   71.39 +import java.io.ByteArrayInputStream;
   71.40 +import java.io.ByteArrayOutputStream;
   71.41 +import java.io.StringReader;
   71.42 +import java.util.Arrays;
   71.43 +import java.util.List;
   71.44 +import javax.imageio.IIOImage;
   71.45 +import javax.imageio.ImageIO;
   71.46 +import javax.imageio.ImageReader;
   71.47 +import javax.imageio.ImageTypeSpecifier;
   71.48 +import javax.imageio.ImageWriteParam;
   71.49 +import javax.imageio.ImageWriter;
   71.50 +import javax.imageio.metadata.IIOMetadata;
   71.51 +import javax.imageio.stream.ImageInputStream;
   71.52 +import javax.imageio.stream.ImageOutputStream;
   71.53 +import javax.imageio.stream.MemoryCacheImageInputStream;
   71.54 +import javax.imageio.stream.MemoryCacheImageOutputStream;
   71.55 +import javax.xml.transform.Result;
   71.56 +import javax.xml.transform.Source;
   71.57 +import javax.xml.transform.TransformerFactory;
   71.58 +import javax.xml.transform.dom.DOMResult;
   71.59 +import javax.xml.transform.stream.StreamSource;
   71.60 +import javax.xml.xpath.XPath;
   71.61 +import javax.xml.xpath.XPathConstants;
   71.62 +import javax.xml.xpath.XPathFactory;
   71.63 +import org.w3c.dom.Document;
   71.64 +import org.w3c.dom.Element;
   71.65 +import org.w3c.dom.Node;
   71.66 +import org.w3c.dom.NodeList;
   71.67 +
   71.68 +public class BooleanAttributes {
   71.69 +
   71.70 +    private static TransformerFactory transformerFactory =
   71.71 +        TransformerFactory.newInstance();
   71.72 +
   71.73 +    private static XPath xpathEngine = XPathFactory.newInstance().newXPath();
   71.74 +
   71.75 +    public static void main(String[] args) throws Exception {
   71.76 +        test("image/png", false, "<javax_imageio_1.0 />",
   71.77 +             "Chroma/BlackIsZero/@value",
   71.78 +             "Compression/Lossless/@value");
   71.79 +
   71.80 +        test("image/png", false,
   71.81 +             "<javax_imageio_png_1.0>" +
   71.82 +             "<iTXt><iTXtEntry keyword='Comment' compressionFlag='TRUE' " +
   71.83 +             "compressionMethod='0' languageTag='en' " +
   71.84 +             "translatedKeyword='comment' text='foo'/></iTXt>" +
   71.85 +             "</javax_imageio_png_1.0>",
   71.86 +             "iTXt/iTXtEntry/@compressionFlag");
   71.87 +
   71.88 +        test("image/png", false,
   71.89 +             "<javax_imageio_png_1.0>" +
   71.90 +             "<iTXt><iTXtEntry keyword='Comment' compressionFlag='FALSE' " +
   71.91 +             "compressionMethod='0' languageTag='en' " +
   71.92 +             "translatedKeyword='comment' text='foo'/></iTXt>" +
   71.93 +             "</javax_imageio_png_1.0>",
   71.94 +             "iTXt/iTXtEntry/@compressionFlag");
   71.95 +
   71.96 +        test("image/gif", false, "<javax_imageio_1.0 />",
   71.97 +             "Chroma/BlackIsZero/@value",
   71.98 +             "Compression/Lossless/@value");
   71.99 +
  71.100 +        test("image/gif", false,
  71.101 +             "<javax_imageio_gif_image_1.0>" +
  71.102 +             "<ImageDescriptor imageLeftPosition='0' imageTopPosition='0' " +
  71.103 +             "imageWidth='16' imageHeight='16' interlaceFlag='TRUE' />" +
  71.104 +             "<LocalColorTable sizeOfLocalColorTable='2' " +
  71.105 +             "backgroundColorIndex='1' sortFlag='TRUE'>" +
  71.106 +             "<ColorTableEntry index='0' red='0' green='0' blue='0' />" +
  71.107 +             "<ColorTableEntry index='1' red='255' green='255' blue='255' />" +
  71.108 +             "</LocalColorTable>" +
  71.109 +             "<GraphicControlExtension disposalMethod='doNotDispose' " +
  71.110 +             "userInputFlag='FALSE' transparentColorFlag='TRUE' " +
  71.111 +             "delayTime='100' transparentColorIndex='1' />" +
  71.112 +             "</javax_imageio_gif_image_1.0>",
  71.113 +             "ImageDescriptor/@interlaceFlag",
  71.114 +             "LocalColorTable/@sortFlag",
  71.115 +             "GraphicControlExtension/@userInputFlag",
  71.116 +             "GraphicControlExtension/@transparentColorFlag");
  71.117 +
  71.118 +        test("image/gif", true,
  71.119 +             "<javax_imageio_gif_stream_1.0>" +
  71.120 +             "<GlobalColorTable sizeOfGlobalColorTable='2' " +
  71.121 +             "backgroundColorIndex='1' sortFlag='TRUE'>" +
  71.122 +             "<ColorTableEntry index='0' red='0' green='0' blue='0' />" +
  71.123 +             "<ColorTableEntry index='1' red='255' green='255' blue='255' />" +
  71.124 +             "</GlobalColorTable>" +
  71.125 +             "</javax_imageio_gif_stream_1.0>",
  71.126 +             "GlobalColorTable/@sortFlag");
  71.127 +
  71.128 +        test("image/jpeg", false, "<javax_imageio_1.0 />",
  71.129 +             "Compression/Lossless/@value");
  71.130 +    }
  71.131 +
  71.132 +    private static void transform(Source src, Result dst)
  71.133 +        throws Exception
  71.134 +    {
  71.135 +        transformerFactory.newTransformer().transform(src, dst);
  71.136 +    }
  71.137 +
  71.138 +    private static void verify(Node meta, String[] xpaths, boolean required)
  71.139 +        throws Exception
  71.140 +    {
  71.141 +        for (String xpath: xpaths) {
  71.142 +            NodeList list = (NodeList)
  71.143 +                xpathEngine.evaluate(xpath, meta, XPathConstants.NODESET);
  71.144 +            if (list.getLength() == 0 && required)
  71.145 +                throw new AssertionError("Missing value: " + xpath);
  71.146 +            for (int i = 0; i < list.getLength(); ++i) {
  71.147 +                String value = list.item(i).getNodeValue();
  71.148 +                if (!(value.equals("TRUE") || value.equals("FALSE")))
  71.149 +                    throw new AssertionError(xpath + " has value " + value);
  71.150 +            }
  71.151 +        }
  71.152 +    }
  71.153 +
  71.154 +    public static void test(String mimeType, boolean useStreamMeta,
  71.155 +                            String metaXml, String... boolXpaths)
  71.156 +        throws Exception
  71.157 +    {
  71.158 +        BufferedImage img =
  71.159 +            new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
  71.160 +        ImageWriter iw = ImageIO.getImageWritersByMIMEType(mimeType).next();
  71.161 +        ByteArrayOutputStream os = new ByteArrayOutputStream();
  71.162 +        ImageOutputStream ios = new MemoryCacheImageOutputStream(os);
  71.163 +        iw.setOutput(ios);
  71.164 +        ImageWriteParam param = null;
  71.165 +        IIOMetadata streamMeta = iw.getDefaultStreamMetadata(param);
  71.166 +        IIOMetadata imageMeta =
  71.167 +            iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), param);
  71.168 +        IIOMetadata meta = useStreamMeta ? streamMeta : imageMeta;
  71.169 +        Source src = new StreamSource(new StringReader(metaXml));
  71.170 +        DOMResult dst = new DOMResult();
  71.171 +        transform(src, dst);
  71.172 +        Document doc = (Document)dst.getNode();
  71.173 +        Element node = doc.getDocumentElement();
  71.174 +        String metaFormat = node.getNodeName();
  71.175 +
  71.176 +        // Verify that the default metadata gets formatted correctly.
  71.177 +        verify(meta.getAsTree(metaFormat), boolXpaths, false);
  71.178 +
  71.179 +        meta.mergeTree(metaFormat, node);
  71.180 +
  71.181 +        // Verify that the merged metadata gets formatte correctly.
  71.182 +        verify(meta.getAsTree(metaFormat), boolXpaths, true);
  71.183 +
  71.184 +        iw.write(streamMeta, new IIOImage(img, null, imageMeta), param);
  71.185 +        iw.dispose();
  71.186 +        ios.close();
  71.187 +        ImageReader ir = ImageIO.getImageReader(iw);
  71.188 +        byte[] bytes = os.toByteArray();
  71.189 +        if (bytes.length == 0)
  71.190 +            throw new AssertionError("Zero length image file");
  71.191 +        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
  71.192 +        ImageInputStream iis = new MemoryCacheImageInputStream(is);
  71.193 +        ir.setInput(iis);
  71.194 +        if (useStreamMeta) meta = ir.getStreamMetadata();
  71.195 +        else meta = ir.getImageMetadata(0);
  71.196 +
  71.197 +        // Verify again after writing and re-reading the image
  71.198 +        verify(meta.getAsTree(metaFormat), boolXpaths, true);
  71.199 +    }
  71.200 +
  71.201 +    public static void xtest(Object... eatAnyArguments) {
  71.202 +        System.err.println("Disabled test! Change xtest back into test!");
  71.203 +    }
  71.204 +
  71.205 +}
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/test/javax/imageio/plugins/gif/EncodeSubImageTest.java	Tue Apr 07 14:02:54 2009 -0700
    72.3 @@ -0,0 +1,161 @@
    72.4 +/*
    72.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    72.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    72.7 + *
    72.8 + * This code is free software; you can redistribute it and/or modify it
    72.9 + * under the terms of the GNU General Public License version 2 only, as
   72.10 + * published by the Free Software Foundation.
   72.11 + *
   72.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   72.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   72.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   72.15 + * version 2 for more details (a copy is included in the LICENSE file that
   72.16 + * accompanied this code).
   72.17 + *
   72.18 + * You should have received a copy of the GNU General Public License version
   72.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   72.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   72.21 + *
   72.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   72.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   72.24 + * have any questions.
   72.25 + */
   72.26 +
   72.27 +/**
   72.28 + * @test
   72.29 + * @bug     6795544
   72.30 + *
   72.31 + * @summary Test verifes that Image I/O gif writer correctly handles
   72.32 + *          buffered images based on translated reasters (typically
   72.33 + *          produced by getSubImage() method).
   72.34 + *
   72.35 + * @run     main EncodeSubImageTest gif
   72.36 + */
   72.37 +
   72.38 +import java.awt.Color;
   72.39 +import java.awt.Graphics;
   72.40 +import java.awt.image.BufferedImage;
   72.41 +import java.awt.image.Raster;
   72.42 +import java.io.File;
   72.43 +import java.io.IOException;
   72.44 +import javax.imageio.IIOImage;
   72.45 +import javax.imageio.ImageIO;
   72.46 +import javax.imageio.ImageWriteParam;
   72.47 +import javax.imageio.ImageWriter;
   72.48 +import javax.imageio.stream.ImageOutputStream;
   72.49 +
   72.50 +public class EncodeSubImageTest {
   72.51 +    private static String format = "gif";
   72.52 +    private static ImageWriter writer;
   72.53 +    private static String file_suffix;
   72.54 +    private static final int subSampleX = 2;
   72.55 +    private static final int subSampleY = 2;
   72.56 +
   72.57 +    public static void main(String[] args) throws IOException {
   72.58 +        if (args.length > 0) {
   72.59 +            format = args[0];
   72.60 +        }
   72.61 +
   72.62 +        writer = ImageIO.getImageWritersByFormatName(format).next();
   72.63 +
   72.64 +        file_suffix =writer.getOriginatingProvider().getFileSuffixes()[0];
   72.65 +
   72.66 +        BufferedImage src = createTestImage();
   72.67 +        EncodeSubImageTest m1 = new EncodeSubImageTest(src);
   72.68 +        m1.doTest("test_src");
   72.69 +
   72.70 +        BufferedImage sub = src.getSubimage(subImageOffset, subImageOffset,
   72.71 +                src.getWidth() - 2 * subImageOffset,
   72.72 +                src.getHeight() - 2 * subImageOffset);
   72.73 +        EncodeSubImageTest m2 = new EncodeSubImageTest(sub);
   72.74 +        m2.doTest("test_sub");
   72.75 +    }
   72.76 +
   72.77 +    BufferedImage img;
   72.78 +
   72.79 +    public EncodeSubImageTest(BufferedImage img) {
   72.80 +        this.img = img;
   72.81 +    }
   72.82 +
   72.83 +    public void doTest(String prefix) throws IOException {
   72.84 +        System.out.println(prefix);
   72.85 +        File f = new File(prefix + file_suffix);
   72.86 +        write(f, false);
   72.87 +        verify(f, false);
   72.88 +
   72.89 +        System.out.println(prefix + "_subsampled");
   72.90 +        f = new File(prefix + "_subsampled");
   72.91 +        write(f, true);
   72.92 +        verify(f, true);
   72.93 +
   72.94 +        System.out.println(prefix + ": Test PASSED.");
   72.95 +    }
   72.96 +
   72.97 +    private static final int subImageOffset = 10;
   72.98 +
   72.99 +    private void verify(File f, boolean isSubsampled) {
  72.100 +        BufferedImage dst = null;
  72.101 +        try {
  72.102 +            dst = ImageIO.read(f);
  72.103 +        } catch (IOException e) {
  72.104 +            throw new RuntimeException("Test FAILED: can't readin test image " +
  72.105 +                f.getAbsolutePath(), e);
  72.106 +        }
  72.107 +        if (dst == null) {
  72.108 +            throw new RuntimeException("Test FAILED: no dst image available.");
  72.109 +        }
  72.110 +
  72.111 +        checkPixel(dst, 0, 0, isSubsampled);
  72.112 +
  72.113 +        checkPixel(dst, img.getWidth() / 2, img.getHeight() / 2, isSubsampled);
  72.114 +    }
  72.115 +
  72.116 +    private void checkPixel(BufferedImage dst, int x, int y,
  72.117 +                            boolean isSubsampled)
  72.118 +    {
  72.119 +        int dx = isSubsampled ? x / subSampleX : x;
  72.120 +        int dy = isSubsampled ? y / subSampleY : y;
  72.121 +        int src_rgb = img.getRGB(x, y);
  72.122 +        System.out.printf("src_rgb: %x\n", src_rgb);
  72.123 +
  72.124 +        int dst_rgb = dst.getRGB(dx, dy);
  72.125 +        System.out.printf("dst_rgb: %x\n", dst_rgb);
  72.126 +
  72.127 +        if (src_rgb != dst_rgb) {
  72.128 +            throw new RuntimeException("Test FAILED: invalid color in dst");
  72.129 +        }
  72.130 +    }
  72.131 +
  72.132 +    private static BufferedImage createTestImage() {
  72.133 +        int w = 100;
  72.134 +        int h = 100;
  72.135 +
  72.136 +        BufferedImage src = new BufferedImage(w, h,
  72.137 +                BufferedImage.TYPE_BYTE_INDEXED);
  72.138 +        Graphics g = src.createGraphics();
  72.139 +        g.setColor(Color.red);
  72.140 +        g.fillRect(0, 0, w, h);
  72.141 +        g.setColor(Color.green);
  72.142 +        g.fillRect(subImageOffset, subImageOffset,
  72.143 +                w - 2 * subImageOffset, h - 2* subImageOffset);
  72.144 +        g.setColor(Color.blue);
  72.145 +        g.fillRect(2 * subImageOffset, 2 * subImageOffset,
  72.146 +                w - 4 * subImageOffset, h - 4 * subImageOffset);
  72.147 +        g.dispose();
  72.148 +
  72.149 +        return src;
  72.150 +    }
  72.151 +
  72.152 +    private void write(File f, boolean subsample) throws IOException {
  72.153 +        ImageOutputStream ios = ImageIO.createImageOutputStream(f);
  72.154 +
  72.155 +        writer.setOutput(ios);
  72.156 +        ImageWriteParam p = writer.getDefaultWriteParam();
  72.157 +        if (subsample) {
  72.158 +            p.setSourceSubsampling(subSampleX, subSampleY, 0, 0);
  72.159 +        }
  72.160 +        writer.write(null, new IIOImage(img, null, null), p);
  72.161 +        ios.close();
  72.162 +        writer.reset();
  72.163 +    }
  72.164 +}
    73.1 --- a/test/javax/imageio/plugins/png/ITXtTest.java	Tue Apr 07 11:43:20 2009 -0700
    73.2 +++ b/test/javax/imageio/plugins/png/ITXtTest.java	Tue Apr 07 14:02:54 2009 -0700
    73.3 @@ -123,7 +123,7 @@
    73.4          }
    73.5          t.keyword = e.getAttribute("keyword");
    73.6          t.isCompressed =
    73.7 -            (Integer.valueOf(e.getAttribute("compressionFlag")).intValue() == 1);
    73.8 +            Boolean.valueOf(e.getAttribute("compressionFlag")).booleanValue();
    73.9          t.compression =
   73.10              Integer.valueOf(e.getAttribute("compressionMethod")).intValue();
   73.11          t.language = e.getAttribute("languageTag");
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/test/javax/imageio/plugins/png/ItxtUtf8Test.java	Tue Apr 07 14:02:54 2009 -0700
    74.3 @@ -0,0 +1,241 @@
    74.4 +/*
    74.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    74.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    74.7 + *
    74.8 + * This code is free software; you can redistribute it and/or modify it
    74.9 + * under the terms of the GNU General Public License version 2 only, as
   74.10 + * published by the Free Software Foundation.
   74.11 + *
   74.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   74.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   74.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   74.15 + * version 2 for more details (a copy is included in the LICENSE file that
   74.16 + * accompanied this code).
   74.17 + *
   74.18 + * You should have received a copy of the GNU General Public License version
   74.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   74.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   74.21 + *
   74.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   74.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   74.24 + * have any questions.
   74.25 + */
   74.26 +
   74.27 +/**
   74.28 + * @test
   74.29 + * @bug 6541476 6782079
   74.30 + * @summary Write and read a PNG file including an non-latin1 iTXt chunk
   74.31 + *          Test also verifies that trunkated png images does not cause
   74.32 + *          an OoutOfMemory error.
   74.33 + *
   74.34 + * @run main ItxtUtf8Test
   74.35 + *
   74.36 + * @run main/othervm/timeout=10 -Xmx2m ItxtUtf8Test truncate
   74.37 + */
   74.38 +
   74.39 +import java.awt.image.BufferedImage;
   74.40 +import java.io.ByteArrayInputStream;
   74.41 +import java.io.ByteArrayOutputStream;
   74.42 +import java.io.OutputStream;
   74.43 +import java.util.Arrays;
   74.44 +import java.util.List;
   74.45 +import javax.imageio.IIOException;
   74.46 +import javax.imageio.IIOImage;
   74.47 +import javax.imageio.ImageIO;
   74.48 +import javax.imageio.ImageReader;
   74.49 +import javax.imageio.ImageTypeSpecifier;
   74.50 +import javax.imageio.ImageWriter;
   74.51 +import javax.imageio.metadata.IIOMetadata;
   74.52 +import javax.imageio.stream.ImageInputStream;
   74.53 +import javax.imageio.stream.ImageOutputStream;
   74.54 +import javax.imageio.stream.MemoryCacheImageInputStream;
   74.55 +import javax.imageio.stream.MemoryCacheImageOutputStream;
   74.56 +import org.w3c.dom.DOMImplementation;
   74.57 +import org.w3c.dom.Document;
   74.58 +import org.w3c.dom.Element;
   74.59 +import org.w3c.dom.Node;
   74.60 +import org.w3c.dom.bootstrap.DOMImplementationRegistry;
   74.61 +
   74.62 +public class ItxtUtf8Test {
   74.63 +
   74.64 +    public static final String
   74.65 +    TEXT = "\u24c9\u24d4\u24e7\u24e3" +
   74.66 +      "\ud835\udc13\ud835\udc1e\ud835\udc31\ud835\udc2d" +
   74.67 +      "\u24c9\u24d4\u24e7\u24e3", // a repetition for compression
   74.68 +    VERBATIM = "\u24e5\u24d4\u24e1\u24d1\u24d0\u24e3\u24d8\u24dc",
   74.69 +    COMPRESSED = "\u24d2\u24de\u24dc\u24df\u24e1\u24d4\u24e2\u24e2\u24d4\u24d3";
   74.70 +
   74.71 +    public static final byte[]
   74.72 +    VBYTES = {
   74.73 +        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x56, // chunk length
   74.74 +        (byte)0x69, (byte)0x54, (byte)0x58, (byte)0x74, // chunk type "iTXt"
   74.75 +        (byte)0x76, (byte)0x65, (byte)0x72, (byte)0x62,
   74.76 +        (byte)0x61, (byte)0x74, (byte)0x69, (byte)0x6d, // keyword "verbatim"
   74.77 +        (byte)0x00, // separator terminating keyword
   74.78 +        (byte)0x00, // compression flag
   74.79 +        (byte)0x00, // compression method, must be zero
   74.80 +        (byte)0x78, (byte)0x2d, (byte)0x63, (byte)0x69,
   74.81 +        (byte)0x72, (byte)0x63, (byte)0x6c, (byte)0x65,
   74.82 +        (byte)0x64, // language tag "x-circled"
   74.83 +        (byte)0x00, // separator terminating language tag
   74.84 +        (byte)0xe2, (byte)0x93, (byte)0xa5, // '\u24e5'
   74.85 +        (byte)0xe2, (byte)0x93, (byte)0x94, // '\u24d4'
   74.86 +        (byte)0xe2, (byte)0x93, (byte)0xa1, // '\u24e1'
   74.87 +        (byte)0xe2, (byte)0x93, (byte)0x91, // '\u24d1'
   74.88 +        (byte)0xe2, (byte)0x93, (byte)0x90, // '\u24d0'
   74.89 +        (byte)0xe2, (byte)0x93, (byte)0xa3, // '\u24e3'
   74.90 +        (byte)0xe2, (byte)0x93, (byte)0x98, // '\u24d8'
   74.91 +        (byte)0xe2, (byte)0x93, (byte)0x9c, // '\u24dc'
   74.92 +        (byte)0x00, // separator terminating the translated keyword
   74.93 +        (byte)0xe2, (byte)0x93, (byte)0x89, // '\u24c9'
   74.94 +        (byte)0xe2, (byte)0x93, (byte)0x94, // '\u24d4'
   74.95 +        (byte)0xe2, (byte)0x93, (byte)0xa7, // '\u24e7'
   74.96 +        (byte)0xe2, (byte)0x93, (byte)0xa3, // '\u24e3'
   74.97 +        (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0x93, // '\ud835\udc13'
   74.98 +        (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0x9e, // '\ud835\udc1e'
   74.99 +        (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0xb1, // '\ud835\udc31'
  74.100 +        (byte)0xf0, (byte)0x9d, (byte)0x90, (byte)0xad, // '\ud835\udc2d'
  74.101 +        (byte)0xe2, (byte)0x93, (byte)0x89, // '\u24c9'
  74.102 +        (byte)0xe2, (byte)0x93, (byte)0x94, // '\u24d4'
  74.103 +        (byte)0xe2, (byte)0x93, (byte)0xa7, // '\u24e7'
  74.104 +        (byte)0xe2, (byte)0x93, (byte)0xa3, // '\u24e3'
  74.105 +        (byte)0xb5, (byte)0xcc, (byte)0x97, (byte)0x56 // CRC
  74.106 +    },
  74.107 +    CBYTES = {
  74.108 +        // we don't want to check the chunk length,
  74.109 +        // as this might depend on implementation.
  74.110 +        (byte)0x69, (byte)0x54, (byte)0x58, (byte)0x74, // chunk type "iTXt"
  74.111 +        (byte)0x63, (byte)0x6f, (byte)0x6d, (byte)0x70,
  74.112 +        (byte)0x72, (byte)0x65, (byte)0x73, (byte)0x73,
  74.113 +        (byte)0x65, (byte)0x64, // keyword "compressed"
  74.114 +        (byte)0x00, // separator terminating keyword
  74.115 +        (byte)0x01, // compression flag
  74.116 +        (byte)0x00, // compression method, 0=deflate
  74.117 +        (byte)0x78, (byte)0x2d, (byte)0x63, (byte)0x69,
  74.118 +        (byte)0x72, (byte)0x63, (byte)0x6c, (byte)0x65,
  74.119 +        (byte)0x64, // language tag "x-circled"
  74.120 +        (byte)0x00, // separator terminating language tag
  74.121 +        // we don't want to check the actual compressed data,
  74.122 +        // as this might depend on implementation.
  74.123 +    };
  74.124 +/*
  74.125 +*/
  74.126 +
  74.127 +    public static void main(String[] args) throws Exception {
  74.128 +        List argList = Arrays.asList(args);
  74.129 +        if (argList.contains("truncate")) {
  74.130 +            try {
  74.131 +                runTest(false, true);
  74.132 +                throw new AssertionError("Expect an error for truncated file");
  74.133 +            }
  74.134 +            catch (IIOException e) {
  74.135 +                // expected an error for a truncated image file.
  74.136 +            }
  74.137 +        }
  74.138 +        else {
  74.139 +            runTest(argList.contains("dump"), false);
  74.140 +        }
  74.141 +    }
  74.142 +
  74.143 +    public static void runTest(boolean dump, boolean truncate)
  74.144 +        throws Exception
  74.145 +    {
  74.146 +        String format = "javax_imageio_png_1.0";
  74.147 +        BufferedImage img =
  74.148 +            new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
  74.149 +        ImageWriter iw = ImageIO.getImageWritersByMIMEType("image/png").next();
  74.150 +        ByteArrayOutputStream os = new ByteArrayOutputStream();
  74.151 +        ImageOutputStream ios = new MemoryCacheImageOutputStream(os);
  74.152 +        iw.setOutput(ios);
  74.153 +        IIOMetadata meta =
  74.154 +            iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), null);
  74.155 +        DOMImplementationRegistry registry;
  74.156 +        registry = DOMImplementationRegistry.newInstance();
  74.157 +        DOMImplementation impl = registry.getDOMImplementation("XML 3.0");
  74.158 +        Document doc = impl.createDocument(null, format, null);
  74.159 +        Element root, itxt, entry;
  74.160 +        root = doc.getDocumentElement();
  74.161 +        root.appendChild(itxt = doc.createElement("iTXt"));
  74.162 +        itxt.appendChild(entry = doc.createElement("iTXtEntry"));
  74.163 +        entry.setAttribute("keyword", "verbatim");
  74.164 +        entry.setAttribute("compressionFlag", "false");
  74.165 +        entry.setAttribute("compressionMethod", "0");
  74.166 +        entry.setAttribute("languageTag", "x-circled");
  74.167 +        entry.setAttribute("translatedKeyword", VERBATIM);
  74.168 +        entry.setAttribute("text", TEXT);
  74.169 +        itxt.appendChild(entry = doc.createElement("iTXtEntry"));
  74.170 +        entry.setAttribute("keyword", "compressed");
  74.171 +        entry.setAttribute("compressionFlag", "true");
  74.172 +        entry.setAttribute("compressionMethod", "0");
  74.173 +        entry.setAttribute("languageTag", "x-circled");
  74.174 +        entry.setAttribute("translatedKeyword", COMPRESSED);
  74.175 +        entry.setAttribute("text", TEXT);
  74.176 +        meta.mergeTree(format, root);
  74.177 +        iw.write(new IIOImage(img, null, meta));
  74.178 +        iw.dispose();
  74.179 +
  74.180 +        byte[] bytes = os.toByteArray();
  74.181 +        if (dump)
  74.182 +            System.out.write(bytes);
  74.183 +        if (findBytes(VBYTES, bytes) < 0)
  74.184 +            throw new AssertionError("verbatim block not found");
  74.185 +        if (findBytes(CBYTES, bytes) < 0)
  74.186 +            throw new AssertionError("compressed block not found");
  74.187 +        int length = bytes.length;
  74.188 +        if (truncate)
  74.189 +            length = findBytes(VBYTES, bytes) + 32;
  74.190 +
  74.191 +        ImageReader ir = ImageIO.getImageReader(iw);
  74.192 +        ByteArrayInputStream is = new ByteArrayInputStream(bytes, 0, length);
  74.193 +        ImageInputStream iis = new MemoryCacheImageInputStream(is);
  74.194 +        ir.setInput(iis);
  74.195 +        meta = ir.getImageMetadata(0);
  74.196 +        Node node = meta.getAsTree(format);
  74.197 +        for (node = node.getFirstChild();
  74.198 +             !"iTXt".equals(node.getNodeName());
  74.199 +             node = node.getNextSibling());
  74.200 +        boolean verbatimSeen = false, compressedSeen = false;
  74.201 +        for (node = node.getFirstChild();
  74.202 +             node != null;
  74.203 +             node = node.getNextSibling()) {
  74.204 +            entry = (Element)node;
  74.205 +            String keyword = entry.getAttribute("keyword");
  74.206 +            String translatedKeyword = entry.getAttribute("translatedKeyword");
  74.207 +            String text = entry.getAttribute("text");
  74.208 +            if ("verbatim".equals(keyword)) {
  74.209 +                if (verbatimSeen) throw new AssertionError("Duplicate");
  74.210 +                verbatimSeen = true;
  74.211 +                if (!VERBATIM.equals(translatedKeyword))
  74.212 +                    throw new AssertionError("Wrong translated keyword");
  74.213 +                if (!TEXT.equals(text))
  74.214 +                    throw new AssertionError("Wrong text");
  74.215 +            }
  74.216 +            else if ("compressed".equals(keyword)) {
  74.217 +                if (compressedSeen) throw new AssertionError("Duplicate");
  74.218 +                compressedSeen = true;
  74.219 +                if (!COMPRESSED.equals(translatedKeyword))
  74.220 +                    throw new AssertionError("Wrong translated keyword");
  74.221 +                if (!TEXT.equals(text))
  74.222 +                    throw new AssertionError("Wrong text");
  74.223 +            }
  74.224 +            else {
  74.225 +                throw new AssertionError("Unexpected keyword");
  74.226 +            }
  74.227 +        }
  74.228 +        if (!(verbatimSeen && compressedSeen))
  74.229 +            throw new AssertionError("Missing chunk");
  74.230 +    }
  74.231 +
  74.232 +    private static final int findBytes(byte[] needle, byte[] haystack) {
  74.233 +        HAYSTACK: for (int h = 0; h <= haystack.length - needle.length; ++h) {
  74.234 +            for (int n = 0; n < needle.length; ++n) {
  74.235 +                if (needle[n] != haystack[h + n]) {
  74.236 +                    continue HAYSTACK;
  74.237 +                }
  74.238 +            }
  74.239 +            return h;
  74.240 +        }
  74.241 +        return -1;
  74.242 +    }
  74.243 +
  74.244 +}
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/test/javax/imageio/plugins/png/MergeStdCommentTest.java	Tue Apr 07 14:02:54 2009 -0700
    75.3 @@ -0,0 +1,64 @@
    75.4 +/*
    75.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    75.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    75.7 + *
    75.8 + * This code is free software; you can redistribute it and/or modify it
    75.9 + * under the terms of the GNU General Public License version 2 only, as
   75.10 + * published by the Free Software Foundation.
   75.11 + *
   75.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   75.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   75.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   75.15 + * version 2 for more details (a copy is included in the LICENSE file that
   75.16 + * accompanied this code).
   75.17 + *
   75.18 + * You should have received a copy of the GNU General Public License version
   75.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   75.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   75.21 + *
   75.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   75.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   75.24 + * have any questions.
   75.25 + */
   75.26 +
   75.27 +/**
   75.28 + * @test
   75.29 + * @bug 5106550
   75.30 + * @summary Merge a comment using the standard metdata format
   75.31 + *          and only a minimal set of attributes
   75.32 + */
   75.33 +
   75.34 +import java.awt.image.BufferedImage;
   75.35 +import javax.imageio.ImageIO;
   75.36 +import javax.imageio.ImageTypeSpecifier;
   75.37 +import javax.imageio.ImageWriter;
   75.38 +import javax.imageio.metadata.IIOMetadata;
   75.39 +import org.w3c.dom.DOMImplementation;
   75.40 +import org.w3c.dom.Document;
   75.41 +import org.w3c.dom.Element;
   75.42 +import org.w3c.dom.bootstrap.DOMImplementationRegistry;
   75.43 +
   75.44 +public class MergeStdCommentTest {
   75.45 +
   75.46 +    public static void main(String[] args) throws Exception {
   75.47 +        String format = "javax_imageio_1.0";
   75.48 +        BufferedImage img =
   75.49 +            new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
   75.50 +        ImageWriter iw = ImageIO.getImageWritersByMIMEType("image/png").next();
   75.51 +        IIOMetadata meta =
   75.52 +            iw.getDefaultImageMetadata(new ImageTypeSpecifier(img), null);
   75.53 +        DOMImplementationRegistry registry;
   75.54 +        registry = DOMImplementationRegistry.newInstance();
   75.55 +        DOMImplementation impl = registry.getDOMImplementation("XML 3.0");
   75.56 +        Document doc = impl.createDocument(null, format, null);
   75.57 +        Element root, text, entry;
   75.58 +        root = doc.getDocumentElement();
   75.59 +        root.appendChild(text = doc.createElement("Text"));
   75.60 +        text.appendChild(entry = doc.createElement("TextEntry"));
   75.61 +        // keyword isn't #REQUIRED by the standard metadata format.
   75.62 +        // However, it is required by the PNG format, so we include it here.
   75.63 +        entry.setAttribute("keyword", "Comment");
   75.64 +        entry.setAttribute("value", "Some demo comment");
   75.65 +        meta.mergeTree(format, root);
   75.66 +    }
   75.67 +}
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/test/javax/imageio/stream/StreamCloserLeak/run_test.sh	Tue Apr 07 14:02:54 2009 -0700
    76.3 @@ -0,0 +1,205 @@
    76.4 +#!/bin/ksh -p
    76.5 +#
    76.6 +# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    76.7 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    76.8 +#
    76.9 +# This code is free software; you can redistribute it and/or modify it
   76.10 +# under the terms of the GNU General Public License version 2 only, as
   76.11 +# published by the Free Software Foundation.
   76.12 +#
   76.13 +# This code is distributed in the hope that it will be useful, but WITHOUT
   76.14 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   76.15 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   76.16 +# version 2 for more details (a copy is included in the LICENSE file that
   76.17 +# accompanied this code).
   76.18 +#
   76.19 +# You should have received a copy of the GNU General Public License version
   76.20 +# 2 along with this work; if not, write to the Free Software Foundation,
   76.21 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   76.22 +#
   76.23 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   76.24 +# CA 95054 USA or visit www.sun.com if you need additional information or
   76.25 +# have any questions.
   76.26 +#
   76.27 +
   76.28 +#
   76.29 +#   @test
   76.30 +#   @bug        6788096
   76.31 +#   @summary    Test simulates the case of multiple applets executed in
   76.32 +#               the same VM and verifies that ImageIO shutdown hook
   76.33 +#               StreamCloser does not cause a leak of classloaders.
   76.34 +#
   76.35 +#   @build      test.Main
   76.36 +#   @build      testapp.Main
   76.37 +#   @run shell  run_test.sh
   76.38 +
   76.39 +# There are several resources which need to be present before many
   76.40 +#  shell scripts can run.  Following are examples of how to check for
   76.41 +#  many common ones.
   76.42 +#
   76.43 +# Note that the shell used is the Korn Shell, KSH
   76.44 +#
   76.45 +# Also note, it is recommended that make files NOT be used.  Rather,
   76.46 +#  put the individual commands directly into this file.  That way,
   76.47 +#  it is possible to use command line arguments and other shell tech-
   76.48 +#  niques to find the compiler, etc on different systems.  For example,
   76.49 +#  a different path could be used depending on whether this were a
   76.50 +#  Solaris or Win32 machine, which is more difficult (if even possible)
   76.51 +#  in a make file.
   76.52 +
   76.53 +
   76.54 +# Beginning of subroutines:
   76.55 +status=1
   76.56 +
   76.57 +#Call this from anywhere to fail the test with an error message
   76.58 +# usage: fail "reason why the test failed"
   76.59 +fail()
   76.60 + { echo "The test failed :-("
   76.61 +   echo "$*" 1>&2
   76.62 +   echo "exit status was $status"
   76.63 +   exit $status
   76.64 + } #end of fail()
   76.65 +
   76.66 +#Call this from anywhere to pass the test with a message
   76.67 +# usage: pass "reason why the test passed if applicable"
   76.68 +pass()
   76.69 + { echo "The test passed!!!"
   76.70 +   echo "$*" 1>&2
   76.71 +   exit 0
   76.72 + } #end of pass()
   76.73 +
   76.74 +# end of subroutines
   76.75 +
   76.76 +
   76.77 +# The beginning of the script proper
   76.78 +
   76.79 +# Checking for proper OS
   76.80 +OS=`uname -s`
   76.81 +case "$OS" in
   76.82 +   SunOS )
   76.83 +      VAR="One value for Sun"
   76.84 +      DEFAULT_JDK=/usr/local/java/jdk1.2/solaris
   76.85 +      FILESEP="/"
   76.86 +      PATHSEP=":"
   76.87 +      TMP="/tmp"
   76.88 +      ;;
   76.89 +
   76.90 +   Linux )
   76.91 +      VAR="A different value for Linux"
   76.92 +      DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
   76.93 +      FILESEP="/"
   76.94 +      PATHSEP=":"
   76.95 +      TMP="/tmp"
   76.96 +      ;;
   76.97 +
   76.98 +   Windows_95 | Windows_98 | Windows_NT | Windows_ME )
   76.99 +      VAR="A different value for Win32"
  76.100 +      DEFAULT_JDK=/usr/local/java/jdk1.2/win32
  76.101 +      FILESEP="\\"
  76.102 +      PATHSEP=";"
  76.103 +      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
  76.104 +      ;;
  76.105 +
  76.106 +   # catch all other OSs
  76.107 +   * )
  76.108 +      echo "Unrecognized system!  $OS"
  76.109 +      fail "Unrecognized system!  $OS"
  76.110 +      ;;
  76.111 +esac
  76.112 +
  76.113 +# Want this test to run standalone as well as in the harness, so do the
  76.114 +#  following to copy the test's directory into the harness's scratch directory
  76.115 +#  and set all appropriate variables:
  76.116 +
  76.117 +if [ -z "${TESTJAVA}" ] ; then
  76.118 +   # TESTJAVA is not set, so the test is running stand-alone.
  76.119 +   # TESTJAVA holds the path to the root directory of the build of the JDK
  76.120 +   # to be tested.  That is, any java files run explicitly in this shell
  76.121 +   # should use TESTJAVA in the path to the java interpreter.
  76.122 +   # So, we'll set this to the JDK spec'd on the command line.  If none
  76.123 +   # is given on the command line, tell the user that and use a cheesy
  76.124 +   # default.
  76.125 +   # THIS IS THE JDK BEING TESTED.
  76.126 +   if [ -n "$1" ] ;
  76.127 +      then TESTJAVA=$1
  76.128 +      else echo "no JDK specified on command line so using default!"
  76.129 +	 TESTJAVA=$DEFAULT_JDK
  76.130 +   fi
  76.131 +   TESTSRC=.
  76.132 +   TESTCLASSES=.
  76.133 +   STANDALONE=1;
  76.134 +fi
  76.135 +echo "JDK under test is: $TESTJAVA"
  76.136 +
  76.137 +
  76.138 +###############  YOUR TEST CODE HERE!!!!!!!  #############
  76.139 +
  76.140 +#All files required for the test should be in the same directory with
  76.141 +# this file.  If converting a standalone test to run with the harness,
  76.142 +# as long as all files are in the same directory and it returns 0 for
  76.143 +# pass, you should be able to cut and paste it into here and it will
  76.144 +# run with the test harness.
  76.145 +
  76.146 +# This is an example of running something -- test
  76.147 +# The stuff below catches the exit status of test then passes or fails
  76.148 +# this shell test as appropriate ( 0 status is considered a pass here )
  76.149 +
  76.150 +echo "Create TestApp.jar..."
  76.151 +
  76.152 +if [ -f TestApp.jar ] ; then
  76.153 +    rm -f TestApp.jar
  76.154 +fi
  76.155 +
  76.156 +${TESTJAVA}/bin/jar -cvf TestApp.jar -C ${TESTCLASSES} testapp
  76.157 +
  76.158 +if [ $? -ne "0" ] ; then
  76.159 +    fail "Failed to create TestApp.jar"
  76.160 +fi
  76.161 +
  76.162 +echo "Create Test.jar..."
  76.163 +if [ -f Test.jar ] ; then
  76.164 +    rm -f Test.jar
  76.165 +fi
  76.166 +
  76.167 +${TESTJAVA}/bin/jar -cvf Test.jar -C ${TESTCLASSES} test
  76.168 +
  76.169 +if [ $? -ne 0 ] ; then
  76.170 +    fail "Failed to create Test.jar"
  76.171 +fi
  76.172 +
  76.173 +# Prepare temp dir for cahce files
  76.174 +mkdir ./tmp
  76.175 +if [ $? -ne 0 ] ; then
  76.176 +    fail "Unable to create temp directory."
  76.177 +fi
  76.178 +
  76.179 +# Verify that all classoladers are destroyed
  76.180 +${TESTJAVA}/bin/java -cp Test.jar test.Main
  76.181 +if [ $? -ne 0 ] ; then
  76.182 +    fail "Test FAILED: some classloaders weren't destroyed."
  76.183 +fi
  76.184 +
  76.185 +
  76.186 +# Verify that ImageIO shutdown hook works correcly
  76.187 +${TESTJAVA}/bin/java -cp Test.jar -DforgetSomeStreams=true test.Main
  76.188 +if [ $? -ne 0 ] ; then
  76.189 +    fail "Test FAILED: some classloaders weren't destroyed of shutdown hook failed."
  76.190 +fi
  76.191 +
  76.192 +# sanity check: verify that all cache files were deleted
  76.193 +cache_files=`ls tmp`
  76.194 +
  76.195 +if [ "x${cache_files}" != "x" ] ; then
  76.196 +    echo "WARNING: some cache files was not deleted: ${cache_files}"
  76.197 +fi
  76.198 +
  76.199 +echo "Test done."
  76.200 +
  76.201 +status=$?
  76.202 +
  76.203 +if [ $status -eq "0" ] ; then
  76.204 +    pass ""
  76.205 +else
  76.206 +    fail "Test failed due to test plugin was not found."
  76.207 +fi
  76.208 +
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/test/javax/imageio/stream/StreamCloserLeak/test/Main.java	Tue Apr 07 14:02:54 2009 -0700
    77.3 @@ -0,0 +1,284 @@
    77.4 +/*
    77.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    77.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    77.7 + *
    77.8 + * This code is free software; you can redistribute it and/or modify it
    77.9 + * under the terms of the GNU General Public License version 2 only, as
   77.10 + * published by the Free Software Foundation.
   77.11 + *
   77.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   77.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   77.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   77.15 + * version 2 for more details (a copy is included in the LICENSE file that
   77.16 + * accompanied this code).
   77.17 + *
   77.18 + * You should have received a copy of the GNU General Public License version
   77.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   77.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   77.21 + *
   77.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   77.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   77.24 + * have any questions.
   77.25 + */
   77.26 +
   77.27 +package test;
   77.28 +
   77.29 +import java.io.File;
   77.30 +import java.io.IOException;
   77.31 +import java.lang.ref.Reference;
   77.32 +import java.lang.ref.ReferenceQueue;
   77.33 +import java.lang.ref.WeakReference;
   77.34 +import java.lang.reflect.Constructor;
   77.35 +import java.lang.reflect.Method;
   77.36 +import java.net.URL;
   77.37 +import java.net.URLClassLoader;
   77.38 +import java.util.HashMap;
   77.39 +import java.util.Map.Entry;
   77.40 +import java.util.Set;
   77.41 +import java.util.WeakHashMap;
   77.42 +import java.util.concurrent.ConcurrentLinkedQueue;
   77.43 +import java.util.concurrent.CountDownLatch;
   77.44 +import javax.imageio.stream.ImageInputStream;
   77.45 +import sun.awt.AppContext;
   77.46 +import sun.awt.SunToolkit;
   77.47 +
   77.48 +public class Main {
   77.49 +
   77.50 +    private static ThreadGroup appsThreadGroup;
   77.51 +
   77.52 +    private static WeakHashMap<MyClassLoader, String> refs =
   77.53 +            new WeakHashMap<MyClassLoader, String>();
   77.54 +
   77.55 +    /** Collection to simulate forgrotten streams **/
   77.56 +    private static HashMap<String, ImageInputStream> strongRefs =
   77.57 +            new HashMap<String, ImageInputStream>();
   77.58 +
   77.59 +    private static ConcurrentLinkedQueue<Throwable> problems =
   77.60 +            new ConcurrentLinkedQueue<Throwable>();
   77.61 +
   77.62 +    private static AppContext mainAppContext = null;
   77.63 +
   77.64 +    private static CountDownLatch doneSignal;
   77.65 +
   77.66 +    private static final int gcTimeout =
   77.67 +        Integer.getInteger("gcTimeout", 10).intValue();
   77.68 +
   77.69 +    private static boolean forgetSomeStreams =
   77.70 +            Boolean.getBoolean("forgetSomeStreams");
   77.71 +
   77.72 +    public static void main(String[] args) throws IOException {
   77.73 +        mainAppContext = SunToolkit.createNewAppContext();
   77.74 +        System.out.println("Current context class loader: " +
   77.75 +                Thread.currentThread().getContextClassLoader());
   77.76 +
   77.77 +        appsThreadGroup = new ThreadGroup("MyAppsThreadGroup");
   77.78 +
   77.79 +        File jar = new File("TestApp.jar");
   77.80 +        if (!jar.exists()) {
   77.81 +            System.out.println(jar.getAbsolutePath() + " was not found!\n" +
   77.82 +                    "Please install the jar with test application correctly!");
   77.83 +            throw new RuntimeException("Test failed: no TestApp.jar");
   77.84 +        }
   77.85 +
   77.86 +        URL[] urls = new URL[]{jar.toURL()};
   77.87 +
   77.88 +        int numApps = Integer.getInteger("numApps", 20).intValue();
   77.89 +
   77.90 +        doneSignal = new CountDownLatch(numApps);
   77.91 +        int cnt = 0;
   77.92 +        while (cnt++ < numApps) {
   77.93 +            launch(urls, "testapp.Main", "launch");
   77.94 +
   77.95 +            checkErrors();
   77.96 +        }
   77.97 +
   77.98 +        System.out.println("Wait for apps completion....");
   77.99 +
  77.100 +        try {
  77.101 +            doneSignal.await();
  77.102 +        } catch (InterruptedException e) {
  77.103 +        }
  77.104 +
  77.105 +        System.out.println("All apps finished.");
  77.106 +
  77.107 +        System.gc();
  77.108 +
  77.109 +        System.out.flush();
  77.110 +
  77.111 +        System.out.println("Enumerate strong refs:");
  77.112 +        for (String is : strongRefs.keySet()) {
  77.113 +            System.out.println("-> " + is);
  77.114 +        }
  77.115 +
  77.116 +        System.out.println("=======================");
  77.117 +
  77.118 +        // wait few seconds
  77.119 +        waitAndGC(gcTimeout);
  77.120 +
  77.121 +        doneSignal = new CountDownLatch(1);
  77.122 +
  77.123 +        Runnable workaround = new Runnable() {
  77.124 +
  77.125 +            public void run() {
  77.126 +                AppContext ctx = null;
  77.127 +                try {
  77.128 +                    ctx = SunToolkit.createNewAppContext();
  77.129 +                } catch (Throwable e) {
  77.130 +                    // ignore...
  77.131 +                } finally {
  77.132 +                    doneSignal.countDown();
  77.133 +                }
  77.134 +            }
  77.135 +        };
  77.136 +
  77.137 +        Thread wt = new Thread(appsThreadGroup, workaround, "Workaround");
  77.138 +        wt.setContextClassLoader(new MyClassLoader(urls, "workaround"));
  77.139 +        wt.start();
  77.140 +        wt = null;
  77.141 +        workaround = null;
  77.142 +
  77.143 +        System.out.println("Wait for workaround completion...");
  77.144 +
  77.145 +        try {
  77.146 +            doneSignal.await();
  77.147 +        } catch (InterruptedException e) {
  77.148 +        }
  77.149 +
  77.150 +        // give a chance to GC
  77.151 +        waitAndGC(gcTimeout);
  77.152 +
  77.153 +        if (!refs.isEmpty()) {
  77.154 +            System.out.println("Classloaders still alive:");
  77.155 +
  77.156 +            for (MyClassLoader l : refs.keySet()) {
  77.157 +                String val = refs.get(l);
  77.158 +
  77.159 +                if (val == null) {
  77.160 +                    throw new RuntimeException("Test FAILED: Invalid classloader name");
  77.161 +                }
  77.162 +                System.out.println("->" + val + (strongRefs.get(val) != null ?
  77.163 +                                    " (has strong ref)" : ""));
  77.164 +                if (strongRefs.get(val) == null) {
  77.165 +                    throw new RuntimeException("Test FAILED: exta class loader is detected! ");
  77.166 +                }
  77.167 +            }
  77.168 +        } else {
  77.169 +            System.out.println("No alive class loaders!!");
  77.170 +        }
  77.171 +        System.out.println("Test PASSED.");
  77.172 +    }
  77.173 +
  77.174 +    private static void waitAndGC(int sec) {
  77.175 +        int cnt = sec;
  77.176 +        System.out.print("Wait ");
  77.177 +        while (cnt-- > 0) {
  77.178 +            try {
  77.179 +                Thread.sleep(1000);
  77.180 +            } catch (InterruptedException e) {
  77.181 +            }
  77.182 +            // do GC every 3 seconds
  77.183 +            if (cnt % 3 == 2) {
  77.184 +                System.gc();
  77.185 +                System.out.print("+");
  77.186 +            } else {
  77.187 +                System.out.print(".");
  77.188 +            }
  77.189 +            checkErrors();
  77.190 +        }
  77.191 +        System.out.println("");
  77.192 +    }
  77.193 +
  77.194 +    private static void checkErrors() {
  77.195 +        while (!problems.isEmpty()) {
  77.196 +            Throwable theProblem = problems.poll();
  77.197 +            System.out.println("Test FAILED!");
  77.198 +            do {
  77.199 +                theProblem.printStackTrace(System.out);
  77.200 +                theProblem = theProblem.getCause();
  77.201 +            } while (theProblem != null);
  77.202 +            throw new RuntimeException("Test FAILED");
  77.203 +        }
  77.204 +    }
  77.205 +    static int counter = 0;
  77.206 +
  77.207 +    private static void launch(URL[] urls, final String className,
  77.208 +                               final String methodName)
  77.209 +    {
  77.210 +        final String uniqClassName = "testapp/Uniq" + counter;
  77.211 +        final boolean saveStrongRef = forgetSomeStreams ? (counter % 5 == 4) : false;
  77.212 +
  77.213 +        System.out.printf("%s: launch the app\n", uniqClassName);
  77.214 +        Runnable launchIt = new Runnable() {
  77.215 +            public void run() {
  77.216 +                AppContext ctx = SunToolkit.createNewAppContext();
  77.217 +
  77.218 +                try {
  77.219 +                    Class appMain =
  77.220 +                        ctx.getContextClassLoader().loadClass(className);
  77.221 +                    Method launch = appMain.getDeclaredMethod(methodName,
  77.222 +                                strongRefs.getClass());
  77.223 +
  77.224 +                    Constructor c = appMain.getConstructor(String.class,
  77.225 +                                                           problems.getClass());
  77.226 +
  77.227 +                    Object o = c.newInstance(uniqClassName, problems);
  77.228 +
  77.229 +                    if (saveStrongRef) {
  77.230 +                        System.out.printf("%s: force strong ref\n",
  77.231 +                                          uniqClassName);
  77.232 +                        launch.invoke(o, strongRefs);
  77.233 +                    } else {
  77.234 +                        HashMap<String, ImageInputStream> empty = null;
  77.235 +                        launch.invoke(o, empty);
  77.236 +                    }
  77.237 +
  77.238 +                    ctx = null;
  77.239 +                } catch (Throwable e) {
  77.240 +                    problems.add(e);
  77.241 +                } finally {
  77.242 +                    doneSignal.countDown();
  77.243 +                }
  77.244 +            }
  77.245 +        };
  77.246 +
  77.247 +        MyClassLoader appClassLoader = new MyClassLoader(urls, uniqClassName);
  77.248 +
  77.249 +        refs.put(appClassLoader, uniqClassName);
  77.250 +
  77.251 +        Thread appThread = new Thread(appsThreadGroup, launchIt,
  77.252 +                                      "AppThread" + counter++);
  77.253 +        appThread.setContextClassLoader(appClassLoader);
  77.254 +
  77.255 +        appThread.start();
  77.256 +        launchIt = null;
  77.257 +        appThread = null;
  77.258 +        appClassLoader = null;
  77.259 +    }
  77.260 +
  77.261 +    private static class MyClassLoader extends URLClassLoader {
  77.262 +
  77.263 +        private static boolean verbose =
  77.264 +            Boolean.getBoolean("verboseClassLoading");
  77.265 +        private String uniqClassName;
  77.266 +
  77.267 +        public MyClassLoader(URL[] urls, String uniq) {
  77.268 +            super(urls);
  77.269 +
  77.270 +            uniqClassName = uniq;
  77.271 +        }
  77.272 +
  77.273 +        public Class loadClass(String name) throws ClassNotFoundException {
  77.274 +            if (verbose) {
  77.275 +                System.out.printf("%s: load class %s\n", uniqClassName, name);
  77.276 +            }
  77.277 +            if (uniqClassName.equals(name)) {
  77.278 +                return Object.class;
  77.279 +            }
  77.280 +            return super.loadClass(name);
  77.281 +        }
  77.282 +
  77.283 +        public String toString() {
  77.284 +            return "MyClassLoader(" + uniqClassName + ")";
  77.285 +        }
  77.286 +    }
  77.287 +}
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/test/javax/imageio/stream/StreamCloserLeak/testapp/Main.java	Tue Apr 07 14:02:54 2009 -0700
    78.3 @@ -0,0 +1,109 @@
    78.4 +/*
    78.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    78.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    78.7 + *
    78.8 + * This code is free software; you can redistribute it and/or modify it
    78.9 + * under the terms of the GNU General Public License version 2 only, as
   78.10 + * published by the Free Software Foundation.
   78.11 + *
   78.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   78.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   78.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   78.15 + * version 2 for more details (a copy is included in the LICENSE file that
   78.16 + * accompanied this code).
   78.17 + *
   78.18 + * You should have received a copy of the GNU General Public License version
   78.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   78.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   78.21 + *
   78.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   78.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   78.24 + * have any questions.
   78.25 + */
   78.26 +
   78.27 +package testapp;
   78.28 +
   78.29 +import java.io.ByteArrayInputStream;
   78.30 +import java.io.File;
   78.31 +import java.io.IOException;
   78.32 +import java.io.InputStream;
   78.33 +import java.util.HashMap;
   78.34 +import java.util.concurrent.ConcurrentLinkedQueue;
   78.35 +import javax.imageio.stream.FileCacheImageInputStream;
   78.36 +import javax.imageio.stream.ImageInputStream;
   78.37 +
   78.38 +public class Main {
   78.39 +
   78.40 +    public static void main(String[] args) {
   78.41 +        Main o = new Main("testapp.some.class", null);
   78.42 +        o.launch(null);
   78.43 +    }
   78.44 +
   78.45 +    private final  String uniqClassName;
   78.46 +    private final ConcurrentLinkedQueue<Throwable> problems;
   78.47 +
   78.48 +    public Main(String uniq, ConcurrentLinkedQueue<Throwable> p) {
   78.49 +        uniqClassName = uniq;
   78.50 +        problems = p;
   78.51 +    }
   78.52 +
   78.53 +    public void launch(HashMap<String, ImageInputStream> refs) {
   78.54 +        System.out.printf("%s: current context class loader: %s\n",
   78.55 +                          uniqClassName,
   78.56 +                Thread.currentThread().getContextClassLoader());
   78.57 +        try {
   78.58 +            byte[] data = new byte[1024];
   78.59 +            ByteArrayInputStream bais = new ByteArrayInputStream(data);
   78.60 +            MyImageInputStream iis = new MyImageInputStream(bais,
   78.61 +                                                            uniqClassName,
   78.62 +                                                            problems);
   78.63 +            if (refs != null) {
   78.64 +                System.out.printf("%s: added to strong store\n",
   78.65 +                                  uniqClassName);
   78.66 +                refs.put(uniqClassName, iis);
   78.67 +            }
   78.68 +            iis.read();
   78.69 +            //leave stream open : let's shutdown hook work!
   78.70 +        } catch (IOException e) {
   78.71 +            problems.add(e);
   78.72 +        }
   78.73 +    }
   78.74 +
   78.75 +    private static class MyImageInputStream extends FileCacheImageInputStream {
   78.76 +        private final String uniqClassName;
   78.77 +        private ConcurrentLinkedQueue<Throwable> problems;
   78.78 +        public MyImageInputStream(InputStream is, String uniq,
   78.79 +                                  ConcurrentLinkedQueue<Throwable> p) throws IOException
   78.80 +   {
   78.81 +            super(is, new File("tmp"));
   78.82 +            uniqClassName = uniq;
   78.83 +            problems = p;
   78.84 +        }
   78.85 +
   78.86 +        @Override
   78.87 +        public void close() throws IOException {
   78.88 +            Test t = new Test();
   78.89 +            try {
   78.90 +                t.doTest(uniqClassName);
   78.91 +            } catch (Throwable e) {
   78.92 +                problems.add(e);
   78.93 +            }
   78.94 +
   78.95 +            super.close();
   78.96 +
   78.97 +            problems = null;
   78.98 +        }
   78.99 +    }
  78.100 +}
  78.101 +
  78.102 +class Test {
  78.103 +    public void doTest(String uniqClassName) throws ClassNotFoundException {
  78.104 +        System.out.printf("%s: Current thread: %s\n", uniqClassName,
  78.105 +                          Thread.currentThread());
  78.106 +
  78.107 +        ClassLoader thisCL = this.getClass().getClassLoader();
  78.108 +        Class uniq = thisCL.loadClass(uniqClassName);
  78.109 +
  78.110 +        System.out.printf("%s: test is done!\n",uniqClassName);
  78.111 +    }
  78.112 +}
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/test/sun/awt/image/DrawByteBinary.java	Tue Apr 07 14:02:54 2009 -0700
    79.3 @@ -0,0 +1,75 @@
    79.4 +/*
    79.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    79.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    79.7 + *
    79.8 + * This code is free software; you can redistribute it and/or modify it
    79.9 + * under the terms of the GNU General Public License version 2 only, as
   79.10 + * published by the Free Software Foundation.
   79.11 + *
   79.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   79.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   79.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   79.15 + * version 2 for more details (a copy is included in the LICENSE file that
   79.16 + * accompanied this code).
   79.17 + *
   79.18 + * You should have received a copy of the GNU General Public License version
   79.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   79.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   79.21 + *
   79.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   79.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   79.24 + * have any questions.
   79.25 + */
   79.26 +
   79.27 +/**
   79.28 + * @test
   79.29 + * @bug     6800846
   79.30 + *
   79.31 + * @summary Test verifes that images with short palette are rendered
   79.32 + *          withourt artifacts.
   79.33 + *
   79.34 + * @run     main DrawByteBinary
   79.35 + */
   79.36 +
   79.37 +
   79.38 +import java.awt.*;
   79.39 +import java.awt.color.*;
   79.40 +import java.awt.image.*;
   79.41 +import static java.awt.image.BufferedImage.*;
   79.42 +
   79.43 +
   79.44 +public class DrawByteBinary {
   79.45 +
   79.46 +    public static void main(String args[]) {
   79.47 +        int w = 100, h = 30;
   79.48 +        int x = 10;
   79.49 +        byte[] arr = {(byte)0xff, (byte)0x0, (byte)0x00};
   79.50 +
   79.51 +        IndexColorModel newCM = new IndexColorModel(1, 2, arr, arr, arr);
   79.52 +        BufferedImage orig = new BufferedImage(w, h, TYPE_BYTE_BINARY, newCM);
   79.53 +        Graphics2D g2d = orig.createGraphics();
   79.54 +        g2d.setColor(Color.white);
   79.55 +        g2d.fillRect(0, 0, w, h);
   79.56 +        g2d.setColor(Color.black);
   79.57 +        g2d.drawLine(x, 0, x, h);
   79.58 +        g2d.dispose();
   79.59 +
   79.60 +        IndexColorModel origCM = (IndexColorModel)orig.getColorModel();
   79.61 +        BufferedImage test = new BufferedImage(w, h, TYPE_BYTE_BINARY,origCM);
   79.62 +        g2d = test.createGraphics();
   79.63 +        g2d.drawImage(orig, 0, 0, null);
   79.64 +        g2d.dispose();
   79.65 +
   79.66 +        int y = h / 2;
   79.67 +
   79.68 +        // we expect white color outside the line
   79.69 +        if (test.getRGB(x - 1, y) != 0xffffffff) {
   79.70 +            throw new RuntimeException("Invalid color outside the line.");
   79.71 +        }
   79.72 +
   79.73 +        // we expect black color on the line
   79.74 +        if (test.getRGB(x, y) != 0xff000000) {
   79.75 +            throw new RuntimeException("Invalid color on the line.");
   79.76 +        }
   79.77 +    }
   79.78 +}
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java	Tue Apr 07 14:02:54 2009 -0700
    80.3 @@ -0,0 +1,120 @@
    80.4 +/*
    80.5 + * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
    80.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    80.7 + *
    80.8 + * This code is free software; you can redistribute it and/or modify it
    80.9 + * under the terms of the GNU General Public License version 2 only, as
   80.10 + * published by the Free Software Foundation.
   80.11 + *
   80.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   80.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   80.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   80.15 + * version 2 for more details (a copy is included in the LICENSE file that
   80.16 + * accompanied this code).
   80.17 + *
   80.18 + * You should have received a copy of the GNU General Public License version
   80.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   80.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   80.21 + *
   80.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   80.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   80.24 + * have any questions.
   80.25 + */
   80.26 +
   80.27 +/**
   80.28 + * @test
   80.29 + * @bug 6476665 6523403 6733501
   80.30 + * @summary Verifies reading and writing profiles and tags of the standard color
   80.31 + * spaces
   80.32 + * @run main ReadWriteProfileTest
   80.33 + */
   80.34 +import java.awt.color.ColorSpace;
   80.35 +import java.awt.color.ICC_Profile;
   80.36 +import java.util.*;
   80.37 +import java.nio.*;
   80.38 +import java.util.Hashtable;
   80.39 +
   80.40 +public class ReadWriteProfileTest implements Runnable {
   80.41 +    /* Location of the tag sig counter in 4-byte words */
   80.42 +    final static int TAG_COUNT_OFFSET = 32;
   80.43 +
   80.44 +    /* Location of the tag sig table in 4-byte words */
   80.45 +    final static int TAG_ELEM_OFFSET = 33;
   80.46 +
   80.47 +    static byte[][] profiles;
   80.48 +    static int [][] tagSigs;
   80.49 +    static Hashtable<Integer,byte[]> [] tags;
   80.50 +
   80.51 +    static int [] cspaces = {ColorSpace.CS_sRGB, ColorSpace.CS_PYCC,
   80.52 +                             ColorSpace.CS_LINEAR_RGB, ColorSpace.CS_CIEXYZ,
   80.53 +                             ColorSpace.CS_GRAY};
   80.54 +
   80.55 +    static String [] csNames = {"sRGB", "PYCC", "LINEAR_RGB", "CIEXYZ", "GRAY"};
   80.56 +
   80.57 +    static void getProfileTags(byte [] data, Hashtable tags) {
   80.58 +        ByteBuffer byteBuf = ByteBuffer.wrap(data);
   80.59 +        IntBuffer intBuf = byteBuf.asIntBuffer();
   80.60 +        int tagCount = intBuf.get(TAG_COUNT_OFFSET);
   80.61 +        intBuf.position(TAG_ELEM_OFFSET);
   80.62 +        for (int i = 0; i < tagCount; i++) {
   80.63 +            int tagSig = intBuf.get();
   80.64 +            int tagDataOff = intBuf.get();
   80.65 +            int tagSize = intBuf.get();
   80.66 +
   80.67 +            byte [] tagData = new byte[tagSize];
   80.68 +            byteBuf.position(tagDataOff);
   80.69 +            byteBuf.get(tagData);
   80.70 +            tags.put(tagSig, tagData);
   80.71 +        }
   80.72 +    }
   80.73 +
   80.74 +    static {
   80.75 +        profiles = new byte[cspaces.length][];
   80.76 +        tags = new Hashtable[cspaces.length];
   80.77 +
   80.78 +        for (int i = 0; i < cspaces.length; i++) {
   80.79 +            ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
   80.80 +            profiles[i] = pf.getData();
   80.81 +            tags[i] = new Hashtable();
   80.82 +            getProfileTags(profiles[i], tags[i]);
   80.83 +        }
   80.84 +    }
   80.85 +
   80.86 +    public void run() {
   80.87 +        for (int i = 0; i < cspaces.length; i++) {
   80.88 +            ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
   80.89 +            byte [] data = pf.getData();
   80.90 +            pf = ICC_Profile.getInstance(data);
   80.91 +            if (!Arrays.equals(data, profiles[i])) {
   80.92 +                System.err.println("Incorrect result of getData() " + "with " +
   80.93 +                                   csNames[i] + " profile");
   80.94 +                throw new RuntimeException("Incorrect result of getData()");
   80.95 +            }
   80.96 +
   80.97 +            for (int tagSig : tags[i].keySet()) {
   80.98 +                byte [] tagData = pf.getData(tagSig);
   80.99 +                byte [] empty = new byte[tagData.length];
  80.100 +                pf.setData(tagSig, empty);
  80.101 +                pf.setData(tagSig, tagData);
  80.102 +
  80.103 +                byte [] tagData1 = pf.getData(tagSig);
  80.104 +
  80.105 +                if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
  80.106 +                {
  80.107 +                    System.err.println("Incorrect result of getData(int) with" +
  80.108 +                                       " tag " +
  80.109 +                                       Integer.toHexString(tagSig) +
  80.110 +                                       " of " + csNames[i] + " profile");
  80.111 +
  80.112 +                    throw new RuntimeException("Incorrect result of " +
  80.113 +                                               "getData(int)");
  80.114 +                }
  80.115 +            }
  80.116 +        }
  80.117 +    }
  80.118 +
  80.119 +    public static void main(String [] args) {
  80.120 +        ReadWriteProfileTest test = new ReadWriteProfileTest();
  80.121 +        test.run();
  80.122 +    }
  80.123 +}
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/test/sun/pisces/DashStrokeTest.java	Tue Apr 07 14:02:54 2009 -0700
    81.3 @@ -0,0 +1,86 @@
    81.4 +/*
    81.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    81.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    81.7 + *
    81.8 + * This code is free software; you can redistribute it and/or modify it
    81.9 + * under the terms of the GNU General Public License version 2 only, as
   81.10 + * published by the Free Software Foundation.
   81.11 + *
   81.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   81.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   81.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   81.15 + * version 2 for more details (a copy is included in the LICENSE file that
   81.16 + * accompanied this code).
   81.17 + *
   81.18 + * You should have received a copy of the GNU General Public License version
   81.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   81.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   81.21 + *
   81.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   81.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   81.24 + * have any questions.
   81.25 + */
   81.26 +
   81.27 +/* @test
   81.28 + * @summary verify that first element is a dash
   81.29 + * @bug 6793344
   81.30 + */
   81.31 +
   81.32 +import java.awt.*;
   81.33 +import java.awt.image.*;
   81.34 +
   81.35 +import javax.swing.JButton;
   81.36 +import javax.swing.JFrame;
   81.37 +import javax.swing.SwingUtilities;
   81.38 +import javax.swing.WindowConstants;
   81.39 +
   81.40 +public class DashStrokeTest extends Component {
   81.41 +
   81.42 +    static BufferedImage bi;
   81.43 +    static boolean printed = false;
   81.44 +
   81.45 +    public Dimension getPreferredSize() {
   81.46 +      return new Dimension(200,200);
   81.47 +    }
   81.48 +
   81.49 +    public static void drawGui() {
   81.50 +        bi = new BufferedImage(200, 20, BufferedImage.TYPE_INT_RGB);
   81.51 +        Graphics2D g2d = bi.createGraphics();
   81.52 +        BasicStroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
   81.53 +                BasicStroke.JOIN_ROUND, 1.0f, new float[] { 0.0f, 200 },
   81.54 +                1.0f);
   81.55 +
   81.56 +        g2d.setStroke(dashStroke);
   81.57 +        g2d.setColor(Color.RED);
   81.58 +        g2d.drawLine(5,10, 100,10);
   81.59 +        printed =true;
   81.60 +    }
   81.61 +
   81.62 +    public static void main(String[] args) {
   81.63 +            try {
   81.64 +            SwingUtilities.invokeAndWait(new Runnable() {
   81.65 +
   81.66 +            @Override
   81.67 +            public void run() {
   81.68 +                drawGui();
   81.69 +            }
   81.70 +
   81.71 +            });
   81.72 +            } catch (Exception e) {
   81.73 +            }
   81.74 +
   81.75 +            if (printed) {
   81.76 +                checkBI(bi, Color.RED);
   81.77 +            }
   81.78 +    }
   81.79 +
   81.80 +    static void checkBI(BufferedImage bi, Color badColor) {
   81.81 +      int badrgb = badColor.getRGB();
   81.82 +
   81.83 +      int col = bi.getRGB(6, 9);
   81.84 +      if (col == badrgb) {
   81.85 +          throw new RuntimeException("A pixel was turned on. ");
   81.86 +      }
   81.87 +   }
   81.88 +}
   81.89 +
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/test/sun/pisces/JoinMiterTest.java	Tue Apr 07 14:02:54 2009 -0700
    82.3 @@ -0,0 +1,48 @@
    82.4 +/*
    82.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    82.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    82.7 + *
    82.8 + * This code is free software; you can redistribute it and/or modify it
    82.9 + * under the terms of the GNU General Public License version 2 only, as
   82.10 + * published by the Free Software Foundation.
   82.11 + *
   82.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   82.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   82.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   82.15 + * version 2 for more details (a copy is included in the LICENSE file that
   82.16 + * accompanied this code).
   82.17 + *
   82.18 + * You should have received a copy of the GNU General Public License version
   82.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   82.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   82.21 + *
   82.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   82.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   82.24 + * have any questions.
   82.25 + */
   82.26 +
   82.27 +/* @test
   82.28 + * @summary Pass if no RuntimeException.
   82.29 + * @bug 6812600
   82.30 + */
   82.31 +import java.awt.*;
   82.32 +import java.awt.image.BufferedImage;
   82.33 +
   82.34 +public class JoinMiterTest {
   82.35 +
   82.36 +  public static void main(String[] args) throws Exception {
   82.37 +    BufferedImage image = new BufferedImage(200, 200,
   82.38 +BufferedImage.TYPE_INT_RGB);
   82.39 +    Graphics2D g = image.createGraphics();
   82.40 +    g.setPaint(Color.WHITE);
   82.41 +    g.fill(new Rectangle(image.getWidth(), image.getHeight()));
   82.42 +    g.translate(25, 100);
   82.43 +    g.setPaint(Color.BLACK);
   82.44 +    g.setStroke(new BasicStroke(20, BasicStroke.CAP_BUTT,
   82.45 +                                BasicStroke.JOIN_MITER));
   82.46 +    g.draw(new Polygon(new int[] {0, 150, 0}, new int[] {75, 0, -75}, 3));
   82.47 +    if (image.getRGB(16, 10) == Color.WHITE.getRGB()) {
   82.48 +      throw new RuntimeException("Miter is not rendered.");
   82.49 +    }
   82.50 +  }
   82.51 +}