/*
 * 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.icns;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.ImageBuilder;

public class IcnsDecoder
{
    private static final int[] palette_4bpp =
    {
        0xffffffff,
        0xfffcf305,
        0xffff6402,
        0xffdd0806,
        0xfff20884,
        0xff4600a5,
        0xff0000d4,
        0xff02abea,
        0xff1fb714,
        0xff006411,
        0xff562c05,
        0xff90713a,
        0xffc0c0c0,
        0xff808080,
        0xff404040,
        0xff000000
    };

    private static final int[] palette_8bpp =
    {
        0xFFFFFFFF,
        0xFFFFFFCC,
        0xFFFFFF99,
        0xFFFFFF66,
        0xFFFFFF33,
        0xFFFFFF00,
        0xFFFFCCFF,
        0xFFFFCCCC,
        0xFFFFCC99,
        0xFFFFCC66,
        0xFFFFCC33,
        0xFFFFCC00,
        0xFFFF99FF,
        0xFFFF99CC,
        0xFFFF9999,
        0xFFFF9966,
        0xFFFF9933,
        0xFFFF9900,
        0xFFFF66FF,
        0xFFFF66CC,
        0xFFFF6699,
        0xFFFF6666,
        0xFFFF6633,
        0xFFFF6600,
        0xFFFF33FF,
        0xFFFF33CC,
        0xFFFF3399,
        0xFFFF3366,
        0xFFFF3333,
        0xFFFF3300,
        0xFFFF00FF,
        0xFFFF00CC,
        0xFFFF0099,
        0xFFFF0066,
        0xFFFF0033,
        0xFFFF0000,
        0xFFCCFFFF,
        0xFFCCFFCC,
        0xFFCCFF99,
        0xFFCCFF66,
        0xFFCCFF33,
        0xFFCCFF00,
        0xFFCCCCFF,
        0xFFCCCCCC,
        0xFFCCCC99,
        0xFFCCCC66,
        0xFFCCCC33,
        0xFFCCCC00,
        0xFFCC99FF,
        0xFFCC99CC,
        0xFFCC9999,
        0xFFCC9966,
        0xFFCC9933,
        0xFFCC9900,
        0xFFCC66FF,
        0xFFCC66CC,
        0xFFCC6699,
        0xFFCC6666,
        0xFFCC6633,
        0xFFCC6600,
        0xFFCC33FF,
        0xFFCC33CC,
        0xFFCC3399,
        0xFFCC3366,
        0xFFCC3333,
        0xFFCC3300,
        0xFFCC00FF,
        0xFFCC00CC,
        0xFFCC0099,
        0xFFCC0066,
        0xFFCC0033,
        0xFFCC0000,
        0xFF99FFFF,
        0xFF99FFCC,
        0xFF99FF99,
        0xFF99FF66,
        0xFF99FF33,
        0xFF99FF00,
        0xFF99CCFF,
        0xFF99CCCC,
        0xFF99CC99,
        0xFF99CC66,
        0xFF99CC33,
        0xFF99CC00,
        0xFF9999FF,
        0xFF9999CC,
        0xFF999999,
        0xFF999966,
        0xFF999933,
        0xFF999900,
        0xFF9966FF,
        0xFF9966CC,
        0xFF996699,
        0xFF996666,
        0xFF996633,
        0xFF996600,
        0xFF9933FF,
        0xFF9933CC,
        0xFF993399,
        0xFF993366,
        0xFF993333,
        0xFF993300,
        0xFF9900FF,
        0xFF9900CC,
        0xFF990099,
        0xFF990066,
        0xFF990033,
        0xFF990000,
        0xFF66FFFF,
        0xFF66FFCC,
        0xFF66FF99,
        0xFF66FF66,
        0xFF66FF33,
        0xFF66FF00,
        0xFF66CCFF,
        0xFF66CCCC,
        0xFF66CC99,
        0xFF66CC66,
        0xFF66CC33,
        0xFF66CC00,
        0xFF6699FF,
        0xFF6699CC,
        0xFF669999,
        0xFF669966,
        0xFF669933,
        0xFF669900,
        0xFF6666FF,
        0xFF6666CC,
        0xFF666699,
        0xFF666666,
        0xFF666633,
        0xFF666600,
        0xFF6633FF,
        0xFF6633CC,
        0xFF663399,
        0xFF663366,
        0xFF663333,
        0xFF663300,
        0xFF6600FF,
        0xFF6600CC,
        0xFF660099,
        0xFF660066,
        0xFF660033,
        0xFF660000,
        0xFF33FFFF,
        0xFF33FFCC,
        0xFF33FF99,
        0xFF33FF66,
        0xFF33FF33,
        0xFF33FF00,
        0xFF33CCFF,
        0xFF33CCCC,
        0xFF33CC99,
        0xFF33CC66,
        0xFF33CC33,
        0xFF33CC00,
        0xFF3399FF,
        0xFF3399CC,
        0xFF339999,
        0xFF339966,
        0xFF339933,
        0xFF339900,
        0xFF3366FF,
        0xFF3366CC,
        0xFF336699,
        0xFF336666,
        0xFF336633,
        0xFF336600,
        0xFF3333FF,
        0xFF3333CC,
        0xFF333399,
        0xFF333366,
        0xFF333333,
        0xFF333300,
        0xFF3300FF,
        0xFF3300CC,
        0xFF330099,
        0xFF330066,
        0xFF330033,
        0xFF330000,
        0xFF00FFFF,
        0xFF00FFCC,
        0xFF00FF99,
        0xFF00FF66,
        0xFF00FF33,
        0xFF00FF00,
        0xFF00CCFF,
        0xFF00CCCC,
        0xFF00CC99,
        0xFF00CC66,
        0xFF00CC33,
        0xFF00CC00,
        0xFF0099FF,
        0xFF0099CC,
        0xFF009999,
        0xFF009966,
        0xFF009933,
        0xFF009900,
        0xFF0066FF,
        0xFF0066CC,
        0xFF006699,
        0xFF006666,
        0xFF006633,
        0xFF006600,
        0xFF0033FF,
        0xFF0033CC,
        0xFF003399,
        0xFF003366,
        0xFF003333,
        0xFF003300,
        0xFF0000FF,
        0xFF0000CC,
        0xFF000099,
        0xFF000066,
        0xFF000033,
        0xFFEE0000,
        0xFFDD0000,
        0xFFBB0000,
        0xFFAA0000,
        0xFF880000,
        0xFF770000,
        0xFF550000,
        0xFF440000,
        0xFF220000,
        0xFF110000,
        0xFF00EE00,
        0xFF00DD00,
        0xFF00BB00,
        0xFF00AA00,
        0xFF008800,
        0xFF007700,
        0xFF005500,
        0xFF004400,
        0xFF002200,
        0xFF001100,
        0xFF0000EE,
        0xFF0000DD,
        0xFF0000BB,
        0xFF0000AA,
        0xFF000088,
        0xFF000077,
        0xFF000055,
        0xFF000044,
        0xFF000022,
        0xFF000011,
        0xFFEEEEEE,
        0xFFDDDDDD,
        0xFFBBBBBB,
        0xFFAAAAAA,
        0xFF888888,
        0xFF777777,
        0xFF555555,
        0xFF444444,
        0xFF222222,
        0xFF111111,
        0xFF000000
    };

    private static void decode1BPPImage(IcnsType imageType, byte[] imageData,
            ImageBuilder image)
    {
        int position = 0;
        int bitsLeft = 0;
        int value = 0;
        for (int y = 0; y < imageType.getHeight(); y++)
        {
            for (int x = 0; x < imageType.getWidth(); x++)
            {
                if (bitsLeft == 0)
                {
                    value = 0xff & imageData[position++];
                    bitsLeft = 8;
                }
                int argb;
                if ((value & 0x80) != 0)
                    argb = 0xff000000;
                else
                    argb = 0xffffffff;
                value <<= 1;
                bitsLeft--;
                image.setRGB(x, y, argb);
            }
        }
    }

    private static void decode4BPPImage(IcnsType imageType, byte[] imageData,
            ImageBuilder image)
    {
        int i = 0;
        boolean visited = false;
        for (int y = 0; y < imageType.getHeight(); y++)
        {
            for (int x = 0; x < imageType.getWidth(); x++)
            {
                int index;
                if (!visited)
                    index = 0xf & (imageData[i] >> 4);
                else
                    index = 0xf & imageData[i++];
                visited = !visited;
                image.setRGB(x, y, palette_4bpp[index]);
            }
        }
    }

    private static void decode8BPPImage(IcnsType imageType, byte[] imageData,
            ImageBuilder image)
    {
        for (int y = 0; y < imageType.getHeight(); y++)
        {
            for (int x = 0; x < imageType.getWidth(); x++)
            {
                int index = 0xff & imageData[y*imageType.getWidth() + x];
                image.setRGB(x, y, palette_8bpp[index]);
            }
        }
    }

    private static void decode32BPPImage(IcnsType imageType, byte[] imageData,
            ImageBuilder image)
    {
        for (int y = 0; y < imageType.getHeight(); y++)
        {
            for (int x = 0; x < imageType.getWidth(); x++)
            {
                int argb = 0xff000000 /* the "alpha" is ignored */ |
                        ((0xff & imageData[4*(y*imageType.getWidth() + x) + 1]) << 16) |
                        ((0xff & imageData[4*(y*imageType.getWidth() + x) + 2]) << 8) |
                        (0xff & imageData[4*(y*imageType.getWidth() + x) + 3]);
                image.setRGB(x, y, argb);
            }
        }
    }

    private static void apply1BPPMask(byte[] maskData, ImageBuilder image) throws ImageReadException
    {
        int position = 0;
        int bitsLeft = 0;
        int value = 0;

        // 1 bit icon types have image data followed by mask data in the same entry
        int totalBytes = (image.getWidth() * image.getHeight() + 7) / 8;
        if (maskData.length >= 2*totalBytes)
            position = totalBytes;
        else
            throw new ImageReadException("1 BPP mask underrun parsing ICNS file");

        for (int y = 0; y < image.getHeight(); y++)
        {
            for (int x = 0; x < image.getWidth(); x++)
            {
                if (bitsLeft == 0)
                {
                    value = 0xff & maskData[position++];
                    bitsLeft = 8;
                }
                int alpha;
                if ((value & 0x80) != 0)
                    alpha = 0xff;
                else
                    alpha = 0x00;
                value <<= 1;
                bitsLeft--;
                image.setRGB(x, y, (alpha << 24) |
                    (0xffffff & image.getRGB(x, y)));
            }
        }
    }

    private static void apply8BPPMask(byte[] maskData, ImageBuilder image)
    {
        for (int y = 0; y < image.getHeight(); y++)
        {
            for (int x = 0; x < image.getWidth(); x++)
            {
                int alpha = 0xff & maskData[y*image.getWidth() + x];
                image.setRGB(x, y, (alpha << 24) |
                    (0xffffff & image.getRGB(x, y)));
            }
        }
    }

    public static List<BufferedImage> decodeAllImages(IcnsImageParser.IcnsElement[] icnsElements)
            throws ImageReadException
    {
        List<BufferedImage> result = new ArrayList<BufferedImage>();
        for (int i = 0; i < icnsElements.length; i++)
        {
            IcnsImageParser.IcnsElement imageElement = icnsElements[i];
            IcnsType imageType = IcnsType.findImageType(imageElement.type);
            if (imageType == null)
                continue;

            IcnsType maskType = null;
            IcnsImageParser.IcnsElement maskElement = null;
            if (imageType.hasMask())
            {
                maskType = imageType;
                maskElement = imageElement;
            }
            else
            {
                maskType = IcnsType.find8BPPMaskType(imageType);
                if (maskType != null)
                {
                    for (int j = 0; j < icnsElements.length; j++)
                    {
                        if (icnsElements[j].type == maskType.getType())
                        {
                            maskElement = icnsElements[j];
                            break;
                        }
                    }
                }
                if (maskElement == null)
                {
                    maskType = IcnsType.find1BPPMaskType(imageType);
                    if (maskType != null)
                    {
                        for (int j = 0; j < icnsElements.length; j++)
                        {
                            if (icnsElements[j].type == maskType.getType())
                            {
                                maskElement = icnsElements[j];
                                break;
                            }
                        }
                    }
                }
            }

            // FIXME: don't skip these when JPEG 2000 support is added:
            if (imageType == IcnsType.ICNS_256x256_32BIT_ARGB_IMAGE ||
                imageType == IcnsType.ICNS_512x512_32BIT_ARGB_IMAGE)
                continue;

            int expectedSize = (imageType.getWidth()*imageType.getHeight()*
                    imageType.getBitsPerPixel() + 7) / 8;
            byte[] imageData;
            if (imageElement.data.length < expectedSize)
            {
                if (imageType.getBitsPerPixel() == 32)
                {
                    imageData = Rle24Compression.decompress(imageType.getWidth(),
                            imageType.getHeight(), imageElement.data);
                }
                else
                    throw new ImageReadException(
                            "Short image data but not a 32 bit compressed type");
            }
            else
                imageData = imageElement.data;

            ImageBuilder imageBuilder = new ImageBuilder(imageType.getWidth(),
                    imageType.getHeight(), true);
            switch (imageType.getBitsPerPixel())
            {
                case 1:
                    decode1BPPImage(imageType, imageData, imageBuilder);
                    break;
                case 4:
                    decode4BPPImage(imageType, imageData, imageBuilder);
                    break;
                case 8:
                    decode8BPPImage(imageType, imageData, imageBuilder);
                    break;
                case 32:
                    decode32BPPImage(imageType, imageData, imageBuilder);
                    break;
                default:
                    throw new ImageReadException(
                        "Unsupported bit depth " + imageType.getBitsPerPixel());
            }

            if (maskElement != null)
            {
                if (maskType.getBitsPerPixel() == 1)
                    apply1BPPMask(maskElement.data, imageBuilder);
                else if (maskType.getBitsPerPixel() == 8)
                    apply8BPPMask(maskElement.data, imageBuilder);
                else
                    throw new ImageReadException("Unsupport mask bit depth " +
                            maskType.getBitsPerPixel());
            }

            result.add(imageBuilder.getBufferedImage());
        }
        return result;
    }
}