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

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.imaging.ImageFormat;
import org.apache.commons.imaging.ImageInfo;
import org.apache.commons.imaging.ImageParser;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;
import org.apache.commons.imaging.Sanselan;
import org.apache.commons.imaging.common.BinaryOutputStream;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.formats.bmp.BmpImageParser;
import org.apache.commons.imaging.palette.PaletteFactory;
import org.apache.commons.imaging.palette.SimplePalette;
import org.apache.commons.imaging.util.Debug;

public class IcoImageParser extends ImageParser
{

    public IcoImageParser()
    {
        super.setByteOrder(BYTE_ORDER_LSB);
    }

    @Override
    public String getName()
    {
        return "ico-Custom";
    }

    @Override
    public String getDefaultExtension()
    {
        return DEFAULT_EXTENSION;
    }

    private static final String DEFAULT_EXTENSION = ".ico";

    private static final String ACCEPTED_EXTENSIONS[] = {
            ".ico", ".cur",
    };

    @Override
    protected String[] getAcceptedExtensions()
    {
        return ACCEPTED_EXTENSIONS;
    }

    @Override
    protected ImageFormat[] getAcceptedTypes()
    {
        return new ImageFormat[]{
            ImageFormat.IMAGE_FORMAT_ICO, //
        };
    }

    @Override
    public boolean embedICCProfile(File src, File dst, byte profile[])
    {
        return false;
    }

