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 }