feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
public class BMPCompressionTypes {
|
||||
|
||||
private static final String[] compressionTypeNames =
|
||||
{"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"};
|
||||
|
||||
static int getType(String typeString) {
|
||||
for (int i = 0; i < compressionTypeNames.length; i++)
|
||||
if (compressionTypeNames[i].equals(typeString))
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static String getName(int type) {
|
||||
return compressionTypeNames[type];
|
||||
}
|
||||
|
||||
public static String[] getCompressionTypes() {
|
||||
return compressionTypeNames.clone();
|
||||
}
|
||||
}
|
||||
50
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPConstants.java
Normal file
50
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPConstants.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
public interface BMPConstants {
|
||||
// bmp versions
|
||||
static final String VERSION_2 = "BMP v. 2.x";
|
||||
static final String VERSION_3 = "BMP v. 3.x";
|
||||
static final String VERSION_3_NT = "BMP v. 3.x NT";
|
||||
static final String VERSION_4 = "BMP v. 4.x";
|
||||
static final String VERSION_5 = "BMP v. 5.x";
|
||||
|
||||
// Color space types
|
||||
static final int LCS_CALIBRATED_RGB = 0;
|
||||
static final int LCS_sRGB = 1;
|
||||
static final int LCS_WINDOWS_COLOR_SPACE = 2;
|
||||
static final int PROFILE_LINKED = 3;
|
||||
static final int PROFILE_EMBEDDED = 4;
|
||||
|
||||
// Compression Types
|
||||
static final int BI_RGB = 0;
|
||||
static final int BI_RLE8 = 1;
|
||||
static final int BI_RLE4 = 2;
|
||||
static final int BI_BITFIELDS = 3;
|
||||
static final int BI_JPEG = 4;
|
||||
static final int BI_PNG = 5;
|
||||
}
|
||||
1837
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPImageReader.java
Normal file
1837
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPImageReader.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
public class BMPImageReaderSpi extends ImageReaderSpi {
|
||||
|
||||
private static String [] writerSpiNames =
|
||||
{"com.sun.imageio.plugins.bmp.BMPImageWriterSpi"};
|
||||
private static String[] formatNames = {"bmp", "BMP"};
|
||||
private static String[] entensions = {"bmp"};
|
||||
private static String[] mimeType = {"image/bmp"};
|
||||
|
||||
private boolean registered = false;
|
||||
|
||||
public BMPImageReaderSpi() {
|
||||
super("Oracle Corporation",
|
||||
"1.0",
|
||||
formatNames,
|
||||
entensions,
|
||||
mimeType,
|
||||
"com.sun.imageio.plugins.bmp.BMPImageReader",
|
||||
new Class[] { ImageInputStream.class },
|
||||
writerSpiNames,
|
||||
false,
|
||||
null, null, null, null,
|
||||
true,
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.bmp.BMPMetadataFormat",
|
||||
null, null);
|
||||
}
|
||||
|
||||
public void onRegistration(ServiceRegistry registry,
|
||||
Class<?> category) {
|
||||
if (registered) {
|
||||
return;
|
||||
}
|
||||
registered = true;
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard BMP Image Reader";
|
||||
}
|
||||
|
||||
public boolean canDecodeInput(Object source) throws IOException {
|
||||
if (!(source instanceof ImageInputStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageInputStream stream = (ImageInputStream)source;
|
||||
byte[] b = new byte[2];
|
||||
stream.mark();
|
||||
stream.readFully(b);
|
||||
stream.reset();
|
||||
|
||||
return (b[0] == 0x42) && (b[1] == 0x4d);
|
||||
}
|
||||
|
||||
public ImageReader createReaderInstance(Object extension)
|
||||
throws IIOException {
|
||||
return new BMPImageReader(this);
|
||||
}
|
||||
}
|
||||
1517
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPImageWriter.java
Normal file
1517
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPImageWriter.java
Normal file
File diff suppressed because it is too large
Load Diff
106
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java
Normal file
106
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.SinglePixelPackedSampleModel;
|
||||
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.IIOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.imageio.plugins.bmp.BMPImageWriteParam;
|
||||
|
||||
public class BMPImageWriterSpi extends ImageWriterSpi {
|
||||
private static String [] readerSpiNames =
|
||||
{"com.sun.imageio.plugins.bmp.BMPImageReaderSpi"};
|
||||
private static String[] formatNames = {"bmp", "BMP"};
|
||||
private static String[] entensions = {"bmp"};
|
||||
private static String[] mimeType = {"image/bmp"};
|
||||
|
||||
private boolean registered = false;
|
||||
|
||||
public BMPImageWriterSpi() {
|
||||
super("Oracle Corporation",
|
||||
"1.0",
|
||||
formatNames,
|
||||
entensions,
|
||||
mimeType,
|
||||
"com.sun.imageio.plugins.bmp.BMPImageWriter",
|
||||
new Class[] { ImageOutputStream.class },
|
||||
readerSpiNames,
|
||||
false,
|
||||
null, null, null, null,
|
||||
true,
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.bmp.BMPMetadataFormat",
|
||||
null, null);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard BMP Image Writer";
|
||||
}
|
||||
|
||||
public void onRegistration(ServiceRegistry registry,
|
||||
Class<?> category) {
|
||||
if (registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
registered = true;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(ImageTypeSpecifier type) {
|
||||
int dataType= type.getSampleModel().getDataType();
|
||||
if (dataType < DataBuffer.TYPE_BYTE || dataType > DataBuffer.TYPE_INT)
|
||||
return false;
|
||||
|
||||
SampleModel sm = type.getSampleModel();
|
||||
int numBands = sm.getNumBands();
|
||||
if (!(numBands == 1 || numBands == 3))
|
||||
return false;
|
||||
|
||||
if (numBands == 1 && dataType != DataBuffer.TYPE_BYTE)
|
||||
return false;
|
||||
|
||||
if (dataType > DataBuffer.TYPE_BYTE &&
|
||||
!(sm instanceof SinglePixelPackedSampleModel))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ImageWriter createWriterInstance(Object extension)
|
||||
throws IIOException {
|
||||
return new BMPImageWriter(this);
|
||||
}
|
||||
}
|
||||
307
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPMetadata.java
Normal file
307
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPMetadata.java
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
import com.sun.imageio.plugins.common.I18N;
|
||||
|
||||
import com.sun.imageio.plugins.common.ImageUtil;
|
||||
|
||||
public class BMPMetadata extends IIOMetadata implements BMPConstants {
|
||||
public static final String nativeMetadataFormatName =
|
||||
"javax_imageio_bmp_1.0";
|
||||
|
||||
// Fields for Image Descriptor
|
||||
public String bmpVersion;
|
||||
public int width ;
|
||||
public int height;
|
||||
public short bitsPerPixel;
|
||||
public int compression;
|
||||
public int imageSize;
|
||||
|
||||
// Fields for PixelsPerMeter
|
||||
public int xPixelsPerMeter;
|
||||
public int yPixelsPerMeter;
|
||||
|
||||
public int colorsUsed;
|
||||
public int colorsImportant;
|
||||
|
||||
// Fields for BI_BITFIELDS compression(Mask)
|
||||
public int redMask;
|
||||
public int greenMask;
|
||||
public int blueMask;
|
||||
public int alphaMask;
|
||||
|
||||
public int colorSpace;
|
||||
|
||||
// Fields for CIE XYZ for the LCS_CALIBRATED_RGB color space
|
||||
public double redX;
|
||||
public double redY;
|
||||
public double redZ;
|
||||
public double greenX;
|
||||
public double greenY;
|
||||
public double greenZ;
|
||||
public double blueX;
|
||||
public double blueY;
|
||||
public double blueZ;
|
||||
|
||||
// Fields for Gamma values for the LCS_CALIBRATED_RGB color space
|
||||
public int gammaRed;
|
||||
public int gammaGreen;
|
||||
public int gammaBlue;
|
||||
|
||||
public int intent;
|
||||
|
||||
// Fields for the Palette and Entries
|
||||
public byte[] palette = null;
|
||||
public int paletteSize;
|
||||
public int red;
|
||||
public int green;
|
||||
public int blue;
|
||||
|
||||
// Fields from CommentExtension
|
||||
// List of byte[]
|
||||
public List comments = null; // new ArrayList();
|
||||
|
||||
public BMPMetadata() {
|
||||
super(true,
|
||||
nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.bmp.BMPMetadataFormat",
|
||||
null, null);
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Node getAsTree(String formatName) {
|
||||
if (formatName.equals(nativeMetadataFormatName)) {
|
||||
return getNativeTree();
|
||||
} else if (formatName.equals
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
return getStandardTree();
|
||||
} else {
|
||||
throw new IllegalArgumentException(I18N.getString("BMPMetadata0"));
|
||||
}
|
||||
}
|
||||
|
||||
private String toISO8859(byte[] data) {
|
||||
try {
|
||||
return new String(data, "ISO-8859-1");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private Node getNativeTree() {
|
||||
IIOMetadataNode root =
|
||||
new IIOMetadataNode(nativeMetadataFormatName);
|
||||
|
||||
addChildNode(root, "BMPVersion", bmpVersion);
|
||||
addChildNode(root, "Width", new Integer(width));
|
||||
addChildNode(root, "Height", new Integer(height));
|
||||
addChildNode(root, "BitsPerPixel", new Short(bitsPerPixel));
|
||||
addChildNode(root, "Compression", new Integer(compression));
|
||||
addChildNode(root, "ImageSize", new Integer(imageSize));
|
||||
|
||||
IIOMetadataNode node = addChildNode(root, "PixelsPerMeter", null);
|
||||
addChildNode(node, "X", new Integer(xPixelsPerMeter));
|
||||
addChildNode(node, "Y", new Integer(yPixelsPerMeter));
|
||||
|
||||
addChildNode(root, "ColorsUsed", new Integer(colorsUsed));
|
||||
addChildNode(root, "ColorsImportant", new Integer(colorsImportant));
|
||||
|
||||
int version = 0;
|
||||
for (int i = 0; i < bmpVersion.length(); i++)
|
||||
if (Character.isDigit(bmpVersion.charAt(i)))
|
||||
version = bmpVersion.charAt(i) -'0';
|
||||
|
||||
if (version >= 4) {
|
||||
node = addChildNode(root, "Mask", null);
|
||||
addChildNode(node, "Red", new Integer(redMask));
|
||||
addChildNode(node, "Green", new Integer(greenMask));
|
||||
addChildNode(node, "Blue", new Integer(blueMask));
|
||||
addChildNode(node, "Alpha", new Integer(alphaMask));
|
||||
|
||||
addChildNode(root, "ColorSpaceType", new Integer(colorSpace));
|
||||
|
||||
node = addChildNode(root, "CIEXYZEndPoints", null);
|
||||
addXYZPoints(node, "Red", redX, redY, redZ);
|
||||
addXYZPoints(node, "Green", greenX, greenY, greenZ);
|
||||
addXYZPoints(node, "Blue", blueX, blueY, blueZ);
|
||||
|
||||
node = addChildNode(root, "Intent", new Integer(intent));
|
||||
}
|
||||
|
||||
// Palette
|
||||
if ((palette != null) && (paletteSize > 0)) {
|
||||
node = addChildNode(root, "Palette", null);
|
||||
int numComps = palette.length / paletteSize;
|
||||
|
||||
for (int i = 0, j = 0; i < paletteSize; i++) {
|
||||
IIOMetadataNode entry =
|
||||
addChildNode(node, "PaletteEntry", null);
|
||||
red = palette[j++] & 0xff;
|
||||
green = palette[j++] & 0xff;
|
||||
blue = palette[j++] & 0xff;
|
||||
addChildNode(entry, "Red", new Byte((byte)red));
|
||||
addChildNode(entry, "Green", new Byte((byte)green));
|
||||
addChildNode(entry, "Blue", new Byte((byte)blue));
|
||||
if (numComps == 4)
|
||||
addChildNode(entry, "Alpha",
|
||||
new Byte((byte)(palette[j++] & 0xff)));
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
// Standard tree node methods
|
||||
protected IIOMetadataNode getStandardChromaNode() {
|
||||
|
||||
if ((palette != null) && (paletteSize > 0)) {
|
||||
IIOMetadataNode node = new IIOMetadataNode("Chroma");
|
||||
IIOMetadataNode subNode = new IIOMetadataNode("Palette");
|
||||
int numComps = palette.length / paletteSize;
|
||||
subNode.setAttribute("value", "" + numComps);
|
||||
|
||||
for (int i = 0, j = 0; i < paletteSize; i++) {
|
||||
IIOMetadataNode subNode1 = new IIOMetadataNode("PaletteEntry");
|
||||
subNode1.setAttribute("index", ""+i);
|
||||
subNode1.setAttribute("red", "" + palette[j++]);
|
||||
subNode1.setAttribute("green", "" + palette[j++]);
|
||||
subNode1.setAttribute("blue", "" + palette[j++]);
|
||||
if (numComps == 4 && palette[j] != 0)
|
||||
subNode1.setAttribute("alpha", "" + palette[j++]);
|
||||
subNode.appendChild(subNode1);
|
||||
}
|
||||
node.appendChild(subNode);
|
||||
return node;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected IIOMetadataNode getStandardCompressionNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("Compression");
|
||||
|
||||
// CompressionTypeName
|
||||
IIOMetadataNode subNode = new IIOMetadataNode("CompressionTypeName");
|
||||
subNode.setAttribute("value", BMPCompressionTypes.getName(compression));
|
||||
node.appendChild(subNode);
|
||||
return node;
|
||||
}
|
||||
|
||||
protected IIOMetadataNode getStandardDataNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("Data");
|
||||
|
||||
String bits = "";
|
||||
if (bitsPerPixel == 24)
|
||||
bits = "8 8 8 ";
|
||||
else if (bitsPerPixel == 16 || bitsPerPixel == 32) {
|
||||
bits = "" + countBits(redMask) + " " + countBits(greenMask) +
|
||||
countBits(blueMask) + "" + countBits(alphaMask);
|
||||
}
|
||||
|
||||
IIOMetadataNode subNode = new IIOMetadataNode("BitsPerSample");
|
||||
subNode.setAttribute("value", bits);
|
||||
node.appendChild(subNode);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
protected IIOMetadataNode getStandardDimensionNode() {
|
||||
if (yPixelsPerMeter > 0.0F && xPixelsPerMeter > 0.0F) {
|
||||
IIOMetadataNode node = new IIOMetadataNode("Dimension");
|
||||
float ratio = yPixelsPerMeter / xPixelsPerMeter;
|
||||
IIOMetadataNode subNode = new IIOMetadataNode("PixelAspectRatio");
|
||||
subNode.setAttribute("value", "" + ratio);
|
||||
node.appendChild(subNode);
|
||||
|
||||
subNode = new IIOMetadataNode("HorizontalPhysicalPixelSpacing");
|
||||
subNode.setAttribute("value", "" + (1 / xPixelsPerMeter * 1000));
|
||||
node.appendChild(subNode);
|
||||
|
||||
subNode = new IIOMetadataNode("VerticalPhysicalPixelSpacing");
|
||||
subNode.setAttribute("value", "" + (1 / yPixelsPerMeter * 1000));
|
||||
node.appendChild(subNode);
|
||||
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setFromTree(String formatName, Node root) {
|
||||
throw new IllegalStateException(I18N.getString("BMPMetadata1"));
|
||||
}
|
||||
|
||||
public void mergeTree(String formatName, Node root) {
|
||||
throw new IllegalStateException(I18N.getString("BMPMetadata1"));
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
throw new IllegalStateException(I18N.getString("BMPMetadata1"));
|
||||
}
|
||||
|
||||
private String countBits(int num) {
|
||||
int count = 0;
|
||||
while(num > 0) {
|
||||
if ((num & 1) == 1)
|
||||
count++;
|
||||
num >>>= 1;
|
||||
}
|
||||
|
||||
return count == 0 ? "" : "" + count;
|
||||
}
|
||||
|
||||
private void addXYZPoints(IIOMetadataNode root, String name, double x, double y, double z) {
|
||||
IIOMetadataNode node = addChildNode(root, name, null);
|
||||
addChildNode(node, "X", new Double(x));
|
||||
addChildNode(node, "Y", new Double(y));
|
||||
addChildNode(node, "Z", new Double(z));
|
||||
}
|
||||
|
||||
private IIOMetadataNode addChildNode(IIOMetadataNode root,
|
||||
String name,
|
||||
Object object) {
|
||||
IIOMetadataNode child = new IIOMetadataNode(name);
|
||||
if (object != null) {
|
||||
child.setUserObject(object);
|
||||
child.setNodeValue(ImageUtil.convertObjectToString(object));
|
||||
}
|
||||
root.appendChild(child);
|
||||
return child;
|
||||
}
|
||||
}
|
||||
208
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPMetadataFormat.java
Normal file
208
jdkSrc/jdk8/com/sun/imageio/plugins/bmp/BMPMetadataFormat.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class BMPMetadataFormat extends IIOMetadataFormatImpl {
|
||||
|
||||
private static IIOMetadataFormat instance = null;
|
||||
|
||||
private BMPMetadataFormat() {
|
||||
super(BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> ImageDescriptor
|
||||
addElement("ImageDescriptor",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ImageDescriptor", "bmpVersion",
|
||||
DATATYPE_STRING, true, null);
|
||||
addAttribute("ImageDescriptor", "width",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("ImageDescriptor", "height",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("ImageDescriptor", "bitsPerPixel",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("ImageDescriptor", "compression",
|
||||
DATATYPE_INTEGER, false, null);
|
||||
addAttribute("ImageDescriptor", "imageSize",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
|
||||
addElement("PixelsPerMeter",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("PixelsPerMeter", "X",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("PixelsPerMeter", "Y",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"1", "65535", true, true);
|
||||
|
||||
addElement("ColorsUsed",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ColorsUsed", "value",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
|
||||
addElement("ColorsImportant",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ColorsImportant", "value",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
|
||||
addElement("BI_BITFIELDS_Mask",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("BI_BITFIELDS_Mask", "red",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("BI_BITFIELDS_Mask", "green",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("BI_BITFIELDS_Mask", "blue",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
|
||||
addElement("ColorSpace",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ColorSpace", "value",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
|
||||
addElement("LCS_CALIBRATED_RGB",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
/// Should the max value be 1.7976931348623157e+308 ?
|
||||
addAttribute("LCS_CALIBRATED_RGB", "redX",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "redY",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "redZ",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "greenX",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "greenY",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "greenZ",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "blueX",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "blueY",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB", "blueZ",
|
||||
DATATYPE_DOUBLE, false, null,
|
||||
"0", "65535", true, true);
|
||||
|
||||
addElement("LCS_CALIBRATED_RGB_GAMMA",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("LCS_CALIBRATED_RGB_GAMMA","red",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB_GAMMA","green",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("LCS_CALIBRATED_RGB_GAMMA","blue",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
|
||||
addElement("Intent",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("Intent", "value",
|
||||
DATATYPE_INTEGER, false, null,
|
||||
"0", "65535", true, true);
|
||||
|
||||
// root -> Palette
|
||||
addElement("Palette",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
2, 256);
|
||||
addAttribute("Palette", "sizeOfPalette",
|
||||
DATATYPE_INTEGER, true, null);
|
||||
addBooleanAttribute("Palette", "sortFlag",
|
||||
false, false);
|
||||
|
||||
// root -> Palette -> PaletteEntry
|
||||
addElement("PaletteEntry", "Palette",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("PaletteEntry", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("PaletteEntry", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("PaletteEntry", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("PaletteEntry", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
|
||||
|
||||
// root -> CommentExtensions
|
||||
addElement("CommentExtensions",
|
||||
BMPMetadata.nativeMetadataFormatName,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> CommentExtensions -> CommentExtension
|
||||
addElement("CommentExtension", "CommentExtensions",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("CommentExtension", "value",
|
||||
DATATYPE_STRING, true, null);
|
||||
}
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static synchronized IIOMetadataFormat getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new BMPMetadataFormat();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.bmp;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class BMPMetadataFormatResources extends ListResourceBundle {
|
||||
|
||||
public BMPMetadataFormatResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
|
||||
// Node name, followed by description
|
||||
{ "BMPVersion", "BMP version string" },
|
||||
{ "Width", "The width of the image" },
|
||||
{ "Height","The height of the image" },
|
||||
{ "BitsPerPixel", "" },
|
||||
{ "PixelsPerMeter", "Resolution in pixels per unit distance" },
|
||||
{ "X", "Pixels Per Meter along X" },
|
||||
{ "Y", "Pixels Per Meter along Y" },
|
||||
{ "ColorsUsed",
|
||||
"Number of color indexes in the color table actually used" },
|
||||
{ "ColorsImportant",
|
||||
"Number of color indexes considered important for display" },
|
||||
{ "Mask",
|
||||
"Color masks; present for BI_BITFIELDS compression only"},
|
||||
|
||||
{ "Intent", "Rendering intent" },
|
||||
{ "Palette", "The color palette" },
|
||||
|
||||
{ "Red", "Red Mask/Color Palette" },
|
||||
{ "Green", "Green Mask/Color Palette/Gamma" },
|
||||
{ "Blue", "Blue Mask/Color Palette/Gamma" },
|
||||
{ "Alpha", "Alpha Mask/Color Palette/Gamma" },
|
||||
|
||||
{ "ColorSpaceType", "Color Space Type" },
|
||||
|
||||
{ "X", "The X coordinate of a point in XYZ color space" },
|
||||
{ "Y", "The Y coordinate of a point in XYZ color space" },
|
||||
{ "Z", "The Z coordinate of a point in XYZ color space" },
|
||||
};
|
||||
}
|
||||
}
|
||||
123
jdkSrc/jdk8/com/sun/imageio/plugins/common/BitFile.java
Normal file
123
jdkSrc/jdk8/com/sun/imageio/plugins/common/BitFile.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
/*
|
||||
* Came from GIFEncoder initially.
|
||||
* Modified - to allow for output compressed data without the block counts
|
||||
* which breakup the compressed data stream for GIF.
|
||||
*/
|
||||
public class BitFile {
|
||||
ImageOutputStream output;
|
||||
byte buffer[];
|
||||
int index;
|
||||
int bitsLeft; // bits left at current index that are avail.
|
||||
|
||||
/** note this also indicates gif format BITFile. **/
|
||||
boolean blocks = false;
|
||||
|
||||
/*
|
||||
* @param output destination for output data
|
||||
* @param blocks GIF LZW requires block counts for output data
|
||||
*/
|
||||
public BitFile(ImageOutputStream output, boolean blocks) {
|
||||
this.output = output;
|
||||
this.blocks = blocks;
|
||||
buffer = new byte[256];
|
||||
index = 0;
|
||||
bitsLeft = 8;
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
int numBytes = index + (bitsLeft == 8 ? 0 : 1);
|
||||
if (numBytes > 0) {
|
||||
if (blocks) {
|
||||
output.write(numBytes);
|
||||
}
|
||||
output.write(buffer, 0, numBytes);
|
||||
buffer[0] = 0;
|
||||
index = 0;
|
||||
bitsLeft = 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBits(int bits, int numbits) throws IOException {
|
||||
int bitsWritten = 0;
|
||||
int numBytes = 255; // gif block count
|
||||
do {
|
||||
// This handles the GIF block count stuff
|
||||
if ((index == 254 && bitsLeft == 0) || index > 254) {
|
||||
if (blocks) {
|
||||
output.write(numBytes);
|
||||
}
|
||||
|
||||
output.write(buffer, 0, numBytes);
|
||||
|
||||
buffer[0] = 0;
|
||||
index = 0;
|
||||
bitsLeft = 8;
|
||||
}
|
||||
|
||||
if (numbits <= bitsLeft) { // bits contents fit in current index byte
|
||||
if (blocks) { // GIF
|
||||
buffer[index] |= (bits & ((1 << numbits) - 1)) << (8 - bitsLeft);
|
||||
bitsWritten += numbits;
|
||||
bitsLeft -= numbits;
|
||||
numbits = 0;
|
||||
} else {
|
||||
buffer[index] |= (bits & ((1 << numbits) - 1)) << (bitsLeft - numbits);
|
||||
bitsWritten += numbits;
|
||||
bitsLeft -= numbits;
|
||||
numbits = 0;
|
||||
}
|
||||
} else { // bits overflow from current byte to next.
|
||||
if (blocks) { // GIF
|
||||
// if bits > space left in current byte then the lowest order bits
|
||||
// of code are taken and put in current byte and rest put in next.
|
||||
buffer[index] |= (bits & ((1 << bitsLeft) - 1)) << (8 - bitsLeft);
|
||||
bitsWritten += bitsLeft;
|
||||
bits >>= bitsLeft;
|
||||
numbits -= bitsLeft;
|
||||
buffer[++index] = 0;
|
||||
bitsLeft = 8;
|
||||
} else {
|
||||
// if bits > space left in current byte then the highest order bits
|
||||
// of code are taken and put in current byte and rest put in next.
|
||||
// at highest order bit location !!
|
||||
int topbits = (bits >>> (numbits - bitsLeft)) & ((1 << bitsLeft) - 1);
|
||||
buffer[index] |= topbits;
|
||||
numbits -= bitsLeft; // ok this many bits gone off the top
|
||||
bitsWritten += bitsLeft;
|
||||
buffer[++index] = 0; // next index
|
||||
bitsLeft = 8;
|
||||
}
|
||||
}
|
||||
} while (numbits != 0);
|
||||
}
|
||||
}
|
||||
136
jdkSrc/jdk8/com/sun/imageio/plugins/common/BogusColorSpace.java
Normal file
136
jdkSrc/jdk8/com/sun/imageio/plugins/common/BogusColorSpace.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
|
||||
/**
|
||||
* A dummy <code>ColorSpace</code> to enable <code>ColorModel</code>
|
||||
* for image data which do not have an innate color representation.
|
||||
*/
|
||||
public class BogusColorSpace extends ColorSpace {
|
||||
/**
|
||||
* Return the type given the number of components.
|
||||
*
|
||||
* @param numComponents The number of components in the
|
||||
* <code>ColorSpace</code>.
|
||||
* @exception IllegalArgumentException if <code>numComponents</code>
|
||||
* is less than 1.
|
||||
*/
|
||||
private static int getType(int numComponents) {
|
||||
if(numComponents < 1) {
|
||||
throw new IllegalArgumentException("numComponents < 1!");
|
||||
}
|
||||
|
||||
int type;
|
||||
switch(numComponents) {
|
||||
case 1:
|
||||
type = ColorSpace.TYPE_GRAY;
|
||||
break;
|
||||
default:
|
||||
// Based on the constant definitions TYPE_2CLR=12 through
|
||||
// TYPE_FCLR=25. This will return unknown types for
|
||||
// numComponents > 15.
|
||||
type = numComponents + 10;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a bogus <code>ColorSpace</code>.
|
||||
*
|
||||
* @param numComponents The number of components in the
|
||||
* <code>ColorSpace</code>.
|
||||
* @exception IllegalArgumentException if <code>numComponents</code>
|
||||
* is less than 1.
|
||||
*/
|
||||
public BogusColorSpace(int numComponents) {
|
||||
super(getType(numComponents), numComponents);
|
||||
}
|
||||
|
||||
//
|
||||
// The following methods simply copy the input array to the
|
||||
// output array while otherwise attempting to adhere to the
|
||||
// specified behavior of the methods vis-a-vis exceptions.
|
||||
//
|
||||
|
||||
public float[] toRGB(float[] colorvalue) {
|
||||
if(colorvalue.length < getNumComponents()) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("colorvalue.length < getNumComponents()");
|
||||
}
|
||||
|
||||
float[] rgbvalue = new float[3];
|
||||
|
||||
System.arraycopy(colorvalue, 0, rgbvalue, 0,
|
||||
Math.min(3, getNumComponents()));
|
||||
|
||||
return colorvalue;
|
||||
}
|
||||
|
||||
public float[] fromRGB(float[] rgbvalue) {
|
||||
if(rgbvalue.length < 3) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("rgbvalue.length < 3");
|
||||
}
|
||||
|
||||
float[] colorvalue = new float[getNumComponents()];
|
||||
|
||||
System.arraycopy(rgbvalue, 0, colorvalue, 0,
|
||||
Math.min(3, colorvalue.length));
|
||||
|
||||
return rgbvalue;
|
||||
}
|
||||
|
||||
public float[] toCIEXYZ(float[] colorvalue) {
|
||||
if(colorvalue.length < getNumComponents()) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("colorvalue.length < getNumComponents()");
|
||||
}
|
||||
|
||||
float[] xyzvalue = new float[3];
|
||||
|
||||
System.arraycopy(colorvalue, 0, xyzvalue, 0,
|
||||
Math.min(3, getNumComponents()));
|
||||
|
||||
return colorvalue;
|
||||
}
|
||||
|
||||
public float[] fromCIEXYZ(float[] xyzvalue) {
|
||||
if(xyzvalue.length < 3) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("xyzvalue.length < 3");
|
||||
}
|
||||
|
||||
float[] colorvalue = new float[getNumComponents()];
|
||||
|
||||
System.arraycopy(xyzvalue, 0, colorvalue, 0,
|
||||
Math.min(3, colorvalue.length));
|
||||
|
||||
return xyzvalue;
|
||||
}
|
||||
}
|
||||
33
jdkSrc/jdk8/com/sun/imageio/plugins/common/I18N.java
Normal file
33
jdkSrc/jdk8/com/sun/imageio/plugins/common/I18N.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
public final class I18N extends I18NImpl {
|
||||
private final static String resource_name = "iio-plugin.properties";
|
||||
public static String getString(String key) {
|
||||
return getString("com.sun.imageio.plugins.common.I18N", resource_name, key);
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/com/sun/imageio/plugins/common/I18NImpl.java
Normal file
62
jdkSrc/jdk8/com/sun/imageio/plugins/common/I18NImpl.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.PropertyResourceBundle;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Class to simplify use of internationalization message strings.
|
||||
* Property files are constructed in terms of content as for JAI with
|
||||
* one "key=value" pair per line. All such files however have the same
|
||||
* name "properties". The resource extractor resolves the extraction of
|
||||
* the file from the jar as the package name is included automatically.
|
||||
*
|
||||
* <p>Extenders need only provide a static method
|
||||
* <code>getString(String)</code> which calls the static method in this
|
||||
* class with the name of the invoking class and returns a
|
||||
* <code>String</code>.
|
||||
*/
|
||||
public class I18NImpl {
|
||||
/**
|
||||
* Returns the message string with the specified key from the
|
||||
* "properties" file in the package containing the class with
|
||||
* the specified name.
|
||||
*/
|
||||
protected static final String getString(String className, String resource_name, String key) {
|
||||
PropertyResourceBundle bundle = null;
|
||||
try {
|
||||
InputStream stream =
|
||||
Class.forName(className).getResourceAsStream(resource_name);
|
||||
bundle = new PropertyResourceBundle(stream);
|
||||
} catch(Throwable e) {
|
||||
throw new RuntimeException(e); // Chain the exception.
|
||||
}
|
||||
|
||||
return (String)bundle.handleGetObject(key);
|
||||
}
|
||||
}
|
||||
1167
jdkSrc/jdk8/com/sun/imageio/plugins/common/ImageUtil.java
Normal file
1167
jdkSrc/jdk8/com/sun/imageio/plugins/common/ImageUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
public class InputStreamAdapter extends InputStream {
|
||||
|
||||
ImageInputStream stream;
|
||||
|
||||
public InputStreamAdapter(ImageInputStream stream) {
|
||||
super();
|
||||
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return stream.read();
|
||||
}
|
||||
|
||||
public int read(byte b[], int off, int len) throws IOException {
|
||||
return stream.read(b, off, len);
|
||||
}
|
||||
}
|
||||
146
jdkSrc/jdk8/com/sun/imageio/plugins/common/LZWCompressor.java
Normal file
146
jdkSrc/jdk8/com/sun/imageio/plugins/common/LZWCompressor.java
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
/*
|
||||
* Modified from original LZWCompressor to change interface to passing a
|
||||
* buffer of data to be compressed.
|
||||
*/
|
||||
public class LZWCompressor {
|
||||
/** base underlying code size of data being compressed 8 for TIFF, 1 to 8 for GIF **/
|
||||
int codeSize;
|
||||
|
||||
/** reserved clear code based on code size **/
|
||||
int clearCode;
|
||||
|
||||
/** reserved end of data code based on code size **/
|
||||
int endOfInfo;
|
||||
|
||||
/** current number bits output for each code **/
|
||||
int numBits;
|
||||
|
||||
/** limit at which current number of bits code size has to be increased **/
|
||||
int limit;
|
||||
|
||||
/** the prefix code which represents the predecessor string to current input point **/
|
||||
short prefix;
|
||||
|
||||
/** output destination for bit codes **/
|
||||
BitFile bf;
|
||||
|
||||
/** general purpose LZW string table **/
|
||||
LZWStringTable lzss;
|
||||
|
||||
/** modify the limits of the code values in LZW encoding due to TIFF bug / feature **/
|
||||
boolean tiffFudge;
|
||||
|
||||
/**
|
||||
* @param out destination for compressed data
|
||||
* @param codeSize the initial code size for the LZW compressor
|
||||
* @param TIFF flag indicating that TIFF lzw fudge needs to be applied
|
||||
* @exception IOException if underlying output stream error
|
||||
**/
|
||||
public LZWCompressor(ImageOutputStream out, int codeSize, boolean TIFF)
|
||||
throws IOException
|
||||
{
|
||||
bf = new BitFile(out, !TIFF); // set flag for GIF as NOT tiff
|
||||
this.codeSize = codeSize;
|
||||
tiffFudge = TIFF;
|
||||
clearCode = 1 << codeSize;
|
||||
endOfInfo = clearCode + 1;
|
||||
numBits = codeSize + 1;
|
||||
|
||||
limit = (1 << numBits) - 1;
|
||||
if (tiffFudge) {
|
||||
--limit;
|
||||
}
|
||||
|
||||
prefix = (short)0xFFFF;
|
||||
lzss = new LZWStringTable();
|
||||
lzss.clearTable(codeSize);
|
||||
bf.writeBits(clearCode, numBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param buf data to be compressed to output stream
|
||||
* @exception IOException if underlying output stream error
|
||||
**/
|
||||
public void compress(byte[] buf, int offset, int length)
|
||||
throws IOException
|
||||
{
|
||||
int idx;
|
||||
byte c;
|
||||
short index;
|
||||
|
||||
int maxOffset = offset + length;
|
||||
for (idx = offset; idx < maxOffset; ++idx) {
|
||||
c = buf[idx];
|
||||
if ((index = lzss.findCharString(prefix, c)) != -1) {
|
||||
prefix = index;
|
||||
} else {
|
||||
bf.writeBits(prefix, numBits);
|
||||
if (lzss.addCharString(prefix, c) > limit) {
|
||||
if (numBits == 12) {
|
||||
bf.writeBits(clearCode, numBits);
|
||||
lzss.clearTable(codeSize);
|
||||
numBits = codeSize + 1;
|
||||
} else {
|
||||
++numBits;
|
||||
}
|
||||
|
||||
limit = (1 << numBits) - 1;
|
||||
if (tiffFudge) {
|
||||
--limit;
|
||||
}
|
||||
}
|
||||
prefix = (short)((short)c & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate to compressor that no more data to go so write out
|
||||
* any remaining buffered data.
|
||||
*
|
||||
* @exception IOException if underlying output stream error
|
||||
*/
|
||||
public void flush() throws IOException {
|
||||
if (prefix != -1) {
|
||||
bf.writeBits(prefix, numBits);
|
||||
}
|
||||
|
||||
bf.writeBits(endOfInfo, numBits);
|
||||
bf.flush();
|
||||
}
|
||||
|
||||
public void dump(PrintStream out) {
|
||||
lzss.dump(out);
|
||||
}
|
||||
}
|
||||
218
jdkSrc/jdk8/com/sun/imageio/plugins/common/LZWStringTable.java
Normal file
218
jdkSrc/jdk8/com/sun/imageio/plugins/common/LZWStringTable.java
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* General purpose LZW String Table.
|
||||
* Extracted from GIFEncoder by Adam Doppelt
|
||||
* Comments added by Robin Luiten
|
||||
* <code>expandCode</code> added by Robin Luiten
|
||||
* The strLen table to give quick access to the lenght of an expanded
|
||||
* code for use by the <code>expandCode</code> method added by Robin.
|
||||
**/
|
||||
public class LZWStringTable {
|
||||
/** codesize + Reserved Codes */
|
||||
private final static int RES_CODES = 2;
|
||||
|
||||
private final static short HASH_FREE = (short)0xFFFF;
|
||||
private final static short NEXT_FIRST = (short)0xFFFF;
|
||||
|
||||
private final static int MAXBITS = 12;
|
||||
private final static int MAXSTR = (1 << MAXBITS);
|
||||
|
||||
private final static short HASHSIZE = 9973;
|
||||
private final static short HASHSTEP = 2039;
|
||||
|
||||
byte[] strChr; // after predecessor character
|
||||
short[] strNxt; // predecessor string
|
||||
short[] strHsh; // hash table to find predecessor + char pairs
|
||||
short numStrings; // next code if adding new prestring + char
|
||||
|
||||
/*
|
||||
* each entry corresponds to a code and contains the length of data
|
||||
* that the code expands to when decoded.
|
||||
*/
|
||||
int[] strLen;
|
||||
|
||||
/*
|
||||
* Constructor allocate memory for string store data
|
||||
*/
|
||||
public LZWStringTable() {
|
||||
strChr = new byte[MAXSTR];
|
||||
strNxt = new short[MAXSTR];
|
||||
strLen = new int[MAXSTR];
|
||||
strHsh = new short[HASHSIZE];
|
||||
}
|
||||
|
||||
/*
|
||||
* @param index value of -1 indicates no predecessor [used in initialisation]
|
||||
* @param b the byte [character] to add to the string store which follows
|
||||
* the predecessor string specified the index.
|
||||
* @return 0xFFFF if no space in table left for addition of predecesor
|
||||
* index and byte b. Else return the code allocated for combination index + b.
|
||||
*/
|
||||
public int addCharString(short index, byte b) {
|
||||
int hshidx;
|
||||
|
||||
if (numStrings >= MAXSTR) { // if used up all codes
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
hshidx = hash(index, b);
|
||||
while (strHsh[hshidx] != HASH_FREE) {
|
||||
hshidx = (hshidx + HASHSTEP) % HASHSIZE;
|
||||
}
|
||||
|
||||
strHsh[hshidx] = numStrings;
|
||||
strChr[numStrings] = b;
|
||||
if (index == HASH_FREE) {
|
||||
strNxt[numStrings] = NEXT_FIRST;
|
||||
strLen[numStrings] = 1;
|
||||
} else {
|
||||
strNxt[numStrings] = index;
|
||||
strLen[numStrings] = strLen[index] + 1;
|
||||
}
|
||||
|
||||
return numStrings++; // return the code and inc for next code
|
||||
}
|
||||
|
||||
/*
|
||||
* @param index index to prefix string
|
||||
* @param b the character that follws the index prefix
|
||||
* @return b if param index is HASH_FREE. Else return the code
|
||||
* for this prefix and byte successor
|
||||
*/
|
||||
public short findCharString(short index, byte b) {
|
||||
int hshidx, nxtidx;
|
||||
|
||||
if (index == HASH_FREE) {
|
||||
return (short)(b & 0xFF); // Rob fixed used to sign extend
|
||||
}
|
||||
|
||||
hshidx = hash(index, b);
|
||||
while ((nxtidx = strHsh[hshidx]) != HASH_FREE) { // search
|
||||
if (strNxt[nxtidx] == index && strChr[nxtidx] == b) {
|
||||
return (short)nxtidx;
|
||||
}
|
||||
hshidx = (hshidx + HASHSTEP) % HASHSIZE;
|
||||
}
|
||||
|
||||
return (short)0xFFFF;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param codesize the size of code to be preallocated for the
|
||||
* string store.
|
||||
*/
|
||||
public void clearTable(int codesize) {
|
||||
numStrings = 0;
|
||||
|
||||
for (int q = 0; q < HASHSIZE; q++) {
|
||||
strHsh[q] = HASH_FREE;
|
||||
}
|
||||
|
||||
int w = (1 << codesize) + RES_CODES;
|
||||
for (int q = 0; q < w; q++) {
|
||||
addCharString((short)0xFFFF, (byte)q); // init with no prefix
|
||||
}
|
||||
}
|
||||
|
||||
static public int hash(short index, byte lastbyte) {
|
||||
return ((int)((short)(lastbyte << 8) ^ index) & 0xFFFF) % HASHSIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If expanded data doesn't fit into array only what will fit is written
|
||||
* to buf and the return value indicates how much of the expanded code has
|
||||
* been written to the buf. The next call to expandCode() should be with
|
||||
* the same code and have the skip parameter set the negated value of the
|
||||
* previous return. Succesive negative return values should be negated and
|
||||
* added together for next skip parameter value with same code.
|
||||
*
|
||||
* @param buf buffer to place expanded data into
|
||||
* @param offset offset to place expanded data
|
||||
* @param code the code to expand to the byte array it represents.
|
||||
* PRECONDITION This code must already be in the LZSS
|
||||
* @param skipHead is the number of bytes at the start of the expanded code to
|
||||
* be skipped before data is written to buf. It is possible that skipHead is
|
||||
* equal to codeLen.
|
||||
* @return the length of data expanded into buf. If the expanded code is longer
|
||||
* than space left in buf then the value returned is a negative number which when
|
||||
* negated is equal to the number of bytes that were used of the code being expanded.
|
||||
* This negative value also indicates the buffer is full.
|
||||
*/
|
||||
public int expandCode(byte[] buf, int offset, short code, int skipHead) {
|
||||
if (offset == -2) {
|
||||
if (skipHead == 1) {
|
||||
skipHead = 0;
|
||||
}
|
||||
}
|
||||
if (code == (short)0xFFFF || // just in case
|
||||
skipHead == strLen[code]) // DONE no more unpacked
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int expandLen; // how much data we are actually expanding
|
||||
int codeLen = strLen[code] - skipHead; // length of expanded code left
|
||||
int bufSpace = buf.length - offset; // how much space left
|
||||
if (bufSpace > codeLen) {
|
||||
expandLen = codeLen; // only got this many to unpack
|
||||
} else {
|
||||
expandLen = bufSpace;
|
||||
}
|
||||
|
||||
int skipTail = codeLen - expandLen; // only > 0 if codeLen > bufSpace [left overs]
|
||||
|
||||
int idx = offset + expandLen; // initialise to exclusive end address of buffer area
|
||||
|
||||
// NOTE: data unpacks in reverse direction and we are placing the
|
||||
// unpacked data directly into the array in the correct location.
|
||||
while ((idx > offset) && (code != (short)0xFFFF)) {
|
||||
if (--skipTail < 0) { // skip required of expanded data
|
||||
buf[--idx] = strChr[code];
|
||||
}
|
||||
code = strNxt[code]; // to predecessor code
|
||||
}
|
||||
|
||||
if (codeLen > expandLen) {
|
||||
return -expandLen; // indicate what part of codeLen used
|
||||
} else {
|
||||
return expandLen; // indicate length of dat unpacked
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintStream out) {
|
||||
int i;
|
||||
for (i = 258; i < numStrings; ++i) {
|
||||
out.println(" strNxt[" + i + "] = " + strNxt[i]
|
||||
+ " strChr " + Integer.toHexString(strChr[i] & 0xFF)
|
||||
+ " strLen " + Integer.toHexString(strLen[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
486
jdkSrc/jdk8/com/sun/imageio/plugins/common/PaletteBuilder.java
Normal file
486
jdkSrc/jdk8/com/sun/imageio/plugins/common/PaletteBuilder.java
Normal file
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.Color;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
|
||||
|
||||
/**
|
||||
* This class implements the octree quantization method
|
||||
* as it is described in the "Graphics Gems"
|
||||
* (ISBN 0-12-286166-3, Chapter 4, pages 297-293)
|
||||
*/
|
||||
public class PaletteBuilder {
|
||||
|
||||
/**
|
||||
* maximum of tree depth
|
||||
*/
|
||||
protected static final int MAXLEVEL = 8;
|
||||
|
||||
protected RenderedImage src;
|
||||
protected ColorModel srcColorModel;
|
||||
protected Raster srcRaster;
|
||||
|
||||
protected int requiredSize;
|
||||
|
||||
protected ColorNode root;
|
||||
|
||||
protected int numNodes;
|
||||
protected int maxNodes;
|
||||
protected int currLevel;
|
||||
protected int currSize;
|
||||
|
||||
protected ColorNode[] reduceList;
|
||||
protected ColorNode[] palette;
|
||||
|
||||
protected int transparency;
|
||||
protected ColorNode transColor;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an image representing given image
|
||||
* <code>src</code> using <code>IndexColorModel</code>.
|
||||
*
|
||||
* Lossless conversion is not always possible (e.g. if number
|
||||
* of colors in the given image exceeds maximum palette size).
|
||||
* Result image then is an approximation constructed by octree
|
||||
* quantization method.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>src</code> is
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @exception UnsupportedOperationException if implemented method
|
||||
* is unable to create approximation of <code>src</code>
|
||||
* and <code>canCreatePalette</code> returns <code>false</code>.
|
||||
*
|
||||
* @see createIndexColorModel
|
||||
*
|
||||
* @see canCreatePalette
|
||||
*
|
||||
*/
|
||||
public static RenderedImage createIndexedImage(RenderedImage src) {
|
||||
PaletteBuilder pb = new PaletteBuilder(src);
|
||||
pb.buildPalette();
|
||||
return pb.getIndexedImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an palette representing colors from given image
|
||||
* <code>img</code>. If number of colors in the given image exceeds
|
||||
* maximum palette size closest colors would be merged.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>img</code> is
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @exception UnsupportedOperationException if implemented method
|
||||
* is unable to create approximation of <code>img</code>
|
||||
* and <code>canCreatePalette</code> returns <code>false</code>.
|
||||
*
|
||||
* @see createIndexedImage
|
||||
*
|
||||
* @see canCreatePalette
|
||||
*
|
||||
*/
|
||||
public static IndexColorModel createIndexColorModel(RenderedImage img) {
|
||||
PaletteBuilder pb = new PaletteBuilder(img);
|
||||
pb.buildPalette();
|
||||
return pb.getIndexColorModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if PaletteBuilder is able to create
|
||||
* palette for given image type.
|
||||
*
|
||||
* @param type an instance of <code>ImageTypeSpecifier</code> to be
|
||||
* indexed.
|
||||
*
|
||||
* @return <code>true</code> if the <code>PaletteBuilder</code>
|
||||
* is likely to be able to create palette for this image type.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>type</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public static boolean canCreatePalette(ImageTypeSpecifier type) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type == null");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if PaletteBuilder is able to create
|
||||
* palette for given rendered image.
|
||||
*
|
||||
* @param image an instance of <code>RenderedImage</code> to be
|
||||
* indexed.
|
||||
*
|
||||
* @return <code>true</code> if the <code>PaletteBuilder</code>
|
||||
* is likely to be able to create palette for this image type.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>image</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public static boolean canCreatePalette(RenderedImage image) {
|
||||
if (image == null) {
|
||||
throw new IllegalArgumentException("image == null");
|
||||
}
|
||||
ImageTypeSpecifier type = new ImageTypeSpecifier(image);
|
||||
return canCreatePalette(type);
|
||||
}
|
||||
|
||||
protected RenderedImage getIndexedImage() {
|
||||
IndexColorModel icm = getIndexColorModel();
|
||||
|
||||
BufferedImage dst =
|
||||
new BufferedImage(src.getWidth(), src.getHeight(),
|
||||
BufferedImage.TYPE_BYTE_INDEXED, icm);
|
||||
|
||||
WritableRaster wr = dst.getRaster();
|
||||
for (int y =0; y < dst.getHeight(); y++) {
|
||||
for (int x = 0; x < dst.getWidth(); x++) {
|
||||
Color aColor = getSrcColor(x,y);
|
||||
wr.setSample(x, y, 0, findColorIndex(root, aColor));
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
protected PaletteBuilder(RenderedImage src) {
|
||||
this(src, 256);
|
||||
}
|
||||
|
||||
protected PaletteBuilder(RenderedImage src, int size) {
|
||||
this.src = src;
|
||||
this.srcColorModel = src.getColorModel();
|
||||
this.srcRaster = src.getData();
|
||||
|
||||
this.transparency =
|
||||
srcColorModel.getTransparency();
|
||||
|
||||
this.requiredSize = size;
|
||||
}
|
||||
|
||||
private Color getSrcColor(int x, int y) {
|
||||
int argb = srcColorModel.getRGB(srcRaster.getDataElements(x, y, null));
|
||||
return new Color(argb, transparency != Transparency.OPAQUE);
|
||||
}
|
||||
|
||||
protected int findColorIndex(ColorNode aNode, Color aColor) {
|
||||
if (transparency != Transparency.OPAQUE &&
|
||||
aColor.getAlpha() != 0xff)
|
||||
{
|
||||
return 0; // default transparnt pixel
|
||||
}
|
||||
|
||||
if (aNode.isLeaf) {
|
||||
return aNode.paletteIndex;
|
||||
} else {
|
||||
int childIndex = getBranchIndex(aColor, aNode.level);
|
||||
|
||||
return findColorIndex(aNode.children[childIndex], aColor);
|
||||
}
|
||||
}
|
||||
|
||||
protected void buildPalette() {
|
||||
reduceList = new ColorNode[MAXLEVEL + 1];
|
||||
for (int i = 0; i < reduceList.length; i++) {
|
||||
reduceList[i] = null;
|
||||
}
|
||||
|
||||
numNodes = 0;
|
||||
maxNodes = 0;
|
||||
root = null;
|
||||
currSize = 0;
|
||||
currLevel = MAXLEVEL;
|
||||
|
||||
/*
|
||||
from the book
|
||||
|
||||
*/
|
||||
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
|
||||
Color aColor = getSrcColor(w - x - 1, h - y - 1);
|
||||
/*
|
||||
* If transparency of given image is not opaque we assume all
|
||||
* colors with alpha less than 1.0 as fully transparent.
|
||||
*/
|
||||
if (transparency != Transparency.OPAQUE &&
|
||||
aColor.getAlpha() != 0xff)
|
||||
{
|
||||
if (transColor == null) {
|
||||
this.requiredSize --; // one slot for transparent color
|
||||
|
||||
transColor = new ColorNode();
|
||||
transColor.isLeaf = true;
|
||||
}
|
||||
transColor = insertNode(transColor, aColor, 0);
|
||||
} else {
|
||||
root = insertNode(root, aColor, 0);
|
||||
}
|
||||
if (currSize > requiredSize) {
|
||||
reduceTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ColorNode insertNode(ColorNode aNode, Color aColor, int aLevel) {
|
||||
|
||||
if (aNode == null) {
|
||||
aNode = new ColorNode();
|
||||
numNodes++;
|
||||
if (numNodes > maxNodes) {
|
||||
maxNodes = numNodes;
|
||||
}
|
||||
aNode.level = aLevel;
|
||||
aNode.isLeaf = (aLevel > MAXLEVEL);
|
||||
if (aNode.isLeaf) {
|
||||
currSize++;
|
||||
}
|
||||
}
|
||||
aNode.colorCount++;
|
||||
aNode.red += aColor.getRed();
|
||||
aNode.green += aColor.getGreen();
|
||||
aNode.blue += aColor.getBlue();
|
||||
|
||||
if (!aNode.isLeaf) {
|
||||
int branchIndex = getBranchIndex(aColor, aLevel);
|
||||
if (aNode.children[branchIndex] == null) {
|
||||
aNode.childCount++;
|
||||
if (aNode.childCount == 2) {
|
||||
aNode.nextReducible = reduceList[aLevel];
|
||||
reduceList[aLevel] = aNode;
|
||||
}
|
||||
}
|
||||
aNode.children[branchIndex] =
|
||||
insertNode(aNode.children[branchIndex], aColor, aLevel + 1);
|
||||
}
|
||||
return aNode;
|
||||
}
|
||||
|
||||
protected IndexColorModel getIndexColorModel() {
|
||||
int size = currSize;
|
||||
if (transColor != null) {
|
||||
size ++; // we need place for transparent color;
|
||||
}
|
||||
|
||||
byte[] red = new byte[size];
|
||||
byte[] green = new byte[size];
|
||||
byte[] blue = new byte[size];
|
||||
|
||||
int index = 0;
|
||||
palette = new ColorNode[size];
|
||||
if (transColor != null) {
|
||||
index ++;
|
||||
}
|
||||
|
||||
if (root != null) {
|
||||
findPaletteEntry(root, index, red, green, blue);
|
||||
}
|
||||
|
||||
IndexColorModel icm = null;
|
||||
if (transColor != null) {
|
||||
icm = new IndexColorModel(8, size, red, green, blue, 0);
|
||||
} else {
|
||||
icm = new IndexColorModel(8, currSize, red, green, blue);
|
||||
}
|
||||
return icm;
|
||||
}
|
||||
|
||||
protected int findPaletteEntry(ColorNode aNode, int index,
|
||||
byte[] red, byte[] green, byte[] blue)
|
||||
{
|
||||
if (aNode.isLeaf) {
|
||||
red[index] = (byte)(aNode.red/aNode.colorCount);
|
||||
green[index] = (byte)(aNode.green/aNode.colorCount);
|
||||
blue[index] = (byte)(aNode.blue/aNode.colorCount);
|
||||
aNode.paletteIndex = index;
|
||||
|
||||
palette[index] = aNode;
|
||||
|
||||
index++;
|
||||
} else {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (aNode.children[i] != null) {
|
||||
index = findPaletteEntry(aNode.children[i], index,
|
||||
red, green, blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
protected int getBranchIndex(Color aColor, int aLevel) {
|
||||
if (aLevel > MAXLEVEL || aLevel < 0) {
|
||||
throw new IllegalArgumentException("Invalid octree node depth: " +
|
||||
aLevel);
|
||||
}
|
||||
|
||||
int shift = MAXLEVEL - aLevel;
|
||||
int red_index = 0x1 & ((0xff & aColor.getRed()) >> shift);
|
||||
int green_index = 0x1 & ((0xff & aColor.getGreen()) >> shift);
|
||||
int blue_index = 0x1 & ((0xff & aColor.getBlue()) >> shift);
|
||||
int index = (red_index << 2) | (green_index << 1) | blue_index;
|
||||
return index;
|
||||
}
|
||||
|
||||
protected void reduceTree() {
|
||||
int level = reduceList.length - 1;
|
||||
while (reduceList[level] == null && level >= 0) {
|
||||
level--;
|
||||
}
|
||||
|
||||
ColorNode thisNode = reduceList[level];
|
||||
if (thisNode == null) {
|
||||
// nothing to reduce
|
||||
return;
|
||||
}
|
||||
|
||||
// look for element with lower color count
|
||||
ColorNode pList = thisNode;
|
||||
int minColorCount = pList.colorCount;
|
||||
|
||||
int cnt = 1;
|
||||
while (pList.nextReducible != null) {
|
||||
if (minColorCount > pList.nextReducible.colorCount) {
|
||||
thisNode = pList;
|
||||
minColorCount = pList.colorCount;
|
||||
}
|
||||
pList = pList.nextReducible;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
// save pointer to first reducible node
|
||||
// NB: current color count for node could be changed in future
|
||||
if (thisNode == reduceList[level]) {
|
||||
reduceList[level] = thisNode.nextReducible;
|
||||
} else {
|
||||
pList = thisNode.nextReducible; // we need to process it
|
||||
thisNode.nextReducible = pList.nextReducible;
|
||||
thisNode = pList;
|
||||
}
|
||||
|
||||
if (thisNode.isLeaf) {
|
||||
return;
|
||||
}
|
||||
|
||||
// reduce node
|
||||
int leafChildCount = thisNode.getLeafChildCount();
|
||||
thisNode.isLeaf = true;
|
||||
currSize -= (leafChildCount - 1);
|
||||
int aDepth = thisNode.level;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
thisNode.children[i] = freeTree(thisNode.children[i]);
|
||||
}
|
||||
thisNode.childCount = 0;
|
||||
}
|
||||
|
||||
protected ColorNode freeTree(ColorNode aNode) {
|
||||
if (aNode == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
aNode.children[i] = freeTree(aNode.children[i]);
|
||||
}
|
||||
|
||||
numNodes--;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The node of color tree.
|
||||
*/
|
||||
protected class ColorNode {
|
||||
public boolean isLeaf;
|
||||
public int childCount;
|
||||
ColorNode[] children;
|
||||
|
||||
public int colorCount;
|
||||
public long red;
|
||||
public long blue;
|
||||
public long green;
|
||||
|
||||
public int paletteIndex;
|
||||
|
||||
public int level;
|
||||
ColorNode nextReducible;
|
||||
|
||||
public ColorNode() {
|
||||
isLeaf = false;
|
||||
level = 0;
|
||||
childCount = 0;
|
||||
children = new ColorNode[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
children[i] = null;
|
||||
}
|
||||
|
||||
colorCount = 0;
|
||||
red = green = blue = 0;
|
||||
|
||||
paletteIndex = 0;
|
||||
}
|
||||
|
||||
public int getLeafChildCount() {
|
||||
if (isLeaf) {
|
||||
return 0;
|
||||
}
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
if (children[i] != null) {
|
||||
if (children[i].isLeaf) {
|
||||
cnt ++;
|
||||
} else {
|
||||
cnt += children[i].getLeafChildCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
public int getRGB() {
|
||||
int r = (int)red/colorCount;
|
||||
int g = (int)green/colorCount;
|
||||
int b = (int)blue/colorCount;
|
||||
|
||||
int c = 0xff << 24 | (0xff&r) << 16 | (0xff&g) << 8 | (0xff&b);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
261
jdkSrc/jdk8/com/sun/imageio/plugins/common/ReaderUtil.java
Normal file
261
jdkSrc/jdk8/com/sun/imageio/plugins/common/ReaderUtil.java
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* This class contains utility methods that may be useful to ImageReader
|
||||
* plugins. Ideally these methods would be in the ImageReader base class
|
||||
* so that all subclasses could benefit from them, but that would be an
|
||||
* addition to the existing API, and it is not yet clear whether these methods
|
||||
* are universally useful, so for now we will leave them here.
|
||||
*/
|
||||
public class ReaderUtil {
|
||||
|
||||
// Helper for computeUpdatedPixels method
|
||||
private static void computeUpdatedPixels(int sourceOffset,
|
||||
int sourceExtent,
|
||||
int destinationOffset,
|
||||
int dstMin,
|
||||
int dstMax,
|
||||
int sourceSubsampling,
|
||||
int passStart,
|
||||
int passExtent,
|
||||
int passPeriod,
|
||||
int[] vals,
|
||||
int offset)
|
||||
{
|
||||
// We need to satisfy the congruences:
|
||||
// dst = destinationOffset + (src - sourceOffset)/sourceSubsampling
|
||||
//
|
||||
// src - passStart == 0 (mod passPeriod)
|
||||
// src - sourceOffset == 0 (mod sourceSubsampling)
|
||||
//
|
||||
// subject to the inequalities:
|
||||
//
|
||||
// src >= passStart
|
||||
// src < passStart + passExtent
|
||||
// src >= sourceOffset
|
||||
// src < sourceOffset + sourceExtent
|
||||
// dst >= dstMin
|
||||
// dst <= dstmax
|
||||
//
|
||||
// where
|
||||
//
|
||||
// dst = destinationOffset + (src - sourceOffset)/sourceSubsampling
|
||||
//
|
||||
// For now we use a brute-force approach although we could
|
||||
// attempt to analyze the congruences. If passPeriod and
|
||||
// sourceSubsamling are relatively prime, the period will be
|
||||
// their product. If they share a common factor, either the
|
||||
// period will be equal to the larger value, or the sequences
|
||||
// will be completely disjoint, depending on the relationship
|
||||
// between passStart and sourceOffset. Since we only have to do this
|
||||
// twice per image (once each for X and Y), it seems cheap enough
|
||||
// to do it the straightforward way.
|
||||
|
||||
boolean gotPixel = false;
|
||||
int firstDst = -1;
|
||||
int secondDst = -1;
|
||||
int lastDst = -1;
|
||||
|
||||
for (int i = 0; i < passExtent; i++) {
|
||||
int src = passStart + i*passPeriod;
|
||||
if (src < sourceOffset) {
|
||||
continue;
|
||||
}
|
||||
if ((src - sourceOffset) % sourceSubsampling != 0) {
|
||||
continue;
|
||||
}
|
||||
if (src >= sourceOffset + sourceExtent) {
|
||||
break;
|
||||
}
|
||||
|
||||
int dst = destinationOffset +
|
||||
(src - sourceOffset)/sourceSubsampling;
|
||||
if (dst < dstMin) {
|
||||
continue;
|
||||
}
|
||||
if (dst > dstMax) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gotPixel) {
|
||||
firstDst = dst; // Record smallest valid pixel
|
||||
gotPixel = true;
|
||||
} else if (secondDst == -1) {
|
||||
secondDst = dst; // Record second smallest valid pixel
|
||||
}
|
||||
lastDst = dst; // Record largest valid pixel
|
||||
}
|
||||
|
||||
vals[offset] = firstDst;
|
||||
|
||||
// If we never saw a valid pixel, set width to 0
|
||||
if (!gotPixel) {
|
||||
vals[offset + 2] = 0;
|
||||
} else {
|
||||
vals[offset + 2] = lastDst - firstDst + 1;
|
||||
}
|
||||
|
||||
// The period is given by the difference of any two adjacent pixels
|
||||
vals[offset + 4] = Math.max(secondDst - firstDst, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method that computes the exact set of destination
|
||||
* pixels that will be written during a particular decoding pass.
|
||||
* The intent is to simplify the work done by readers in combining
|
||||
* the source region, source subsampling, and destination offset
|
||||
* information obtained from the <code>ImageReadParam</code> with
|
||||
* the offsets and periods of a progressive or interlaced decoding
|
||||
* pass.
|
||||
*
|
||||
* @param sourceRegion a <code>Rectangle</code> containing the
|
||||
* source region being read, offset by the source subsampling
|
||||
* offsets, and clipped against the source bounds, as returned by
|
||||
* the <code>getSourceRegion</code> method.
|
||||
* @param destinationOffset a <code>Point</code> containing the
|
||||
* coordinates of the upper-left pixel to be written in the
|
||||
* destination.
|
||||
* @param dstMinX the smallest X coordinate (inclusive) of the
|
||||
* destination <code>Raster</code>.
|
||||
* @param dstMinY the smallest Y coordinate (inclusive) of the
|
||||
* destination <code>Raster</code>.
|
||||
* @param dstMaxX the largest X coordinate (inclusive) of the destination
|
||||
* <code>Raster</code>.
|
||||
* @param dstMaxY the largest Y coordinate (inclusive) of the destination
|
||||
* <code>Raster</code>.
|
||||
* @param sourceXSubsampling the X subsampling factor.
|
||||
* @param sourceYSubsampling the Y subsampling factor.
|
||||
* @param passXStart the smallest source X coordinate (inclusive)
|
||||
* of the current progressive pass.
|
||||
* @param passYStart the smallest source Y coordinate (inclusive)
|
||||
* of the current progressive pass.
|
||||
* @param passWidth the width in pixels of the current progressive
|
||||
* pass.
|
||||
* @param passHeight the height in pixels of the current progressive
|
||||
* pass.
|
||||
* @param passPeriodX the X period (horizontal spacing between
|
||||
* pixels) of the current progressive pass.
|
||||
* @param passPeriodY the Y period (vertical spacing between
|
||||
* pixels) of the current progressive pass.
|
||||
*
|
||||
* @return an array of 6 <code>int</code>s containing the
|
||||
* destination min X, min Y, width, height, X period and Y period
|
||||
* of the region that will be updated.
|
||||
*/
|
||||
public static int[] computeUpdatedPixels(Rectangle sourceRegion,
|
||||
Point destinationOffset,
|
||||
int dstMinX,
|
||||
int dstMinY,
|
||||
int dstMaxX,
|
||||
int dstMaxY,
|
||||
int sourceXSubsampling,
|
||||
int sourceYSubsampling,
|
||||
int passXStart,
|
||||
int passYStart,
|
||||
int passWidth,
|
||||
int passHeight,
|
||||
int passPeriodX,
|
||||
int passPeriodY)
|
||||
{
|
||||
int[] vals = new int[6];
|
||||
computeUpdatedPixels(sourceRegion.x, sourceRegion.width,
|
||||
destinationOffset.x,
|
||||
dstMinX, dstMaxX, sourceXSubsampling,
|
||||
passXStart, passWidth, passPeriodX,
|
||||
vals, 0);
|
||||
computeUpdatedPixels(sourceRegion.y, sourceRegion.height,
|
||||
destinationOffset.y,
|
||||
dstMinY, dstMaxY, sourceYSubsampling,
|
||||
passYStart, passHeight, passPeriodY,
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* An utility method to allocate and initialize a byte array
|
||||
* step by step with pre-defined limit, instead of allocating
|
||||
* a large array up-front based on the length derived from
|
||||
* an image header.
|
||||
*
|
||||
* @param iis a {@code ImageInputStream} to decode data and store
|
||||
* it in byte array.
|
||||
* @param length the size of data to decode
|
||||
*
|
||||
* @return array of size length when decode succeeeds
|
||||
*
|
||||
* @throws IOException if decoding of stream fails
|
||||
*/
|
||||
public static byte[] staggeredReadByteStream(ImageInputStream iis,
|
||||
int length) throws IOException {
|
||||
final int UNIT_SIZE = 1024000;
|
||||
byte[] decodedData;
|
||||
if (length < UNIT_SIZE) {
|
||||
decodedData = new byte[length];
|
||||
iis.readFully(decodedData, 0, length);
|
||||
} else {
|
||||
int bytesToRead = length;
|
||||
int bytesRead = 0;
|
||||
List<byte[]> bufs = new ArrayList<>();
|
||||
while (bytesToRead != 0) {
|
||||
int sz = Math.min(bytesToRead, UNIT_SIZE);
|
||||
byte[] unit = new byte[sz];
|
||||
iis.readFully(unit, 0, sz);
|
||||
bufs.add(unit);
|
||||
bytesRead += sz;
|
||||
bytesToRead -= sz;
|
||||
}
|
||||
decodedData = new byte[bytesRead];
|
||||
int copiedBytes = 0;
|
||||
for (byte[] ba : bufs) {
|
||||
System.arraycopy(ba, 0, decodedData, copiedBytes, ba.length);
|
||||
copiedBytes += ba.length;
|
||||
}
|
||||
}
|
||||
return decodedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class StandardMetadataFormat extends IIOMetadataFormatImpl {
|
||||
|
||||
// Utility method for nodes with a single attribute named "value"
|
||||
private void addSingleAttributeElement(String elementName,
|
||||
String parentName,
|
||||
int dataType) {
|
||||
addElement(elementName, parentName, CHILD_POLICY_EMPTY);
|
||||
addAttribute(elementName, "value", dataType, true, null);
|
||||
}
|
||||
|
||||
public StandardMetadataFormat() {
|
||||
super(standardMetadataFormatName, CHILD_POLICY_SOME);
|
||||
List values;
|
||||
|
||||
// root -> Chroma
|
||||
addElement("Chroma", standardMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> Chroma -> ColorSpaceType
|
||||
addElement("ColorSpaceType", "Chroma",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
values = new ArrayList();
|
||||
values.add("XYZ");
|
||||
values.add("Lab");
|
||||
values.add("Luv");
|
||||
values.add("YCbCr");
|
||||
values.add("Yxy");
|
||||
values.add("YCCK");
|
||||
values.add("PhotoYCC");
|
||||
values.add("RGB");
|
||||
values.add("GRAY");
|
||||
values.add("HSV");
|
||||
values.add("HLS");
|
||||
values.add("CMYK");
|
||||
values.add("CMY");
|
||||
values.add("2CLR");
|
||||
values.add("3CLR");
|
||||
values.add("4CLR");
|
||||
values.add("5CLR");
|
||||
values.add("6CLR");
|
||||
values.add("7CLR");
|
||||
values.add("8CLR");
|
||||
values.add("9CLR");
|
||||
values.add("ACLR");
|
||||
values.add("BCLR");
|
||||
values.add("CCLR");
|
||||
values.add("DCLR");
|
||||
values.add("ECLR");
|
||||
values.add("FCLR");
|
||||
addAttribute("ColorSpaceType",
|
||||
"name",
|
||||
DATATYPE_STRING,
|
||||
true,
|
||||
null,
|
||||
values);
|
||||
|
||||
// root -> Chroma -> NumChannels
|
||||
addElement("NumChannels", "Chroma",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("NumChannels", "value",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Chroma -> Gamma
|
||||
addElement("Gamma", "Chroma", CHILD_POLICY_EMPTY);
|
||||
addAttribute("Gamma", "value",
|
||||
DATATYPE_FLOAT, true, null);
|
||||
|
||||
// root -> Chroma -> BlackIsZero
|
||||
addElement("BlackIsZero", "Chroma", CHILD_POLICY_EMPTY);
|
||||
addBooleanAttribute("BlackIsZero", "value", true, true);
|
||||
|
||||
// root -> Chroma -> Palette
|
||||
addElement("Palette", "Chroma", 0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Chroma -> PaletteEntry
|
||||
addElement("PaletteEntry", "Palette", CHILD_POLICY_EMPTY);
|
||||
addAttribute("PaletteEntry", "index", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
addAttribute("PaletteEntry", "red", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
addAttribute("PaletteEntry", "green", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
addAttribute("PaletteEntry", "blue", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
addAttribute("PaletteEntry", "alpha", DATATYPE_INTEGER,
|
||||
false, "255");
|
||||
|
||||
// root -> Chroma -> BackgroundIndex
|
||||
addElement("BackgroundIndex", "Chroma", CHILD_POLICY_EMPTY);
|
||||
addAttribute("BackgroundIndex", "value", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
|
||||
// root -> Chroma -> BackgroundColor
|
||||
addElement("BackgroundColor", "Chroma", CHILD_POLICY_EMPTY);
|
||||
addAttribute("BackgroundColor", "red", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
addAttribute("BackgroundColor", "green", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
addAttribute("BackgroundColor", "blue", DATATYPE_INTEGER,
|
||||
true, null);
|
||||
|
||||
// root -> Compression
|
||||
addElement("Compression", standardMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> Compression -> CompressionTypeName
|
||||
addSingleAttributeElement("CompressionTypeName",
|
||||
"Compression",
|
||||
DATATYPE_STRING);
|
||||
|
||||
// root -> Compression -> Lossless
|
||||
addElement("Lossless", "Compression", CHILD_POLICY_EMPTY);
|
||||
addBooleanAttribute("Lossless", "value", true, true);
|
||||
|
||||
// root -> Compression -> NumProgressiveScans
|
||||
addSingleAttributeElement("NumProgressiveScans",
|
||||
"Compression",
|
||||
DATATYPE_INTEGER);
|
||||
|
||||
// root -> Compression -> BitRate
|
||||
addSingleAttributeElement("BitRate",
|
||||
"Compression",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Data
|
||||
addElement("Data", standardMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> Data -> PlanarConfiguration
|
||||
addElement("PlanarConfiguration", "Data", CHILD_POLICY_EMPTY);
|
||||
|
||||
values = new ArrayList();
|
||||
values.add("PixelInterleaved");
|
||||
values.add("PlaneInterleaved");
|
||||
values.add("LineInterleaved");
|
||||
values.add("TileInterleaved");
|
||||
addAttribute("PlanarConfiguration", "value",
|
||||
DATATYPE_STRING,
|
||||
true,
|
||||
null,
|
||||
values);
|
||||
|
||||
// root -> Data -> SampleFormat
|
||||
addElement("SampleFormat", "Data", CHILD_POLICY_EMPTY);
|
||||
|
||||
values = new ArrayList();
|
||||
values.add("SignedIntegral");
|
||||
values.add("UnsignedIntegral");
|
||||
values.add("Real");
|
||||
values.add("Index");
|
||||
addAttribute("SampleFormat", "value",
|
||||
DATATYPE_STRING,
|
||||
true,
|
||||
null,
|
||||
values);
|
||||
|
||||
// root -> Data -> BitsPerSample
|
||||
addElement("BitsPerSample", "Data",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("BitsPerSample", "value",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Data -> SignificantBitsPerSample
|
||||
addElement("SignificantBitsPerSample", "Data", CHILD_POLICY_EMPTY);
|
||||
addAttribute("SignificantBitsPerSample", "value",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Data -> SampleMSB
|
||||
addElement("SampleMSB", "Data",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("SampleMSB", "value",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Dimension
|
||||
addElement("Dimension", standardMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> Dimension -> PixelAspectRatio
|
||||
addSingleAttributeElement("PixelAspectRatio",
|
||||
"Dimension",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Dimension -> ImageOrientation
|
||||
addElement("ImageOrientation", "Dimension",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
values = new ArrayList();
|
||||
values.add("Normal");
|
||||
values.add("Rotate90");
|
||||
values.add("Rotate180");
|
||||
values.add("Rotate270");
|
||||
values.add("FlipH");
|
||||
values.add("FlipV");
|
||||
values.add("FlipHRotate90");
|
||||
values.add("FlipVRotate90");
|
||||
addAttribute("ImageOrientation", "value",
|
||||
DATATYPE_STRING,
|
||||
true,
|
||||
null,
|
||||
values);
|
||||
|
||||
// root -> Dimension -> HorizontalPixelSize
|
||||
addSingleAttributeElement("HorizontalPixelSize",
|
||||
"Dimension",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Dimension -> VerticalPixelSize
|
||||
addSingleAttributeElement("VerticalPixelSize",
|
||||
"Dimension",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Dimension -> HorizontalPhysicalPixelSpacing
|
||||
addSingleAttributeElement("HorizontalPhysicalPixelSpacing",
|
||||
"Dimension",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Dimension -> VerticalPhysicalPixelSpacing
|
||||
addSingleAttributeElement("VerticalPhysicalPixelSpacing",
|
||||
"Dimension",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Dimension -> HorizontalPosition
|
||||
addSingleAttributeElement("HorizontalPosition",
|
||||
"Dimension",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Dimension -> VerticalPosition
|
||||
addSingleAttributeElement("VerticalPosition",
|
||||
"Dimension",
|
||||
DATATYPE_FLOAT);
|
||||
|
||||
// root -> Dimension -> HorizontalPixelOffset
|
||||
addSingleAttributeElement("HorizontalPixelOffset",
|
||||
"Dimension",
|
||||
DATATYPE_INTEGER);
|
||||
|
||||
// root -> Dimension -> VerticalPixelOffset
|
||||
addSingleAttributeElement("VerticalPixelOffset",
|
||||
"Dimension",
|
||||
DATATYPE_INTEGER);
|
||||
|
||||
// root -> Dimension -> HorizontalScreenSize
|
||||
addSingleAttributeElement("HorizontalScreenSize",
|
||||
"Dimension",
|
||||
DATATYPE_INTEGER);
|
||||
|
||||
// root -> Dimension -> VerticalScreenSize
|
||||
addSingleAttributeElement("VerticalScreenSize",
|
||||
"Dimension",
|
||||
DATATYPE_INTEGER);
|
||||
|
||||
|
||||
// root -> Document
|
||||
addElement("Document", standardMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> Document -> FormatVersion
|
||||
addElement("FormatVersion", "Document",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("FormatVersion", "value",
|
||||
DATATYPE_STRING,
|
||||
true,
|
||||
null);
|
||||
|
||||
// root -> Document -> SubimageInterpretation
|
||||
addElement("SubimageInterpretation", "Document",
|
||||
CHILD_POLICY_EMPTY);
|
||||
values = new ArrayList();
|
||||
values.add("Standalone");
|
||||
values.add("SinglePage");
|
||||
values.add("FullResolution");
|
||||
values.add("ReducedResolution");
|
||||
values.add("PyramidLayer");
|
||||
values.add("Preview");
|
||||
values.add("VolumeSlice");
|
||||
values.add("ObjectView");
|
||||
values.add("Panorama");
|
||||
values.add("AnimationFrame");
|
||||
values.add("TransparencyMask");
|
||||
values.add("CompositingLayer");
|
||||
values.add("SpectralSlice");
|
||||
values.add("Unknown");
|
||||
addAttribute("SubimageInterpretation", "value",
|
||||
DATATYPE_STRING,
|
||||
true,
|
||||
null,
|
||||
values);
|
||||
|
||||
// root -> Document -> ImageCreationTime
|
||||
addElement("ImageCreationTime", "Document",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ImageCreationTime", "year",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null);
|
||||
addAttribute("ImageCreationTime", "month",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"1", "12", true, true);
|
||||
addAttribute("ImageCreationTime", "day",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"1", "31", true, true);
|
||||
addAttribute("ImageCreationTime", "hour",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "23", true, true);
|
||||
addAttribute("ImageCreationTime", "minute",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "59", true, true);
|
||||
// second = 60 denotes leap second
|
||||
addAttribute("ImageCreationTime", "second",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "60", true, true);
|
||||
|
||||
// root -> Document -> ImageModificationTime
|
||||
addElement("ImageModificationTime", "Document",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ImageModificationTime", "year",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null);
|
||||
addAttribute("ImageModificationTime", "month",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"1", "12", true, true);
|
||||
addAttribute("ImageModificationTime", "day",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"1", "31", true, true);
|
||||
addAttribute("ImageModificationTime", "hour",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "23", true, true);
|
||||
addAttribute("ImageModificationTime", "minute",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "59", true, true);
|
||||
// second = 60 denotes leap second
|
||||
addAttribute("ImageModificationTime", "second",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "60", true, true);
|
||||
|
||||
// root -> Text
|
||||
addElement("Text", standardMetadataFormatName,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Text -> TextEntry
|
||||
addElement("TextEntry", "Text", CHILD_POLICY_EMPTY);
|
||||
addAttribute("TextEntry", "keyword",
|
||||
DATATYPE_STRING,
|
||||
false,
|
||||
null);
|
||||
addAttribute("TextEntry", "value",
|
||||
DATATYPE_STRING,
|
||||
true,
|
||||
null);
|
||||
addAttribute("TextEntry", "language",
|
||||
DATATYPE_STRING,
|
||||
false,
|
||||
null);
|
||||
addAttribute("TextEntry", "encoding",
|
||||
DATATYPE_STRING,
|
||||
false,
|
||||
null);
|
||||
|
||||
values = new ArrayList();
|
||||
values.add("none");
|
||||
values.add("lzw");
|
||||
values.add("zip");
|
||||
values.add("bzip");
|
||||
values.add("other");
|
||||
addAttribute("TextEntry", "compression",
|
||||
DATATYPE_STRING,
|
||||
false,
|
||||
"none",
|
||||
values);
|
||||
|
||||
// root -> Transparency
|
||||
addElement("Transparency", standardMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> Transparency -> Alpha
|
||||
addElement("Alpha", "Transparency", CHILD_POLICY_EMPTY);
|
||||
|
||||
values = new ArrayList();
|
||||
values.add("none");
|
||||
values.add("premultiplied");
|
||||
values.add("nonpremultiplied");
|
||||
addAttribute("Alpha", "value",
|
||||
DATATYPE_STRING,
|
||||
false,
|
||||
"none",
|
||||
values);
|
||||
|
||||
// root -> Transparency -> TransparentIndex
|
||||
addSingleAttributeElement("TransparentIndex", "Transparency",
|
||||
DATATYPE_INTEGER);
|
||||
|
||||
// root -> Transparency -> TransparentColor
|
||||
addElement("TransparentColor", "Transparency",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("TransparentColor", "value",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Transparency -> TileTransparencies
|
||||
addElement("TileTransparencies", "Transparency",
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Transparency -> TileTransparencies -> TransparentTile
|
||||
addElement("TransparentTile", "TileTransparencies",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("TransparentTile", "x",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null);
|
||||
addAttribute("TransparentTile", "y",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null);
|
||||
|
||||
// root -> Transparency -> TileOpacities
|
||||
addElement("TileOpacities", "Transparency",
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> Transparency -> TileOpacities -> OpaqueTile
|
||||
addElement("OpaqueTile", "TileOpacities",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("OpaqueTile", "x",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null);
|
||||
addAttribute("OpaqueTile", "y",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null);
|
||||
}
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class StandardMetadataFormatResources extends ListResourceBundle {
|
||||
|
||||
public StandardMetadataFormatResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
|
||||
// Node name, followed by description, or
|
||||
// Node name + "/" + AttributeName, followed by description
|
||||
|
||||
{ "Chroma", "Chroma (color) information" },
|
||||
|
||||
{ "ColorSpaceType", "The raw color space of the image" },
|
||||
|
||||
{ "NumChannels",
|
||||
"The number of channels in the raw image, including alpha" },
|
||||
|
||||
{ "Gamma", "The image gamma" },
|
||||
|
||||
{ "BlackIsZero",
|
||||
"True if smaller values represent darker shades"},
|
||||
|
||||
{ "Palette", "Palette-color information" },
|
||||
|
||||
{ "PaletteEntry", "A palette entry" },
|
||||
{ "PaletteEntry/index", "The index of the palette entry" },
|
||||
{ "PaletteEntry/red", "The red value for the palette entry" },
|
||||
{ "PaletteEntry/green", "The green value for the palette entry" },
|
||||
{ "PaletteEntry/blue", "The blue value for the palette entry" },
|
||||
{ "PaletteEntry/alpha", "The alpha value for the palette entry" },
|
||||
|
||||
{ "BackgroundIndex", "A palette index to be used as a background" },
|
||||
|
||||
{ "BackgroundColor", "An RGB triple to be used as a background" },
|
||||
{ "BackgroundColor/red", "The red background value" },
|
||||
{ "BackgroundColor/green", "The green background value" },
|
||||
{ "BackgroundColor/blue", "The blue background value" },
|
||||
|
||||
{ "Compression", "Compression information" },
|
||||
|
||||
{ "CompressionTypeName", "The name of the compression scheme in use" },
|
||||
|
||||
{ "Lossless",
|
||||
"True if the compression scheme is lossless" },
|
||||
|
||||
{ "BitRate", "The estimated bit rate of the compression scheme" },
|
||||
|
||||
{ "NumProgressiveScans",
|
||||
"The number of progressive scans used in the image encoding"},
|
||||
|
||||
{ "Data", "Information on the image layout" },
|
||||
|
||||
{ "PlanarConfiguration",
|
||||
"The organization of image samples in the stream" },
|
||||
|
||||
{ "SampleFormat", "The numeric format of image samples" },
|
||||
|
||||
{ "BitsPerSample", "The number of bits per sample"},
|
||||
{ "BitsPerSample/value",
|
||||
"A list of integers, one per channel" },
|
||||
|
||||
{ "SignificantBitsPerSample",
|
||||
"The number of significant bits per sample"},
|
||||
{ "SignificantBitsPerSample/value",
|
||||
"A list of integers, one per channel" },
|
||||
|
||||
{ "SampleMSB",
|
||||
"The position of the most significant bit of each sample"},
|
||||
{ "SampleMSB/value",
|
||||
"A list of integers, one per channel" },
|
||||
|
||||
{ "Dimension", "Dimension information" },
|
||||
|
||||
{ "PixelAspectRatio", "The width of a pixel divided by its height" },
|
||||
|
||||
{ "ImageOrientation", "The desired orientation of the image in terms of flips and counter-clockwise rotations" },
|
||||
|
||||
{ "HorizontalPixelSize",
|
||||
"The width of a pixel, in millimeters, as it should be rendered on media" },
|
||||
|
||||
{ "VerticalPixelSize",
|
||||
"The height of a pixel, in millimeters, as it should be rendered on media" },
|
||||
|
||||
{ "HorizontalPhysicalPixelSpacing",
|
||||
"The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image" },
|
||||
|
||||
{ "VerticalPhysicalPixelSpacing",
|
||||
"The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image" },
|
||||
|
||||
{ "HorizontalPosition",
|
||||
"The horizontal position, in millimeters, where the image should be rendered on media " },
|
||||
|
||||
{ "VerticalPosition",
|
||||
"The vertical position, in millimeters, where the image should be rendered on media " },
|
||||
|
||||
{ "HorizontalPixelOffset",
|
||||
"The horizontal position, in pixels, where the image should be rendered onto a raster display" },
|
||||
|
||||
{ "VerticalPixelOffset",
|
||||
"The vertical position, in pixels, where the image should be rendered onto a raster display" },
|
||||
|
||||
{ "HorizontalScreenSize",
|
||||
"The width, in pixels, of the raster display into which the image should be rendered" },
|
||||
|
||||
{ "VerticalScreenSize",
|
||||
"The height, in pixels, of the raster display into which the image should be rendered" },
|
||||
|
||||
{ "Document", "Document information" },
|
||||
|
||||
{ "FormatVersion",
|
||||
"The version of the format used by the stream" },
|
||||
|
||||
{ "SubimageInterpretation",
|
||||
"The interpretation of this image in relation to the other images stored in the same stream" },
|
||||
|
||||
{ "ImageCreationTime", "The time of image creation" },
|
||||
{ "ImageCreationTime/year",
|
||||
"The full year (e.g., 1967, not 67)" },
|
||||
{ "ImageCreationTime/month",
|
||||
"The month, with January = 1" },
|
||||
{ "ImageCreationTime/day",
|
||||
"The day of the month" },
|
||||
{ "ImageCreationTime/hour",
|
||||
"The hour from 0 to 23" },
|
||||
{ "ImageCreationTime/minute",
|
||||
"The minute from 0 to 59" },
|
||||
{ "ImageCreationTime/second",
|
||||
"The second from 0 to 60 (60 = leap second)" },
|
||||
|
||||
{ "ImageModificationTime", "The time of the last image modification" },
|
||||
{ "ImageModificationTime/year",
|
||||
"The full year (e.g., 1967, not 67)" },
|
||||
{ "ImageModificationTime/month",
|
||||
"The month, with January = 1" },
|
||||
{ "ImageModificationTime/day",
|
||||
"The day of the month" },
|
||||
{ "ImageModificationTime/hour",
|
||||
"The hour from 0 to 23" },
|
||||
{ "ImageModificationTime/minute",
|
||||
"The minute from 0 to 59" },
|
||||
{ "ImageModificationTime/second",
|
||||
"The second from 0 to 60 (60 = leap second)" },
|
||||
|
||||
{ "Text", "Text information" },
|
||||
|
||||
{ "TextEntry", "A text entry"},
|
||||
{ "TextEntry/keyword", "A keyword associated with the text entry" },
|
||||
{ "TextEntry/value", "the text entry" },
|
||||
{ "TextEntry/language", "The language of the text" },
|
||||
{ "TextEntry/encoding", "The encoding of the text" },
|
||||
{ "TextEntry/compression", "The method used to compress the text" },
|
||||
|
||||
{ "Transparency", "Transparency information" },
|
||||
|
||||
{ "Alpha", "The type of alpha information contained in the image" },
|
||||
|
||||
{ "TransparentIndex", "A palette index to be treated as transparent" },
|
||||
|
||||
{ "TransparentColor", "An RGB color to be treated as transparent" },
|
||||
{ "TransparentColor/red",
|
||||
"The red channel of the transparent color" },
|
||||
{ "TransparentColor/green",
|
||||
"The green channel of the transparent color" },
|
||||
{ "TransparentColor/blue",
|
||||
"The blue channel of the transparent color" },
|
||||
|
||||
{ "TileTransparencies", "A list of completely transparent tiles" },
|
||||
|
||||
{ "TransparentTile", "The index of a completely transparent tile" },
|
||||
{ "TransparentTile/x", "The tile's X index" },
|
||||
{ "TransparentTile/y", "The tile's Y index" },
|
||||
|
||||
{ "TileOpacities", "A list of completely opaque tiles" },
|
||||
|
||||
{ "OpaqueTile", "The index of a completely opaque tile" },
|
||||
{ "OpaqueTile/x", "The tile's X index" },
|
||||
{ "OpaqueTile/y", "The tile's Y index" },
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageInputStreamImpl;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
public final class SubImageInputStream extends ImageInputStreamImpl {
|
||||
|
||||
ImageInputStream stream;
|
||||
long startingPos;
|
||||
int startingLength;
|
||||
int length;
|
||||
|
||||
public SubImageInputStream(ImageInputStream stream, int length)
|
||||
throws IOException {
|
||||
this.stream = stream;
|
||||
this.startingPos = stream.getStreamPosition();
|
||||
this.startingLength = this.length = length;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (length == 0) { // Local EOF
|
||||
return -1;
|
||||
} else {
|
||||
--length;
|
||||
return stream.read();
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (length == 0) { // Local EOF
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = Math.min(len, length);
|
||||
int bytes = stream.read(b, off, len);
|
||||
length -= bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public long length() {
|
||||
return startingLength;
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
stream.seek(pos - startingPos);
|
||||
streamPos = pos;
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
// Empty finalizer (for improved performance; no need to call
|
||||
// super.finalize() in this case)
|
||||
}
|
||||
}
|
||||
446
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageMetadata.java
Normal file
446
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageMetadata.java
Normal file
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
public class GIFImageMetadata extends GIFMetadata {
|
||||
|
||||
// package scope
|
||||
static final String
|
||||
nativeMetadataFormatName = "javax_imageio_gif_image_1.0";
|
||||
|
||||
static final String[] disposalMethodNames = {
|
||||
"none",
|
||||
"doNotDispose",
|
||||
"restoreToBackgroundColor",
|
||||
"restoreToPrevious",
|
||||
"undefinedDisposalMethod4",
|
||||
"undefinedDisposalMethod5",
|
||||
"undefinedDisposalMethod6",
|
||||
"undefinedDisposalMethod7"
|
||||
};
|
||||
|
||||
// Fields from Image Descriptor
|
||||
public int imageLeftPosition;
|
||||
public int imageTopPosition;
|
||||
public int imageWidth;
|
||||
public int imageHeight;
|
||||
public boolean interlaceFlag = false;
|
||||
public boolean sortFlag = false;
|
||||
public byte[] localColorTable = null;
|
||||
|
||||
// Fields from Graphic Control Extension
|
||||
public int disposalMethod = 0;
|
||||
public boolean userInputFlag = false;
|
||||
public boolean transparentColorFlag = false;
|
||||
public int delayTime = 0;
|
||||
public int transparentColorIndex = 0;
|
||||
|
||||
// Fields from Plain Text Extension
|
||||
public boolean hasPlainTextExtension = false;
|
||||
public int textGridLeft;
|
||||
public int textGridTop;
|
||||
public int textGridWidth;
|
||||
public int textGridHeight;
|
||||
public int characterCellWidth;
|
||||
public int characterCellHeight;
|
||||
public int textForegroundColor;
|
||||
public int textBackgroundColor;
|
||||
public byte[] text;
|
||||
|
||||
// Fields from ApplicationExtension
|
||||
// List of byte[]
|
||||
public List applicationIDs = null; // new ArrayList();
|
||||
|
||||
// List of byte[]
|
||||
public List authenticationCodes = null; // new ArrayList();
|
||||
|
||||
// List of byte[]
|
||||
public List applicationData = null; // new ArrayList();
|
||||
|
||||
// Fields from CommentExtension
|
||||
// List of byte[]
|
||||
public List comments = null; // new ArrayList();
|
||||
|
||||
protected GIFImageMetadata(boolean standardMetadataFormatSupported,
|
||||
String nativeMetadataFormatName,
|
||||
String nativeMetadataFormatClassName,
|
||||
String[] extraMetadataFormatNames,
|
||||
String[] extraMetadataFormatClassNames)
|
||||
{
|
||||
super(standardMetadataFormatSupported,
|
||||
nativeMetadataFormatName,
|
||||
nativeMetadataFormatClassName,
|
||||
extraMetadataFormatNames,
|
||||
extraMetadataFormatClassNames);
|
||||
}
|
||||
|
||||
public GIFImageMetadata() {
|
||||
this(true,
|
||||
nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.gif.GIFImageMetadataFormat",
|
||||
null, null);
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Node getAsTree(String formatName) {
|
||||
if (formatName.equals(nativeMetadataFormatName)) {
|
||||
return getNativeTree();
|
||||
} else if (formatName.equals
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
return getStandardTree();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not a recognized format!");
|
||||
}
|
||||
}
|
||||
|
||||
private String toISO8859(byte[] data) {
|
||||
try {
|
||||
return new String(data, "ISO-8859-1");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private Node getNativeTree() {
|
||||
IIOMetadataNode node; // scratch node
|
||||
IIOMetadataNode root =
|
||||
new IIOMetadataNode(nativeMetadataFormatName);
|
||||
|
||||
// Image descriptor
|
||||
node = new IIOMetadataNode("ImageDescriptor");
|
||||
node.setAttribute("imageLeftPosition",
|
||||
Integer.toString(imageLeftPosition));
|
||||
node.setAttribute("imageTopPosition",
|
||||
Integer.toString(imageTopPosition));
|
||||
node.setAttribute("imageWidth", Integer.toString(imageWidth));
|
||||
node.setAttribute("imageHeight", Integer.toString(imageHeight));
|
||||
node.setAttribute("interlaceFlag",
|
||||
interlaceFlag ? "TRUE" : "FALSE");
|
||||
root.appendChild(node);
|
||||
|
||||
// Local color table
|
||||
if (localColorTable != null) {
|
||||
node = new IIOMetadataNode("LocalColorTable");
|
||||
int numEntries = localColorTable.length/3;
|
||||
node.setAttribute("sizeOfLocalColorTable",
|
||||
Integer.toString(numEntries));
|
||||
node.setAttribute("sortFlag",
|
||||
sortFlag ? "TRUE" : "FALSE");
|
||||
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
IIOMetadataNode entry =
|
||||
new IIOMetadataNode("ColorTableEntry");
|
||||
entry.setAttribute("index", Integer.toString(i));
|
||||
int r = localColorTable[3*i] & 0xff;
|
||||
int g = localColorTable[3*i + 1] & 0xff;
|
||||
int b = localColorTable[3*i + 2] & 0xff;
|
||||
entry.setAttribute("red", Integer.toString(r));
|
||||
entry.setAttribute("green", Integer.toString(g));
|
||||
entry.setAttribute("blue", Integer.toString(b));
|
||||
node.appendChild(entry);
|
||||
}
|
||||
root.appendChild(node);
|
||||
}
|
||||
|
||||
// Graphic control extension
|
||||
node = new IIOMetadataNode("GraphicControlExtension");
|
||||
node.setAttribute("disposalMethod",
|
||||
disposalMethodNames[disposalMethod]);
|
||||
node.setAttribute("userInputFlag",
|
||||
userInputFlag ? "TRUE" : "FALSE");
|
||||
node.setAttribute("transparentColorFlag",
|
||||
transparentColorFlag ? "TRUE" : "FALSE");
|
||||
node.setAttribute("delayTime",
|
||||
Integer.toString(delayTime));
|
||||
node.setAttribute("transparentColorIndex",
|
||||
Integer.toString(transparentColorIndex));
|
||||
root.appendChild(node);
|
||||
|
||||
if (hasPlainTextExtension) {
|
||||
node = new IIOMetadataNode("PlainTextExtension");
|
||||
node.setAttribute("textGridLeft",
|
||||
Integer.toString(textGridLeft));
|
||||
node.setAttribute("textGridTop",
|
||||
Integer.toString(textGridTop));
|
||||
node.setAttribute("textGridWidth",
|
||||
Integer.toString(textGridWidth));
|
||||
node.setAttribute("textGridHeight",
|
||||
Integer.toString(textGridHeight));
|
||||
node.setAttribute("characterCellWidth",
|
||||
Integer.toString(characterCellWidth));
|
||||
node.setAttribute("characterCellHeight",
|
||||
Integer.toString(characterCellHeight));
|
||||
node.setAttribute("textForegroundColor",
|
||||
Integer.toString(textForegroundColor));
|
||||
node.setAttribute("textBackgroundColor",
|
||||
Integer.toString(textBackgroundColor));
|
||||
node.setAttribute("text", toISO8859(text));
|
||||
|
||||
root.appendChild(node);
|
||||
}
|
||||
|
||||
// Application extensions
|
||||
int numAppExtensions = applicationIDs == null ?
|
||||
0 : applicationIDs.size();
|
||||
if (numAppExtensions > 0) {
|
||||
node = new IIOMetadataNode("ApplicationExtensions");
|
||||
for (int i = 0; i < numAppExtensions; i++) {
|
||||
IIOMetadataNode appExtNode =
|
||||
new IIOMetadataNode("ApplicationExtension");
|
||||
byte[] applicationID = (byte[])applicationIDs.get(i);
|
||||
appExtNode.setAttribute("applicationID",
|
||||
toISO8859(applicationID));
|
||||
byte[] authenticationCode = (byte[])authenticationCodes.get(i);
|
||||
appExtNode.setAttribute("authenticationCode",
|
||||
toISO8859(authenticationCode));
|
||||
byte[] appData = (byte[])applicationData.get(i);
|
||||
appExtNode.setUserObject((byte[])appData.clone());
|
||||
node.appendChild(appExtNode);
|
||||
}
|
||||
|
||||
root.appendChild(node);
|
||||
}
|
||||
|
||||
// Comment extensions
|
||||
int numComments = comments == null ? 0 : comments.size();
|
||||
if (numComments > 0) {
|
||||
node = new IIOMetadataNode("CommentExtensions");
|
||||
for (int i = 0; i < numComments; i++) {
|
||||
IIOMetadataNode commentNode =
|
||||
new IIOMetadataNode("CommentExtension");
|
||||
byte[] comment = (byte[])comments.get(i);
|
||||
commentNode.setAttribute("value", toISO8859(comment));
|
||||
node.appendChild(commentNode);
|
||||
}
|
||||
|
||||
root.appendChild(node);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardChromaNode() {
|
||||
IIOMetadataNode chroma_node = new IIOMetadataNode("Chroma");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
node = new IIOMetadataNode("ColorSpaceType");
|
||||
node.setAttribute("name", "RGB");
|
||||
chroma_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("NumChannels");
|
||||
node.setAttribute("value", transparentColorFlag ? "4" : "3");
|
||||
chroma_node.appendChild(node);
|
||||
|
||||
// Gamma not in format
|
||||
|
||||
node = new IIOMetadataNode("BlackIsZero");
|
||||
node.setAttribute("value", "TRUE");
|
||||
chroma_node.appendChild(node);
|
||||
|
||||
if (localColorTable != null) {
|
||||
node = new IIOMetadataNode("Palette");
|
||||
int numEntries = localColorTable.length/3;
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
IIOMetadataNode entry =
|
||||
new IIOMetadataNode("PaletteEntry");
|
||||
entry.setAttribute("index", Integer.toString(i));
|
||||
entry.setAttribute("red",
|
||||
Integer.toString(localColorTable[3*i] & 0xff));
|
||||
entry.setAttribute("green",
|
||||
Integer.toString(localColorTable[3*i + 1] & 0xff));
|
||||
entry.setAttribute("blue",
|
||||
Integer.toString(localColorTable[3*i + 2] & 0xff));
|
||||
node.appendChild(entry);
|
||||
}
|
||||
chroma_node.appendChild(node);
|
||||
}
|
||||
|
||||
// BackgroundIndex not in image
|
||||
// BackgroundColor not in format
|
||||
|
||||
return chroma_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardCompressionNode() {
|
||||
IIOMetadataNode compression_node = new IIOMetadataNode("Compression");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
node = new IIOMetadataNode("CompressionTypeName");
|
||||
node.setAttribute("value", "lzw");
|
||||
compression_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("Lossless");
|
||||
node.setAttribute("value", "TRUE");
|
||||
compression_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("NumProgressiveScans");
|
||||
node.setAttribute("value", interlaceFlag ? "4" : "1");
|
||||
compression_node.appendChild(node);
|
||||
|
||||
// BitRate not in format
|
||||
|
||||
return compression_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardDataNode() {
|
||||
IIOMetadataNode data_node = new IIOMetadataNode("Data");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
// PlanarConfiguration not in format
|
||||
|
||||
node = new IIOMetadataNode("SampleFormat");
|
||||
node.setAttribute("value", "Index");
|
||||
data_node.appendChild(node);
|
||||
|
||||
// BitsPerSample not in image
|
||||
// SignificantBitsPerSample not in format
|
||||
// SampleMSB not in format
|
||||
|
||||
return data_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardDimensionNode() {
|
||||
IIOMetadataNode dimension_node = new IIOMetadataNode("Dimension");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
// PixelAspectRatio not in image
|
||||
|
||||
node = new IIOMetadataNode("ImageOrientation");
|
||||
node.setAttribute("value", "Normal");
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
// HorizontalPixelSize not in format
|
||||
// VerticalPixelSize not in format
|
||||
// HorizontalPhysicalPixelSpacing not in format
|
||||
// VerticalPhysicalPixelSpacing not in format
|
||||
// HorizontalPosition not in format
|
||||
// VerticalPosition not in format
|
||||
|
||||
node = new IIOMetadataNode("HorizontalPixelOffset");
|
||||
node.setAttribute("value", Integer.toString(imageLeftPosition));
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("VerticalPixelOffset");
|
||||
node.setAttribute("value", Integer.toString(imageTopPosition));
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
// HorizontalScreenSize not in image
|
||||
// VerticalScreenSize not in image
|
||||
|
||||
return dimension_node;
|
||||
}
|
||||
|
||||
// Document not in image
|
||||
|
||||
public IIOMetadataNode getStandardTextNode() {
|
||||
if (comments == null) {
|
||||
return null;
|
||||
}
|
||||
Iterator commentIter = comments.iterator();
|
||||
if (!commentIter.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IIOMetadataNode text_node = new IIOMetadataNode("Text");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
while (commentIter.hasNext()) {
|
||||
byte[] comment = (byte[])commentIter.next();
|
||||
String s = null;
|
||||
try {
|
||||
s = new String(comment, "ISO-8859-1");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("Encoding ISO-8859-1 unknown!");
|
||||
}
|
||||
|
||||
node = new IIOMetadataNode("TextEntry");
|
||||
node.setAttribute("value", s);
|
||||
node.setAttribute("encoding", "ISO-8859-1");
|
||||
node.setAttribute("compression", "none");
|
||||
text_node.appendChild(node);
|
||||
}
|
||||
|
||||
return text_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardTransparencyNode() {
|
||||
if (!transparentColorFlag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IIOMetadataNode transparency_node =
|
||||
new IIOMetadataNode("Transparency");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
// Alpha not in format
|
||||
|
||||
node = new IIOMetadataNode("TransparentIndex");
|
||||
node.setAttribute("value",
|
||||
Integer.toString(transparentColorIndex));
|
||||
transparency_node.appendChild(node);
|
||||
|
||||
// TransparentColor not in format
|
||||
// TileTransparencies not in format
|
||||
// TileOpacities not in format
|
||||
|
||||
return transparency_node;
|
||||
}
|
||||
|
||||
public void setFromTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException
|
||||
{
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
|
||||
protected void mergeNativeTree(Node root) throws IIOInvalidTreeException
|
||||
{
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
|
||||
protected void mergeStandardTree(Node root) throws IIOInvalidTreeException
|
||||
{
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class GIFImageMetadataFormat extends IIOMetadataFormatImpl {
|
||||
|
||||
private static IIOMetadataFormat instance = null;
|
||||
|
||||
private GIFImageMetadataFormat() {
|
||||
super(GIFImageMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> ImageDescriptor
|
||||
addElement("ImageDescriptor",
|
||||
GIFImageMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ImageDescriptor", "imageLeftPosition",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("ImageDescriptor", "imageTopPosition",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("ImageDescriptor", "imageWidth",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("ImageDescriptor", "imageHeight",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addBooleanAttribute("ImageDescriptor", "interlaceFlag",
|
||||
false, false);
|
||||
|
||||
// root -> LocalColorTable
|
||||
addElement("LocalColorTable",
|
||||
GIFImageMetadata.nativeMetadataFormatName,
|
||||
2, 256);
|
||||
addAttribute("LocalColorTable", "sizeOfLocalColorTable",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
Arrays.asList(GIFStreamMetadata.colorTableSizes));
|
||||
addBooleanAttribute("LocalColorTable", "sortFlag",
|
||||
false, false);
|
||||
|
||||
// root -> LocalColorTable -> ColorTableEntry
|
||||
addElement("ColorTableEntry", "LocalColorTable",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ColorTableEntry", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("ColorTableEntry", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("ColorTableEntry", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("ColorTableEntry", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
|
||||
// root -> GraphicControlExtension
|
||||
addElement("GraphicControlExtension",
|
||||
GIFImageMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("GraphicControlExtension", "disposalMethod",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(GIFImageMetadata.disposalMethodNames));
|
||||
addBooleanAttribute("GraphicControlExtension", "userInputFlag",
|
||||
false, false);
|
||||
addBooleanAttribute("GraphicControlExtension", "transparentColorFlag",
|
||||
false, false);
|
||||
addAttribute("GraphicControlExtension", "delayTime",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("GraphicControlExtension", "transparentColorIndex",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
|
||||
// root -> PlainTextExtension
|
||||
addElement("PlainTextExtension",
|
||||
GIFImageMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("PlainTextExtension", "textGridLeft",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("PlainTextExtension", "textGridTop",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("PlainTextExtension", "textGridWidth",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("PlainTextExtension", "textGridHeight",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("PlainTextExtension", "characterCellWidth",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("PlainTextExtension", "characterCellHeight",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("PlainTextExtension", "textForegroundColor",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("PlainTextExtension", "textBackgroundColor",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
|
||||
// root -> ApplicationExtensions
|
||||
addElement("ApplicationExtensions",
|
||||
GIFImageMetadata.nativeMetadataFormatName,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> ApplicationExtensions -> ApplicationExtension
|
||||
addElement("ApplicationExtension", "ApplicationExtensions",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ApplicationExtension", "applicationID",
|
||||
DATATYPE_STRING, true, null);
|
||||
addAttribute("ApplicationExtension", "authenticationCode",
|
||||
DATATYPE_STRING, true, null);
|
||||
addObjectValue("ApplicationExtension", byte.class,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> CommentExtensions
|
||||
addElement("CommentExtensions",
|
||||
GIFImageMetadata.nativeMetadataFormatName,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> CommentExtensions -> CommentExtension
|
||||
addElement("CommentExtension", "CommentExtensions",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("CommentExtension", "value",
|
||||
DATATYPE_STRING, true, null);
|
||||
}
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static synchronized IIOMetadataFormat getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new GIFImageMetadataFormat();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class GIFImageMetadataFormatResources extends ListResourceBundle {
|
||||
|
||||
public GIFImageMetadataFormatResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
|
||||
// Node name, followed by description
|
||||
{ "ImageDescriptor", "The image descriptor" },
|
||||
{ "LocalColorTable", "The local color table" },
|
||||
{ "ColorTableEntry", "A local color table entry" },
|
||||
{ "GraphicControlExtension", "A graphic control extension" },
|
||||
{ "PlainTextExtension", "A plain text (text grid) extension" },
|
||||
{ "ApplicationExtensions", "A set of application extensions" },
|
||||
{ "ApplicationExtension", "An application extension" },
|
||||
{ "CommentExtensions", "A set of comments" },
|
||||
{ "CommentExtension", "A comment" },
|
||||
|
||||
// Node name + "/" + AttributeName, followed by description
|
||||
{ "ImageDescriptor/imageLeftPosition",
|
||||
"The X offset of the image relative to the screen origin" },
|
||||
{ "ImageDescriptor/imageTopPosition",
|
||||
"The Y offset of the image relative to the screen origin" },
|
||||
{ "ImageDescriptor/imageWidth",
|
||||
"The width of the image" },
|
||||
{ "ImageDescriptor/imageHeight",
|
||||
"The height of the image" },
|
||||
{ "ImageDescriptor/interlaceFlag",
|
||||
"True if the image is stored using interlacing" },
|
||||
{ "LocalColorTable/sizeOfLocalColorTable",
|
||||
"The number of entries in the local color table" },
|
||||
{ "LocalColorTable/sortFlag",
|
||||
"True if the local color table is sorted by frequency" },
|
||||
{ "ColorTableEntry/index", "The index of the color table entry" },
|
||||
{ "ColorTableEntry/red",
|
||||
"The red value for the color table entry" },
|
||||
{ "ColorTableEntry/green",
|
||||
"The green value for the color table entry" },
|
||||
{ "ColorTableEntry/blue",
|
||||
"The blue value for the color table entry" },
|
||||
{ "GraphicControlExtension/disposalMethod",
|
||||
"The disposal method for this frame" },
|
||||
{ "GraphicControlExtension/userInputFlag",
|
||||
"True if the frame should be advanced based on user input" },
|
||||
{ "GraphicControlExtension/transparentColorFlag",
|
||||
"True if a transparent color exists" },
|
||||
{ "GraphicControlExtension/delayTime",
|
||||
"The time to delay between frames, in hundredths of a second" },
|
||||
{ "GraphicControlExtension/transparentColorIndex",
|
||||
"The transparent color, if transparentColorFlag is true" },
|
||||
{ "PlainTextExtension/textGridLeft",
|
||||
"The X offset of the text grid" },
|
||||
{ "PlainTextExtension/textGridTop",
|
||||
"The Y offset of the text grid" },
|
||||
{ "PlainTextExtension/textGridWidth",
|
||||
"The number of columns in the text grid" },
|
||||
{ "PlainTextExtension/textGridHeight",
|
||||
"The number of rows in the text grid" },
|
||||
{ "PlainTextExtension/characterCellWidth",
|
||||
"The width of a character cell" },
|
||||
{ "PlainTextExtension/characterCellHeight",
|
||||
"The height of a character cell" },
|
||||
{ "PlainTextExtension/textForegroundColor",
|
||||
"The text foreground color index" },
|
||||
{ "PlainTextExtension/textBackgroundColor",
|
||||
"The text background color index" },
|
||||
{ "ApplicationExtension/applicationID",
|
||||
"The application ID" },
|
||||
{ "ApplicationExtension/authenticationCode",
|
||||
"The authentication code" },
|
||||
{ "CommentExtension/value", "The comment" },
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
1090
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageReader.java
Normal file
1090
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageReader.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Iterator;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
public class GIFImageReaderSpi extends ImageReaderSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final String[] names = { "gif", "GIF" };
|
||||
|
||||
private static final String[] suffixes = { "gif" };
|
||||
|
||||
private static final String[] MIMETypes = { "image/gif" };
|
||||
|
||||
private static final String readerClassName =
|
||||
"com.sun.imageio.plugins.gif.GIFImageReader";
|
||||
|
||||
private static final String[] writerSpiNames = {
|
||||
"com.sun.imageio.plugins.gif.GIFImageWriterSpi"
|
||||
};
|
||||
|
||||
public GIFImageReaderSpi() {
|
||||
super(vendorName,
|
||||
version,
|
||||
names,
|
||||
suffixes,
|
||||
MIMETypes,
|
||||
readerClassName,
|
||||
new Class[] { ImageInputStream.class },
|
||||
writerSpiNames,
|
||||
true,
|
||||
GIFStreamMetadata.nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.gif.GIFStreamMetadataFormat",
|
||||
null, null,
|
||||
true,
|
||||
GIFImageMetadata.nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.gif.GIFImageMetadataFormat",
|
||||
null, null
|
||||
);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard GIF image reader";
|
||||
}
|
||||
|
||||
public boolean canDecodeInput(Object input) throws IOException {
|
||||
if (!(input instanceof ImageInputStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageInputStream stream = (ImageInputStream)input;
|
||||
byte[] b = new byte[6];
|
||||
stream.mark();
|
||||
stream.readFully(b);
|
||||
stream.reset();
|
||||
|
||||
return b[0] == 'G' && b[1] == 'I' && b[2] == 'F' && b[3] == '8' &&
|
||||
(b[4] == '7' || b[4] == '9') && b[5] == 'a';
|
||||
}
|
||||
|
||||
public ImageReader createReaderInstance(Object extension) {
|
||||
return new GIFImageReader(this);
|
||||
}
|
||||
|
||||
}
|
||||
1317
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageWriter.java
Normal file
1317
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageWriter.java
Normal file
File diff suppressed because it is too large
Load Diff
104
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java
Normal file
104
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import com.sun.imageio.plugins.common.PaletteBuilder;
|
||||
|
||||
public class GIFImageWriterSpi extends ImageWriterSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final String[] names = { "gif", "GIF" };
|
||||
|
||||
private static final String[] suffixes = { "gif" };
|
||||
|
||||
private static final String[] MIMETypes = { "image/gif" };
|
||||
|
||||
private static final String writerClassName =
|
||||
"com.sun.imageio.plugins.gif.GIFImageWriter";
|
||||
|
||||
private static final String[] readerSpiNames = {
|
||||
"com.sun.imageio.plugins.gif.GIFImageReaderSpi"
|
||||
};
|
||||
|
||||
public GIFImageWriterSpi() {
|
||||
super(vendorName,
|
||||
version,
|
||||
names,
|
||||
suffixes,
|
||||
MIMETypes,
|
||||
writerClassName,
|
||||
new Class[] { ImageOutputStream.class },
|
||||
readerSpiNames,
|
||||
true,
|
||||
GIFWritableStreamMetadata.NATIVE_FORMAT_NAME,
|
||||
"com.sun.imageio.plugins.gif.GIFStreamMetadataFormat",
|
||||
null, null,
|
||||
true,
|
||||
GIFWritableImageMetadata.NATIVE_FORMAT_NAME,
|
||||
"com.sun.imageio.plugins.gif.GIFImageMetadataFormat",
|
||||
null, null
|
||||
);
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(ImageTypeSpecifier type) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type == null!");
|
||||
}
|
||||
|
||||
SampleModel sm = type.getSampleModel();
|
||||
ColorModel cm = type.getColorModel();
|
||||
|
||||
boolean canEncode = sm.getNumBands() == 1 &&
|
||||
sm.getSampleSize(0) <= 8 &&
|
||||
sm.getWidth() <= 65535 &&
|
||||
sm.getHeight() <= 65535 &&
|
||||
(cm == null || cm.getComponentSize()[0] <= 8);
|
||||
|
||||
if (canEncode) {
|
||||
return true;
|
||||
} else {
|
||||
return PaletteBuilder.canCreatePalette(type);
|
||||
}
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard GIF image writer";
|
||||
}
|
||||
|
||||
public ImageWriter createWriterInstance(Object extension) {
|
||||
return new GIFImageWriter(this);
|
||||
}
|
||||
}
|
||||
317
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFMetadata.java
Normal file
317
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFMetadata.java
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Class which adds utility DOM element attribute access methods to
|
||||
* <code>IIOMetadata</code> for subclass use.
|
||||
*/
|
||||
abstract class GIFMetadata extends IIOMetadata {
|
||||
|
||||
/**
|
||||
* Represents an undefined value of integer attributes.
|
||||
*/
|
||||
static final int UNDEFINED_INTEGER_VALUE = -1;
|
||||
|
||||
//
|
||||
// Note: These attribute methods were shamelessly lifted from
|
||||
// com.sun.imageio.plugins.png.PNGMetadata and modified.
|
||||
//
|
||||
|
||||
// Shorthand for throwing an IIOInvalidTreeException
|
||||
protected static void fatal(Node node, String reason)
|
||||
throws IIOInvalidTreeException {
|
||||
throw new IIOInvalidTreeException(reason, node);
|
||||
}
|
||||
|
||||
// Get an integer-valued attribute
|
||||
protected static String getStringAttribute(Node node, String name,
|
||||
String defaultValue,
|
||||
boolean required,
|
||||
String[] range)
|
||||
throws IIOInvalidTreeException {
|
||||
Node attr = node.getAttributes().getNamedItem(name);
|
||||
if (attr == null) {
|
||||
if (!required) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
fatal(node, "Required attribute " + name + " not present!");
|
||||
}
|
||||
}
|
||||
String value = attr.getNodeValue();
|
||||
|
||||
if (range != null) {
|
||||
if (value == null) {
|
||||
fatal(node,
|
||||
"Null value for "+node.getNodeName()+
|
||||
" attribute "+name+"!");
|
||||
}
|
||||
boolean validValue = false;
|
||||
int len = range.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (value.equals(range[i])) {
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!validValue) {
|
||||
fatal(node,
|
||||
"Bad value for "+node.getNodeName()+
|
||||
" attribute "+name+"!");
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// Get an integer-valued attribute
|
||||
protected static int getIntAttribute(Node node, String name,
|
||||
int defaultValue, boolean required,
|
||||
boolean bounded, int min, int max)
|
||||
throws IIOInvalidTreeException {
|
||||
String value = getStringAttribute(node, name, null, required, null);
|
||||
if (value == null || "".equals(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
int intValue = defaultValue;
|
||||
try {
|
||||
intValue = Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
fatal(node,
|
||||
"Bad value for "+node.getNodeName()+
|
||||
" attribute "+name+"!");
|
||||
}
|
||||
if (bounded && (intValue < min || intValue > max)) {
|
||||
fatal(node,
|
||||
"Bad value for "+node.getNodeName()+
|
||||
" attribute "+name+"!");
|
||||
}
|
||||
return intValue;
|
||||
}
|
||||
|
||||
// Get a float-valued attribute
|
||||
protected static float getFloatAttribute(Node node, String name,
|
||||
float defaultValue,
|
||||
boolean required)
|
||||
throws IIOInvalidTreeException {
|
||||
String value = getStringAttribute(node, name, null, required, null);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Float.parseFloat(value);
|
||||
}
|
||||
|
||||
// Get a required integer-valued attribute
|
||||
protected static int getIntAttribute(Node node, String name,
|
||||
boolean bounded, int min, int max)
|
||||
throws IIOInvalidTreeException {
|
||||
return getIntAttribute(node, name, -1, true, bounded, min, max);
|
||||
}
|
||||
|
||||
// Get a required float-valued attribute
|
||||
protected static float getFloatAttribute(Node node, String name)
|
||||
throws IIOInvalidTreeException {
|
||||
return getFloatAttribute(node, name, -1.0F, true);
|
||||
}
|
||||
|
||||
// Get a boolean-valued attribute
|
||||
protected static boolean getBooleanAttribute(Node node, String name,
|
||||
boolean defaultValue,
|
||||
boolean required)
|
||||
throws IIOInvalidTreeException {
|
||||
Node attr = node.getAttributes().getNamedItem(name);
|
||||
if (attr == null) {
|
||||
if (!required) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
fatal(node, "Required attribute " + name + " not present!");
|
||||
}
|
||||
}
|
||||
String value = attr.getNodeValue();
|
||||
// Allow lower case booleans for backward compatibility, #5082756
|
||||
if (value.equals("TRUE") || value.equals("true")) {
|
||||
return true;
|
||||
} else if (value.equals("FALSE") || value.equals("false")) {
|
||||
return false;
|
||||
} else {
|
||||
fatal(node, "Attribute " + name + " must be 'TRUE' or 'FALSE'!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get a required boolean-valued attribute
|
||||
protected static boolean getBooleanAttribute(Node node, String name)
|
||||
throws IIOInvalidTreeException {
|
||||
return getBooleanAttribute(node, name, false, true);
|
||||
}
|
||||
|
||||
// Get an enumerated attribute as an index into a String array
|
||||
protected static int getEnumeratedAttribute(Node node,
|
||||
String name,
|
||||
String[] legalNames,
|
||||
int defaultValue,
|
||||
boolean required)
|
||||
throws IIOInvalidTreeException {
|
||||
Node attr = node.getAttributes().getNamedItem(name);
|
||||
if (attr == null) {
|
||||
if (!required) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
fatal(node, "Required attribute " + name + " not present!");
|
||||
}
|
||||
}
|
||||
String value = attr.getNodeValue();
|
||||
for (int i = 0; i < legalNames.length; i++) {
|
||||
if(value.equals(legalNames[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
fatal(node, "Illegal value for attribute " + name + "!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get a required enumerated attribute as an index into a String array
|
||||
protected static int getEnumeratedAttribute(Node node,
|
||||
String name,
|
||||
String[] legalNames)
|
||||
throws IIOInvalidTreeException {
|
||||
return getEnumeratedAttribute(node, name, legalNames, -1, true);
|
||||
}
|
||||
|
||||
// Get a String-valued attribute
|
||||
protected static String getAttribute(Node node, String name,
|
||||
String defaultValue, boolean required)
|
||||
throws IIOInvalidTreeException {
|
||||
Node attr = node.getAttributes().getNamedItem(name);
|
||||
if (attr == null) {
|
||||
if (!required) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
fatal(node, "Required attribute " + name + " not present!");
|
||||
}
|
||||
}
|
||||
return attr.getNodeValue();
|
||||
}
|
||||
|
||||
// Get a required String-valued attribute
|
||||
protected static String getAttribute(Node node, String name)
|
||||
throws IIOInvalidTreeException {
|
||||
return getAttribute(node, name, null, true);
|
||||
}
|
||||
|
||||
protected GIFMetadata(boolean standardMetadataFormatSupported,
|
||||
String nativeMetadataFormatName,
|
||||
String nativeMetadataFormatClassName,
|
||||
String[] extraMetadataFormatNames,
|
||||
String[] extraMetadataFormatClassNames) {
|
||||
super(standardMetadataFormatSupported,
|
||||
nativeMetadataFormatName,
|
||||
nativeMetadataFormatClassName,
|
||||
extraMetadataFormatNames,
|
||||
extraMetadataFormatClassNames);
|
||||
}
|
||||
|
||||
public void mergeTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException {
|
||||
if (formatName.equals(nativeMetadataFormatName)) {
|
||||
if (root == null) {
|
||||
throw new IllegalArgumentException("root == null!");
|
||||
}
|
||||
mergeNativeTree(root);
|
||||
} else if (formatName.equals
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
if (root == null) {
|
||||
throw new IllegalArgumentException("root == null!");
|
||||
}
|
||||
mergeStandardTree(root);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not a recognized format!");
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] getColorTable(Node colorTableNode,
|
||||
String entryNodeName,
|
||||
boolean lengthExpected,
|
||||
int expectedLength)
|
||||
throws IIOInvalidTreeException {
|
||||
byte[] red = new byte[256];
|
||||
byte[] green = new byte[256];
|
||||
byte[] blue = new byte[256];
|
||||
int maxIndex = -1;
|
||||
|
||||
Node entry = colorTableNode.getFirstChild();
|
||||
if (entry == null) {
|
||||
fatal(colorTableNode, "Palette has no entries!");
|
||||
}
|
||||
|
||||
while (entry != null) {
|
||||
if (!entry.getNodeName().equals(entryNodeName)) {
|
||||
fatal(colorTableNode,
|
||||
"Only a "+entryNodeName+" may be a child of a "+
|
||||
entry.getNodeName()+"!");
|
||||
}
|
||||
|
||||
int index = getIntAttribute(entry, "index", true, 0, 255);
|
||||
if (index > maxIndex) {
|
||||
maxIndex = index;
|
||||
}
|
||||
red[index] = (byte)getIntAttribute(entry, "red", true, 0, 255);
|
||||
green[index] = (byte)getIntAttribute(entry, "green", true, 0, 255);
|
||||
blue[index] = (byte)getIntAttribute(entry, "blue", true, 0, 255);
|
||||
|
||||
entry = entry.getNextSibling();
|
||||
}
|
||||
|
||||
int numEntries = maxIndex + 1;
|
||||
|
||||
if (lengthExpected && numEntries != expectedLength) {
|
||||
fatal(colorTableNode, "Unexpected length for palette!");
|
||||
}
|
||||
|
||||
byte[] colorTable = new byte[3*numEntries];
|
||||
for (int i = 0, j = 0; i < numEntries; i++) {
|
||||
colorTable[j++] = red[i];
|
||||
colorTable[j++] = green[i];
|
||||
colorTable[j++] = blue[i];
|
||||
}
|
||||
|
||||
return colorTable;
|
||||
}
|
||||
|
||||
protected abstract void mergeNativeTree(Node root)
|
||||
throws IIOInvalidTreeException;
|
||||
|
||||
protected abstract void mergeStandardTree(Node root)
|
||||
throws IIOInvalidTreeException;
|
||||
}
|
||||
317
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFStreamMetadata.java
Normal file
317
jdkSrc/jdk8/com/sun/imageio/plugins/gif/GIFStreamMetadata.java
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
// TODO - document elimination of globalColorTableFlag
|
||||
|
||||
public class GIFStreamMetadata extends GIFMetadata {
|
||||
|
||||
// package scope
|
||||
static final String
|
||||
nativeMetadataFormatName = "javax_imageio_gif_stream_1.0";
|
||||
|
||||
static final String[] versionStrings = { "87a", "89a" };
|
||||
|
||||
public String version; // 87a or 89a
|
||||
public int logicalScreenWidth;
|
||||
public int logicalScreenHeight;
|
||||
public int colorResolution; // 1 to 8
|
||||
public int pixelAspectRatio;
|
||||
|
||||
public int backgroundColorIndex; // Valid if globalColorTable != null
|
||||
public boolean sortFlag; // Valid if globalColorTable != null
|
||||
|
||||
static final String[] colorTableSizes = {
|
||||
"2", "4", "8", "16", "32", "64", "128", "256"
|
||||
};
|
||||
|
||||
// Set global color table flag in header to 0 if null, 1 otherwise
|
||||
public byte[] globalColorTable = null;
|
||||
|
||||
protected GIFStreamMetadata(boolean standardMetadataFormatSupported,
|
||||
String nativeMetadataFormatName,
|
||||
String nativeMetadataFormatClassName,
|
||||
String[] extraMetadataFormatNames,
|
||||
String[] extraMetadataFormatClassNames)
|
||||
{
|
||||
super(standardMetadataFormatSupported,
|
||||
nativeMetadataFormatName,
|
||||
nativeMetadataFormatClassName,
|
||||
extraMetadataFormatNames,
|
||||
extraMetadataFormatClassNames);
|
||||
}
|
||||
|
||||
public GIFStreamMetadata() {
|
||||
this(true,
|
||||
nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.gif.GIFStreamMetadataFormat",
|
||||
null, null);
|
||||
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Node getAsTree(String formatName) {
|
||||
if (formatName.equals(nativeMetadataFormatName)) {
|
||||
return getNativeTree();
|
||||
} else if (formatName.equals
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
return getStandardTree();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not a recognized format!");
|
||||
}
|
||||
}
|
||||
|
||||
private Node getNativeTree() {
|
||||
IIOMetadataNode node; // scratch node
|
||||
IIOMetadataNode root =
|
||||
new IIOMetadataNode(nativeMetadataFormatName);
|
||||
|
||||
node = new IIOMetadataNode("Version");
|
||||
node.setAttribute("value", version);
|
||||
root.appendChild(node);
|
||||
|
||||
// Image descriptor
|
||||
node = new IIOMetadataNode("LogicalScreenDescriptor");
|
||||
/* NB: At the moment we use empty strings to support undefined
|
||||
* integer values in tree representation.
|
||||
* We need to add better support for undefined/default values later.
|
||||
*/
|
||||
node.setAttribute("logicalScreenWidth",
|
||||
logicalScreenWidth == UNDEFINED_INTEGER_VALUE ?
|
||||
"" : Integer.toString(logicalScreenWidth));
|
||||
node.setAttribute("logicalScreenHeight",
|
||||
logicalScreenHeight == UNDEFINED_INTEGER_VALUE ?
|
||||
"" : Integer.toString(logicalScreenHeight));
|
||||
// Stored value plus one
|
||||
node.setAttribute("colorResolution",
|
||||
colorResolution == UNDEFINED_INTEGER_VALUE ?
|
||||
"" : Integer.toString(colorResolution));
|
||||
node.setAttribute("pixelAspectRatio",
|
||||
Integer.toString(pixelAspectRatio));
|
||||
root.appendChild(node);
|
||||
|
||||
if (globalColorTable != null) {
|
||||
node = new IIOMetadataNode("GlobalColorTable");
|
||||
int numEntries = globalColorTable.length/3;
|
||||
node.setAttribute("sizeOfGlobalColorTable",
|
||||
Integer.toString(numEntries));
|
||||
node.setAttribute("backgroundColorIndex",
|
||||
Integer.toString(backgroundColorIndex));
|
||||
node.setAttribute("sortFlag",
|
||||
sortFlag ? "TRUE" : "FALSE");
|
||||
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
IIOMetadataNode entry =
|
||||
new IIOMetadataNode("ColorTableEntry");
|
||||
entry.setAttribute("index", Integer.toString(i));
|
||||
int r = globalColorTable[3*i] & 0xff;
|
||||
int g = globalColorTable[3*i + 1] & 0xff;
|
||||
int b = globalColorTable[3*i + 2] & 0xff;
|
||||
entry.setAttribute("red", Integer.toString(r));
|
||||
entry.setAttribute("green", Integer.toString(g));
|
||||
entry.setAttribute("blue", Integer.toString(b));
|
||||
node.appendChild(entry);
|
||||
}
|
||||
root.appendChild(node);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardChromaNode() {
|
||||
IIOMetadataNode chroma_node = new IIOMetadataNode("Chroma");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
node = new IIOMetadataNode("ColorSpaceType");
|
||||
node.setAttribute("name", "RGB");
|
||||
chroma_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("BlackIsZero");
|
||||
node.setAttribute("value", "TRUE");
|
||||
chroma_node.appendChild(node);
|
||||
|
||||
// NumChannels not in stream
|
||||
// Gamma not in format
|
||||
|
||||
if (globalColorTable != null) {
|
||||
node = new IIOMetadataNode("Palette");
|
||||
int numEntries = globalColorTable.length/3;
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
IIOMetadataNode entry =
|
||||
new IIOMetadataNode("PaletteEntry");
|
||||
entry.setAttribute("index", Integer.toString(i));
|
||||
entry.setAttribute("red",
|
||||
Integer.toString(globalColorTable[3*i] & 0xff));
|
||||
entry.setAttribute("green",
|
||||
Integer.toString(globalColorTable[3*i + 1] & 0xff));
|
||||
entry.setAttribute("blue",
|
||||
Integer.toString(globalColorTable[3*i + 2] & 0xff));
|
||||
node.appendChild(entry);
|
||||
}
|
||||
chroma_node.appendChild(node);
|
||||
|
||||
// backgroundColorIndex is valid iff there is a color table
|
||||
node = new IIOMetadataNode("BackgroundIndex");
|
||||
node.setAttribute("value", Integer.toString(backgroundColorIndex));
|
||||
chroma_node.appendChild(node);
|
||||
}
|
||||
|
||||
return chroma_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardCompressionNode() {
|
||||
IIOMetadataNode compression_node = new IIOMetadataNode("Compression");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
node = new IIOMetadataNode("CompressionTypeName");
|
||||
node.setAttribute("value", "lzw");
|
||||
compression_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("Lossless");
|
||||
node.setAttribute("value", "TRUE");
|
||||
compression_node.appendChild(node);
|
||||
|
||||
// NumProgressiveScans not in stream
|
||||
// BitRate not in format
|
||||
|
||||
return compression_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardDataNode() {
|
||||
IIOMetadataNode data_node = new IIOMetadataNode("Data");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
// PlanarConfiguration
|
||||
|
||||
node = new IIOMetadataNode("SampleFormat");
|
||||
node.setAttribute("value", "Index");
|
||||
data_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("BitsPerSample");
|
||||
node.setAttribute("value",
|
||||
colorResolution == UNDEFINED_INTEGER_VALUE ?
|
||||
"" : Integer.toString(colorResolution));
|
||||
data_node.appendChild(node);
|
||||
|
||||
// SignificantBitsPerSample
|
||||
// SampleMSB
|
||||
|
||||
return data_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardDimensionNode() {
|
||||
IIOMetadataNode dimension_node = new IIOMetadataNode("Dimension");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
node = new IIOMetadataNode("PixelAspectRatio");
|
||||
float aspectRatio = 1.0F;
|
||||
if (pixelAspectRatio != 0) {
|
||||
aspectRatio = (pixelAspectRatio + 15)/64.0F;
|
||||
}
|
||||
node.setAttribute("value", Float.toString(aspectRatio));
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("ImageOrientation");
|
||||
node.setAttribute("value", "Normal");
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
// HorizontalPixelSize not in format
|
||||
// VerticalPixelSize not in format
|
||||
// HorizontalPhysicalPixelSpacing not in format
|
||||
// VerticalPhysicalPixelSpacing not in format
|
||||
// HorizontalPosition not in format
|
||||
// VerticalPosition not in format
|
||||
// HorizontalPixelOffset not in stream
|
||||
// VerticalPixelOffset not in stream
|
||||
|
||||
node = new IIOMetadataNode("HorizontalScreenSize");
|
||||
node.setAttribute("value",
|
||||
logicalScreenWidth == UNDEFINED_INTEGER_VALUE ?
|
||||
"" : Integer.toString(logicalScreenWidth));
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
node = new IIOMetadataNode("VerticalScreenSize");
|
||||
node.setAttribute("value",
|
||||
logicalScreenHeight == UNDEFINED_INTEGER_VALUE ?
|
||||
"" : Integer.toString(logicalScreenHeight));
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
return dimension_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardDocumentNode() {
|
||||
IIOMetadataNode document_node = new IIOMetadataNode("Document");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
node = new IIOMetadataNode("FormatVersion");
|
||||
node.setAttribute("value", version);
|
||||
document_node.appendChild(node);
|
||||
|
||||
// SubimageInterpretation not in format
|
||||
// ImageCreationTime not in format
|
||||
// ImageModificationTime not in format
|
||||
|
||||
return document_node;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardTextNode() {
|
||||
// Not in stream
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIOMetadataNode getStandardTransparencyNode() {
|
||||
// Not in stream
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setFromTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException
|
||||
{
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
|
||||
protected void mergeNativeTree(Node root) throws IIOInvalidTreeException
|
||||
{
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
|
||||
protected void mergeStandardTree(Node root) throws IIOInvalidTreeException
|
||||
{
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
throw new IllegalStateException("Metadata is read-only!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class GIFStreamMetadataFormat extends IIOMetadataFormatImpl {
|
||||
|
||||
private static IIOMetadataFormat instance = null;
|
||||
|
||||
private GIFStreamMetadataFormat() {
|
||||
super(GIFStreamMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> Version
|
||||
addElement("Version", GIFStreamMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("Version", "value",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(GIFStreamMetadata.versionStrings));
|
||||
|
||||
// root -> LogicalScreenDescriptor
|
||||
addElement("LogicalScreenDescriptor",
|
||||
GIFStreamMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("LogicalScreenDescriptor", "logicalScreenWidth",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("LogicalScreenDescriptor", "logicalScreenHeight",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
addAttribute("LogicalScreenDescriptor", "colorResolution",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "8", true, true);
|
||||
addAttribute("LogicalScreenDescriptor", "pixelAspectRatio",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
|
||||
// root -> GlobalColorTable
|
||||
addElement("GlobalColorTable",
|
||||
GIFStreamMetadata.nativeMetadataFormatName,
|
||||
2, 256);
|
||||
addAttribute("GlobalColorTable", "sizeOfGlobalColorTable",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
Arrays.asList(GIFStreamMetadata.colorTableSizes));
|
||||
addAttribute("GlobalColorTable", "backgroundColorIndex",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addBooleanAttribute("GlobalColorTable", "sortFlag",
|
||||
false, false);
|
||||
|
||||
// root -> GlobalColorTable -> ColorTableEntry
|
||||
addElement("ColorTableEntry", "GlobalColorTable",
|
||||
CHILD_POLICY_EMPTY);
|
||||
addAttribute("ColorTableEntry", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("ColorTableEntry", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("ColorTableEntry", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
addAttribute("ColorTableEntry", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "255", true, true);
|
||||
}
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static synchronized IIOMetadataFormat getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new GIFStreamMetadataFormat();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class GIFStreamMetadataFormatResources extends ListResourceBundle {
|
||||
|
||||
public GIFStreamMetadataFormatResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
|
||||
// Node name, followed by description
|
||||
{ "Version", "The file version, either 87a or 89a" },
|
||||
{ "LogicalScreenDescriptor",
|
||||
"The logical screen descriptor, except for the global color table" },
|
||||
{ "GlobalColorTable", "The global color table" },
|
||||
{ "ColorTableEntry", "A global color table entry" },
|
||||
|
||||
// Node name + "/" + AttributeName, followed by description
|
||||
{ "Version/value",
|
||||
"The version string" },
|
||||
{ "LogicalScreenDescriptor/logicalScreenWidth",
|
||||
"The width in pixels of the whole picture" },
|
||||
{ "LogicalScreenDescriptor/logicalScreenHeight",
|
||||
"The height in pixels of the whole picture" },
|
||||
{ "LogicalScreenDescriptor/colorResolution",
|
||||
"The number of bits of color resolution, beteen 1 and 8" },
|
||||
{ "LogicalScreenDescriptor/pixelAspectRatio",
|
||||
"If 0, indicates square pixels, else W/H = (value + 15)/64" },
|
||||
{ "GlobalColorTable/sizeOfGlobalColorTable",
|
||||
"The number of entries in the global color table" },
|
||||
{ "GlobalColorTable/backgroundColorIndex",
|
||||
"The index of the color table entry to be used as a background" },
|
||||
{ "GlobalColorTable/sortFlag",
|
||||
"True if the global color table is sorted by frequency" },
|
||||
{ "ColorTableEntry/index", "The index of the color table entry" },
|
||||
{ "ColorTableEntry/red",
|
||||
"The red value for the color table entry" },
|
||||
{ "ColorTableEntry/green",
|
||||
"The green value for the color table entry" },
|
||||
{ "ColorTableEntry/blue",
|
||||
"The blue value for the color table entry" },
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
class GIFWritableImageMetadata extends GIFImageMetadata {
|
||||
|
||||
// package scope
|
||||
static final String
|
||||
NATIVE_FORMAT_NAME = "javax_imageio_gif_image_1.0";
|
||||
|
||||
GIFWritableImageMetadata() {
|
||||
super(true,
|
||||
NATIVE_FORMAT_NAME,
|
||||
"com.sun.imageio.plugins.gif.GIFImageMetadataFormat",
|
||||
null, null);
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
// Fields from Image Descriptor
|
||||
imageLeftPosition = 0;
|
||||
imageTopPosition = 0;
|
||||
imageWidth = 0;
|
||||
imageHeight = 0;
|
||||
interlaceFlag = false;
|
||||
sortFlag = false;
|
||||
localColorTable = null;
|
||||
|
||||
// Fields from Graphic Control Extension
|
||||
disposalMethod = 0;
|
||||
userInputFlag = false;
|
||||
transparentColorFlag = false;
|
||||
delayTime = 0;
|
||||
transparentColorIndex = 0;
|
||||
|
||||
// Fields from Plain Text Extension
|
||||
hasPlainTextExtension = false;
|
||||
textGridLeft = 0;
|
||||
textGridTop = 0;
|
||||
textGridWidth = 0;
|
||||
textGridHeight = 0;
|
||||
characterCellWidth = 0;
|
||||
characterCellHeight = 0;
|
||||
textForegroundColor = 0;
|
||||
textBackgroundColor = 0;
|
||||
text = null;
|
||||
|
||||
// Fields from ApplicationExtension
|
||||
applicationIDs = null;
|
||||
authenticationCodes = null;
|
||||
applicationData = null;
|
||||
|
||||
// Fields from CommentExtension
|
||||
// List of byte[]
|
||||
comments = null;
|
||||
}
|
||||
|
||||
private byte[] fromISO8859(String data) {
|
||||
try {
|
||||
return data.getBytes("ISO-8859-1");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "".getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
protected void mergeNativeTree(Node root) throws IIOInvalidTreeException {
|
||||
Node node = root;
|
||||
if (!node.getNodeName().equals(nativeMetadataFormatName)) {
|
||||
fatal(node, "Root must be " + nativeMetadataFormatName);
|
||||
}
|
||||
|
||||
node = node.getFirstChild();
|
||||
while (node != null) {
|
||||
String name = node.getNodeName();
|
||||
|
||||
if (name.equals("ImageDescriptor")) {
|
||||
imageLeftPosition = getIntAttribute(node,
|
||||
"imageLeftPosition",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
|
||||
imageTopPosition = getIntAttribute(node,
|
||||
"imageTopPosition",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
|
||||
imageWidth = getIntAttribute(node,
|
||||
"imageWidth",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
|
||||
imageHeight = getIntAttribute(node,
|
||||
"imageHeight",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
|
||||
interlaceFlag = getBooleanAttribute(node, "interlaceFlag",
|
||||
false, true);
|
||||
} else if (name.equals("LocalColorTable")) {
|
||||
int sizeOfLocalColorTable =
|
||||
getIntAttribute(node, "sizeOfLocalColorTable",
|
||||
true, 2, 256);
|
||||
if (sizeOfLocalColorTable != 2 &&
|
||||
sizeOfLocalColorTable != 4 &&
|
||||
sizeOfLocalColorTable != 8 &&
|
||||
sizeOfLocalColorTable != 16 &&
|
||||
sizeOfLocalColorTable != 32 &&
|
||||
sizeOfLocalColorTable != 64 &&
|
||||
sizeOfLocalColorTable != 128 &&
|
||||
sizeOfLocalColorTable != 256) {
|
||||
fatal(node,
|
||||
"Bad value for LocalColorTable attribute sizeOfLocalColorTable!");
|
||||
}
|
||||
|
||||
sortFlag = getBooleanAttribute(node, "sortFlag", false, true);
|
||||
|
||||
localColorTable = getColorTable(node, "ColorTableEntry",
|
||||
true, sizeOfLocalColorTable);
|
||||
} else if (name.equals("GraphicControlExtension")) {
|
||||
String disposalMethodName =
|
||||
getStringAttribute(node, "disposalMethod", null,
|
||||
true, disposalMethodNames);
|
||||
disposalMethod = 0;
|
||||
while(!disposalMethodName.equals(disposalMethodNames[disposalMethod])) {
|
||||
disposalMethod++;
|
||||
}
|
||||
|
||||
userInputFlag = getBooleanAttribute(node, "userInputFlag",
|
||||
false, true);
|
||||
|
||||
transparentColorFlag =
|
||||
getBooleanAttribute(node, "transparentColorFlag",
|
||||
false, true);
|
||||
|
||||
delayTime = getIntAttribute(node,
|
||||
"delayTime",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
|
||||
transparentColorIndex =
|
||||
getIntAttribute(node, "transparentColorIndex",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
} else if (name.equals("PlainTextExtension")) {
|
||||
hasPlainTextExtension = true;
|
||||
|
||||
textGridLeft = getIntAttribute(node,
|
||||
"textGridLeft",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
|
||||
textGridTop = getIntAttribute(node,
|
||||
"textGridTop",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
|
||||
textGridWidth = getIntAttribute(node,
|
||||
"textGridWidth",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
|
||||
textGridHeight = getIntAttribute(node,
|
||||
"textGridHeight",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
|
||||
characterCellWidth = getIntAttribute(node,
|
||||
"characterCellWidth",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
|
||||
characterCellHeight = getIntAttribute(node,
|
||||
"characterCellHeight",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
|
||||
textForegroundColor = getIntAttribute(node,
|
||||
"textForegroundColor",
|
||||
-1, true,
|
||||
true, 0, 255);
|
||||
|
||||
textBackgroundColor = getIntAttribute(node,
|
||||
"textBackgroundColor",
|
||||
-1, true,
|
||||
true, 0, 255);
|
||||
|
||||
// XXX The "text" attribute of the PlainTextExtension element
|
||||
// is not defined in the GIF image metadata format but it is
|
||||
// present in the GIFImageMetadata class. Consequently it is
|
||||
// used here but not required and with a default of "". See
|
||||
// bug 5082763.
|
||||
|
||||
String textString =
|
||||
getStringAttribute(node, "text", "", false, null);
|
||||
text = fromISO8859(textString);
|
||||
} else if (name.equals("ApplicationExtensions")) {
|
||||
IIOMetadataNode applicationExtension =
|
||||
(IIOMetadataNode)node.getFirstChild();
|
||||
|
||||
if (!applicationExtension.getNodeName().equals("ApplicationExtension")) {
|
||||
fatal(node,
|
||||
"Only a ApplicationExtension may be a child of a ApplicationExtensions!");
|
||||
}
|
||||
|
||||
String applicationIDString =
|
||||
getStringAttribute(applicationExtension, "applicationID",
|
||||
null, true, null);
|
||||
|
||||
String authenticationCodeString =
|
||||
getStringAttribute(applicationExtension, "authenticationCode",
|
||||
null, true, null);
|
||||
|
||||
Object applicationExtensionData =
|
||||
applicationExtension.getUserObject();
|
||||
if (applicationExtensionData == null ||
|
||||
!(applicationExtensionData instanceof byte[])) {
|
||||
fatal(applicationExtension,
|
||||
"Bad user object in ApplicationExtension!");
|
||||
}
|
||||
|
||||
if (applicationIDs == null) {
|
||||
applicationIDs = new ArrayList();
|
||||
authenticationCodes = new ArrayList();
|
||||
applicationData = new ArrayList();
|
||||
}
|
||||
|
||||
applicationIDs.add(fromISO8859(applicationIDString));
|
||||
authenticationCodes.add(fromISO8859(authenticationCodeString));
|
||||
applicationData.add(applicationExtensionData);
|
||||
} else if (name.equals("CommentExtensions")) {
|
||||
Node commentExtension = node.getFirstChild();
|
||||
if (commentExtension != null) {
|
||||
while(commentExtension != null) {
|
||||
if (!commentExtension.getNodeName().equals("CommentExtension")) {
|
||||
fatal(node,
|
||||
"Only a CommentExtension may be a child of a CommentExtensions!");
|
||||
}
|
||||
|
||||
if (comments == null) {
|
||||
comments = new ArrayList();
|
||||
}
|
||||
|
||||
String comment =
|
||||
getStringAttribute(commentExtension, "value", null,
|
||||
true, null);
|
||||
|
||||
comments.add(fromISO8859(comment));
|
||||
|
||||
commentExtension = commentExtension.getNextSibling();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fatal(node, "Unknown child of root node!");
|
||||
}
|
||||
|
||||
node = node.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
protected void mergeStandardTree(Node root)
|
||||
throws IIOInvalidTreeException {
|
||||
Node node = root;
|
||||
if (!node.getNodeName()
|
||||
.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
fatal(node, "Root must be " +
|
||||
IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||
}
|
||||
|
||||
node = node.getFirstChild();
|
||||
while (node != null) {
|
||||
String name = node.getNodeName();
|
||||
|
||||
if (name.equals("Chroma")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("Palette")) {
|
||||
localColorTable = getColorTable(childNode,
|
||||
"PaletteEntry",
|
||||
false, -1);
|
||||
break;
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
} else if (name.equals("Compression")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("NumProgressiveScans")) {
|
||||
int numProgressiveScans =
|
||||
getIntAttribute(childNode, "value", 4, false,
|
||||
true, 1, Integer.MAX_VALUE);
|
||||
if (numProgressiveScans > 1) {
|
||||
interlaceFlag = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
} else if (name.equals("Dimension")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("HorizontalPixelOffset")) {
|
||||
imageLeftPosition = getIntAttribute(childNode,
|
||||
"value",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
} else if (childName.equals("VerticalPixelOffset")) {
|
||||
imageTopPosition = getIntAttribute(childNode,
|
||||
"value",
|
||||
-1, true,
|
||||
true, 0, 65535);
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
} else if (name.equals("Text")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("TextEntry") &&
|
||||
getAttribute(childNode, "compression",
|
||||
"none", false).equals("none") &&
|
||||
Charset.isSupported(getAttribute(childNode,
|
||||
"encoding",
|
||||
"ISO-8859-1",
|
||||
false))) {
|
||||
String value = getAttribute(childNode, "value");
|
||||
byte[] comment = fromISO8859(value);
|
||||
if (comments == null) {
|
||||
comments = new ArrayList();
|
||||
}
|
||||
comments.add(comment);
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
} else if (name.equals("Transparency")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("TransparentIndex")) {
|
||||
transparentColorIndex = getIntAttribute(childNode,
|
||||
"value",
|
||||
-1, true,
|
||||
true, 0, 255);
|
||||
transparentColorFlag = true;
|
||||
break;
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
node = node.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
public void setFromTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException
|
||||
{
|
||||
reset();
|
||||
mergeTree(formatName, root);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.gif;
|
||||
|
||||
/*
|
||||
* The source for this class was copied verbatim from the source for
|
||||
* package com.sun.imageio.plugins.gif.GIFImageMetadata and then modified
|
||||
* to make the class read-write capable.
|
||||
*/
|
||||
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
class GIFWritableStreamMetadata extends GIFStreamMetadata {
|
||||
|
||||
// package scope
|
||||
static final String
|
||||
NATIVE_FORMAT_NAME = "javax_imageio_gif_stream_1.0";
|
||||
|
||||
public GIFWritableStreamMetadata() {
|
||||
super(true,
|
||||
NATIVE_FORMAT_NAME,
|
||||
"com.sun.imageio.plugins.gif.GIFStreamMetadataFormat", // XXX J2SE
|
||||
null, null);
|
||||
|
||||
// initialize metadata fields by default values
|
||||
reset();
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void mergeTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException {
|
||||
if (formatName.equals(nativeMetadataFormatName)) {
|
||||
if (root == null) {
|
||||
throw new IllegalArgumentException("root == null!");
|
||||
}
|
||||
mergeNativeTree(root);
|
||||
} else if (formatName.equals
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
if (root == null) {
|
||||
throw new IllegalArgumentException("root == null!");
|
||||
}
|
||||
mergeStandardTree(root);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not a recognized format!");
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
version = null;
|
||||
|
||||
logicalScreenWidth = UNDEFINED_INTEGER_VALUE;
|
||||
logicalScreenHeight = UNDEFINED_INTEGER_VALUE;
|
||||
colorResolution = UNDEFINED_INTEGER_VALUE;
|
||||
pixelAspectRatio = 0;
|
||||
|
||||
backgroundColorIndex = 0;
|
||||
sortFlag = false;
|
||||
globalColorTable = null;
|
||||
}
|
||||
|
||||
protected void mergeNativeTree(Node root) throws IIOInvalidTreeException {
|
||||
Node node = root;
|
||||
if (!node.getNodeName().equals(nativeMetadataFormatName)) {
|
||||
fatal(node, "Root must be " + nativeMetadataFormatName);
|
||||
}
|
||||
|
||||
node = node.getFirstChild();
|
||||
while (node != null) {
|
||||
String name = node.getNodeName();
|
||||
|
||||
if (name.equals("Version")) {
|
||||
version = getStringAttribute(node, "value", null,
|
||||
true, versionStrings);
|
||||
} else if (name.equals("LogicalScreenDescriptor")) {
|
||||
/* NB: At the moment we use empty strings to support undefined
|
||||
* integer values in tree representation.
|
||||
* We need to add better support for undefined/default values
|
||||
* later.
|
||||
*/
|
||||
logicalScreenWidth = getIntAttribute(node,
|
||||
"logicalScreenWidth",
|
||||
UNDEFINED_INTEGER_VALUE,
|
||||
true,
|
||||
true, 1, 65535);
|
||||
|
||||
logicalScreenHeight = getIntAttribute(node,
|
||||
"logicalScreenHeight",
|
||||
UNDEFINED_INTEGER_VALUE,
|
||||
true,
|
||||
true, 1, 65535);
|
||||
|
||||
colorResolution = getIntAttribute(node,
|
||||
"colorResolution",
|
||||
UNDEFINED_INTEGER_VALUE,
|
||||
true,
|
||||
true, 1, 8);
|
||||
|
||||
pixelAspectRatio = getIntAttribute(node,
|
||||
"pixelAspectRatio",
|
||||
0, true,
|
||||
true, 0, 255);
|
||||
} else if (name.equals("GlobalColorTable")) {
|
||||
int sizeOfGlobalColorTable =
|
||||
getIntAttribute(node, "sizeOfGlobalColorTable",
|
||||
true, 2, 256);
|
||||
if (sizeOfGlobalColorTable != 2 &&
|
||||
sizeOfGlobalColorTable != 4 &&
|
||||
sizeOfGlobalColorTable != 8 &&
|
||||
sizeOfGlobalColorTable != 16 &&
|
||||
sizeOfGlobalColorTable != 32 &&
|
||||
sizeOfGlobalColorTable != 64 &&
|
||||
sizeOfGlobalColorTable != 128 &&
|
||||
sizeOfGlobalColorTable != 256) {
|
||||
fatal(node,
|
||||
"Bad value for GlobalColorTable attribute sizeOfGlobalColorTable!");
|
||||
}
|
||||
|
||||
backgroundColorIndex = getIntAttribute(node,
|
||||
"backgroundColorIndex",
|
||||
0, true,
|
||||
true, 0, 255);
|
||||
|
||||
sortFlag = getBooleanAttribute(node, "sortFlag", false, true);
|
||||
|
||||
globalColorTable = getColorTable(node, "ColorTableEntry",
|
||||
true, sizeOfGlobalColorTable);
|
||||
} else {
|
||||
fatal(node, "Unknown child of root node!");
|
||||
}
|
||||
|
||||
node = node.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
protected void mergeStandardTree(Node root)
|
||||
throws IIOInvalidTreeException {
|
||||
Node node = root;
|
||||
if (!node.getNodeName()
|
||||
.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
fatal(node, "Root must be " +
|
||||
IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||
}
|
||||
|
||||
node = node.getFirstChild();
|
||||
while (node != null) {
|
||||
String name = node.getNodeName();
|
||||
|
||||
if (name.equals("Chroma")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("Palette")) {
|
||||
globalColorTable = getColorTable(childNode,
|
||||
"PaletteEntry",
|
||||
false, -1);
|
||||
|
||||
} else if (childName.equals("BackgroundIndex")) {
|
||||
backgroundColorIndex = getIntAttribute(childNode,
|
||||
"value",
|
||||
-1, true,
|
||||
true, 0, 255);
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
} else if (name.equals("Data")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("BitsPerSample")) {
|
||||
colorResolution = getIntAttribute(childNode,
|
||||
"value",
|
||||
-1, true,
|
||||
true, 1, 8);
|
||||
break;
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
} else if (name.equals("Dimension")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("PixelAspectRatio")) {
|
||||
float aspectRatio = getFloatAttribute(childNode,
|
||||
"value");
|
||||
if (aspectRatio == 1.0F) {
|
||||
pixelAspectRatio = 0;
|
||||
} else {
|
||||
int ratio = (int)(aspectRatio*64.0F - 15.0F);
|
||||
pixelAspectRatio =
|
||||
Math.max(Math.min(ratio, 255), 0);
|
||||
}
|
||||
} else if (childName.equals("HorizontalScreenSize")) {
|
||||
logicalScreenWidth = getIntAttribute(childNode,
|
||||
"value",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
} else if (childName.equals("VerticalScreenSize")) {
|
||||
logicalScreenHeight = getIntAttribute(childNode,
|
||||
"value",
|
||||
-1, true,
|
||||
true, 1, 65535);
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
} else if (name.equals("Document")) {
|
||||
Node childNode = node.getFirstChild();
|
||||
while(childNode != null) {
|
||||
String childName = childNode.getNodeName();
|
||||
if (childName.equals("FormatVersion")) {
|
||||
String formatVersion =
|
||||
getStringAttribute(childNode, "value", null,
|
||||
true, null);
|
||||
for (int i = 0; i < versionStrings.length; i++) {
|
||||
if (formatVersion.equals(versionStrings[i])) {
|
||||
version = formatVersion;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
node = node.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
public void setFromTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException
|
||||
{
|
||||
reset();
|
||||
mergeTree(formatName, root);
|
||||
}
|
||||
}
|
||||
136
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/AdobeMarkerSegment.java
Normal file
136
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/AdobeMarkerSegment.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* An Adobe APP14 (Application-Specific) marker segment.
|
||||
*/
|
||||
class AdobeMarkerSegment extends MarkerSegment {
|
||||
int version;
|
||||
int flags0;
|
||||
int flags1;
|
||||
int transform;
|
||||
private static final int ID_SIZE = 5;
|
||||
|
||||
AdobeMarkerSegment(int transform) {
|
||||
super(JPEG.APP14);
|
||||
version = 101;
|
||||
flags0 = 0;
|
||||
flags1 = 0;
|
||||
this.transform = transform;
|
||||
}
|
||||
|
||||
AdobeMarkerSegment(JPEGBuffer buffer) throws IOException {
|
||||
super(buffer);
|
||||
buffer.bufPtr += ID_SIZE; // Skip the id
|
||||
version = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
|
||||
version |= buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
flags0 = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
|
||||
flags0 |= buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
flags1 = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
|
||||
flags1 |= buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
transform = buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
buffer.bufAvail -= length;
|
||||
}
|
||||
|
||||
AdobeMarkerSegment(Node node) throws IIOInvalidTreeException {
|
||||
this(0); // default transform will be changed
|
||||
updateFromNativeNode(node, true);
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("app14Adobe");
|
||||
node.setAttribute("version", Integer.toString(version));
|
||||
node.setAttribute("flags0", Integer.toString(flags0));
|
||||
node.setAttribute("flags1", Integer.toString(flags1));
|
||||
node.setAttribute("transform", Integer.toString(transform));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void updateFromNativeNode(Node node, boolean fromScratch)
|
||||
throws IIOInvalidTreeException {
|
||||
// Only the transform is required
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
transform = getAttributeValue(node, attrs, "transform", 0, 2, true);
|
||||
int count = attrs.getLength();
|
||||
if (count > 4) {
|
||||
throw new IIOInvalidTreeException
|
||||
("Adobe APP14 node cannot have > 4 attributes", node);
|
||||
}
|
||||
if (count > 1) {
|
||||
int value = getAttributeValue(node, attrs, "version",
|
||||
100, 255, false);
|
||||
version = (value != -1) ? value : version;
|
||||
value = getAttributeValue(node, attrs, "flags0", 0, 65535, false);
|
||||
flags0 = (value != -1) ? value : flags0;
|
||||
value = getAttributeValue(node, attrs, "flags1", 0, 65535, false);
|
||||
flags1 = (value != -1) ? value : flags1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
length = 14;
|
||||
writeTag(ios);
|
||||
byte [] id = {0x41, 0x64, 0x6F, 0x62, 0x65};
|
||||
ios.write(id);
|
||||
write2bytes(ios, version);
|
||||
write2bytes(ios, flags0);
|
||||
write2bytes(ios, flags1);
|
||||
ios.write(transform);
|
||||
}
|
||||
|
||||
static void writeAdobeSegment(ImageOutputStream ios, int transform)
|
||||
throws IOException {
|
||||
(new AdobeMarkerSegment(transform)).write(ios);
|
||||
}
|
||||
|
||||
void print () {
|
||||
printTag("Adobe APP14");
|
||||
System.out.print("Version: ");
|
||||
System.out.println(version);
|
||||
System.out.print("Flags0: 0x");
|
||||
System.out.println(Integer.toHexString(flags0));
|
||||
System.out.print("Flags1: 0x");
|
||||
System.out.println(Integer.toHexString(flags1));
|
||||
System.out.print("Transform: ");
|
||||
System.out.println(transform);
|
||||
}
|
||||
}
|
||||
133
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/COMMarkerSegment.java
Normal file
133
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/COMMarkerSegment.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* A Comment marker segment. Retains an array of bytes representing the
|
||||
* comment data as it is read from the stream. If the marker segment is
|
||||
* constructed from a String, then local default encoding is assumed
|
||||
* when creating the byte array. If the marker segment is created from
|
||||
* an <code>IIOMetadataNode</code>, the user object, if present is
|
||||
* assumed to be a byte array containing the comment data. If there is
|
||||
* no user object then the comment attribute is used to create the
|
||||
* byte array, again assuming the default local encoding.
|
||||
*/
|
||||
class COMMarkerSegment extends MarkerSegment {
|
||||
private static final String ENCODING = "ISO-8859-1";
|
||||
|
||||
/**
|
||||
* Constructs a marker segment from the given buffer, which contains
|
||||
* data from an <code>ImageInputStream</code>. This is used when
|
||||
* reading metadata from a stream.
|
||||
*/
|
||||
COMMarkerSegment(JPEGBuffer buffer) throws IOException {
|
||||
super(buffer);
|
||||
loadData(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a marker segment from a String. This is used when
|
||||
* modifying metadata from a non-native tree and when transcoding.
|
||||
* The default encoding is used to construct the byte array.
|
||||
*/
|
||||
COMMarkerSegment(String comment) {
|
||||
super(JPEG.COM);
|
||||
data = comment.getBytes(); // Default encoding
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a marker segment from a native tree node. If the node
|
||||
* is an <code>IIOMetadataNode</code> and contains a user object,
|
||||
* that object is used rather than the string attribute. If the
|
||||
* string attribute is used, the default encoding is used.
|
||||
*/
|
||||
COMMarkerSegment(Node node) throws IIOInvalidTreeException{
|
||||
super(JPEG.COM);
|
||||
if (node instanceof IIOMetadataNode) {
|
||||
IIOMetadataNode ourNode = (IIOMetadataNode) node;
|
||||
data = (byte []) ourNode.getUserObject();
|
||||
}
|
||||
if (data == null) {
|
||||
String comment =
|
||||
node.getAttributes().getNamedItem("comment").getNodeValue();
|
||||
if (comment != null) {
|
||||
data = comment.getBytes(); // Default encoding
|
||||
} else {
|
||||
throw new IIOInvalidTreeException("Empty comment node!", node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array encoded as a String, using ISO-Latin-1 encoding.
|
||||
* If an application needs another encoding, the data array must be
|
||||
* consulted directly.
|
||||
*/
|
||||
String getComment() {
|
||||
try {
|
||||
return new String (data, ENCODING);
|
||||
} catch (UnsupportedEncodingException e) {} // Won't happen
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> containing the data array
|
||||
* as a user object and a string encoded using ISO-8895-1, as an
|
||||
* attribute.
|
||||
*/
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("com");
|
||||
node.setAttribute("comment", getComment());
|
||||
if (data != null) {
|
||||
node.setUserObject(data.clone());
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format, directly from the data array.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
length = 2 + data.length;
|
||||
writeTag(ios);
|
||||
ios.write(data);
|
||||
}
|
||||
|
||||
void print() {
|
||||
printTag("COM");
|
||||
System.out.println("<" + getComment() + ">");
|
||||
}
|
||||
}
|
||||
260
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/DHTMarkerSegment.java
Normal file
260
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/DHTMarkerSegment.java
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* A DHT (Define Huffman Table) marker segment.
|
||||
*/
|
||||
class DHTMarkerSegment extends MarkerSegment {
|
||||
List tables = new ArrayList();
|
||||
|
||||
DHTMarkerSegment(boolean needFour) {
|
||||
super(JPEG.DHT);
|
||||
tables.add(new Htable(JPEGHuffmanTable.StdDCLuminance, true, 0));
|
||||
if (needFour) {
|
||||
tables.add(new Htable(JPEGHuffmanTable.StdDCChrominance, true, 1));
|
||||
}
|
||||
tables.add(new Htable(JPEGHuffmanTable.StdACLuminance, false, 0));
|
||||
if (needFour) {
|
||||
tables.add(new Htable(JPEGHuffmanTable.StdACChrominance, false, 1));
|
||||
}
|
||||
}
|
||||
|
||||
DHTMarkerSegment(JPEGBuffer buffer) throws IOException {
|
||||
super(buffer);
|
||||
int count = length;
|
||||
while (count > 0) {
|
||||
Htable newGuy = new Htable(buffer);
|
||||
tables.add(newGuy);
|
||||
count -= 1 + 16 + newGuy.values.length;
|
||||
}
|
||||
buffer.bufAvail -= length;
|
||||
}
|
||||
|
||||
DHTMarkerSegment(JPEGHuffmanTable[] dcTables,
|
||||
JPEGHuffmanTable[] acTables) {
|
||||
super(JPEG.DHT);
|
||||
for (int i = 0; i < dcTables.length; i++) {
|
||||
tables.add(new Htable(dcTables[i], true, i));
|
||||
}
|
||||
for (int i = 0; i < acTables.length; i++) {
|
||||
tables.add(new Htable(acTables[i], false, i));
|
||||
}
|
||||
}
|
||||
|
||||
DHTMarkerSegment(Node node) throws IIOInvalidTreeException {
|
||||
super(JPEG.DHT);
|
||||
NodeList children = node.getChildNodes();
|
||||
int size = children.getLength();
|
||||
if ((size < 1) || (size > 4)) {
|
||||
throw new IIOInvalidTreeException("Invalid DHT node", node);
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
tables.add(new Htable(children.item(i)));
|
||||
}
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
DHTMarkerSegment newGuy = (DHTMarkerSegment) super.clone();
|
||||
newGuy.tables = new ArrayList(tables.size());
|
||||
Iterator iter = tables.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Htable table = (Htable) iter.next();
|
||||
newGuy.tables.add(table.clone());
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("dht");
|
||||
for (int i= 0; i<tables.size(); i++) {
|
||||
Htable table = (Htable) tables.get(i);
|
||||
node.appendChild(table.getNativeNode());
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
// We don't write DHT segments; the IJG library does.
|
||||
}
|
||||
|
||||
void print() {
|
||||
printTag("DHT");
|
||||
System.out.println("Num tables: "
|
||||
+ Integer.toString(tables.size()));
|
||||
for (int i= 0; i<tables.size(); i++) {
|
||||
Htable table = (Htable) tables.get(i);
|
||||
table.print();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
|
||||
Htable getHtableFromNode(Node node) throws IIOInvalidTreeException {
|
||||
return new Htable(node);
|
||||
}
|
||||
|
||||
void addHtable(JPEGHuffmanTable table, boolean isDC, int id) {
|
||||
tables.add(new Htable(table, isDC, id));
|
||||
}
|
||||
|
||||
/**
|
||||
* A Huffman table within a DHT marker segment.
|
||||
*/
|
||||
class Htable implements Cloneable {
|
||||
int tableClass; // 0 == DC, 1 == AC
|
||||
int tableID; // 0 - 4
|
||||
private static final int NUM_LENGTHS = 16;
|
||||
// # of codes of each length
|
||||
short [] numCodes = new short[NUM_LENGTHS];
|
||||
short [] values;
|
||||
|
||||
Htable(JPEGBuffer buffer) {
|
||||
tableClass = buffer.buf[buffer.bufPtr] >>> 4;
|
||||
tableID = buffer.buf[buffer.bufPtr++] & 0xf;
|
||||
for (int i = 0; i < NUM_LENGTHS; i++) {
|
||||
numCodes[i] = (short) (buffer.buf[buffer.bufPtr++] & 0xff);
|
||||
}
|
||||
|
||||
int numValues = 0;
|
||||
for (int i = 0; i < NUM_LENGTHS; i++) {
|
||||
numValues += numCodes[i];
|
||||
}
|
||||
values = new short[numValues];
|
||||
for (int i = 0; i < numValues; i++) {
|
||||
values[i] = (short) (buffer.buf[buffer.bufPtr++] & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
Htable(JPEGHuffmanTable table, boolean isDC, int id) {
|
||||
tableClass = isDC ? 0 : 1;
|
||||
tableID = id;
|
||||
numCodes = table.getLengths();
|
||||
values = table.getValues();
|
||||
}
|
||||
|
||||
Htable(Node node) throws IIOInvalidTreeException {
|
||||
if (node.getNodeName().equals("dhtable")) {
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
int count = attrs.getLength();
|
||||
if (count != 2) {
|
||||
throw new IIOInvalidTreeException
|
||||
("dhtable node must have 2 attributes", node);
|
||||
}
|
||||
tableClass = getAttributeValue(node, attrs, "class", 0, 1, true);
|
||||
tableID = getAttributeValue(node, attrs, "htableId", 0, 3, true);
|
||||
if (node instanceof IIOMetadataNode) {
|
||||
IIOMetadataNode ourNode = (IIOMetadataNode) node;
|
||||
JPEGHuffmanTable table =
|
||||
(JPEGHuffmanTable) ourNode.getUserObject();
|
||||
if (table == null) {
|
||||
throw new IIOInvalidTreeException
|
||||
("dhtable node must have user object", node);
|
||||
}
|
||||
numCodes = table.getLengths();
|
||||
values = table.getValues();
|
||||
} else {
|
||||
throw new IIOInvalidTreeException
|
||||
("dhtable node must have user object", node);
|
||||
}
|
||||
} else {
|
||||
throw new IIOInvalidTreeException
|
||||
("Invalid node, expected dqtable", node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
Htable newGuy = null;
|
||||
try {
|
||||
newGuy = (Htable) super.clone();
|
||||
} catch (CloneNotSupportedException e) {} // won't happen
|
||||
if (numCodes != null) {
|
||||
newGuy.numCodes = (short []) numCodes.clone();
|
||||
}
|
||||
if (values != null) {
|
||||
newGuy.values = (short []) values.clone();
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("dhtable");
|
||||
node.setAttribute("class", Integer.toString(tableClass));
|
||||
node.setAttribute("htableId", Integer.toString(tableID));
|
||||
|
||||
node.setUserObject(new JPEGHuffmanTable(numCodes, values));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
void print() {
|
||||
System.out.println("Huffman Table");
|
||||
System.out.println("table class: "
|
||||
+ ((tableClass == 0) ? "DC":"AC"));
|
||||
System.out.println("table id: " + Integer.toString(tableID));
|
||||
|
||||
(new JPEGHuffmanTable(numCodes, values)).toString();
|
||||
/*
|
||||
System.out.print("Lengths:");
|
||||
for (int i=0; i<16; i++) {
|
||||
System.out.print(" " + Integer.toString(numCodes[i]));
|
||||
}
|
||||
int count = 0;
|
||||
if (values.length > 16) {
|
||||
System.out.println("\nFirst 16 Values:");
|
||||
count = 16;
|
||||
} else {
|
||||
System.out.println("\nValues:");
|
||||
count = values.length;
|
||||
}
|
||||
for (int i=0; i<count; i++) {
|
||||
System.out.println(Integer.toString(values[i]&0xff));
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
309
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/DQTMarkerSegment.java
Normal file
309
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/DQTMarkerSegment.java
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.plugins.jpeg.JPEGQTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* A DQT (Define Quantization Table) marker segment.
|
||||
*/
|
||||
class DQTMarkerSegment extends MarkerSegment {
|
||||
List tables = new ArrayList(); // Could be 1 to 4
|
||||
|
||||
DQTMarkerSegment(float quality, boolean needTwo) {
|
||||
super(JPEG.DQT);
|
||||
tables.add(new Qtable(true, quality));
|
||||
if (needTwo) {
|
||||
tables.add(new Qtable(false, quality));
|
||||
}
|
||||
}
|
||||
|
||||
DQTMarkerSegment(JPEGBuffer buffer) throws IOException {
|
||||
super(buffer);
|
||||
int count = length;
|
||||
while (count > 0) {
|
||||
Qtable newGuy = new Qtable(buffer);
|
||||
tables.add(newGuy);
|
||||
count -= newGuy.data.length+1;
|
||||
}
|
||||
buffer.bufAvail -= length;
|
||||
}
|
||||
|
||||
DQTMarkerSegment(JPEGQTable[] qtables) {
|
||||
super(JPEG.DQT);
|
||||
for (int i = 0; i < qtables.length; i++) {
|
||||
tables.add(new Qtable(qtables[i], i));
|
||||
}
|
||||
}
|
||||
|
||||
DQTMarkerSegment(Node node) throws IIOInvalidTreeException {
|
||||
super(JPEG.DQT);
|
||||
NodeList children = node.getChildNodes();
|
||||
int size = children.getLength();
|
||||
if ((size < 1) || (size > 4)) {
|
||||
throw new IIOInvalidTreeException("Invalid DQT node", node);
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
tables.add(new Qtable(children.item(i)));
|
||||
}
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
DQTMarkerSegment newGuy = (DQTMarkerSegment) super.clone();
|
||||
newGuy.tables = new ArrayList(tables.size());
|
||||
Iterator iter = tables.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Qtable table = (Qtable) iter.next();
|
||||
newGuy.tables.add(table.clone());
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("dqt");
|
||||
for (int i= 0; i<tables.size(); i++) {
|
||||
Qtable table = (Qtable) tables.get(i);
|
||||
node.appendChild(table.getNativeNode());
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
// We don't write DQT segments; the IJG library does.
|
||||
}
|
||||
|
||||
void print() {
|
||||
printTag("DQT");
|
||||
System.out.println("Num tables: "
|
||||
+ Integer.toString(tables.size()));
|
||||
for (int i= 0; i<tables.size(); i++) {
|
||||
Qtable table = (Qtable) tables.get(i);
|
||||
table.print();
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assuming the given table was generated by scaling the "standard"
|
||||
* visually lossless luminance table, extract the scale factor that
|
||||
* was used.
|
||||
*/
|
||||
Qtable getChromaForLuma(Qtable luma) {
|
||||
Qtable newGuy = null;
|
||||
// Determine if the table is all the same values
|
||||
// if so, use the same table
|
||||
boolean allSame = true;
|
||||
for (int i = 1; i < luma.QTABLE_SIZE; i++) {
|
||||
if (luma.data[i] != luma.data[i-1]) {
|
||||
allSame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allSame) {
|
||||
newGuy = (Qtable) luma.clone();
|
||||
newGuy.tableID = 1;
|
||||
} else {
|
||||
// Otherwise, find the largest coefficient less than 255. This is
|
||||
// the largest value that we know did not clamp on scaling.
|
||||
int largestPos = 0;
|
||||
for (int i = 1; i < luma.QTABLE_SIZE; i++) {
|
||||
if (luma.data[i] > luma.data[largestPos]) {
|
||||
largestPos = i;
|
||||
}
|
||||
}
|
||||
// Compute the scale factor by dividing it by the value in the
|
||||
// same position from the "standard" table.
|
||||
// If the given table was not generated by scaling the standard,
|
||||
// the resulting table will still be reasonable, as it will reflect
|
||||
// a comparable scaling of chrominance frequency response of the
|
||||
// eye.
|
||||
float scaleFactor = ((float)(luma.data[largestPos]))
|
||||
/ ((float)(JPEGQTable.K1Div2Luminance.getTable()[largestPos]));
|
||||
// generate a new table
|
||||
JPEGQTable jpegTable =
|
||||
JPEGQTable.K2Div2Chrominance.getScaledInstance(scaleFactor,
|
||||
true);
|
||||
newGuy = new Qtable(jpegTable, 1);
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
Qtable getQtableFromNode(Node node) throws IIOInvalidTreeException {
|
||||
return new Qtable(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* A quantization table within a DQT marker segment.
|
||||
*/
|
||||
class Qtable implements Cloneable {
|
||||
int elementPrecision;
|
||||
int tableID;
|
||||
final int QTABLE_SIZE = 64;
|
||||
int [] data; // 64 elements, in natural order
|
||||
|
||||
/**
|
||||
* The zigzag-order position of the i'th element
|
||||
* of a DCT block read in natural order.
|
||||
*/
|
||||
private final int [] zigzag = {
|
||||
0, 1, 5, 6, 14, 15, 27, 28,
|
||||
2, 4, 7, 13, 16, 26, 29, 42,
|
||||
3, 8, 12, 17, 25, 30, 41, 43,
|
||||
9, 11, 18, 24, 31, 40, 44, 53,
|
||||
10, 19, 23, 32, 39, 45, 52, 54,
|
||||
20, 22, 33, 38, 46, 51, 55, 60,
|
||||
21, 34, 37, 47, 50, 56, 59, 61,
|
||||
35, 36, 48, 49, 57, 58, 62, 63
|
||||
};
|
||||
|
||||
Qtable(boolean wantLuma, float quality) {
|
||||
elementPrecision = 0;
|
||||
JPEGQTable base = null;
|
||||
if (wantLuma) {
|
||||
tableID = 0;
|
||||
base = JPEGQTable.K1Div2Luminance;
|
||||
} else {
|
||||
tableID = 1;
|
||||
base = JPEGQTable.K2Div2Chrominance;
|
||||
}
|
||||
if (quality != JPEG.DEFAULT_QUALITY) {
|
||||
quality = JPEG.convertToLinearQuality(quality);
|
||||
if (wantLuma) {
|
||||
base = JPEGQTable.K1Luminance.getScaledInstance
|
||||
(quality, true);
|
||||
} else {
|
||||
base = JPEGQTable.K2Div2Chrominance.getScaledInstance
|
||||
(quality, true);
|
||||
}
|
||||
}
|
||||
data = base.getTable();
|
||||
}
|
||||
|
||||
Qtable(JPEGBuffer buffer) throws IIOException {
|
||||
elementPrecision = buffer.buf[buffer.bufPtr] >>> 4;
|
||||
tableID = buffer.buf[buffer.bufPtr++] & 0xf;
|
||||
if (elementPrecision != 0) {
|
||||
// IJG is compiled for 8-bits, so this shouldn't happen
|
||||
throw new IIOException ("Unsupported element precision");
|
||||
}
|
||||
data = new int [QTABLE_SIZE];
|
||||
// Read from zig-zag order to natural order
|
||||
for (int i = 0; i < QTABLE_SIZE; i++) {
|
||||
data[i] = buffer.buf[buffer.bufPtr+zigzag[i]] & 0xff;
|
||||
}
|
||||
buffer.bufPtr += QTABLE_SIZE;
|
||||
}
|
||||
|
||||
Qtable(JPEGQTable table, int id) {
|
||||
elementPrecision = 0;
|
||||
tableID = id;
|
||||
data = table.getTable();
|
||||
}
|
||||
|
||||
Qtable(Node node) throws IIOInvalidTreeException {
|
||||
if (node.getNodeName().equals("dqtable")) {
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
int count = attrs.getLength();
|
||||
if ((count < 1) || (count > 2)) {
|
||||
throw new IIOInvalidTreeException
|
||||
("dqtable node must have 1 or 2 attributes", node);
|
||||
}
|
||||
elementPrecision = 0;
|
||||
tableID = getAttributeValue(node, attrs, "qtableId", 0, 3, true);
|
||||
if (node instanceof IIOMetadataNode) {
|
||||
IIOMetadataNode ourNode = (IIOMetadataNode) node;
|
||||
JPEGQTable table = (JPEGQTable) ourNode.getUserObject();
|
||||
if (table == null) {
|
||||
throw new IIOInvalidTreeException
|
||||
("dqtable node must have user object", node);
|
||||
}
|
||||
data = table.getTable();
|
||||
} else {
|
||||
throw new IIOInvalidTreeException
|
||||
("dqtable node must have user object", node);
|
||||
}
|
||||
} else {
|
||||
throw new IIOInvalidTreeException
|
||||
("Invalid node, expected dqtable", node);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
Qtable newGuy = null;
|
||||
try {
|
||||
newGuy = (Qtable) super.clone();
|
||||
} catch (CloneNotSupportedException e) {} // won't happen
|
||||
if (data != null) {
|
||||
newGuy.data = (int []) data.clone();
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("dqtable");
|
||||
node.setAttribute("elementPrecision",
|
||||
Integer.toString(elementPrecision));
|
||||
node.setAttribute("qtableId",
|
||||
Integer.toString(tableID));
|
||||
node.setUserObject(new JPEGQTable(data));
|
||||
return node;
|
||||
}
|
||||
|
||||
void print() {
|
||||
System.out.println("Table id: " + Integer.toString(tableID));
|
||||
System.out.println("Element precision: "
|
||||
+ Integer.toString(elementPrecision));
|
||||
|
||||
(new JPEGQTable(data)).toString();
|
||||
/*
|
||||
for (int i = 0; i < 64; i++) {
|
||||
if (i % 8 == 0) {
|
||||
System.out.println();
|
||||
}
|
||||
System.out.print(" " + Integer.toString(data[i]));
|
||||
}
|
||||
System.out.println();
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* A DRI (Define Restart Interval) marker segment.
|
||||
*/
|
||||
class DRIMarkerSegment extends MarkerSegment {
|
||||
/**
|
||||
* Restart interval, or 0 if none is specified.
|
||||
*/
|
||||
int restartInterval = 0;
|
||||
|
||||
DRIMarkerSegment(JPEGBuffer buffer)
|
||||
throws IOException {
|
||||
super(buffer);
|
||||
restartInterval = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
|
||||
restartInterval |= buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
buffer.bufAvail -= length;
|
||||
}
|
||||
|
||||
DRIMarkerSegment(Node node) throws IIOInvalidTreeException {
|
||||
super(JPEG.DRI);
|
||||
updateFromNativeNode(node, true);
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("dri");
|
||||
node.setAttribute("interval", Integer.toString(restartInterval));
|
||||
return node;
|
||||
}
|
||||
|
||||
void updateFromNativeNode(Node node, boolean fromScratch)
|
||||
throws IIOInvalidTreeException {
|
||||
restartInterval = getAttributeValue(node, null, "interval",
|
||||
0, 65535, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
// We don't write DRI segments; the IJG library does.
|
||||
}
|
||||
|
||||
void print() {
|
||||
printTag("DRI");
|
||||
System.out.println("Interval: "
|
||||
+ Integer.toString(restartInterval));
|
||||
}
|
||||
}
|
||||
1564
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java
Normal file
1564
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java
Normal file
File diff suppressed because it is too large
Load Diff
368
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEG.java
Normal file
368
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEG.java
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.plugins.jpeg.JPEGQTable;
|
||||
import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
|
||||
/**
|
||||
* A class containing JPEG-related constants, definitions, and
|
||||
* static methods. This class and its constants must be public so that
|
||||
* <code>JPEGImageWriteParam</code> can see it.
|
||||
*/
|
||||
public class JPEG {
|
||||
|
||||
// List of all the JPEG markers (pre-JPEG2000)
|
||||
|
||||
/** For temporary use in arithmetic coding */
|
||||
public static final int TEM = 0x01;
|
||||
|
||||
// Codes 0x02 - 0xBF are reserved
|
||||
|
||||
// SOF markers for Nondifferential Huffman coding
|
||||
/** Baseline DCT */
|
||||
public static final int SOF0 = 0xC0;
|
||||
/** Extended Sequential DCT */
|
||||
public static final int SOF1 = 0xC1;
|
||||
/** Progressive DCT */
|
||||
public static final int SOF2 = 0xC2;
|
||||
/** Lossless Sequential */
|
||||
public static final int SOF3 = 0xC3;
|
||||
|
||||
/** Define Huffman Tables */
|
||||
public static final int DHT = 0xC4;
|
||||
|
||||
// SOF markers for Differential Huffman coding
|
||||
/** Differential Sequential DCT */
|
||||
public static final int SOF5 = 0xC5;
|
||||
/** Differential Progressive DCT */
|
||||
public static final int SOF6 = 0xC6;
|
||||
/** Differential Lossless */
|
||||
public static final int SOF7 = 0xC7;
|
||||
|
||||
/** Reserved for JPEG extensions */
|
||||
public static final int JPG = 0xC8;
|
||||
|
||||
// SOF markers for Nondifferential arithmetic coding
|
||||
/** Extended Sequential DCT, Arithmetic coding */
|
||||
public static final int SOF9 = 0xC9;
|
||||
/** Progressive DCT, Arithmetic coding */
|
||||
public static final int SOF10 = 0xCA;
|
||||
/** Lossless Sequential, Arithmetic coding */
|
||||
public static final int SOF11 = 0xCB;
|
||||
|
||||
/** Define Arithmetic conditioning tables */
|
||||
public static final int DAC = 0xCC;
|
||||
|
||||
// SOF markers for Differential arithmetic coding
|
||||
/** Differential Sequential DCT, Arithmetic coding */
|
||||
public static final int SOF13 = 0xCD;
|
||||
/** Differential Progressive DCT, Arithmetic coding */
|
||||
public static final int SOF14 = 0xCE;
|
||||
/** Differential Lossless, Arithmetic coding */
|
||||
public static final int SOF15 = 0xCF;
|
||||
|
||||
// Restart Markers
|
||||
public static final int RST0 = 0xD0;
|
||||
public static final int RST1 = 0xD1;
|
||||
public static final int RST2 = 0xD2;
|
||||
public static final int RST3 = 0xD3;
|
||||
public static final int RST4 = 0xD4;
|
||||
public static final int RST5 = 0xD5;
|
||||
public static final int RST6 = 0xD6;
|
||||
public static final int RST7 = 0xD7;
|
||||
/** Number of restart markers */
|
||||
public static final int RESTART_RANGE = 8;
|
||||
|
||||
/** Start of Image */
|
||||
public static final int SOI = 0xD8;
|
||||
/** End of Image */
|
||||
public static final int EOI = 0xD9;
|
||||
/** Start of Scan */
|
||||
public static final int SOS = 0xDA;
|
||||
|
||||
/** Define Quantisation Tables */
|
||||
public static final int DQT = 0xDB;
|
||||
|
||||
/** Define Number of lines */
|
||||
public static final int DNL = 0xDC;
|
||||
|
||||
/** Define Restart Interval */
|
||||
public static final int DRI = 0xDD;
|
||||
|
||||
/** Define Heirarchical progression */
|
||||
public static final int DHP = 0xDE;
|
||||
|
||||
/** Expand reference image(s) */
|
||||
public static final int EXP = 0xDF;
|
||||
|
||||
// Application markers
|
||||
/** APP0 used by JFIF */
|
||||
public static final int APP0 = 0xE0;
|
||||
public static final int APP1 = 0xE1;
|
||||
public static final int APP2 = 0xE2;
|
||||
public static final int APP3 = 0xE3;
|
||||
public static final int APP4 = 0xE4;
|
||||
public static final int APP5 = 0xE5;
|
||||
public static final int APP6 = 0xE6;
|
||||
public static final int APP7 = 0xE7;
|
||||
public static final int APP8 = 0xE8;
|
||||
public static final int APP9 = 0xE9;
|
||||
public static final int APP10 = 0xEA;
|
||||
public static final int APP11 = 0xEB;
|
||||
public static final int APP12 = 0xEC;
|
||||
public static final int APP13 = 0xED;
|
||||
/** APP14 used by Adobe */
|
||||
public static final int APP14 = 0xEE;
|
||||
public static final int APP15 = 0xEF;
|
||||
|
||||
// codes 0xF0 to 0xFD are reserved
|
||||
|
||||
/** Comment marker */
|
||||
public static final int COM = 0xFE;
|
||||
|
||||
// JFIF Resolution units
|
||||
/** The X and Y units simply indicate the aspect ratio of the pixels. */
|
||||
public static final int DENSITY_UNIT_ASPECT_RATIO = 0;
|
||||
/** Pixel density is in pixels per inch. */
|
||||
public static final int DENSITY_UNIT_DOTS_INCH = 1;
|
||||
/** Pixel density is in pixels per centemeter. */
|
||||
public static final int DENSITY_UNIT_DOTS_CM = 2;
|
||||
/** The max known value for DENSITY_UNIT */
|
||||
public static final int NUM_DENSITY_UNIT = 3;
|
||||
|
||||
// Adobe transform values
|
||||
public static final int ADOBE_IMPOSSIBLE = -1;
|
||||
public static final int ADOBE_UNKNOWN = 0;
|
||||
public static final int ADOBE_YCC = 1;
|
||||
public static final int ADOBE_YCCK = 2;
|
||||
|
||||
// Spi initialization stuff
|
||||
public static final String vendor = "Oracle Corporation";
|
||||
public static final String version = "0.5";
|
||||
// Names of the formats we can read or write
|
||||
static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"};
|
||||
static final String [] suffixes = {"jpg", "jpeg"};
|
||||
static final String [] MIMETypes = {"image/jpeg"};
|
||||
public static final String nativeImageMetadataFormatName =
|
||||
"javax_imageio_jpeg_image_1.0";
|
||||
public static final String nativeImageMetadataFormatClassName =
|
||||
"com.sun.imageio.plugins.jpeg.JPEGImageMetadataFormat";
|
||||
public static final String nativeStreamMetadataFormatName =
|
||||
"javax_imageio_jpeg_stream_1.0";
|
||||
public static final String nativeStreamMetadataFormatClassName =
|
||||
"com.sun.imageio.plugins.jpeg.JPEGStreamMetadataFormat";
|
||||
|
||||
// IJG Color codes.
|
||||
public static final int JCS_UNKNOWN = 0; // error/unspecified
|
||||
public static final int JCS_GRAYSCALE = 1; // monochrome
|
||||
public static final int JCS_RGB = 2; // red/green/blue
|
||||
public static final int JCS_YCbCr = 3; // Y/Cb/Cr (also known as YUV)
|
||||
public static final int JCS_CMYK = 4; // C/M/Y/K
|
||||
public static final int JCS_YCC = 5; // PhotoYCC
|
||||
public static final int JCS_RGBA = 6; // RGB-Alpha
|
||||
public static final int JCS_YCbCrA = 7; // Y/Cb/Cr/Alpha
|
||||
// 8 and 9 were old "Legacy" codes which the old code never identified
|
||||
// on reading anyway. Support for writing them is being dropped, too.
|
||||
public static final int JCS_YCCA = 10; // PhotoYCC-Alpha
|
||||
public static final int JCS_YCCK = 11; // Y/Cb/Cr/K
|
||||
|
||||
public static final int NUM_JCS_CODES = JCS_YCCK+1;
|
||||
|
||||
/** IJG can handle up to 4-channel JPEGs */
|
||||
static final int [] [] bandOffsets = {{0},
|
||||
{0, 1},
|
||||
{0, 1, 2},
|
||||
{0, 1, 2, 3}};
|
||||
|
||||
static final int [] bOffsRGB = { 2, 1, 0 };
|
||||
|
||||
/* These are kept in the inner class to avoid static initialization
|
||||
* of the CMM class until someone actually needs it.
|
||||
* (e.g. do not init CMM on the request for jpeg mime types)
|
||||
*/
|
||||
public static class JCS {
|
||||
public static final ColorSpace sRGB =
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
|
||||
private static ColorSpace YCC = null;
|
||||
private static boolean yccInited = false;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Default value for ImageWriteParam
|
||||
public static final float DEFAULT_QUALITY = 0.75F;
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given <code>ColorSpace</code>
|
||||
* object is an instance of ICC_ColorSpace but is not one of the
|
||||
* standard <code>ColorSpaces</code> returned by
|
||||
* <code>ColorSpace.getInstance()</code>.
|
||||
*/
|
||||
static boolean isNonStandardICC(ColorSpace cs) {
|
||||
boolean retval = false;
|
||||
if ((cs instanceof ICC_ColorSpace)
|
||||
&& (!cs.isCS_sRGB())
|
||||
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_CIEXYZ)))
|
||||
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_GRAY)))
|
||||
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB)))
|
||||
&& (!cs.equals(ColorSpace.getInstance(ColorSpace.CS_PYCC)))
|
||||
) {
|
||||
retval = true;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given imageType can be used
|
||||
* in a JFIF file. If <code>input</code> is true, then the
|
||||
* image type is considered before colorspace conversion.
|
||||
*/
|
||||
static boolean isJFIFcompliant(ImageTypeSpecifier imageType,
|
||||
boolean input) {
|
||||
ColorModel cm = imageType.getColorModel();
|
||||
// Can't have alpha
|
||||
if (cm.hasAlpha()) {
|
||||
return false;
|
||||
}
|
||||
// Gray is OK, always
|
||||
int numComponents = imageType.getNumComponents();
|
||||
if (numComponents == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it isn't gray, it must have 3 channels
|
||||
if (numComponents != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input) {
|
||||
// Must be RGB
|
||||
if (cm.getColorSpace().getType() == ColorSpace.TYPE_RGB) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Must be YCbCr
|
||||
if (cm.getColorSpace().getType() == ColorSpace.TYPE_YCbCr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an image type, return the Adobe transform corresponding to
|
||||
* that type, or ADOBE_IMPOSSIBLE if the image type is incompatible
|
||||
* with an Adobe marker segment. If <code>input</code> is true, then
|
||||
* the image type is considered before colorspace conversion.
|
||||
*/
|
||||
static int transformForType(ImageTypeSpecifier imageType, boolean input) {
|
||||
int retval = ADOBE_IMPOSSIBLE;
|
||||
ColorModel cm = imageType.getColorModel();
|
||||
switch (cm.getColorSpace().getType()) {
|
||||
case ColorSpace.TYPE_GRAY:
|
||||
retval = ADOBE_UNKNOWN;
|
||||
break;
|
||||
case ColorSpace.TYPE_RGB:
|
||||
retval = input ? ADOBE_YCC : ADOBE_UNKNOWN;
|
||||
break;
|
||||
case ColorSpace.TYPE_YCbCr:
|
||||
retval = ADOBE_YCC;
|
||||
break;
|
||||
case ColorSpace.TYPE_CMYK:
|
||||
retval = input ? ADOBE_YCCK : ADOBE_IMPOSSIBLE;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an ImageWriteParam (i.e. IJG) non-linear quality value
|
||||
* to a float suitable for passing to JPEGQTable.getScaledInstance().
|
||||
*/
|
||||
static float convertToLinearQuality(float quality) {
|
||||
// The following is converted from the IJG code.
|
||||
if (quality <= 0.0F) {
|
||||
quality = 0.01F;
|
||||
}
|
||||
|
||||
if (quality > 1.00F) {
|
||||
quality = 1.00F;
|
||||
}
|
||||
|
||||
if (quality < 0.5F) {
|
||||
quality = 0.5F / quality;
|
||||
} else {
|
||||
quality = 2.0F - (quality * 2.0F);
|
||||
}
|
||||
|
||||
return quality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of default, visually lossless quantization tables.
|
||||
*/
|
||||
static JPEGQTable [] getDefaultQTables() {
|
||||
JPEGQTable [] qTables = new JPEGQTable[2];
|
||||
qTables[0] = JPEGQTable.K1Div2Luminance;
|
||||
qTables[1] = JPEGQTable.K2Div2Chrominance;
|
||||
return qTables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of default Huffman tables.
|
||||
*/
|
||||
static JPEGHuffmanTable [] getDefaultHuffmanTables(boolean wantDC) {
|
||||
JPEGHuffmanTable [] tables = new JPEGHuffmanTable[2];
|
||||
if (wantDC) {
|
||||
tables[0] = JPEGHuffmanTable.StdDCLuminance;
|
||||
tables[1] = JPEGHuffmanTable.StdDCChrominance;
|
||||
} else {
|
||||
tables[0] = JPEGHuffmanTable.StdACLuminance;
|
||||
tables[1] = JPEGHuffmanTable.StdACChrominance;
|
||||
}
|
||||
return tables;
|
||||
}
|
||||
|
||||
}
|
||||
254
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGBuffer.java
Normal file
254
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGBuffer.java
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A class wrapping a buffer and its state. For efficiency,
|
||||
* the members are made visible to other classes in this package.
|
||||
*/
|
||||
class JPEGBuffer {
|
||||
|
||||
private boolean debug = false;
|
||||
|
||||
/**
|
||||
* The size of the buffer. This is large enough to hold all
|
||||
* known marker segments (other than thumbnails and icc profiles)
|
||||
*/
|
||||
final int BUFFER_SIZE = 4096;
|
||||
|
||||
/**
|
||||
* The actual buffer.
|
||||
*/
|
||||
byte [] buf;
|
||||
|
||||
/**
|
||||
* The number of bytes available for reading from the buffer.
|
||||
* Anytime data is read from the buffer, this should be updated.
|
||||
*/
|
||||
int bufAvail;
|
||||
|
||||
/**
|
||||
* A pointer to the next available byte in the buffer. This is
|
||||
* used to read data from the buffer and must be updated to
|
||||
* move through the buffer.
|
||||
*/
|
||||
int bufPtr;
|
||||
|
||||
/**
|
||||
* The ImageInputStream buffered.
|
||||
*/
|
||||
ImageInputStream iis;
|
||||
|
||||
JPEGBuffer (ImageInputStream iis) {
|
||||
buf = new byte[BUFFER_SIZE];
|
||||
bufAvail = 0;
|
||||
bufPtr = 0;
|
||||
this.iis = iis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that there are at least <code>count</code> bytes available
|
||||
* in the buffer, loading more data and moving any remaining
|
||||
* bytes to the front. A count of 0 means to just fill the buffer.
|
||||
* If the count is larger than the buffer size, just fills the buffer.
|
||||
* If the end of the stream is encountered before a non-0 count can
|
||||
* be satisfied, an <code>IIOException</code> is thrown with the
|
||||
* message "Image Format Error".
|
||||
*/
|
||||
void loadBuf(int count) throws IOException {
|
||||
if (debug) {
|
||||
System.out.print("loadbuf called with ");
|
||||
System.out.print("count " + count + ", ");
|
||||
System.out.println("bufAvail " + bufAvail + ", ");
|
||||
}
|
||||
if (count != 0) {
|
||||
if (bufAvail >= count) { // have enough
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (bufAvail == BUFFER_SIZE) { // already full
|
||||
return;
|
||||
}
|
||||
}
|
||||
// First copy any remaining bytes down to the beginning
|
||||
if ((bufAvail > 0) && (bufAvail < BUFFER_SIZE)) {
|
||||
System.arraycopy(buf, bufPtr, buf, 0, bufAvail);
|
||||
}
|
||||
// Now fill the rest of the buffer
|
||||
int ret = iis.read(buf, bufAvail, buf.length - bufAvail);
|
||||
if (debug) {
|
||||
System.out.println("iis.read returned " + ret);
|
||||
}
|
||||
if (ret != -1) {
|
||||
bufAvail += ret;
|
||||
}
|
||||
bufPtr = 0;
|
||||
int minimum = Math.min(BUFFER_SIZE, count);
|
||||
if (bufAvail < minimum) {
|
||||
throw new IIOException ("Image Format Error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the data array from the stream, starting with
|
||||
* the buffer and then reading directly from the stream
|
||||
* if necessary. The buffer is left in an appropriate
|
||||
* state. If the end of the stream is encountered, an
|
||||
* <code>IIOException</code> is thrown with the
|
||||
* message "Image Format Error".
|
||||
*/
|
||||
void readData(byte [] data) throws IOException {
|
||||
int count = data.length;
|
||||
// First see what's left in the buffer.
|
||||
if (bufAvail >= count) { // It's enough
|
||||
System.arraycopy(buf, bufPtr, data, 0, count);
|
||||
bufAvail -= count;
|
||||
bufPtr += count;
|
||||
return;
|
||||
}
|
||||
int offset = 0;
|
||||
if (bufAvail > 0) { // Some there, but not enough
|
||||
System.arraycopy(buf, bufPtr, data, 0, bufAvail);
|
||||
offset = bufAvail;
|
||||
count -= bufAvail;
|
||||
bufAvail = 0;
|
||||
bufPtr = 0;
|
||||
}
|
||||
// Now read the rest directly from the stream
|
||||
if (iis.read(data, offset, count) != count) {
|
||||
throw new IIOException ("Image format Error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips <code>count</code> bytes, leaving the buffer
|
||||
* in an appropriate state. If the end of the stream is
|
||||
* encountered, an <code>IIOException</code> is thrown with the
|
||||
* message "Image Format Error".
|
||||
*/
|
||||
void skipData(int count) throws IOException {
|
||||
// First see what's left in the buffer.
|
||||
if (bufAvail >= count) { // It's enough
|
||||
bufAvail -= count;
|
||||
bufPtr += count;
|
||||
return;
|
||||
}
|
||||
if (bufAvail > 0) { // Some there, but not enough
|
||||
count -= bufAvail;
|
||||
bufAvail = 0;
|
||||
bufPtr = 0;
|
||||
}
|
||||
// Now read the rest directly from the stream
|
||||
if (iis.skipBytes(count) != count) {
|
||||
throw new IIOException ("Image format Error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push back the remaining contents of the buffer by
|
||||
* repositioning the input stream.
|
||||
*/
|
||||
void pushBack() throws IOException {
|
||||
iis.seek(iis.getStreamPosition()-bufAvail);
|
||||
bufAvail = 0;
|
||||
bufPtr = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stream position corresponding to the next
|
||||
* available byte in the buffer.
|
||||
*/
|
||||
long getStreamPosition() throws IOException {
|
||||
return (iis.getStreamPosition()-bufAvail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the buffer until the next 0xff byte, reloading
|
||||
* the buffer as necessary. The buffer position is left
|
||||
* pointing to the first non-0xff byte after a run of
|
||||
* 0xff bytes. If the end of the stream is encountered,
|
||||
* an EOI marker is inserted into the buffer and <code>true</code>
|
||||
* is returned. Otherwise returns <code>false</code>.
|
||||
*/
|
||||
boolean scanForFF(JPEGImageReader reader) throws IOException {
|
||||
boolean retval = false;
|
||||
boolean foundFF = false;
|
||||
while (foundFF == false) {
|
||||
while (bufAvail > 0) {
|
||||
if ((buf[bufPtr++] & 0xff) == 0xff) {
|
||||
bufAvail--;
|
||||
foundFF = true;
|
||||
break; // out of inner while
|
||||
}
|
||||
bufAvail--;
|
||||
}
|
||||
// Reload the buffer and keep going
|
||||
loadBuf(0);
|
||||
// Skip any remaining pad bytes
|
||||
if (foundFF == true) {
|
||||
while ((bufAvail > 0) && (buf[bufPtr] & 0xff) == 0xff) {
|
||||
bufPtr++; // Only if it still is 0xff
|
||||
bufAvail--;
|
||||
}
|
||||
}
|
||||
if (bufAvail == 0) { // Premature EOF
|
||||
// send out a warning, but treat it as EOI
|
||||
//reader.warningOccurred(JPEGImageReader.WARNING_NO_EOI);
|
||||
retval = true;
|
||||
buf[0] = (byte)JPEG.EOI;
|
||||
bufAvail = 1;
|
||||
bufPtr = 0;
|
||||
foundFF = true;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the contents of the buffer, in hex.
|
||||
* @param count the number of bytes to print,
|
||||
* starting at the current available byte.
|
||||
*/
|
||||
void print(int count) {
|
||||
System.out.print("buffer has ");
|
||||
System.out.print(bufAvail);
|
||||
System.out.println(" bytes available");
|
||||
if (bufAvail < count) {
|
||||
count = bufAvail;
|
||||
}
|
||||
for (int ptr = bufPtr; count > 0; count--) {
|
||||
int val = (int)buf[ptr++] & 0xff;
|
||||
System.out.print(" " + Integer.toHexString(val));
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ColorModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class JPEGImageMetadataFormat extends JPEGMetadataFormat {
|
||||
|
||||
private static JPEGImageMetadataFormat theInstance = null;
|
||||
|
||||
private JPEGImageMetadataFormat() {
|
||||
super(JPEG.nativeImageMetadataFormatName,
|
||||
CHILD_POLICY_ALL);
|
||||
|
||||
addElement("JPEGvariety",
|
||||
JPEG.nativeImageMetadataFormatName,
|
||||
CHILD_POLICY_CHOICE);
|
||||
|
||||
addElement("markerSequence",
|
||||
JPEG.nativeImageMetadataFormatName,
|
||||
CHILD_POLICY_SEQUENCE);
|
||||
|
||||
addElement("app0JFIF", "JPEGvariety", CHILD_POLICY_SOME);
|
||||
|
||||
addStreamElements("markerSequence");
|
||||
|
||||
addElement("app14Adobe", "markerSequence", CHILD_POLICY_EMPTY);
|
||||
|
||||
addElement("sof", "markerSequence", 1, 4);
|
||||
|
||||
addElement("sos", "markerSequence", 1, 4);
|
||||
|
||||
addElement("JFXX", "app0JFIF", 1, Integer.MAX_VALUE);
|
||||
|
||||
addElement("app0JFXX", "JFXX", CHILD_POLICY_CHOICE);
|
||||
|
||||
addElement("app2ICC", "app0JFIF", CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("app0JFIF",
|
||||
"majorVersion",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"1",
|
||||
"0", "255",
|
||||
true, true);
|
||||
addAttribute("app0JFIF",
|
||||
"minorVersion",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"2",
|
||||
"0", "255",
|
||||
true, true);
|
||||
List resUnits = new ArrayList();
|
||||
resUnits.add("0");
|
||||
resUnits.add("1");
|
||||
resUnits.add("2");
|
||||
addAttribute("app0JFIF",
|
||||
"resUnits",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
resUnits);
|
||||
addAttribute("app0JFIF",
|
||||
"Xdensity",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"1",
|
||||
"1", "65535",
|
||||
true, true);
|
||||
addAttribute("app0JFIF",
|
||||
"Ydensity",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"1",
|
||||
"1", "65535",
|
||||
true, true);
|
||||
addAttribute("app0JFIF",
|
||||
"thumbWidth",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "255",
|
||||
true, true);
|
||||
addAttribute("app0JFIF",
|
||||
"thumbHeight",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "255",
|
||||
true, true);
|
||||
|
||||
addElement("JFIFthumbJPEG", "app0JFXX", CHILD_POLICY_SOME);
|
||||
addElement("JFIFthumbPalette", "app0JFXX", CHILD_POLICY_EMPTY);
|
||||
addElement("JFIFthumbRGB", "app0JFXX", CHILD_POLICY_EMPTY);
|
||||
|
||||
List codes = new ArrayList();
|
||||
codes.add("16"); // Hex 10
|
||||
codes.add("17"); // Hex 11
|
||||
codes.add("19"); // Hex 13
|
||||
addAttribute("app0JFXX",
|
||||
"extensionCode",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
codes);
|
||||
|
||||
addChildElement("markerSequence", "JFIFthumbJPEG");
|
||||
|
||||
addAttribute("JFIFthumbPalette",
|
||||
"thumbWidth",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
"0", "255",
|
||||
true, true);
|
||||
addAttribute("JFIFthumbPalette",
|
||||
"thumbHeight",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
"0", "255",
|
||||
true, true);
|
||||
|
||||
addAttribute("JFIFthumbRGB",
|
||||
"thumbWidth",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
"0", "255",
|
||||
true, true);
|
||||
addAttribute("JFIFthumbRGB",
|
||||
"thumbHeight",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
"0", "255",
|
||||
true, true);
|
||||
|
||||
addObjectValue("app2ICC", ICC_Profile.class, false, null);
|
||||
|
||||
addAttribute("app14Adobe",
|
||||
"version",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"100",
|
||||
"100", "255",
|
||||
true, true);
|
||||
addAttribute("app14Adobe",
|
||||
"flags0",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "65535",
|
||||
true, true);
|
||||
addAttribute("app14Adobe",
|
||||
"flags1",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "65535",
|
||||
true, true);
|
||||
|
||||
List transforms = new ArrayList();
|
||||
transforms.add("0");
|
||||
transforms.add("1");
|
||||
transforms.add("2");
|
||||
addAttribute("app14Adobe",
|
||||
"transform",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
transforms);
|
||||
|
||||
addElement("componentSpec", "sof", CHILD_POLICY_EMPTY);
|
||||
|
||||
List procs = new ArrayList();
|
||||
procs.add("0");
|
||||
procs.add("1");
|
||||
procs.add("2");
|
||||
addAttribute("sof",
|
||||
"process",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
procs);
|
||||
addAttribute("sof",
|
||||
"samplePrecision",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"8");
|
||||
addAttribute("sof",
|
||||
"numLines",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
"0", "65535",
|
||||
true, true);
|
||||
addAttribute("sof",
|
||||
"samplesPerLine",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
"0", "65535",
|
||||
true, true);
|
||||
List comps = new ArrayList();
|
||||
comps.add("1");
|
||||
comps.add("2");
|
||||
comps.add("3");
|
||||
comps.add("4");
|
||||
addAttribute("sof",
|
||||
"numFrameComponents",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
null,
|
||||
comps);
|
||||
|
||||
addAttribute("componentSpec",
|
||||
"componentId",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"0", "255",
|
||||
true, true);
|
||||
addAttribute("componentSpec",
|
||||
"HsamplingFactor",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"1", "255",
|
||||
true, true);
|
||||
addAttribute("componentSpec",
|
||||
"VsamplingFactor",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"1", "255",
|
||||
true, true);
|
||||
List tabids = new ArrayList();
|
||||
tabids.add("0");
|
||||
tabids.add("1");
|
||||
tabids.add("2");
|
||||
tabids.add("3");
|
||||
addAttribute("componentSpec",
|
||||
"QtableSelector",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
tabids);
|
||||
|
||||
addElement("scanComponentSpec", "sos", CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sos",
|
||||
"numScanComponents",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
comps);
|
||||
addAttribute("sos",
|
||||
"startSpectralSelection",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "63",
|
||||
true, true);
|
||||
addAttribute("sos",
|
||||
"endSpectralSelection",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"63",
|
||||
"0", "63",
|
||||
true, true);
|
||||
addAttribute("sos",
|
||||
"approxHigh",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "15",
|
||||
true, true);
|
||||
addAttribute("sos",
|
||||
"approxLow",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0",
|
||||
"0", "15",
|
||||
true, true);
|
||||
|
||||
addAttribute("scanComponentSpec",
|
||||
"componentSelector",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"0", "255",
|
||||
true, true);
|
||||
addAttribute("scanComponentSpec",
|
||||
"dcHuffTable",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
tabids);
|
||||
addAttribute("scanComponentSpec",
|
||||
"acHuffTable",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
tabids);
|
||||
}
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
// All images can have these
|
||||
if (elementName.equals(getRootName())
|
||||
|| elementName.equals("JPEGvariety")
|
||||
|| isInSubtree(elementName, "markerSequence")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it is an element in the app0jfif subtree, just check
|
||||
// that the image type is JFIF compliant.
|
||||
if ((isInSubtree(elementName, "app0JFIF"))
|
||||
&& JPEG.isJFIFcompliant(imageType, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static synchronized IIOMetadataFormat getInstance() {
|
||||
if (theInstance == null) {
|
||||
theInstance = new JPEGImageMetadataFormat();
|
||||
}
|
||||
return theInstance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class JPEGImageMetadataFormatResources
|
||||
extends JPEGMetadataFormatResources {
|
||||
|
||||
static final Object[][] imageContents = {
|
||||
// Node name, followed by description
|
||||
{ "JPEGvariety", "A node grouping all marker segments specific to the variety of stream being read/written (e.g. JFIF) - may be empty" },
|
||||
{ "markerSequence", "A node grouping all non-jfif marker segments" },
|
||||
{ "app0jfif", "A JFIF APP0 marker segment" },
|
||||
{ "app14Adobe", "An Adobe APP14 marker segment" },
|
||||
{ "sof", "A Start Of Frame marker segment" },
|
||||
{ "sos", "A Start Of Scan marker segment" },
|
||||
{ "app0JFXX", "A JFIF extension marker segment" },
|
||||
{ "app2ICC", "An ICC profile APP2 marker segment" },
|
||||
{ "JFIFthumbJPEG",
|
||||
"A JFIF thumbnail in JPEG format (no JFIF segments permitted)" },
|
||||
{ "JFIFthumbPalette", "A JFIF thumbnail as an RGB indexed image" },
|
||||
{ "JFIFthumbRGB", "A JFIF thumbnail as an RGB image" },
|
||||
{ "componentSpec", "A component specification for a frame" },
|
||||
{ "scanComponentSpec", "A component specification for a scan" },
|
||||
|
||||
// Node name + "/" + AttributeName, followed by description
|
||||
{ "app0JFIF/majorVersion",
|
||||
"The major JFIF version number" },
|
||||
{ "app0JFIF/minorVersion",
|
||||
"The minor JFIF version number" },
|
||||
{ "app0JFIF/resUnits",
|
||||
"The resolution units for Xdensity and Ydensity "
|
||||
+ "(0 = no units, just aspect ratio; 1 = dots/inch; 2 = dots/cm)" },
|
||||
{ "app0JFIF/Xdensity",
|
||||
"The horizontal density or aspect ratio numerator" },
|
||||
{ "app0JFIF/Ydensity",
|
||||
"The vertical density or aspect ratio denominator" },
|
||||
{ "app0JFIF/thumbWidth",
|
||||
"The width of the thumbnail, or 0 if there isn't one" },
|
||||
{ "app0JFIF/thumbHeight",
|
||||
"The height of the thumbnail, or 0 if there isn't one" },
|
||||
{ "app0JFXX/extensionCode",
|
||||
"The JFXX extension code identifying thumbnail type: "
|
||||
+ "(16 = JPEG, 17 = indexed, 19 = RGB" },
|
||||
{ "JFIFthumbPalette/thumbWidth",
|
||||
"The width of the thumbnail" },
|
||||
{ "JFIFthumbPalette/thumbHeight",
|
||||
"The height of the thumbnail" },
|
||||
{ "JFIFthumbRGB/thumbWidth",
|
||||
"The width of the thumbnail" },
|
||||
{ "JFIFthumbRGB/thumbHeight",
|
||||
"The height of the thumbnail" },
|
||||
{ "app14Adobe/version",
|
||||
"The version of Adobe APP14 marker segment" },
|
||||
{ "app14Adobe/flags0",
|
||||
"The flags0 variable of an APP14 marker segment" },
|
||||
{ "app14Adobe/flags1",
|
||||
"The flags1 variable of an APP14 marker segment" },
|
||||
{ "app14Adobe/transform",
|
||||
"The color transform applied to the image "
|
||||
+ "(0 = Unknown, 1 = YCbCr, 2 = YCCK)" },
|
||||
{ "sof/process",
|
||||
"The JPEG process (0 = Baseline sequential, "
|
||||
+ "1 = Extended sequential, 2 = Progressive)" },
|
||||
{ "sof/samplePrecision",
|
||||
"The number of bits per sample" },
|
||||
{ "sof/numLines",
|
||||
"The number of lines in the image" },
|
||||
{ "sof/samplesPerLine",
|
||||
"The number of samples per line" },
|
||||
{ "sof/numFrameComponents",
|
||||
"The number of components in the image" },
|
||||
{ "componentSpec/componentId",
|
||||
"The id for this component" },
|
||||
{ "componentSpec/HsamplingFactor",
|
||||
"The horizontal sampling factor for this component" },
|
||||
{ "componentSpec/VsamplingFactor",
|
||||
"The vertical sampling factor for this component" },
|
||||
{ "componentSpec/QtableSelector",
|
||||
"The quantization table to use for this component" },
|
||||
{ "sos/numScanComponents",
|
||||
"The number of components in the scan" },
|
||||
{ "sos/startSpectralSelection",
|
||||
"The first spectral band included in this scan" },
|
||||
{ "sos/endSpectralSelection",
|
||||
"The last spectral band included in this scan" },
|
||||
{ "sos/approxHigh",
|
||||
"The highest bit position included in this scan" },
|
||||
{ "sos/approxLow",
|
||||
"The lowest bit position included in this scan" },
|
||||
{ "scanComponentSpec/componentSelector",
|
||||
"The id of this component" },
|
||||
{ "scanComponentSpec/dcHuffTable",
|
||||
"The huffman table to use for encoding DC coefficients" },
|
||||
{ "scanComponentSpec/acHuffTable",
|
||||
"The huffman table to use for encoding AC coefficients" }
|
||||
};
|
||||
|
||||
public JPEGImageMetadataFormatResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
// return a copy of the combined commonContents and imageContents;
|
||||
// in theory we want a deep clone of the combined arrays,
|
||||
// but since it only contains (immutable) Strings, this shallow
|
||||
// copy is sufficient
|
||||
Object[][] combinedContents =
|
||||
new Object[commonContents.length + imageContents.length][2];
|
||||
int combined = 0;
|
||||
for (int i = 0; i < commonContents.length; i++, combined++) {
|
||||
combinedContents[combined][0] = commonContents[i][0];
|
||||
combinedContents[combined][1] = commonContents[i][1];
|
||||
}
|
||||
for (int i = 0; i < imageContents.length; i++, combined++) {
|
||||
combinedContents[combined][0] = imageContents[i][0];
|
||||
combinedContents[combined][1] = imageContents[i][1];
|
||||
}
|
||||
return combinedContents;
|
||||
}
|
||||
}
|
||||
1858
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGImageReader.java
Normal file
1858
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGImageReader.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class JPEGImageReaderResources extends ListResourceBundle {
|
||||
|
||||
public JPEGImageReaderResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
|
||||
{Integer.toString(JPEGImageReader.WARNING_NO_EOI),
|
||||
"Truncated File - Missing EOI marker"},
|
||||
{Integer.toString(JPEGImageReader.WARNING_NO_JFIF_IN_THUMB),
|
||||
"JFIF markers not allowed in JFIF JPEG thumbnail; ignored"},
|
||||
{Integer.toString(JPEGImageReader.WARNING_IGNORE_INVALID_ICC),
|
||||
"Embedded color profile is invalid; ignored"}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
public class JPEGImageReaderSpi extends ImageReaderSpi {
|
||||
|
||||
private static String [] writerSpiNames =
|
||||
{"com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi"};
|
||||
|
||||
public JPEGImageReaderSpi() {
|
||||
super(JPEG.vendor,
|
||||
JPEG.version,
|
||||
JPEG.names,
|
||||
JPEG.suffixes,
|
||||
JPEG.MIMETypes,
|
||||
"com.sun.imageio.plugins.jpeg.JPEGImageReader",
|
||||
new Class[] { ImageInputStream.class },
|
||||
writerSpiNames,
|
||||
true,
|
||||
JPEG.nativeStreamMetadataFormatName,
|
||||
JPEG.nativeStreamMetadataFormatClassName,
|
||||
null, null,
|
||||
true,
|
||||
JPEG.nativeImageMetadataFormatName,
|
||||
JPEG.nativeImageMetadataFormatClassName,
|
||||
null, null
|
||||
);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard JPEG Image Reader";
|
||||
}
|
||||
|
||||
public boolean canDecodeInput(Object source) throws IOException {
|
||||
if (!(source instanceof ImageInputStream)) {
|
||||
return false;
|
||||
}
|
||||
ImageInputStream iis = (ImageInputStream) source;
|
||||
iis.mark();
|
||||
// If the first two bytes are a JPEG SOI marker, it's probably
|
||||
// a JPEG file. If they aren't, it definitely isn't a JPEG file.
|
||||
int byte1 = iis.read();
|
||||
int byte2 = iis.read();
|
||||
iis.reset();
|
||||
if ((byte1 == 0xFF) && (byte2 == JPEG.SOI)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ImageReader createReaderInstance(Object extension)
|
||||
throws IIOException {
|
||||
return new JPEGImageReader(this);
|
||||
}
|
||||
|
||||
}
|
||||
1939
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java
Normal file
1939
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class JPEGImageWriterResources extends ListResourceBundle {
|
||||
|
||||
public JPEGImageWriterResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
|
||||
{Integer.toString(JPEGImageWriter.WARNING_DEST_IGNORED),
|
||||
"Only Rasters or band subsets may be written with a destination type. "
|
||||
+ "Destination type ignored."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_STREAM_METADATA_IGNORED),
|
||||
"Stream metadata ignored on write"},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_DEST_METADATA_COMP_MISMATCH),
|
||||
"Metadata component ids incompatible with destination type. "
|
||||
+ "Metadata modified."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_DEST_METADATA_JFIF_MISMATCH),
|
||||
"Metadata JFIF settings incompatible with destination type. "
|
||||
+ "Metadata modified."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_DEST_METADATA_ADOBE_MISMATCH),
|
||||
"Metadata Adobe settings incompatible with destination type. "
|
||||
+ "Metadata modified."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_IMAGE_METADATA_JFIF_MISMATCH),
|
||||
"Metadata JFIF settings incompatible with image type. "
|
||||
+ "Metadata modified."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_IMAGE_METADATA_ADOBE_MISMATCH),
|
||||
"Metadata Adobe settings incompatible with image type. "
|
||||
+ "Metadata modified."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_METADATA_NOT_JPEG_FOR_RASTER),
|
||||
"Metadata must be JPEGMetadata when writing a Raster. "
|
||||
+ "Metadata ignored."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_NO_BANDS_ON_INDEXED),
|
||||
"Band subset not allowed for an IndexColorModel image. "
|
||||
+ "Band subset ignored."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_ILLEGAL_THUMBNAIL),
|
||||
"Thumbnails must be simple (possibly index) RGB or grayscale. "
|
||||
+ "Incompatible thumbnail ignored."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_IGNORING_THUMBS ),
|
||||
"Thumbnails ignored for non-JFIF-compatible image."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_FORCING_JFIF ),
|
||||
"Thumbnails require JFIF marker segment. "
|
||||
+ "Missing node added to metadata."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_THUMB_CLIPPED ),
|
||||
"Thumbnail clipped."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_METADATA_ADJUSTED_FOR_THUMB ),
|
||||
"Metadata adjusted (made JFIF-compatible) for thumbnail."},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_NO_RGB_THUMB_AS_INDEXED ),
|
||||
"RGB thumbnail can't be written as indexed. Written as RGB"},
|
||||
{Integer.toString(JPEGImageWriter.WARNING_NO_GRAY_THUMB_AS_INDEXED),
|
||||
"Grayscale thumbnail can't be written as indexed. Written as JPEG"},
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Locale;
|
||||
|
||||
public class JPEGImageWriterSpi extends ImageWriterSpi {
|
||||
|
||||
private static String [] readerSpiNames =
|
||||
{"com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi"};
|
||||
|
||||
public JPEGImageWriterSpi() {
|
||||
super(JPEG.vendor,
|
||||
JPEG.version,
|
||||
JPEG.names,
|
||||
JPEG.suffixes,
|
||||
JPEG.MIMETypes,
|
||||
"com.sun.imageio.plugins.jpeg.JPEGImageWriter",
|
||||
new Class[] { ImageOutputStream.class },
|
||||
readerSpiNames,
|
||||
true,
|
||||
JPEG.nativeStreamMetadataFormatName,
|
||||
JPEG.nativeStreamMetadataFormatClassName,
|
||||
null, null,
|
||||
true,
|
||||
JPEG.nativeImageMetadataFormatName,
|
||||
JPEG.nativeImageMetadataFormatClassName,
|
||||
null, null
|
||||
);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard JPEG Image Writer";
|
||||
}
|
||||
|
||||
public boolean isFormatLossless() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(ImageTypeSpecifier type) {
|
||||
SampleModel sampleModel = type.getSampleModel();
|
||||
|
||||
// Find the maximum bit depth across all channels
|
||||
int[] sampleSize = sampleModel.getSampleSize();
|
||||
int bitDepth = sampleSize[0];
|
||||
for (int i = 1; i < sampleSize.length; i++) {
|
||||
if (sampleSize[i] > bitDepth) {
|
||||
bitDepth = sampleSize[i];
|
||||
}
|
||||
}
|
||||
|
||||
// 4450894: Ensure bitDepth is between 1 and 8
|
||||
if (bitDepth < 1 || bitDepth > 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ImageWriter createWriterInstance(Object extension)
|
||||
throws IIOException {
|
||||
return new JPEGImageWriter(this);
|
||||
}
|
||||
}
|
||||
2417
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
Normal file
2417
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
Normal file
File diff suppressed because it is too large
Load Diff
157
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGMetadataFormat.java
Normal file
157
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/JPEGMetadataFormat.java
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.plugins.jpeg.JPEGQTable;
|
||||
import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
abstract class JPEGMetadataFormat extends IIOMetadataFormatImpl {
|
||||
// 2-byte length reduces max to 65533
|
||||
private static final int MAX_JPEG_DATA_SIZE = 65533;
|
||||
|
||||
String resourceBaseName = this.getClass().getName() + "Resources";
|
||||
|
||||
JPEGMetadataFormat(String formatName, int childPolicy) {
|
||||
super(formatName, childPolicy);
|
||||
setResourceBaseName(resourceBaseName);
|
||||
}
|
||||
|
||||
// Format shared between image and stream formats
|
||||
void addStreamElements(String parentName) {
|
||||
addElement("dqt", parentName, 1, 4);
|
||||
|
||||
addElement("dqtable", "dqt", CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("dqtable",
|
||||
"elementPrecision",
|
||||
DATATYPE_INTEGER,
|
||||
false,
|
||||
"0");
|
||||
List tabids = new ArrayList();
|
||||
tabids.add("0");
|
||||
tabids.add("1");
|
||||
tabids.add("2");
|
||||
tabids.add("3");
|
||||
addAttribute("dqtable",
|
||||
"qtableId",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
tabids);
|
||||
addObjectValue("dqtable",
|
||||
JPEGQTable.class,
|
||||
true,
|
||||
null);
|
||||
|
||||
addElement("dht", parentName, 1, 4);
|
||||
addElement("dhtable", "dht", CHILD_POLICY_EMPTY);
|
||||
List classes = new ArrayList();
|
||||
classes.add("0");
|
||||
classes.add("1");
|
||||
addAttribute("dhtable",
|
||||
"class",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
classes);
|
||||
addAttribute("dhtable",
|
||||
"htableId",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
tabids);
|
||||
addObjectValue("dhtable",
|
||||
JPEGHuffmanTable.class,
|
||||
true,
|
||||
null);
|
||||
|
||||
|
||||
addElement("dri", parentName, CHILD_POLICY_EMPTY);
|
||||
addAttribute("dri",
|
||||
"interval",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"0", "65535",
|
||||
true, true);
|
||||
|
||||
addElement("com", parentName, CHILD_POLICY_EMPTY);
|
||||
addAttribute("com",
|
||||
"comment",
|
||||
DATATYPE_STRING,
|
||||
false,
|
||||
null);
|
||||
addObjectValue("com", byte[].class, 1, MAX_JPEG_DATA_SIZE);
|
||||
|
||||
addElement("unknown", parentName, CHILD_POLICY_EMPTY);
|
||||
addAttribute("unknown",
|
||||
"MarkerTag",
|
||||
DATATYPE_INTEGER,
|
||||
true,
|
||||
null,
|
||||
"0", "255",
|
||||
true, true);
|
||||
addObjectValue("unknown", byte[].class, 1, MAX_JPEG_DATA_SIZE);
|
||||
}
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
// Just check if it appears in the format
|
||||
if (isInSubtree(elementName, getRootName())){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the named element occurs in the
|
||||
* subtree of the format starting with the node named by
|
||||
* <code>subtreeName</code>, including the node
|
||||
* itself. <code>subtreeName</code> may be any node in
|
||||
* the format. If it is not, an
|
||||
* <code>IllegalArgumentException</code> is thrown.
|
||||
*/
|
||||
protected boolean isInSubtree(String elementName,
|
||||
String subtreeName) {
|
||||
if (elementName.equals(subtreeName)) {
|
||||
return true;
|
||||
}
|
||||
String [] children = getChildNames(elementName);
|
||||
for (int i=0; i < children.length; i++) {
|
||||
if (isInSubtree(elementName, children[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
abstract class JPEGMetadataFormatResources
|
||||
extends ListResourceBundle {
|
||||
|
||||
static final Object[][] commonContents = {
|
||||
// Node name, followed by description
|
||||
{ "dqt", "A Define Quantization Table(s) marker segment" },
|
||||
{ "dqtable", "A single quantization table" },
|
||||
{ "dht", "A Define Huffman Table(s) marker segment" },
|
||||
{ "dhtable", "A single Huffman table" },
|
||||
{ "dri", "A Define Restart Interval marker segment" },
|
||||
{ "com", "A Comment marker segment. The user object contains "
|
||||
+ "the actual bytes."},
|
||||
{ "unknown", "An unrecognized marker segment. The user object "
|
||||
+ "contains the data not including length." },
|
||||
|
||||
// Node name + "/" + AttributeName, followed by description
|
||||
{ "dqtable/elementPrecision",
|
||||
"The number of bits in each table element (0 = 8, 1 = 16)" },
|
||||
{ "dgtable/qtableId",
|
||||
"The table id" },
|
||||
{ "dhtable/class",
|
||||
"Indicates whether this is a DC (0) or an AC (1) table" },
|
||||
{ "dhtable/htableId",
|
||||
"The table id" },
|
||||
{ "dri/interval",
|
||||
"The restart interval in MCUs" },
|
||||
{ "com/comment",
|
||||
"The comment as a string (used only if user object is null)" },
|
||||
{ "unknown/MarkerTag",
|
||||
"The tag identifying this marker segment" }
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class JPEGStreamMetadataFormat extends JPEGMetadataFormat {
|
||||
|
||||
private static JPEGStreamMetadataFormat theInstance = null;
|
||||
|
||||
private JPEGStreamMetadataFormat() {
|
||||
super(JPEG.nativeStreamMetadataFormatName,
|
||||
CHILD_POLICY_SEQUENCE);
|
||||
addStreamElements(getRootName());
|
||||
}
|
||||
|
||||
public static synchronized IIOMetadataFormat getInstance() {
|
||||
if (theInstance == null) {
|
||||
theInstance = new JPEGStreamMetadataFormat();
|
||||
}
|
||||
return theInstance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class JPEGStreamMetadataFormatResources
|
||||
extends JPEGMetadataFormatResources {
|
||||
|
||||
public JPEGStreamMetadataFormatResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
// return a copy of commonContents; in theory we want a deep clone
|
||||
// of commonContents, but since it only contains (immutable) Strings,
|
||||
// this shallow copy is sufficient
|
||||
Object[][] commonCopy = new Object[commonContents.length][2];
|
||||
for (int i = 0; i < commonContents.length; i++) {
|
||||
commonCopy[i][0] = commonContents[i][0];
|
||||
commonCopy[i][1] = commonContents[i][1];
|
||||
}
|
||||
return commonCopy;
|
||||
}
|
||||
}
|
||||
229
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/MarkerSegment.java
Normal file
229
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/MarkerSegment.java
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* All metadata is stored in MarkerSegments. Marker segments
|
||||
* that we know about are stored in subclasses of this
|
||||
* basic class, which used for unrecognized APPn marker
|
||||
* segments. XXX break out UnknownMarkerSegment as a subclass
|
||||
* and make this abstract, avoiding unused data field.
|
||||
*/
|
||||
class MarkerSegment implements Cloneable {
|
||||
protected static final int LENGTH_SIZE = 2; // length is 2 bytes
|
||||
int tag; // See JPEG.java
|
||||
int length; /* Sometimes needed by subclasses; doesn't include
|
||||
itself. Meaningful only if constructed from a stream */
|
||||
byte [] data = null; // Raw segment data, used for unrecognized segments
|
||||
boolean unknown = false; // Set to true if the tag is not recognized
|
||||
|
||||
/**
|
||||
* Constructor for creating <code>MarkerSegment</code>s by reading
|
||||
* from an <code>ImageInputStream</code>.
|
||||
*/
|
||||
MarkerSegment(JPEGBuffer buffer) throws IOException {
|
||||
|
||||
buffer.loadBuf(3); // tag plus length
|
||||
tag = buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
length = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
|
||||
length |= buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
length -= 2; // JPEG length includes itself, we don't
|
||||
|
||||
if (length < 0) {
|
||||
throw new IIOException("Invalid segment length: " + length);
|
||||
}
|
||||
buffer.bufAvail -= 3;
|
||||
// Now that we know the true length, ensure that we've got it,
|
||||
// or at least a bufferful if length is too big.
|
||||
buffer.loadBuf(length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used when creating segments other than by
|
||||
* reading them from a stream.
|
||||
*/
|
||||
MarkerSegment(int tag) {
|
||||
this.tag = tag;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a MarkerSegment from an "unknown" DOM Node.
|
||||
*/
|
||||
MarkerSegment(Node node) throws IIOInvalidTreeException {
|
||||
// The type of node should have been verified already.
|
||||
// get the attribute and assign it to the tag
|
||||
tag = getAttributeValue(node,
|
||||
null,
|
||||
"MarkerTag",
|
||||
0, 255,
|
||||
true);
|
||||
length = 0;
|
||||
// get the user object and clone it to the data
|
||||
if (node instanceof IIOMetadataNode) {
|
||||
IIOMetadataNode iioNode = (IIOMetadataNode) node;
|
||||
try {
|
||||
data = (byte []) iioNode.getUserObject();
|
||||
} catch (Exception e) {
|
||||
IIOInvalidTreeException newGuy =
|
||||
new IIOInvalidTreeException
|
||||
("Can't get User Object", node);
|
||||
newGuy.initCause(e);
|
||||
throw newGuy;
|
||||
}
|
||||
} else {
|
||||
throw new IIOInvalidTreeException
|
||||
("Node must have User Object", node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep copy of data array.
|
||||
*/
|
||||
protected Object clone() {
|
||||
MarkerSegment newGuy = null;
|
||||
try {
|
||||
newGuy = (MarkerSegment) super.clone();
|
||||
} catch (CloneNotSupportedException e) {} // won't happen
|
||||
if (this.data != null) {
|
||||
newGuy.data = (byte[]) data.clone();
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
/**
|
||||
* We have determined that we don't know the type, so load
|
||||
* the data using the length parameter.
|
||||
*/
|
||||
void loadData(JPEGBuffer buffer) throws IOException {
|
||||
data = new byte[length];
|
||||
buffer.readData(data);
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("unknown");
|
||||
node.setAttribute("MarkerTag", Integer.toString(tag));
|
||||
node.setUserObject(data);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static int getAttributeValue(Node node,
|
||||
NamedNodeMap attrs,
|
||||
String name,
|
||||
int min,
|
||||
int max,
|
||||
boolean required)
|
||||
throws IIOInvalidTreeException {
|
||||
if (attrs == null) {
|
||||
attrs = node.getAttributes();
|
||||
}
|
||||
String valueString = attrs.getNamedItem(name).getNodeValue();
|
||||
int value = -1;
|
||||
if (valueString == null) {
|
||||
if (required) {
|
||||
throw new IIOInvalidTreeException
|
||||
(name + " attribute not found", node);
|
||||
}
|
||||
} else {
|
||||
value = Integer.parseInt(valueString);
|
||||
if ((value < min) || (value > max)) {
|
||||
throw new IIOInvalidTreeException
|
||||
(name + " attribute out of range", node);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the marker, tag, and length. Note that length
|
||||
* should be verified by the caller as a correct JPEG
|
||||
* length, i.e it includes itself.
|
||||
*/
|
||||
void writeTag(ImageOutputStream ios) throws IOException {
|
||||
ios.write(0xff);
|
||||
ios.write(tag);
|
||||
write2bytes(ios, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
length = 2 + ((data != null) ? data.length : 0);
|
||||
writeTag(ios);
|
||||
if (data != null) {
|
||||
ios.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
static void write2bytes(ImageOutputStream ios,
|
||||
int value) throws IOException {
|
||||
ios.write((value >> 8) & 0xff);
|
||||
ios.write(value & 0xff);
|
||||
|
||||
}
|
||||
|
||||
void printTag(String prefix) {
|
||||
System.out.println(prefix + " marker segment - marker = 0x"
|
||||
+ Integer.toHexString(tag));
|
||||
System.out.println("length: " + length);
|
||||
}
|
||||
|
||||
void print() {
|
||||
printTag("Unknown");
|
||||
if (length > 10) {
|
||||
System.out.print("First 5 bytes:");
|
||||
for (int i=0;i<5;i++) {
|
||||
System.out.print(" Ox"
|
||||
+ Integer.toHexString((int)data[i]));
|
||||
}
|
||||
System.out.print("\nLast 5 bytes:");
|
||||
for (int i=data.length-5;i<data.length;i++) {
|
||||
System.out.print(" Ox"
|
||||
+ Integer.toHexString((int)data[i]));
|
||||
}
|
||||
} else {
|
||||
System.out.print("Data:");
|
||||
for (int i=0;i<data.length;i++) {
|
||||
System.out.print(" Ox"
|
||||
+ Integer.toHexString((int)data[i]));
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
284
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/SOFMarkerSegment.java
Normal file
284
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/SOFMarkerSegment.java
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
//import javax.imageio.IIOException;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* An SOF (Start Of Frame) marker segment.
|
||||
*/
|
||||
class SOFMarkerSegment extends MarkerSegment {
|
||||
int samplePrecision;
|
||||
int numLines;
|
||||
int samplesPerLine;
|
||||
ComponentSpec [] componentSpecs; // Array size is num components
|
||||
|
||||
SOFMarkerSegment(boolean wantProg,
|
||||
boolean wantExtended,
|
||||
boolean willSubsample,
|
||||
byte[] componentIDs,
|
||||
int numComponents) {
|
||||
super(wantProg ? JPEG.SOF2
|
||||
: wantExtended ? JPEG.SOF1
|
||||
: JPEG.SOF0);
|
||||
samplePrecision = 8;
|
||||
numLines = 0;
|
||||
samplesPerLine = 0;
|
||||
componentSpecs = new ComponentSpec[numComponents];
|
||||
for(int i = 0; i < numComponents; i++) {
|
||||
int factor = 1;
|
||||
int qsel = 0;
|
||||
if (willSubsample) {
|
||||
factor = 2;
|
||||
if ((i == 1) || (i == 2)) {
|
||||
factor = 1;
|
||||
qsel = 1;
|
||||
}
|
||||
}
|
||||
componentSpecs[i] = new ComponentSpec(componentIDs[i], factor, qsel);
|
||||
}
|
||||
}
|
||||
|
||||
SOFMarkerSegment(JPEGBuffer buffer) throws IOException{
|
||||
super(buffer);
|
||||
samplePrecision = buffer.buf[buffer.bufPtr++];
|
||||
numLines = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
|
||||
numLines |= buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
samplesPerLine = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
|
||||
samplesPerLine |= buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
int numComponents = buffer.buf[buffer.bufPtr++] & 0xff;
|
||||
componentSpecs = new ComponentSpec [numComponents];
|
||||
for (int i = 0; i < numComponents; i++) {
|
||||
componentSpecs[i] = new ComponentSpec(buffer);
|
||||
}
|
||||
buffer.bufAvail -= length;
|
||||
}
|
||||
|
||||
SOFMarkerSegment(Node node) throws IIOInvalidTreeException {
|
||||
// All attributes are optional, so setup defaults first
|
||||
super(JPEG.SOF0);
|
||||
samplePrecision = 8;
|
||||
numLines = 0;
|
||||
samplesPerLine = 0;
|
||||
updateFromNativeNode(node, true);
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
SOFMarkerSegment newGuy = (SOFMarkerSegment) super.clone();
|
||||
if (componentSpecs != null) {
|
||||
newGuy.componentSpecs = (ComponentSpec []) componentSpecs.clone();
|
||||
for (int i = 0; i < componentSpecs.length; i++) {
|
||||
newGuy.componentSpecs[i] =
|
||||
(ComponentSpec) componentSpecs[i].clone();
|
||||
}
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("sof");
|
||||
node.setAttribute("process", Integer.toString(tag-JPEG.SOF0));
|
||||
node.setAttribute("samplePrecision",
|
||||
Integer.toString(samplePrecision));
|
||||
node.setAttribute("numLines",
|
||||
Integer.toString(numLines));
|
||||
node.setAttribute("samplesPerLine",
|
||||
Integer.toString(samplesPerLine));
|
||||
node.setAttribute("numFrameComponents",
|
||||
Integer.toString(componentSpecs.length));
|
||||
for (int i = 0; i < componentSpecs.length; i++) {
|
||||
node.appendChild(componentSpecs[i].getNativeNode());
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void updateFromNativeNode(Node node, boolean fromScratch)
|
||||
throws IIOInvalidTreeException {
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
int value = getAttributeValue(node, attrs, "process", 0, 2, false);
|
||||
tag = (value != -1) ? value+JPEG.SOF0 : tag;
|
||||
// If samplePrecision is present, it must be 8.
|
||||
// This just checks. We don't bother to assign the value.
|
||||
value = getAttributeValue(node, attrs, "samplePrecision", 8, 8, false);
|
||||
value = getAttributeValue(node, attrs, "numLines", 0, 65535, false);
|
||||
numLines = (value != -1) ? value : numLines;
|
||||
value = getAttributeValue(node, attrs, "samplesPerLine", 0, 65535, false);
|
||||
samplesPerLine = (value != -1) ? value : samplesPerLine;
|
||||
int numComponents = getAttributeValue(node, attrs, "numFrameComponents",
|
||||
1, 4, false);
|
||||
NodeList children = node.getChildNodes();
|
||||
if (children.getLength() != numComponents) {
|
||||
throw new IIOInvalidTreeException
|
||||
("numFrameComponents must match number of children", node);
|
||||
}
|
||||
componentSpecs = new ComponentSpec [numComponents];
|
||||
for (int i = 0; i < numComponents; i++) {
|
||||
componentSpecs[i] = new ComponentSpec(children.item(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
// We don't write SOF segments; the IJG library does.
|
||||
}
|
||||
|
||||
void print () {
|
||||
printTag("SOF");
|
||||
System.out.print("Sample precision: ");
|
||||
System.out.println(samplePrecision);
|
||||
System.out.print("Number of lines: ");
|
||||
System.out.println(numLines);
|
||||
System.out.print("Samples per line: ");
|
||||
System.out.println(samplesPerLine);
|
||||
System.out.print("Number of components: ");
|
||||
System.out.println(componentSpecs.length);
|
||||
for(int i = 0; i<componentSpecs.length; i++) {
|
||||
componentSpecs[i].print();
|
||||
}
|
||||
}
|
||||
|
||||
int getIDencodedCSType () {
|
||||
for (int i = 0; i < componentSpecs.length; i++) {
|
||||
if (componentSpecs[i].componentId < 'A') {
|
||||
return JPEG.JCS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
switch(componentSpecs.length) {
|
||||
case 3:
|
||||
if ((componentSpecs[0].componentId == 'R')
|
||||
&&(componentSpecs[0].componentId == 'G')
|
||||
&&(componentSpecs[0].componentId == 'B')) {
|
||||
return JPEG.JCS_RGB;
|
||||
}
|
||||
if ((componentSpecs[0].componentId == 'Y')
|
||||
&&(componentSpecs[0].componentId == 'C')
|
||||
&&(componentSpecs[0].componentId == 'c')) {
|
||||
return JPEG.JCS_YCC;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if ((componentSpecs[0].componentId == 'R')
|
||||
&&(componentSpecs[0].componentId == 'G')
|
||||
&&(componentSpecs[0].componentId == 'B')
|
||||
&&(componentSpecs[0].componentId == 'A')) {
|
||||
return JPEG.JCS_RGBA;
|
||||
}
|
||||
if ((componentSpecs[0].componentId == 'Y')
|
||||
&&(componentSpecs[0].componentId == 'C')
|
||||
&&(componentSpecs[0].componentId == 'c')
|
||||
&&(componentSpecs[0].componentId == 'A')) {
|
||||
return JPEG.JCS_YCCA;
|
||||
}
|
||||
}
|
||||
|
||||
return JPEG.JCS_UNKNOWN;
|
||||
}
|
||||
|
||||
ComponentSpec getComponentSpec(byte id, int factor, int qSelector) {
|
||||
return new ComponentSpec(id, factor, qSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
* A component spec within an SOF marker segment.
|
||||
*/
|
||||
class ComponentSpec implements Cloneable {
|
||||
int componentId;
|
||||
int HsamplingFactor;
|
||||
int VsamplingFactor;
|
||||
int QtableSelector;
|
||||
|
||||
ComponentSpec(byte id, int factor, int qSelector) {
|
||||
componentId = id;
|
||||
HsamplingFactor = factor;
|
||||
VsamplingFactor = factor;
|
||||
QtableSelector = qSelector;
|
||||
}
|
||||
|
||||
ComponentSpec(JPEGBuffer buffer) {
|
||||
// Parent already did a loadBuf
|
||||
componentId = buffer.buf[buffer.bufPtr++];
|
||||
HsamplingFactor = buffer.buf[buffer.bufPtr] >>> 4;
|
||||
VsamplingFactor = buffer.buf[buffer.bufPtr++] & 0xf;
|
||||
QtableSelector = buffer.buf[buffer.bufPtr++];
|
||||
}
|
||||
|
||||
ComponentSpec(Node node) throws IIOInvalidTreeException {
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
componentId = getAttributeValue(node, attrs, "componentId", 0, 255, true);
|
||||
HsamplingFactor = getAttributeValue(node, attrs, "HsamplingFactor",
|
||||
1, 255, true);
|
||||
VsamplingFactor = getAttributeValue(node, attrs, "VsamplingFactor",
|
||||
1, 255, true);
|
||||
QtableSelector = getAttributeValue(node, attrs, "QtableSelector",
|
||||
0, 3, true);
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {} // won't happen
|
||||
return null;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("componentSpec");
|
||||
node.setAttribute("componentId",
|
||||
Integer.toString(componentId));
|
||||
node.setAttribute("HsamplingFactor",
|
||||
Integer.toString(HsamplingFactor));
|
||||
node.setAttribute("VsamplingFactor",
|
||||
Integer.toString(VsamplingFactor));
|
||||
node.setAttribute("QtableSelector",
|
||||
Integer.toString(QtableSelector));
|
||||
return node;
|
||||
}
|
||||
|
||||
void print () {
|
||||
System.out.print("Component ID: ");
|
||||
System.out.println(componentId);
|
||||
System.out.print("H sampling factor: ");
|
||||
System.out.println(HsamplingFactor);
|
||||
System.out.print("V sampling factor: ");
|
||||
System.out.println(VsamplingFactor);
|
||||
System.out.print("Q table selector: ");
|
||||
System.out.println(QtableSelector);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
241
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/SOSMarkerSegment.java
Normal file
241
jdkSrc/jdk8/com/sun/imageio/plugins/jpeg/SOSMarkerSegment.java
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.jpeg;
|
||||
|
||||
//import javax.imageio.IIOException;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
||||
/**
|
||||
* An SOS (Start Of Scan) marker segment.
|
||||
*/
|
||||
class SOSMarkerSegment extends MarkerSegment {
|
||||
int startSpectralSelection;
|
||||
int endSpectralSelection;
|
||||
int approxHigh;
|
||||
int approxLow;
|
||||
ScanComponentSpec [] componentSpecs; // Array size is numScanComponents
|
||||
|
||||
SOSMarkerSegment(boolean willSubsample,
|
||||
byte[] componentIDs,
|
||||
int numComponents) {
|
||||
super(JPEG.SOS);
|
||||
startSpectralSelection = 0;
|
||||
endSpectralSelection = 63;
|
||||
approxHigh = 0;
|
||||
approxLow = 0;
|
||||
componentSpecs = new ScanComponentSpec[numComponents];
|
||||
for (int i = 0; i < numComponents; i++) {
|
||||
int tableSel = 0;
|
||||
if (willSubsample) {
|
||||
if ((i == 1) || (i == 2)) {
|
||||
tableSel = 1;
|
||||
}
|
||||
}
|
||||
componentSpecs[i] = new ScanComponentSpec(componentIDs[i],
|
||||
tableSel);
|
||||
}
|
||||
}
|
||||
|
||||
SOSMarkerSegment(JPEGBuffer buffer) throws IOException {
|
||||
super(buffer);
|
||||
int numComponents = buffer.buf[buffer.bufPtr++];
|
||||
componentSpecs = new ScanComponentSpec[numComponents];
|
||||
for (int i = 0; i < numComponents; i++) {
|
||||
componentSpecs[i] = new ScanComponentSpec(buffer);
|
||||
}
|
||||
startSpectralSelection = buffer.buf[buffer.bufPtr++];
|
||||
endSpectralSelection = buffer.buf[buffer.bufPtr++];
|
||||
approxHigh = buffer.buf[buffer.bufPtr] >> 4;
|
||||
approxLow = buffer.buf[buffer.bufPtr++] &0xf;
|
||||
buffer.bufAvail -= length;
|
||||
}
|
||||
|
||||
SOSMarkerSegment(Node node) throws IIOInvalidTreeException {
|
||||
super(JPEG.SOS);
|
||||
startSpectralSelection = 0;
|
||||
endSpectralSelection = 63;
|
||||
approxHigh = 0;
|
||||
approxLow = 0;
|
||||
updateFromNativeNode(node, true);
|
||||
}
|
||||
|
||||
protected Object clone () {
|
||||
SOSMarkerSegment newGuy = (SOSMarkerSegment) super.clone();
|
||||
if (componentSpecs != null) {
|
||||
newGuy.componentSpecs =
|
||||
(ScanComponentSpec []) componentSpecs.clone();
|
||||
for (int i = 0; i < componentSpecs.length; i++) {
|
||||
newGuy.componentSpecs[i] =
|
||||
(ScanComponentSpec) componentSpecs[i].clone();
|
||||
}
|
||||
}
|
||||
return newGuy;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("sos");
|
||||
node.setAttribute("numScanComponents",
|
||||
Integer.toString(componentSpecs.length));
|
||||
node.setAttribute("startSpectralSelection",
|
||||
Integer.toString(startSpectralSelection));
|
||||
node.setAttribute("endSpectralSelection",
|
||||
Integer.toString(endSpectralSelection));
|
||||
node.setAttribute("approxHigh",
|
||||
Integer.toString(approxHigh));
|
||||
node.setAttribute("approxLow",
|
||||
Integer.toString(approxLow));
|
||||
for (int i = 0; i < componentSpecs.length; i++) {
|
||||
node.appendChild(componentSpecs[i].getNativeNode());
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void updateFromNativeNode(Node node, boolean fromScratch)
|
||||
throws IIOInvalidTreeException {
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
int numComponents = getAttributeValue(node, attrs, "numScanComponents",
|
||||
1, 4, true);
|
||||
int value = getAttributeValue(node, attrs, "startSpectralSelection",
|
||||
0, 63, false);
|
||||
startSpectralSelection = (value != -1) ? value : startSpectralSelection;
|
||||
value = getAttributeValue(node, attrs, "endSpectralSelection",
|
||||
0, 63, false);
|
||||
endSpectralSelection = (value != -1) ? value : endSpectralSelection;
|
||||
value = getAttributeValue(node, attrs, "approxHigh", 0, 15, false);
|
||||
approxHigh = (value != -1) ? value : approxHigh;
|
||||
value = getAttributeValue(node, attrs, "approxLow", 0, 15, false);
|
||||
approxLow = (value != -1) ? value : approxLow;
|
||||
|
||||
// Now the children
|
||||
NodeList children = node.getChildNodes();
|
||||
if (children.getLength() != numComponents) {
|
||||
throw new IIOInvalidTreeException
|
||||
("numScanComponents must match the number of children", node);
|
||||
}
|
||||
componentSpecs = new ScanComponentSpec[numComponents];
|
||||
for (int i = 0; i < numComponents; i++) {
|
||||
componentSpecs[i] = new ScanComponentSpec(children.item(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for this segment to the stream in
|
||||
* valid JPEG format.
|
||||
*/
|
||||
void write(ImageOutputStream ios) throws IOException {
|
||||
// We don't write SOS segments; the IJG library does.
|
||||
}
|
||||
|
||||
void print () {
|
||||
printTag("SOS");
|
||||
System.out.print("Start spectral selection: ");
|
||||
System.out.println(startSpectralSelection);
|
||||
System.out.print("End spectral selection: ");
|
||||
System.out.println(endSpectralSelection);
|
||||
System.out.print("Approx high: ");
|
||||
System.out.println(approxHigh);
|
||||
System.out.print("Approx low: ");
|
||||
System.out.println(approxLow);
|
||||
System.out.print("Num scan components: ");
|
||||
System.out.println(componentSpecs.length);
|
||||
for (int i = 0; i< componentSpecs.length; i++) {
|
||||
componentSpecs[i].print();
|
||||
}
|
||||
}
|
||||
|
||||
ScanComponentSpec getScanComponentSpec(byte componentSel, int tableSel) {
|
||||
return new ScanComponentSpec(componentSel, tableSel);
|
||||
}
|
||||
|
||||
/**
|
||||
* A scan component spec within an SOS marker segment.
|
||||
*/
|
||||
class ScanComponentSpec implements Cloneable {
|
||||
int componentSelector;
|
||||
int dcHuffTable;
|
||||
int acHuffTable;
|
||||
|
||||
ScanComponentSpec(byte componentSel, int tableSel) {
|
||||
componentSelector = componentSel;
|
||||
dcHuffTable = tableSel;
|
||||
acHuffTable = tableSel;
|
||||
}
|
||||
|
||||
ScanComponentSpec(JPEGBuffer buffer) {
|
||||
// Parent already loaded the buffer
|
||||
componentSelector = buffer.buf[buffer.bufPtr++];
|
||||
dcHuffTable = buffer.buf[buffer.bufPtr] >> 4;
|
||||
acHuffTable = buffer.buf[buffer.bufPtr++] & 0xf;
|
||||
}
|
||||
|
||||
ScanComponentSpec(Node node) throws IIOInvalidTreeException {
|
||||
NamedNodeMap attrs = node.getAttributes();
|
||||
componentSelector = getAttributeValue(node, attrs, "componentSelector",
|
||||
0, 255, true);
|
||||
dcHuffTable = getAttributeValue(node, attrs, "dcHuffTable",
|
||||
0, 3, true);
|
||||
acHuffTable = getAttributeValue(node, attrs, "acHuffTable",
|
||||
0, 3, true);
|
||||
}
|
||||
|
||||
protected Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {} // won't happen
|
||||
return null;
|
||||
}
|
||||
|
||||
IIOMetadataNode getNativeNode() {
|
||||
IIOMetadataNode node = new IIOMetadataNode("scanComponentSpec");
|
||||
node.setAttribute("componentSelector",
|
||||
Integer.toString(componentSelector));
|
||||
node.setAttribute("dcHuffTable",
|
||||
Integer.toString(dcHuffTable));
|
||||
node.setAttribute("acHuffTable",
|
||||
Integer.toString(acHuffTable));
|
||||
return node;
|
||||
}
|
||||
|
||||
void print () {
|
||||
System.out.print("Component Selector: ");
|
||||
System.out.println(componentSelector);
|
||||
System.out.print("DC huffman table: ");
|
||||
System.out.println(dcHuffTable);
|
||||
System.out.print("AC huffman table: ");
|
||||
System.out.println(acHuffTable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1649
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageReader.java
Normal file
1649
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageReader.java
Normal file
File diff suppressed because it is too large
Load Diff
103
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageReaderSpi.java
Normal file
103
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageReaderSpi.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.png;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Iterator;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
public class PNGImageReaderSpi extends ImageReaderSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final String[] names = { "png", "PNG" };
|
||||
|
||||
private static final String[] suffixes = { "png" };
|
||||
|
||||
private static final String[] MIMETypes = { "image/png", "image/x-png" };
|
||||
|
||||
private static final String readerClassName =
|
||||
"com.sun.imageio.plugins.png.PNGImageReader";
|
||||
|
||||
private static final String[] writerSpiNames = {
|
||||
"com.sun.imageio.plugins.png.PNGImageWriterSpi"
|
||||
};
|
||||
|
||||
public PNGImageReaderSpi() {
|
||||
super(vendorName,
|
||||
version,
|
||||
names,
|
||||
suffixes,
|
||||
MIMETypes,
|
||||
readerClassName,
|
||||
new Class[] { ImageInputStream.class },
|
||||
writerSpiNames,
|
||||
false,
|
||||
null, null,
|
||||
null, null,
|
||||
true,
|
||||
PNGMetadata.nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.png.PNGMetadataFormat",
|
||||
null, null
|
||||
);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard PNG image reader";
|
||||
}
|
||||
|
||||
public boolean canDecodeInput(Object input) throws IOException {
|
||||
if (!(input instanceof ImageInputStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageInputStream stream = (ImageInputStream)input;
|
||||
byte[] b = new byte[8];
|
||||
stream.mark();
|
||||
stream.readFully(b);
|
||||
stream.reset();
|
||||
|
||||
return (b[0] == (byte)137 &&
|
||||
b[1] == (byte)80 &&
|
||||
b[2] == (byte)78 &&
|
||||
b[3] == (byte)71 &&
|
||||
b[4] == (byte)13 &&
|
||||
b[5] == (byte)10 &&
|
||||
b[6] == (byte)26 &&
|
||||
b[7] == (byte)10);
|
||||
}
|
||||
|
||||
public ImageReader createReaderInstance(Object extension) {
|
||||
return new PNGImageReader(this);
|
||||
}
|
||||
}
|
||||
1171
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageWriter.java
Normal file
1171
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageWriter.java
Normal file
File diff suppressed because it is too large
Load Diff
126
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageWriterSpi.java
Normal file
126
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGImageWriterSpi.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.png;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
public class PNGImageWriterSpi extends ImageWriterSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final String[] names = { "png", "PNG" };
|
||||
|
||||
private static final String[] suffixes = { "png" };
|
||||
|
||||
private static final String[] MIMETypes = { "image/png", "image/x-png" };
|
||||
|
||||
private static final String writerClassName =
|
||||
"com.sun.imageio.plugins.png.PNGImageWriter";
|
||||
|
||||
private static final String[] readerSpiNames = {
|
||||
"com.sun.imageio.plugins.png.PNGImageReaderSpi"
|
||||
};
|
||||
|
||||
public PNGImageWriterSpi() {
|
||||
super(vendorName,
|
||||
version,
|
||||
names,
|
||||
suffixes,
|
||||
MIMETypes,
|
||||
writerClassName,
|
||||
new Class[] { ImageOutputStream.class },
|
||||
readerSpiNames,
|
||||
false,
|
||||
null, null,
|
||||
null, null,
|
||||
true,
|
||||
PNGMetadata.nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.png.PNGMetadataFormat",
|
||||
null, null
|
||||
);
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(ImageTypeSpecifier type) {
|
||||
SampleModel sampleModel = type.getSampleModel();
|
||||
ColorModel colorModel = type.getColorModel();
|
||||
|
||||
// Find the maximum bit depth across all channels
|
||||
int[] sampleSize = sampleModel.getSampleSize();
|
||||
int bitDepth = sampleSize[0];
|
||||
for (int i = 1; i < sampleSize.length; i++) {
|
||||
if (sampleSize[i] > bitDepth) {
|
||||
bitDepth = sampleSize[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure bitDepth is between 1 and 16
|
||||
if (bitDepth < 1 || bitDepth > 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check number of bands, alpha
|
||||
int numBands = sampleModel.getNumBands();
|
||||
if (numBands < 1 || numBands > 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean hasAlpha = colorModel.hasAlpha();
|
||||
// Fix 4464413: PNGTransparency reg-test was failing
|
||||
// because for IndexColorModels that have alpha,
|
||||
// numBands == 1 && hasAlpha == true, thus causing
|
||||
// the check below to fail and return false.
|
||||
if (colorModel instanceof IndexColorModel) {
|
||||
return true;
|
||||
}
|
||||
if ((numBands == 1 || numBands == 3) && hasAlpha) {
|
||||
return false;
|
||||
}
|
||||
if ((numBands == 2 || numBands == 4) && !hasAlpha) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard PNG image writer";
|
||||
}
|
||||
|
||||
public ImageWriter createWriterInstance(Object extension) {
|
||||
return new PNGImageWriter(this);
|
||||
}
|
||||
}
|
||||
2047
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGMetadata.java
Normal file
2047
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGMetadata.java
Normal file
File diff suppressed because it is too large
Load Diff
500
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGMetadataFormat.java
Normal file
500
jdkSrc/jdk8/com/sun/imageio/plugins/png/PNGMetadataFormat.java
Normal file
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.png;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.ListResourceBundle;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class PNGMetadataFormat extends IIOMetadataFormatImpl {
|
||||
|
||||
private static IIOMetadataFormat instance = null;
|
||||
|
||||
private static String VALUE_0 = "0";
|
||||
private static String VALUE_1 = "1";
|
||||
private static String VALUE_12 = "12";
|
||||
private static String VALUE_23 = "23";
|
||||
private static String VALUE_31 = "31";
|
||||
private static String VALUE_59 = "59";
|
||||
private static String VALUE_60 = "60";
|
||||
private static String VALUE_255 = "255";
|
||||
private static String VALUE_MAX_16 = "65535"; // 2^16 - 1
|
||||
private static String VALUE_MAX_32 = "2147483647"; // 2^32 - 1
|
||||
|
||||
private PNGMetadataFormat() {
|
||||
super(PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> IHDR
|
||||
addElement("IHDR", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("IHDR", "width",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_1, VALUE_MAX_32, true, true);
|
||||
|
||||
addAttribute("IHDR", "height",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_1, VALUE_MAX_32, true, true);
|
||||
|
||||
addAttribute("IHDR", "bitDepth",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
Arrays.asList(PNGMetadata.IHDR_bitDepths));
|
||||
|
||||
String[] colorTypes = {
|
||||
"Grayscale", "RGB", "Palette", "GrayAlpha", "RGBAlpha"
|
||||
};
|
||||
addAttribute("IHDR", "colorType",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(colorTypes));
|
||||
|
||||
addAttribute("IHDR", "compressionMethod",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(PNGMetadata.IHDR_compressionMethodNames));
|
||||
|
||||
addAttribute("IHDR", "filterMethod",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(PNGMetadata.IHDR_filterMethodNames));
|
||||
|
||||
addAttribute("IHDR", "interlaceMethod",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(PNGMetadata.IHDR_interlaceMethodNames));
|
||||
|
||||
// root -> PLTE
|
||||
addElement("PLTE", PNGMetadata.nativeMetadataFormatName,
|
||||
1, 256);
|
||||
|
||||
// root -> PLTE -> PLTEEntry
|
||||
addElement("PLTEEntry", "PLTE",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("PLTEEntry", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("PLTEEntry", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("PLTEEntry", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("PLTEEntry", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> bKGD
|
||||
addElement("bKGD", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_CHOICE);
|
||||
|
||||
// root -> bKGD -> bKGD_Grayscale
|
||||
addElement("bKGD_Grayscale", "bKGD",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("bKGD_Grayscale", "gray",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
// root -> bKGD -> bKGD_RGB
|
||||
addElement("bKGD_RGB", "bKGD",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("bKGD_RGB", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("bKGD_RGB", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("bKGD_RGB", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
// root -> bKGD -> bKGD_Palette
|
||||
addElement("bKGD_Palette", "bKGD",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("bKGD_Palette", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> cHRM
|
||||
addElement("cHRM", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("cHRM", "whitePointX",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("cHRM", "whitePointY",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("cHRM", "redX",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("cHRM", "redY",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("cHRM", "greenX",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("cHRM", "greenY",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("cHRM", "blueX",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("cHRM", "blueY",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
// root -> gAMA
|
||||
addElement("gAMA", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("gAMA", "value",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_32, true, true);
|
||||
|
||||
// root -> hIST
|
||||
addElement("hIST", PNGMetadata.nativeMetadataFormatName,
|
||||
1, 256);
|
||||
|
||||
// root -> hISTEntry
|
||||
addElement("hISTEntry", "hIST",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("hISTEntry", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("hISTEntry", "value",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
// root -> iCCP
|
||||
addElement("iCCP", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("iCCP", "profileName",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addAttribute("iCCP", "compressionMethod",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(PNGMetadata.iCCP_compressionMethodNames));
|
||||
|
||||
addObjectValue("iCCP", byte.class, 0, Integer.MAX_VALUE);
|
||||
|
||||
// root -> iTXt
|
||||
addElement("iTXt", PNGMetadata.nativeMetadataFormatName,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> iTXt -> iTXtEntry
|
||||
addElement("iTXtEntry", "iTXt",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("iTXtEntry", "keyword",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addBooleanAttribute("iTXtEntry", "compressionFlag",
|
||||
false, false);
|
||||
|
||||
addAttribute("iTXtEntry", "compressionMethod",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addAttribute("iTXtEntry", "languageTag",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addAttribute("iTXtEntry", "translatedKeyword",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addAttribute("iTXtEntry", "text",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
// root -> pHYS
|
||||
addElement("pHYS", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("pHYS", "pixelsPerUnitXAxis",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_32, true, true);
|
||||
addAttribute("pHYS", "pixelsPerUnitYAxis",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_32, true, true);
|
||||
addAttribute("pHYS", "unitSpecifier",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(PNGMetadata.unitSpecifierNames));
|
||||
|
||||
// root -> sBIT
|
||||
addElement("sBIT", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_CHOICE);
|
||||
|
||||
// root -> sBIT -> sBIT_Grayscale
|
||||
addElement("sBIT_Grayscale", "sBIT",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sBIT_Grayscale", "gray",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> sBIT -> sBIT_GrayAlpha
|
||||
addElement("sBIT_GrayAlpha", "sBIT",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sBIT_GrayAlpha", "gray",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_GrayAlpha", "alpha",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> sBIT -> sBIT_RGB
|
||||
addElement("sBIT_RGB", "sBIT",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sBIT_RGB", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_RGB", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_RGB", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> sBIT -> sBIT_RGBAlpha
|
||||
addElement("sBIT_RGBAlpha", "sBIT",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sBIT_RGBAlpha", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_RGBAlpha", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_RGBAlpha", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_RGBAlpha", "alpha",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> sBIT -> sBIT_Palette
|
||||
addElement("sBIT_Palette", "sBIT",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sBIT_Palette", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_Palette", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sBIT_Palette", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> sPLT
|
||||
addElement("sPLT", PNGMetadata.nativeMetadataFormatName,
|
||||
1, 256);
|
||||
|
||||
// root -> sPLT -> sPLTEntry
|
||||
addElement("sPLTEntry", "sPLT",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sPLTEntry", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sPLTEntry", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sPLTEntry", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sPLTEntry", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("sPLTEntry", "alpha",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> sRGB
|
||||
addElement("sRGB", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("sRGB", "renderingIntent",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(PNGMetadata.renderingIntentNames));
|
||||
|
||||
// root -> tEXt
|
||||
addElement("tEXt", PNGMetadata.nativeMetadataFormatName,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> tEXt -> tEXtEntry
|
||||
addElement("tEXtEntry", "tEXt",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("tEXtEntry", "keyword",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addAttribute("tEXtEntry", "value",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
// root -> tIME
|
||||
addElement("tIME", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("tIME", "year",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("tIME", "month",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_1, VALUE_12, true, true);
|
||||
|
||||
addAttribute("tIME", "day",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_1, VALUE_31, true, true);
|
||||
|
||||
addAttribute("tIME", "hour",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_23, true, true);
|
||||
|
||||
addAttribute("tIME", "minute",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_59, true, true);
|
||||
|
||||
addAttribute("tIME", "second",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_60, true, true);
|
||||
|
||||
// root -> tRNS
|
||||
addElement("tRNS", PNGMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_CHOICE);
|
||||
|
||||
// root -> tRNS -> tRNS_Grayscale
|
||||
addElement("tRNS_Grayscale", "tRNS",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("tRNS_Grayscale", "gray",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
// root -> tRNS -> tRNS_RGB
|
||||
addElement("tRNS_RGB", "tRNS",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("tRNS_RGB", "red",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("tRNS_RGB", "green",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
addAttribute("tRNS_RGB", "blue",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_MAX_16, true, true);
|
||||
|
||||
// root -> tRNS -> tRNS_Palette
|
||||
addElement("tRNS_Palette", "tRNS",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("tRNS_Palette", "index",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
addAttribute("tRNS_Palette", "alpha",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
VALUE_0, VALUE_255, true, true);
|
||||
|
||||
// root -> zTXt
|
||||
addElement("zTXt", PNGMetadata.nativeMetadataFormatName,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> zTXt -> zTXtEntry
|
||||
addElement("zTXtEntry", "zTXt",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("zTXtEntry", "keyword",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addAttribute("zTXtEntry", "compressionMethod",
|
||||
DATATYPE_STRING, true, null,
|
||||
Arrays.asList(PNGMetadata.zTXt_compressionMethodNames));
|
||||
|
||||
addAttribute("zTXtEntry", "text",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
// root -> UnknownChunks
|
||||
addElement("UnknownChunks", PNGMetadata.nativeMetadataFormatName,
|
||||
1, Integer.MAX_VALUE);
|
||||
|
||||
// root -> UnknownChunks -> UnknownChunk
|
||||
addElement("UnknownChunk", "UnknownChunks",
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("UnknownChunk", "type",
|
||||
DATATYPE_STRING, true, null);
|
||||
|
||||
addObjectValue("UnknownChunk", byte.class, 0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static synchronized IIOMetadataFormat getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new PNGMetadataFormat();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.png;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public class PNGMetadataFormatResources extends ListResourceBundle {
|
||||
|
||||
public PNGMetadataFormatResources() {}
|
||||
|
||||
protected Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
|
||||
// Node name, followed by description
|
||||
{ "IHDR", "The IHDR chunk, containing the header" },
|
||||
{ "PLTE", "The PLTE chunk, containing the palette" },
|
||||
{ "PLTEEntry", "A palette entry" },
|
||||
{ "bKGD", "The bKGD chunk, containing the background color" },
|
||||
{ "bKGD_RGB", "An RGB background color, for RGB and RGBAlpha images" },
|
||||
{ "bKGD_Grayscale",
|
||||
"A grayscale background color, for Gray and GrayAlpha images" },
|
||||
{ "bKGD_Palette", "A background palette index" },
|
||||
{ "cHRM", "The cHRM chunk, containing color calibration" },
|
||||
{ "gAMA", "The gAMA chunk, containing the image gamma" },
|
||||
{ "hIST", "The hIST chunk, containing histogram information " },
|
||||
{ "hISTEntry", "A histogram entry" },
|
||||
{ "iCCP", "The iCCP chunk, containing an ICC color profile" },
|
||||
{ "iTXt", "The iTXt chunk, containing internationalized text" },
|
||||
{ "iTXtEntry", "A localized text entry" },
|
||||
{ "pHYS",
|
||||
"The pHYS chunk, containing the pixel size and aspect ratio" },
|
||||
{ "sBIT", "The sBIT chunk, containing significant bit information" },
|
||||
{ "sBIT_Grayscale", "Significant bit information for gray samples" },
|
||||
{ "sBIT_GrayAlpha",
|
||||
"Significant bit information for gray and alpha samples" },
|
||||
{ "sBIT_RGB", "Significant bit information for RGB samples" },
|
||||
{ "sBIT_RGBAlpha", "Significant bit information for RGBA samples" },
|
||||
{ "sBIT_Palette",
|
||||
"Significant bit information for RGB palette entries" },
|
||||
{ "sPLT", "The sPLT chunk, containing a suggested palette" },
|
||||
{ "sPLTEntry", "A suggested palette entry" },
|
||||
{ "sRGB", "The sRGB chunk, containing rendering intent information" },
|
||||
{ "tEXt", "The tEXt chunk, containing text" },
|
||||
{ "tEXtEntry", "A text entry" },
|
||||
{ "tIME", "The tIME chunk, containing the image modification time" },
|
||||
{ "tRNS", "The tRNS chunk, containing transparency information" },
|
||||
{ "tRNS_Grayscale",
|
||||
"A grayscale value that should be considered transparent" },
|
||||
{ "tRNS_RGB",
|
||||
"An RGB value that should be considered transparent" },
|
||||
{ "tRNS_Palette",
|
||||
"A palette index that should be considered transparent" },
|
||||
{ "zTXt", "The zTXt chunk, containing compressed text" },
|
||||
{ "zTXtEntry", "A compressed text entry" },
|
||||
{ "UnknownChunks", "A set of unknown chunks" },
|
||||
{ "UnknownChunk", "Unknown chunk data stored as a byte array" },
|
||||
|
||||
// Node name + "/" + AttributeName, followed by description
|
||||
{ "IHDR/width", "The width of the image in pixels" },
|
||||
{ "IHDR/height", "The height of the image in pixels" },
|
||||
{ "IHDR/bitDepth", "The bit depth of the image samples" },
|
||||
{ "IHDR/colorType", "The color type of the image" },
|
||||
{ "IHDR/compressionMethod",
|
||||
"The compression used for image data, always \"deflate\"" },
|
||||
{ "IHDR/filterMethod",
|
||||
"The filtering method used for compression, always \"adaptive\"" },
|
||||
{ "IHDR/interlaceMethod",
|
||||
"The interlacing method, \"none\" or \"adam7\"" },
|
||||
|
||||
{ "PLTEEntry/index", "The index of a palette entry" },
|
||||
{ "PLTEEntry/red", "The red value of a palette entry" },
|
||||
{ "PLTEEntry/green", "The green value of a palette entry" },
|
||||
{ "PLTEEntry/blue", "The blue value of a palette entry" },
|
||||
|
||||
{ "bKGD_Grayscale/gray", "A gray value to be used as a background" },
|
||||
{ "bKGD_RGB/red", "A red value to be used as a background" },
|
||||
{ "bKGD_RGB/green", "A green value to be used as a background" },
|
||||
{ "bKGD_RGB/blue", "A blue value to be used as a background" },
|
||||
{ "bKGD_Palette/index", "A palette index to be used as a background" },
|
||||
|
||||
{ "cHRM/whitePointX",
|
||||
"The CIE x coordinate of the white point, multiplied by 1e5" },
|
||||
{ "cHRM/whitePointY",
|
||||
"The CIE y coordinate of the white point, multiplied by 1e5" },
|
||||
{ "cHRM/redX",
|
||||
"The CIE x coordinate of the red primary, multiplied by 1e5" },
|
||||
{ "cHRM/redY",
|
||||
"The CIE y coordinate of the red primary, multiplied by 1e5" },
|
||||
{ "cHRM/greenX",
|
||||
"The CIE x coordinate of the green primary, multiplied by 1e5" },
|
||||
{ "cHRM/greenY",
|
||||
"The CIE y coordinate of the green primary, multiplied by 1e5" },
|
||||
{ "cHRM/blueX",
|
||||
"The CIE x coordinate of the blue primary, multiplied by 1e5" },
|
||||
{ "cHRM/blueY",
|
||||
"The CIE y coordinate of the blue primary, multiplied by 1e5" },
|
||||
|
||||
{ "gAMA/value",
|
||||
"The image gamma, multiplied by 1e5" },
|
||||
|
||||
{ "hISTEntry/index", "The palette index of this histogram entry" },
|
||||
{ "hISTEntry/value", "The frequency of this histogram entry" },
|
||||
|
||||
{ "iCCP/profileName", "The name of this ICC profile" },
|
||||
{ "iCCP/compressionMethod",
|
||||
"The compression method used to store this ICC profile" },
|
||||
|
||||
{ "iTXtEntry/keyword", "The keyword" },
|
||||
{ "iTXtEntry/compressionMethod",
|
||||
"The compression method used to store this iTXt entry" },
|
||||
{ "iTXtEntry/languageTag",
|
||||
"The ISO tag describing the language this iTXt entry" },
|
||||
{ "iTXtEntry/translatedKeyword",
|
||||
"The translated keyword for iTXt entry" },
|
||||
{ "iTXtEntry/text",
|
||||
"The localized text" },
|
||||
|
||||
{ "pHYS/pixelsPerUnitXAxis",
|
||||
"The number of horizontal pixels per unit, multiplied by 1e5" },
|
||||
{ "pHYS/pixelsPerUnitYAxis",
|
||||
"The number of vertical pixels per unit, multiplied by 1e5" },
|
||||
{ "pHYS/unitSpecifier",
|
||||
"The unit specifier for this chunk (i.e., meters)" },
|
||||
|
||||
{ "sBIT_Grayscale/gray",
|
||||
"The number of significant bits of the gray samples" },
|
||||
{ "sBIT_GrayAlpha/gray",
|
||||
"The number of significant bits of the gray samples" },
|
||||
{ "sBIT_GrayAlpha/alpha",
|
||||
"The number of significant bits of the alpha samples" },
|
||||
{ "sBIT_RGB/red",
|
||||
"The number of significant bits of the red samples" },
|
||||
{ "sBIT_RGB/green",
|
||||
"The number of significant bits of the green samples" },
|
||||
{ "sBIT_RGB/blue",
|
||||
"The number of significant bits of the blue samples" },
|
||||
{ "sBIT_RGBAlpha/red",
|
||||
"The number of significant bits of the red samples" },
|
||||
{ "sBIT_RGBAlpha/green",
|
||||
"The number of significant bits of the green samples" },
|
||||
{ "sBIT_RGBAlpha/blue",
|
||||
"The number of significant bits of the blue samples" },
|
||||
{ "sBIT_RGBAlpha/alpha",
|
||||
"The number of significant bits of the alpha samples" },
|
||||
{ "sBIT_Palette/red",
|
||||
"The number of significant bits of the red palette entries" },
|
||||
{ "sBIT_Palette/green",
|
||||
"The number of significant bits of the green palette entries" },
|
||||
{ "sBIT_Palette/blue",
|
||||
"The number of significant bits of the blue palette entries" },
|
||||
|
||||
{ "sPLTEntry/index", "The index of a suggested palette entry" },
|
||||
{ "sPLTEntry/red", "The red value of a suggested palette entry" },
|
||||
{ "sPLTEntry/green", "The green value of a suggested palette entry" },
|
||||
{ "sPLTEntry/blue", "The blue value of a suggested palette entry" },
|
||||
{ "sPLTEntry/alpha", "The blue value of a suggested palette entry" },
|
||||
|
||||
{ "sRGB/renderingIntent", "The rendering intent" },
|
||||
|
||||
{ "tEXtEntry/keyword", "The keyword" },
|
||||
{ "tEXtEntry/value", "The text" },
|
||||
|
||||
{ "tIME/year", "The year when the image was last modified" },
|
||||
{ "tIME/month",
|
||||
"The month when the image was last modified, 1 = January" },
|
||||
{ "tIME/day",
|
||||
"The day of the month when the image was last modified" },
|
||||
{ "tIME/hour",
|
||||
"The hour when the image was last modified" },
|
||||
{ "tIME/minute",
|
||||
"The minute when the image was last modified" },
|
||||
{ "tIME/second",
|
||||
"The second when the image was last modified, 60 = leap second" },
|
||||
|
||||
{ "tRNS_Grayscale/gray",
|
||||
"The gray value to be considered transparent" },
|
||||
{ "tRNS_RGB/red",
|
||||
"The red value to be considered transparent" },
|
||||
{ "tRNS_RGB/green",
|
||||
"The green value to be considered transparent" },
|
||||
{ "tRNS_RGB/blue",
|
||||
"The blure value to be considered transparent" },
|
||||
{ "tRNS_Palette/index",
|
||||
"A palette index to be considered transparent" },
|
||||
{ "tRNS_Palette/alpha",
|
||||
"The transparency associated with the palette entry" },
|
||||
|
||||
{ "zTXtEntry/keyword", "The keyword" },
|
||||
{ "zTXtEntry/compressionMethod", "The compression method" },
|
||||
{ "zTXtEntry/text", "The compressed text" },
|
||||
|
||||
{ "UnknownChunk/type", "The 4-character type of the unknown chunk" }
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
192
jdkSrc/jdk8/com/sun/imageio/plugins/png/RowFilter.java
Normal file
192
jdkSrc/jdk8/com/sun/imageio/plugins/png/RowFilter.java
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.png;
|
||||
|
||||
public class RowFilter {
|
||||
|
||||
private static final int abs(int x) {
|
||||
return (x < 0) ? -x : x;
|
||||
}
|
||||
|
||||
// Returns the sum of absolute differences
|
||||
protected static int subFilter(byte[] currRow,
|
||||
byte[] subFilteredRow,
|
||||
int bytesPerPixel,
|
||||
int bytesPerRow) {
|
||||
int badness = 0;
|
||||
for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
|
||||
int curr = currRow[i] & 0xff;
|
||||
int left = currRow[i - bytesPerPixel] & 0xff;
|
||||
int difference = curr - left;
|
||||
subFilteredRow[i] = (byte)difference;
|
||||
|
||||
badness += abs(difference);
|
||||
}
|
||||
|
||||
return badness;
|
||||
}
|
||||
|
||||
// Returns the sum of absolute differences
|
||||
protected static int upFilter(byte[] currRow,
|
||||
byte[] prevRow,
|
||||
byte[] upFilteredRow,
|
||||
int bytesPerPixel,
|
||||
int bytesPerRow) {
|
||||
int badness = 0;
|
||||
for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
|
||||
int curr = currRow[i] & 0xff;
|
||||
int up = prevRow[i] & 0xff;
|
||||
int difference = curr - up;
|
||||
upFilteredRow[i] = (byte)difference;
|
||||
|
||||
badness += abs(difference);
|
||||
}
|
||||
|
||||
return badness;
|
||||
}
|
||||
|
||||
protected final int paethPredictor(int a, int b, int c) {
|
||||
int p = a + b - c;
|
||||
int pa = abs(p - a);
|
||||
int pb = abs(p - b);
|
||||
int pc = abs(p - c);
|
||||
|
||||
if ((pa <= pb) && (pa <= pc)) {
|
||||
return a;
|
||||
} else if (pb <= pc) {
|
||||
return b;
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
public int filterRow(int colorType,
|
||||
byte[] currRow,
|
||||
byte[] prevRow,
|
||||
byte[][] scratchRows,
|
||||
int bytesPerRow,
|
||||
int bytesPerPixel) {
|
||||
|
||||
// Use type 0 for palette images
|
||||
if (colorType != PNGImageReader.PNG_COLOR_PALETTE) {
|
||||
System.arraycopy(currRow, bytesPerPixel,
|
||||
scratchRows[0], bytesPerPixel,
|
||||
bytesPerRow);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int[] filterBadness = new int[5];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
filterBadness[i] = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
{
|
||||
int badness = 0;
|
||||
|
||||
for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
|
||||
int curr = currRow[i] & 0xff;
|
||||
badness += curr;
|
||||
}
|
||||
|
||||
filterBadness[0] = badness;
|
||||
}
|
||||
|
||||
{
|
||||
byte[] subFilteredRow = scratchRows[1];
|
||||
int badness = subFilter(currRow,
|
||||
subFilteredRow,
|
||||
bytesPerPixel,
|
||||
bytesPerRow);
|
||||
|
||||
filterBadness[1] = badness;
|
||||
}
|
||||
|
||||
{
|
||||
byte[] upFilteredRow = scratchRows[2];
|
||||
int badness = upFilter(currRow,
|
||||
prevRow,
|
||||
upFilteredRow,
|
||||
bytesPerPixel,
|
||||
bytesPerRow);
|
||||
|
||||
filterBadness[2] = badness;
|
||||
}
|
||||
|
||||
{
|
||||
byte[] averageFilteredRow = scratchRows[3];
|
||||
int badness = 0;
|
||||
|
||||
for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
|
||||
int curr = currRow[i] & 0xff;
|
||||
int left = currRow[i - bytesPerPixel] & 0xff;
|
||||
int up = prevRow[i] & 0xff;
|
||||
int difference = curr - (left + up)/2;;
|
||||
averageFilteredRow[i] = (byte)difference;
|
||||
|
||||
badness += abs(difference);
|
||||
}
|
||||
|
||||
filterBadness[3] = badness;
|
||||
}
|
||||
|
||||
{
|
||||
byte[] paethFilteredRow = scratchRows[4];
|
||||
int badness = 0;
|
||||
|
||||
for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
|
||||
int curr = currRow[i] & 0xff;
|
||||
int left = currRow[i - bytesPerPixel] & 0xff;
|
||||
int up = prevRow[i] & 0xff;
|
||||
int upleft = prevRow[i - bytesPerPixel] & 0xff;
|
||||
int predictor = paethPredictor(left, up, upleft);
|
||||
int difference = curr - predictor;
|
||||
paethFilteredRow[i] = (byte)difference;
|
||||
|
||||
badness += abs(difference);
|
||||
}
|
||||
|
||||
filterBadness[4] = badness;
|
||||
}
|
||||
|
||||
int minBadness = filterBadness[0];
|
||||
int filterType = 0;
|
||||
|
||||
for (int i = 1; i < 5; i++) {
|
||||
if (filterBadness[i] < minBadness) {
|
||||
minBadness = filterBadness[i];
|
||||
filterType = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (filterType == 0) {
|
||||
System.arraycopy(currRow, bytesPerPixel,
|
||||
scratchRows[0], bytesPerPixel,
|
||||
bytesPerRow);
|
||||
}
|
||||
|
||||
return filterType;
|
||||
}
|
||||
}
|
||||
322
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPImageReader.java
Normal file
322
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPImageReader.java
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.wbmp;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
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,
|
||||
* and shift the decoded image origin if the proper decoding parameter
|
||||
* are set in the provided <code>WBMPImageReadParam</code>.
|
||||
*/
|
||||
public class WBMPImageReader extends ImageReader {
|
||||
/** The input stream where reads from */
|
||||
private ImageInputStream iis = null;
|
||||
|
||||
/** Indicates whether the header is read. */
|
||||
private boolean gotHeader = false;
|
||||
|
||||
/** The original image width. */
|
||||
private int width;
|
||||
|
||||
/** The original image height. */
|
||||
private int height;
|
||||
|
||||
private int wbmpType;
|
||||
|
||||
private WBMPMetadata metadata;
|
||||
|
||||
/** Constructs <code>WBMPImageReader</code> from the provided
|
||||
* <code>ImageReaderSpi</code>.
|
||||
*/
|
||||
public WBMPImageReader(ImageReaderSpi originator) {
|
||||
super(originator);
|
||||
}
|
||||
|
||||
/** Overrides the method defined in the superclass. */
|
||||
public void setInput(Object input,
|
||||
boolean seekForwardOnly,
|
||||
boolean ignoreMetadata) {
|
||||
super.setInput(input, seekForwardOnly, ignoreMetadata);
|
||||
iis = (ImageInputStream) input; // Always works
|
||||
gotHeader = false;
|
||||
}
|
||||
|
||||
/** Overrides the method defined in the superclass. */
|
||||
public int getNumImages(boolean allowSearch) throws IOException {
|
||||
if (iis == null) {
|
||||
throw new IllegalStateException(I18N.getString("GetNumImages0"));
|
||||
}
|
||||
if (seekForwardOnly && allowSearch) {
|
||||
throw new IllegalStateException(I18N.getString("GetNumImages1"));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getWidth(int imageIndex) throws IOException {
|
||||
checkIndex(imageIndex);
|
||||
readHeader();
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight(int imageIndex) throws IOException {
|
||||
checkIndex(imageIndex);
|
||||
readHeader();
|
||||
return height;
|
||||
}
|
||||
|
||||
public boolean isRandomAccessEasy(int imageIndex) throws IOException {
|
||||
checkIndex(imageIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkIndex(int imageIndex) {
|
||||
if (imageIndex != 0) {
|
||||
throw new IndexOutOfBoundsException(I18N.getString("WBMPImageReader0"));
|
||||
}
|
||||
}
|
||||
|
||||
public void readHeader() throws IOException {
|
||||
if (gotHeader)
|
||||
return;
|
||||
|
||||
if (iis == null) {
|
||||
throw new IllegalStateException("Input source not set!");
|
||||
}
|
||||
|
||||
metadata = new WBMPMetadata();
|
||||
|
||||
wbmpType = iis.readByte(); // TypeField
|
||||
byte fixHeaderField = iis.readByte();
|
||||
|
||||
// check for valid wbmp image
|
||||
if (fixHeaderField != 0
|
||||
|| !isValidWbmpType(wbmpType))
|
||||
{
|
||||
throw new IIOException(I18N.getString("WBMPImageReader2"));
|
||||
}
|
||||
|
||||
metadata.wbmpType = wbmpType;
|
||||
|
||||
// Read image width
|
||||
width = ReaderUtil.readMultiByteInteger(iis);
|
||||
metadata.width = width;
|
||||
|
||||
// Read image height
|
||||
height = ReaderUtil.readMultiByteInteger(iis);
|
||||
metadata.height = height;
|
||||
|
||||
gotHeader = true;
|
||||
}
|
||||
|
||||
public Iterator getImageTypes(int imageIndex)
|
||||
throws IOException {
|
||||
checkIndex(imageIndex);
|
||||
readHeader();
|
||||
|
||||
BufferedImage bi =
|
||||
new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
|
||||
ArrayList list = new ArrayList(1);
|
||||
list.add(new ImageTypeSpecifier(bi));
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
public ImageReadParam getDefaultReadParam() {
|
||||
return new ImageReadParam();
|
||||
}
|
||||
|
||||
public IIOMetadata getImageMetadata(int imageIndex)
|
||||
throws IOException {
|
||||
checkIndex(imageIndex);
|
||||
if (metadata == null) {
|
||||
readHeader();
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public IIOMetadata getStreamMetadata() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public BufferedImage read(int imageIndex, ImageReadParam param)
|
||||
throws IOException {
|
||||
|
||||
if (iis == null) {
|
||||
throw new IllegalStateException(I18N.getString("WBMPImageReader1"));
|
||||
}
|
||||
|
||||
checkIndex(imageIndex);
|
||||
clearAbortRequest();
|
||||
processImageStarted(imageIndex);
|
||||
if (param == null)
|
||||
param = getDefaultReadParam();
|
||||
|
||||
//read header
|
||||
readHeader();
|
||||
|
||||
Rectangle sourceRegion = new Rectangle(0, 0, 0, 0);
|
||||
Rectangle destinationRegion = new Rectangle(0, 0, 0, 0);
|
||||
|
||||
computeRegions(param, this.width, this.height,
|
||||
param.getDestination(),
|
||||
sourceRegion,
|
||||
destinationRegion);
|
||||
|
||||
int scaleX = param.getSourceXSubsampling();
|
||||
int scaleY = param.getSourceYSubsampling();
|
||||
int xOffset = param.getSubsamplingXOffset();
|
||||
int yOffset = param.getSubsamplingYOffset();
|
||||
|
||||
// If the destination is provided, then use it. Otherwise, create new one
|
||||
BufferedImage bi = param.getDestination();
|
||||
|
||||
if (bi == null)
|
||||
bi = new BufferedImage(destinationRegion.x + destinationRegion.width,
|
||||
destinationRegion.y + destinationRegion.height,
|
||||
BufferedImage.TYPE_BYTE_BINARY);
|
||||
|
||||
boolean noTransform =
|
||||
destinationRegion.equals(new Rectangle(0, 0, width, height)) &&
|
||||
destinationRegion.equals(new Rectangle(0, 0, bi.getWidth(), bi.getHeight()));
|
||||
|
||||
// Get the image data.
|
||||
WritableRaster tile = bi.getWritableTile(0, 0);
|
||||
|
||||
// Get the SampleModel.
|
||||
MultiPixelPackedSampleModel sm =
|
||||
(MultiPixelPackedSampleModel)bi.getSampleModel();
|
||||
|
||||
if (noTransform) {
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return bi;
|
||||
}
|
||||
|
||||
// If noTransform is necessary, read the data.
|
||||
iis.read(((DataBufferByte)tile.getDataBuffer()).getData(),
|
||||
0, height*sm.getScanlineStride());
|
||||
processImageUpdate(bi,
|
||||
0, 0,
|
||||
width, height, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F);
|
||||
} else {
|
||||
int len = (this.width + 7) / 8;
|
||||
byte[] buf = new byte[len];
|
||||
byte[] data = ((DataBufferByte)tile.getDataBuffer()).getData();
|
||||
int lineStride = sm.getScanlineStride();
|
||||
iis.skipBytes(len * sourceRegion.y);
|
||||
int skipLength = len * (scaleY - 1);
|
||||
|
||||
// cache the values to avoid duplicated computation
|
||||
int[] srcOff = new int[destinationRegion.width];
|
||||
int[] destOff = new int[destinationRegion.width];
|
||||
int[] srcPos = new int[destinationRegion.width];
|
||||
int[] destPos = new int[destinationRegion.width];
|
||||
|
||||
for (int i = destinationRegion.x, x = sourceRegion.x, j = 0;
|
||||
i < destinationRegion.x + destinationRegion.width;
|
||||
i++, j++, x += scaleX) {
|
||||
srcPos[j] = x >> 3;
|
||||
srcOff[j] = 7 - (x & 7);
|
||||
destPos[j] = i >> 3;
|
||||
destOff[j] = 7 - (i & 7);
|
||||
}
|
||||
|
||||
for (int j = 0, y = sourceRegion.y,
|
||||
k = destinationRegion.y * lineStride;
|
||||
j < destinationRegion.height; j++, y+=scaleY) {
|
||||
|
||||
if (abortRequested())
|
||||
break;
|
||||
iis.read(buf, 0, len);
|
||||
for (int i = 0; i < destinationRegion.width; i++) {
|
||||
//get the bit and assign to the data buffer of the raster
|
||||
int v = (buf[srcPos[i]] >> srcOff[i]) & 1;
|
||||
data[k + destPos[i]] |= v << destOff[i];
|
||||
}
|
||||
|
||||
k += lineStride;
|
||||
iis.skipBytes(skipLength);
|
||||
processImageUpdate(bi,
|
||||
0, j,
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F*j/destinationRegion.height);
|
||||
}
|
||||
}
|
||||
|
||||
if (abortRequested())
|
||||
processReadAborted();
|
||||
else
|
||||
processImageComplete();
|
||||
return bi;
|
||||
}
|
||||
|
||||
public boolean canReadRaster() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Raster readRaster(int imageIndex,
|
||||
ImageReadParam param) throws IOException {
|
||||
BufferedImage bi = read(imageIndex, param);
|
||||
return bi.getData();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
iis = null;
|
||||
gotHeader = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method verifies that given byte is valid wbmp type marker.
|
||||
* At the moment only 0x0 marker is described by wbmp spec.
|
||||
*/
|
||||
boolean isValidWbmpType(int type) {
|
||||
return type == 0;
|
||||
}
|
||||
}
|
||||
130
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java
Normal file
130
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.wbmp;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
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"};
|
||||
private static String[] entensions = {"wbmp"};
|
||||
private static String[] mimeType = {"image/vnd.wap.wbmp"};
|
||||
|
||||
private boolean registered = false;
|
||||
|
||||
public WBMPImageReaderSpi() {
|
||||
super("Oracle Corporation",
|
||||
"1.0",
|
||||
formatNames,
|
||||
entensions,
|
||||
mimeType,
|
||||
"com.sun.imageio.plugins.wbmp.WBMPImageReader",
|
||||
new Class[] { ImageInputStream.class },
|
||||
writerSpiNames,
|
||||
true,
|
||||
null, null, null, null,
|
||||
true,
|
||||
WBMPMetadata.nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.wbmp.WBMPMetadataFormat",
|
||||
null, null);
|
||||
}
|
||||
|
||||
public void onRegistration(ServiceRegistry registry,
|
||||
Class<?> category) {
|
||||
if (registered) {
|
||||
return;
|
||||
}
|
||||
registered = true;
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard WBMP Image Reader";
|
||||
}
|
||||
|
||||
public boolean canDecodeInput(Object source) throws IOException {
|
||||
if (!(source instanceof ImageInputStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageInputStream stream = (ImageInputStream)source;
|
||||
|
||||
stream.mark();
|
||||
try {
|
||||
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
|
||||
return false;
|
||||
}
|
||||
|
||||
int width = ReaderUtil.readMultiByteInteger(stream);
|
||||
int height = ReaderUtil.readMultiByteInteger(stream);
|
||||
// check image dimension
|
||||
if (width <= 0 || height <= 0) {
|
||||
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.
|
||||
return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT);
|
||||
}
|
||||
|
||||
dataLength -= stream.getStreamPosition();
|
||||
|
||||
long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1);
|
||||
|
||||
return (dataLength == scanSize * height);
|
||||
} finally {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public ImageReader createReaderInstance(Object extension)
|
||||
throws IIOException {
|
||||
return new WBMPImageReader(this);
|
||||
}
|
||||
}
|
||||
315
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPImageWriter.java
Normal file
315
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPImageWriter.java
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.wbmp;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.metadata.IIOInvalidTreeException;
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
import com.sun.imageio.plugins.common.I18N;
|
||||
|
||||
/**
|
||||
* The Java Image IO plugin writer for encoding a binary RenderedImage into
|
||||
* a WBMP format.
|
||||
*
|
||||
* The encoding process may clip, subsample using the parameters
|
||||
* specified in the <code>ImageWriteParam</code>.
|
||||
*
|
||||
* @see com.sun.media.imageio.plugins.WBMPImageWriteParam
|
||||
*/
|
||||
public class WBMPImageWriter extends ImageWriter {
|
||||
/** The output stream to write into */
|
||||
private ImageOutputStream stream = null;
|
||||
|
||||
// Get the number of bits required to represent an int.
|
||||
private static int getNumBits(int intValue) {
|
||||
int numBits = 32;
|
||||
int mask = 0x80000000;
|
||||
while(mask != 0 && (intValue & mask) == 0) {
|
||||
numBits--;
|
||||
mask >>>= 1;
|
||||
}
|
||||
return numBits;
|
||||
}
|
||||
|
||||
// Convert an int value to WBMP multi-byte format.
|
||||
private static byte[] intToMultiByte(int intValue) {
|
||||
int numBitsLeft = getNumBits(intValue);
|
||||
byte[] multiBytes = new byte[(numBitsLeft + 6)/7];
|
||||
|
||||
int maxIndex = multiBytes.length - 1;
|
||||
for(int b = 0; b <= maxIndex; b++) {
|
||||
multiBytes[b] = (byte)((intValue >>> ((maxIndex - b)*7))&0x7f);
|
||||
if(b != maxIndex) {
|
||||
multiBytes[b] |= (byte)0x80;
|
||||
}
|
||||
}
|
||||
|
||||
return multiBytes;
|
||||
}
|
||||
|
||||
/** Constructs <code>WBMPImageWriter</code> based on the provided
|
||||
* <code>ImageWriterSpi</code>.
|
||||
*/
|
||||
public WBMPImageWriter(ImageWriterSpi originator) {
|
||||
super(originator);
|
||||
}
|
||||
|
||||
public void setOutput(Object output) {
|
||||
super.setOutput(output); // validates output
|
||||
if (output != null) {
|
||||
if (!(output instanceof ImageOutputStream))
|
||||
throw new IllegalArgumentException(I18N.getString("WBMPImageWriter"));
|
||||
this.stream = (ImageOutputStream)output;
|
||||
} else
|
||||
this.stream = null;
|
||||
}
|
||||
|
||||
public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,
|
||||
ImageWriteParam param) {
|
||||
WBMPMetadata meta = new WBMPMetadata();
|
||||
meta.wbmpType = 0; // default wbmp level
|
||||
return meta;
|
||||
}
|
||||
|
||||
public IIOMetadata convertStreamMetadata(IIOMetadata inData,
|
||||
ImageWriteParam param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIOMetadata convertImageMetadata(IIOMetadata metadata,
|
||||
ImageTypeSpecifier type,
|
||||
ImageWriteParam param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean canWriteRasters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void write(IIOMetadata streamMetadata,
|
||||
IIOImage image,
|
||||
ImageWriteParam param) throws IOException {
|
||||
|
||||
if (stream == null) {
|
||||
throw new IllegalStateException(I18N.getString("WBMPImageWriter3"));
|
||||
}
|
||||
|
||||
if (image == null) {
|
||||
throw new IllegalArgumentException(I18N.getString("WBMPImageWriter4"));
|
||||
}
|
||||
|
||||
clearAbortRequest();
|
||||
processImageStarted(0);
|
||||
if (param == null)
|
||||
param = getDefaultWriteParam();
|
||||
|
||||
RenderedImage input = null;
|
||||
Raster inputRaster = null;
|
||||
boolean writeRaster = image.hasRaster();
|
||||
Rectangle sourceRegion = param.getSourceRegion();
|
||||
SampleModel sampleModel = null;
|
||||
|
||||
if (writeRaster) {
|
||||
inputRaster = image.getRaster();
|
||||
sampleModel = inputRaster.getSampleModel();
|
||||
} else {
|
||||
input = image.getRenderedImage();
|
||||
sampleModel = input.getSampleModel();
|
||||
|
||||
inputRaster = input.getData();
|
||||
}
|
||||
|
||||
checkSampleModel(sampleModel);
|
||||
if (sourceRegion == null)
|
||||
sourceRegion = inputRaster.getBounds();
|
||||
else
|
||||
sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
|
||||
|
||||
if (sourceRegion.isEmpty())
|
||||
throw new RuntimeException(I18N.getString("WBMPImageWriter1"));
|
||||
|
||||
int scaleX = param.getSourceXSubsampling();
|
||||
int scaleY = param.getSourceYSubsampling();
|
||||
int xOffset = param.getSubsamplingXOffset();
|
||||
int yOffset = param.getSubsamplingYOffset();
|
||||
|
||||
sourceRegion.translate(xOffset, yOffset);
|
||||
sourceRegion.width -= xOffset;
|
||||
sourceRegion.height -= yOffset;
|
||||
|
||||
int minX = sourceRegion.x / scaleX;
|
||||
int minY = sourceRegion.y / scaleY;
|
||||
int w = (sourceRegion.width + scaleX - 1) / scaleX;
|
||||
int h = (sourceRegion.height + scaleY - 1) / scaleY;
|
||||
|
||||
Rectangle destinationRegion = new Rectangle(minX, minY, w, h);
|
||||
sampleModel = sampleModel.createCompatibleSampleModel(w, h);
|
||||
|
||||
SampleModel destSM= sampleModel;
|
||||
|
||||
// If the data are not formatted nominally then reformat.
|
||||
if(sampleModel.getDataType() != DataBuffer.TYPE_BYTE ||
|
||||
!(sampleModel instanceof MultiPixelPackedSampleModel) ||
|
||||
((MultiPixelPackedSampleModel)sampleModel).getDataBitOffset() != 0) {
|
||||
destSM =
|
||||
new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
|
||||
w, h, 1,
|
||||
w + 7 >> 3, 0);
|
||||
}
|
||||
|
||||
if (!destinationRegion.equals(sourceRegion)) {
|
||||
if (scaleX == 1 && scaleY == 1)
|
||||
inputRaster = inputRaster.createChild(inputRaster.getMinX(),
|
||||
inputRaster.getMinY(),
|
||||
w, h, minX, minY, null);
|
||||
else {
|
||||
WritableRaster ras = Raster.createWritableRaster(destSM,
|
||||
new Point(minX, minY));
|
||||
|
||||
byte[] data = ((DataBufferByte)ras.getDataBuffer()).getData();
|
||||
|
||||
for(int j = minY, y = sourceRegion.y, k = 0;
|
||||
j < minY + h; j++, y += scaleY) {
|
||||
|
||||
for (int i = 0, x = sourceRegion.x;
|
||||
i <w; i++, x +=scaleX) {
|
||||
int v = inputRaster.getSample(x, y, 0);
|
||||
data[k + (i >> 3)] |= v << (7 - (i & 7));
|
||||
}
|
||||
k += w + 7 >> 3;
|
||||
}
|
||||
inputRaster = ras;
|
||||
}
|
||||
}
|
||||
|
||||
// If the data are not formatted nominally then reformat.
|
||||
if(!destSM.equals(inputRaster.getSampleModel())) {
|
||||
WritableRaster raster =
|
||||
Raster.createWritableRaster(destSM,
|
||||
new Point(inputRaster.getMinX(),
|
||||
inputRaster.getMinY()));
|
||||
raster.setRect(inputRaster);
|
||||
inputRaster = raster;
|
||||
}
|
||||
|
||||
// Check whether the image is white-is-zero.
|
||||
boolean isWhiteZero = false;
|
||||
if(!writeRaster && input.getColorModel() instanceof IndexColorModel) {
|
||||
IndexColorModel icm = (IndexColorModel)input.getColorModel();
|
||||
isWhiteZero = icm.getRed(0) > icm.getRed(1);
|
||||
}
|
||||
|
||||
// Get the line stride, bytes per row, and data array.
|
||||
int lineStride =
|
||||
((MultiPixelPackedSampleModel)destSM).getScanlineStride();
|
||||
int bytesPerRow = (w + 7)/8;
|
||||
byte[] bdata = ((DataBufferByte)inputRaster.getDataBuffer()).getData();
|
||||
|
||||
// Write WBMP header.
|
||||
stream.write(0); // TypeField
|
||||
stream.write(0); // FixHeaderField
|
||||
stream.write(intToMultiByte(w)); // width
|
||||
stream.write(intToMultiByte(h)); // height
|
||||
|
||||
// Write the data.
|
||||
if(!isWhiteZero && lineStride == bytesPerRow) {
|
||||
// Write the entire image.
|
||||
stream.write(bdata, 0, h * bytesPerRow);
|
||||
processImageProgress(100.0F);
|
||||
} else {
|
||||
// Write the image row-by-row.
|
||||
int offset = 0;
|
||||
if(!isWhiteZero) {
|
||||
// Black-is-zero
|
||||
for(int row = 0; row < h; row++) {
|
||||
if (abortRequested())
|
||||
break;
|
||||
stream.write(bdata, offset, bytesPerRow);
|
||||
offset += lineStride;
|
||||
processImageProgress(100.0F * row / h);
|
||||
}
|
||||
} else {
|
||||
// White-is-zero: need to invert data.
|
||||
byte[] inverted = new byte[bytesPerRow];
|
||||
for(int row = 0; row < h; row++) {
|
||||
if (abortRequested())
|
||||
break;
|
||||
for(int col = 0; col < bytesPerRow; col++) {
|
||||
inverted[col] = (byte)(~(bdata[col+offset]));
|
||||
}
|
||||
stream.write(inverted, 0, bytesPerRow);
|
||||
offset += lineStride;
|
||||
processImageProgress(100.0F * row / h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (abortRequested())
|
||||
processWriteAborted();
|
||||
else {
|
||||
processImageComplete();
|
||||
stream.flushBefore(stream.getStreamPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
stream = null;
|
||||
}
|
||||
|
||||
private void checkSampleModel(SampleModel sm) {
|
||||
int type = sm.getDataType();
|
||||
if (type < DataBuffer.TYPE_BYTE || type > DataBuffer.TYPE_INT
|
||||
|| sm.getNumBands() != 1 || sm.getSampleSize(0) != 1)
|
||||
throw new IllegalArgumentException(I18N.getString("WBMPImageWriter2"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.wbmp;
|
||||
|
||||
import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.MultiPixelPackedSampleModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Locale;
|
||||
|
||||
public class WBMPImageWriterSpi extends ImageWriterSpi {
|
||||
private static String [] readerSpiNames =
|
||||
{"com.sun.imageio.plugins.wbmp.WBMPImageReaderSpi"};
|
||||
private static String[] formatNames = {"wbmp", "WBMP"};
|
||||
private static String[] entensions = {"wbmp"};
|
||||
private static String[] mimeType = {"image/vnd.wap.wbmp"};
|
||||
|
||||
private boolean registered = false;
|
||||
|
||||
public WBMPImageWriterSpi() {
|
||||
super("Oracle Corporation",
|
||||
"1.0",
|
||||
formatNames,
|
||||
entensions,
|
||||
mimeType,
|
||||
"com.sun.imageio.plugins.wbmp.WBMPImageWriter",
|
||||
new Class[] { ImageOutputStream.class },
|
||||
readerSpiNames,
|
||||
true,
|
||||
null, null, null, null,
|
||||
true,
|
||||
null, null, null, null);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Standard WBMP Image Writer";
|
||||
}
|
||||
|
||||
public void onRegistration(ServiceRegistry registry,
|
||||
Class<?> category) {
|
||||
if (registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
registered = true;
|
||||
}
|
||||
|
||||
public boolean canEncodeImage(ImageTypeSpecifier type) {
|
||||
SampleModel sm = type.getSampleModel();
|
||||
if (!(sm instanceof MultiPixelPackedSampleModel))
|
||||
return false;
|
||||
if (sm.getSampleSize(0) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ImageWriter createWriterInstance(Object extension)
|
||||
throws IIOException {
|
||||
return new WBMPImageWriter(this);
|
||||
}
|
||||
}
|
||||
134
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPMetadata.java
Normal file
134
jdkSrc/jdk8/com/sun/imageio/plugins/wbmp/WBMPMetadata.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.wbmp;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import org.w3c.dom.Node;
|
||||
import com.sun.imageio.plugins.common.I18N;
|
||||
|
||||
import com.sun.imageio.plugins.common.ImageUtil;
|
||||
|
||||
public class WBMPMetadata extends IIOMetadata {
|
||||
|
||||
static final String nativeMetadataFormatName =
|
||||
"javax_imageio_wbmp_1.0";
|
||||
|
||||
public int wbmpType;
|
||||
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
public WBMPMetadata() {
|
||||
super(true,
|
||||
nativeMetadataFormatName,
|
||||
"com.sun.imageio.plugins.wbmp.WBMPMetadataFormat",
|
||||
null, null);
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Node getAsTree(String formatName) {
|
||||
if (formatName.equals(nativeMetadataFormatName)) {
|
||||
return getNativeTree();
|
||||
} else if (formatName.equals
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
return getStandardTree();
|
||||
} else {
|
||||
throw new IllegalArgumentException(I18N.getString("WBMPMetadata0"));
|
||||
}
|
||||
}
|
||||
|
||||
private Node getNativeTree() {
|
||||
IIOMetadataNode root =
|
||||
new IIOMetadataNode(nativeMetadataFormatName);
|
||||
|
||||
addChildNode(root, "WBMPType", new Integer(wbmpType));
|
||||
addChildNode(root, "Width", new Integer(width));
|
||||
addChildNode(root, "Height", new Integer(height));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public void setFromTree(String formatName, Node root) {
|
||||
throw new IllegalStateException(I18N.getString("WBMPMetadata1"));
|
||||
}
|
||||
|
||||
public void mergeTree(String formatName, Node root) {
|
||||
throw new IllegalStateException(I18N.getString("WBMPMetadata1"));
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
throw new IllegalStateException(I18N.getString("WBMPMetadata1"));
|
||||
}
|
||||
|
||||
private IIOMetadataNode addChildNode(IIOMetadataNode root,
|
||||
String name,
|
||||
Object object) {
|
||||
IIOMetadataNode child = new IIOMetadataNode(name);
|
||||
if (object != null) {
|
||||
child.setUserObject(object);
|
||||
child.setNodeValue(ImageUtil.convertObjectToString(object));
|
||||
}
|
||||
root.appendChild(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
protected IIOMetadataNode getStandardChromaNode() {
|
||||
|
||||
IIOMetadataNode node = new IIOMetadataNode("Chroma");
|
||||
IIOMetadataNode subNode = new IIOMetadataNode("BlackIsZero");
|
||||
subNode.setAttribute("value", "TRUE");
|
||||
|
||||
node.appendChild(subNode);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
protected IIOMetadataNode getStandardDimensionNode() {
|
||||
IIOMetadataNode dimension_node = new IIOMetadataNode("Dimension");
|
||||
IIOMetadataNode node = null; // scratch node
|
||||
|
||||
// PixelAspectRatio not in image
|
||||
|
||||
node = new IIOMetadataNode("ImageOrientation");
|
||||
node.setAttribute("value", "Normal");
|
||||
dimension_node.appendChild(node);
|
||||
|
||||
return dimension_node;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.plugins.wbmp;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadataFormat;
|
||||
import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
|
||||
public class WBMPMetadataFormat extends IIOMetadataFormatImpl {
|
||||
|
||||
private static IIOMetadataFormat instance = null;
|
||||
|
||||
private WBMPMetadataFormat() {
|
||||
super(WBMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_SOME);
|
||||
|
||||
// root -> ImageDescriptor
|
||||
addElement("ImageDescriptor",
|
||||
WBMPMetadata.nativeMetadataFormatName,
|
||||
CHILD_POLICY_EMPTY);
|
||||
|
||||
addAttribute("ImageDescriptor", "WBMPType",
|
||||
DATATYPE_INTEGER, true, "0");
|
||||
|
||||
addAttribute("ImageDescriptor", "Width",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"0", "65535", true, true);
|
||||
addAttribute("ImageDescriptor", "Height",
|
||||
DATATYPE_INTEGER, true, null,
|
||||
"1", "65535", true, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean canNodeAppear(String elementName,
|
||||
ImageTypeSpecifier imageType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static synchronized IIOMetadataFormat getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new WBMPMetadataFormat();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
63
jdkSrc/jdk8/com/sun/imageio/spi/FileImageInputStreamSpi.java
Normal file
63
jdkSrc/jdk8/com/sun/imageio/spi/FileImageInputStreamSpi.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.FileImageInputStream;
|
||||
|
||||
public class FileImageInputStreamSpi extends ImageInputStreamSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final Class inputClass = File.class;
|
||||
|
||||
public FileImageInputStreamSpi() {
|
||||
super(vendorName, version, inputClass);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Service provider that instantiates a FileImageInputStream from a File";
|
||||
}
|
||||
|
||||
public ImageInputStream createInputStreamInstance(Object input,
|
||||
boolean useCache,
|
||||
File cacheDir) {
|
||||
if (input instanceof File) {
|
||||
try {
|
||||
return new FileImageInputStream((File)input);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageOutputStreamSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.stream.FileImageOutputStream;
|
||||
|
||||
public class FileImageOutputStreamSpi extends ImageOutputStreamSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final Class outputClass = File.class;
|
||||
|
||||
public FileImageOutputStreamSpi() {
|
||||
super(vendorName, version, outputClass);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Service provider that instantiates a FileImageOutputStream from a File";
|
||||
}
|
||||
|
||||
public ImageOutputStream createOutputStreamInstance(Object output,
|
||||
boolean useCache,
|
||||
File cacheDir) {
|
||||
if (output instanceof File) {
|
||||
try {
|
||||
return new FileImageOutputStream((File)output);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.FileCacheImageInputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
|
||||
public class InputStreamImageInputStreamSpi extends ImageInputStreamSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final Class inputClass = InputStream.class;
|
||||
|
||||
public InputStreamImageInputStreamSpi() {
|
||||
super(vendorName, version, inputClass);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Service provider that instantiates a FileCacheImageInputStream or MemoryCacheImageInputStream from an InputStream";
|
||||
}
|
||||
|
||||
public boolean canUseCacheFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean needsCacheFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ImageInputStream createInputStreamInstance(Object input,
|
||||
boolean useCache,
|
||||
File cacheDir)
|
||||
throws IOException {
|
||||
if (input instanceof InputStream) {
|
||||
InputStream is = (InputStream)input;
|
||||
|
||||
if (useCache) {
|
||||
return new FileCacheImageInputStream(is, cacheDir);
|
||||
} else {
|
||||
return new MemoryCacheImageInputStream(is);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageOutputStreamSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.stream.FileCacheImageOutputStream;
|
||||
import javax.imageio.stream.MemoryCacheImageOutputStream;
|
||||
|
||||
public class OutputStreamImageOutputStreamSpi extends ImageOutputStreamSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final Class outputClass = OutputStream.class;
|
||||
|
||||
public OutputStreamImageOutputStreamSpi() {
|
||||
super(vendorName, version, outputClass);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Service provider that instantiates an OutputStreamImageOutputStream from an OutputStream";
|
||||
}
|
||||
|
||||
public boolean canUseCacheFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean needsCacheFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ImageOutputStream createOutputStreamInstance(Object output,
|
||||
boolean useCache,
|
||||
File cacheDir)
|
||||
throws IOException {
|
||||
if (output instanceof OutputStream) {
|
||||
OutputStream os = (OutputStream)output;
|
||||
if (useCache) {
|
||||
return new FileCacheImageOutputStream(os, cacheDir);
|
||||
} else {
|
||||
return new MemoryCacheImageOutputStream(os);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
65
jdkSrc/jdk8/com/sun/imageio/spi/RAFImageInputStreamSpi.java
Normal file
65
jdkSrc/jdk8/com/sun/imageio/spi/RAFImageInputStreamSpi.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageInputStreamSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.FileImageInputStream;
|
||||
|
||||
public class RAFImageInputStreamSpi extends ImageInputStreamSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final Class inputClass = RandomAccessFile.class;
|
||||
|
||||
public RAFImageInputStreamSpi() {
|
||||
super(vendorName, version, inputClass);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Service provider that instantiates a FileImageInputStream from a RandomAccessFile";
|
||||
}
|
||||
|
||||
public ImageInputStream createInputStreamInstance(Object input,
|
||||
boolean useCache,
|
||||
File cacheDir) {
|
||||
if (input instanceof RandomAccessFile) {
|
||||
try {
|
||||
return new FileImageInputStream((RandomAccessFile)input);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException
|
||||
("input not a RandomAccessFile!");
|
||||
}
|
||||
}
|
||||
}
|
||||
66
jdkSrc/jdk8/com/sun/imageio/spi/RAFImageOutputStreamSpi.java
Normal file
66
jdkSrc/jdk8/com/sun/imageio/spi/RAFImageOutputStreamSpi.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.ImageOutputStreamSpi;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import javax.imageio.stream.FileImageOutputStream;
|
||||
|
||||
public class RAFImageOutputStreamSpi extends ImageOutputStreamSpi {
|
||||
|
||||
private static final String vendorName = "Oracle Corporation";
|
||||
|
||||
private static final String version = "1.0";
|
||||
|
||||
private static final Class outputClass = RandomAccessFile.class;
|
||||
|
||||
public RAFImageOutputStreamSpi() {
|
||||
super(vendorName, version, outputClass);
|
||||
}
|
||||
|
||||
public String getDescription(Locale locale) {
|
||||
return "Service provider that instantiates a FileImageOutputStream from a RandomAccessFile";
|
||||
}
|
||||
|
||||
public ImageOutputStream createOutputStreamInstance(Object output,
|
||||
boolean useCache,
|
||||
File cacheDir) {
|
||||
if (output instanceof RandomAccessFile) {
|
||||
try {
|
||||
return new FileImageOutputStream((RandomAccessFile)output);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException
|
||||
("input not a RandomAccessFile!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.stream;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import sun.java2d.DisposerRecord;
|
||||
|
||||
/**
|
||||
* Convenience class that closes a given resource (e.g. RandomAccessFile),
|
||||
* typically associated with an Image{Input,Output}Stream, prior to the
|
||||
* stream being garbage collected.
|
||||
*/
|
||||
public class CloseableDisposerRecord implements DisposerRecord {
|
||||
private Closeable closeable;
|
||||
|
||||
public CloseableDisposerRecord(Closeable closeable) {
|
||||
this.closeable = closeable;
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
if (closeable != null) {
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
closeable = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
134
jdkSrc/jdk8/com/sun/imageio/stream/StreamCloser.java
Normal file
134
jdkSrc/jdk8/com/sun/imageio/stream/StreamCloser.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* This class provide means to properly close hanging
|
||||
* image input/output streams on VM shutdown.
|
||||
* This might be useful for proper cleanup such as removal
|
||||
* of temporary files.
|
||||
*
|
||||
* Addition of stream do not prevent it from being garbage collected
|
||||
* if no other references to it exists. Stream can be closed
|
||||
* explicitly without removal from StreamCloser queue.
|
||||
* Explicit removal from the queue only helps to save some memory.
|
||||
*/
|
||||
public class StreamCloser {
|
||||
|
||||
private static WeakHashMap<CloseAction, Object> toCloseQueue;
|
||||
private static Thread streamCloser;
|
||||
|
||||
public static void addToQueue(CloseAction ca) {
|
||||
synchronized (StreamCloser.class) {
|
||||
if (toCloseQueue == null) {
|
||||
toCloseQueue =
|
||||
new WeakHashMap<CloseAction, Object>();
|
||||
}
|
||||
|
||||
toCloseQueue.put(ca, null);
|
||||
|
||||
if (streamCloser == null) {
|
||||
final Runnable streamCloserRunnable = new Runnable() {
|
||||
public void run() {
|
||||
if (toCloseQueue != null) {
|
||||
synchronized (StreamCloser.class) {
|
||||
Set<CloseAction> set =
|
||||
toCloseQueue.keySet();
|
||||
// Make a copy of the set in order to avoid
|
||||
// concurrent modification (the is.close()
|
||||
// will in turn call removeFromQueue())
|
||||
CloseAction[] actions =
|
||||
new CloseAction[set.size()];
|
||||
actions = set.toArray(actions);
|
||||
for (CloseAction ca : actions) {
|
||||
if (ca != null) {
|
||||
try {
|
||||
ca.performAction();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
/* The thread must be a member of a thread group
|
||||
* which will not get GCed before VM exit.
|
||||
* Make its parent the top-level thread group.
|
||||
*/
|
||||
ThreadGroup tg =
|
||||
Thread.currentThread().getThreadGroup();
|
||||
for (ThreadGroup tgn = tg;
|
||||
tgn != null;
|
||||
tg = tgn, tgn = tg.getParent());
|
||||
streamCloser = new Thread(tg, streamCloserRunnable);
|
||||
/* Set context class loader to null in order to avoid
|
||||
* keeping a strong reference to an application classloader.
|
||||
*/
|
||||
streamCloser.setContextClassLoader(null);
|
||||
Runtime.getRuntime().addShutdownHook(streamCloser);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeFromQueue(CloseAction ca) {
|
||||
synchronized (StreamCloser.class) {
|
||||
if (toCloseQueue != null) {
|
||||
toCloseQueue.remove(ca);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CloseAction createCloseAction(ImageInputStream iis) {
|
||||
return new CloseAction(iis);
|
||||
}
|
||||
|
||||
public static final class CloseAction {
|
||||
private ImageInputStream iis;
|
||||
|
||||
private CloseAction(ImageInputStream iis) {
|
||||
this.iis = iis;
|
||||
}
|
||||
|
||||
public void performAction() throws IOException {
|
||||
if (iis != null) {
|
||||
iis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
jdkSrc/jdk8/com/sun/imageio/stream/StreamFinalizer.java
Normal file
72
jdkSrc/jdk8/com/sun/imageio/stream/StreamFinalizer.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.imageio.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* Small class to assist in properly closing an ImageInputStream instance
|
||||
* prior to garbage collection. The ImageInputStreamImpl class defines a
|
||||
* finalize() method, but in a number of its public subclasses
|
||||
* (e.g. FileImageInputStream) we override the finalize() method to be
|
||||
* empty for performance reasons, and instead rely on the Disposer mechanism
|
||||
* for closing/disposing resources. This is fine when one of these classes
|
||||
* is instantiated directly (e.g. new FileImageInputStream()) but in the
|
||||
* unlikely case where a user defines their own subclass of one of those
|
||||
* streams, we need some way to get back to the behavior of
|
||||
* ImageInputStreamImpl, which will call close() as part of finalization.
|
||||
*
|
||||
* Typically an Image{Input,Output}Stream will construct an instance of
|
||||
* StreamFinalizer in its constructor if it detects that it has been
|
||||
* subclassed by the user. The ImageInputStream instance will hold a
|
||||
* reference to the StreamFinalizer, and the StreamFinalizer will hold a
|
||||
* reference back to the ImageInputStream from which it was created. When
|
||||
* both are no longer reachable, the StreamFinalizer.finalize() method will
|
||||
* be called, which will take care of closing down the ImageInputStream.
|
||||
*
|
||||
* Clearly this is a bit of a hack, but it will likely only be used in the
|
||||
* rarest of circumstances: when a user has subclassed one of the public
|
||||
* stream classes. (It should be no worse than the old days when the public
|
||||
* stream classes had non-empty finalize() methods.)
|
||||
*/
|
||||
public class StreamFinalizer {
|
||||
private ImageInputStream stream;
|
||||
|
||||
public StreamFinalizer(ImageInputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
stream = null;
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user