1 /* 2 * Copyright (c) 2001, 2004, 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.png; 27 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.List; 31 import java.util.ListResourceBundle; 32 import javax.imageio.ImageTypeSpecifier; 33 import javax.imageio.metadata.IIOMetadataFormat; 34 import javax.imageio.metadata.IIOMetadataFormatImpl; 35 36 public class PNGMetadataFormat extends IIOMetadataFormatImpl { 37 38 private static IIOMetadataFormat instance = null; 39 40 private static String VALUE_0 = "0"; 41 private static String VALUE_1 = "1"; 42 private static String VALUE_12 = "12"; 43 private static String VALUE_23 = "23"; 44 private static String VALUE_31 = "31"; 45 private static String VALUE_59 = "59"; 46 private static String VALUE_60 = "60"; 47 private static String VALUE_255 = "255"; 48 private static String VALUE_MAX_16 = "65535"; // 2^16 - 1 49 private static String VALUE_MAX_32 = "2147483647"; // 2^32 - 1 50 PNGMetadataFormat()51 private PNGMetadataFormat() { 52 super(PNGMetadata.nativeMetadataFormatName, 53 CHILD_POLICY_SOME); 54 55 // root -> IHDR 56 addElement("IHDR", PNGMetadata.nativeMetadataFormatName, 57 CHILD_POLICY_EMPTY); 58 59 addAttribute("IHDR", "width", 60 DATATYPE_INTEGER, true, null, 61 VALUE_1, VALUE_MAX_32, true, true); 62 63 addAttribute("IHDR", "height", 64 DATATYPE_INTEGER, true, null, 65 VALUE_1, VALUE_MAX_32, true, true); 66 67 addAttribute("IHDR", "bitDepth", 68 DATATYPE_INTEGER, true, null, 69 Arrays.asList(PNGMetadata.IHDR_bitDepths)); 70 71 String[] colorTypes = { 72 "Grayscale", "RGB", "Palette", "GrayAlpha", "RGBAlpha" 73 }; 74 addAttribute("IHDR", "colorType", 75 DATATYPE_STRING, true, null, 76 Arrays.asList(colorTypes)); 77 78 addAttribute("IHDR", "compressionMethod", 79 DATATYPE_STRING, true, null, 80 Arrays.asList(PNGMetadata.IHDR_compressionMethodNames)); 81 82 addAttribute("IHDR", "filterMethod", 83 DATATYPE_STRING, true, null, 84 Arrays.asList(PNGMetadata.IHDR_filterMethodNames)); 85 86 addAttribute("IHDR", "interlaceMethod", 87 DATATYPE_STRING, true, null, 88 Arrays.asList(PNGMetadata.IHDR_interlaceMethodNames)); 89 90 // root -> PLTE 91 addElement("PLTE", PNGMetadata.nativeMetadataFormatName, 92 1, 256); 93 94 // root -> PLTE -> PLTEEntry 95 addElement("PLTEEntry", "PLTE", 96 CHILD_POLICY_EMPTY); 97 98 addAttribute("PLTEEntry", "index", 99 DATATYPE_INTEGER, true, null, 100 VALUE_0, VALUE_255, true, true); 101 102 addAttribute("PLTEEntry", "red", 103 DATATYPE_INTEGER, true, null, 104 VALUE_0, VALUE_255, true, true); 105 106 addAttribute("PLTEEntry", "green", 107 DATATYPE_INTEGER, true, null, 108 VALUE_0, VALUE_255, true, true); 109 110 addAttribute("PLTEEntry", "blue", 111 DATATYPE_INTEGER, true, null, 112 VALUE_0, VALUE_255, true, true); 113 114 // root -> bKGD 115 addElement("bKGD", PNGMetadata.nativeMetadataFormatName, 116 CHILD_POLICY_CHOICE); 117 118 // root -> bKGD -> bKGD_Grayscale 119 addElement("bKGD_Grayscale", "bKGD", 120 CHILD_POLICY_EMPTY); 121 122 addAttribute("bKGD_Grayscale", "gray", 123 DATATYPE_INTEGER, true, null, 124 VALUE_0, VALUE_MAX_16, true, true); 125 126 // root -> bKGD -> bKGD_RGB 127 addElement("bKGD_RGB", "bKGD", 128 CHILD_POLICY_EMPTY); 129 130 addAttribute("bKGD_RGB", "red", 131 DATATYPE_INTEGER, true, null, 132 VALUE_0, VALUE_MAX_16, true, true); 133 134 addAttribute("bKGD_RGB", "green", 135 DATATYPE_INTEGER, true, null, 136 VALUE_0, VALUE_MAX_16, true, true); 137 138 addAttribute("bKGD_RGB", "blue", 139 DATATYPE_INTEGER, true, null, 140 VALUE_0, VALUE_MAX_16, true, true); 141 142 // root -> bKGD -> bKGD_Palette 143 addElement("bKGD_Palette", "bKGD", 144 CHILD_POLICY_EMPTY); 145 146 addAttribute("bKGD_Palette", "index", 147 DATATYPE_INTEGER, true, null, 148 VALUE_0, VALUE_255, true, true); 149 150 // root -> cHRM 151 addElement("cHRM", PNGMetadata.nativeMetadataFormatName, 152 CHILD_POLICY_EMPTY); 153 154 addAttribute("cHRM", "whitePointX", 155 DATATYPE_INTEGER, true, null, 156 VALUE_0, VALUE_MAX_16, true, true); 157 158 addAttribute("cHRM", "whitePointY", 159 DATATYPE_INTEGER, true, null, 160 VALUE_0, VALUE_MAX_16, true, true); 161 162 addAttribute("cHRM", "redX", 163 DATATYPE_INTEGER, true, null, 164 VALUE_0, VALUE_MAX_16, true, true); 165 166 addAttribute("cHRM", "redY", 167 DATATYPE_INTEGER, true, null, 168 VALUE_0, VALUE_MAX_16, true, true); 169 170 addAttribute("cHRM", "greenX", 171 DATATYPE_INTEGER, true, null, 172 VALUE_0, VALUE_MAX_16, true, true); 173 174 addAttribute("cHRM", "greenY", 175 DATATYPE_INTEGER, true, null, 176 VALUE_0, VALUE_MAX_16, true, true); 177 178 addAttribute("cHRM", "blueX", 179 DATATYPE_INTEGER, true, null, 180 VALUE_0, VALUE_MAX_16, true, true); 181 182 addAttribute("cHRM", "blueY", 183 DATATYPE_INTEGER, true, null, 184 VALUE_0, VALUE_MAX_16, true, true); 185 186 // root -> gAMA 187 addElement("gAMA", PNGMetadata.nativeMetadataFormatName, 188 CHILD_POLICY_EMPTY); 189 190 addAttribute("gAMA", "value", 191 DATATYPE_INTEGER, true, null, 192 VALUE_0, VALUE_MAX_32, true, true); 193 194 // root -> hIST 195 addElement("hIST", PNGMetadata.nativeMetadataFormatName, 196 1, 256); 197 198 // root -> hISTEntry 199 addElement("hISTEntry", "hIST", 200 CHILD_POLICY_EMPTY); 201 202 addAttribute("hISTEntry", "index", 203 DATATYPE_INTEGER, true, null, 204 VALUE_0, VALUE_255, true, true); 205 206 addAttribute("hISTEntry", "value", 207 DATATYPE_INTEGER, true, null, 208 VALUE_0, VALUE_MAX_16, true, true); 209 210 // root -> iCCP 211 addElement("iCCP", PNGMetadata.nativeMetadataFormatName, 212 CHILD_POLICY_EMPTY); 213 214 addAttribute("iCCP", "profileName", 215 DATATYPE_STRING, true, null); 216 217 addAttribute("iCCP", "compressionMethod", 218 DATATYPE_STRING, true, null, 219 Arrays.asList(PNGMetadata.iCCP_compressionMethodNames)); 220 221 addObjectValue("iCCP", byte.class, 0, Integer.MAX_VALUE); 222 223 // root -> iTXt 224 addElement("iTXt", PNGMetadata.nativeMetadataFormatName, 225 1, Integer.MAX_VALUE); 226 227 // root -> iTXt -> iTXtEntry 228 addElement("iTXtEntry", "iTXt", 229 CHILD_POLICY_EMPTY); 230 231 addAttribute("iTXtEntry", "keyword", 232 DATATYPE_STRING, true, null); 233 234 addBooleanAttribute("iTXtEntry", "compressionFlag", 235 false, false); 236 237 addAttribute("iTXtEntry", "compressionMethod", 238 DATATYPE_STRING, true, null); 239 240 addAttribute("iTXtEntry", "languageTag", 241 DATATYPE_STRING, true, null); 242 243 addAttribute("iTXtEntry", "translatedKeyword", 244 DATATYPE_STRING, true, null); 245 246 addAttribute("iTXtEntry", "text", 247 DATATYPE_STRING, true, null); 248 249 // root -> pHYS 250 addElement("pHYS", PNGMetadata.nativeMetadataFormatName, 251 CHILD_POLICY_EMPTY); 252 253 addAttribute("pHYS", "pixelsPerUnitXAxis", 254 DATATYPE_INTEGER, true, null, 255 VALUE_0, VALUE_MAX_32, true, true); 256 addAttribute("pHYS", "pixelsPerUnitYAxis", 257 DATATYPE_INTEGER, true, null, 258 VALUE_0, VALUE_MAX_32, true, true); 259 addAttribute("pHYS", "unitSpecifier", 260 DATATYPE_STRING, true, null, 261 Arrays.asList(PNGMetadata.unitSpecifierNames)); 262 263 // root -> sBIT 264 addElement("sBIT", PNGMetadata.nativeMetadataFormatName, 265 CHILD_POLICY_CHOICE); 266 267 // root -> sBIT -> sBIT_Grayscale 268 addElement("sBIT_Grayscale", "sBIT", 269 CHILD_POLICY_EMPTY); 270 271 addAttribute("sBIT_Grayscale", "gray", 272 DATATYPE_INTEGER, true, null, 273 VALUE_0, VALUE_255, true, true); 274 275 // root -> sBIT -> sBIT_GrayAlpha 276 addElement("sBIT_GrayAlpha", "sBIT", 277 CHILD_POLICY_EMPTY); 278 279 addAttribute("sBIT_GrayAlpha", "gray", 280 DATATYPE_INTEGER, true, null, 281 VALUE_0, VALUE_255, true, true); 282 283 addAttribute("sBIT_GrayAlpha", "alpha", 284 DATATYPE_INTEGER, true, null, 285 VALUE_0, VALUE_255, true, true); 286 287 // root -> sBIT -> sBIT_RGB 288 addElement("sBIT_RGB", "sBIT", 289 CHILD_POLICY_EMPTY); 290 291 addAttribute("sBIT_RGB", "red", 292 DATATYPE_INTEGER, true, null, 293 VALUE_0, VALUE_255, true, true); 294 295 addAttribute("sBIT_RGB", "green", 296 DATATYPE_INTEGER, true, null, 297 VALUE_0, VALUE_255, true, true); 298 299 addAttribute("sBIT_RGB", "blue", 300 DATATYPE_INTEGER, true, null, 301 VALUE_0, VALUE_255, true, true); 302 303 // root -> sBIT -> sBIT_RGBAlpha 304 addElement("sBIT_RGBAlpha", "sBIT", 305 CHILD_POLICY_EMPTY); 306 307 addAttribute("sBIT_RGBAlpha", "red", 308 DATATYPE_INTEGER, true, null, 309 VALUE_0, VALUE_255, true, true); 310 311 addAttribute("sBIT_RGBAlpha", "green", 312 DATATYPE_INTEGER, true, null, 313 VALUE_0, VALUE_255, true, true); 314 315 addAttribute("sBIT_RGBAlpha", "blue", 316 DATATYPE_INTEGER, true, null, 317 VALUE_0, VALUE_255, true, true); 318 319 addAttribute("sBIT_RGBAlpha", "alpha", 320 DATATYPE_INTEGER, true, null, 321 VALUE_0, VALUE_255, true, true); 322 323 // root -> sBIT -> sBIT_Palette 324 addElement("sBIT_Palette", "sBIT", 325 CHILD_POLICY_EMPTY); 326 327 addAttribute("sBIT_Palette", "red", 328 DATATYPE_INTEGER, true, null, 329 VALUE_0, VALUE_255, true, true); 330 331 addAttribute("sBIT_Palette", "green", 332 DATATYPE_INTEGER, true, null, 333 VALUE_0, VALUE_255, true, true); 334 335 addAttribute("sBIT_Palette", "blue", 336 DATATYPE_INTEGER, true, null, 337 VALUE_0, VALUE_255, true, true); 338 339 // root -> sPLT 340 addElement("sPLT", PNGMetadata.nativeMetadataFormatName, 341 1, 256); 342 343 // root -> sPLT -> sPLTEntry 344 addElement("sPLTEntry", "sPLT", 345 CHILD_POLICY_EMPTY); 346 347 addAttribute("sPLTEntry", "index", 348 DATATYPE_INTEGER, true, null, 349 VALUE_0, VALUE_255, true, true); 350 351 addAttribute("sPLTEntry", "red", 352 DATATYPE_INTEGER, true, null, 353 VALUE_0, VALUE_255, true, true); 354 355 addAttribute("sPLTEntry", "green", 356 DATATYPE_INTEGER, true, null, 357 VALUE_0, VALUE_255, true, true); 358 359 addAttribute("sPLTEntry", "blue", 360 DATATYPE_INTEGER, true, null, 361 VALUE_0, VALUE_255, true, true); 362 363 addAttribute("sPLTEntry", "alpha", 364 DATATYPE_INTEGER, true, null, 365 VALUE_0, VALUE_255, true, true); 366 367 // root -> sRGB 368 addElement("sRGB", PNGMetadata.nativeMetadataFormatName, 369 CHILD_POLICY_EMPTY); 370 371 addAttribute("sRGB", "renderingIntent", 372 DATATYPE_STRING, true, null, 373 Arrays.asList(PNGMetadata.renderingIntentNames)); 374 375 // root -> tEXt 376 addElement("tEXt", PNGMetadata.nativeMetadataFormatName, 377 1, Integer.MAX_VALUE); 378 379 // root -> tEXt -> tEXtEntry 380 addElement("tEXtEntry", "tEXt", 381 CHILD_POLICY_EMPTY); 382 383 addAttribute("tEXtEntry", "keyword", 384 DATATYPE_STRING, true, null); 385 386 addAttribute("tEXtEntry", "value", 387 DATATYPE_STRING, true, null); 388 389 // root -> tIME 390 addElement("tIME", PNGMetadata.nativeMetadataFormatName, 391 CHILD_POLICY_EMPTY); 392 393 addAttribute("tIME", "year", 394 DATATYPE_INTEGER, true, null, 395 VALUE_0, VALUE_MAX_16, true, true); 396 397 addAttribute("tIME", "month", 398 DATATYPE_INTEGER, true, null, 399 VALUE_1, VALUE_12, true, true); 400 401 addAttribute("tIME", "day", 402 DATATYPE_INTEGER, true, null, 403 VALUE_1, VALUE_31, true, true); 404 405 addAttribute("tIME", "hour", 406 DATATYPE_INTEGER, true, null, 407 VALUE_0, VALUE_23, true, true); 408 409 addAttribute("tIME", "minute", 410 DATATYPE_INTEGER, true, null, 411 VALUE_0, VALUE_59, true, true); 412 413 addAttribute("tIME", "second", 414 DATATYPE_INTEGER, true, null, 415 VALUE_0, VALUE_60, true, true); 416 417 // root -> tRNS 418 addElement("tRNS", PNGMetadata.nativeMetadataFormatName, 419 CHILD_POLICY_CHOICE); 420 421 // root -> tRNS -> tRNS_Grayscale 422 addElement("tRNS_Grayscale", "tRNS", 423 CHILD_POLICY_EMPTY); 424 425 addAttribute("tRNS_Grayscale", "gray", 426 DATATYPE_INTEGER, true, null, 427 VALUE_0, VALUE_MAX_16, true, true); 428 429 // root -> tRNS -> tRNS_RGB 430 addElement("tRNS_RGB", "tRNS", 431 CHILD_POLICY_EMPTY); 432 433 addAttribute("tRNS_RGB", "red", 434 DATATYPE_INTEGER, true, null, 435 VALUE_0, VALUE_MAX_16, true, true); 436 437 addAttribute("tRNS_RGB", "green", 438 DATATYPE_INTEGER, true, null, 439 VALUE_0, VALUE_MAX_16, true, true); 440 441 addAttribute("tRNS_RGB", "blue", 442 DATATYPE_INTEGER, true, null, 443 VALUE_0, VALUE_MAX_16, true, true); 444 445 // root -> tRNS -> tRNS_Palette 446 addElement("tRNS_Palette", "tRNS", 447 CHILD_POLICY_EMPTY); 448 449 addAttribute("tRNS_Palette", "index", 450 DATATYPE_INTEGER, true, null, 451 VALUE_0, VALUE_255, true, true); 452 453 addAttribute("tRNS_Palette", "alpha", 454 DATATYPE_INTEGER, true, null, 455 VALUE_0, VALUE_255, true, true); 456 457 // root -> zTXt 458 addElement("zTXt", PNGMetadata.nativeMetadataFormatName, 459 1, Integer.MAX_VALUE); 460 461 // root -> zTXt -> zTXtEntry 462 addElement("zTXtEntry", "zTXt", 463 CHILD_POLICY_EMPTY); 464 465 addAttribute("zTXtEntry", "keyword", 466 DATATYPE_STRING, true, null); 467 468 addAttribute("zTXtEntry", "compressionMethod", 469 DATATYPE_STRING, true, null, 470 Arrays.asList(PNGMetadata.zTXt_compressionMethodNames)); 471 472 addAttribute("zTXtEntry", "text", 473 DATATYPE_STRING, true, null); 474 475 // root -> UnknownChunks 476 addElement("UnknownChunks", PNGMetadata.nativeMetadataFormatName, 477 1, Integer.MAX_VALUE); 478 479 // root -> UnknownChunks -> UnknownChunk 480 addElement("UnknownChunk", "UnknownChunks", 481 CHILD_POLICY_EMPTY); 482 483 addAttribute("UnknownChunk", "type", 484 DATATYPE_STRING, true, null); 485 486 addObjectValue("UnknownChunk", byte.class, 0, Integer.MAX_VALUE); 487 } 488 canNodeAppear(String elementName, ImageTypeSpecifier imageType)489 public boolean canNodeAppear(String elementName, 490 ImageTypeSpecifier imageType) { 491 return true; 492 } 493 getInstance()494 public static synchronized IIOMetadataFormat getInstance() { 495 if (instance == null) { 496 instance = new PNGMetadataFormat(); 497 } 498 return instance; 499 } 500 } 501