src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java

Print this page


   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");