⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgifhandler.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the plugins of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** WARNING:**      A separate license from Unisys may be required to use the gif**      reader. See http://www.unisys.com/about__unisys/lzw/**      for information from Unisys**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qgifhandler.h"#include <qimage.h>#include <qiodevice.h>#include <qvariant.h>#define Q_TRANSPARENT 0x00ffffff/*  Incremental image decoder for GIF image format.  This subclass of QImageFormat decodes GIF format images,  including animated GIFs. Internally in*/class QGIFFormat {public:    QGIFFormat();    ~QGIFFormat();    int decode(QImage *image, const uchar* buffer, int length,               int *nextFrameDelay, int *loopCount, QSize *nextSize);    bool newFrame;    bool partialNewFrame;private:    void fillRect(QImage *image, int x, int y, int w, int h, QRgb col);    inline QRgb color(uchar index) const;    // GIF specific stuff    QRgb* globalcmap;    QRgb* localcmap;    QImage backingstore;    unsigned char hold[16];    bool gif89;    int count;    int ccount;    int expectcount;    enum State {        Header,        LogicalScreenDescriptor,        GlobalColorMap,        LocalColorMap,        Introducer,        ImageDescriptor,        TableImageLZWSize,        ImageDataBlockSize,        ImageDataBlock,        ExtensionLabel,        GraphicControlExtension,        ApplicationExtension,        NetscapeExtensionBlockSize,        NetscapeExtensionBlock,        SkipBlockSize,        SkipBlock,        Done,        Error    } state;    int gncols;    int lncols;    int ncols;    int lzwsize;    bool lcmap;    int swidth, sheight;    int width, height;    int left, top, right, bottom;    enum Disposal { NoDisposal, DoNotChange, RestoreBackground, RestoreImage };    Disposal disposal;    bool disposed;    int trans_index;    bool gcmap;    int bgcol;    int interlace;    int accum;    int bitcount;    enum { max_lzw_bits=12 }; // (poor-compiler's static const int)    int code_size, clear_code, end_code, max_code_size, max_code;    int firstcode, oldcode, incode;    short table[2][1<< max_lzw_bits];    short stack[(1<<(max_lzw_bits))*2];    short *sp;    bool needfirst;    int x, y;    int frame;    bool out_of_bounds;    bool digress;    void nextY(QImage *image);    void disposePrevious(QImage *image);};/*!    Constructs a QGIFFormat.*/QGIFFormat::QGIFFormat(){    globalcmap = 0;    localcmap = 0;    lncols = 0;    gncols = 0;    disposal = NoDisposal;    out_of_bounds = false;    disposed = true;    frame = -1;    state = Header;    count = 0;    lcmap = false;    newFrame = false;    partialNewFrame = false;}/*!    Destroys a QGIFFormat.*/QGIFFormat::~QGIFFormat(){    if (globalcmap) delete[] globalcmap;    if (localcmap) delete[] localcmap;}void QGIFFormat::disposePrevious(QImage *image){    if (out_of_bounds) {        // flush anything that survived        // ### Changed: QRect(0, 0, swidth, sheight)    }    // Handle disposal of previous image before processing next one    if (disposed) return;    int l = qMin(swidth-1,left);    int r = qMin(swidth-1,right);    int t = qMin(sheight-1,top);    int b = qMin(sheight-1,bottom);    switch (disposal) {      case NoDisposal:        break;      case DoNotChange:        break;      case RestoreBackground:        if (trans_index>=0) {            // Easy:  we use the transparent color            fillRect(image, l, t, r-l+1, b-t+1, Q_TRANSPARENT);        } else if (bgcol>=0) {            // Easy:  we use the bgcol given            fillRect(image, l, t, r-l+1, b-t+1, color(bgcol));        } else {            // Impossible:  We don't know of a bgcol - use pixel 0            QRgb *bits = (QRgb*)image->bits();            fillRect(image, l, t, r-l+1, b-t+1, bits[0]);        }        // ### Changed: QRect(l, t, r-l+1, b-t+1)        break;      case RestoreImage: {        if (frame >= 0) {            for (int ln=t; ln<=b; ln++) {                memcpy(image->scanLine(ln)+l,                    backingstore.scanLine(ln-t),                    (r-l+1)*sizeof(QRgb));            }            // ### Changed: QRect(l, t, r-l+1, b-t+1)        }      }    }    disposal = NoDisposal; // Until an extension says otherwise.    disposed = true;}/*!    This function decodes some data into image changes.    Returns the number of bytes consumed.*/int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,                       int *nextFrameDelay, int *loopCount, QSize *nextSize){    // We are required to state that    //    "The Graphics Interchange Format(c) is the Copyright property of    //    CompuServe Incorporated. GIF(sm) is a Service Mark property of    //    CompuServe Incorporated."#define LM(l, m) (((m)<<8)|l)    digress = false;    int initial = length;    while (!digress && length) {        length--;        unsigned char ch=*buffer++;        switch (state) {          case Header:            hold[count++]=ch;            if (count==6) {                // Header                gif89=(hold[3]!='8' || hold[4]!='7');                state=LogicalScreenDescriptor;                count=0;            }            break;          case LogicalScreenDescriptor:            hold[count++]=ch;            if (count==7) {                // Logical Screen Descriptor                swidth=LM(hold[0], hold[1]);                sheight=LM(hold[2], hold[3]);                gcmap=!!(hold[4]&0x80);                //UNUSED: bpchan=(((hold[4]&0x70)>>3)+1);                //UNUSED: gcmsortflag=!!(hold[4]&0x08);                gncols=2<<(hold[4]&0x7);                bgcol=(gcmap) ? hold[5] : -1;                //aspect=hold[6] ? double(hold[6]+15)/64.0 : 1.0;                trans_index = -1;                count=0;                ncols=gncols;                if (gcmap) {                    ccount=0;                    state=GlobalColorMap;                    globalcmap = new QRgb[gncols+1]; // +1 for trans_index                    globalcmap[gncols] = Q_TRANSPARENT;                } else {                    state=Introducer;                }            }            break;          case GlobalColorMap: case LocalColorMap:            hold[count++]=ch;            if (count==3) {                QRgb rgb = qRgb(hold[0], hold[1], hold[2]);                if (state == LocalColorMap) {                    if (ccount < lncols)                        localcmap[ccount] =  rgb;                } else {                    globalcmap[ccount] = rgb;                }                if (++ccount >= ncols) {                    if (state == LocalColorMap)                        state=TableImageLZWSize;                    else                        state=Introducer;                }                count=0;            }            break;          case Introducer:            hold[count++]=ch;            switch (ch) {              case ',':                state=ImageDescriptor;                break;              case '!':                state=ExtensionLabel;                break;              case ';':                  // ### Changed: QRect(0, 0, swidth, sheight)                state=Done;                break;              default:                digress=true;                // Unexpected Introducer - ignore block                state=Error;            }            break;          case ImageDescriptor:            hold[count++]=ch;            if (count==10) {                int newleft=LM(hold[1], hold[2]);                int newtop=LM(hold[3], hold[4]);                int newwidth=LM(hold[5], hold[6]);                int newheight=LM(hold[7], hold[8]);                // disbelieve ridiculous logical screen sizes,                // unless the image frames are also large.                if (swidth/10 > qMax(newwidth,200))                    swidth = -1;                if (sheight/10 > qMax(newheight,200))                    sheight = -1;                if (swidth <= 0)                    swidth = newleft + newwidth;                if (sheight <= 0)                    sheight = newtop + newheight;                QImage::Format format = trans_index >= 0 ? QImage::Format_ARGB32 : QImage::Format_RGB32;                if (image->isNull() || (image->size() != QSize(swidth, sheight)) || image->format() != format) {                    (*image) = QImage(swidth, sheight, format);                    memset(image->bits(), 0, image->numBytes());                    // ### size of the upcoming frame, should rather                    // be known before decoding it.                    *nextSize = QSize(swidth, sheight);                }                disposePrevious(image);                disposed = false;                left = newleft;                top = newtop;                width = newwidth;                height = newheight;                right=qMax(0, qMin(left+width, swidth)-1);                bottom=qMax(0, qMin(top+height, sheight)-1);                lcmap=!!(hold[9]&0x80);                interlace=!!(hold[9]&0x40);                //bool lcmsortflag=!!(hold[9]&0x20);                lncols=lcmap ? (2<<(hold[9]&0x7)) : 0;                if (lncols) {                    if (localcmap)                        delete [] localcmap;                    localcmap = new QRgb[lncols+1];                    localcmap[lncols] = Q_TRANSPARENT;                    ncols = lncols;                } else {                    ncols = gncols;                }                frame++;                if (frame == 0) {                    if (left || top || width<swidth || height<sheight) {                        // Not full-size image - erase with bg or transparent                        if (trans_index >= 0) {                            fillRect(image, 0, 0, swidth, sheight, color(trans_index));                            // ### Changed: QRect(0, 0, swidth, sheight)                        } else if (bgcol>=0) {                            fillRect(image, 0, 0, swidth, sheight, color(bgcol));                            // ### Changed: QRect(0, 0, swidth, sheight)                        }                    }                }                if (disposal == RestoreImage) {                    int l = qMin(swidth-1,left);                    int r = qMin(swidth-1,right);                    int t = qMin(sheight-1,top);                    int b = qMin(sheight-1,bottom);                    int w = r-l+1;                    int h = b-t+1;                    if (backingstore.width() < w                        || backingstore.height() < h) {                        // We just use the backing store as a byte array                        backingstore = QImage(qMax(backingstore.width(), w),                                              qMax(backingstore.height(), h),                                              QImage::Format_RGB32);                        memset(image->bits(), 0, image->numBytes());                    }                    for (int ln=0; ln<h; ln++) {                        memcpy(backingstore.scanLine(ln),                               image->scanLine(t+ln)+l, w*sizeof(QRgb));                    }                }                count=0;                if (lcmap) {                    ccount=0;                    state=LocalColorMap;                } else {                    state=TableImageLZWSize;                }                x = left;                y = top;                accum = 0;                bitcount = 0;                sp = stack;                firstcode = oldcode = 0;                needfirst = true;                out_of_bounds = left>=swidth || y>=sheight;            }            break;          case TableImageLZWSize: {            lzwsize=ch;            if (lzwsize > max_lzw_bits) {                state=Error;            } else {                code_size=lzwsize+1;                clear_code=1<<lzwsize;                end_code=clear_code+1;                max_code_size=2*clear_code;                max_code=clear_code+2;                int i;                for (i=0; i<clear_code; i++) {                    table[0][i]=0;                    table[1][i]=i;                }                state=ImageDataBlockSize;            }            count=0;            break;          } case ImageDataBlockSize:            expectcount=ch;            if (expectcount) {                state=ImageDataBlock;            } else {                state=Introducer;                digress = true;                newFrame = true;            }            break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -