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

📄 qpixmap_x11.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (isNull())        return QImage(); // null image    int            w  = width();    int            h  = height();    int            d  = depth();    Visual *visual = (Visual *) data->xinfo.visual();    bool    trucol = (visual->c_class >= TrueColor) && d > 1;    QImage::Format format = QImage::Format_Mono;    if (d > 1 && d <= 8) {        d = 8;        format = QImage::Format_Indexed8;    }    // we could run into the situation where d == 8 AND trucol is true, which can    // cause problems when converting to and from images.  in this case, always treat    // the depth as 32...    if (d > 8 || trucol) {        d = 32;        format = QImage::Format_RGB32;    }    XImage *xi = XGetImage(X11->display, data->hd, 0, 0, w, h, AllPlanes,                           (d == 1) ? XYPixmap : ZPixmap);    Q_CHECK_PTR(xi);    if (!xi)        return QImage();    if (data->picture && data->d == 32) {        QImage image(data->w, data->h, QImage::Format_ARGB32_Premultiplied);        memcpy(image.bits(), xi->data, xi->bytes_per_line * xi->height);        // we may have to swap the byte order        if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)            || (QSysInfo::ByteOrder == QSysInfo::BigEndian))        {            for (int i=0; i < image.height(); i++) {                uint *p = (uint*) image.scanLine(i);                uint *end = p + image.width();                if ((xi->byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)                    || (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {                    while (p < end) {                        *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)                             | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);                        p++;                    }                } else if (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian) {                    while (p < end) {                        *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)                             | ((*p ) & 0xff00ff00);                        p++;                    }                }            }        }        // throw away image data        qSafeXDestroyImage(xi);        return image;    }    if (d == 1 && xi->bitmap_bit_order == LSBFirst)        format = QImage::Format_MonoLSB;    if (data->x11_mask && format == QImage::Format_RGB32)        format = QImage::Format_ARGB32;    QImage image(w, h, format);    if (image.isNull())                        // could not create image        return image;    QImage alpha;    if (data->x11_mask) {        alpha = mask().toImage();    }    bool ale = alpha.format() == QImage::Format_MonoLSB;    if (trucol) {                                // truecolor        const uint red_mask         = (uint)visual->red_mask;        const uint green_mask         = (uint)visual->green_mask;        const uint blue_mask         = (uint)visual->blue_mask;        const int  red_shift         = highest_bit(red_mask)   - 7;        const int  green_shift = highest_bit(green_mask) - 7;        const int  blue_shift         = highest_bit(blue_mask)  - 7;        const uint red_bits    = n_bits(red_mask);        const uint green_bits  = n_bits(green_mask);        const uint blue_bits   = n_bits(blue_mask);        static uint red_table_bits   = 0;        static uint green_table_bits = 0;        static uint blue_table_bits  = 0;        if (red_bits < 8 && red_table_bits != red_bits) {            build_scale_table(&red_scale_table, red_bits);            red_table_bits = red_bits;        }        if (blue_bits < 8 && blue_table_bits != blue_bits) {            build_scale_table(&blue_scale_table, blue_bits);            blue_table_bits = blue_bits;        }        if (green_bits < 8 && green_table_bits != green_bits) {            build_scale_table(&green_scale_table, green_bits);            green_table_bits = green_bits;        }        int  r, g, b;        QRgb  *dst;        uchar *src;        uint   pixel;        int    bppc = xi->bits_per_pixel;        if (bppc > 8 && xi->byte_order == LSBFirst)            bppc++;        for (int y = 0; y < h; y++) {            uchar* asrc = data->x11_mask ? alpha.scanLine(y) : 0;            dst = (QRgb *)image.scanLine(y);            src = (uchar *)xi->data + xi->bytes_per_line*y;            for (int x = 0; x < w; x++) {                switch (bppc) {                case 8:                    pixel = *src++;                    break;                case 16:                        // 16 bit MSB                    pixel = src[1] | (uint)src[0] << 8;                    src += 2;                    break;                case 17:                        // 16 bit LSB                    pixel = src[0] | (uint)src[1] << 8;                    src += 2;                    break;                case 24:                        // 24 bit MSB                    pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;                    src += 3;                    break;                case 25:                        // 24 bit LSB                    pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;                    src += 3;                    break;                case 32:                        // 32 bit MSB                    pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;                    src += 4;                    break;                case 33:                        // 32 bit LSB                    pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;                    src += 4;                    break;                default:                        // should not really happen                    x = w;                        // leave loop                    y = h;                    pixel = 0;                // eliminate compiler warning                    qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);                }                if (red_shift > 0)                    r = (pixel & red_mask) >> red_shift;                else                    r = (pixel & red_mask) << -red_shift;                if (green_shift > 0)                    g = (pixel & green_mask) >> green_shift;                else                    g = (pixel & green_mask) << -green_shift;                if (blue_shift > 0)                    b = (pixel & blue_mask) >> blue_shift;                else                    b = (pixel & blue_mask) << -blue_shift;                if (red_bits < 8)                    r = red_scale_table[r];                if (green_bits < 8)                    g = green_scale_table[g];                if (blue_bits < 8)                    b = blue_scale_table[b];                if (data->x11_mask) {                    if (ale) {                        *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;                    } else {                        *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;                    }                } else {                    *dst++ = qRgb(r, g, b);                }            }        }    } else if (xi->bits_per_pixel == d) {        // compatible depth        char *xidata = xi->data;                // copy each scanline        int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);        for (int y=0; y<h; y++) {            memcpy(image.scanLine(y), xidata, bpl);            xidata += xi->bytes_per_line;        }    } else {        /* Typically 2 or 4 bits display depth */        qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",                 xi->bits_per_pixel);        return QImage();    }    if (d == 1) {                                // bitmap        image.setNumColors(2);        image.setColor(0, qRgb(255,255,255));        image.setColor(1, qRgb(0,0,0));    } else if (!trucol) {                        // pixmap with colormap        register uchar *p;        uchar *end;        uchar  use[256];                        // pixel-in-use table        uchar  pix[256];                        // pixel translation table        int    ncols, bpl;        memset(use, 0, 256);        memset(pix, 0, 256);        bpl = image.bytesPerLine();        if (data->x11_mask) {                                // which pixels are used?            for (int i = 0; i < h; i++) {                uchar* asrc = alpha.scanLine(i);                p = image.scanLine(i);                if (ale) {                    for (int x = 0; x < w; x++) {                        if (asrc[x >> 3] & (1 << (x & 7)))                            use[*p] = 1;                        ++p;                    }                } else {                    for (int x = 0; x < w; x++) {                        if (asrc[x >> 3] & (0x80 >> (x & 7)))                            use[*p] = 1;                        ++p;                    }                }            }        } else {            for (int i = 0; i < h; i++) {                p = image.scanLine(i);                end = p + bpl;                while (p < end)                    use[*p++] = 1;            }        }        ncols = 0;        for (int i = 0; i < 256; i++) {                // build translation table            if (use[i])                pix[i] = ncols++;        }        for (int i = 0; i < h; i++) {                        // translate pixels            p = image.scanLine(i);            end = p + bpl;            while (p < end) {                *p = pix[*p];                p++;            }        }        if (data->x11_mask) {            int trans;            if (ncols < 256) {                trans = ncols++;                image.setNumColors(ncols);        // create color table                image.setColor(trans, 0x00000000);            } else {                image.setNumColors(ncols);        // create color table                // oh dear... no spare "transparent" pixel.                // use first pixel in image (as good as any).                trans = image.scanLine(0)[0];            }            for (int i = 0; i < h; i++) {                uchar* asrc = alpha.scanLine(i);                p = image.scanLine(i);                if (ale) {                    for (int x = 0; x < w; x++) {                        if (!(asrc[x >> 3] & (1 << (x & 7))))                            *p = trans;                        ++p;                    }                } else {                    for (int x = 0; x < w; x++) {                        if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))                            *p = trans;                        ++p;                    }                }            }        } else {            image.setNumColors(ncols);        // create color table        }        QVector<QColor> colors = QColormap::instance(data->xinfo.screen()).colormap();        int j = 0;        for (int i=0; i<colors.size(); i++) {                // translate pixels            if (use[i])                image.setColor(j++, 0xff000000 | colors.at(i).rgb());        }    }    qSafeXDestroyImage(xi);    return image;}/*!    \fn QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)    Converts the given \a image to a pixmap using the specified \a    flags to control the conversion.  The \a flags argument is a    bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a    flags sets all the default options.    In case of monochrome and 8-bit images, the image is first    converted to a 32-bit pixmap and then filled with the colors in    the color table. If this is too expensive an operation, you can    use QBitmap::fromImage() instead.    \sa toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}*/QPixmap QPixmap::fromImage(const QImage &img, Qt::ImageConversionFlags flags){    QPixmap pixmap;    if (img.isNull()) {        qWarning("QPixmap::fromImage: Cannot convert a null image");        return pixmap;    }    QImage  image = img;    const int         w   = image.width();    const int         h   = image.height();    int         d   = image.depth();    const int         dd  = X11->use_xrender && img.hasAlphaChannel() ? 32 : pixmap.data->xinfo.depth();    bool force_mono = (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly);    if (uint(w) >= 32768 || uint(h) >= 32768)        return QPixmap();    // must be monochrome    if (force_mono) {        if (d != 1) {            // dither            image = image.convertToFormat(QImage::Format_MonoLSB, flags);            d = 1;        }    } else {                                        // can be both        bool conv8 = false;        if (d > 8 && dd <= 8) {                // convert to 8 bit            if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)                flags = (flags & ~Qt::DitherMode_Mask)                        | Qt::PreferDither;            conv8 = true;        } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {            conv8 = (d == 1);                        // native depth wanted        } else if (d == 1) {            if (image.numColors() == 2) {                QRgb c0 = image.color(0);        // Auto: convert to best                QRgb c1 = image.color(1);                conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);            } else {                // eg. 1-color monochrome images (they do exist).                conv8 = true;            }        }        if (conv8) {            image = image.convertToFormat(QImage::Format_Indexed8, flags);            d = 8;        }    }

⌨️ 快捷键说明

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