/**
 * 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.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;

import javax.imageio.ImageReadParam;

import org.apache.pdfbox.jbig2.Bitmap;
import org.apache.pdfbox.jbig2.JBIG2ReadParam;
import org.apache.pdfbox.jbig2.util.CombinationOperator;

public class Bitmaps
{

    /**
     * Returns the given bitmap as writable raster.
     * 
     * @param bitmap the given bitmap
     * @return the raster representation of the bitmap
     */
    public static WritableRaster asRaster(final Bitmap bitmap)
    {
        return asRaster(bitmap, FilterType.Gaussian);
    }

    /**
     * Returns the given bitmap as writable raster.
     * 
     * @param bitmap the given bitmap
     * @param filterType type of filter which is used when creating the writable raster
     * @return the raster representation of the bitmap
     */
    public static WritableRaster asRaster(final Bitmap bitmap, final FilterType filterType)
    {
        if (bitmap == null)
            throw new IllegalArgumentException("bitmap must not be null");

        final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0,
                new Rectangle(0, 0, bitmap.getWidth(), bitmap.getHeight()),
                new Dimension(bitmap.getWidth(), bitmap.getHeight()));

        return asRaster(bitmap, param, filterType);
    }

    /**
     * Returns the given bitmap as writable raster.
     * 
     * @param bitmap the given bitmap
     * @param param ImageReadParam to be used when creating the writable raster
     * @param filterType type of filter which is used when creating the writable raster
     * @return the raster representation of the bitmap
     */
    public static WritableRaster asRaster(Bitmap bitmap, final ImageReadParam param,
            final FilterType filterType)
    {
        if (bitmap == null)
            throw new IllegalArgumentException("bitmap must not be null");

        if (param == null)
            throw new IllegalArgumentException("param must not be null");

        final Dimension sourceRenderSize = param.getSourceRenderSize();

        double scaleX;
        double scaleY;
        if (sourceRenderSize != null)
        {
            scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
            scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
        }
        else
        {
            scaleX = scaleY = 1;
        }

        Rectangle sourceRegion = param.getSourceRegion();
        if (sourceRegion != null && !bitmap.getBounds().equals(sourceRegion))
        {
            // make sure we don't request an area outside of the source bitmap
            sourceRegion = bitmap.getBounds().intersection(sourceRegion);

            // get region of interest
            bitmap = Bitmaps.extract(sourceRegion, bitmap);
        }

        /*
         * Subsampling is the advance of columns/rows for each pixel in the according direction. The resulting image's
         * quality will be bad because we loose information if we step over columns/rows. For example, a thin line (1
         * pixel high) may disappear completely. To avoid this we use resize filters if scaling will be performed
         * anyway. The resize filters use scale factors, one for horizontal and vertical direction. We care about the
         * given subsampling steps by adjusting the scale factors. If scaling is not performed, subsampling is performed
         * in its original manner.
         */

        final boolean requiresScaling = scaleX != 1 || scaleY != 1;

        final boolean requiresXSubsampling = param.getSourceXSubsampling() != 1;
        final boolean requiresYSubsampling = param.getSourceYSubsampling() != 1;

        if (requiresXSubsampling && requiresYSubsampling)
        {
            // Apply vertical and horizontal subsampling
            if (requiresScaling)
            {
                scaleX /= (double) param.getSourceXSubsampling();
                scaleY /= (double) param.getSourceYSubsampling();
            }
            else
            {
                bitmap = subsample(bitmap, param);
            }
        }
        else
        {
            if (requiresXSubsampling)
            {
                // Apply horizontal subsampling only
                if (requiresScaling)
                {
                    scaleX /= (double) param.getSourceXSubsampling();
                }
                else
                {
                    bitmap = Bitmaps.subsampleX(bitmap, param.getSourceXSubsampling(),
                            param.getSubsamplingXOffset());
                }
            }

            if (requiresYSubsampling)
            {
                // Apply vertical subsampling only
                if (requiresScaling)
                {
                    scaleY /= (double) param.getSourceYSubsampling();
                }
                else
                {
                    bitmap = Bitmaps.subsampleY(bitmap, param.getSourceYSubsampling(),
                            param.getSubsamplingYOffset());
                }
            }
        }

        return buildRaster(bitmap, filterType, scaleX, scaleY);
    }

    private static WritableRaster buildRaster(final Bitmap bitmap, final FilterType filterType,
            final double scaleX, final double scaleY)
    {
        final Rectangle dstBounds = new Rectangle(0, 0, //
                (int) Math.round(bitmap.getWidth() * scaleX), //
                (int) Math.round(bitmap.getHeight() * scaleY));

        final WritableRaster dst = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                dstBounds.width, dstBounds.height, 1, new Point());

        if (scaleX != 1 || scaleY != 1)
        {
            // scaling required
            final Resizer resizer = new Resizer(scaleX, scaleY);
            final Filter filter = Filter.byType(filterType);
            resizer.resize(bitmap, bitmap.getBounds() /* sourceRegion */, dst, dstBounds, filter,
                    filter);
        }
        else
        {
            // scaling not required, paste bitmap into raster pixel per pixel
            int byteIndex = 0;
            for (int y = 0; y < bitmap.getHeight(); y++)
            {
                for (int x = 0; x < bitmap.getWidth(); byteIndex++)
                {
                    final int pixels = (~bitmap.getByte(byteIndex)) & 0xFF;
                    final int relevantPixels = bitmap.getWidth() - x > 8 ? 8
                            : bitmap.getWidth() - x;
                    final int endIdx = 7 - relevantPixels;
                    for (int bytePosition = 7; bytePosition > endIdx; bytePosition--, x++)
                    {
                        dst.setSample(x, y, 0, (pixels >> bytePosition) & 0x1);
                    }
                }
            }
        }

        return dst;
    }

    /**
     * Returns the given bitmap as buffered image.
     * 
     * @param bitmap the given bitmap
     * @return the image representation of the bitmap
     */
    public static BufferedImage asBufferedImage(Bitmap bitmap)
    {
        return asBufferedImage(bitmap, FilterType.Gaussian);
    }

    /**
     * Returns the given bitmap as buffered image.
     * 
     * @param bitmap the given bitmap
     * @param filterType type of filter which is used when creating the buffered image
     * @return the image representation of the bitmap
     */
    public static BufferedImage asBufferedImage(Bitmap bitmap, FilterType filterType)
    {
        if (bitmap == null)
            throw new IllegalArgumentException("bitmap must not be null");

        final JBIG2ReadParam param = new JBIG2ReadParam(1, 1, 0, 0,
                new Rectangle(0, 0, bitmap.getWidth(), bitmap.getHeight()),
                new Dimension(bitmap.getWidth(), bitmap.getHeight()));

        return asBufferedImage(bitmap, param, filterType);
    }

    /**
     * Returns the given bitmap as buffered image.
     * 
     * @param bitmap the given bitmap
     * @param param ImageReadParam to be used when creating the buffered image
     * @param filterType type of filter which is used when creating the buffered image
     * @return the image representation of the bitmap
     */
    public static BufferedImage asBufferedImage(Bitmap bitmap, ImageReadParam param,
            FilterType filterType)
    {
        if (bitmap == null)
            throw new IllegalArgumentException("bitmap must not be null");

        if (param == null)
            throw new IllegalArgumentException("param must not be null");

        final WritableRaster raster = asRaster(bitmap, param, filterType);

        final Dimension sourceRenderSize = param.getSourceRenderSize();

        final double scaleX;
        final double scaleY;
        if (sourceRenderSize != null)
        {
            scaleX = sourceRenderSize.getWidth() / bitmap.getWidth();
            scaleY = sourceRenderSize.getHeight() / bitmap.getHeight();
        }
        else
        {
            scaleX = scaleY = 1d;
        }

        ColorModel cm = null;
        final boolean isScaled = scaleX != 1 || scaleY != 1;
        if (isScaled)
        {
            final int size = 256;
            final int divisor = size - 1;

            final byte[] gray = new byte[size];
            for (int i = size - 1, s = 0; i >= 0; i--, s++)
            {
                gray[i] = (byte) (255 - s * 255 / divisor);
            }
            cm = new IndexColorModel(8, size, gray, gray, gray);
        }
        else
        {

            cm = new IndexColorModel(8, 2, //
                    new byte[] { 0x00, (byte) 0xff }, new byte[] { 0x00, (byte) 0xff },
                    new byte[] { 0x00, (byte) 0xff });
        }

        return new BufferedImage(cm, raster, false, null);
    }

    /**
     * Returns the specified rectangle area of the bitmap.
     * 
     * @param roi - A {@link Rectangle} that specifies the requested image section.
     * @param src the given bitmap
     * @return A {@code Bitmap} that represents the requested image section.
     */
    public static Bitmap extract(final Rectangle roi, final Bitmap src)
    {
        final Bitmap dst = new Bitmap(roi.width, roi.height);

        final int upShift = roi.x & 0x07;
        final int downShift = 8 - upShift;
        int dstLineStartIdx = 0;

        final int padding = (8 - dst.getWidth() & 0x07);
        int srcLineStartIdx = src.getByteIndex(roi.x, roi.y);
        int srcLineEndIdx = src.getByteIndex(roi.x + roi.width - 1, roi.y);
        final boolean usePadding = dst.getRowStride() == srcLineEndIdx + 1 - srcLineStartIdx;

        for (int y = roi.y; y < roi.getMaxY(); y++)
        {
            int srcIdx = srcLineStartIdx;
            int dstIdx = dstLineStartIdx;

            if (srcLineStartIdx == srcLineEndIdx)
            {
                final byte pixels = (byte) (src.getByte(srcIdx) << upShift);
                dst.setByte(dstIdx, unpad(padding, pixels));
            }
            else if (upShift == 0)
            {
                for (int x = srcLineStartIdx; x <= srcLineEndIdx; x++)
                {
                    byte value = src.getByte(srcIdx++);

                    if (x == srcLineEndIdx && usePadding)
                    {
                        value = unpad(padding, value);
                    }

                    dst.setByte(dstIdx++, value);
                }
            }
            else
            {
                copyLine(src, dst, upShift, downShift, padding, srcLineStartIdx, srcLineEndIdx,
                        usePadding, srcIdx, dstIdx);
            }

            srcLineStartIdx += src.getRowStride();
            srcLineEndIdx += src.getRowStride();
            dstLineStartIdx += dst.getRowStride();
        }

        return dst;
    }

    private static void copyLine(Bitmap src, Bitmap dst, int sourceUpShift, int sourceDownShift,
            int padding, int firstSourceByteOfLine, int lastSourceByteOfLine, boolean usePadding,
            int sourceOffset, int targetOffset)
    {
        for (int x = firstSourceByteOfLine; x < lastSourceByteOfLine; x++)
        {

            if (sourceOffset + 1 < src.getByteArray().length)
            {
                final boolean isLastByte = x + 1 == lastSourceByteOfLine;
                byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift
                        | (src.getByte(sourceOffset) & 0xff) >>> sourceDownShift);

                if (isLastByte && !usePadding)
                {
                    value = unpad(padding, value);
                }

                dst.setByte(targetOffset++, value);

                if (isLastByte && usePadding)
                {
                    value = unpad(padding,
                            (byte) ((src.getByte(sourceOffset) & 0xff) << sourceUpShift));
                    dst.setByte(targetOffset, value);
                }

            }
            else
            {
                final byte value = (byte) (src.getByte(sourceOffset++) << sourceUpShift & 0xff);
                dst.setByte(targetOffset++, value);
            }
        }
    }

    /**
     * Removes unnecessary bits from a byte.
     * 
     * @param padding - The amount of unnecessary bits.
     * @param value - The byte that should be cleaned up.
     * @return A cleaned byte.
     */
    private static byte unpad(int padding, byte value)
    {
        return (byte) (value >> padding << padding);
    }

    public static Bitmap subsample(Bitmap src, ImageReadParam param)
    {
        if (src == null)
            throw new IllegalArgumentException("src must not be null");

        if (param == null)
            throw new IllegalArgumentException("param must not be null");

        final int xSubsampling = param.getSourceXSubsampling();
        final int ySubsampling = param.getSourceYSubsampling();
        final int xSubsamplingOffset = param.getSubsamplingXOffset();
        final int ySubsamplingOffset = param.getSubsamplingYOffset();

        final int dstWidth = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
        final int dstHeight = (src.getHeight() - ySubsamplingOffset) / ySubsampling;

        final Bitmap dst = new Bitmap(dstWidth, dstHeight);

        for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst
                .getHeight(); yDst++, ySrc += ySubsampling)
        {
            for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst
                    .getWidth(); xDst++, xSrc += xSubsampling)
            {
                final byte pixel = src.getPixel(xSrc, ySrc);
                if (pixel != 0)
                    dst.setPixel(xDst, yDst, pixel);
            }
        }

        return dst;
    }

    public static Bitmap subsampleX(Bitmap src, final int xSubsampling,
            final int xSubsamplingOffset)
    {
        if (src == null)
            throw new IllegalArgumentException("src must not be null");

        final int dstHeight = (src.getWidth() - xSubsamplingOffset) / xSubsampling;
        final Bitmap dst = new Bitmap(src.getWidth(), dstHeight);

        for (int yDst = 0; yDst < dst.getHeight(); yDst++)
        {
            for (int xDst = 0, xSrc = xSubsamplingOffset; xDst < dst
                    .getWidth(); xDst++, xSrc += xSubsampling)
            {
                final byte pixel = src.getPixel(xSrc, yDst);
                if (pixel != 0)
                    dst.setPixel(xDst, yDst, pixel);
            }
        }

        return dst;
    }

    public static Bitmap subsampleY(Bitmap src, final int ySubsampling,
            final int ySubsamplingOffset)
    {
        if (src == null)
            throw new IllegalArgumentException("src must not be null");

        final int dstWidth = (src.getWidth() - ySubsamplingOffset) / ySubsampling;
        final Bitmap dst = new Bitmap(dstWidth, src.getHeight());

        for (int yDst = 0, ySrc = ySubsamplingOffset; yDst < dst
                .getHeight(); yDst++, ySrc += ySubsampling)
        {
            for (int xDst = 0; xDst < dst.getWidth(); xDst++)
            {
                final byte pixel = src.getPixel(xDst, ySrc);
                if (pixel != 0)
                    dst.setPixel(xDst, yDst, pixel);
            }
        }

        return dst;
    }

    /**
     * The method combines two given bytes with an logical operator.
     * <p>
     * The JBIG2 Standard specifies 5 possible combinations of bytes.<br>
     * <p>
     * <b>Hint:</b> Please take a look at ISO/IEC 14492:2001 (E) for detailed definition and description of the
     * operators.
     * 
     * @param value1 - The value that should be combined with value2.
     * @param value2 - The value that should be combined with value1.
     * @param op - The specified combination operator.
     * 
     * @return The combination result.
     */
    public static byte combineBytes(byte value1, byte value2, CombinationOperator op)
    {

        switch (op)
        {
        case OR:
            return (byte) (value2 | value1);
        case AND:
            return (byte) (value2 & value1);
        case XOR:
            return (byte) (value2 ^ value1);
        case XNOR:
            return (byte) ~(value1 ^ value2);
        case REPLACE:
        default:
            // Old value is replaced by new value.
            return value2;
        }
    }

    /**
     * This method combines a given bitmap with the current instance.
     * <p>
     * Parts of the bitmap to blit that are outside of the target bitmap will be ignored.
     * 
     * @param src - The bitmap that should be combined with the one of the current instance.
     * @param dst - The destination bitmap.
     * @param x - The x coordinate where the upper left corner of the bitmap to blit should be positioned.
     * @param y - The y coordinate where the upper left corner of the bitmap to blit should be positioned.
     * @param combinationOperator - The combination operator for combining two pixels.
     */
    public static void blit(Bitmap src, Bitmap dst, int x, int y,
            CombinationOperator combinationOperator)
    {

        int startLine = 0;
        int srcStartIdx = 0;
        int srcEndIdx = (src.getRowStride() - 1);

        // Ignore those parts of the source bitmap which would be placed outside the target bitmap.
        if (x < 0)
        {
            srcStartIdx = -x;
            x = 0;
        }
        else if (x + src.getWidth() > dst.getWidth())
        {
            srcEndIdx -= (src.getWidth() + x - dst.getWidth());
        }

        if (y < 0)
        {
            startLine = -y;
            y = 0;
            srcStartIdx += src.getRowStride();
            srcEndIdx += src.getRowStride();
        }
        else if (y + src.getHeight() > dst.getHeight())
        {
            startLine = src.getHeight() + y - dst.getHeight();
        }

        final int shiftVal1 = x & 0x07;
        final int shiftVal2 = 8 - shiftVal1;

        final int padding = src.getWidth() & 0x07;
        final int toShift = shiftVal2 - padding;

        final boolean useShift = (shiftVal2 & 0x07) != 0;
        final boolean specialCase = src.getWidth() <= ((srcEndIdx - srcStartIdx) << 3) + shiftVal2;

        final int dstStartIdx = dst.getByteIndex(x, y);

        final int lastLine = Math.min(src.getHeight(), startLine + dst.getHeight());

        if (!useShift)
        {
            blitUnshifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx,
                    combinationOperator);
        }
        else if (specialCase)
        {
            blitSpecialShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx,
                    toShift, shiftVal1, shiftVal2, combinationOperator);
        }
        else
        {
            blitShifted(src, dst, startLine, lastLine, dstStartIdx, srcStartIdx, srcEndIdx, toShift,
                    shiftVal1, shiftVal2, combinationOperator, padding);
        }
    }

    private static void blitUnshifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
            int dstStartIdx, int srcStartIdx, int srcEndIdx, CombinationOperator op)
    {

        for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
                .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
        {
            int dstIdx = dstStartIdx;

            // Go through the bytes in a line of the Symbol
            for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
            {
                byte oldByte = dst.getByte(dstIdx);
                byte newByte = src.getByte(srcIdx);
                dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
            }
        }
    }

    private static void blitSpecialShifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
            int dstStartIdx, int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1,
            int shiftVal2, CombinationOperator op)
    {

        for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
                .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
        {
            short register = 0;
            int dstIdx = dstStartIdx;

            // Go through the bytes in a line of the Symbol
            for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
            {
                byte oldByte = dst.getByte(dstIdx);
                register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);
                byte newByte = (byte) (register >> 8);

                if (srcIdx == srcEndIdx)
                {
                    newByte = unpad(toShift, newByte);
                }

                dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));
                register <<= shiftVal1;
            }
        }
    }

    private static void blitShifted(Bitmap src, Bitmap dst, int startLine, int lastLine,
            int dstStartIdx, int srcStartIdx, int srcEndIdx, int toShift, int shiftVal1,
            int shiftVal2, CombinationOperator op, int padding)
    {

        for (int dstLine = startLine; dstLine < lastLine; dstLine++, dstStartIdx += dst
                .getRowStride(), srcStartIdx += src.getRowStride(), srcEndIdx += src.getRowStride())
        {
            short register = 0;
            int dstIdx = dstStartIdx;

            // Go through the bytes in a line of the symbol
            for (int srcIdx = srcStartIdx; srcIdx <= srcEndIdx; srcIdx++)
            {
                byte oldByte = dst.getByte(dstIdx);
                register = (short) ((register | src.getByte(srcIdx) & 0xff) << shiftVal2);

                byte newByte = (byte) (register >> 8);
                dst.setByte(dstIdx++, Bitmaps.combineBytes(oldByte, newByte, op));

                register <<= shiftVal1;

                if (srcIdx == srcEndIdx)
                {
                    newByte = (byte) (register >> (8 - shiftVal2));

                    if (padding != 0)
                    {
                        newByte = unpad(8 + toShift, newByte);
                    }

                    oldByte = dst.getByte(dstIdx);
                    dst.setByte(dstIdx, Bitmaps.combineBytes(oldByte, newByte, op));
                }
            }
        }
    }

}
