001/* 002 * $RCSfile: ResolutionBox.java,v $ 003 * 004 * 005 * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without 008 * modification, are permitted provided that the following conditions 009 * are met: 010 * 011 * - Redistribution of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * 014 * - Redistribution in binary form must reproduce the above copyright 015 * notice, this list of conditions and the following disclaimer in 016 * the documentation and/or other materials provided with the 017 * distribution. 018 * 019 * Neither the name of Sun Microsystems, Inc. or the names of 020 * contributors may be used to endorse or promote products derived 021 * from this software without specific prior written permission. 022 * 023 * This software is provided "AS IS," without a warranty of any 024 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 025 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 026 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 027 * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 028 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 029 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 030 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 031 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 032 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 033 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 034 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 035 * POSSIBILITY OF SUCH DAMAGES. 036 * 037 * You acknowledge that this software is not designed or intended for 038 * use in the design, construction, operation or maintenance of any 039 * nuclear facility. 040 * 041 * $Revision: 1.1 $ 042 * $Date: 2005/02/11 05:01:37 $ 043 * $State: Exp $ 044 */ 045package com.sun.media.imageioimpl.plugins.jpeg2000; 046 047import javax.imageio.metadata.IIOInvalidTreeException; 048import javax.imageio.metadata.IIOMetadataNode; 049import org.w3c.dom.Node; 050import org.w3c.dom.NodeList; 051 052/** This class is defined to represent a Resolution Box of JPEG JP2 053 * file format. A Data Entry URL Box has a length, and a fixed type 054 * of "resc" (capture resolution) or "resd" (default display resolution). 055 * 056 * Its contens includes the resolution numerators, denominator, and the 057 * exponents for both horizontal and vertical directions. 058 */ 059public class ResolutionBox extends Box { 060 /** The data elements in this box. */ 061 private short numV; 062 private short numH; 063 private short denomV; 064 private short denomH; 065 private byte expV; 066 private byte expH; 067 068 /** The cached horizontal/vertical resolutions. */ 069 private float hRes; 070 private float vRes; 071 072 /** Constructs a <code>ResolutionBox</code> from the provided type and 073 * content data array. 074 */ 075 public ResolutionBox(int type, byte[] data) { 076 super(18, type, data); 077 } 078 079 /** Constructs a <code>ResolutionBox</code> from the provided type and 080 * horizontal/vertical resolutions. 081 */ 082 public ResolutionBox(int type, float hRes, float vRes) { 083 super(18, type, null); 084 this.hRes = hRes; 085 this.vRes = vRes; 086 denomH = denomV = 1; 087 088 expV = 0; 089 if (vRes >= 32768) { 090 int temp = (int)vRes; 091 while (temp >= 32768) { 092 expV++; 093 temp /= 10; 094 } 095 numV = (short)(temp & 0xFFFF); 096 } else { 097 numV = (short)vRes; 098 } 099 100 expH = 0; 101 if (hRes >= 32768) { 102 int temp = (int)hRes; 103 while (temp >= 32768) { 104 expH++; 105 temp /= 10; 106 } 107 numH = (short)(temp & 0xFFFF); 108 } else { 109 numH = (short)hRes; 110 } 111 } 112 113 /** Constructs a <code>ResolutionBox</code> based on the provided 114 * <code>org.w3c.dom.Node</code>. 115 */ 116 public ResolutionBox(Node node) throws IIOInvalidTreeException { 117 super(node); 118 NodeList children = node.getChildNodes(); 119 for (int i = 0; i < children.getLength(); i++) { 120 Node child = children.item(i); 121 String name = child.getNodeName(); 122 123 if ("VerticalResolutionNumerator".equals(name)) { 124 numV = Box.getShortElementValue(child); 125 } 126 127 if ("VerticalResolutionDenominator".equals(name)) { 128 denomV = Box.getShortElementValue(child); 129 } 130 131 if ("HorizontalResolutionNumerator".equals(name)) { 132 numH = Box.getShortElementValue(child); 133 } 134 135 if ("HorizontalResolutionDenominator".equals(name)) { 136 denomH = Box.getShortElementValue(child); 137 } 138 139 if ("VerticalResolutionExponent".equals(name)) { 140 expV = Box.getByteElementValue(child); 141 } 142 143 if ("HorizontalResolutionExponent".equals(name)) { 144 expH = Box.getByteElementValue(child); 145 } 146 } 147 } 148 149 /** Return the horizontal resolution. */ 150 public float getHorizontalResolution() { 151 return hRes; 152 } 153 154 /** Return the vertical resolution. */ 155 public float getVerticalResolution() { 156 return vRes; 157 } 158 159 /** Parse the data elements from the provided content data array. */ 160 protected void parse(byte[] data) { 161 numV = (short)(((data[0] & 0xFF) << 8) | (data[1] & 0xFF)); 162 denomV = (short)(((data[2] & 0xFF) << 8) | (data[3] & 0xFF)); 163 numH = (short)(((data[4] & 0xFF) << 8) | (data[5] & 0xFF)); 164 denomH = (short)(((data[6] & 0xFF) << 8) | (data[7] & 0xFF)); 165 expV = data[8]; 166 expH = data[9]; 167 vRes = (float)((numV & 0xFFFF) * Math.pow(10, expV) / (denomV & 0xFFFF)); 168 hRes = (float)((numH & 0xFFFF)* Math.pow(10, expH) / (denomH & 0xFFFF)); 169 } 170 171 /** Creates an <code>IIOMetadataNode</code> from this resolution 172 * box. The format of this node is defined in the XML dtd and xsd 173 * for the JP2 image file. 174 */ 175 public IIOMetadataNode getNativeNode() { 176 IIOMetadataNode node = new IIOMetadataNode(Box.getName(getType())); 177 setDefaultAttributes(node); 178 179 IIOMetadataNode child = new IIOMetadataNode("VerticalResolutionNumerator"); 180 child.setUserObject(new Short(numV)); 181 child.setNodeValue("" + numV); 182 node.appendChild(child); 183 184 child = new IIOMetadataNode("VerticalResolutionDenominator"); 185 child.setUserObject(new Short(denomV)); 186 child.setNodeValue("" + denomV); 187 node.appendChild(child); 188 189 child = new IIOMetadataNode("HorizontalResolutionNumerator"); 190 child.setUserObject(new Short(numH)); 191 child.setNodeValue("" + numH); 192 node.appendChild(child); 193 194 child = new IIOMetadataNode("HorizontalResolutionDenominator"); 195 child.setUserObject(new Short(denomH)); 196 child.setNodeValue("" + denomH); 197 node.appendChild(child); 198 199 child = new IIOMetadataNode("VerticalResolutionExponent"); 200 child.setUserObject(new Byte(expV)); 201 child.setNodeValue("" + expV); 202 node.appendChild(child); 203 204 child = new IIOMetadataNode("HorizontalResolutionExponent"); 205 child.setUserObject(new Byte(expH)); 206 child.setNodeValue("" + expH); 207 node.appendChild(child); 208 209 return node; 210 } 211 212 protected void compose() { 213 if (data != null) 214 return; 215 data = new byte[10]; 216 data[0] = (byte)(numV >> 8); 217 data[1] = (byte)(numV & 0xFF); 218 data[2] = (byte)(denomV >> 8); 219 data[3] = (byte)(denomV & 0xFF); 220 221 data[4] = (byte)(numH >> 8); 222 data[5] = (byte)(numH & 0xFF); 223 data[6] = (byte)(denomH >> 8); 224 data[7] = (byte)(denomH & 0xFF); 225 226 data[8] = expV; 227 data[9] = expH; 228 } 229}