Ejemplo n.º 1
0
static bool read_xpm_header(
    QIODevice *device, const char * const * source, int& index, QByteArray &state,
    int *cpp, int *ncols, int *w, int *h)
{
    QByteArray buf(200, 0);

    if (!read_xpm_string(buf, device, source, index, state))
        return false;

    if (sscanf(buf, "%d %d %d %d", w, h, ncols, cpp) < 4)
        return false;                                        // < 4 numbers parsed

    return true;
}
Ejemplo n.º 2
0
static bool read_xpm_header(
    QIODevice *device, const char * const * source, int& index, QByteArray &state,
    int *cpp, int *ncols, int *w, int *h)
{
    QByteArray buf(200, 0);

    if (!read_xpm_string(buf, device, source, index, state))
        return false;

#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE)
        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;
}
Ejemplo n.º 3
0
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 < 0 || 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.setColorCount(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;
                }
            }
            // avoid uninitialized memory for malformed xpms
            if (x < w) {
                qWarning("QImage: XPM pixels missing on image line %d (possibly a C++ trigraph).", y);
                memset(p, 0, w - x);
            }
        } 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;
            }
            // avoid uninitialized memory for malformed xpms
            if (x < w) {
                qWarning("QImage: XPM pixels missing on image line %d (possibly a C++ trigraph).", y);
                memset(p, 0, (w - x)*4);
            }
        }
    }

    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;
}