/*
 * 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.ImageFormats;
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.Imaging;
import org.apache.commons.imaging.PixelDensity;
import org.apache.commons.imaging.common.BinaryOutputStream;
import org.apache.commons.imaging.common.ByteOrder;
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.IoUtils;

public class IcoImageParser extends ImageParser {

    public IcoImageParser() {
        super.setByteOrder(ByteOrder.LITTLE_ENDIAN);
    }

    @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[] { ImageFormats.ICO, //
        };
    }

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

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

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

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

    @Override
    public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String,Object> 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(final PrintWriter pw) {
            pw.println("FileHeader");
            pw.println("Reserved: " + reserved);
            pw.println("IconType: " + iconType);
            pw.println("IconCount: " + iconCount);
            pw.println();
        }
    }

    private FileHeader readFileHeader(final InputStream is)
            throws ImageReadException, IOException {
        final int Reserved = read2Bytes("Reserved", is, "Not a Valid ICO File");
        final int IconType = read2Bytes("IconType", is, "Not a Valid ICO File");
        final 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(final 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(final InputStream is) throws IOException {
        // Width (1 byte), Width of Icon (1 to 255)
        final byte Width = readByte("Width", is, "Not a Valid ICO File");
        // Height (1 byte), Height of Icon (1 to 255)
        final byte Height = readByte("Height", 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.
        final byte ColorCount = readByte("ColorCount", is, "Not a Valid ICO File");
        // Reserved (1 byte), Not used (always 0)
        final byte Reserved = readByte("Reserved", is, "Not a Valid ICO File");
        // Planes (2 bytes), always 1
        final int Planes = read2Bytes("Planes", is, "Not a Valid ICO File");
        // BitCount (2 bytes), number of bits per pixel (1 for monchrome,
        // 4 for 16 colors, 8 for 256 colors, 24 for true colors,
        // 32 for true colors + alpha channel)
        final int BitCount = read2Bytes("BitCount", is, "Not a Valid ICO File");
        // ImageSize (4 bytes), Length of resource in bytes
        final int ImageSize = read4Bytes("ImageSize", is, "Not a Valid ICO File");
        // ImageOffset (4 bytes), start of the image in the file
        final int ImageOffset = read4Bytes("ImageOffset", is, "Not a Valid ICO 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(final 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(final 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(final 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(final PrintWriter pw) {
            pw.println("PNGIconData");
            pw.println();
        }
    }

    private IconData readBitmapIconData(final byte[] iconData, final IconInfo fIconInfo)
            throws ImageReadException, IOException {
        final ByteArrayInputStream is = new ByteArrayInputStream(iconData);
        final int Size = read4Bytes("Size", is, "Not a Valid ICO File"); // Size (4
                                                                   // bytes),
                                                                   // size of
                                                                   // this
                                                                   // structure
                                                                   // (always
                                                                   // 40)
        final int Width = read4Bytes("Width", is, "Not a Valid ICO File"); // Width (4
                                                                     // bytes),
                                                                     // width of
                                                                     // the
                                                                     // image
                                                                     // (same as
                                                                     // iconinfo.width)
        final int Height = read4Bytes("Height", is, "Not a Valid ICO File"); // Height
                                                                       // (4
                                                                       // bytes),
                                                                       // scanlines
                                                                       // in the
                                                                       // color
                                                                       // map +
                                                                       // transparent
                                                                       // map
                                                                       // (iconinfo.height
                                                                       // * 2)
        final int Planes = read2Bytes("Planes", is, "Not a Valid ICO File"); // Planes
                                                                       // (2
                                                                       // bytes),
                                                                       // always
                                                                       // 1
        final 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)
        final int SizeImage = read4Bytes("SizeImage", is, "Not a Valid ICO File"); // SizeImage
                                                                             // (4
                                                                             // bytes),
                                                                             // we
                                                                             // don?t
                                                                             // use
                                                                             // this
                                                                             // (0)
        final int XPelsPerMeter = read4Bytes("XPelsPerMeter", is,
                "Not a Valid ICO File"); // XPelsPerMeter (4 bytes), we don?t
                                         // use this (0)
        final int YPelsPerMeter = read4Bytes("YPelsPerMeter", is,
                "Not a Valid ICO File"); // YPelsPerMeter (4 bytes), we don?t
                                         // use this (0)
        final int ColorsUsed = read4Bytes("ColorsUsed", is, "Not a Valid ICO File"); // ColorsUsed
                                                                               // (4
                                                                               // bytes),
                                                                               // we
                                                                               // don?t
                                                                               // use
                                                                               // this
                                                                               // (0)
        final 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");
        }
        final byte[] RestOfFile = readBytes("RestOfFile", is, is.available());

        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;
        }

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

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

        final ByteArrayOutputStream baos = new ByteArrayOutputStream(bitmapSize);
        BinaryOutputStream bos = null;
        boolean canThrow = false;
        try {
            bos = new BinaryOutputStream(baos,
                    ByteOrder.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();
            canThrow = true;
        } finally {
            IoUtils.closeQuietly(canThrow, bos);
        }

        final ByteArrayInputStream bmpInputStream = new ByteArrayInputStream(
                baos.toByteArray());
        final 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.
        }
        final int tcolor_map_size_bytes = t_scanline_size * (Height / 2);
        byte[] transparency_map = null;
        try {
            transparency_map = this.readBytes("transparency_map",
                    bmpInputStream, tcolor_map_size_bytes,
                    "Not a Valid ICO File");
        } catch (final 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) {
                        final 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(final byte[] iconData, final IconInfo fIconInfo)
            throws ImageReadException, IOException {
        final ImageFormat imageFormat = Imaging.guessFormat(iconData);
        if (imageFormat.equals(ImageFormats.PNG)) {
            final BufferedImage bufferedImage = Imaging.getBufferedImage(iconData);
            final 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(final ByteSource byteSource)
            throws ImageReadException, IOException {
        InputStream is = null;
        boolean canThrow = false;
        try {
            is = byteSource.getInputStream();
            final FileHeader fileHeader = readFileHeader(is);

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

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

            final ImageContents ret = new ImageContents(fileHeader, fIconDatas);
            canThrow = true;
            return ret;
        } finally {
            IoUtils.closeQuietly(canThrow, is);
        }
    }

    @Override
    public boolean dumpImageFile(final PrintWriter pw, final ByteSource byteSource)
            throws ImageReadException, IOException {
        final ImageContents contents = readImage(byteSource);
        contents.fileHeader.dump(pw);
        for (final IconData iconData : contents.iconDatas) {
            iconData.dump(pw);
        }
        return true;
    }

    @Override
    public final BufferedImage getBufferedImage(final ByteSource byteSource,
            final Map<String,Object> params) throws ImageReadException, IOException {
        final ImageContents contents = readImage(byteSource);
        final 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(final ByteSource byteSource)
            throws ImageReadException, IOException {
        final List<BufferedImage> result = new ArrayList<BufferedImage>();
        final ImageContents contents = readImage(byteSource);

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

            final 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(final BufferedImage src, final OutputStream os, Map<String,Object> params)
            throws ImageWriteException, IOException {
        // make copy of params; we'll clear keys as we consume them.
        params = (params == null) ? new HashMap<String,Object>() : new HashMap<String,Object>(params);

        // clear format key.
        if (params.containsKey(PARAM_KEY_FORMAT)) {
            params.remove(PARAM_KEY_FORMAT);
        }
        
        final PixelDensity pixelDensity = (PixelDensity) params.remove(PARAM_KEY_PIXEL_DENSITY);

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

        final PaletteFactory paletteFactory = new PaletteFactory();
        final SimplePalette palette = paletteFactory
                .makeExactRgbPaletteSimple(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;
        }

        final BinaryOutputStream bos = new BinaryOutputStream(os, ByteOrder.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.
        }
        final 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(pixelDensity == null ? 0 : (int)Math.round(pixelDensity.horizontalDensityMetres())); // x pixels per meter
        bos.write4Bytes(pixelDensity == null ? 0 : (int)Math.round(pixelDensity.horizontalDensityMetres())); // 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()) {
                    final 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;
        final 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++) {
                final int argb = src.getRGB(x, y);
                if (bitCount < 8) {
                    final int rgb = 0xffffff & argb;
                    final 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) {
                    final int rgb = 0xffffff & argb;
                    final 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);
            }
        }

        final 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++) {
                final int argb = src.getRGB(x, y);
                final 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 ImagingConstants.
     * @return Xmp Xml as String, if present. Otherwise, returns null.
     */
    @Override
    public String getXmpXml(final ByteSource byteSource, final Map<String,Object> params)
            throws ImageReadException, IOException {
        return null;
    }
}
