/* * 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); } } }
/*
* 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);
}
}
}