Ignore:
Timestamp:
Mar 8, 2010, 12:52:58 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.2 sources.

Location:
trunk
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/plugins/imageformats/gif/main.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/gif/qgifhandler.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    7272
    7373    int decode(QImage *image, const uchar* buffer, int length,
    74                int *nextFrameDelay, int *loopCount, QSize *nextSize);
     74               int *nextFrameDelay, int *loopCount);
     75    static void scan(QIODevice *device, QVector<QSize> *imageSizes, int *loopCount);
    7576
    7677    bool newFrame;
     
    230231*/
    231232int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
    232                        int *nextFrameDelay, int *loopCount, QSize *nextSize)
     233                       int *nextFrameDelay, int *loopCount)
    233234{
    234235    // We are required to state that
     
    347348                    bits = image->bits();
    348349                    memset(bits, 0, image->byteCount());
    349 
    350                     // ### size of the upcoming frame, should rather
    351                     // be known before decoding it.
    352                     *nextSize = QSize(swidth, sheight);
    353350                }
    354351
     
    646643}
    647644
     645/*!
     646   Scans through the data stream defined by \a device and returns the image
     647   sizes found in the stream in the \a imageSizes vector.
     648*/
     649void QGIFFormat::scan(QIODevice *device, QVector<QSize> *imageSizes, int *loopCount)
     650{
     651    if (!device)
     652        return;
     653
     654    qint64 oldPos = device->pos();
     655    if (!device->seek(0))
     656        return;
     657
     658    int colorCount = 0;
     659    int localColorCount = 0;
     660    int globalColorCount = 0;
     661    int colorReadCount = 0;
     662    bool localColormap = false;
     663    bool globalColormap = false;
     664    int count = 0;
     665    int blockSize = 0;
     666    int imageWidth = 0;
     667    int imageHeight = 0;
     668    bool done = false;
     669    uchar hold[16];
     670    State state = Header;
     671
     672    const int readBufferSize = 40960; // 40k read buffer
     673    QByteArray readBuffer(device->read(readBufferSize));
     674
     675    if (readBuffer.isEmpty()) {
     676        device->seek(oldPos);
     677        return;
     678    }
     679
     680    // This is a specialized version of the state machine from decode(),
     681    // which doesn't do any image decoding or mallocing, and has an
     682    // optimized way of skipping SkipBlocks, ImageDataBlocks and
     683    // Global/LocalColorMaps.
     684
     685    while (!readBuffer.isEmpty()) {
     686        int length = readBuffer.size();
     687        const uchar *buffer = (const uchar *) readBuffer.constData();
     688        while (!done && length) {
     689            length--;
     690            uchar ch = *buffer++;
     691            switch (state) {
     692            case Header:
     693                hold[count++] = ch;
     694                if (count == 6) {
     695                    state = LogicalScreenDescriptor;
     696                    count = 0;
     697                }
     698                break;
     699            case LogicalScreenDescriptor:
     700                hold[count++] = ch;
     701                if (count == 7) {
     702                    imageWidth = LM(hold[0], hold[1]);
     703                    imageHeight = LM(hold[2], hold[3]);
     704                    globalColormap = !!(hold[4] & 0x80);
     705                    globalColorCount = 2 << (hold[4] & 0x7);
     706                    count = 0;
     707                    colorCount = globalColorCount;
     708                    if (globalColormap) {
     709                        int colorTableSize = 3 * globalColorCount;
     710                        if (length >= colorTableSize) {
     711                            // skip the global color table in one go
     712                            length -= colorTableSize;
     713                            buffer += colorTableSize;
     714                            state = Introducer;
     715                        } else {
     716                            colorReadCount = 0;
     717                            state = GlobalColorMap;
     718                        }
     719                    } else {
     720                        state=Introducer;
     721                    }
     722                }
     723                break;
     724            case GlobalColorMap:
     725            case LocalColorMap:
     726                hold[count++] = ch;
     727                if (count == 3) {
     728                    if (++colorReadCount >= colorCount) {
     729                        if (state == LocalColorMap)
     730                            state = TableImageLZWSize;
     731                        else
     732                            state = Introducer;
     733                    }
     734                    count = 0;
     735                }
     736                break;
     737            case Introducer:
     738                hold[count++] = ch;
     739                switch (ch) {
     740                case 0x2c:
     741                    state = ImageDescriptor;
     742                    break;
     743                case 0x21:
     744                    state = ExtensionLabel;
     745                    break;
     746                case 0x3b:
     747                    state = Done;
     748                    break;
     749                default:
     750                    done = true;
     751                    state = Error;
     752                }
     753                break;
     754            case ImageDescriptor:
     755                hold[count++] = ch;
     756                if (count == 10) {
     757                    int newLeft = LM(hold[1], hold[2]);
     758                    int newTop = LM(hold[3], hold[4]);
     759                    int newWidth = LM(hold[5], hold[6]);
     760                    int newHeight = LM(hold[7], hold[8]);
     761
     762                    if (imageWidth/10 > qMax(newWidth,200))
     763                        imageWidth = -1;
     764                    if (imageHeight/10 > qMax(newHeight,200))
     765                        imageHeight = -1;
     766
     767                    if (imageWidth <= 0)
     768                        imageWidth = newLeft + newWidth;
     769                    if (imageHeight <= 0)
     770                        imageHeight = newTop + newHeight;
     771
     772                    *imageSizes << QSize(imageWidth, imageHeight);
     773
     774                    localColormap = !!(hold[9] & 0x80);
     775                    localColorCount = localColormap ? (2 << (hold[9] & 0x7)) : 0;
     776                    if (localColorCount)
     777                        colorCount = localColorCount;
     778                    else
     779                        colorCount = globalColorCount;
     780
     781                    count = 0;
     782                    if (localColormap) {
     783                        int colorTableSize = 3 * localColorCount;
     784                        if (length >= colorTableSize) {
     785                            // skip the local color table in one go
     786                            length -= colorTableSize;
     787                            buffer += colorTableSize;
     788                            state = TableImageLZWSize;
     789                        } else {
     790                            colorReadCount = 0;
     791                            state = LocalColorMap;
     792                        }
     793                    } else {
     794                        state = TableImageLZWSize;
     795                    }
     796                }
     797                break;
     798            case TableImageLZWSize:
     799                if (ch > max_lzw_bits)
     800                    state = Error;
     801                else
     802                    state = ImageDataBlockSize;
     803                count = 0;
     804                break;
     805            case ImageDataBlockSize:
     806                blockSize = ch;
     807                if (blockSize) {
     808                    if (length >= blockSize) {
     809                        // we can skip the block in one go
     810                        length -= blockSize;
     811                        buffer += blockSize;
     812                        count = 0;
     813                    } else {
     814                        state = ImageDataBlock;
     815                    }
     816                } else {
     817                    state = Introducer;
     818                }
     819                break;
     820            case ImageDataBlock:
     821                ++count;
     822                if (count == blockSize) {
     823                    count = 0;
     824                    state = ImageDataBlockSize;
     825                }
     826                break;
     827            case ExtensionLabel:
     828                switch (ch) {
     829                case 0xf9:
     830                    state = GraphicControlExtension;
     831                    break;
     832                case 0xff:
     833                    state = ApplicationExtension;
     834                    break;
     835                default:
     836                    state = SkipBlockSize;
     837                }
     838                count = 0;
     839                break;
     840            case ApplicationExtension:
     841                if (count < 11)
     842                    hold[count] = ch;
     843                ++count;
     844                if (count == hold[0] + 1) {
     845                    if (qstrncmp((char*)(hold+1), "NETSCAPE", 8) == 0)
     846                        state=NetscapeExtensionBlockSize;
     847                    else
     848                        state=SkipBlockSize;
     849                    count = 0;
     850                }
     851                break;
     852            case GraphicControlExtension:
     853                if (count < 5)
     854                    hold[count] = ch;
     855                ++count;
     856                if (count == hold[0] + 1) {
     857                    count = 0;
     858                    state = SkipBlockSize;
     859                }
     860                break;
     861            case NetscapeExtensionBlockSize:
     862                blockSize = ch;
     863                count = 0;
     864                if (blockSize)
     865                    state = NetscapeExtensionBlock;
     866                else
     867                    state = Introducer;
     868                break;
     869            case NetscapeExtensionBlock:
     870                if (count < 3)
     871                    hold[count] = ch;
     872                count++;
     873                if (count == blockSize) {
     874                    *loopCount = LM(hold[1], hold[2]);
     875                    state = SkipBlockSize;
     876                }
     877                break;
     878            case SkipBlockSize:
     879                blockSize = ch;
     880                count = 0;
     881                if (blockSize) {
     882                    if (length >= blockSize) {
     883                        // we can skip the block in one go
     884                        length -= blockSize;
     885                        buffer += blockSize;
     886                    } else {
     887                        state = SkipBlock;
     888                    }
     889                } else {
     890                    state = Introducer;
     891                }
     892                break;
     893            case SkipBlock:
     894                ++count;
     895                if (count == blockSize)
     896                    state = SkipBlockSize;
     897                break;
     898            case Done:
     899                done = true;
     900                break;
     901            case Error:
     902                device->seek(oldPos);
     903                return;
     904            }
     905        }
     906        readBuffer = device->read(readBufferSize);
     907    }
     908    device->seek(oldPos);
     909    return;
     910}
     911
    648912void QGIFFormat::fillRect(QImage *image, int col, int row, int w, int h, QRgb color)
    649913{
     
    7641028    gifFormat = new QGIFFormat;
    7651029    nextDelay = 0;
    766     loopCnt = 0;
     1030    loopCnt = 1;
    7671031    frameNumber = -1;
    768     nextSize = QSize();
     1032    scanIsCached = false;
    7691033}
    7701034
     
    7881052
    7891053        int decoded = gifFormat->decode(&lastImage, (const uchar *)buffer.constData(), buffer.size(),
    790                                         &nextDelay, &loopCnt, &nextSize);
     1054                                        &nextDelay, &loopCnt);
    7911055        if (decoded == -1)
    7921056            break;
     
    8321096
    8331097        int decoded = gifFormat->decode(&lastImage, (const uchar *)buffer.constData(), buffer.size(),
    834                                         &nextDelay, &loopCnt, &nextSize);
     1098                                        &nextDelay, &loopCnt);
    8351099        if (decoded == -1)
    8361100            break;
     
    8631127{
    8641128    if (option == Size) {
    865         if (imageIsComing())
    866             return nextSize;
     1129        if (!scanIsCached) {
     1130            QGIFFormat::scan(device(), &imageSizes, &loopCnt);
     1131            scanIsCached = true;
     1132        }
     1133        // before the first frame is read, or we have an empty data stream
     1134        if (frameNumber == -1)
     1135            return (imageSizes.count() > 0) ? QVariant(imageSizes.at(0)) : QVariant();
     1136        // after the last frame has been read, the next size is undefined
     1137        if (frameNumber >= imageSizes.count() - 1)
     1138            return QVariant();
     1139        // and the last case: the size of the next frame
     1140        return imageSizes.at(frameNumber + 1);
    8671141    } else if (option == Animation) {
    8681142        return true;
     
    8841158int QGifHandler::imageCount() const
    8851159{
    886     return 0; // Don't know
     1160    if (!scanIsCached) {
     1161        QGIFFormat::scan(device(), &imageSizes, &loopCnt);
     1162        scanIsCached = true;
     1163    }
     1164    return imageSizes.count();
    8871165}
    8881166
    8891167int QGifHandler::loopCount() const
    8901168{
     1169    if (!scanIsCached) {
     1170        QGIFFormat::scan(device(), &imageSizes, &loopCnt);
     1171        scanIsCached = true;
     1172    }
    8911173    return loopCnt-1; // In GIF, loop count is iteration count, so subtract one
    8921174}
  • trunk/src/plugins/imageformats/gif/qgifhandler.h

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    8888    mutable int loopCnt;
    8989    int frameNumber;
    90     mutable QSize nextSize;
     90    mutable QVector<QSize> imageSizes;
     91    mutable bool scanIsCached;
    9192};
    9293
  • trunk/src/plugins/imageformats/ico/main.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/ico/qicohandler.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    557557                    icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits;
    558558                icoAttrib.w = iconEntry.bWidth;
     559                if (icoAttrib.w == 0)
     560                    icoAttrib.w = header.biWidth;
    559561                icoAttrib.h = iconEntry.bHeight;
     562                if (icoAttrib.h == 0)
     563                    icoAttrib.h = header.biHeight/2;
    560564
    561565                QImage::Format format = QImage::Format_ARGB32;
  • trunk/src/plugins/imageformats/ico/qicohandler.h

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/jpeg/main.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/jpeg/qjpeghandler.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/jpeg/qjpeghandler.h

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/mng/main.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/mng/qmnghandler.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/mng/qmnghandler.h

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/svg/main.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/svg/qsvgiohandler.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/svg/qsvgiohandler.h

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/tiff/main.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/tiff/qtiffhandler.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/plugins/imageformats/tiff/qtiffhandler.h

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
Note: See TracChangeset for help on using the changeset viewer.