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

📄 qbmphandler.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module 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.**** 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 "private/qbmphandler_p.h"#ifndef QT_NO_IMAGEFORMAT_BMP#include <qimage.h>#include <qvariant.h>#include <qvector.h>static void swapPixel01(QImage *image)        // 1-bpp: swap 0 and 1 pixels{    int i;    if (image->depth() == 1 && image->numColors() == 2) {        register uint *p = (uint *)image->bits();        int nbytes = image->numBytes();        for (i=0; i<nbytes/4; i++) {            *p = ~*p;            p++;        }        uchar *p2 = (uchar *)p;        for (i=0; i<(nbytes&3); i++) {            *p2 = ~*p2;            p2++;        }        QRgb t = image->color(0);                // swap color 0 and 1        image->setColor(0, image->color(1));        image->setColor(1, t);    }}/*    QImageIO::defineIOHandler("BMP", "^BM", 0,                               read_bmp_image, write_bmp_image);*//*****************************************************************************  BMP (DIB) image read/write functions *****************************************************************************/const int BMP_FILEHDR_SIZE = 14;                // size of BMP_FILEHDR dataQDataStream &operator>>(QDataStream &s, BMP_FILEHDR &bf){                                                // read file header    s.readRawData(bf.bfType, 2);    s >> bf.bfSize >> bf.bfReserved1 >> bf.bfReserved2 >> bf.bfOffBits;    return s;}QDataStream &operator<<(QDataStream &s, const BMP_FILEHDR &bf){                                                // write file header    s.writeRawData(bf.bfType, 2);    s << bf.bfSize << bf.bfReserved1 << bf.bfReserved2 << bf.bfOffBits;    return s;}const int BMP_OLD  = 12;                        // old Windows/OS2 BMP sizeconst int BMP_WIN  = 40;                        // new Windows BMP sizeconst int BMP_OS2  = 64;                        // new OS/2 BMP sizeconst int BMP_RGB  = 0;                                // no compressionconst int BMP_RLE8 = 1;                                // run-length encoded, 8 bitsconst int BMP_RLE4 = 2;                                // run-length encoded, 4 bitsconst int BMP_BITFIELDS = 3;                        // RGB values encoded in data as bit-fieldsQDataStream &operator>>(QDataStream &s, BMP_INFOHDR &bi){    s >> bi.biSize;    if (bi.biSize == BMP_WIN || bi.biSize == BMP_OS2) {        s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;        s >> bi.biCompression >> bi.biSizeImage;        s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;        s >> bi.biClrUsed >> bi.biClrImportant;    }    else {                                        // probably old Windows format        qint16 w, h;        s >> w >> h >> bi.biPlanes >> bi.biBitCount;        bi.biWidth  = w;        bi.biHeight = h;        bi.biCompression = BMP_RGB;                // no compression        bi.biSizeImage = 0;        bi.biXPelsPerMeter = bi.biYPelsPerMeter = 0;        bi.biClrUsed = bi.biClrImportant = 0;    }    return s;}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;}static int calc_shift(int mask){    int result = 0;    while (!(mask & 1)) {        result++;        mask >>= 1;    }    return result;}static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf){    // read BMP file header    s >> bf;    if (s.status() != QDataStream::Ok)        return false;    // check header    if (qstrncmp(bf.bfType,"BM",2) != 0)        return false;    return true;}static bool read_dib_infoheader(QDataStream &s, BMP_INFOHDR &bi){    s >> bi;                                        // read BMP info header    if (s.status() != QDataStream::Ok)        return false;    int nbits = bi.biBitCount;    int comp = bi.biCompression;    if (!(nbits == 1 || nbits == 4 || nbits == 8 || nbits == 16 || nbits == 24 || nbits == 32) ||        bi.biPlanes != 1 || comp > BMP_BITFIELDS)        return false;                                        // weird BMP image    if (!(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||        (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)))         return false;                                // weird compression type    return true;}static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int startpos, QImage &image){    QIODevice* d = s.device();    if (d->atEnd())                                // end of stream/file        return false;#if 0    qDebug("offset...........%d", offset);    qDebug("startpos.........%d", startpos);    qDebug("biSize...........%d", bi.biSize);    qDebug("biWidth..........%d", bi.biWidth);    qDebug("biHeight.........%d", bi.biHeight);    qDebug("biPlanes.........%d", bi.biPlanes);    qDebug("biBitCount.......%d", bi.biBitCount);    qDebug("biCompression....%d", bi.biCompression);    qDebug("biSizeImage......%d", bi.biSizeImage);    qDebug("biXPelsPerMeter..%d", bi.biXPelsPerMeter);    qDebug("biYPelsPerMeter..%d", bi.biYPelsPerMeter);    qDebug("biClrUsed........%d", bi.biClrUsed);    qDebug("biClrImportant...%d", bi.biClrImportant);#endif    int w = bi.biWidth,         h = bi.biHeight,  nbits = bi.biBitCount;    int t = bi.biSize,         comp = bi.biCompression;    int red_mask = 0;    int green_mask = 0;    int blue_mask = 0;    int red_shift = 0;    int green_shift = 0;    int blue_shift = 0;    int red_scale = 0;    int green_scale = 0;    int blue_scale = 0;    int ncols = 0;    int depth = 0;    QImage::Format format;    switch (nbits) {        case 32:        case 24:        case 16:            depth = 32;            format = QImage::Format_RGB32;            break;        case 8:        case 4:            depth = 8;            format = QImage::Format_Indexed8;            break;        default:            depth = 1;            format = QImage::Format_Mono;    }    if (bi.biHeight < 0)        h = -h;                  // support images with negative height    if (image.size() != QSize(w, h) || image.format() != format) {        image = QImage(w, h, format);        if (image.isNull())                        // could not create image            return false;    }    if (depth != 32) {        ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;        image.setNumColors(ncols);    }    image.setDotsPerMeterX(bi.biXPelsPerMeter);    image.setDotsPerMeterY(bi.biYPelsPerMeter);    if (!d->isSequential())        d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap    if (ncols > 0) {                                // read color table        uchar rgb[4];        int   rgb_len = t == BMP_OLD ? 3 : 4;        for (int i=0; i<ncols; i++) {            if (d->read((char *)rgb, rgb_len) != rgb_len)                return false;            image.setColor(i, qRgb(rgb[2],rgb[1],rgb[0]));            if (d->atEnd())                        // truncated file                return false;        }    } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) {        if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))            return false;        if (d->read((char *)&green_mask, sizeof(green_mask)) != sizeof(green_mask))            return false;        if (d->read((char *)&blue_mask, sizeof(blue_mask)) != sizeof(blue_mask))            return false;        red_shift = calc_shift(red_mask);        red_scale = 256 / ((red_mask >> red_shift) + 1);        green_shift = calc_shift(green_mask);        green_scale = 256 / ((green_mask >> green_shift) + 1);        blue_shift = calc_shift(blue_mask);        blue_scale = 256 / ((blue_mask >> blue_shift) + 1);    } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {        blue_mask = 0x000000ff;        green_mask = 0x0000ff00;        red_mask = 0x00ff0000;        blue_shift = 0;        green_shift = 8;        red_shift = 16;        blue_scale = green_scale = red_scale = 1;    } else if (comp == BMP_RGB && nbits == 16) {        blue_mask = 0x001f;        green_mask = 0x03e0;        red_mask = 0x7c00;        blue_shift = 0;        green_shift = 2;        red_shift = 7;        red_scale = 1;        green_scale = 1;        blue_scale = 8;    }    // offset can be bogus, be careful    if (offset>=0 && startpos + offset > d->pos()) {        if (!d->isSequential())            d->seek(startpos + offset);                // start of image data    }    int             bpl = image.bytesPerLine();    uchar *data = image.bits();    if (nbits == 1) {                                // 1 bit BMP image        while (--h >= 0) {            if (d->read((char*)(data + h*bpl), bpl) != bpl)                break;        }        if (ncols == 2 && qGray(image.color(0)) < qGray(image.color(1)))            swapPixel01(&image);                // pixel 0 is white!    }    else if (nbits == 4) {                        // 4 bit BMP image        int    buflen = ((w+7)/8)*4;        uchar *buf    = new uchar[buflen];        if (comp == BMP_RLE4) {                // run length compression            int x=0, y=0, c, i;            quint8 b;            register uchar *p = data + (h-1)*bpl;            const uchar *endp = p + w;            while (y < h) {                if (!d->getChar((char *)&b))                    break;                if (b == 0) {                        // escape code                    if (!d->getChar((char *)&b) || b == 1) {                        y = h;                // exit loop                    } else switch (b) {                        case 0:                        // end of line                            x = 0;                            y++;                            p = data + (h-y-1)*bpl;                            break;                        case 2:                        // delta (jump)                        {                            quint8 tmp;                            d->getChar((char *)&tmp);                            x += tmp;                            d->getChar((char *)&tmp);                            y += tmp;                        }                            // Protection                            if ((uint)x >= (uint)w)                                x = w-1;                            if ((uint)y >= (uint)h)                                y = h-1;                            p = data + (h-y-1)*bpl + x;                            break;                        default:                // absolute mode                            // Protection                            if (p + b > endp)                                b = endp-p;                            i = (c = b)/2;                            while (i--) {                                d->getChar((char *)&b);                                *p++ = b >> 4;                                *p++ = b & 0x0f;                            }                            if (c & 1) {                                unsigned char tmp;                                d->getChar((char *)&tmp);                                *p++ = tmp >> 4;                            }                            if ((((c & 3) + 1) & 2) == 2)                                d->getChar(0);        // align on word boundary                            x += c;                    }                } else {                        // encoded mode                    // Protection                    if (p + b > endp)                        b = endp-p;                    i = (c = b)/2;                    d->getChar((char *)&b);                // 2 pixels to be repeated                    while (i--) {                        *p++ = b >> 4;                        *p++ = b & 0x0f;                    }                    if (c & 1)                        *p++ = b >> 4;                    x += c;                }            }        } else if (comp == BMP_RGB) {                // no compression            memset(data, 0, h*bpl);            while (--h >= 0) {                if (d->read((char*)buf,buflen) != buflen)                    break;                register uchar *p = data + h*bpl;                uchar *b = buf;                for (int i=0; i<w/2; i++) {        // convert nibbles to bytes                    *p++ = *b >> 4;                    *p++ = *b++ & 0x0f;                }

⌨️ 快捷键说明

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