    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}