/**
 * 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.pdfbox.jbig2.image;

import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;

abstract class Scanline
{
    public interface ScanlineFilter
    {
        public void filter(int x, int y, int componentIndex, Object data, int length);
    }

    /**
     * A Scanline for pixel interleaved byte data with three components. Although its name contains "BGR" it doesn't
     * really matter how the components are organized, als long as there are three of them.
     */
    protected static final class ByteBGRScanline extends Scanline
    {
        private final Raster srcRaster;
        private final WritableRaster dstRaster;

        private final int data[];

        protected ByteBGRScanline(Raster src, WritableRaster dst, final int length)
        {
            super(length);
            srcRaster = src;
            dstRaster = dst;

            data = new int[3 * length];
        }

        @Override
        protected void accumulate(final int weight, final Scanline dst)
        {
            final ByteBGRScanline bcs = (ByteBGRScanline) dst;

            final int abuf[] = data;
            final int bbuf[] = bcs.data;

            for (int b = 0; b < bbuf.length; b++)
                bbuf[b] += weight * abuf[b];
        }

        @Override
        protected void clear()
        {
            final int[] b = data;
            for (int j = 0; j < b.length; j++)
                b[j] = 0;
        }

        @Override
        protected void fetch(final int x, final int y)
        {
            srcRaster.getPixels(x, y, length, 1, data);
        }

        @Override
        protected void filter(final int[] preShift, final int[] postShift, final Weighttab[] tabs,
                final Scanline dst)
        {
            final ByteBGRScanline bcs = (ByteBGRScanline) dst;
            final int nx = dst.length;

            // start sum at 1<<shift-1 for rounding
            final int start[] = new int[] { 1 << postShift[0] - 1, 1 << postShift[1] - 1,
                    1 << postShift[2] - 1 };
            final int abuf[] = data;
            final int bbuf[] = bcs.data;

            // the next two blocks are duplicated except for the missing shift
            // operation if preShift==0.
            if (preShift[0] != 0 || preShift[1] != 0 || preShift[2] != 0)
                for (int bp = 0, b = 0; b < nx; b++)
                {
                    final Weighttab wtab = tabs[b];
                    final int an = wtab.weights.length;

                    int sumr = start[0];
                    int sumg = start[1];
                    int sumb = start[2];
                    for (int wp = 0, ap = wtab.i0 * 3; wp < an && ap < abuf.length; wp++)
                    {
                        final int w = wtab.weights[wp];
                        sumr += w * (abuf[ap++] >> preShift[0]);
                        sumg += w * (abuf[ap++] >> preShift[1]);
                        sumb += w * (abuf[ap++] >> preShift[2]);
                    }

                    int t = sumr >> postShift[0];
                    bbuf[bp++] = t < 0 ? 0 : t > 255 ? 255 : t;
                    t = sumg >> postShift[1];
                    bbuf[bp++] = t < 0 ? 0 : t > 255 ? 255 : t;
                    t = sumb >> postShift[2];
                    bbuf[bp++] = t < 0 ? 0 : t > 255 ? 255 : t;
                }
            else
                for (int bp = 0, b = 0; b < nx; b++)
                {
                    final Weighttab wtab = tabs[b];
                    final int an = wtab.weights.length;

                    int sumr = start[0];
                    int sumg = start[1];
                    int sumb = start[2];
                    for (int wp = 0, ap = wtab.i0 * 3; wp < an && ap < abuf.length; wp++)
                    {
                        final int w = wtab.weights[wp];
                        sumr += w * abuf[ap++];
                        sumg += w * abuf[ap++];
                        sumb += w * abuf[ap++];
                    }

                    bbuf[bp++] = sumr >> postShift[0];
                    bbuf[bp++] = sumg >> postShift[1];
                    bbuf[bp++] = sumb >> postShift[2];
                }
        }

        @Override
        protected void shift(final int[] shift)
        {
            final int half[] = new int[] { 1 << shift[0] - 1, 1 << shift[1] - 1,
                    1 << shift[2] - 1 };

            final int abuf[] = data;

            for (int b = 0; b < abuf.length;)
            {
                for (int c = 0; c < 3; c++, b++)
                {
                    final int t = abuf[b] + half[c] >> shift[c];
                    abuf[b] = t < 0 ? 0 : t > 255 ? 255 : t;
                }
            }
        }

        @Override
        protected void store(final int x, final int y)
        {
            dstRaster.setPixels(x, y, length, 1, data);
        }
    }

    /**
     * A Scanline for packed integer pixels.
     */
    protected static final class IntegerSinglePixelPackedScanline extends Scanline
    {
        private final Raster srcRaster;
        private final WritableRaster dstRaster;

        private final int data[];
        private final int[] bitMasks;
        private final int[] bitOffsets;
        private final int componentCount;
        private final SinglePixelPackedSampleModel srcSM;
        private final int tmp[];

        protected IntegerSinglePixelPackedScanline(Raster src, WritableRaster dst, final int length)
        {
            super(length);
            srcRaster = src;
            dstRaster = dst;

            srcSM = (SinglePixelPackedSampleModel) srcRaster.getSampleModel();

            bitMasks = srcSM.getBitMasks();
            bitOffsets = srcSM.getBitOffsets();
            componentCount = bitMasks.length;

            if (componentCount != bitOffsets.length || bitOffsets.length != srcSM.getNumBands())
                throw new IllegalArgumentException(
                        "weird: getBitMasks().length != getBitOffsets().length");

            tmp = new int[componentCount];

            data = new int[componentCount * length];
        }

        @Override
        protected void accumulate(final int weight, final Scanline dst)
        {
            final IntegerSinglePixelPackedScanline ispps = (IntegerSinglePixelPackedScanline) dst;

            final int abuf[] = data;
            final int bbuf[] = ispps.data;

            for (int b = 0; b < bbuf.length; b++)
                bbuf[b] += weight * abuf[b];
        }

        @Override
        protected void clear()
        {
            final int[] b = data;
            for (int j = 0; j < b.length; j++)
                b[j] = 0;
        }

        @Override
        protected void fetch(final int x, final int y)
        {
            srcRaster.getPixels(x, y, length, 1, data);
        }

        @Override
        protected void filter(final int[] preShift, final int[] postShift, final Weighttab[] tabs,
                final Scanline dst)
        {
            final IntegerSinglePixelPackedScanline ispps = (IntegerSinglePixelPackedScanline) dst;
            final int nx = dst.length;

            // start sum at 1<<shift-1 for rounding
            final int start[] = tmp;
            for (int c = 0; c < componentCount; c++)
                start[c] = 1 << postShift[c] - 1;

            final int abuf[] = data;
            final int bbuf[] = ispps.data;

            // the next two blocks are duplicated except for the missing shift
            // operation if preShift==0.
            boolean hasPreShift = false;
            for (int c = 0; c < componentCount && !hasPreShift; c++)
                hasPreShift |= preShift[c] != 0;
            if (hasPreShift)
                for (int bp = 0, b = 0; b < nx; b++)
                {
                    final Weighttab wtab = tabs[b];
                    final int an = wtab.weights.length;

                    for (int c = 0; c < componentCount; c++)
                    {
                        int sum = start[c];
                        for (int wp = 0, ap = wtab.i0 * componentCount + c; wp < an
                                && ap < abuf.length; wp++, ap += componentCount)
                            sum += wtab.weights[wp] * (abuf[ap] >> preShift[c]);

                        final int t = sum >> postShift[c];
                        bbuf[bp++] = t < 0 ? 0 : t > 255 ? 255 : t;
                    }
                }
            else
                for (int bp = 0, b = 0; b < nx; b++)
                {
                    final Weighttab wtab = tabs[b];
                    final int an = wtab.weights.length;

                    for (int c = 0; c < componentCount; c++)
                    {
                        int sum = start[c];
                        for (int wp = 0, ap = wtab.i0 * componentCount + c; wp < an
                                && ap < abuf.length; wp++, ap += componentCount)
                            sum += wtab.weights[wp] * abuf[ap];

                        bbuf[bp++] = sum >> postShift[c];
                    }
                }
        }

        @Override
        protected void shift(final int[] shift)
        {
            final int half[] = tmp;
            for (int c = 0; c < componentCount; c++)
                half[c] = 1 << shift[c] - 1;

            final int abuf[] = data;

            for (int b = 0; b < abuf.length;)
            {
                for (int c = 0; c < componentCount; c++, b++)
                {
                    final int t = abuf[b] + half[c] >> shift[c];
                    abuf[b] = t < 0 ? 0 : t > 255 ? 255 : t;
                }
            }
        }

        @Override
        protected void store(final int x, final int y)
        {
            dstRaster.setPixels(x, y, length, 1, data);
        }
    }

    /**
     * A Scanline for packed integer pixels.
     */
    protected static final class GenericRasterScanline extends Scanline
    {
        private final Raster srcRaster;
        private final WritableRaster dstRaster;

        private final int componentCount;
        private final int data[][];
        private final SampleModel srcSM;
        private final SampleModel dstSM;
        private final int channelMask[];
        private final int[] tmp;
        private final ScanlineFilter inputFilter;

        protected GenericRasterScanline(Raster src, WritableRaster dst, final int length,
                int bitsPerChannel[], ScanlineFilter inputFilter)
        {
            super(length);
            srcRaster = src;
            dstRaster = dst;
            this.inputFilter = inputFilter;

            srcSM = srcRaster.getSampleModel();
            dstSM = dstRaster.getSampleModel();

            componentCount = srcSM.getNumBands();

            if (componentCount != dstSM.getNumBands())
                throw new IllegalArgumentException(
                        "weird: src raster num bands != dst raster num bands");

            tmp = new int[componentCount];

            data = new int[componentCount][];
            for (int i = 0; i < data.length; i++)
                data[i] = new int[length];

            channelMask = new int[componentCount];
            for (int c = 0; c < componentCount; c++)
                channelMask[c] = (1 << bitsPerChannel[c]) - 1;
        }

        @Override
        protected void accumulate(final int weight, final Scanline dst)
        {
            final GenericRasterScanline grs = (GenericRasterScanline) dst;

            final int l = grs.data[0].length;
            for (int c = 0; c < componentCount; c++)
            {
                final int ac[] = data[c];
                final int bc[] = grs.data[c];

                for (int b = 0; b < l; b++)
                    bc[b] += weight * ac[b];
            }
        }

        @Override
        protected void clear()
        {
            for (int c = 0; c < componentCount; c++)
            {
                final int[] b = data[c];
                for (int x = 0; x < b.length; x++)
                    b[x] = 0;
            }
        }

        @Override
        protected void fetch(final int x, final int y)
        {
            for (int c = 0; c < componentCount; c++)
            {
                srcRaster.getSamples(x, y, length, 1, c, data[c]);
                if (null != inputFilter)
                    inputFilter.filter(x, y, c, data[c], length);
            }
        }

        @Override
        protected void filter(final int[] preShift, final int[] postShift, final Weighttab[] tabs,
                final Scanline dst)
        {
            final GenericRasterScanline grs = (GenericRasterScanline) dst;
            final int nx = dst.length;

            // start sum at 1<<shift-1 for rounding
            final int start[] = tmp;
            for (int c = 0; c < componentCount; c++)
                start[c] = 1 << postShift[c] - 1;

            final int l = data[0].length;

            // the next two blocks are duplicated except for the missing shift
            // operation if preShift==0.
            boolean hasPreShift = false;
            for (int c = 0; c < componentCount && !hasPreShift; c++)
                hasPreShift |= preShift[c] != 0;
            if (hasPreShift)
                for (int c = 0; c < componentCount; c++)
                {
                    final int ac[] = data[c];
                    final int bc[] = grs.data[c];
                    final int m = channelMask[c];
                    for (int b = 0; b < nx; b++)
                    {
                        final Weighttab wtab = tabs[b];
                        final int an = wtab.weights.length;

                        int sum = start[c];
                        for (int wp = 0, ap = wtab.i0; wp < an && ap < l; wp++, ap++)
                            sum += wtab.weights[wp] * (ac[ap] >> preShift[c]);

                        final int t = sum >> postShift[c];
                        bc[b] = t < 0 ? 0 : t > m ? m : t;
                    }
                }
            else
                for (int c = 0; c < componentCount; c++)
                {
                    final int ac[] = data[c];
                    final int bc[] = grs.data[c];

                    for (int b = 0; b < nx; b++)
                    {
                        final Weighttab wtab = tabs[b];
                        final int an = wtab.weights.length;

                        int sum = start[c];
                        for (int wp = 0, ap = wtab.i0; wp < an && ap < l; wp++, ap++)
                            sum += wtab.weights[wp] * ac[ap];

                        bc[b] = sum >> postShift[c];
                    }
                }
        }

        @Override
        protected void shift(final int[] shift)
        {
            final int half[] = tmp;
            for (int c = 0; c < componentCount; c++)
                half[c] = 1 << shift[c] - 1;

            final int abuf[][] = data;

            final int l = abuf[0].length;
            for (int c = 0; c < componentCount; c++)
            {
                final int ac[] = data[c];
                final int m = channelMask[c];

                for (int a = 0; a < l; a++)
                {
                    final int t = ac[a] + half[c] >> shift[c];
                    ac[a] = t < 0 ? 0 : t > m ? m : t;
                }
            }
        }

        @Override
        protected void store(final int x, final int y)
        {
            final int nx = length;
            for (int c = 0; c < componentCount; c++)
                dstRaster.setSamples(x, y, nx, 1, c, data[c]);
        }
    }

    /**
     * A Scanline for BiLevel input data ({@link MultiPixelPackedSampleModel}) to indexed output data
     * (<code>sun.awt.image.ByteInterleavedRaster</code>).
     */
    protected static final class ByteBiLevelPackedScanline extends Scanline
    {
        private final Raster srcRaster;
        private final WritableRaster dstRaster;

        private final int data[];

        protected ByteBiLevelPackedScanline(Raster src, WritableRaster dst, final int length)
        {
            super(length);
            srcRaster = src;
            dstRaster = dst;

            data = new int[length];
        }

        @Override
        protected void accumulate(final int weight, final Scanline dst)
        {
            final ByteBiLevelPackedScanline bblps = (ByteBiLevelPackedScanline) dst;

            final int abuf[] = data;
            final int bbuf[] = bblps.data;

            for (int b = 0; b < bbuf.length; b++)
                bbuf[b] += weight * abuf[b];
        }

        @Override
        protected void clear()
        {
            final int[] b = data;
            for (int j = 0; j < b.length; j++)
                b[j] = 0;
        }

        @Override
        protected void fetch(final int x, final int y)
        {
            srcRaster.getPixels(x, y, length, 1, data);
            for (int i = 0; i < length; i++)
                if (data[i] != 0)
                    data[i] = 255;
        }

        @Override
        protected void filter(final int[] preShift, final int[] postShift, final Weighttab[] tabs,
                final Scanline dst)
        {
            final ByteBiLevelPackedScanline bblps = (ByteBiLevelPackedScanline) dst;
            final int nx = dst.length;

            // start sum at 1<<shift-1 for rounding
            final int start = 1 << postShift[0] - 1;
            final int abuf[] = data;
            final int bbuf[] = bblps.data;

            // the next two blocks are duplicated except for the missing shift
            // operation if preShift==0.
            final int preShift0 = preShift[0];
            final int postShift0 = postShift[0];
            if (preShift0 != 0)
                for (int bp = 0, b = 0; b < nx; b++)
                {
                    final Weighttab wtab = tabs[b];
                    final int an = wtab.weights.length;

                    int sum = start;
                    for (int wp = 0, ap = wtab.i0; wp < an && ap < abuf.length; wp++)
                    {
                        sum += wtab.weights[wp] * (abuf[ap++] >> preShift0);
                    }

                    final int t = sum >> postShift0;
                    bbuf[bp++] = t < 0 ? 0 : t > 255 ? 255 : t;
                }
            else
                for (int bp = 0, b = 0; b < nx; b++)
                {
                    final Weighttab wtab = tabs[b];
                    final int an = wtab.weights.length;

                    int sum = start;
                    for (int wp = 0, ap = wtab.i0; wp < an && ap < abuf.length; wp++)
                    {
                        sum += wtab.weights[wp] * abuf[ap++];
                    }

                    bbuf[bp++] = sum >> postShift0;
                }
        }

        @Override
        protected void shift(final int[] shift)
        {
            final int shift0 = shift[0];
            final int half = 1 << shift0 - 1;

            final int abuf[] = data;

            for (int b = 0; b < abuf.length; b++)
            {
                final int t = abuf[b] + half >> shift0;
                abuf[b] = t < 0 ? 0 : t > 255 ? 255 : t;
            }
        }

        @Override
        protected void store(final int x, final int y)
        {
            dstRaster.setPixels(x, y, length, 1, data);
        }
    }

    int y;
    protected final int length;

    protected Scanline(final int width)
    {
        length = width;
    }

    protected final int getWidth()
    {
        return length;
    }

    protected abstract void clear();

    protected abstract void fetch(int x, int y);

    protected abstract void filter(int[] preShift, int[] postShift, Weighttab[] xweights,
            Scanline dst);

    protected abstract void accumulate(int weight, Scanline dst);

    protected abstract void shift(int[] finalshift);

    protected abstract void store(int x, int y);
}
