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

📄 qpixmap_x11.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (d == 1 || d == 16) {        QImage im = image.convertToFormat(QImage::Format_RGB32, flags);        return fromImage(im);    }    Display *dpy   = X11->display;    Visual *visual = (Visual *) pixmap.data->xinfo.visual();    XImage *xi           = 0;    bool    trucol = (visual->c_class >= TrueColor);    int     nbytes = image.numBytes();    uchar  *newbits= 0;#ifndef QT_NO_XRENDER    if (X11->use_xrender && image.hasAlphaChannel()) {        const QImage &cimage = image;        pixmap.data->w = w;        pixmap.data->h = h;        pixmap.data->d = 32;        pixmap.data->hd =            (Qt::HANDLE)XCreatePixmap(dpy, RootWindow(dpy, pixmap.data->xinfo.screen()),                                      w, h, pixmap.data->d);        pixmap.data->picture = XRenderCreatePicture(X11->display, pixmap.data->hd,                                                    XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);        xi = XCreateImage(dpy, visual, pixmap.data->d, ZPixmap, 0, 0, w, h, 32, 0);        Q_CHECK_PTR(xi);        newbits = (uchar *)malloc(xi->bytes_per_line*h);        Q_CHECK_PTR(newbits);        xi->data = (char *)newbits;        switch(cimage.format()) {        case QImage::Format_Indexed8: {            QVector<QRgb> colorTable = cimage.colorTable();            uint *xidata = (uint *)xi->data;            for (int y = 0; y < h; ++y) {                const uchar *p = cimage.scanLine(y);                for (int x = 0; x < w; ++x) {                    const QRgb rgb = colorTable[p[x]];                    const int a = qAlpha(rgb);                    if (a == 0xff)                        *xidata = rgb;                    else                        // RENDER expects premultiplied alpha                        *xidata = qRgba(qt_div_255(qRed(rgb) * a),                                        qt_div_255(qGreen(rgb) * a),                                        qt_div_255(qBlue(rgb) * a),                                        a);                    ++xidata;                }            }        }            break;        case QImage::Format_RGB32: {            uint *xidata = (uint *)xi->data;            for (int y = 0; y < h; ++y) {                const QRgb *p = (const QRgb *) cimage.scanLine(y);                for (int x = 0; x < w; ++x)                    *xidata++ = p[x] | 0xff000000;            }        }            break;        case QImage::Format_ARGB32: {            uint *xidata = (uint *)xi->data;            for (int y = 0; y < h; ++y) {                const QRgb *p = (const QRgb *) cimage.scanLine(y);                for (int x = 0; x < w; ++x) {                    const QRgb rgb = p[x];                    const int a = qAlpha(rgb);                    if (a == 0xff)                        *xidata = rgb;                    else                        // RENDER expects premultiplied alpha                        *xidata = qRgba(qt_div_255(qRed(rgb) * a),                                        qt_div_255(qGreen(rgb) * a),                                        qt_div_255(qBlue(rgb) * a),                                        a);                    ++xidata;                }            }        }            break;        case QImage::Format_ARGB32_Premultiplied: {            uint *xidata = (uint *)xi->data;            for (int y = 0; y < h; ++y) {                const QRgb *p = (const QRgb *) cimage.scanLine(y);                memcpy(xidata, p, w*sizeof(QRgb));                xidata += w;            }        }            break;        default:            Q_ASSERT(false);        }        if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {            uint *xidata = (uint *)xi->data;            uint *xiend = xidata + w*h;            while (xidata < xiend) {                *xidata = (*xidata >> 24)                          | ((*xidata >> 8) & 0xff00)                          | ((*xidata << 8) & 0xff0000)                          | (*xidata << 24);                ++xidata;            }        }        GC gc = XCreateGC(dpy, pixmap.data->hd, 0, 0);        XPutImage(dpy, pixmap.data->hd, gc, xi, 0, 0, 0, 0, w, h);        XFreeGC(dpy, gc);        qSafeXDestroyImage(xi);        return pixmap;    }#endif // QT_NO_XRENDER    if (trucol) {                                // truecolor display        if (image.format() == QImage::Format_ARGB32_Premultiplied)            image = image.convertToFormat(QImage::Format_ARGB32);        const QImage &cimage = image;        QRgb  pix[256];                                // pixel translation table        const bool  d8 = (d == 8);        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  rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;        const uint  gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;        const uint  bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;        if (d8) {                                // setup pixel translation            QVector<QRgb> ctable = cimage.colorTable();            for (int i=0; i < cimage.numColors(); i++) {                int r = qRed  (ctable[i]);                int g = qGreen(ctable[i]);                int b = qBlue (ctable[i]);                r = red_shift        > 0 ? r << red_shift   : r >> -red_shift;                g = green_shift > 0 ? g << green_shift : g >> -green_shift;                b = blue_shift        > 0 ? b << blue_shift  : b >> -blue_shift;                pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)                         | ~(blue_mask | green_mask | red_mask);            }        }        xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);        Q_CHECK_PTR(xi);        newbits = (uchar *)malloc(xi->bytes_per_line*h);        Q_CHECK_PTR(newbits);        if (!newbits)                                // no memory            return QPixmap();        int    bppc = xi->bits_per_pixel;        bool contig_bits = n_bits(red_mask) == rbits &&                           n_bits(green_mask) == gbits &&                           n_bits(blue_mask) == bbits;        bool dither_tc =            // Want it?            (flags & Qt::Dither_Mask) != Qt::ThresholdDither &&            (flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&            // Need it?            bppc < 24 && !d8 &&            // Can do it? (Contiguous bits?)            contig_bits;        static bool init=false;        static int D[16][16];        if (dither_tc && !init) {            // I also contributed this code to XV - WWA.            /*              The dither matrix, D, is obtained with this formula:              D2 = [0 2]              [3 1]              D2*n = [4*Dn       4*Dn+2*Un]              [4*Dn+3*Un  4*Dn+1*Un]            */            int n,i,j;            init=1;            /* Set D2 */            D[0][0]=0;            D[1][0]=2;            D[0][1]=3;            D[1][1]=1;            /* Expand using recursive definition given above */            for (n=2; n<16; n*=2) {                for (i=0; i<n; i++) {                    for (j=0; j<n; j++) {                        D[i][j]*=4;                        D[i+n][j]=D[i][j]+2;                        D[i][j+n]=D[i][j]+3;                        D[i+n][j+n]=D[i][j]+1;                    }                }            }            init=true;        }        enum { BPP8,               BPP16_565, BPP16_555,               BPP16_MSB, BPP16_LSB,               BPP24_888,               BPP24_MSB, BPP24_LSB,               BPP32_8888,               BPP32_MSB, BPP32_LSB        } mode = BPP8;        bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);        if(bppc == 8) // 8 bit            mode = BPP8;        else if(bppc == 16) { // 16 bit MSB/LSB            if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)                mode = BPP16_565;            else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)                mode = BPP16_555;            else                mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;        } else if(bppc == 24) { // 24 bit MSB/LSB            if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)                mode = BPP24_888;            else                mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;        } else if(bppc == 32) { // 32 bit MSB/LSB            if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)                mode = BPP32_8888;            else                mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;        } else            qFatal("Logic error 3");#define GET_PIXEL                                                       \        uint pixel;                                                     \        if (d8) pixel = pix[*src++];                                    \        else {                                                          \            int r = qRed  (*p);                                         \            int g = qGreen(*p);                                         \            int b = qBlue (*p++);                                       \            r = red_shift   > 0                                         \                ? r << red_shift   : r >> -red_shift;                   \            g = green_shift > 0                                         \                ? g << green_shift : g >> -green_shift;                 \            b = blue_shift  > 0                                         \                ? b << blue_shift  : b >> -blue_shift;                  \            pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask)   \                    | ~(blue_mask | green_mask | red_mask);             \        }#define GET_PIXEL_DITHER_TC                                             \        int r = qRed  (*p);                                             \        int g = qGreen(*p);                                             \        int b = qBlue (*p++);                                           \        const int thres = D[x%16][y%16];                                \        if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255)             \            > thres)                                                    \            r += (1<<(8-rbits));                                        \        if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255)             \            > thres)                                                    \            g += (1<<(8-gbits));                                        \        if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255)             \            > thres)                                                    \            b += (1<<(8-bbits));                                        \        r = red_shift   > 0                                             \            ? r << red_shift   : r >> -red_shift;                       \        g = green_shift > 0                                             \            ? g << green_shift : g >> -green_shift;                     \        b = blue_shift  > 0                                             \            ? b << blue_shift  : b >> -blue_shift;                      \        uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);// again, optimized case// can't be optimized that much :(#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \                                rbits,gbits,bbits)                      \        const int thres = D[x%16][y%16];                                \        int r = qRed  (*p);                                             \        if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255)             \            > thres)                                                    \            r += (1<<(8-rbits));                                        \        int g = qGreen(*p);                                             \        if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255)             \            > thres)                                                    \            g += (1<<(8-gbits));                                        \        int b = qBlue (*p++);                                           \        if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255)             \            > thres)                                                    \            b += (1<<(8-bbits));                                        \        uint pixel = ((r red_shift) & red_mask)                         \                     | ((g green_shift) & green_mask)                   \                     | ((b blue_shift) & blue_mask);#define CYCLE(body)                                             \        for (int y=0; y<h; y++) {                               \            const uchar* src = cimage.scanLine(y);              \            uchar* dst = newbits + xi->bytes_per_line*y;        \            const QRgb* p = (const QRgb *)src;                  \            body                                                \                }        if (dither_tc) {            switch (mode) {            case BPP16_565:                CYCLE(                    quint16* dst16 = (quint16*)dst;                    for (int x=0; x<w; x++) {                        GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)                            *dst16++ = pixel;                    }                    )                    break;            case BPP16_555:                CYCLE(                    quint16* dst16 = (quint16*)dst;                    for (int x=0; x<w; x++) {                        GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)                            *dst16++ = pixel;                    }                    )                    break;            case BPP16_MSB:                        // 16 bit MSB                CYCLE(                    for (int x=0; x<w; x++) {                        GET_PIXEL_DITHER_TC                            *dst++ = (pixel >> 8);                        *dst++ = pixel;                    }                    )                    break;            case BPP16_LSB:                        // 16 bit LSB                CYCLE(                    for (int x=0; x<w; x++) {                        GET_PIXEL_DITHER_TC                            *dst++ = pixel;                        *dst++ = pixel >> 8;                    }                    )                    break;            default:                qFatal("Logic error");            }        } else {            switch (mode) {            case BPP8:                        // 8 bit                CYCLE(                    Q_UNUSED(p);                    for (int x=0; x<w; x++)                        *dst++ = pix[*src++];                    )                    break;            case BPP16_565:                CYCLE(                    quint16* dst16 = (quint16*)dst;                    for (int x = 0; x < w; x++) {                        *dst16++ = ((*p >> 8) & 0xf800)                                   | ((*p >> 5) & 0x7e0)                                   | ((*p >> 3) & 0x1f);

⌨️ 快捷键说明

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