/*
 * kimgio import filter for MS Windows .ico files
 *
 * Distributed under the terms of the LGPL
 * Copyright (c) 2000 Malte Starostik <malte@kde.org>
 *
 */

#include "ICOHandler.h"

#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>

#include <QtGui/QImage>
#include <QtGui/QBitmap>
#include <QtGui/QApplication>
#include <QtCore/QVector>
#include <QtGui/QDesktopWidget>

namespace
{
    // Global header (see http://www.daubnet.com/formats/ICO.html)
    struct IcoHeader
    {
        enum Type { Icon = 1, Cursor };
        quint16 reserved;
        quint16 type;
        quint16 count;
    };

    inline QDataStream& operator >>( QDataStream& s, IcoHeader& h )
    {
        return s >> h.reserved >> h.type >> h.count;
    }

    // Based on qt_read_dib et al. from qimage.cpp
    // (c) 1992-2002 Trolltech AS.
    struct BMP_INFOHDR
    {
        static const quint32 Size = 40;
        quint32  biSize;                // size of this struct
        quint32  biWidth;               // pixmap width
        quint32  biHeight;              // pixmap height
        quint16  biPlanes;              // should be 1
        quint16  biBitCount;            // number of bits per pixel
        enum Compression { RGB = 0 };
        quint32  biCompression;         // compression method
        quint32  biSizeImage;           // size of image
        quint32  biXPelsPerMeter;       // horizontal resolution
        quint32  biYPelsPerMeter;       // vertical resolution
        quint32  biClrUsed;             // number of colors used
        quint32  biClrImportant;        // number of important colors
    };
    const quint32 BMP_INFOHDR::Size;

    QDataStream& operator >>( QDataStream &s, BMP_INFOHDR &bi )
    {
        s >> bi.biSize;
        if ( bi.biSize == BMP_INFOHDR::Size )
        {
            s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
            s >> bi.biCompression >> bi.biSizeImage;
            s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
            s >> bi.biClrUsed >> bi.biClrImportant;
        }
        return s;
    }

#if 0
    QDataStream &operator<<( QDataStream &s, const BMP_INFOHDR &bi )
    {
        s << bi.biSize;
        s << bi.biWidth << bi.biHeight;
        s << bi.biPlanes;
        s << bi.biBitCount;
        s << bi.biCompression;
        s << bi.biSizeImage;
        s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
        s << bi.biClrUsed << bi.biClrImportant;
        return s;
    }
#endif

    // Header for every icon in the file
    struct IconRec
    {
        unsigned char width;
        unsigned char height;
        quint16 colors;
        quint16 hotspotX;
        quint16 hotspotY;
        quint32 size;
        quint32 offset;
    };

    inline QDataStream& operator >>( QDataStream& s, IconRec& r )
    {
        return s >> r.width >> r.height >> r.colors
                 >> r.hotspotX >> r.hotspotY >> r.size >> r.offset;
    }

    struct LessDifference
    {
        LessDifference( unsigned s, unsigned c )
            : size( s ), colors( c ) {}

        bool operator ()( const IconRec& lhs, const IconRec& rhs ) const
        {
            // closest size match precedes everything else
            if ( std::abs( int( lhs.width - size ) ) <
                 std::abs( int( rhs.width - size ) ) ) return true;
            else if ( std::abs( int( lhs.width - size ) ) >
                 std::abs( int( rhs.width - size ) ) ) return false;
            else if ( colors == 0 )
            {
                // high/true color requested
                if ( lhs.colors == 0 ) return true;
                else if ( rhs.colors == 0 ) return false;
                else return lhs.colors > rhs.colors;
            }
            else
            {
                // indexed icon requested
                if ( lhs.colors == 0 && rhs.colors == 0 ) return false;
                else if ( lhs.colors == 0 ) return false;
                else return std::abs( int( lhs.colors - colors ) ) <
                            std::abs( int( rhs.colors - colors ) );
            }
        }
        unsigned size;
        unsigned colors;
    };

