001/*
002 * $RCSfile: CLibPNGMetadataFormat.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:39 $
043 * $State: Exp $
044 */
045
046package com.github.jaiimageio.impl.plugins.png;
047
048import java.util.ArrayList;
049import java.util.Arrays;
050import java.util.List;
051import java.util.ListResourceBundle;
052import javax.imageio.ImageTypeSpecifier;
053import javax.imageio.metadata.IIOMetadataFormat;
054import javax.imageio.metadata.IIOMetadataFormatImpl;
055
056public class CLibPNGMetadataFormat extends IIOMetadataFormatImpl {
057
058    private static IIOMetadataFormat instance = null;
059
060    private static String VALUE_0 = "0";
061    private static String VALUE_1 = "1";
062    private static String VALUE_12 = "12";
063    private static String VALUE_23 = "23";
064    private static String VALUE_31 = "31";
065    private static String VALUE_59 = "59";
066    private static String VALUE_60 = "60";
067    private static String VALUE_255 = "255";
068    private static String VALUE_MAX_16 = "65535"; // 2^16 - 1
069    private static String VALUE_MAX_32 = "2147483647"; // 2^32 - 1
070
071    private CLibPNGMetadataFormat() {
072        super(CLibPNGMetadata.nativeMetadataFormatName,
073              CHILD_POLICY_SOME);
074
075        // root -> IHDR
076        addElement("IHDR", CLibPNGMetadata.nativeMetadataFormatName,
077                   CHILD_POLICY_EMPTY);
078
079        addAttribute("IHDR", "width", 
080                     DATATYPE_INTEGER, true, null, 
081                     VALUE_1, VALUE_MAX_32, true, true);
082
083        addAttribute("IHDR", "height", 
084                     DATATYPE_INTEGER, true, null, 
085                     VALUE_1, VALUE_MAX_32, true, true);
086
087        addAttribute("IHDR", "bitDepth", 
088                     DATATYPE_INTEGER, true, null,
089                     Arrays.asList(CLibPNGMetadata.IHDR_bitDepths));
090
091        String[] colorTypes = {
092            "Grayscale", "RGB", "Palette", "GrayAlpha", "RGBAlpha"
093        };
094        addAttribute("IHDR", "colorType", 
095                     DATATYPE_STRING, true, null,
096                     Arrays.asList(colorTypes));
097
098        addAttribute("IHDR", "compressionMethod",
099                     DATATYPE_STRING, true, null,
100                     Arrays.asList(CLibPNGMetadata.IHDR_compressionMethodNames));
101
102        addAttribute("IHDR", "filterMethod",
103                     DATATYPE_STRING, true, null,
104                     Arrays.asList(CLibPNGMetadata.IHDR_filterMethodNames));
105
106        addAttribute("IHDR", "interlaceMethod",
107                     DATATYPE_STRING, true, null,
108                     Arrays.asList(CLibPNGMetadata.IHDR_interlaceMethodNames));
109
110        // root -> PLTE
111        addElement("PLTE", CLibPNGMetadata.nativeMetadataFormatName,
112                   1, 256);
113        
114        // root -> PLTE -> PLTEEntry
115        addElement("PLTEEntry", "PLTE",
116                   CHILD_POLICY_EMPTY);
117
118        addAttribute("PLTEEntry", "index",
119                     DATATYPE_INTEGER, true, null,
120                     VALUE_0, VALUE_255, true, true);
121        
122        addAttribute("PLTEEntry", "red",
123                     DATATYPE_INTEGER, true, null,
124                     VALUE_0, VALUE_255, true, true);
125        
126        addAttribute("PLTEEntry", "green",
127                     DATATYPE_INTEGER, true, null,
128                     VALUE_0, VALUE_255, true, true);
129        
130        addAttribute("PLTEEntry", "blue",
131                     DATATYPE_INTEGER, true, null,
132                     VALUE_0, VALUE_255, true, true);
133
134        // root -> bKGD
135        addElement("bKGD", CLibPNGMetadata.nativeMetadataFormatName,
136                   CHILD_POLICY_CHOICE);
137
138        // root -> bKGD -> bKGD_Grayscale
139        addElement("bKGD_Grayscale", "bKGD",
140                   CHILD_POLICY_EMPTY);
141
142        addAttribute("bKGD_Grayscale", "gray",
143                     DATATYPE_INTEGER, true, null,
144                     VALUE_0, VALUE_MAX_16, true, true);
145
146        // root -> bKGD -> bKGD_RGB
147        addElement("bKGD_RGB", "bKGD",
148                   CHILD_POLICY_EMPTY);
149
150        addAttribute("bKGD_RGB", "red",
151                     DATATYPE_INTEGER, true, null,
152                     VALUE_0, VALUE_MAX_16, true, true);
153
154        addAttribute("bKGD_RGB", "green",
155                     DATATYPE_INTEGER, true, null,
156                     VALUE_0, VALUE_MAX_16, true, true);
157
158        addAttribute("bKGD_RGB", "blue",
159                     DATATYPE_INTEGER, true, null,
160                     VALUE_0, VALUE_MAX_16, true, true);
161
162        // root -> bKGD -> bKGD_Palette
163        addElement("bKGD_Palette", "bKGD",
164                   CHILD_POLICY_EMPTY);
165
166        addAttribute("bKGD_Palette", "index",
167                     DATATYPE_INTEGER, true, null,
168                     VALUE_0, VALUE_255, true, true);
169
170        // root -> cHRM
171        addElement("cHRM", CLibPNGMetadata.nativeMetadataFormatName,
172                   CHILD_POLICY_EMPTY);
173
174        addAttribute("cHRM", "whitePointX",
175                     DATATYPE_INTEGER, true, null,
176                     VALUE_0, VALUE_MAX_16, true, true);
177
178        addAttribute("cHRM", "whitePointY",
179                     DATATYPE_INTEGER, true, null,
180                     VALUE_0, VALUE_MAX_16, true, true);
181
182        addAttribute("cHRM", "redX",
183                     DATATYPE_INTEGER, true, null,
184                     VALUE_0, VALUE_MAX_16, true, true);
185
186        addAttribute("cHRM", "redY",
187                     DATATYPE_INTEGER, true, null,
188                     VALUE_0, VALUE_MAX_16, true, true);
189
190        addAttribute("cHRM", "greenX",
191                     DATATYPE_INTEGER, true, null,
192                     VALUE_0, VALUE_MAX_16, true, true);
193
194        addAttribute("cHRM", "greenY",
195                     DATATYPE_INTEGER, true, null,
196                     VALUE_0, VALUE_MAX_16, true, true);
197
198        addAttribute("cHRM", "blueX",
199                     DATATYPE_INTEGER, true, null,
200                     VALUE_0, VALUE_MAX_16, true, true);
201
202        addAttribute("cHRM", "blueY",
203                     DATATYPE_INTEGER, true, null,
204                     VALUE_0, VALUE_MAX_16, true, true);
205
206        // root -> gAMA
207        addElement("gAMA", CLibPNGMetadata.nativeMetadataFormatName,
208                   CHILD_POLICY_EMPTY);
209
210        addAttribute("gAMA", "value",
211                     DATATYPE_INTEGER, true, null,
212                     VALUE_0, VALUE_MAX_32, true, true);
213
214        // root -> hIST
215        addElement("hIST", CLibPNGMetadata.nativeMetadataFormatName,
216                   1, 256);
217
218        // root -> hISTEntry
219        addElement("hISTEntry", "hIST",
220                   CHILD_POLICY_EMPTY);
221
222        addAttribute("hISTEntry", "index",
223                     DATATYPE_INTEGER, true, null,
224                     VALUE_0, VALUE_255, true, true);
225
226        addAttribute("hISTEntry", "value",
227                     DATATYPE_INTEGER, true, null,
228                     VALUE_0, VALUE_MAX_16, true, true);
229
230        // root -> iCCP
231        addElement("iCCP", CLibPNGMetadata.nativeMetadataFormatName,
232                   CHILD_POLICY_EMPTY);
233
234        addAttribute("iCCP", "profileName",
235                     DATATYPE_STRING, true, null);
236
237        addAttribute("iCCP", "compressionMethod",
238                     DATATYPE_STRING, true, null,
239                     Arrays.asList(CLibPNGMetadata.iCCP_compressionMethodNames));
240
241        addObjectValue("iCCP", byte.class, 0, Integer.MAX_VALUE);
242
243        // root -> iTXt
244        addElement("iTXt", CLibPNGMetadata.nativeMetadataFormatName,
245                   1, Integer.MAX_VALUE);
246
247        // root -> iTXt -> iTXtEntry
248        addElement("iTXtEntry", "iTXt",
249                   CHILD_POLICY_EMPTY);
250
251        addAttribute("iTXtEntry", "keyword",
252                     DATATYPE_STRING, true, null);
253
254        addBooleanAttribute("iTXtEntry", "compressionFlag",
255                            false, false);
256
257        addAttribute("iTXtEntry", "compressionMethod",
258                     DATATYPE_STRING, true, null);
259
260        addAttribute("iTXtEntry", "languageTag",
261                     DATATYPE_STRING, true, null);
262
263        addAttribute("iTXtEntry", "translatedKeyword",
264                     DATATYPE_STRING, true, null);
265
266        addAttribute("iTXtEntry", "text",
267                     DATATYPE_STRING, true, null);
268
269        // root -> pHYS
270        addElement("pHYS", CLibPNGMetadata.nativeMetadataFormatName,
271                   CHILD_POLICY_EMPTY);
272
273        addAttribute("pHYS", "pixelsPerUnitXAxis",
274                     DATATYPE_INTEGER, true, null,
275                     VALUE_0, VALUE_MAX_32, true, true);
276        addAttribute("pHYS", "pixelsPerUnitYAxis",
277                     DATATYPE_INTEGER, true, null,
278                     VALUE_0, VALUE_MAX_32, true, true);
279        addAttribute("pHYS", "unitSpecifier",
280                     DATATYPE_STRING, true, null,
281                     Arrays.asList(CLibPNGMetadata.unitSpecifierNames));
282
283        // root -> sBIT
284        addElement("sBIT", CLibPNGMetadata.nativeMetadataFormatName,
285                   CHILD_POLICY_CHOICE);
286
287        // root -> sBIT -> sBIT_Grayscale
288        addElement("sBIT_Grayscale", "sBIT",
289                   CHILD_POLICY_EMPTY);
290
291        addAttribute("sBIT_Grayscale", "gray",
292                     DATATYPE_INTEGER, true, null,
293                     VALUE_0, VALUE_255, true, true);
294
295        // root -> sBIT -> sBIT_GrayAlpha
296        addElement("sBIT_GrayAlpha", "sBIT",
297                   CHILD_POLICY_EMPTY);
298
299        addAttribute("sBIT_GrayAlpha", "gray",
300                     DATATYPE_INTEGER, true, null,
301                     VALUE_0, VALUE_255, true, true);
302
303        addAttribute("sBIT_GrayAlpha", "alpha",
304                     DATATYPE_INTEGER, true, null,
305                     VALUE_0, VALUE_255, true, true);
306
307        // root -> sBIT -> sBIT_RGB
308        addElement("sBIT_RGB", "sBIT",
309                   CHILD_POLICY_EMPTY);
310
311        addAttribute("sBIT_RGB", "red",
312                     DATATYPE_INTEGER, true, null,
313                     VALUE_0, VALUE_255, true, true);
314
315        addAttribute("sBIT_RGB", "green",
316                     DATATYPE_INTEGER, true, null,
317                     VALUE_0, VALUE_255, true, true);
318
319        addAttribute("sBIT_RGB", "blue",
320                     DATATYPE_INTEGER, true, null,
321                     VALUE_0, VALUE_255, true, true);
322
323        // root -> sBIT -> sBIT_RGBAlpha
324        addElement("sBIT_RGBAlpha", "sBIT",
325                   CHILD_POLICY_EMPTY);
326
327        addAttribute("sBIT_RGBAlpha", "red",
328                     DATATYPE_INTEGER, true, null,
329                     VALUE_0, VALUE_255, true, true);
330
331        addAttribute("sBIT_RGBAlpha", "green",
332                     DATATYPE_INTEGER, true, null,
333                     VALUE_0, VALUE_255, true, true);
334
335        addAttribute("sBIT_RGBAlpha", "blue",
336                     DATATYPE_INTEGER, true, null,
337                     VALUE_0, VALUE_255, true, true);
338
339        addAttribute("sBIT_RGBAlpha", "alpha",
340                     DATATYPE_INTEGER, true, null,
341                     VALUE_0, VALUE_255, true, true);
342
343        // root -> sBIT -> sBIT_Palette
344        addElement("sBIT_Palette", "sBIT",
345                   CHILD_POLICY_EMPTY);
346
347        addAttribute("sBIT_Palette", "red",
348                     DATATYPE_INTEGER, true, null,
349                     VALUE_0, VALUE_255, true, true);
350
351        addAttribute("sBIT_Palette", "green",
352                     DATATYPE_INTEGER, true, null,
353                     VALUE_0, VALUE_255, true, true);
354
355        addAttribute("sBIT_Palette", "blue",
356                     DATATYPE_INTEGER, true, null,
357                     VALUE_0, VALUE_255, true, true);
358
359        // root -> sPLT
360        addElement("sPLT", CLibPNGMetadata.nativeMetadataFormatName,
361                   1, 256);
362
363        // root -> sPLT -> sPLTEntry
364        addElement("sPLTEntry", "sPLT",
365                   CHILD_POLICY_EMPTY);
366
367        addAttribute("sPLTEntry", "index",
368                     DATATYPE_INTEGER, true, null,
369                     VALUE_0, VALUE_255, true, true);
370
371        addAttribute("sPLTEntry", "red",
372                     DATATYPE_INTEGER, true, null,
373                     VALUE_0, VALUE_255, true, true);
374
375        addAttribute("sPLTEntry", "green",
376                     DATATYPE_INTEGER, true, null,
377                     VALUE_0, VALUE_255, true, true);
378
379        addAttribute("sPLTEntry", "blue",
380                     DATATYPE_INTEGER, true, null,
381                     VALUE_0, VALUE_255, true, true);
382
383        addAttribute("sPLTEntry", "alpha",
384                     DATATYPE_INTEGER, true, null,
385                     VALUE_0, VALUE_255, true, true);
386
387        // root -> sRGB
388        addElement("sRGB", CLibPNGMetadata.nativeMetadataFormatName,
389                   CHILD_POLICY_EMPTY);
390
391        addAttribute("sRGB", "renderingIntent",
392                     DATATYPE_STRING, true, null,
393                     Arrays.asList(CLibPNGMetadata.renderingIntentNames));
394
395        // root -> tEXt
396        addElement("tEXt", CLibPNGMetadata.nativeMetadataFormatName,
397                   1, Integer.MAX_VALUE);
398
399        // root -> tEXt -> tEXtEntry
400        addElement("tEXtEntry", "tEXt",
401                   CHILD_POLICY_EMPTY);
402
403        addAttribute("tEXtEntry", "keyword",
404                     DATATYPE_STRING, true, null);
405
406        addAttribute("tEXtEntry", "value",
407                     DATATYPE_STRING, true, null);
408
409        // root -> tIME
410        addElement("tIME", CLibPNGMetadata.nativeMetadataFormatName,
411                   CHILD_POLICY_EMPTY);
412        
413        addAttribute("tIME", "year",
414                     DATATYPE_INTEGER, true, null,
415                     VALUE_0, VALUE_MAX_16, true, true);
416
417        addAttribute("tIME", "month",
418                     DATATYPE_INTEGER, true, null,
419                     VALUE_1, VALUE_12, true, true);
420
421        addAttribute("tIME", "day",
422                     DATATYPE_INTEGER, true, null,
423                     VALUE_1, VALUE_31, true, true);
424
425        addAttribute("tIME", "hour",
426                     DATATYPE_INTEGER, true, null,
427                     VALUE_0, VALUE_23, true, true);
428
429        addAttribute("tIME", "minute",
430                     DATATYPE_INTEGER, true, null,
431                     VALUE_0, VALUE_59, true, true);
432
433        addAttribute("tIME", "second",
434                     DATATYPE_INTEGER, true, null,
435                     VALUE_0, VALUE_60, true, true);
436
437        // root -> tRNS
438        addElement("tRNS", CLibPNGMetadata.nativeMetadataFormatName,
439                   CHILD_POLICY_CHOICE);
440        
441        // root -> tRNS -> tRNS_Grayscale
442        addElement("tRNS_Grayscale", "tRNS",
443                   CHILD_POLICY_EMPTY);
444
445        addAttribute("tRNS_Grayscale", "gray",
446                     DATATYPE_INTEGER, true, null,
447                     VALUE_0, VALUE_MAX_16, true, true);
448
449        // root -> tRNS -> tRNS_RGB
450        addElement("tRNS_RGB", "tRNS",
451                   CHILD_POLICY_EMPTY);
452
453        addAttribute("tRNS_RGB", "red",
454                     DATATYPE_INTEGER, true, null,
455                     VALUE_0, VALUE_MAX_16, true, true);
456
457        addAttribute("tRNS_RGB", "green",
458                     DATATYPE_INTEGER, true, null,
459                     VALUE_0, VALUE_MAX_16, true, true);
460
461        addAttribute("tRNS_RGB", "blue",
462                     DATATYPE_INTEGER, true, null,
463                     VALUE_0, VALUE_MAX_16, true, true);
464
465        // root -> tRNS -> tRNS_Palette
466        addElement("tRNS_Palette", "tRNS",
467                   CHILD_POLICY_EMPTY);
468
469        addAttribute("tRNS_Palette", "index",
470                     DATATYPE_INTEGER, true, null,
471                     VALUE_0, VALUE_255, true, true);
472
473        addAttribute("tRNS_Palette", "alpha",
474                     DATATYPE_INTEGER, true, null,
475                     VALUE_0, VALUE_255, true, true);
476
477        // root -> zTXt
478        addElement("zTXt", CLibPNGMetadata.nativeMetadataFormatName,
479                   1, Integer.MAX_VALUE);
480
481        // root -> zTXt -> zTXtEntry
482        addElement("zTXtEntry", "zTXt",
483                   CHILD_POLICY_EMPTY);
484
485        addAttribute("zTXtEntry", "keyword",
486                     DATATYPE_STRING, true, null);
487
488        addAttribute("zTXtEntry", "compressionMethod",
489                     DATATYPE_STRING, true, null,
490                     Arrays.asList(CLibPNGMetadata.zTXt_compressionMethodNames));
491
492        addAttribute("zTXtEntry", "text", 
493                     DATATYPE_STRING, true, null);
494
495        // root -> UnknownChunks
496        addElement("UnknownChunks", CLibPNGMetadata.nativeMetadataFormatName,
497                   1, Integer.MAX_VALUE);
498
499        // root -> UnknownChunks -> UnknownChunk
500        addElement("UnknownChunk", "UnknownChunks",
501                   CHILD_POLICY_EMPTY);
502
503        addAttribute("UnknownChunk", "type",
504                     DATATYPE_STRING, true, null);
505
506        addObjectValue("UnknownChunk", byte.class, 0, Integer.MAX_VALUE);
507    }
508
509    public boolean canNodeAppear(String elementName,
510                                 ImageTypeSpecifier imageType) {
511        return true;
512    }
513    
514    public static synchronized IIOMetadataFormat getInstance() {
515        if (instance == null) {
516            instance = new CLibPNGMetadataFormat();
517        }
518        return instance;
519    }
520}