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