1 /* 2 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.imageio.plugins.jpeg; 27 28 //import javax.imageio.IIOException; 29 import javax.imageio.metadata.IIOInvalidTreeException; 30 import javax.imageio.metadata.IIOMetadataNode; 31 import javax.imageio.stream.ImageOutputStream; 32 33 import java.io.IOException; 34 35 import org.w3c.dom.Node; 36 import org.w3c.dom.NodeList; 37 import org.w3c.dom.NamedNodeMap; 38 39 /** 40 * An SOS (Start Of Scan) marker segment. 41 */ 42 class SOSMarkerSegment extends MarkerSegment { 43 int startSpectralSelection; 44 int endSpectralSelection; 45 int approxHigh; 46 int approxLow; 47 ScanComponentSpec [] componentSpecs; // Array size is numScanComponents 48 49 SOSMarkerSegment(boolean willSubsample, 50 byte[] componentIDs, 51 int numComponents) { 52 super(JPEG.SOS); 53 startSpectralSelection = 0; 54 endSpectralSelection = 63; 55 approxHigh = 0; 56 approxLow = 0; 57 componentSpecs = new ScanComponentSpec[numComponents]; 58 for (int i = 0; i < numComponents; i++) { 59 int tableSel = 0; 60 if (willSubsample) { 61 if ((i == 1) || (i == 2)) { 62 tableSel = 1; 63 } 64 } 65 componentSpecs[i] = new ScanComponentSpec(componentIDs[i], 66 tableSel); 67 } 68 } 69 70 SOSMarkerSegment(JPEGBuffer buffer) throws IOException { 71 super(buffer); 72 int numComponents = buffer.buf[buffer.bufPtr++]; 73 componentSpecs = new ScanComponentSpec[numComponents]; 74 for (int i = 0; i < numComponents; i++) { 75 componentSpecs[i] = new ScanComponentSpec(buffer); 76 } 77 startSpectralSelection = buffer.buf[buffer.bufPtr++]; 78 endSpectralSelection = buffer.buf[buffer.bufPtr++]; 79 approxHigh = buffer.buf[buffer.bufPtr] >> 4; 80 approxLow = buffer.buf[buffer.bufPtr++] &0xf; 81 buffer.bufAvail -= length; 82 } 83 84 SOSMarkerSegment(Node node) throws IIOInvalidTreeException { 85 super(JPEG.SOS); 86 startSpectralSelection = 0; 87 endSpectralSelection = 63; 88 approxHigh = 0; 89 approxLow = 0; 90 updateFromNativeNode(node, true); 91 } 92 93 protected Object clone () { 94 SOSMarkerSegment newGuy = (SOSMarkerSegment) super.clone(); 95 if (componentSpecs != null) { 96 newGuy.componentSpecs = 97 (ScanComponentSpec []) componentSpecs.clone(); 98 for (int i = 0; i < componentSpecs.length; i++) { 99 newGuy.componentSpecs[i] = 100 (ScanComponentSpec) componentSpecs[i].clone(); 101 } 102 } 103 return newGuy; 104 } 105 106 IIOMetadataNode getNativeNode() { 107 IIOMetadataNode node = new IIOMetadataNode("sos"); 108 node.setAttribute("numScanComponents", 109 Integer.toString(componentSpecs.length)); 110 node.setAttribute("startSpectralSelection", 111 Integer.toString(startSpectralSelection)); 112 node.setAttribute("endSpectralSelection", 113 Integer.toString(endSpectralSelection)); 114 node.setAttribute("approxHigh", 115 Integer.toString(approxHigh)); 116 node.setAttribute("approxLow", 117 Integer.toString(approxLow)); 118 for (int i = 0; i < componentSpecs.length; i++) { 119 node.appendChild(componentSpecs[i].getNativeNode()); 120 } 121 122 return node; 123 } 124 125 void updateFromNativeNode(Node node, boolean fromScratch) 126 throws IIOInvalidTreeException { 127 NamedNodeMap attrs = node.getAttributes(); 128 int numComponents = getAttributeValue(node, attrs, "numScanComponents", 129 1, 4, true); 130 int value = getAttributeValue(node, attrs, "startSpectralSelection", 131 0, 63, false); 132 startSpectralSelection = (value != -1) ? value : startSpectralSelection; 133 value = getAttributeValue(node, attrs, "endSpectralSelection", 134 0, 63, false); 135 endSpectralSelection = (value != -1) ? value : endSpectralSelection; 136 value = getAttributeValue(node, attrs, "approxHigh", 0, 15, false); 137 approxHigh = (value != -1) ? value : approxHigh; 138 value = getAttributeValue(node, attrs, "approxLow", 0, 15, false); 139 approxLow = (value != -1) ? value : approxLow; 140 141 // Now the children 142 NodeList children = node.getChildNodes(); 143 if (children.getLength() != numComponents) { 144 throw new IIOInvalidTreeException 145 ("numScanComponents must match the number of children", node); 146 } 147 componentSpecs = new ScanComponentSpec[numComponents]; 148 for (int i = 0; i < numComponents; i++) { 149 componentSpecs[i] = new ScanComponentSpec(children.item(i)); 150 } 151 } 152 153 /** 154 * Writes the data for this segment to the stream in 155 * valid JPEG format. 156 */ 157 void write(ImageOutputStream ios) throws IOException { 158 // We don't write SOS segments; the IJG library does. 159 } 160 161 void print () { 162 printTag("SOS"); 163 System.out.print("Start spectral selection: "); 164 System.out.println(startSpectralSelection); 165 System.out.print("End spectral selection: "); 166 System.out.println(endSpectralSelection); 167 System.out.print("Approx high: "); 168 System.out.println(approxHigh); 169 System.out.print("Approx low: "); 170 System.out.println(approxLow); 171 System.out.print("Num scan components: "); 172 System.out.println(componentSpecs.length); 173 for (int i = 0; i< componentSpecs.length; i++) { 174 componentSpecs[i].print(); 175 } 176 } 177 178 ScanComponentSpec getScanComponentSpec(byte componentSel, int tableSel) { 179 return new ScanComponentSpec(componentSel, tableSel); 180 } 181 182 /** 183 * A scan component spec within an SOS marker segment. 184 */ 185 class ScanComponentSpec implements Cloneable { 186 int componentSelector; 187 int dcHuffTable; 188 int acHuffTable; 189 190 ScanComponentSpec(byte componentSel, int tableSel) { 191 componentSelector = componentSel; 192 dcHuffTable = tableSel; 193 acHuffTable = tableSel; 194 } 195 196 ScanComponentSpec(JPEGBuffer buffer) { 197 // Parent already loaded the buffer 198 componentSelector = buffer.buf[buffer.bufPtr++]; 199 dcHuffTable = buffer.buf[buffer.bufPtr] >> 4; 200 acHuffTable = buffer.buf[buffer.bufPtr++] & 0xf; 201 } 202 203 ScanComponentSpec(Node node) throws IIOInvalidTreeException { 204 NamedNodeMap attrs = node.getAttributes(); 205 componentSelector = getAttributeValue(node, attrs, "componentSelector", 206 0, 255, true); 207 dcHuffTable = getAttributeValue(node, attrs, "dcHuffTable", 208 0, 3, true); 209 acHuffTable = getAttributeValue(node, attrs, "acHuffTable", 210 0, 3, true); 211 } 212 213 protected Object clone() { 214 try { 215 return super.clone(); 216 } catch (CloneNotSupportedException e) {} // won't happen 217 return null; 218 } 219 220 IIOMetadataNode getNativeNode() { 221 IIOMetadataNode node = new IIOMetadataNode("scanComponentSpec"); 222 node.setAttribute("componentSelector", 223 Integer.toString(componentSelector)); 224 node.setAttribute("dcHuffTable", 225 Integer.toString(dcHuffTable)); 226 node.setAttribute("acHuffTable", 227 Integer.toString(acHuffTable)); 228 return node; 229 } 230 231 void print () { 232 System.out.print("Component Selector: "); 233 System.out.println(componentSelector); 234 System.out.print("DC huffman table: "); 235 System.out.println(dcHuffTable); 236 System.out.print("AC huffman table: "); 237 System.out.println(acHuffTable); 238 } 239 } 240 241 }