1 /*
2 * Copyright (c) 2000, 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
327 icm.getAlphas(alpha);
328 }
329
330 /*
331 * NB: PNG_COLOR_GRAY_ALPHA color type may be not optimal for images
332 * contained more than 1024 pixels (or even than 768 pixels in case of
333 * single transparent pixel in palette).
334 * For such images alpha samples in raster will occupy more space than
335 * it is required to store palette so it could be reasonable to
336 * use PNG_COLOR_PALETTE color type for large images.
337 */
338
339 if (isGray && hasAlpha && (bitDepth == 8 || bitDepth == 16)) {
340 IHDR_colorType = PNGImageReader.PNG_COLOR_GRAY_ALPHA;
341 } else if (isGray && !hasAlpha) {
342 IHDR_colorType = PNGImageReader.PNG_COLOR_GRAY;
343 } else {
344 IHDR_colorType = PNGImageReader.PNG_COLOR_PALETTE;
345 PLTE_present = true;
346 PLTE_order = null;
347 PLTE_red = (byte[])reds.clone();
348 PLTE_green = (byte[])greens.clone();
349 PLTE_blue = (byte[])blues.clone();
350
351 if (hasAlpha) {
352 tRNS_present = true;
353 tRNS_colorType = PNGImageReader.PNG_COLOR_PALETTE;
354
355 PLTE_order = new int[alpha.length];
356
357 // Reorder the palette so that non-opaque entries
358 // come first. Since the tRNS chunk does not have
359 // to store trailing 255's, this can save a
360 // considerable amount of space when encoding
361 // images with only one transparent pixel value,
362 // e.g., images from GIF sources.
363
364 byte[] newAlpha = new byte[alpha.length];
365
366 // Scan for non-opaque entries and assign them
367 // positions starting at 0.
368 int newIndex = 0;
369 for (int i = 0; i < alpha.length; i++) {
413 } else if (numBands == 4) {
414 IHDR_colorType = PNGImageReader.PNG_COLOR_RGB_ALPHA;
415 } else {
416 throw new RuntimeException("Number of bands not 1-4!");
417 }
418 }
419
420 IHDR_present = true;
421 }
422
423 public boolean isReadOnly() {
424 return false;
425 }
426
427 private ArrayList<byte[]> cloneBytesArrayList(ArrayList<byte[]> in) {
428 if (in == null) {
429 return null;
430 } else {
431 ArrayList<byte[]> list = new ArrayList<byte[]>(in.size());
432 for (byte[] b: in) {
433 list.add((b == null) ? null : (byte[])b.clone());
434 }
435 return list;
436 }
437 }
438
439 // Deep clone
440 public Object clone() {
441 PNGMetadata metadata;
442 try {
443 metadata = (PNGMetadata)super.clone();
444 } catch (CloneNotSupportedException e) {
445 return null;
446 }
447
448 // unknownChunkData needs deep clone
449 metadata.unknownChunkData =
450 cloneBytesArrayList(this.unknownChunkData);
451
452 return metadata;
453 }
686 sPLT_node.appendChild(entry);
687 }
688
689 root.appendChild(sPLT_node);
690 }
691
692 // sRGB
693 if (sRGB_present) {
694 IIOMetadataNode sRGB_node = new IIOMetadataNode("sRGB");
695 sRGB_node.setAttribute("renderingIntent",
696 renderingIntentNames[sRGB_renderingIntent]);
697
698 root.appendChild(sRGB_node);
699 }
700
701 // tEXt
702 if (tEXt_keyword.size() > 0) {
703 IIOMetadataNode tEXt_parent = new IIOMetadataNode("tEXt");
704 for (int i = 0; i < tEXt_keyword.size(); i++) {
705 IIOMetadataNode tEXt_node = new IIOMetadataNode("tEXtEntry");
706 tEXt_node.setAttribute("keyword" , (String)tEXt_keyword.get(i));
707 tEXt_node.setAttribute("value" , (String)tEXt_text.get(i));
708
709 tEXt_parent.appendChild(tEXt_node);
710 }
711
712 root.appendChild(tEXt_parent);
713 }
714
715 // tIME
716 if (tIME_present) {
717 IIOMetadataNode tIME_node = new IIOMetadataNode("tIME");
718 tIME_node.setAttribute("year", Integer.toString(tIME_year));
719 tIME_node.setAttribute("month", Integer.toString(tIME_month));
720 tIME_node.setAttribute("day", Integer.toString(tIME_day));
721 tIME_node.setAttribute("hour", Integer.toString(tIME_hour));
722 tIME_node.setAttribute("minute", Integer.toString(tIME_minute));
723 tIME_node.setAttribute("second", Integer.toString(tIME_second));
724
725 root.appendChild(tIME_node);
726 }
727
742 }
743 } else if (tRNS_colorType == PNGImageReader.PNG_COLOR_GRAY) {
744 node = new IIOMetadataNode("tRNS_Grayscale");
745 node.setAttribute("gray", Integer.toString(tRNS_gray));
746 } else if (tRNS_colorType == PNGImageReader.PNG_COLOR_RGB) {
747 node = new IIOMetadataNode("tRNS_RGB");
748 node.setAttribute("red", Integer.toString(tRNS_red));
749 node.setAttribute("green", Integer.toString(tRNS_green));
750 node.setAttribute("blue", Integer.toString(tRNS_blue));
751 }
752 tRNS_node.appendChild(node);
753
754 root.appendChild(tRNS_node);
755 }
756
757 // zTXt
758 if (zTXt_keyword.size() > 0) {
759 IIOMetadataNode zTXt_parent = new IIOMetadataNode("zTXt");
760 for (int i = 0; i < zTXt_keyword.size(); i++) {
761 IIOMetadataNode zTXt_node = new IIOMetadataNode("zTXtEntry");
762 zTXt_node.setAttribute("keyword", (String)zTXt_keyword.get(i));
763
764 int cm = ((Integer)zTXt_compressionMethod.get(i)).intValue();
765 zTXt_node.setAttribute("compressionMethod",
766 zTXt_compressionMethodNames[cm]);
767
768 zTXt_node.setAttribute("text", (String)zTXt_text.get(i));
769
770 zTXt_parent.appendChild(zTXt_node);
771 }
772
773 root.appendChild(zTXt_parent);
774 }
775
776 // Unknown chunks
777 if (unknownChunkType.size() > 0) {
778 IIOMetadataNode unknown_parent =
779 new IIOMetadataNode("UnknownChunks");
780 for (int i = 0; i < unknownChunkType.size(); i++) {
781 IIOMetadataNode unknown_node =
782 new IIOMetadataNode("UnknownChunk");
783 unknown_node.setAttribute("type",
784 (String)unknownChunkType.get(i));
785 unknown_node.setUserObject((byte[])unknownChunkData.get(i));
786
787 unknown_parent.appendChild(unknown_node);
788 }
789
790 root.appendChild(unknown_parent);
791 }
792
793 return root;
794 }
795
796 private int getNumChannels() {
797 // Determine number of channels
798 // Be careful about palette color with transparency
799 int numChannels = IHDR_numChannels[IHDR_colorType];
800 if (IHDR_colorType == PNGImageReader.PNG_COLOR_PALETTE &&
801 tRNS_present && tRNS_colorType == IHDR_colorType) {
802 numChannels = 4;
803 }
804 return numChannels;
805 }
999 node.setAttribute("hour", Integer.toString(tIME_hour));
1000 node.setAttribute("minute", Integer.toString(tIME_minute));
1001 node.setAttribute("second", Integer.toString(tIME_second));
1002 document_node.appendChild(node);
1003
1004 return document_node;
1005 }
1006
1007 public IIOMetadataNode getStandardTextNode() {
1008 int numEntries = tEXt_keyword.size() +
1009 iTXt_keyword.size() + zTXt_keyword.size();
1010 if (numEntries == 0) {
1011 return null;
1012 }
1013
1014 IIOMetadataNode text_node = new IIOMetadataNode("Text");
1015 IIOMetadataNode node = null; // scratch node
1016
1017 for (int i = 0; i < tEXt_keyword.size(); i++) {
1018 node = new IIOMetadataNode("TextEntry");
1019 node.setAttribute("keyword", (String)tEXt_keyword.get(i));
1020 node.setAttribute("value", (String)tEXt_text.get(i));
1021 node.setAttribute("encoding", "ISO-8859-1");
1022 node.setAttribute("compression", "none");
1023
1024 text_node.appendChild(node);
1025 }
1026
1027 for (int i = 0; i < iTXt_keyword.size(); i++) {
1028 node = new IIOMetadataNode("TextEntry");
1029 node.setAttribute("keyword", iTXt_keyword.get(i));
1030 node.setAttribute("value", iTXt_text.get(i));
1031 node.setAttribute("language",
1032 iTXt_languageTag.get(i));
1033 if (iTXt_compressionFlag.get(i)) {
1034 node.setAttribute("compression", "zip");
1035 } else {
1036 node.setAttribute("compression", "none");
1037 }
1038
1039 text_node.appendChild(node);
1040 }
1041
1042 for (int i = 0; i < zTXt_keyword.size(); i++) {
1043 node = new IIOMetadataNode("TextEntry");
1044 node.setAttribute("keyword", (String)zTXt_keyword.get(i));
1045 node.setAttribute("value", (String)zTXt_text.get(i));
1046 node.setAttribute("compression", "zip");
1047
1048 text_node.appendChild(node);
1049 }
1050
1051 return text_node;
1052 }
1053
1054 public IIOMetadataNode getStandardTransparencyNode() {
1055 IIOMetadataNode transparency_node =
1056 new IIOMetadataNode("Transparency");
1057 IIOMetadataNode node = null; // scratch node
1058
1059 node = new IIOMetadataNode("Alpha");
1060 boolean hasAlpha =
1061 (IHDR_colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA) ||
1062 (IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) ||
1063 (IHDR_colorType == PNGImageReader.PNG_COLOR_PALETTE &&
1064 tRNS_present &&
1065 (tRNS_colorType == IHDR_colorType) &&
1383
1384 int numEntries = maxindex + 1;
1385 hIST_histogram = new char[numEntries];
1386 System.arraycopy(hist, 0, hIST_histogram, 0, numEntries);
1387
1388 hIST_present = true;
1389 } else if (name.equals("iCCP")) {
1390 iCCP_profileName = getAttribute(node, "profileName");
1391 iCCP_compressionMethod =
1392 getEnumeratedAttribute(node, "compressionMethod",
1393 iCCP_compressionMethodNames);
1394 Object compressedProfile =
1395 ((IIOMetadataNode)node).getUserObject();
1396 if (compressedProfile == null) {
1397 fatal(node, "No ICCP profile present in user object!");
1398 }
1399 if (!(compressedProfile instanceof byte[])) {
1400 fatal(node, "User object not a byte array!");
1401 }
1402
1403 iCCP_compressedProfile =
1404 (byte[])((byte[])compressedProfile).clone();
1405
1406 iCCP_present = true;
1407 } else if (name.equals("iTXt")) {
1408 Node iTXt_node = node.getFirstChild();
1409 while (iTXt_node != null) {
1410 if (!iTXt_node.getNodeName().equals("iTXtEntry")) {
1411 fatal(node,
1412 "Only an iTXtEntry may be a child of an iTXt!");
1413 }
1414
1415 String keyword = getAttribute(iTXt_node, "keyword");
1416 if (isValidKeyword(keyword)) {
1417 iTXt_keyword.add(keyword);
1418
1419 boolean compressionFlag =
1420 getBooleanAttribute(iTXt_node, "compressionFlag");
1421 iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag));
1422
1423 String compressionMethod =
1424 getAttribute(iTXt_node, "compressionMethod");
|
1 /*
2 * Copyright (c) 2000, 2014, 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
327 icm.getAlphas(alpha);
328 }
329
330 /*
331 * NB: PNG_COLOR_GRAY_ALPHA color type may be not optimal for images
332 * contained more than 1024 pixels (or even than 768 pixels in case of
333 * single transparent pixel in palette).
334 * For such images alpha samples in raster will occupy more space than
335 * it is required to store palette so it could be reasonable to
336 * use PNG_COLOR_PALETTE color type for large images.
337 */
338
339 if (isGray && hasAlpha && (bitDepth == 8 || bitDepth == 16)) {
340 IHDR_colorType = PNGImageReader.PNG_COLOR_GRAY_ALPHA;
341 } else if (isGray && !hasAlpha) {
342 IHDR_colorType = PNGImageReader.PNG_COLOR_GRAY;
343 } else {
344 IHDR_colorType = PNGImageReader.PNG_COLOR_PALETTE;
345 PLTE_present = true;
346 PLTE_order = null;
347 PLTE_red = reds.clone();
348 PLTE_green = greens.clone();
349 PLTE_blue = blues.clone();
350
351 if (hasAlpha) {
352 tRNS_present = true;
353 tRNS_colorType = PNGImageReader.PNG_COLOR_PALETTE;
354
355 PLTE_order = new int[alpha.length];
356
357 // Reorder the palette so that non-opaque entries
358 // come first. Since the tRNS chunk does not have
359 // to store trailing 255's, this can save a
360 // considerable amount of space when encoding
361 // images with only one transparent pixel value,
362 // e.g., images from GIF sources.
363
364 byte[] newAlpha = new byte[alpha.length];
365
366 // Scan for non-opaque entries and assign them
367 // positions starting at 0.
368 int newIndex = 0;
369 for (int i = 0; i < alpha.length; i++) {
413 } else if (numBands == 4) {
414 IHDR_colorType = PNGImageReader.PNG_COLOR_RGB_ALPHA;
415 } else {
416 throw new RuntimeException("Number of bands not 1-4!");
417 }
418 }
419
420 IHDR_present = true;
421 }
422
423 public boolean isReadOnly() {
424 return false;
425 }
426
427 private ArrayList<byte[]> cloneBytesArrayList(ArrayList<byte[]> in) {
428 if (in == null) {
429 return null;
430 } else {
431 ArrayList<byte[]> list = new ArrayList<byte[]>(in.size());
432 for (byte[] b: in) {
433 list.add((b == null) ? null : b.clone());
434 }
435 return list;
436 }
437 }
438
439 // Deep clone
440 public Object clone() {
441 PNGMetadata metadata;
442 try {
443 metadata = (PNGMetadata)super.clone();
444 } catch (CloneNotSupportedException e) {
445 return null;
446 }
447
448 // unknownChunkData needs deep clone
449 metadata.unknownChunkData =
450 cloneBytesArrayList(this.unknownChunkData);
451
452 return metadata;
453 }
686 sPLT_node.appendChild(entry);
687 }
688
689 root.appendChild(sPLT_node);
690 }
691
692 // sRGB
693 if (sRGB_present) {
694 IIOMetadataNode sRGB_node = new IIOMetadataNode("sRGB");
695 sRGB_node.setAttribute("renderingIntent",
696 renderingIntentNames[sRGB_renderingIntent]);
697
698 root.appendChild(sRGB_node);
699 }
700
701 // tEXt
702 if (tEXt_keyword.size() > 0) {
703 IIOMetadataNode tEXt_parent = new IIOMetadataNode("tEXt");
704 for (int i = 0; i < tEXt_keyword.size(); i++) {
705 IIOMetadataNode tEXt_node = new IIOMetadataNode("tEXtEntry");
706 tEXt_node.setAttribute("keyword" , tEXt_keyword.get(i));
707 tEXt_node.setAttribute("value" , tEXt_text.get(i));
708
709 tEXt_parent.appendChild(tEXt_node);
710 }
711
712 root.appendChild(tEXt_parent);
713 }
714
715 // tIME
716 if (tIME_present) {
717 IIOMetadataNode tIME_node = new IIOMetadataNode("tIME");
718 tIME_node.setAttribute("year", Integer.toString(tIME_year));
719 tIME_node.setAttribute("month", Integer.toString(tIME_month));
720 tIME_node.setAttribute("day", Integer.toString(tIME_day));
721 tIME_node.setAttribute("hour", Integer.toString(tIME_hour));
722 tIME_node.setAttribute("minute", Integer.toString(tIME_minute));
723 tIME_node.setAttribute("second", Integer.toString(tIME_second));
724
725 root.appendChild(tIME_node);
726 }
727
742 }
743 } else if (tRNS_colorType == PNGImageReader.PNG_COLOR_GRAY) {
744 node = new IIOMetadataNode("tRNS_Grayscale");
745 node.setAttribute("gray", Integer.toString(tRNS_gray));
746 } else if (tRNS_colorType == PNGImageReader.PNG_COLOR_RGB) {
747 node = new IIOMetadataNode("tRNS_RGB");
748 node.setAttribute("red", Integer.toString(tRNS_red));
749 node.setAttribute("green", Integer.toString(tRNS_green));
750 node.setAttribute("blue", Integer.toString(tRNS_blue));
751 }
752 tRNS_node.appendChild(node);
753
754 root.appendChild(tRNS_node);
755 }
756
757 // zTXt
758 if (zTXt_keyword.size() > 0) {
759 IIOMetadataNode zTXt_parent = new IIOMetadataNode("zTXt");
760 for (int i = 0; i < zTXt_keyword.size(); i++) {
761 IIOMetadataNode zTXt_node = new IIOMetadataNode("zTXtEntry");
762 zTXt_node.setAttribute("keyword", zTXt_keyword.get(i));
763
764 int cm = (zTXt_compressionMethod.get(i)).intValue();
765 zTXt_node.setAttribute("compressionMethod",
766 zTXt_compressionMethodNames[cm]);
767
768 zTXt_node.setAttribute("text", zTXt_text.get(i));
769
770 zTXt_parent.appendChild(zTXt_node);
771 }
772
773 root.appendChild(zTXt_parent);
774 }
775
776 // Unknown chunks
777 if (unknownChunkType.size() > 0) {
778 IIOMetadataNode unknown_parent =
779 new IIOMetadataNode("UnknownChunks");
780 for (int i = 0; i < unknownChunkType.size(); i++) {
781 IIOMetadataNode unknown_node =
782 new IIOMetadataNode("UnknownChunk");
783 unknown_node.setAttribute("type",
784 unknownChunkType.get(i));
785 unknown_node.setUserObject(unknownChunkData.get(i));
786
787 unknown_parent.appendChild(unknown_node);
788 }
789
790 root.appendChild(unknown_parent);
791 }
792
793 return root;
794 }
795
796 private int getNumChannels() {
797 // Determine number of channels
798 // Be careful about palette color with transparency
799 int numChannels = IHDR_numChannels[IHDR_colorType];
800 if (IHDR_colorType == PNGImageReader.PNG_COLOR_PALETTE &&
801 tRNS_present && tRNS_colorType == IHDR_colorType) {
802 numChannels = 4;
803 }
804 return numChannels;
805 }
999 node.setAttribute("hour", Integer.toString(tIME_hour));
1000 node.setAttribute("minute", Integer.toString(tIME_minute));
1001 node.setAttribute("second", Integer.toString(tIME_second));
1002 document_node.appendChild(node);
1003
1004 return document_node;
1005 }
1006
1007 public IIOMetadataNode getStandardTextNode() {
1008 int numEntries = tEXt_keyword.size() +
1009 iTXt_keyword.size() + zTXt_keyword.size();
1010 if (numEntries == 0) {
1011 return null;
1012 }
1013
1014 IIOMetadataNode text_node = new IIOMetadataNode("Text");
1015 IIOMetadataNode node = null; // scratch node
1016
1017 for (int i = 0; i < tEXt_keyword.size(); i++) {
1018 node = new IIOMetadataNode("TextEntry");
1019 node.setAttribute("keyword", tEXt_keyword.get(i));
1020 node.setAttribute("value", tEXt_text.get(i));
1021 node.setAttribute("encoding", "ISO-8859-1");
1022 node.setAttribute("compression", "none");
1023
1024 text_node.appendChild(node);
1025 }
1026
1027 for (int i = 0; i < iTXt_keyword.size(); i++) {
1028 node = new IIOMetadataNode("TextEntry");
1029 node.setAttribute("keyword", iTXt_keyword.get(i));
1030 node.setAttribute("value", iTXt_text.get(i));
1031 node.setAttribute("language",
1032 iTXt_languageTag.get(i));
1033 if (iTXt_compressionFlag.get(i)) {
1034 node.setAttribute("compression", "zip");
1035 } else {
1036 node.setAttribute("compression", "none");
1037 }
1038
1039 text_node.appendChild(node);
1040 }
1041
1042 for (int i = 0; i < zTXt_keyword.size(); i++) {
1043 node = new IIOMetadataNode("TextEntry");
1044 node.setAttribute("keyword", zTXt_keyword.get(i));
1045 node.setAttribute("value", zTXt_text.get(i));
1046 node.setAttribute("compression", "zip");
1047
1048 text_node.appendChild(node);
1049 }
1050
1051 return text_node;
1052 }
1053
1054 public IIOMetadataNode getStandardTransparencyNode() {
1055 IIOMetadataNode transparency_node =
1056 new IIOMetadataNode("Transparency");
1057 IIOMetadataNode node = null; // scratch node
1058
1059 node = new IIOMetadataNode("Alpha");
1060 boolean hasAlpha =
1061 (IHDR_colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA) ||
1062 (IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) ||
1063 (IHDR_colorType == PNGImageReader.PNG_COLOR_PALETTE &&
1064 tRNS_present &&
1065 (tRNS_colorType == IHDR_colorType) &&
1383
1384 int numEntries = maxindex + 1;
1385 hIST_histogram = new char[numEntries];
1386 System.arraycopy(hist, 0, hIST_histogram, 0, numEntries);
1387
1388 hIST_present = true;
1389 } else if (name.equals("iCCP")) {
1390 iCCP_profileName = getAttribute(node, "profileName");
1391 iCCP_compressionMethod =
1392 getEnumeratedAttribute(node, "compressionMethod",
1393 iCCP_compressionMethodNames);
1394 Object compressedProfile =
1395 ((IIOMetadataNode)node).getUserObject();
1396 if (compressedProfile == null) {
1397 fatal(node, "No ICCP profile present in user object!");
1398 }
1399 if (!(compressedProfile instanceof byte[])) {
1400 fatal(node, "User object not a byte array!");
1401 }
1402
1403 iCCP_compressedProfile = ((byte[])compressedProfile).clone();
1404
1405 iCCP_present = true;
1406 } else if (name.equals("iTXt")) {
1407 Node iTXt_node = node.getFirstChild();
1408 while (iTXt_node != null) {
1409 if (!iTXt_node.getNodeName().equals("iTXtEntry")) {
1410 fatal(node,
1411 "Only an iTXtEntry may be a child of an iTXt!");
1412 }
1413
1414 String keyword = getAttribute(iTXt_node, "keyword");
1415 if (isValidKeyword(keyword)) {
1416 iTXt_keyword.add(keyword);
1417
1418 boolean compressionFlag =
1419 getBooleanAttribute(iTXt_node, "compressionFlag");
1420 iTXt_compressionFlag.add(Boolean.valueOf(compressionFlag));
1421
1422 String compressionMethod =
1423 getAttribute(iTXt_node, "compressionMethod");
|