    bool loadFromDIB( QDataStream& stream, const IconRec& rec, QImage& icon )
    {
        BMP_INFOHDR header;
        stream >> header;
        if ( stream.atEnd() || header.biSize != BMP_INFOHDR::Size ||
             header.biSize > rec.size ||
             header.biCompression != BMP_INFOHDR::RGB ||
             ( header.biBitCount != 1 && header.biBitCount != 4 &&
               header.biBitCount != 8 && header.biBitCount != 24 &&
               header.biBitCount != 32 ) ) return false;

        unsigned paletteSize, paletteEntries;

        if (header.biBitCount > 8)
        {
            paletteEntries = 0;
            paletteSize    = 0;
        }
        else
        {
            paletteSize    = (1 << header.biBitCount);
            paletteEntries = paletteSize;
            if (header.biClrUsed && header.biClrUsed < paletteSize)
                paletteEntries = header.biClrUsed;
        }

        // Always create a 32-bit image to get the mask right
        // Note: this is safe as rec.width, rec.height are bytes
        icon = QImage( rec.width, rec.height, QImage::Format_ARGB32 );
        if ( icon.isNull() ) return false;

        QVector< QRgb > colorTable( paletteSize );

        colorTable.fill( QRgb( 0 ) );
        for ( unsigned i = 0; i < paletteEntries; ++i )
        {
            unsigned char rgb[ 4 ];
            stream.readRawData( reinterpret_cast< char* >( &rgb ),
                                 sizeof( rgb ) );
            colorTable[ i ] = qRgb( rgb[ 2 ], rgb[ 1 ], rgb[ 0 ] );
        }

        unsigned bpl = ( rec.width * header.biBitCount + 31 ) / 32 * 4;

        unsigned char* buf = new unsigned char[ bpl ];
        for ( unsigned y = rec.height; !stream.atEnd() && y--; )
        {
            stream.readRawData( reinterpret_cast< char* >( buf ), bpl );
            unsigned char* pixel = buf;
            QRgb* p = reinterpret_cast< QRgb* >( icon.scanLine( y ) );
            switch ( header.biBitCount )
            {
                case 1:
                    for ( unsigned x = 0; x < rec.width; ++x )
                        *p++ = colorTable[
                            ( pixel[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ];
                    break;
                case 4:
                    for ( unsigned x = 0; x < rec.width; ++x )
                        if ( x & 1 ) *p++ = colorTable[ pixel[ x / 2 ] & 0x0f ];
                        else *p++ = colorTable[ pixel[ x / 2 ] >> 4 ];
                    break;
                case 8:
                    for ( unsigned x = 0; x < rec.width; ++x )
                        *p++ = colorTable[ pixel[ x ] ];
                    break;
                case 24:
                    for ( unsigned x = 0; x < rec.width; ++x )
                        *p++ = qRgb( pixel[ 3 * x + 2 ],
                                     pixel[ 3 * x + 1 ],
                                     pixel[ 3 * x ] );
                    break;
                case 32:
                    for ( unsigned x = 0; x < rec.width; ++x )
                        *p++ = qRgba( pixel[ 4 * x + 2 ],
                                      pixel[ 4 * x + 1 ],
                                      pixel[ 4 * x ],
                                      pixel[ 4 * x  + 3] );
                    break;
            }
        }
        delete[] buf;

        if ( header.biBitCount < 32 )
        {
            // Traditional 1-bit mask
            bpl = ( rec.width + 31 ) / 32 * 4;
            buf = new unsigned char[ bpl ];
            for ( unsigned y = rec.height; y--; )
            {
                stream.readRawData( reinterpret_cast< char* >( buf ), bpl );
                QRgb* p = reinterpret_cast< QRgb* >( icon.scanLine( y ) );
                for ( unsigned x = 0; x < rec.width; ++x, ++p )
                    if ( ( ( buf[ x / 8 ] >> ( 7 - ( x & 0x07 ) ) ) & 1 ) )
                        *p &= RGB_MASK;
            }
            delete[] buf;
        }
        return true;
    }
}

ICOHandler::ICOHandler()
{
}

bool ICOHandler::canRead() const
{
    return canRead(device());
}

bool ICOHandler::read(QImage *outImage)
{

    qint64 offset = device()->pos();

    QDataStream stream( device() );
    stream.setByteOrder( QDataStream::LittleEndian );
    IcoHeader header;
    stream >> header;
    if ( stream.atEnd() || !header.count ||
         ( header.type != IcoHeader::Icon && header.type != IcoHeader::Cursor) )
        return false;

    unsigned requestedSize = 32;
    unsigned requestedColors =  QApplication::desktop()->depth() > 8 ? 0 : QApplication::desktop()->depth();
    int requestedIndex = -1;
#if 0
    if ( io->parameters() )
    {
        QStringList params = QString(io->parameters()).split( ';', QString::SkipEmptyParts );
        QMap< QString, QString > options;
        for ( QStringList::ConstIterator it = params.begin();
              it != params.end(); ++it )
        {
            QStringList tmp = (*it).split( '=', QString::SkipEmptyParts );
            if ( tmp.count() == 2 ) options[ tmp[ 0 ] ] = tmp[ 1 ];
        }
        if ( options[ "index" ].toUInt() )
            requestedIndex = options[ "index" ].toUInt();
        if ( options[ "size" ].toUInt() )
            requestedSize = options[ "size" ].toUInt();
        if ( options[ "colors" ].toUInt() )
            requestedColors = options[ "colors" ].toUInt();
    }
#endif

    typedef std::vector< IconRec > IconList;
    IconList icons;
    for ( unsigned i = 0; i < header.count; ++i )
    {
        if ( stream.atEnd() )
            return false;
        IconRec rec;
        stream >> rec;
        icons.push_back( rec );
    }
    IconList::const_iterator selected;
    if (requestedIndex >= 0) {
        selected = std::min( icons.begin() + requestedIndex, icons.end() );
    } else {
        selected = std::min_element( icons.begin(), icons.end(),
                                     LessDifference( requestedSize, requestedColors ) );
    }
    if ( stream.atEnd() || selected == icons.end() ||
         offset + selected->offset > device()->size() )
        return false;

    device()->seek( offset + selected->offset );
    QImage icon;
    if ( loadFromDIB( stream, *selected, icon ) )
    {
#ifndef QT_NO_IMAGE_TEXT
        icon.setText( "X-Index", 0, QString::number( selected - icons.begin() ) );
        if ( header.type == IcoHeader::Cursor )
        {
            icon.setText( "X-HotspotX", 0, QString::number( selected->hotspotX ) );
            icon.setText( "X-HotspotY", 0, QString::number( selected->hotspotY ) );
        }
#endif
        *outImage = icon;
        return true;
    }
    return false;
}

bool ICOHandler::write(const QImage &/*image*/)
{
#if 0
    if (image.isNull())
        return;

    QByteArray dibData;
    QDataStream dib(dibData, QIODevice::ReadWrite);
    dib.setByteOrder(QDataStream::LittleEndian);

    QImage pixels = image;
    QImage mask;
    if (io->image().hasAlphaBuffer())
        mask = image.createAlphaMask();
    else
        mask = image.createHeuristicMask();
    mask.invertPixels();
    for ( int y = 0; y < pixels.height(); ++y )
        for ( int x = 0; x < pixels.width(); ++x )
            if ( mask.pixel( x, y ) == 0 ) pixels.setPixel( x, y, 0 );

    if (!qt_write_dib(dib, pixels))
        return;

   uint hdrPos = dib.device()->at();
    if (!qt_write_dib(dib, mask))
        return;
    memmove(dibData.data() + hdrPos, dibData.data() + hdrPos + BMP_WIN + 8, dibData.size() - hdrPos - BMP_WIN - 8);
    dibData.resize(dibData.size() - BMP_WIN - 8);

    QDataStream ico(device());
    ico.setByteOrder(QDataStream::LittleEndian);
    IcoHeader hdr;
    hdr.reserved = 0;
    hdr.type = Icon;
    hdr.count = 1;
    ico << hdr.reserved << hdr.type << hdr.count;
    IconRec rec;
    rec.width = image.width();
    rec.height = image.height();
    if (image.numColors() <= 16)
        rec.colors = 16;
    else if (image.depth() <= 8)
        rec.colors = 256;
    else
        rec.colors = 0;
    rec.hotspotX = 0;
    rec.hotspotY = 0;
    rec.dibSize = dibData.size();
    ico << rec.width << rec.height << rec.colors
        << rec.hotspotX << rec.hotspotY << rec.dibSize;
    rec.dibOffset = ico.device()->at() + sizeof(rec.dibOffset);
    ico << rec.dibOffset;

    BMP_INFOHDR dibHeader;
    dib.device()->at(0);
    dib >> dibHeader;
    dibHeader.biHeight = image.height() << 1;
    dib.device()->at(0);
    dib << dibHeader;

    ico.writeRawBytes(dibData.data(), dibData.size());
    return true;
#endif
    return false;
}

QByteArray ICOHandler::name() const
{
    return "ico";
}

bool ICOHandler::canRead(QIODevice *device)
{
    if (!device) {
        qWarning("ICOHandler::canRead() called with no device");
        return false;
    }

    const qint64 oldPos = device->pos();

    char head[8];
    qint64 readBytes = device->read(head, sizeof(head));
    const bool readOk = readBytes == sizeof(head);

    if (device->isSequential()) {
        while (readBytes > 0)
            device->ungetChar(head[readBytes-- - 1]);
    } else {
        device->seek(oldPos);
    }

    if ( !readOk )
        return false;

    return head[2] == '\001' && head[3] == '\000' && // type should be 1
        ( head[6] == 16 || head[6] == 32 || head[6] == 64 ) && // width can only be one of those
        ( head[7] == 16 || head[7] == 32 || head[7] == 64 );   // same for height
}

class ICOPlugin : public QImageIOPlugin
{
public:
    QStringList keys() const;
    Capabilities capabilities(QIODevice *device, const QByteArray &format) const;
    QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const;
};

QStringList ICOPlugin::keys() const
{
    return QStringList() << "ico" << "ICO";
}

QImageIOPlugin::Capabilities ICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const
{
    if (format == "ico" || format == "ICO")
        return Capabilities(CanRead);
    if (!format.isEmpty())
        return 0;
    if (!device->isOpen())
        return 0;

    Capabilities cap;
    if (device->isReadable() && ICOHandler::canRead(device))
        cap |= CanRead;
    return cap;
}

QImageIOHandler *ICOPlugin::create(QIODevice *device, const QByteArray &format) const
{
    QImageIOHandler *handler = new ICOHandler;
    handler->setDevice(device);
    handler->setFormat(format);
    return handler;
}

Q_EXPORT_STATIC_PLUGIN(ICOPlugin)
Q_EXPORT_PLUGIN2(qtwebico, ICOPlugin)
