001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.imaging.formats.png;
018
019import java.io.IOException;
020import java.nio.charset.StandardCharsets;
021
022import org.apache.commons.imaging.common.BinaryFunctions;
023import org.apache.commons.imaging.formats.png.chunks.PngChunk;
024import org.apache.commons.imaging.formats.png.chunks.PngChunkGama;
025import org.apache.commons.imaging.formats.png.chunks.PngChunkIccp;
026import org.apache.commons.imaging.formats.png.chunks.PngChunkIdat;
027import org.apache.commons.imaging.formats.png.chunks.PngChunkIhdr;
028import org.apache.commons.imaging.formats.png.chunks.PngChunkItxt;
029import org.apache.commons.imaging.formats.png.chunks.PngChunkPhys;
030import org.apache.commons.imaging.formats.png.chunks.PngChunkPlte;
031import org.apache.commons.imaging.formats.png.chunks.PngChunkScal;
032import org.apache.commons.imaging.formats.png.chunks.PngChunkText;
033import org.apache.commons.imaging.formats.png.chunks.PngChunkZtxt;
034
035/**
036 * Type of PNG chunk.
037 *
038 * @see <a href="https://www.w3.org/TR/png/#11Chunks">Portable Network Graphics Specification - Chunk specifications</a>
039 */
040public enum ChunkType {
041
042    /**
043     * Image header
044     */
045    IHDR(PngChunkIhdr::new),
046
047    /**
048     * Palette
049     */
050    PLTE(PngChunkPlte::new),
051
052    /**
053     * Image data
054     */
055    IDAT(PngChunkIdat::new),
056
057    /**
058     * Image trailer
059     */
060    IEND,
061
062    /**
063     * Transparency
064     */
065    tRNS,
066
067    /**
068     * Primary chromaticities and white point
069     */
070    cHRM,
071
072    /**
073     * Image gamma
074     */
075    gAMA(PngChunkGama::new),
076
077    /**
078     * Embedded ICC profile
079     */
080    iCCP(PngChunkIccp::new),
081
082    /**
083     * Significant bits
084     */
085    sBIT,
086
087    /**
088     * Standard RGB color space
089     */
090    sRGB,
091
092    /**
093     * Textual data
094     */
095    tEXt(PngChunkText::new),
096
097    /**
098     * Compressed textual data
099     */
100    zTXt(PngChunkZtxt::new),
101
102    /**
103     * International textual data
104     */
105    iTXt(PngChunkItxt::new),
106
107    /**
108     * Background color
109     */
110    bKGD,
111
112    /**
113     * Image histogram
114     */
115    hIST,
116
117    /**
118     * Physical pixel dimensions
119     */
120    pHYs(PngChunkPhys::new),
121
122    /**
123     * Suggested palette
124     */
125    sPLT,
126
127    /**
128     * Image last-modification time
129     */
130    tIME,
131
132    /*
133     * PNGEXT
134     */
135
136    /**
137     * Image offset
138     *
139     * @since 1.0.0-alpha6
140     */
141    oFFs(Extension.PNGEXT),
142
143    /**
144     * Calibration of pixel values
145     *
146     * @since 1.0.0-alpha6
147     */
148    pCAL(Extension.PNGEXT),
149
150    /**
151     * Physical scale
152     */
153    sCAL(Extension.PNGEXT, PngChunkScal::new),
154
155    /**
156     * GIF Graphic Control Extension
157     *
158     * @since 1.0.0-alpha6
159     */
160    gIFg(Extension.PNGEXT),
161
162    /**
163     * GIF Application Extension
164     *
165     * @since 1.0.0-alpha6
166     */
167    gIFx(Extension.PNGEXT),
168
169    /**
170     * Indicator of Stereo Image
171     *
172     * @since 1.0.0-alpha6
173     */
174    sTER(Extension.PNGEXT),
175
176    /**
177     * Exchangeable Image File (Exif) Profile
178     *
179     * @since 1.0.0-alpha6
180     */
181    eXIf(Extension.PNGEXT),
182
183    ;
184
185    @FunctionalInterface
186    private interface ChunkConstructor {
187        PngChunk make(int length, int chunkType, int crc, byte[] bytes) throws IOException;
188    }
189
190    private static final ChunkType[] types = values();
191
192    static ChunkType findType(final int chunkType) {
193        for (final ChunkType type : types) {
194            if (type.value == chunkType) {
195                return type;
196            }
197        }
198        return null;
199    }
200
201    static PngChunk makeChunk(final int length, final int chunkType, final int crc, final byte[] bytes) throws IOException {
202        final ChunkType type = findType(chunkType);
203        return type != null && type.constructor != null
204                ? type.constructor.make(length, chunkType, crc, bytes)
205                : new PngChunk(length, chunkType, crc, bytes);
206    }
207
208    final byte[] array;
209    final int value;
210    final Extension extension;
211    final ChunkConstructor constructor;
212
213    ChunkType() {
214        this(null, null);
215    }
216
217    ChunkType(final ChunkConstructor constructor) {
218        this(null, constructor);
219    }
220
221    ChunkType(final Extension extension) {
222        this(extension, null);
223    }
224
225    ChunkType(final Extension extension, final ChunkConstructor constructor) {
226        final char[] chars = name().toCharArray();
227        this.array = name().getBytes(StandardCharsets.UTF_8);
228        this.value = BinaryFunctions.charsToQuad(chars[0], chars[1], chars[2], chars[3]);
229        this.extension = extension;
230        this.constructor = constructor;
231    }
232}