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.metadata.IIOMetadataFormat; 29 import javax.imageio.metadata.IIOMetadataFormatImpl; 30 import javax.imageio.ImageTypeSpecifier; 31 32 import java.awt.color.ICC_Profile; 33 import java.awt.color.ColorSpace; 34 import java.awt.image.ColorModel; 35 36 import java.util.List; 37 import java.util.ArrayList; 38 39 public class JPEGImageMetadataFormat extends JPEGMetadataFormat { 40 41 private static JPEGImageMetadataFormat theInstance = null; 42 43 private JPEGImageMetadataFormat() { 44 super(JPEG.nativeImageMetadataFormatName, 45 CHILD_POLICY_ALL); 46 47 addElement("JPEGvariety", 48 JPEG.nativeImageMetadataFormatName, 49 CHILD_POLICY_CHOICE); 50 51 addElement("markerSequence", 52 JPEG.nativeImageMetadataFormatName, 53 CHILD_POLICY_SEQUENCE); 54 55 addElement("app0JFIF", "JPEGvariety", CHILD_POLICY_SOME); 56 57 addStreamElements("markerSequence"); 58 59 addElement("app14Adobe", "markerSequence", CHILD_POLICY_EMPTY); 60 61 addElement("sof", "markerSequence", 1, 4); 62 63 addElement("sos", "markerSequence", 1, 4); 64 65 addElement("JFXX", "app0JFIF", 1, Integer.MAX_VALUE); 66 67 addElement("app0JFXX", "JFXX", CHILD_POLICY_CHOICE); 68 69 addElement("app2ICC", "app0JFIF", CHILD_POLICY_EMPTY); 70 71 addAttribute("app0JFIF", 72 "majorVersion", 73 DATATYPE_INTEGER, 74 false, 75 "1", 76 "0", "255", 77 true, true); 78 addAttribute("app0JFIF", 79 "minorVersion", 80 DATATYPE_INTEGER, 81 false, 82 "2", 83 "0", "255", 84 true, true); 85 List resUnits = new ArrayList(); 86 resUnits.add("0"); 87 resUnits.add("1"); 88 resUnits.add("2"); 89 addAttribute("app0JFIF", 90 "resUnits", 91 DATATYPE_INTEGER, 92 false, 93 "0", 94 resUnits); 95 addAttribute("app0JFIF", 96 "Xdensity", 97 DATATYPE_INTEGER, 98 false, 99 "1", 100 "1", "65535", 101 true, true); 102 addAttribute("app0JFIF", 103 "Ydensity", 104 DATATYPE_INTEGER, 105 false, 106 "1", 107 "1", "65535", 108 true, true); 109 addAttribute("app0JFIF", 110 "thumbWidth", 111 DATATYPE_INTEGER, 112 false, 113 "0", 114 "0", "255", 115 true, true); 116 addAttribute("app0JFIF", 117 "thumbHeight", 118 DATATYPE_INTEGER, 119 false, 120 "0", 121 "0", "255", 122 true, true); 123 124 addElement("JFIFthumbJPEG", "app0JFXX", CHILD_POLICY_SOME); 125 addElement("JFIFthumbPalette", "app0JFXX", CHILD_POLICY_EMPTY); 126 addElement("JFIFthumbRGB", "app0JFXX", CHILD_POLICY_EMPTY); 127 128 List codes = new ArrayList(); 129 codes.add("16"); // Hex 10 130 codes.add("17"); // Hex 11 131 codes.add("19"); // Hex 13 132 addAttribute("app0JFXX", 133 "extensionCode", 134 DATATYPE_INTEGER, 135 false, 136 null, 137 codes); 138 139 addChildElement("markerSequence", "JFIFthumbJPEG"); 140 141 addAttribute("JFIFthumbPalette", 142 "thumbWidth", 143 DATATYPE_INTEGER, 144 false, 145 null, 146 "0", "255", 147 true, true); 148 addAttribute("JFIFthumbPalette", 149 "thumbHeight", 150 DATATYPE_INTEGER, 151 false, 152 null, 153 "0", "255", 154 true, true); 155 156 addAttribute("JFIFthumbRGB", 157 "thumbWidth", 158 DATATYPE_INTEGER, 159 false, 160 null, 161 "0", "255", 162 true, true); 163 addAttribute("JFIFthumbRGB", 164 "thumbHeight", 165 DATATYPE_INTEGER, 166 false, 167 null, 168 "0", "255", 169 true, true); 170 171 addObjectValue("app2ICC", ICC_Profile.class, false, null); 172 173 addAttribute("app14Adobe", 174 "version", 175 DATATYPE_INTEGER, 176 false, 177 "100", 178 "100", "255", 179 true, true); 180 addAttribute("app14Adobe", 181 "flags0", 182 DATATYPE_INTEGER, 183 false, 184 "0", 185 "0", "65535", 186 true, true); 187 addAttribute("app14Adobe", 188 "flags1", 189 DATATYPE_INTEGER, 190 false, 191 "0", 192 "0", "65535", 193 true, true); 194 195 List transforms = new ArrayList(); 196 transforms.add("0"); 197 transforms.add("1"); 198 transforms.add("2"); 199 addAttribute("app14Adobe", 200 "transform", 201 DATATYPE_INTEGER, 202 true, 203 null, 204 transforms); 205 206 addElement("componentSpec", "sof", CHILD_POLICY_EMPTY); 207 208 List procs = new ArrayList(); 209 procs.add("0"); 210 procs.add("1"); 211 procs.add("2"); 212 addAttribute("sof", 213 "process", 214 DATATYPE_INTEGER, 215 false, 216 null, 217 procs); 218 addAttribute("sof", 219 "samplePrecision", 220 DATATYPE_INTEGER, 221 false, 222 "8"); 223 addAttribute("sof", 224 "numLines", 225 DATATYPE_INTEGER, 226 false, 227 null, 228 "0", "65535", 229 true, true); 230 addAttribute("sof", 231 "samplesPerLine", 232 DATATYPE_INTEGER, 233 false, 234 null, 235 "0", "65535", 236 true, true); 237 List comps = new ArrayList(); 238 comps.add("1"); 239 comps.add("2"); 240 comps.add("3"); 241 comps.add("4"); 242 addAttribute("sof", 243 "numFrameComponents", 244 DATATYPE_INTEGER, 245 false, 246 null, 247 comps); 248 249 addAttribute("componentSpec", 250 "componentId", 251 DATATYPE_INTEGER, 252 true, 253 null, 254 "0", "255", 255 true, true); 256 addAttribute("componentSpec", 257 "HsamplingFactor", 258 DATATYPE_INTEGER, 259 true, 260 null, 261 "1", "255", 262 true, true); 263 addAttribute("componentSpec", 264 "VsamplingFactor", 265 DATATYPE_INTEGER, 266 true, 267 null, 268 "1", "255", 269 true, true); 270 List tabids = new ArrayList(); 271 tabids.add("0"); 272 tabids.add("1"); 273 tabids.add("2"); 274 tabids.add("3"); 275 addAttribute("componentSpec", 276 "QtableSelector", 277 DATATYPE_INTEGER, 278 true, 279 null, 280 tabids); 281 282 addElement("scanComponentSpec", "sos", CHILD_POLICY_EMPTY); 283 284 addAttribute("sos", 285 "numScanComponents", 286 DATATYPE_INTEGER, 287 true, 288 null, 289 comps); 290 addAttribute("sos", 291 "startSpectralSelection", 292 DATATYPE_INTEGER, 293 false, 294 "0", 295 "0", "63", 296 true, true); 297 addAttribute("sos", 298 "endSpectralSelection", 299 DATATYPE_INTEGER, 300 false, 301 "63", 302 "0", "63", 303 true, true); 304 addAttribute("sos", 305 "approxHigh", 306 DATATYPE_INTEGER, 307 false, 308 "0", 309 "0", "15", 310 true, true); 311 addAttribute("sos", 312 "approxLow", 313 DATATYPE_INTEGER, 314 false, 315 "0", 316 "0", "15", 317 true, true); 318 319 addAttribute("scanComponentSpec", 320 "componentSelector", 321 DATATYPE_INTEGER, 322 true, 323 null, 324 "0", "255", 325 true, true); 326 addAttribute("scanComponentSpec", 327 "dcHuffTable", 328 DATATYPE_INTEGER, 329 true, 330 null, 331 tabids); 332 addAttribute("scanComponentSpec", 333 "acHuffTable", 334 DATATYPE_INTEGER, 335 true, 336 null, 337 tabids); 338 } 339 340 public boolean canNodeAppear(String elementName, 341 ImageTypeSpecifier imageType) { 342 // All images can have these 343 if (elementName.equals(getRootName()) 344 || elementName.equals("JPEGvariety") 345 || isInSubtree(elementName, "markerSequence")) { 346 return true; 347 } 348 349 // If it is an element in the app0jfif subtree, just check 350 // that the image type is JFIF compliant. 351 if ((isInSubtree(elementName, "app0JFIF")) 352 && JPEG.isJFIFcompliant(imageType, true)) { 353 return true; 354 } 355 356 return false; 357 } 358 359 360 public static synchronized IIOMetadataFormat getInstance() { 361 if (theInstance == null) { 362 theInstance = new JPEGImageMetadataFormat(); 363 } 364 return theInstance; 365 } 366 }