/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.imaging.formats.png;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.BinaryFileParser;
import org.apache.commons.imaging.formats.png.chunks.PngChunkPlte;
import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilter;
import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilterAverage;
import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilterNone;
import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilterPaeth;
import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilterSub;
import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilterUp;
import org.apache.commons.imaging.formats.transparencyfilters.TransparencyFilter;

public abstract class ScanExpediter extends BinaryFileParser
{
    protected final int width;
    protected final int height;
    protected final InputStream is;
    protected final BufferedImage bi;
    protected final int colorType;
    protected final int bitDepth;
    protected final int bytesPerPixel;
    protected final int bitsPerPixel;
    protected final PngChunkPlte pngChunkPLTE;
    protected final GammaCorrection gammaCorrection;
    protected final TransparencyFilter transparencyFilter;

    public ScanExpediter(int width, int height, InputStream is,
            BufferedImage bi, int color_type, int bitDepth, int bitsPerPixel,
            PngChunkPlte pngChunkPLTE, GammaCorrection gammaCorrection,
            TransparencyFilter transparencyFilter)

    {
        this.width = width;
        this.height = height;
        this.is = is;
        this.bi = bi;
        this.colorType = color_type;
        this.bitDepth = bitDepth;
        this.bytesPerPixel = this.getBitsToBytesRoundingUp(bitsPerPixel);
        this.bitsPerPixel = bitsPerPixel;
        this.pngChunkPLTE = pngChunkPLTE;
        this.gammaCorrection = gammaCorrection;
        this.transparencyFilter = transparencyFilter;
    }

    protected int getBitsToBytesRoundingUp(int bits)
    {
        int bytes = bits / 8;
        if ((bits % 8 > 0))
            bytes++;
        return bytes;
    }

    protected final int getPixelARGB(int alpha, int red, int green, int blue)
    {
        int rgb = ((0xff & alpha) << 24) | ((0xff & red) << 16)
                | ((0xff & green) << 8) | ((0xff & blue) << 0);

        return rgb;
    }

    protected final int getPixelRGB(int red, int green, int blue)
    {
        return getPixelARGB(0xff, red, green, blue);
    }

    public abstract void drive() throws ImageReadException, IOException;

    protected int getRGB(BitParser bitParser, int pixelIndexInScanline)
            throws ImageReadException, IOException
    {

        switch (colorType)
        {
        case 0: // 1,2,4,8,16 Each pixel is a grayscale sample.
        {
            int sample = bitParser.getSampleAsByte(pixelIndexInScanline, 0);

            if (gammaCorrection != null)
            {
                sample = gammaCorrection.correctSample(sample);
            }

            int rgb = getPixelRGB(sample, sample, sample);

            if (transparencyFilter != null)
                rgb = transparencyFilter.filter(rgb, sample);

            return rgb;

        }
        case 2: // 8,16 Each pixel is an R,G,B triple.
        {
            int red = bitParser.getSampleAsByte(pixelIndexInScanline, 0);
            int green = bitParser.getSampleAsByte(pixelIndexInScanline, 1);
            int blue = bitParser.getSampleAsByte(pixelIndexInScanline, 2);

            int rgb = getPixelRGB(red, green, blue);

            if (transparencyFilter != null)
                rgb = transparencyFilter.filter(rgb, -1);

            if (gammaCorrection != null)
            {
                int alpha = (0xff000000 & rgb) >> 24; // make sure to preserve
                // transparency
                red = gammaCorrection.correctSample(red);
                green = gammaCorrection.correctSample(green);
                blue = gammaCorrection.correctSample(blue);
                rgb = getPixelARGB(alpha, red, green, blue);
            }

            return rgb;
        }
            //
        case 3: // 1,2,4,8 Each pixel is a palette index;
            // a PLTE chunk must appear.
        {
            int index = bitParser.getSample(pixelIndexInScanline, 0);

            int rgb = pngChunkPLTE.getRGB(index);

            if (transparencyFilter != null)
                rgb = transparencyFilter.filter(rgb, index);

            return rgb;
        }
        case 4: // 8,16 Each pixel is a grayscale sample,
            // followed by an alpha sample.
        {
            int sample = bitParser.getSampleAsByte(pixelIndexInScanline, 0);
            int alpha = bitParser.getSampleAsByte(pixelIndexInScanline, 1);

            if (gammaCorrection != null)
                sample = gammaCorrection.correctSample(sample);

            int rgb = getPixelARGB(alpha, sample, sample, sample);
            return rgb;

        }
        case 6: // 8,16 Each pixel is an R,G,B triple,
        {
            int red = bitParser.getSampleAsByte(pixelIndexInScanline, 0);
            int green = bitParser.getSampleAsByte(pixelIndexInScanline, 1);
            int blue = bitParser.getSampleAsByte(pixelIndexInScanline, 2);
            int alpha = bitParser.getSampleAsByte(pixelIndexInScanline, 3);

            if (gammaCorrection != null)
            {
                red = gammaCorrection.correctSample(red);
                green = gammaCorrection.correctSample(green);
                blue = gammaCorrection.correctSample(blue);
            }

            int rgb = getPixelARGB(alpha, red, green, blue);
            return rgb;
        }
        default:
            throw new ImageReadException("PNG: unknown color type: "
                    + colorType);
        }
    }

    protected ScanlineFilter getScanlineFilter(int filter_type,
            int BytesPerPixel) throws ImageReadException
    {
        ScanlineFilter filter;

        switch (filter_type)
        {
        case 0: // None
            filter = new ScanlineFilterNone();
            break;

        case 1: // Sub
            filter = new ScanlineFilterSub(BytesPerPixel);
            break;

        case 2: // Up
            filter = new ScanlineFilterUp(BytesPerPixel);
            break;

        case 3: // Average
            filter = new ScanlineFilterAverage(BytesPerPixel);
            break;

        case 4: // Paeth
            filter = new ScanlineFilterPaeth(BytesPerPixel);
            break;

        default:
            throw new ImageReadException("PNG: unknown filter_type: "
                    + filter_type);

        }

        return filter;
    }

    protected byte[] unfilterScanline(int filter_type, byte src[], byte prev[],
            int BytesPerPixel) throws ImageReadException, IOException
    {
        ScanlineFilter filter = getScanlineFilter(filter_type, BytesPerPixel);

        byte dst[] = new byte[src.length];
        filter.unfilter(src, dst, prev);
        return dst;
    }

    protected byte[] getNextScanline(InputStream is, int length, byte prev[],
            int BytesPerPixel) throws ImageReadException, IOException
    {
        int filterType = is.read();
        if (filterType < 0)
            throw new ImageReadException("PNG: missing filter type");

        byte scanline[] = this.readByteArray("scanline", length, is,
                "PNG: missing image data");

        byte unfiltered[] = unfilterScanline(filterType, scanline, prev,
                BytesPerPixel);

        return unfiltered;
    }

}