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

📄 qxpmhandler.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{    QByteArray buf(200, 0);    if (!read_xpm_string(buf, device, source, index, state))        return false;#if defined(_MSC_VER) && _MSC_VER >= 1400	if (sscanf_s(buf, "%d %d %d %d", w, h, ncols, cpp) < 4)#else    if (sscanf(buf, "%d %d %d %d", w, h, ncols, cpp) < 4)#endif        return false;                                        // < 4 numbers parsed    return true;}// Reads XPM body (color information & pixels).static bool read_xpm_body(    QIODevice *device, const char * const * source, int& index, QByteArray& state,    int cpp, int ncols, int w, int h, QImage& image){    QByteArray buf(200, 0);    int i;    if (cpp > 15)        return false;    // For > 256 colors, we delay creation of the image until    // after we have read the color specifications, so that we can    // create it in correct format (Format_RGB32 vs Format_ARGB32,    // depending on absence or presence of "c none", respectively)    if (ncols <= 256) {        if (image.size() != QSize(w, h) || image.format() != QImage::Format_Indexed8) {            image = QImage(w, h, QImage::Format_Indexed8);            if (image.isNull())                return false;        }        image.setNumColors(ncols);    }    QMap<quint64, int> colorMap;    int currentColor;    bool hasTransparency = false;    for(currentColor=0; currentColor < ncols; ++currentColor) {        if (!read_xpm_string(buf, device, source, index, state)) {            qWarning("QImage: XPM color specification missing");            return false;        }        QByteArray index;        index = buf.left(cpp);        buf = buf.mid(cpp).simplified().trimmed().toLower();        QList<QByteArray> tokens = buf.split(' ');        i = tokens.indexOf("c");        if (i < 0)            i = tokens.indexOf("g");        if (i < 0)            i = tokens.indexOf("g4");        if (i < 0)            i = tokens.indexOf("m");        if (i < 0) {            qWarning("QImage: XPM color specification is missing: %s", buf.constData());            return false;        // no c/g/g4/m specification at all        }        QByteArray color;        while ((++i < tokens.size()) && !is_xpm_color_spec_prefix(tokens.at(i))) {            color.append(tokens.at(i));        }        if (color.isEmpty()) {            qWarning("QImage: XPM color value is missing from specification: %s", buf.constData());            return false;        // no color value        }        buf = color;        if (buf == "none") {            hasTransparency = true;            int transparentColor = currentColor;            if (ncols <= 256) {                image.setColor(transparentColor, 0);                colorMap.insert(xpmHash(QLatin1String(index.constData())), transparentColor);            } else {                colorMap.insert(xpmHash(QLatin1String(index.constData())), 0);            }        } else {            QRgb c_rgb;            if (((buf.length()-1) % 3) && (buf[0] == '#')) {                buf.truncate(((buf.length()-1) / 4 * 3) + 1); // remove alpha channel left by imagemagick            }            if (buf[0] == '#') {                qt_get_hex_rgb(buf, &c_rgb);            } else {                qt_get_named_xpm_rgb(buf, &c_rgb);            }            if (ncols <= 256) {                image.setColor(currentColor, 0xff000000 | c_rgb);                colorMap.insert(xpmHash(QLatin1String(index.constData())), currentColor);            } else {                colorMap.insert(xpmHash(QLatin1String(index.constData())), 0xff000000 | c_rgb);            }        }    }    if (ncols > 256) {        // Now we can create 32-bit image of appropriate format        QImage::Format format = hasTransparency ?                                QImage::Format_ARGB32 : QImage::Format_RGB32;        if (image.size() != QSize(w, h) || image.format() != format) {            image = QImage(w, h, format);            if (image.isNull())                return false;        }    }    // Read pixels    for(int y=0; y<h; y++) {        if (!read_xpm_string(buf, device, source, index, state)) {            qWarning("QImage: XPM pixels missing on image line %d", y);            return false;        }        if (image.depth() == 8) {            uchar *p = image.scanLine(y);            uchar *d = (uchar *)buf.data();            uchar *end = d + buf.length();            int x;            if (cpp == 1) {                char b[2];                b[1] = '\0';                for (x=0; x<w && d<end; x++) {                    b[0] = *d++;                    *p++ = (uchar)colorMap[xpmHash(b)];                }            } else {                char b[16];                b[cpp] = '\0';                for (x=0; x<w && d<end; x++) {                    memcpy(b, (char *)d, cpp);                    *p++ = (uchar)colorMap[xpmHash(b)];                    d += cpp;                }            }        } else {            QRgb *p = (QRgb*)image.scanLine(y);            uchar *d = (uchar *)buf.data();            uchar *end = d + buf.length();            int x;            char b[16];            b[cpp] = '\0';            for (x=0; x<w && d<end; x++) {                memcpy(b, (char *)d, cpp);                *p++ = (QRgb)colorMap[xpmHash(b)];                d += cpp;            }        }    }    if (device) {        // Rewind unused characters, and skip to the end of the XPM struct.        for (int i = state.size() - 1; i >= 0; --i)            device->ungetChar(state[i]);        char c;        while (device->getChar(&c) && c != ';');        while (device->getChar(&c) && c != '\n');    }    return true;}//// INTERNAL//// Reads an .xpm from either the QImageIO or from the QString *.// One of the two HAS to be 0, the other one is used.//bool qt_read_xpm_image_or_array(QIODevice *device, const char * const * source, QImage &image){    if (!source)        return true;        QByteArray buf(200, 0);    QByteArray state;    int cpp, ncols, w, h, index = 0;    if (device) {        // "/* XPM */"        int readBytes;        if ((readBytes = device->readLine(buf.data(), buf.size())) < 0)            return false;        if (buf.indexOf("/* XPM") != 0) {            while (readBytes > 0) {                device->ungetChar(buf.at(readBytes - 1));                --readBytes;            }            return false;        }// bad magic    }    if (!read_xpm_header(device, source, index, state, &cpp, &ncols, &w, &h))        return false;    return read_xpm_body(device, source, index, state, cpp, ncols, w, h, image);}static const char* xpm_color_name(int cpp, int index){    static char returnable[5];    static const char code[] = ".#abcdefghijklmnopqrstuvwxyzABCD"                               "EFGHIJKLMNOPQRSTUVWXYZ0123456789";    // cpp is limited to 4 and index is limited to 64^cpp    if (cpp > 1) {        if (cpp > 2) {            if (cpp > 3) {                returnable[3] = code[index % 64];                index /= 64;            } else                returnable[3] = '\0';            returnable[2] = code[index % 64];            index /= 64;        } else            returnable[2] = '\0';        // the following 4 lines are a joke!        if (index == 0)            index = 64*44+21;        else if (index == 64*44+21)            index = 0;        returnable[1] = code[index % 64];        index /= 64;    } else        returnable[1] = '\0';    returnable[0] = code[index];    return returnable;}// write XPM image datastatic bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const QString &fileName){    if (!device->isWritable())        return false;    QImage image;    if (sourceImage.depth() != 32)        image = sourceImage.convertToFormat(QImage::Format_RGB32);    else        image = sourceImage;    QMap<QRgb, int> colorMap;    int w = image.width(), h = image.height(), ncolors = 0;    int x, y;    // build color table    for(y=0; y<h; y++) {        QRgb * yp = (QRgb *)image.scanLine(y);        for(x=0; x<w; x++) {            QRgb color = *(yp + x);            if (!colorMap.contains(color))                colorMap.insert(color, ncolors++);        }    }    // number of 64-bit characters per pixel needed to encode all colors    int cpp = 1;    for (int k = 64; ncolors > k; k *= 64) {        ++cpp;        // limit to 4 characters per pixel        // 64^4 colors is enough for a 4096x4096 image         if (cpp > 4)            break;    }    QString line;    // write header    QTextStream s(device);    s << "/* XPM */" << endl      << "static char *" << fbname(fileName) << "[]={" << endl      << "\"" << w << " " << h << " " << ncolors << " " << cpp << "\"";    // write palette    QMap<QRgb, int>::Iterator c = colorMap.begin();    while (c != colorMap.end()) {        QRgb color = c.key();        if (image.format() != QImage::Format_RGB32 && !qAlpha(color))            line.sprintf("\"%s c None\"",                          xpm_color_name(cpp, *c));        else            line.sprintf("\"%s c #%02x%02x%02x\"",                          xpm_color_name(cpp, *c),                          qRed(color),                          qGreen(color),                          qBlue(color));        ++c;        s << "," << endl << line;    }    // write pixels, limit to 4 characters per pixel    line.truncate(cpp*w);    for(y=0; y<h; y++) {        QRgb * yp = (QRgb *) image.scanLine(y);        int cc = 0;        for(x=0; x<w; x++) {            int color = (int)(*(yp + x));            QByteArray chars(xpm_color_name(cpp, colorMap[color]));            line[cc++] = QLatin1Char(chars[0]);            if (cpp > 1) {                line[cc++] = QLatin1Char(chars[1]);                if (cpp > 2) {                    line[cc++] = QLatin1Char(chars[2]);                    if (cpp > 3) {                        line[cc++] = QLatin1Char(chars[3]);                    }                }            }        }        s << "," << endl << "\"" << line << "\"";    }    s << "};" << endl;    return (s.status() == QTextStream::Ok);}QXpmHandler::QXpmHandler()    : state(Ready), index(0){}bool QXpmHandler::readHeader(){    state = Error;    if (!read_xpm_header(device(), 0, index, buffer, &cpp, &ncols, &width, &height))        return false;    state = ReadHeader;    return true;}bool QXpmHandler::readImage(QImage *image){    if (state == Error)        return false;        if (state == Ready && !readHeader()) {        state = Error;        return false;    }    if (!read_xpm_body(device(), 0, index, buffer, cpp, ncols, width, height, *image)) {        state = Error;        return false;    }    state = Ready;    return true;}bool QXpmHandler::canRead() const{    if (state == Ready && canRead(device())) {        setFormat("xpm");        return true;    }    return state != Error;}bool QXpmHandler::canRead(QIODevice *device){    if (!device) {        qWarning("QXpmHandler::canRead() called with no device");        return false;    }    char head[6];    if (device->peek(head, sizeof(head)) != sizeof(head))        return false;    return qstrncmp(head, "/* XPM", 6) == 0;}bool QXpmHandler::read(QImage *image){    if (!canRead())        return false;    return readImage(image);}bool QXpmHandler::write(const QImage &image){    return write_xpm_image(image, device(), fileName);}bool QXpmHandler::supportsOption(ImageOption option) const{    return option == Name        || option == Size;}QVariant QXpmHandler::option(ImageOption option) const{    if (option == Name) {        return fileName;    } else if (option == Size) {        if (state == Error)            return QVariant();        if (state == Ready && !const_cast<QXpmHandler*>(this)->readHeader())            return QVariant();        return QSize(width, height);    }    return QVariant();}void QXpmHandler::setOption(ImageOption option, const QVariant &value){    if (option == Name)        fileName = value.toString();}QByteArray QXpmHandler::name() const{    return "xpm";}#endif // QT_NO_IMAGEFORMAT_XPM

⌨️ 快捷键说明

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