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.github.jaiimageio.jpeg2000.impl; 046 047import javax.imageio.metadata.IIOInvalidTreeException; 048import javax.imageio.metadata.IIOMetadataNode; 049 050import org.w3c.dom.Node; 051import org.w3c.dom.NodeList; 052 053/** This class is defined to represent a Resolution Box of JPEG JP2 054 * file format. A Data Entry URL Box has a length, and a fixed type 055 * of "resc" (capture resolution) or "resd" (default display resolution). 056 * 057 * Its contens includes the resolution numerators, denominator, and the 058 * exponents for both horizontal and vertical directions. 059 */ 060public class ResolutionBox extends Box { 061 /** The data elements in this box. */ 062 private short numV; 063 private short numH; 064 private short denomV; 065 private short denomH; 066 private byte expV; 067 private byte expH; 068 069 /** The cached horizontal/vertical resolutions. */ 070 private float hRes; 071 private float vRes; 072 073 /** Constructs a <code>ResolutionBox</code> from the provided type and 074 * content data array. 075 */ 076 public ResolutionBox(int type, byte[] data) { 077 super(18, type, data); 078 } 079 080 /** Constructs a <code>ResolutionBox</code> from the provided type and 081 * horizontal/vertical resolutions. 082 */ 083 public ResolutionBox(int type, float hRes, float vRes) { 084 super(18, type, null); 085 this.hRes = hRes; 086 this.vRes = vRes; 087 denomH = denomV = 1; 088 089 expV = 0; 090 if (vRes >= 32768) { 091 int temp = (int)vRes; 092 while (temp >= 32768) { 093 expV++; 094 temp /= 10; 095 } 096 numV = (short)(temp & 0xFFFF); 097 } else { 098 numV = (short)vRes; 099 } 100 101 expH = 0; 102 if (hRes >= 32768) { 103 int temp = (int)hRes; 104 while (temp >= 32768) { 105 expH++; 106 temp /= 10; 107 } 108 numH = (short)(temp & 0xFFFF); 109 } else { 110 numH = (short)hRes; 111 } 112 } 113 114 /** Constructs a <code>ResolutionBox</code> based on the provided 115 * <code>org.w3c.dom.Node</code>. 116 */ 117 public ResolutionBox(Node node) throws IIOInvalidTreeException { 118 super(node); 119 NodeList children = node.getChildNodes(); 120 for (int i = 0; i < children.getLength(); i++) { 121 Node child = children.item(i); 122 String name = child.getNodeName(); 123 124 if ("VerticalResolutionNumerator".equals(name)) { 125 numV = Box.getShortElementValue(child); 126 } 127 128 if ("VerticalResolutionDenominator".equals(name)) { 129 denomV = Box.getShortElementValue(child); 130 } 131 132 if ("HorizontalResolutionNumerator".equals(name)) { 133 numH = Box.getShortElementValue(child); 134 } 135 136 if ("HorizontalResolutionDenominator".equals(name)) { 137 denomH = Box.getShortElementValue(child); 138 } 139 140 if ("VerticalResolutionExponent".equals(name)) { 141 expV = Box.getByteElementValue(child); 142 } 143 144 if ("HorizontalResolutionExponent".equals(name)) { 145 expH = Box.getByteElementValue(child); 146 } 147 } 148 } 149 150 /** Return the horizontal resolution. */ 151 public float getHorizontalResolution() { 152 return hRes; 153 } 154 155 /** Return the vertical resolution. */ 156 public float getVerticalResolution() { 157 return vRes; 158 } 159 160 /** Parse the data elements from the provided content data array. */ 161 protected void parse(byte[] data) { 162 numV = (short)(((data[0] & 0xFF) << 8) | (data[1] & 0xFF)); 163 denomV = (short)(((data[2] & 0xFF) << 8) | (data[3] & 0xFF)); 164 numH = (short)(((data[4] & 0xFF) << 8) | (data[5] & 0xFF)); 165 denomH = (short)(((data[6] & 0xFF) << 8) | (data[7] & 0xFF)); 166 expV = data[8]; 167 expH = data[9]; 168 vRes = (float)((numV & 0xFFFF) * Math.pow(10, expV) / (denomV & 0xFFFF)); 169 hRes = (float)((numH & 0xFFFF)* Math.pow(10, expH) / (denomH & 0xFFFF)); 170 } 171 172 /** Creates an <code>IIOMetadataNode</code> from this resolution 173 * box. The format of this node is defined in the XML dtd and xsd 174 * for the JP2 image file. 175 */ 176 public IIOMetadataNode getNativeNode() { 177 IIOMetadataNode node = new IIOMetadataNode(Box.getName(getType())); 178 setDefaultAttributes(node); 179 180 IIOMetadataNode child = new IIOMetadataNode("VerticalResolutionNumerator"); 181 child.setUserObject(new Short(numV)); 182 child.setNodeValue("" + numV); 183 node.appendChild(child); 184 185 child = new IIOMetadataNode("VerticalResolutionDenominator"); 186 child.setUserObject(new Short(denomV)); 187 child.setNodeValue("" + denomV); 188 node.appendChild(child); 189 190 child = new IIOMetadataNode("HorizontalResolutionNumerator"); 191 child.setUserObject(new Short(numH)); 192 child.setNodeValue("" + numH); 193 node.appendChild(child); 194 195 child = new IIOMetadataNode("HorizontalResolutionDenominator"); 196 child.setUserObject(new Short(denomH)); 197 child.setNodeValue("" + denomH); 198 node.appendChild(child); 199 200 child = new IIOMetadataNode("VerticalResolutionExponent"); 201 child.setUserObject(new Byte(expV)); 202 child.setNodeValue("" + expV); 203 node.appendChild(child); 204 205 child = new IIOMetadataNode("HorizontalResolutionExponent"); 206 child.setUserObject(new Byte(expH)); 207 child.setNodeValue("" + expH); 208 node.appendChild(child); 209 210 return node; 211 } 212 213 protected void compose() { 214 if (data != null) 215 return; 216 data = new byte[10]; 217 data[0] = (byte)(numV >> 8); 218 data[1] = (byte)(numV & 0xFF); 219 data[2] = (byte)(denomV >> 8); 220 data[3] = (byte)(denomV & 0xFF); 221 222 data[4] = (byte)(numH >> 8); 223 data[5] = (byte)(numH & 0xFF); 224 data[6] = (byte)(denomH >> 8); 225 data[7] = (byte)(denomH & 0xFF); 226 227 data[8] = expV; 228 data[9] = expH; 229 } 230}