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.chunks;
018
019import static org.apache.commons.imaging.common.BinaryFunctions.readByte;
020
021import java.io.ByteArrayInputStream;
022import java.io.IOException;
023import java.util.Arrays;
024
025import org.apache.commons.imaging.ImagingException;
026import org.apache.commons.imaging.common.Allocator;
027import org.apache.commons.imaging.formats.png.GammaCorrection;
028
029public final class PngChunkPlte extends PngChunk {
030    private final int[] rgb;
031
032    public PngChunkPlte(final int length, final int chunkType, final int crc, final byte[] bytes) throws ImagingException, IOException {
033        super(length, chunkType, crc, bytes);
034
035        final ByteArrayInputStream is = new ByteArrayInputStream(bytes);
036
037        if (length % 3 != 0) {
038            throw new ImagingException("PLTE: wrong length: " + length);
039        }
040
041        final int count = length / 3;
042
043        rgb = Allocator.intArray(count);
044
045        for (int i = 0; i < count; i++) {
046            final int red = readByte("red[" + i + "]", is, "Not a Valid PNG File: PLTE Corrupt");
047            final int green = readByte("green[" + i + "]", is, "Not a Valid PNG File: PLTE Corrupt");
048            final int blue = readByte("blue[" + i + "]", is, "Not a Valid PNG File: PLTE Corrupt");
049            rgb[i] = 0xff000000 | (0xff & red) << 16 | (0xff & green) << 8 | (0xff & blue) << 0;
050        }
051    }
052
053    public void correct(final GammaCorrection gammaCorrection) {
054        Arrays.setAll(rgb, i -> gammaCorrection.correctArgb(rgb[i]));
055    }
056
057    public int[] getRgb() {
058        return rgb.clone();
059    }
060
061    // public void printPalette() {
062    // Debug.debug();
063    // Debug.debug("palette");
064    // for (int i = 0; i < rgb.length; i++) {
065    // Debug.debug("\t" + "palette[" + i + "];", rgb[i] + " (0x"
066    // + Integer.toHexString(rgb[i]) + ")");
067    //
068    // }
069    // Debug.debug();
070    // }
071
072    public int getRgb(final int index) throws ImagingException {
073        if (index < 0 || index >= rgb.length) {
074            throw new ImagingException("PNG: unknown Palette reference: " + index);
075        }
076        return rgb[index];
077    }
078
079}