# HG changeset patch # User jgodinez # Date 1246311742 25200 # Node ID c8270bf40b76e2ab1cd6446d58e056ef97ca08ff # Parent f1c6e189f315c3cff85b5a700d3fc8d0af5d0712# Parent db307834eb9b01138facd0f9e773fa5b6871234b Merge diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java Mon Jun 29 14:42:22 2009 -0700 @@ -506,6 +506,19 @@ writeFileHeader(fileSize, offset); + /* According to MSDN description, the top-down image layout + * is allowed only if compression type is BI_RGB or BI_BITFIELDS. + * Images with any other compression type must be wrote in the + * bottom-up layout. + */ + if (compressionType == BMPConstants.BI_RGB || + compressionType == BMPConstants.BI_BITFIELDS) + { + isTopDown = bmpParam.isTopDown(); + } else { + isTopDown = false; + } + writeInfoHeader(headerSize, bitsPerPixel); // compression @@ -588,8 +601,6 @@ return; } - isTopDown = bmpParam.isTopDown(); - int maxBandOffset = bandOffsets[0]; for (int i = 1; i < bandOffsets.length; i++) if (bandOffsets[i] > maxBandOffset) @@ -1299,7 +1310,7 @@ stream.writeInt(w); // height - stream.writeInt(h); + stream.writeInt(isTopDown ? -h : h); // number of planes stream.writeShort(1); diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/common/ReaderUtil.java Mon Jun 29 14:42:22 2009 -0700 @@ -27,6 +27,8 @@ import java.awt.Point; import java.awt.Rectangle; +import java.io.IOException; +import javax.imageio.stream.ImageInputStream; /** * This class contains utility methods that may be useful to ImageReader @@ -198,4 +200,17 @@ vals, 1); return vals; } + + public static int readMultiByteInteger(ImageInputStream iis) + throws IOException + { + int value = iis.readByte(); + int result = value & 0x7f; + while((value & 0x80) == 0x80) { + result <<= 7; + value = iis.readByte(); + result |= (value & 0x7f); + } + return result; + } } diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Mon Jun 29 14:42:22 2009 -0700 @@ -215,17 +215,21 @@ public static class JCS { public static final ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); - public static final ColorSpace YCC; + + private static ColorSpace YCC = null; + private static boolean yccInited = false; - static { - ColorSpace cs = null; - try { - cs = ColorSpace.getInstance(ColorSpace.CS_PYCC); - } catch (IllegalArgumentException e) { - // PYCC.pf may not always be installed - } finally { - YCC = cs; + public static ColorSpace getYCC() { + if (!yccInited) { + try { + YCC = ColorSpace.getInstance(ColorSpace.CS_PYCC); + } catch (IllegalArgumentException e) { + // PYCC.pf may not always be installed + } finally { + yccInited = true; + } } + return YCC; } } diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Mon Jun 29 14:42:22 2009 -0700 @@ -41,6 +41,7 @@ import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import java.awt.color.ICC_ColorSpace; +import java.awt.color.CMMException; import java.awt.image.BufferedImage; import java.awt.image.Raster; import java.awt.image.WritableRaster; @@ -53,6 +54,7 @@ import java.util.List; import java.util.Iterator; import java.util.ArrayList; +import java.util.NoSuchElementException; import sun.java2d.Disposer; import sun.java2d.DisposerRecord; @@ -215,51 +217,6 @@ /** The DisposerRecord that handles the actual disposal of this reader. */ private DisposerRecord disposerRecord; - /** - * Maintain an array of the default image types corresponding to the - * various supported IJG colorspace codes. - */ - private static final ImageTypeSpecifier [] defaultTypes = - new ImageTypeSpecifier [JPEG.NUM_JCS_CODES]; - - static { - defaultTypes[JPEG.JCS_GRAYSCALE] = - ImageTypeSpecifier.createFromBufferedImageType - (BufferedImage.TYPE_BYTE_GRAY); - defaultTypes[JPEG.JCS_RGB] = - ImageTypeSpecifier.createInterleaved - (JPEG.JCS.sRGB, - JPEG.bOffsRGB, - DataBuffer.TYPE_BYTE, - false, - false); - defaultTypes[JPEG.JCS_RGBA] = - ImageTypeSpecifier.createPacked - (JPEG.JCS.sRGB, - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x000000ff, - DataBuffer.TYPE_INT, - false); - if (JPEG.JCS.YCC != null) { - defaultTypes[JPEG.JCS_YCC] = - ImageTypeSpecifier.createInterleaved - (JPEG.JCS.YCC, - JPEG.bandOffsets[2], - DataBuffer.TYPE_BYTE, - false, - false); - defaultTypes[JPEG.JCS_YCCA] = - ImageTypeSpecifier.createInterleaved - (JPEG.JCS.YCC, - JPEG.bandOffsets[3], - DataBuffer.TYPE_BYTE, - true, - false); - } - } - /** Sets up static C structures. */ private static native void initReaderIDs(Class iisClass, Class qTableClass, @@ -673,6 +630,17 @@ !java.util.Arrays.equals(oldData, newData)) { iccCS = new ICC_ColorSpace(newProfile); + // verify new color space + try { + float[] colors = iccCS.fromRGB(new float[] {1f, 0f, 0f}); + } catch (CMMException e) { + /* + * Embedded profile seems to be corrupted. + * Ignore this profile. + */ + iccCS = null; + warningOccurred(WARNING_IGNORE_INVALID_ICC); + } } } @@ -706,11 +674,11 @@ * Return an ImageTypeSpecifier corresponding to the given * color space code, or null if the color space is unsupported. */ - private ImageTypeSpecifier getImageType(int code) { - ImageTypeSpecifier ret = null; + private ImageTypeProducer getImageType(int code) { + ImageTypeProducer ret = null; if ((code > 0) && (code < JPEG.NUM_JCS_CODES)) { - ret = defaultTypes[code]; + ret = ImageTypeProducer.getTypeProducer(code); } return ret; } @@ -724,7 +692,7 @@ } // Returns null if it can't be represented - return getImageType(colorSpaceCode); + return getImageType(colorSpaceCode).getType(); } finally { clearThreadLock(); } @@ -758,13 +726,13 @@ // Get the raw ITS, if there is one. Note that this // won't always be the same as the default. - ImageTypeSpecifier raw = getImageType(colorSpaceCode); + ImageTypeProducer raw = getImageType(colorSpaceCode); // Given the encoded colorspace, build a list of ITS's // representing outputs you could handle starting // with the default. - ArrayList list = new ArrayList(1); + ArrayList list = new ArrayList(1); switch (colorSpaceCode) { case JPEG.JCS_GRAYSCALE: @@ -774,9 +742,7 @@ case JPEG.JCS_RGB: list.add(raw); list.add(getImageType(JPEG.JCS_GRAYSCALE)); - if (JPEG.JCS.YCC != null) { - list.add(getImageType(JPEG.JCS_YCC)); - } + list.add(getImageType(JPEG.JCS_YCC)); break; case JPEG.JCS_RGBA: list.add(raw); @@ -801,19 +767,21 @@ list.add(getImageType(JPEG.JCS_RGB)); if (iccCS != null) { - list.add(ImageTypeSpecifier.createInterleaved + list.add(new ImageTypeProducer() { + protected ImageTypeSpecifier produce() { + return ImageTypeSpecifier.createInterleaved (iccCS, JPEG.bOffsRGB, // Assume it's for RGB DataBuffer.TYPE_BYTE, false, - false)); + false); + } + }); } list.add(getImageType(JPEG.JCS_GRAYSCALE)); - if (JPEG.JCS.YCC != null) { // Might be null if PYCC.pf not installed - list.add(getImageType(JPEG.JCS_YCC)); - } + list.add(getImageType(JPEG.JCS_YCC)); break; case JPEG.JCS_YCbCrA: // Default is to convert to RGBA // As there is no YCbCr ColorSpace, we can't support @@ -822,7 +790,7 @@ break; } - return list.iterator(); + return new ImageTypeIterator(list.iterator()); } /** @@ -872,6 +840,10 @@ if (csType == ColorSpace.TYPE_RGB) { // We want RGB // IJG can do this for us more efficiently setOutColorSpace(structPointer, JPEG.JCS_RGB); + // Update java state according to changes + // in the native part of decoder. + outColorSpaceCode = JPEG.JCS_RGB; + numComponents = 3; } else if (csType != ColorSpace.TYPE_GRAY) { throw new IIOException("Incompatible color conversion"); } @@ -881,6 +853,10 @@ if (colorSpaceCode == JPEG.JCS_YCbCr) { // If the jpeg space is YCbCr, IJG can do it setOutColorSpace(structPointer, JPEG.JCS_GRAYSCALE); + // Update java state according to changes + // in the native part of decoder. + outColorSpaceCode = JPEG.JCS_GRAYSCALE; + numComponents = 1; } } else if ((iccCS != null) && (cm.getNumComponents() == numComponents) && @@ -906,20 +882,26 @@ } break; case JPEG.JCS_YCC: - if (JPEG.JCS.YCC == null) { // We can't do YCC at all - throw new IIOException("Incompatible color conversion"); - } - if ((cs != JPEG.JCS.YCC) && - (cm.getNumComponents() == numComponents)) { - convert = new ColorConvertOp(JPEG.JCS.YCC, cs, null); + { + ColorSpace YCC = JPEG.JCS.getYCC(); + if (YCC == null) { // We can't do YCC at all + throw new IIOException("Incompatible color conversion"); + } + if ((cs != YCC) && + (cm.getNumComponents() == numComponents)) { + convert = new ColorConvertOp(YCC, cs, null); + } } break; case JPEG.JCS_YCCA: - // No conversions available; image must be YCCA - if ((JPEG.JCS.YCC == null) || // We can't do YCC at all - (cs != JPEG.JCS.YCC) || - (cm.getNumComponents() != numComponents)) { - throw new IIOException("Incompatible color conversion"); + { + ColorSpace YCC = JPEG.JCS.getYCC(); + // No conversions available; image must be YCCA + if ((YCC == null) || // We can't do YCC at all + (cs != YCC) || + (cm.getNumComponents() != numComponents)) { + throw new IIOException("Incompatible color conversion"); + } } break; default: @@ -1554,3 +1536,140 @@ } } } + +/** + * An internal helper class that wraps producer's iterator + * and extracts specifier instances on demand. + */ +class ImageTypeIterator implements Iterator { + private Iterator producers; + private ImageTypeSpecifier theNext = null; + + public ImageTypeIterator(Iterator producers) { + this.producers = producers; + } + + public boolean hasNext() { + if (theNext != null) { + return true; + } + if (!producers.hasNext()) { + return false; + } + do { + theNext = producers.next().getType(); + } while (theNext == null && producers.hasNext()); + + return (theNext != null); + } + + public ImageTypeSpecifier next() { + if (theNext != null || hasNext()) { + ImageTypeSpecifier t = theNext; + theNext = null; + return t; + } else { + throw new NoSuchElementException(); + } + } + + public void remove() { + producers.remove(); + } +} + +/** + * An internal helper class that provides means for deferred creation + * of ImageTypeSpecifier instance required to describe available + * destination types. + * + * This implementation only supports standard + * jpeg color spaces (defined by corresponding JCS color space code). + * + * To support other color spaces one can override produce() method to + * return custom instance of ImageTypeSpecifier. + */ +class ImageTypeProducer { + + private ImageTypeSpecifier type = null; + boolean failed = false; + private int csCode; + + public ImageTypeProducer(int csCode) { + this.csCode = csCode; + } + + public ImageTypeProducer() { + csCode = -1; // undefined + } + + public synchronized ImageTypeSpecifier getType() { + if (!failed && type == null) { + try { + type = produce(); + } catch (Throwable e) { + failed = true; + } + } + return type; + } + + private static final ImageTypeProducer [] defaultTypes = + new ImageTypeProducer [JPEG.NUM_JCS_CODES]; + + public synchronized static ImageTypeProducer getTypeProducer(int csCode) { + if (csCode < 0 || csCode >= JPEG.NUM_JCS_CODES) { + return null; + } + if (defaultTypes[csCode] == null) { + defaultTypes[csCode] = new ImageTypeProducer(csCode); + } + return defaultTypes[csCode]; + } + + protected ImageTypeSpecifier produce() { + switch (csCode) { + case JPEG.JCS_GRAYSCALE: + return ImageTypeSpecifier.createFromBufferedImageType + (BufferedImage.TYPE_BYTE_GRAY); + case JPEG.JCS_RGB: + return ImageTypeSpecifier.createInterleaved(JPEG.JCS.sRGB, + JPEG.bOffsRGB, + DataBuffer.TYPE_BYTE, + false, + false); + case JPEG.JCS_RGBA: + return ImageTypeSpecifier.createPacked(JPEG.JCS.sRGB, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff, + DataBuffer.TYPE_INT, + false); + case JPEG.JCS_YCC: + if (JPEG.JCS.getYCC() != null) { + return ImageTypeSpecifier.createInterleaved( + JPEG.JCS.getYCC(), + JPEG.bandOffsets[2], + DataBuffer.TYPE_BYTE, + false, + false); + } else { + return null; + } + case JPEG.JCS_YCCA: + if (JPEG.JCS.getYCC() != null) { + return ImageTypeSpecifier.createInterleaved( + JPEG.JCS.getYCC(), + JPEG.bandOffsets[3], + DataBuffer.TYPE_BYTE, + true, + false); + } else { + return null; + } + default: + return null; + } + } +} diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Mon Jun 29 14:42:22 2009 -0700 @@ -812,7 +812,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.JCS.YCC) { + if (cs == JPEG.JCS.getYCC()) { if (!alpha) { if (jfif != null) { convertTosRGB = true; @@ -1494,7 +1494,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.JCS.YCC) { + if (cs == JPEG.JCS.getYCC()) { if (alpha) { retval = JPEG.JCS_YCCA; } else { @@ -1533,7 +1533,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.JCS.YCC) { + if (cs == JPEG.JCS.getYCC()) { if (alpha) { retval = JPEG.JCS_YCCA; } else { @@ -1579,7 +1579,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.JCS.YCC) { + if (cs == JPEG.JCS.getYCC()) { if (alpha) { retval = JPEG.JCS_YCCA; } else { diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java Mon Jun 29 14:42:22 2009 -0700 @@ -490,7 +490,7 @@ } break; case ColorSpace.TYPE_3CLR: - if (cs == JPEG.JCS.YCC) { + if (cs == JPEG.JCS.getYCC()) { wantJFIF = false; componentIDs[0] = (byte) 'Y'; componentIDs[1] = (byte) 'C'; diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReader.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReader.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReader.java Mon Jun 29 14:42:22 2009 -0700 @@ -45,6 +45,7 @@ import java.util.Iterator; import com.sun.imageio.plugins.common.I18N; +import com.sun.imageio.plugins.common.ReaderUtil; /** This class is the Java Image IO plugin reader for WBMP images. * It may subsample the image, clip the image, @@ -141,11 +142,11 @@ metadata.wbmpType = wbmpType; // Read image width - width = readMultiByteInteger(); + width = ReaderUtil.readMultiByteInteger(iis); metadata.width = width; // Read image height - height = readMultiByteInteger(); + height = ReaderUtil.readMultiByteInteger(iis); metadata.height = height; gotHeader = true; @@ -311,17 +312,6 @@ gotHeader = false; } - private int readMultiByteInteger() throws IOException { - int value = iis.readByte(); - int result = value & 0x7f; - while((value & 0x80) == 0x80) { - result <<= 7; - value = iis.readByte(); - result |= (value & 0x7f); - } - return result; - } - /* * This method verifies that given byte is valid wbmp type marker. * At the moment only 0x0 marker is described by wbmp spec. diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Mon Jun 29 14:42:22 2009 -0700 @@ -33,9 +33,13 @@ import java.io.IOException; import javax.imageio.ImageReader; import javax.imageio.IIOException; +import com.sun.imageio.plugins.common.ReaderUtil; public class WBMPImageReaderSpi extends ImageReaderSpi { + private static final int MAX_WBMP_WIDTH = 1024; + private static final int MAX_WBMP_HEIGHT = 768; + private static String [] writerSpiNames = {"com.sun.imageio.plugins.wbmp.WBMPImageWriterSpi"}; private static String[] formatNames = {"wbmp", "WBMP"}; @@ -79,16 +83,44 @@ } ImageInputStream stream = (ImageInputStream)source; - byte[] b = new byte[3]; stream.mark(); - stream.readFully(b); + int type = stream.readByte(); // TypeField + int fixHeaderField = stream.readByte(); + // check WBMP "header" + if (type != 0 || fixHeaderField != 0) { + // while WBMP reader does not support ext WBMP headers + stream.reset(); + return false; + } + + int width = ReaderUtil.readMultiByteInteger(stream); + int height = ReaderUtil.readMultiByteInteger(stream); + // check image dimension + if (width <= 0 || height <= 0) { + stream.reset(); + return false; + } + + long dataLength = stream.length(); + if (dataLength == -1) { + // We can't verify that amount of data in the stream + // corresponds to image dimension because we do not know + // the length of the data stream. + // Assuming that wbmp image are used for mobile devices, + // let's introduce an upper limit for image dimension. + // In case if exact amount of raster data is unknown, + // let's reject images with dimension above the limit. + stream.reset(); + return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT); + } + + dataLength -= stream.getStreamPosition(); stream.reset(); - return ((b[0] == (byte)0) && // TypeField == 0 - b[1] == 0 && // FixHeaderField == 0xxx00000; not support ext header - ((b[2] & 0x8f) != 0 || (b[2] & 0x7f) != 0)); // First width byte - //XXX: b[2] & 0x8f) != 0 for the bug in Sony Ericsson encoder. + long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1); + + return (dataLength == scanSize * height); } public ImageReader createReaderInstance(Object extension) diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/java/awt/Font.java --- a/jdk/src/share/classes/java/awt/Font.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/java/awt/Font.java Mon Jun 29 14:42:22 2009 -0700 @@ -445,18 +445,19 @@ */ private AttributeValues getAttributeValues() { if (values == null) { - values = new AttributeValues(); - values.setFamily(name); - values.setSize(pointSize); // expects the float value. + AttributeValues valuesTmp = new AttributeValues(); + valuesTmp.setFamily(name); + valuesTmp.setSize(pointSize); // expects the float value. if ((style & BOLD) != 0) { - values.setWeight(2); // WEIGHT_BOLD + valuesTmp.setWeight(2); // WEIGHT_BOLD } if ((style & ITALIC) != 0) { - values.setPosture(.2f); // POSTURE_OBLIQUE + valuesTmp.setPosture(.2f); // POSTURE_OBLIQUE } - values.defineAll(PRIMARY_MASK); // for streaming compatibility + valuesTmp.defineAll(PRIMARY_MASK); // for streaming compatibility + values = valuesTmp; } return values; diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/java/awt/GraphicsEnvironment.java --- a/jdk/src/share/classes/java/awt/GraphicsEnvironment.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/java/awt/GraphicsEnvironment.java Mon Jun 29 14:42:22 2009 -0700 @@ -79,8 +79,9 @@ try { // long t0 = System.currentTimeMillis(); - localEnv = - (GraphicsEnvironment) Class.forName(nm).newInstance(); + ClassLoader cl = ClassLoader.getSystemClassLoader(); + Class geCls = Class.forName(nm, true, cl); + localEnv = (GraphicsEnvironment)geCls.newInstance(); // long t1 = System.currentTimeMillis(); // System.out.println("GE creation took " + (t1-t0)+ "ms."); if (isHeadless()) { diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/java/awt/color/ICC_Profile.java --- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java Mon Jun 29 14:42:22 2009 -0700 @@ -863,11 +863,16 @@ case ColorSpace.CS_PYCC: synchronized(ICC_Profile.class) { if (PYCCprofile == null) { - ProfileDeferralInfo pInfo = - new ProfileDeferralInfo("PYCC.pf", - ColorSpace.TYPE_3CLR, 3, - CLASS_DISPLAY); - PYCCprofile = getDeferredInstance(pInfo); + if (getProfileFile("PYCC.pf") != null) { + ProfileDeferralInfo pInfo = + new ProfileDeferralInfo("PYCC.pf", + ColorSpace.TYPE_3CLR, 3, + CLASS_DISPLAY); + PYCCprofile = getDeferredInstance(pInfo); + } else { + throw new IllegalArgumentException( + "Can't load standard profile: PYCC.pf"); + } } thisProfile = PYCCprofile; } @@ -1783,17 +1788,33 @@ return (FileInputStream)java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { - return privilegedOpenProfile(fileName); + File f = privilegedGetProfileFile(fileName); + if (f != null) { + try { + return new FileInputStream(f); + } catch (FileNotFoundException e) { + } + } + return null; + } + }); + } + + private static File getProfileFile(final String fileName) { + return (File)java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + return privilegedGetProfileFile(fileName); } }); } /* - * this version is called from doPrivileged in privilegedOpenProfile. - * the whole method is privileged! + * this version is called from doPrivileged in openProfile + * or getProfileFile, so the whole method is privileged! */ - private static FileInputStream privilegedOpenProfile(String fileName) { - FileInputStream fis = null; + + private static File privilegedGetProfileFile(String fileName) { String path, dir, fullPath; File f = new File(fileName); /* try absolute file name */ @@ -1830,12 +1851,9 @@ } if (f.isFile()) { - try { - fis = new FileInputStream(f); - } catch (FileNotFoundException e) { - } + return f; } - return fis; + return null; } diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/javax/imageio/ImageIO.java --- a/jdk/src/share/classes/javax/imageio/ImageIO.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/javax/imageio/ImageIO.java Mon Jun 29 14:42:22 2009 -0700 @@ -28,6 +28,7 @@ import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; +import java.io.FilePermission; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; @@ -195,13 +196,22 @@ } else { cachepath = getTempDir(); - if (cachepath == null) { + if (cachepath == null || cachepath.isEmpty()) { getCacheInfo().setHasPermission(Boolean.FALSE); return false; } } - security.checkWrite(cachepath); + // we have to check whether we can read, write, + // and delete cache files. + // So, compose cache file path and check it. + String filepath = cachepath; + if (!filepath.endsWith(File.separator)) { + filepath += File.separator; + } + filepath += "*"; + + security.checkPermission(new FilePermission(filepath, "read, write, delete")); } } catch (SecurityException e) { getCacheInfo().setHasPermission(Boolean.FALSE); diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/classes/sun/font/TrueTypeFont.java --- a/jdk/src/share/classes/sun/font/TrueTypeFont.java Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/classes/sun/font/TrueTypeFont.java Mon Jun 29 14:42:22 2009 -0700 @@ -160,6 +160,13 @@ private boolean supportsJA; private boolean supportsCJK; + /* These are for faster access to the name of the font as + * typically exposed via API to applications. + */ + private Locale nameLocale; + private String localeFamilyName; + private String localeFullName; + /** * - does basic verification of the file * - reads the header table for this font (within a collection) @@ -1092,6 +1099,10 @@ * greater than 32767, so read and store those as ints */ int stringPtr = sbuffer.get() & 0xffff; + + nameLocale = sun.awt.SunToolkit.getStartupLocale(); + short nameLocaleID = FontManager.getLCIDFromLocale(nameLocale); + for (int i=0; i x0) bboxX0 = x0; - if (bboxX1 < x1) bboxX1 = x1; + if (bboxX1 < x1 + 1) bboxX1 = x1 + 1; while (bboxY1++ < y) { reallocRowInfo(alphaRows+1); minTouched[alphaRows] = 0; diff -r f1c6e189f315 -r c8270bf40b76 jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c --- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Thu Jun 25 12:10:01 2009 -0700 +++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Mon Jun 29 14:42:22 2009 -0700 @@ -1783,7 +1783,7 @@ struct jpeg_source_mgr *src; - JSAMPROW scanLinePtr; + JSAMPROW scanLinePtr = NULL; jint bands[MAX_BANDS]; int i, j; jint *body; @@ -1819,7 +1819,7 @@ cinfo = (j_decompress_ptr) data->jpegObj; - if ((numBands < 1) || (numBands > cinfo->num_components) || + if ((numBands < 1) || (sourceXStart < 0) || (sourceXStart >= (jint)cinfo->image_width) || (sourceYStart < 0) || (sourceYStart >= (jint)cinfo->image_height) || (sourceWidth < 1) || (sourceWidth > (jint)cinfo->image_width) || @@ -1877,16 +1877,6 @@ return data->abortFlag; // We already threw an out of memory exception } - // Allocate a 1-scanline buffer - scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->num_components); - if (scanLinePtr == NULL) { - RELEASE_ARRAYS(env, data, src->next_input_byte); - JNU_ThrowByName( env, - "java/lang/OutOfMemoryError", - "Reading JPEG Stream"); - return data->abortFlag; - } - /* Establish the setjmp return context for sun_jpeg_error_exit to use. */ jerr = (sun_jpeg_error_ptr) cinfo->err; @@ -1900,7 +1890,10 @@ buffer); JNU_ThrowByName(env, "javax/imageio/IIOException", buffer); } - free(scanLinePtr); + if (scanLinePtr != NULL) { + free(scanLinePtr); + scanLinePtr = NULL; + } return data->abortFlag; } @@ -1938,6 +1931,23 @@ jpeg_start_decompress(cinfo); + if (numBands != cinfo->output_components) { + JNU_ThrowByName(env, "javax/imageio/IIOException", + "Invalid argument to native readImage"); + return data->abortFlag; + } + + + // Allocate a 1-scanline buffer + scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->output_components); + if (scanLinePtr == NULL) { + RELEASE_ARRAYS(env, data, src->next_input_byte); + JNU_ThrowByName( env, + "java/lang/OutOfMemoryError", + "Reading JPEG Stream"); + return data->abortFlag; + } + // loop over progressive passes done = FALSE; while (!done) { @@ -1965,9 +1975,9 @@ scanlineLimit = sourceYStart+sourceHeight; pixelLimit = scanLinePtr - +(sourceXStart+sourceWidth)*cinfo->num_components; - - pixelStride = stepX*cinfo->num_components; + +(sourceXStart+sourceWidth)*cinfo->output_components; + + pixelStride = stepX*cinfo->output_components; targetLine = 0; while ((data->abortFlag == JNI_FALSE) @@ -1982,12 +1992,12 @@ // Optimization: The component bands are ordered sequentially, // so we can simply use memcpy() to copy the intermediate // scanline buffer into the raster. - in = scanLinePtr + (sourceXStart * cinfo->num_components); + in = scanLinePtr + (sourceXStart * cinfo->output_components); if (pixelLimit > in) { memcpy(out, in, pixelLimit - in); } } else { - for (in = scanLinePtr+sourceXStart*cinfo->num_components; + for (in = scanLinePtr+sourceXStart*cinfo->output_components; in < pixelLimit; in += pixelStride) { for (i = 0; i < numBands; i++) { diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/javax/imageio/CachePremissionsTest/CachePermissionsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/CachePremissionsTest/CachePermissionsTest.java Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,120 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6684104 + * @summary Test verifies that ImageIO checks all permissions required for + * the file cache usage: + * + * no policy file: No security restrictions. + * Expected result: ImageIO creates file-cached stream. + * + * w.policy: the case when we have read and write permissions + * for java.io.temp directory but have only write permission + * for a temp file. + * Expected result: ImageIO create a memory-cached stream + * image output stream. + * + * rw.policy: the case when we have read and write permissions + * for java.io.temp directory but have only read and write + * permission for a temp cache file. + * Expected result: ImageIO creates a memory-cached stream + * because temporary cache file can not be deleted. + * + * rwd.policy: the case when we have read and write permissions + * for java.io.temp directory and have all required permissions + * (read, write, and delete) for a temporary cache file. + * Expected result: ImageIO creates file-cached stream. + * + * -Djava.security.debug=access can be used to verify file permissions. + * + * @run main CachePermissionsTest true + * @run main/othervm/policy=w.policy CachePermissionsTest false + * @run main/othervm/policy=rw.policy CachePermissionsTest false + * @run main/othervm/policy=rwd.policy CachePermissionsTest true + */ + +import java.io.File; +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import javax.imageio.stream.ImageOutputStream; + +import javax.imageio.ImageIO; + + +public class CachePermissionsTest { + public static void main(String[] args) { + boolean isFileCacheExpected = + Boolean.valueOf(args[0]).booleanValue(); + System.out.println("Is file cache expected: " + isFileCacheExpected); + + ImageIO.setUseCache(true); + + System.out.println("java.io.tmpdir is " + System.getProperty("java.io.tmpdir")); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try { + ImageOutputStream ios = ImageIO.createImageOutputStream(baos); + + boolean isFileCache = ios.isCachedFile(); + System.out.println("Is file cache used: " + isFileCache); + + if (isFileCache !=isFileCacheExpected) { + System.out.println("WARNING: file chace usage is not as expected!"); + } + + System.out.println("Verify data writing..."); + for (int i = 0; i < 8192; i++) { + ios.writeInt(i); + } + + System.out.println("Verify data reading..."); + ios.seek(0L); + + for (int i = 0; i < 8192; i++) { + int j = ios.readInt(); + if (i != j) { + throw new RuntimeException("Wrong data in the stream " + j + " instead of " + i); + } + } + + System.out.println("Verify stream closing..."); + ios.close(); + } catch (IOException e) { + /* + * Something went wrong? + */ + throw new RuntimeException("Test FAILED.", e); + } catch (SecurityException e) { + /* + * We do not expect security execptions here: + * we there are any security restrition, ImageIO + * should swith to memory-cached streams, instead + * of using file cache. + */ + throw new RuntimeException("Test FAILED.", e); + } + } +} diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/javax/imageio/CachePremissionsTest/rw.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/CachePremissionsTest/rw.policy Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,5 @@ +grant { + permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "java.io.tmpdir", "read"; + permission java.io.FilePermission "${java.io.tmpdir}${/}*", "read, write"; +}; diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/javax/imageio/CachePremissionsTest/rwd.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/CachePremissionsTest/rwd.policy Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,5 @@ +grant { + permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "java.io.tmpdir", "read"; + permission java.io.FilePermission "${java.io.tmpdir}${/}*", "read, write, delete"; +}; diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/javax/imageio/CachePremissionsTest/w.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/CachePremissionsTest/w.policy Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,5 @@ +grant { + permission java.util.PropertyPermission "test.classes", "read"; + permission java.util.PropertyPermission "java.io.tmpdir", "read"; + permission java.io.FilePermission "${java.io.tmpdir}${/}*", "write"; +}; diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/javax/imageio/plugins/bmp/TopDownTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/bmp/TopDownTest.java Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,142 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6296893 + * @summary Test verifies that the isTopDown flag does not cause + * a writing of bmp image in wrong scanline layout. + * @run main TopDownTest + */ + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.image.BufferedImage; + +import java.awt.image.IndexColorModel; +import java.io.File; +import java.io.IOException; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.plugins.bmp.BMPImageWriteParam; +import javax.imageio.stream.ImageOutputStream; +import static java.awt.image.BufferedImage.TYPE_INT_RGB; +import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED; + +public class TopDownTest { + + public static void main(String[] args) throws IOException { + BufferedImage src = createTestImage(24); + + writeWithCompression(src, "BI_BITFIELDS"); + + writeWithCompression(src, "BI_RGB"); + + src = createTestImage(8); + writeWithCompression(src, "BI_RLE8"); + + src = createTestImage(4); + writeWithCompression(src, "BI_RLE4"); + + } + + private static void writeWithCompression(BufferedImage src, + String compression) throws IOException + { + System.out.println("Compression: " + compression); + ImageWriter writer = ImageIO.getImageWritersByFormatName("BMP").next(); + if (writer == null) { + throw new RuntimeException("Test failed: no bmp writer available"); + } + File fout = File.createTempFile(compression + "_", ".bmp", + new File(".")); + + ImageOutputStream ios = ImageIO.createImageOutputStream(fout); + writer.setOutput(ios); + + BMPImageWriteParam param = (BMPImageWriteParam) + writer.getDefaultWriteParam(); + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionType(compression); + param.setTopDown(true); + writer.write(null, new IIOImage(src, null, null), param); + writer.dispose(); + ios.flush(); + ios.close(); + + BufferedImage dst = ImageIO.read(fout); + + verify(dst); + } + + private static void verify(BufferedImage dst) { + int top_rgb = dst.getRGB(50, 25); + System.out.printf("top_rgb: %x\n", top_rgb); + int bot_rgb = dst.getRGB(50, 75); + System.out.printf("bot_rgb: %x\n", bot_rgb); + + // expect to see blue color on the top of image + if (top_rgb != 0xff0000ff) { + throw new RuntimeException("Invaid top color: " + + Integer.toHexString(bot_rgb)); + } + if (bot_rgb != 0xffff0000) { + throw new RuntimeException("Invalid bottom color: " + + Integer.toHexString(bot_rgb)); + } + } + + private static BufferedImage createTestImage(int bpp) { + + BufferedImage img = null; + switch (bpp) { + case 8: + img = new BufferedImage(100, 100, TYPE_BYTE_INDEXED); + break; + case 4: { + byte[] r = new byte[16]; + byte[] g = new byte[16]; + byte[] b = new byte[16]; + + r[1] = (byte)0xff; + b[0] = (byte)0xff; + + IndexColorModel icm = new IndexColorModel(4, 16, r, g, b); + img = new BufferedImage(100, 100, TYPE_BYTE_INDEXED, icm); + } + break; + case 24: + default: + img = new BufferedImage(100, 100, TYPE_INT_RGB); + } + Graphics g = img.createGraphics(); + g.setColor(Color.blue); + g.fillRect(0, 0, 100, 50); + g.setColor(Color.red); + g.fillRect(0, 50, 100, 50); + g.dispose(); + return img; + } +} diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/javax/imageio/plugins/jpeg/ReadAsGrayTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/jpeg/ReadAsGrayTest.java Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,179 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 4893408 + * + * @summary Test verifies that Image I/O jpeg reader correctly handles + * destination types if number of color components in destination + * differs from number of color components in the jpeg image. + * Particularly, it verifies reading YCbCr image as a grayscaled + * and reading grayscaled jpeg as a RGB. + * + * @run main ReadAsGrayTest + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.stream.ImageInputStream; +import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR; +import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY; +import static java.awt.color.ColorSpace.TYPE_GRAY; +import static java.awt.color.ColorSpace.CS_sRGB; + +public class ReadAsGrayTest { + static Color[] colors = new Color[] { + Color.white, Color.red, Color.green, + Color.blue, Color.black }; + + static final int dx = 50; + static final int h = 100; + + static ColorSpace sRGB = ColorSpace.getInstance(CS_sRGB); + + + public static void main(String[] args) throws IOException { + System.out.println("Type TYPE_BYTE_GRAY"); + doTest(TYPE_BYTE_GRAY); + + System.out.println("Type TYPE_3BYTE_BGR"); + doTest(TYPE_3BYTE_BGR); + + System.out.println("Test PASSED."); + } + + private static void doTest(int type) throws IOException { + BufferedImage src = createTestImage(type); + + File f = new File("test.jpg"); + + if (!ImageIO.write(src, "jpg", f)) { + throw new RuntimeException("Failed to write test image."); + } + + ImageInputStream iis = ImageIO.createImageInputStream(f); + ImageReader reader = ImageIO.getImageReaders(iis).next(); + reader.setInput(iis); + + Iterator types = reader.getImageTypes(0); + ImageTypeSpecifier srgb = null; + ImageTypeSpecifier gray = null; + // look for gray and srgb types + while ((srgb == null || gray == null) && types.hasNext()) { + ImageTypeSpecifier t = types.next(); + if (t.getColorModel().getColorSpace().getType() == TYPE_GRAY) { + gray = t; + } + if (t.getColorModel().getColorSpace() == sRGB) { + srgb = t; + } + } + if (gray == null) { + throw new RuntimeException("No gray type available."); + } + if (srgb == null) { + throw new RuntimeException("No srgb type available."); + } + + System.out.println("Read as GRAY..."); + testType(reader, gray, src); + + System.out.println("Read as sRGB..."); + testType(reader, srgb, src); + } + + private static void testType(ImageReader reader, + ImageTypeSpecifier t, + BufferedImage src) + throws IOException + { + ImageReadParam p = reader.getDefaultReadParam(); + p.setDestinationType(t); + BufferedImage dst = reader.read(0, p); + + verify(src, dst, t); + } + + private static void verify(BufferedImage src, + BufferedImage dst, + ImageTypeSpecifier type) + { + BufferedImage test = + type.createBufferedImage(src.getWidth(), src.getHeight()); + Graphics2D g = test.createGraphics(); + g.drawImage(src, 0, 0, null); + g.dispose(); + + for (int i = 0; i < colors.length; i++) { + int x = i * dx + dx / 2; + int y = h / 2; + + Color c_test = new Color(test.getRGB(x, y)); + Color c_dst = new Color(dst.getRGB(x, y)); + + if (!compareWithTolerance(c_test, c_dst, 0.01f)) { + String msg = String.format("Invalid color: %x instead of %x", + c_dst.getRGB(), c_test.getRGB()); + throw new RuntimeException("Test failed: " + msg); + } + } + System.out.println("Verified."); + } + + private static boolean compareWithTolerance(Color a, Color b, float delta) { + float[] a_rgb = new float[3]; + a_rgb = a.getRGBColorComponents(a_rgb); + float[] b_rgb = new float[3]; + b_rgb = b.getRGBColorComponents(b_rgb); + + for (int i = 0; i < 3; i++) { + if (Math.abs(a_rgb[i] - b_rgb[i]) > delta) { + return false; + } + } + return true; + } + + private static BufferedImage createTestImage(int type) { + BufferedImage img = new BufferedImage(dx * colors.length, h, type); + + Graphics2D g = img.createGraphics(); + for (int i = 0; i < colors.length; i++) { + g.setColor(colors[i]); + g.fillRect(i * dx, 0, dx, h); + } + g.dispose(); + + return img; + } +} diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/javax/imageio/plugins/wbmp/CanDecodeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/wbmp/CanDecodeTest.java Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,131 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 5101862 + * @summary Test verifies that SPI of WBMP image reader + * does not claims to be able to decode QT movies, + * tga images, or ico files. + * @run main CanDecodeTest + */ + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Vector; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; + +public class CanDecodeTest { + + public static void main(String[] args) throws IOException { + ImageReader r = + ImageIO.getImageReadersByFormatName("WBMP").next(); + ImageReaderSpi spi = r.getOriginatingProvider(); + + Vector tests = getTestCases(); + for (TestCase t : tests) { + t.doTest(spi); + } + System.out.println("Test passed."); + } + + private static Vector getTestCases() { + Vector v = new Vector(4); + v.add(new TestCase("wbmp", new byte[]{(byte) 0x00, (byte) 0x00, + (byte) 0x60, (byte) 0x14}, 244, true)); + v.add(new TestCase("mov", new byte[]{(byte) 0x00, (byte) 0x00, + (byte) 0x07, (byte) 0xb5, (byte) 0x6d}, 82397, false)); + v.add(new TestCase("tga", new byte[]{(byte) 0x00, (byte) 0x00, + (byte) 0x0a, (byte) 0x00}, 39693, false)); + v.add(new TestCase("ico", new byte[]{(byte) 0x00, (byte) 0x00, + (byte) 0x01, (byte) 0x00}, 1078, false)); + return v; + } + + private static class TestCase { + + private String title; + private byte[] header; + private int dataLength; + private boolean canDecode; + + public TestCase(String title, byte[] header, + int dataLength, boolean canDecode) { + this.title = title; + this.dataLength = dataLength; + this.header = header.clone(); + this.canDecode = canDecode; + + } + + public void doTest(ImageReaderSpi spi) throws IOException { + System.out.println("Test for " + title + + (canDecode ? " (can decode)" : " (can't decode)")); + System.out.print("As a stream..."); + ImageInputStream iis = + ImageIO.createImageInputStream(getDataStream()); + + if (spi.canDecodeInput(iis) != canDecode) { + throw new RuntimeException("Test failed: wrong decideion " + + "for stream data"); + } + System.out.println("OK"); + + System.out.print("As a file..."); + iis = ImageIO.createImageInputStream(getDataFile()); + if (spi.canDecodeInput(iis) != canDecode) { + throw new RuntimeException("Test failed: wrong decideion " + + "for file data"); + } + System.out.println("OK"); + } + + private byte[] getData() { + byte[] data = new byte[dataLength]; + Arrays.fill(data, (byte) 0); + System.arraycopy(header, 0, data, 0, header.length); + + return data; + } + public InputStream getDataStream() { + return new ByteArrayInputStream(getData()); + } + + public File getDataFile() throws IOException { + File f = File.createTempFile("wbmp_", "." + title, new File(".")); + FileOutputStream fos = new FileOutputStream(f); + fos.write(getData()); + fos.flush(); + fos.close(); + + return f; + } + } +} diff -r f1c6e189f315 -r c8270bf40b76 jdk/test/sun/pisces/ScaleTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/pisces/ScaleTest.java Mon Jun 29 14:42:22 2009 -0700 @@ -0,0 +1,58 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.awt.*; +import java.awt.geom.Ellipse2D; +import java.awt.image.BufferedImage; +import java.io.File; +import javax.imageio.ImageIO; + + +public class ScaleTest { + public static void main(String[] args) throws Exception { + BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); + Graphics2D g = image.createGraphics(); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setPaint(Color.WHITE); + g.fill(new Rectangle(image.getWidth(), image.getHeight())); + g.scale(.9, .9); + g.setPaint(Color.BLACK); + g.setStroke(new BasicStroke(0.5f)); + g.draw(new Ellipse2D.Double(25, 25, 150, 150)); + + // To visually check it + //ImageIO.write(image, "PNG", new File(args[0])); + + boolean nonWhitePixelFound = false; + for (int x = 100; x < 200; ++x) { + if (image.getRGB(x, 90) != Color.WHITE.getRGB()) { + nonWhitePixelFound = true; + break; + } + } + if (!nonWhitePixelFound) { + throw new RuntimeException("A circle is rendered like a 'C' shape."); + } + } +}