feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user