241 lines · 9.1 KB · Java
RawDownload
/* * 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);        }    } }