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.common; 27 28 import java.util.ArrayList; 29 import java.util.List; 30 import javax.imageio.ImageTypeSpecifier; 31 import javax.imageio.metadata.IIOMetadataFormatImpl; 32 33 public class StandardMetadataFormat extends IIOMetadataFormatImpl { 34 35 // Utility method for nodes with a single attribute named "value" 36 private void addSingleAttributeElement(String elementName, 37 String parentName, 38 int dataType) { 39 addElement(elementName, parentName, CHILD_POLICY_EMPTY); 40 addAttribute(elementName, "value", dataType, true, null); 41 } 42 43 public StandardMetadataFormat() { 44 super(standardMetadataFormatName, CHILD_POLICY_SOME); 45 List<String> values; 46 47 // root -> Chroma 48 addElement("Chroma", standardMetadataFormatName, 49 CHILD_POLICY_SOME); 50 51 // root -> Chroma -> ColorSpaceType 52 addElement("ColorSpaceType", "Chroma", 53 CHILD_POLICY_EMPTY); 54 55 values = new ArrayList<>(); 56 values.add("XYZ"); 57 values.add("Lab"); 58 values.add("Luv"); 59 values.add("YCbCr"); 60 values.add("Yxy"); 61 values.add("YCCK"); 62 values.add("PhotoYCC"); 63 values.add("RGB"); 64 values.add("GRAY"); 65 values.add("HSV"); 66 values.add("HLS"); 67 values.add("CMYK"); 68 values.add("CMY"); 69 values.add("2CLR"); 70 values.add("3CLR"); 71 values.add("4CLR"); 72 values.add("5CLR"); 73 values.add("6CLR"); 74 values.add("7CLR"); 75 values.add("8CLR"); 76 values.add("9CLR"); 77 values.add("ACLR"); 78 values.add("BCLR"); 79 values.add("CCLR"); 80 values.add("DCLR"); 81 values.add("ECLR"); 82 values.add("FCLR"); 83 addAttribute("ColorSpaceType", 84 "name", 85 DATATYPE_STRING, 86 true, 87 null, 88 values); 89 90 // root -> Chroma -> NumChannels 91 addElement("NumChannels", "Chroma", 92 CHILD_POLICY_EMPTY); 93 addAttribute("NumChannels", "value", 94 DATATYPE_INTEGER, 95 true, 96 0, Integer.MAX_VALUE); 97 98 // root -> Chroma -> Gamma 99 addElement("Gamma", "Chroma", CHILD_POLICY_EMPTY); 100 addAttribute("Gamma", "value", 101 DATATYPE_FLOAT, true, null); 102 103 // root -> Chroma -> BlackIsZero 104 addElement("BlackIsZero", "Chroma", CHILD_POLICY_EMPTY); 105 addBooleanAttribute("BlackIsZero", "value", true, true); 106 107 // root -> Chroma -> Palette 108 addElement("Palette", "Chroma", 0, Integer.MAX_VALUE); 109 110 // root -> Chroma -> PaletteEntry 111 addElement("PaletteEntry", "Palette", CHILD_POLICY_EMPTY); 112 addAttribute("PaletteEntry", "index", DATATYPE_INTEGER, 113 true, null); 114 addAttribute("PaletteEntry", "red", DATATYPE_INTEGER, 115 true, null); 116 addAttribute("PaletteEntry", "green", DATATYPE_INTEGER, 117 true, null); 118 addAttribute("PaletteEntry", "blue", DATATYPE_INTEGER, 119 true, null); 120 addAttribute("PaletteEntry", "alpha", DATATYPE_INTEGER, 121 false, "255"); 122 123 // root -> Chroma -> BackgroundIndex 124 addElement("BackgroundIndex", "Chroma", CHILD_POLICY_EMPTY); 125 addAttribute("BackgroundIndex", "value", DATATYPE_INTEGER, 126 true, null); 127 128 // root -> Chroma -> BackgroundColor 129 addElement("BackgroundColor", "Chroma", CHILD_POLICY_EMPTY); 130 addAttribute("BackgroundColor", "red", DATATYPE_INTEGER, 131 true, null); 132 addAttribute("BackgroundColor", "green", DATATYPE_INTEGER, 133 true, null); 134 addAttribute("BackgroundColor", "blue", DATATYPE_INTEGER, 135 true, null); 136 137 // root -> Compression 138 addElement("Compression", standardMetadataFormatName, 139 CHILD_POLICY_SOME); 140 141 // root -> Compression -> CompressionTypeName 142 addSingleAttributeElement("CompressionTypeName", 143 "Compression", 144 DATATYPE_STRING); 145 146 // root -> Compression -> Lossless 147 addElement("Lossless", "Compression", CHILD_POLICY_EMPTY); 148 addBooleanAttribute("Lossless", "value", true, true); 149 150 // root -> Compression -> NumProgressiveScans 151 addSingleAttributeElement("NumProgressiveScans", 152 "Compression", 153 DATATYPE_INTEGER); 154 155 // root -> Compression -> BitRate 156 addSingleAttributeElement("BitRate", 157 "Compression", 158 DATATYPE_FLOAT); 159 160 // root -> Data 161 addElement("Data", standardMetadataFormatName, 162 CHILD_POLICY_SOME); 163 164 // root -> Data -> PlanarConfiguration 165 addElement("PlanarConfiguration", "Data", CHILD_POLICY_EMPTY); 166 167 values = new ArrayList<>(); 168 values.add("PixelInterleaved"); 169 values.add("PlaneInterleaved"); 170 values.add("LineInterleaved"); 171 values.add("TileInterleaved"); 172 addAttribute("PlanarConfiguration", "value", 173 DATATYPE_STRING, 174 true, 175 null, 176 values); 177 178 // root -> Data -> SampleFormat 179 addElement("SampleFormat", "Data", CHILD_POLICY_EMPTY); 180 181 values = new ArrayList<>(); 182 values.add("SignedIntegral"); 183 values.add("UnsignedIntegral"); 184 values.add("Real"); 185 values.add("Index"); 186 addAttribute("SampleFormat", "value", 187 DATATYPE_STRING, 188 true, 189 null, 190 values); 191 192 // root -> Data -> BitsPerSample 193 addElement("BitsPerSample", "Data", 194 CHILD_POLICY_EMPTY); 195 addAttribute("BitsPerSample", "value", 196 DATATYPE_INTEGER, 197 true, 198 1, Integer.MAX_VALUE); 199 200 // root -> Data -> SignificantBitsPerSample 201 addElement("SignificantBitsPerSample", "Data", CHILD_POLICY_EMPTY); 202 addAttribute("SignificantBitsPerSample", "value", 203 DATATYPE_INTEGER, 204 true, 205 1, Integer.MAX_VALUE); 206 207 // root -> Data -> SampleMSB 208 addElement("SampleMSB", "Data", 209 CHILD_POLICY_EMPTY); 210 addAttribute("SampleMSB", "value", 211 DATATYPE_INTEGER, 212 true, 213 1, Integer.MAX_VALUE); 214 215 // root -> Dimension 216 addElement("Dimension", standardMetadataFormatName, 217 CHILD_POLICY_SOME); 218 219 // root -> Dimension -> PixelAspectRatio 220 addSingleAttributeElement("PixelAspectRatio", 221 "Dimension", 222 DATATYPE_FLOAT); 223 224 // root -> Dimension -> ImageOrientation 225 addElement("ImageOrientation", "Dimension", 226 CHILD_POLICY_EMPTY); 227 228 values = new ArrayList<>(); 229 values.add("Normal"); 230 values.add("Rotate90"); 231 values.add("Rotate180"); 232 values.add("Rotate270"); 233 values.add("FlipH"); 234 values.add("FlipV"); 235 values.add("FlipHRotate90"); 236 values.add("FlipVRotate90"); 237 addAttribute("ImageOrientation", "value", 238 DATATYPE_STRING, 239 true, 240 null, 241 values); 242 243 // root -> Dimension -> HorizontalPixelSize 244 addSingleAttributeElement("HorizontalPixelSize", 245 "Dimension", 246 DATATYPE_FLOAT); 247 248 // root -> Dimension -> VerticalPixelSize 249 addSingleAttributeElement("VerticalPixelSize", 250 "Dimension", 251 DATATYPE_FLOAT); 252 253 // root -> Dimension -> HorizontalPhysicalPixelSpacing 254 addSingleAttributeElement("HorizontalPhysicalPixelSpacing", 255 "Dimension", 256 DATATYPE_FLOAT); 257 258 // root -> Dimension -> VerticalPhysicalPixelSpacing 259 addSingleAttributeElement("VerticalPhysicalPixelSpacing", 260 "Dimension", 261 DATATYPE_FLOAT); 262 263 // root -> Dimension -> HorizontalPosition 264 addSingleAttributeElement("HorizontalPosition", 265 "Dimension", 266 DATATYPE_FLOAT); 267 268 // root -> Dimension -> VerticalPosition 269 addSingleAttributeElement("VerticalPosition", 270 "Dimension", 271 DATATYPE_FLOAT); 272 273 // root -> Dimension -> HorizontalPixelOffset 274 addSingleAttributeElement("HorizontalPixelOffset", 275 "Dimension", 276 DATATYPE_INTEGER); 277 278 // root -> Dimension -> VerticalPixelOffset 279 addSingleAttributeElement("VerticalPixelOffset", 280 "Dimension", 281 DATATYPE_INTEGER); 282 283 // root -> Dimension -> HorizontalScreenSize 284 addSingleAttributeElement("HorizontalScreenSize", 285 "Dimension", 286 DATATYPE_INTEGER); 287 288 // root -> Dimension -> VerticalScreenSize 289 addSingleAttributeElement("VerticalScreenSize", 290 "Dimension", 291 DATATYPE_INTEGER); 292 293 294 // root -> Document 295 addElement("Document", standardMetadataFormatName, 296 CHILD_POLICY_SOME); 297 298 // root -> Document -> FormatVersion 299 addElement("FormatVersion", "Document", 300 CHILD_POLICY_EMPTY); 301 addAttribute("FormatVersion", "value", 302 DATATYPE_STRING, 303 true, 304 null); 305 306 // root -> Document -> SubimageInterpretation 307 addElement("SubimageInterpretation", "Document", 308 CHILD_POLICY_EMPTY); 309 values = new ArrayList<>(); 310 values.add("Standalone"); 311 values.add("SinglePage"); 312 values.add("FullResolution"); 313 values.add("ReducedResolution"); 314 values.add("PyramidLayer"); 315 values.add("Preview"); 316 values.add("VolumeSlice"); 317 values.add("ObjectView"); 318 values.add("Panorama"); 319 values.add("AnimationFrame"); 320 values.add("TransparencyMask"); 321 values.add("CompositingLayer"); 322 values.add("SpectralSlice"); 323 values.add("Unknown"); 324 addAttribute("SubimageInterpretation", "value", 325 DATATYPE_STRING, 326 true, 327 null, 328 values); 329 330 // root -> Document -> ImageCreationTime 331 addElement("ImageCreationTime", "Document", 332 CHILD_POLICY_EMPTY); 333 addAttribute("ImageCreationTime", "year", 334 DATATYPE_INTEGER, 335 true, 336 null); 337 addAttribute("ImageCreationTime", "month", 338 DATATYPE_INTEGER, 339 true, 340 null, 341 "1", "12", true, true); 342 addAttribute("ImageCreationTime", "day", 343 DATATYPE_INTEGER, 344 true, 345 null, 346 "1", "31", true, true); 347 addAttribute("ImageCreationTime", "hour", 348 DATATYPE_INTEGER, 349 false, 350 "0", 351 "0", "23", true, true); 352 addAttribute("ImageCreationTime", "minute", 353 DATATYPE_INTEGER, 354 false, 355 "0", 356 "0", "59", true, true); 357 // second = 60 denotes leap second 358 addAttribute("ImageCreationTime", "second", 359 DATATYPE_INTEGER, 360 false, 361 "0", 362 "0", "60", true, true); 363 364 // root -> Document -> ImageModificationTime 365 addElement("ImageModificationTime", "Document", 366 CHILD_POLICY_EMPTY); 367 addAttribute("ImageModificationTime", "year", 368 DATATYPE_INTEGER, 369 true, 370 null); 371 addAttribute("ImageModificationTime", "month", 372 DATATYPE_INTEGER, 373 true, 374 null, 375 "1", "12", true, true); 376 addAttribute("ImageModificationTime", "day", 377 DATATYPE_INTEGER, 378 true, 379 null, 380 "1", "31", true, true); 381 addAttribute("ImageModificationTime", "hour", 382 DATATYPE_INTEGER, 383 false, 384 "0", 385 "0", "23", true, true); 386 addAttribute("ImageModificationTime", "minute", 387 DATATYPE_INTEGER, 388 false, 389 "0", 390 "0", "59", true, true); 391 // second = 60 denotes leap second 392 addAttribute("ImageModificationTime", "second", 393 DATATYPE_INTEGER, 394 false, 395 "0", 396 "0", "60", true, true); 397 398 // root -> Text 399 addElement("Text", standardMetadataFormatName, 400 0, Integer.MAX_VALUE); 401 402 // root -> Text -> TextEntry 403 addElement("TextEntry", "Text", CHILD_POLICY_EMPTY); 404 addAttribute("TextEntry", "keyword", 405 DATATYPE_STRING, 406 false, 407 null); 408 addAttribute("TextEntry", "value", 409 DATATYPE_STRING, 410 true, 411 null); 412 addAttribute("TextEntry", "language", 413 DATATYPE_STRING, 414 false, 415 null); 416 addAttribute("TextEntry", "encoding", 417 DATATYPE_STRING, 418 false, 419 null); 420 421 values = new ArrayList<>(); 422 values.add("none"); 423 values.add("lzw"); 424 values.add("zip"); 425 values.add("bzip"); 426 values.add("other"); 427 addAttribute("TextEntry", "compression", 428 DATATYPE_STRING, 429 false, 430 "none", 431 values); 432 433 // root -> Transparency 434 addElement("Transparency", standardMetadataFormatName, 435 CHILD_POLICY_SOME); 436 437 // root -> Transparency -> Alpha 438 addElement("Alpha", "Transparency", CHILD_POLICY_EMPTY); 439 440 values = new ArrayList<>(); 441 values.add("none"); 442 values.add("premultiplied"); 443 values.add("nonpremultiplied"); 444 addAttribute("Alpha", "value", 445 DATATYPE_STRING, 446 false, 447 "none", 448 values); 449 450 // root -> Transparency -> TransparentIndex 451 addSingleAttributeElement("TransparentIndex", "Transparency", 452 DATATYPE_INTEGER); 453 454 // root -> Transparency -> TransparentColor 455 addElement("TransparentColor", "Transparency", 456 CHILD_POLICY_EMPTY); 457 addAttribute("TransparentColor", "value", 458 DATATYPE_INTEGER, 459 true, 460 0, Integer.MAX_VALUE); 461 462 // root -> Transparency -> TileTransparencies 463 addElement("TileTransparencies", "Transparency", 464 0, Integer.MAX_VALUE); 465 466 // root -> Transparency -> TileTransparencies -> TransparentTile 467 addElement("TransparentTile", "TileTransparencies", 468 CHILD_POLICY_EMPTY); 469 addAttribute("TransparentTile", "x", 470 DATATYPE_INTEGER, 471 true, 472 null); 473 addAttribute("TransparentTile", "y", 474 DATATYPE_INTEGER, 475 true, 476 null); 477 478 // root -> Transparency -> TileOpacities 479 addElement("TileOpacities", "Transparency", 480 0, Integer.MAX_VALUE); 481 482 // root -> Transparency -> TileOpacities -> OpaqueTile 483 addElement("OpaqueTile", "TileOpacities", 484 CHILD_POLICY_EMPTY); 485 addAttribute("OpaqueTile", "x", 486 DATATYPE_INTEGER, 487 true, 488 null); 489 addAttribute("OpaqueTile", "y", 490 DATATYPE_INTEGER, 491 true, 492 null); 493 } 494 495 public boolean canNodeAppear(String elementName, 496 ImageTypeSpecifier imageType) { 497 return true; 498 } 499 }