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  
21  import org.apache.commons.imaging.common.BinaryFileParser;
22  
23  /**
24   * A PNG image is composed of several chunks. This is the base class for the chunks,
25   * 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      public final int length;
31      public final int chunkType;
32      public final int crc;
33      private final byte[] bytes;
34  
35      private final boolean[] propertyBits;
36      public final boolean ancillary;
37      public final boolean isPrivate;
38      public final boolean reserved;
39      public final boolean safeToCopy;
40  
41      /**
42       * Constructor.
43       * @param length chunk length
44       * @param chunkType chunk type
45       * @param crc CRC computed over the chunk type and chunk data (but not the length)
46       * @param bytes chunk data bytes
47       */
48      public PngChunk(final int length, final int chunkType, final int crc, final byte[] bytes) {
49          this.length = length;
50          this.chunkType = chunkType;
51          this.crc = crc;
52          this.bytes = bytes.clone();
53  
54          propertyBits = new boolean[4];
55          int shift = 24;
56          for (int i = 0; i < 4; i++) {
57              final int theByte = 0xff & (chunkType >> shift);
58              shift -= 8;
59              final int theMask = 1 << 5;
60              propertyBits[i] = ((theByte & theMask) > 0);
61          }
62  
63          ancillary = propertyBits[0];
64          isPrivate = propertyBits[1];
65          reserved = propertyBits[2];
66          safeToCopy = propertyBits[3];
67      }
68  
69      /**
70       * Return a copy of the chunk bytes.
71       * @return the chunk bytes
72       */
73      public byte[] getBytes() {
74          return bytes.clone();
75      }
76  
77      /**
78       * Return a copy of the chunk property bits.
79       * @return the chunk property bits
80       */
81      public boolean[] getPropertyBits() {
82          return propertyBits.clone();
83      }
84  
85      /**
86       * Create and return a {@link ByteArrayInputStream} for the chunk bytes.
87       *
88       * <p>The caller is responsible for closing the resource.</p>
89       *
90       * @return a ByteArrayInputStream for the chunk bytes
91       */
92      protected ByteArrayInputStream getDataStream() {
93          return new ByteArrayInputStream(getBytes());
94      }
95  
96  }