    @Override
    public IImageMetadata getMetadata(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    @Override
    public ImageInfo getImageInfo(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    @Override
    public Dimension getImageSize(ByteSource byteSource,
            Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    @Override
    public byte[] getICCProfileBytes(ByteSource byteSource,
            Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    private static class FileHeader
    {
        public final int reserved; // Reserved (2 bytes), always 0
        public final int iconType; // IconType (2 bytes), if the image is an icon it?s 1, for cursors the value is 2.
        public final int iconCount; //IconCount (2 bytes), number of icons in this file.

        public FileHeader(final int reserved, final int iconType,
                final int iconCount)
        {
            this.reserved = reserved;
            this.iconType = iconType;
            this.iconCount = iconCount;
        }

        public void dump(PrintWriter pw)
        {
            pw.println("FileHeader");
            pw.println("Reserved: " + reserved);
            pw.println("IconType: " + iconType);
            pw.println("IconCount: " + iconCount);
            pw.println();
        }
    }

    private FileHeader readFileHeader(InputStream is)
            throws ImageReadException, IOException
    {
        int Reserved = read2Bytes("Reserved", is, "Not a Valid ICO File");
        int IconType = read2Bytes("IconType", is, "Not a Valid ICO File");
        int IconCount = read2Bytes("IconCount", is, "Not a Valid ICO File");

        if (Reserved != 0)
            throw new ImageReadException("Not a Valid ICO File: reserved is " + Reserved);
        if (IconType != 1 && IconType != 2)
            throw new ImageReadException("Not a Valid ICO File: icon type is " + IconType);

        return new FileHeader(Reserved, IconType, IconCount);

    }

    private static class IconInfo
    {
        public final byte Width;
        public final byte Height;
        public final byte ColorCount;
        public final byte Reserved;
        public final int Planes;
        public final int BitCount;
        public final int ImageSize;
        public final int ImageOffset;

        public IconInfo(final byte width, final byte height,
                final byte colorCount, final byte reserved, final int planes,
                final int bitCount, final int imageSize, final int imageOffset)
        {
            Width = width;
            Height = height;
            ColorCount = colorCount;
            Reserved = reserved;
            Planes = planes;
            BitCount = bitCount;
            ImageSize = imageSize;
            ImageOffset = imageOffset;
        }

        public void dump(PrintWriter pw)
        {
            pw.println("IconInfo");
            pw.println("Width: " + Width);
            pw.println("Height: " + Height);
            pw.println("ColorCount: " + ColorCount);
            pw.println("Reserved: " + Reserved);
            pw.println("Planes: " + Planes);
            pw.println("BitCount: " + BitCount);
            pw.println("ImageSize: " + ImageSize);
            pw.println("ImageOffset: " + ImageOffset);
        }
    }

    private IconInfo readIconInfo(InputStream is) throws ImageReadException,
            IOException
    {
        byte Width = readByte("Width", is, "Not a Valid ICO File"); // Width (1 byte), Width of Icon (1 to 255)
        byte Height = readByte("Height", is, "Not a Valid ICO File"); // Height (1 byte), Height of Icon (1 to 255)
        byte ColorCount = readByte("ColorCount", is, "Not a Valid ICO File"); // ColorCount (1 byte), Number of colors, either 0 for 24 bit or higher, 2 for monochrome or 16 for 16 color images.
        byte Reserved = readByte("Reserved", is, "Not a Valid ICO File"); // Reserved (1 byte), Not used (always 0)
        int Planes = read2Bytes("Planes", is, "Not a Valid ICO File"); // Planes (2 bytes), always 1
        int BitCount = read2Bytes("BitCount", is, "Not a Valid ICO File"); // BitCount (2 bytes), number of bits per pixel (1 for monochrome, 4 for 16 colors, 8 for 256 colors, 24 for true colors, 32 for true colors + alpha channel)
        int ImageSize = read4Bytes("ImageSize", is, "Not a Valid ICO File"); // ImageSize (4 bytes), Length of resource in bytes
        int ImageOffset = read4Bytes("ImageOffset", is, "Not a Valid ICO File"); // ImageOffset (4 bytes), start of the image in the file.

        return new IconInfo(Width, Height, ColorCount, Reserved, Planes,
                BitCount, ImageSize, ImageOffset);
    }

    private static class BitmapHeader
    {
        public final int Size;
        public final int Width;
        public final int Height;
        public final int Planes;
        public final int BitCount;
        public final int Compression;
        public final int SizeImage;
        public final int XPelsPerMeter;
        public final int YPelsPerMeter;
        public final int ColorsUsed;
        public final int ColorsImportant;

        public BitmapHeader(final int size, final int width, final int height,
                final int planes, final int bitCount, final int compression,
                final int sizeImage, final int pelsPerMeter,
                final int pelsPerMeter2, final int colorsUsed,
                final int colorsImportant)
        {
            Size = size;
            Width = width;
            Height = height;
            Planes = planes;
            BitCount = bitCount;
            Compression = compression;
            SizeImage = sizeImage;
            XPelsPerMeter = pelsPerMeter;
            YPelsPerMeter = pelsPerMeter2;
            ColorsUsed = colorsUsed;
            ColorsImportant = colorsImportant;
        }

        public void dump(PrintWriter pw)
        {
            pw.println("BitmapHeader");

            pw.println("Size: " + Size);
            pw.println("Width: " + Width);
            pw.println("Height: " + Height);
            pw.println("Planes: " + Planes);
            pw.println("BitCount: " + BitCount);
            pw.println("Compression: " + Compression);
            pw.println("SizeImage: " + SizeImage);
            pw.println("XPelsPerMeter: " + XPelsPerMeter);
            pw.println("YPelsPerMeter: " + YPelsPerMeter);
            pw.println("ColorsUsed: " + ColorsUsed);
            pw.println("ColorsImportant: " + ColorsImportant);
        }
    }

    private static abstract class IconData
    {
        public final IconInfo iconInfo;

        public IconData(final IconInfo iconInfo)
        {
            this.iconInfo = iconInfo;
        }

        public void dump(PrintWriter pw)
        {
            iconInfo.dump(pw);
            pw.println();
            dumpSubclass(pw);
        }

        protected abstract void dumpSubclass(PrintWriter pw);
        public abstract BufferedImage readBufferedImage() throws ImageReadException;
    }

    private static class BitmapIconData extends IconData
    {
        public final BitmapHeader header;
        public final BufferedImage bufferedImage;

        public BitmapIconData(final IconInfo iconInfo, final BitmapHeader header,
                final BufferedImage bufferedImage)
        {
            super(iconInfo);
            this.header = header;
            this.bufferedImage = bufferedImage;
        }

        @Override
        public BufferedImage readBufferedImage() throws ImageReadException
        {
            return bufferedImage;
        }

        @Override
        protected void dumpSubclass(PrintWriter pw)
        {
            pw.println("BitmapIconData");
            header.dump(pw);
            pw.println();
        }
    }

    private static class PNGIconData extends IconData
    {
        public final BufferedImage bufferedImage;

        public PNGIconData(final IconInfo iconInfo, final BufferedImage bufferedImage)
        {
            super(iconInfo);
            this.bufferedImage = bufferedImage;
        }

        @Override
        public BufferedImage readBufferedImage()
        {
            return bufferedImage;
        }

        @Override
        protected void dumpSubclass(PrintWriter pw)
        {
            pw.println("PNGIconData");
            pw.println();
        }
    }

    private IconData readBitmapIconData(byte[] iconData, IconInfo fIconInfo) throws ImageReadException, IOException
    {
        ByteArrayInputStream is = new ByteArrayInputStream(iconData);
        int Size = read4Bytes("Size", is, "Not a Valid ICO File"); // Size (4 bytes), size of this structure (always 40)
        int Width = read4Bytes("Width", is, "Not a Valid ICO File"); // Width (4 bytes), width of the image (same as iconinfo.width)
        int Height = read4Bytes("Height", is, "Not a Valid ICO File"); // Height (4 bytes), scanlines in the color map + transparent map (iconinfo.height * 2)
        int Planes = read2Bytes("Planes", is, "Not a Valid ICO File"); // Planes (2 bytes), always 1
        int BitCount = read2Bytes("BitCount", is, "Not a Valid ICO File"); // BitCount (2 bytes), 1,4,8,16,24,32 (see iconinfo for details)
        int Compression = read4Bytes("Compression", is, "Not a Valid ICO File"); // Compression (4 bytes), we don?t use this (0)
        int SizeImage = read4Bytes("SizeImage", is, "Not a Valid ICO File"); // SizeImage (4 bytes), we don?t use this (0)
        int XPelsPerMeter = read4Bytes("XPelsPerMeter", is,
                "Not a Valid ICO File"); // XPelsPerMeter (4 bytes), we don?t use this (0)
        int YPelsPerMeter = read4Bytes("YPelsPerMeter", is,
                "Not a Valid ICO File"); // YPelsPerMeter (4 bytes), we don?t use this (0)
        int ColorsUsed = read4Bytes("ColorsUsed", is, "Not a Valid ICO File"); // ColorsUsed (4 bytes), we don?t use this (0)
        int ColorsImportant = read4Bytes("ColorsImportant", is,
                "Not a Valid ICO File"); // ColorsImportant (4 bytes), we don?t use this (0)
        int RedMask = 0;
        int GreenMask = 0;
        int BlueMask = 0;
        int AlphaMask = 0;
        if (Compression == 3)
        {
            RedMask = read4Bytes("RedMask", is, "Not a Valid ICO File");
            GreenMask = read4Bytes("GreenMask", is, "Not a Valid ICO File");
            BlueMask = read4Bytes("BlueMask", is, "Not a Valid ICO File");
        }
        byte[] RestOfFile = readByteArray("RestOfFile", is.available(), is);

        if (Size != 40)
            throw new ImageReadException("Not a Valid ICO File: Wrong bitmap header size " + Size);
        if (Planes != 1)
            throw new ImageReadException("Not a Valid ICO File: Planes can't be " + Planes);

        if (Compression == 0 && BitCount == 32)
        {
            // 32 BPP RGB icons need an alpha channel, but BMP files don't have
            // one unless BI_BITFIELDS is used...
            Compression = 3;
            RedMask = 0x00ff0000;
            GreenMask = 0x0000ff00;
            BlueMask = 0x000000ff;
            AlphaMask = 0xff000000;
        }

        BitmapHeader header = new BitmapHeader(Size, Width, Height, Planes,
                BitCount, Compression, SizeImage, XPelsPerMeter, YPelsPerMeter,
                ColorsUsed, ColorsImportant);

        int bitmapPixelsOffset = 14 + 56 +
                4 * ((ColorsUsed == 0 && BitCount <= 8) ? (1 << BitCount) : ColorsUsed);
        int bitmapSize = 14 + 56 + RestOfFile.length;

        ByteArrayOutputStream baos = new ByteArrayOutputStream(bitmapSize);
        BinaryOutputStream bos = new BinaryOutputStream(baos,
                BinaryOutputStream.BYTE_ORDER_LITTLE_ENDIAN);

        bos.write('B');
        bos.write('M');
        bos.write4Bytes(bitmapSize);
        bos.write4Bytes(0);
        bos.write4Bytes(bitmapPixelsOffset);

        bos.write4Bytes(56);
        bos.write4Bytes(Width);
        bos.write4Bytes(Height / 2);
        bos.write2Bytes(Planes);
        bos.write2Bytes(BitCount);
        bos.write4Bytes(Compression);
        bos.write4Bytes(SizeImage);
        bos.write4Bytes(XPelsPerMeter);
        bos.write4Bytes(YPelsPerMeter);
        bos.write4Bytes(ColorsUsed);
        bos.write4Bytes(ColorsImportant);
        bos.write4Bytes(RedMask);
        bos.write4Bytes(GreenMask);
        bos.write4Bytes(BlueMask);
        bos.write4Bytes(AlphaMask);
        bos.write(RestOfFile);
        bos.flush();

        ByteArrayInputStream bmpInputStream = new ByteArrayInputStream(baos.toByteArray());
        BufferedImage bmpImage = new BmpImageParser().getBufferedImage(bmpInputStream, null);

        // Transparency map is optional with 32 BPP icons, because they already have
        // an alpha channel, and Windows only uses the transparency map when it has to
        // display the icon on a < 32 BPP screen. But it's still used instead of alpha
        // if the image would be completely transparent with alpha...
        int t_scanline_size = (Width + 7) / 8;
        if ((t_scanline_size % 4) != 0)
            t_scanline_size += 4 - (t_scanline_size % 4); // pad scanline to 4 byte size.
        int tcolor_map_size_bytes = t_scanline_size * (Height/2);
        byte[] transparency_map = null;
        try
        {
            transparency_map = this.readByteArray("transparency_map",
                    tcolor_map_size_bytes, bmpInputStream, "Not a Valid ICO File");
        }
        catch (IOException ioEx)
        {
            if (BitCount != 32)
            throw ioEx;
        }

        boolean allAlphasZero = true;
        if (BitCount == 32)
        {
            for (int y = 0; allAlphasZero && y < bmpImage.getHeight(); y++)
            {
                for (int x = 0; x < bmpImage.getWidth(); x++)
                {
                    if ((bmpImage.getRGB(x, y) & 0xff000000) != 0)
                    {
                        allAlphasZero = false;
                        break;
                    }
                }
            }
        }
        BufferedImage resultImage;
        if (allAlphasZero)
        {
            resultImage = new BufferedImage(bmpImage.getWidth(), bmpImage.getHeight(),
                    BufferedImage.TYPE_INT_ARGB);
            for (int y = 0; y < resultImage.getHeight(); y++)
            {
                for (int x = 0; x < resultImage.getWidth(); x++)
                {
                    int alpha = 0xff;
                    if (transparency_map != null)
                    {
                        int alpha_byte = 0xff & transparency_map[t_scanline_size
                                * (bmpImage.getHeight() - y - 1) + (x / 8)];
                        alpha = 0x01 & (alpha_byte >> (7 - (x % 8)));
                        alpha = (alpha == 0) ? 0xff : 0x00;
                    }
                    resultImage.setRGB(x, y, (alpha << 24) | (0xffffff & bmpImage.getRGB(x, y)));
                }
            }
        }
        else
            resultImage = bmpImage;
        return new BitmapIconData(fIconInfo, header, resultImage);
    }

    private IconData readIconData(byte[] iconData, IconInfo fIconInfo)
            throws ImageReadException, IOException
    {
        ImageFormat imageFormat = Sanselan.guessFormat(iconData);
        if (imageFormat.equals(ImageFormat.IMAGE_FORMAT_PNG))
        {
            BufferedImage bufferedImage = Sanselan.getBufferedImage(iconData);
            PNGIconData pngIconData = new PNGIconData(fIconInfo, bufferedImage);
            return pngIconData;
        }
        else
        {
            return readBitmapIconData(iconData, fIconInfo);
        }
    }

    private static class ImageContents
    {
        public final FileHeader fileHeader;
        public final IconData iconDatas[];

        public ImageContents(final FileHeader fileHeader,
                final IconData[] iconDatas)
        {
            super();
            this.fileHeader = fileHeader;
            this.iconDatas = iconDatas;
        }
    }

    private ImageContents readImage(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        InputStream is = null;
        try
        {
            is = byteSource.getInputStream();
            FileHeader fileHeader = readFileHeader(is);

            IconInfo fIconInfos[] = new IconInfo[fileHeader.iconCount];
            for (int i = 0; i < fileHeader.iconCount; i++)
            {
                fIconInfos[i] = readIconInfo(is);
            }

            IconData fIconDatas[] = new IconData[fileHeader.iconCount];
            for (int i = 0; i < fileHeader.iconCount; i++)
            {
                byte[] iconData = byteSource.getBlock(fIconInfos[i].ImageOffset,
                        fIconInfos[i].ImageSize);
                fIconDatas[i] = readIconData(iconData, fIconInfos[i]);
            }

            return new ImageContents(fileHeader, fIconDatas);
        }
        finally
        {
            try
            {
                if (is != null) {
                    is.close();
                }
            }
            catch (Exception e)
            {
                Debug.debug(e);
            }

        }
    }

    @Override
    public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
            throws ImageReadException, IOException
    {
        ImageContents contents = readImage(byteSource);
        contents.fileHeader.dump(pw);
        for (int i = 0; i < contents.iconDatas.length; i++)
            contents.iconDatas[i].dump(pw);
        return true;
    }

    @Override
    public final BufferedImage getBufferedImage(ByteSource byteSource,
            Map params) throws ImageReadException, IOException
    {
        ImageContents contents = readImage(byteSource);
        FileHeader fileHeader = contents.fileHeader;
        if (fileHeader.iconCount > 0)
            return contents.iconDatas[0].readBufferedImage();
        else
            throw new ImageReadException("No icons in ICO file");
    }

    @Override
    public List<BufferedImage> getAllBufferedImages(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        List<BufferedImage> result = new ArrayList<BufferedImage>();
        ImageContents contents = readImage(byteSource);

        FileHeader fileHeader = contents.fileHeader;
        for (int i = 0; i < fileHeader.iconCount; i++)
        {
            IconData iconData = contents.iconDatas[i];

            BufferedImage image = iconData.readBufferedImage();

            result.add(image);
        }

        return result;
    }

    //    public boolean extractImages(ByteSource byteSource, File dst_dir,
    //            String dst_root, ImageParser encoder) throws ImageReadException,
    //            IOException, ImageWriteException
    //    {
    //        ImageContents contents = readImage(byteSource);
    //
    //        FileHeader fileHeader = contents.fileHeader;
    //        for (int i = 0; i < fileHeader.iconCount; i++)
    //        {
    //            IconData iconData = contents.iconDatas[i];
    //
    //            BufferedImage image = readBufferedImage(iconData);
    //
    //            int size = Math.max(iconData.iconInfo.Width,
    //                    iconData.iconInfo.Height);
    //            File file = new File(dst_dir, dst_root + "_" + size + "_"
    //                    + iconData.iconInfo.BitCount
    //                    + encoder.getDefaultExtension());
    //            encoder.writeImage(image, new FileOutputStream(file), null);
    //        }
    //
    //        return true;
    //    }

    @Override
    public void writeImage(BufferedImage src, OutputStream os, Map params)
            throws ImageWriteException, IOException
    {
        // make copy of params; we'll clear keys as we consume them.
        params = (params == null) ? new HashMap() : new HashMap(params);

        // clear format key.
        if (params.containsKey(PARAM_KEY_FORMAT))
            params.remove(PARAM_KEY_FORMAT);

        if (params.size() > 0)
        {
            Object firstKey = params.keySet().iterator().next();
            throw new ImageWriteException("Unknown parameter: " + firstKey);
        }

        final PaletteFactory paletteFactory = new PaletteFactory();
        final SimplePalette palette = paletteFactory.makePaletteSimple(src, 256);
        final int bitCount;
        final boolean hasTransparency = paletteFactory.hasTransparency(src);
        if (palette == null)
        {
            if (hasTransparency)
                bitCount = 32;
            else
                bitCount = 24;
        }
        else if (palette.length() <= 2)
            bitCount = 1;
        else if (palette.length() <= 16)
            bitCount = 4;
        else
            bitCount = 8;

        BinaryOutputStream bos = new BinaryOutputStream(os, BYTE_ORDER_INTEL);

        int scanline_size = (bitCount * src.getWidth() + 7) / 8;
        if ((scanline_size % 4) != 0)
            scanline_size += 4 - (scanline_size % 4); // pad scanline to 4 byte size.
        int t_scanline_size = (src.getWidth() + 7) / 8;
        if ((t_scanline_size % 4) != 0)
            t_scanline_size += 4 - (t_scanline_size % 4); // pad scanline to 4 byte size.
        int imageSize = 40 + 4 * (bitCount <= 8 ? (1 << bitCount) : 0) +
                src.getHeight() * scanline_size +
                src.getHeight() * t_scanline_size;

        // ICONDIR
        bos.write2Bytes(0); // reserved
        bos.write2Bytes(1); // 1=ICO, 2=CUR
        bos.write2Bytes(1); // count

        // ICONDIRENTRY
        int iconDirEntryWidth = src.getWidth();
        int iconDirEntryHeight = src.getHeight();
        if (iconDirEntryWidth > 255 || iconDirEntryHeight > 255)
        {
            iconDirEntryWidth = 0;
            iconDirEntryHeight = 0;
        }
        bos.write(iconDirEntryWidth);
        bos.write(iconDirEntryHeight);
        bos.write((bitCount >= 8) ? 0 : (1 << bitCount));
        bos.write(0); // reserved
        bos.write2Bytes(1); // color planes
        bos.write2Bytes(bitCount);
        bos.write4Bytes(imageSize);
        bos.write4Bytes(22); // image offset

        // BITMAPINFOHEADER
        bos.write4Bytes(40); // size
        bos.write4Bytes(src.getWidth());
        bos.write4Bytes(2 * src.getHeight());
        bos.write2Bytes(1); // planes
        bos.write2Bytes(bitCount);
        bos.write4Bytes(0); // compression
        bos.write4Bytes(0); // image size
        bos.write4Bytes(0); // x pixels per meter
        bos.write4Bytes(0); // y pixels per meter
        bos.write4Bytes(0); // colors used, 0 = (1 << bitCount) (ignored)
        bos.write4Bytes(0); // colors important

        if (palette != null)
        {
            for (int i = 0; i < (1 << bitCount); i++)
            {
                if (i < palette.length())
                {
                    int argb = palette.getEntry(i);
                    bos.write(0xff & argb);
                    bos.write(0xff & (argb >> 8));
                    bos.write(0xff & (argb >> 16));
                    bos.write(0);
                }
                else
                {
                    bos.write(0);
                    bos.write(0);
                    bos.write(0);
                    bos.write(0);
                }
            }
        }

        int bit_cache = 0;
        int bits_in_cache = 0;
        int row_padding = scanline_size - (bitCount * src.getWidth() + 7) / 8;
        for (int y = src.getHeight() - 1; y >= 0; y--)
        {
            for (int x = 0; x < src.getWidth(); x++)
            {
                int argb = src.getRGB(x, y);
                if (bitCount < 8)
                {
                    int rgb = 0xffffff & argb;
                    int index = palette.getPaletteIndex(rgb);
                    bit_cache <<= bitCount;
                    bit_cache |= index;
                    bits_in_cache += bitCount;
                    if (bits_in_cache >= 8)
                    {
                        bos.write(0xff & bit_cache);
                        bit_cache = 0;
                        bits_in_cache = 0;
                    }
                }
                else if (bitCount == 8)
                {
                    int rgb = 0xffffff & argb;
                    int index = palette.getPaletteIndex(rgb);
                    bos.write(0xff & index);
                }
                else if (bitCount == 24)
                {
                    bos.write(0xff & argb);
                    bos.write(0xff & (argb >> 8));
                    bos.write(0xff & (argb >> 16));
                }
                else if (bitCount == 32)
                {
                    bos.write(0xff & argb);
                    bos.write(0xff & (argb >> 8));
                    bos.write(0xff & (argb >> 16));
                    bos.write(0xff & (argb >> 24));
                }
            }

            if (bits_in_cache > 0)
            {
                bit_cache <<= (8 - bits_in_cache);
                bos.write(0xff & bit_cache);
                bit_cache = 0;
                bits_in_cache = 0;
            }

            for (int x = 0; x < row_padding; x++)
                bos.write(0);
        }

        int t_row_padding = t_scanline_size - (src.getWidth() + 7) / 8;
        for (int y = src.getHeight() - 1; y >= 0; y--)
        {
            for (int x = 0; x < src.getWidth(); x++)
            {
                int argb = src.getRGB(x, y);
                int alpha = 0xff & (argb >> 24);
                bit_cache <<= 1;
                if (alpha == 0)
                    bit_cache |= 1;
                bits_in_cache++;
                if (bits_in_cache >= 8)
                {
                    bos.write(0xff & bit_cache);
                    bit_cache = 0;
                    bits_in_cache = 0;
                }
            }

            if (bits_in_cache > 0)
            {
                bit_cache <<= (8 - bits_in_cache);
                bos.write(0xff & bit_cache);
                bit_cache = 0;
                bits_in_cache = 0;
            }

            for (int x = 0; x < t_row_padding; x++)
                bos.write(0);
        }
    }

    /**
     * Extracts embedded XML metadata as XML string.
     * <p>
     *
     * @param byteSource
     *            File containing image data.
     * @param params
     *            Map of optional parameters, defined in SanselanConstants.
     * @return Xmp Xml as String, if present.  Otherwise, returns null.
     */
    @Override
    public String getXmpXml(ByteSource byteSource, Map params)
            throws ImageReadException, IOException {
        return null;
    }
}
