View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.imaging.formats.png.chunks;
18  
19  import java.io.ByteArrayInputStream;
20  import java.util.Objects;
21  
22  import org.apache.commons.imaging.common.BinaryFileParser;
23  
24  /**
25   * A PNG image is composed of several chunks. This is the base class for the chunks, used by the parser.
26   *
27   * @see <a href="https://en.wikipedia.org/wiki/Portable_Network_Graphics#%22Chunks%22_within_the_file">Portable_Network_Graphics</a>
28   */
29  public class PngChunk extends BinaryFileParser {
30  
31      private final int length;
32      private final int chunkType;
33      private final int crc;
34      private final byte[] bytes;
35  
36      private final boolean[] propertyBits;
37      private final boolean ancillary;
38      private final boolean isPrivate;
39      private final boolean reserved;
40      private final boolean safeToCopy;
41  
42      /**
43       * Constructs a new instance.
44       *
45       * @param length    chunk length
46       * @param chunkType chunk type
47       * @param crc       CRC computed over the chunk type and chunk data (but not the length)
48       * @param bytes     chunk data bytes
49       * @throws NullPointerException if bytes is null.
50       */
51      public PngChunk(final int length, final int chunkType, final int crc, final byte[] bytes) {
52          this.length = length;
53          this.chunkType = chunkType;
54          this.crc = crc;
55          this.bytes = Objects.requireNonNull(bytes, "bytes").clone();
56  
57          propertyBits = new boolean[4];
58          int shift = 24;
59          final int theMask = 1 << 5;
60          for (int i = 0; i < propertyBits.length; i++) {
61              final int theByte = 0xff & chunkType >> shift;
62              shift -= 8;
63              propertyBits[i] = (theByte & theMask) > 0;
64          }
65  
66          ancillary = propertyBits[0];
67          isPrivate = propertyBits[1];
68          reserved = propertyBits[2];
69          safeToCopy = propertyBits[3];
70      }
71  
72      /**
73       * Gets a copy of the chunk bytes.
74       *
75       * @return the chunk bytes
76       */
77      public byte[] getBytes() {
78          return bytes.clone();
79      }
80  
81      public int getChunkType() {
82          return chunkType;
83      }
84  
85      public int getCrc() {
86          return crc;
87      }
88  
89      /**
90       * Gets a new {@link ByteArrayInputStream} for the chunk bytes.
91       *
92       * <p>
93       * The caller is responsible for closing the resource.
94       * </p>
95       *
96       * @return a ByteArrayInputStream for the chunk bytes
97       */
98      protected ByteArrayInputStream getDataStream() {
99          return new ByteArrayInputStream(bytes);
100     }
101 
102     public int getLength() {
103         return length;
104     }
105 
106     /**
107      * Gets a copy of the chunk property bits.
108      *
109      * @return the chunk property bits
110      */
111     public boolean[] getPropertyBits() {
112         return propertyBits.clone();
113     }
114 
115     public boolean isAncillary() {
116         return ancillary;
117     }
118 
119     public boolean isPrivate() {
120         return isPrivate;
121     }
122 
123     public boolean isReserved() {
124         return reserved;
125     }
126 
127     public boolean isSafeToCopy() {
128         return safeToCopy;
129     }
130 
131 }