diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch) | |
tree | 5ac38a06f3dde268dc7927dc155896926aaf7012 /kdeui/kpixmapio.cpp | |
download | tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdeui/kpixmapio.cpp')
-rw-r--r-- | kdeui/kpixmapio.cpp | 908 |
1 files changed, 908 insertions, 0 deletions
diff --git a/kdeui/kpixmapio.cpp b/kdeui/kpixmapio.cpp new file mode 100644 index 000000000..fd2854fb0 --- /dev/null +++ b/kdeui/kpixmapio.cpp @@ -0,0 +1,908 @@ +/* vi: ts=8 sts=4 sw=4 + * + * + * This file is part of the KDE project, module kdeui. + * Copyright (C) 2000 Geert Jansen <jansen@kde.org>. + * + * You can Freely distribute this program under the GNU Library General + * Public License. See the file "COPYING.LIB" for the exact licensing terms. + * + * kpixmapio.cpp: Fast pixmap <-> image conversion. + */ + +#include "kpixmapio.h" +#include "config.h" + +#include <qimage.h> +#include <qpixmap.h> +#include <qcolor.h> +#include <qglobal.h> + +#include <kglobal.h> +#include <kconfig.h> +#include <kdebug.h> + +#include <sys/types.h> +#ifdef Q_OS_UNIX +#include <sys/ipc.h> +#include <sys/shm.h> +#endif + +#ifdef Q_WS_X11 +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#ifdef HAVE_MITSHM +#include <X11/extensions/XShm.h> +#endif +#ifdef __osf__ +extern "C" int XShmQueryExtension(Display *display); +#endif +#else +#undef HAVE_MITSHM +#endif + +// d pointer + +struct KPixmapIOPrivate +{ + int shmsize; + int shmpolicy; + int threshold; + int bpp; + int byteorder; +#ifdef Q_WS_X11 + XImage *ximage; +#ifdef HAVE_MITSHM + XShmSegmentInfo *shminfo; + bool first_try; +#endif +#else + void *ximage; +#endif +}; + + +// From Qt: Returns the position of the lowest set bit in val. + +typedef unsigned char uchar; +typedef unsigned int uint; + +#ifdef HAVE_MITSHM +static int lowest_bit(uint val) +{ + int i; + uint test = 1; + for (i=0; (!(val & test)) && i<32; i++, test<<=1); + return (i == 32) ? -1 : i; +} +#endif + +/*** KPixmapIO ***/ + +KPixmapIO::KPixmapIO() +{ + m_bShm = false; + d = new KPixmapIOPrivate; + +#ifdef HAVE_MITSHM + setShmPolicy(ShmDontKeep); + KConfig *config = KGlobal::config(); + if (!config->readBoolEntry("UseMitShm", true)) + return; + + int ignore; + if (XQueryExtension(qt_xdisplay(), "MIT-SHM", &ignore, &ignore, &ignore)) + { + if (XShmQueryExtension(qt_xdisplay())) + m_bShm = true; + } + if (!m_bShm) + { + kdDebug(290) << k_lineinfo << "MIT-SHM not available!\n"; + d->ximage = 0; + d->shminfo = 0; + d->shmsize = 0; + return; + } + + // Sort out bit format. Create a temporary XImage for this. + d->shminfo = new XShmSegmentInfo; + d->ximage = XShmCreateImage(qt_xdisplay(), (Visual *) QPaintDevice::x11AppVisual(), + QPaintDevice::x11AppDepth(), ZPixmap, 0L, d->shminfo, 10, 10); + d->bpp = d->ximage->bits_per_pixel; + d->first_try = true; + int bpp = d->bpp; + if (d->ximage->byte_order == LSBFirst) + bpp++; + int red_shift = lowest_bit(d->ximage->red_mask); + int green_shift = lowest_bit(d->ximage->green_mask); + int blue_shift = lowest_bit(d->ximage->blue_mask); + XDestroyImage(d->ximage); d->ximage = 0L; + d->shmsize = 0; + + // Offer discrete possibilities for the bitformat. Each will have its + // own routine. The general algorithm using bitshifts is much too slow; + // this has to be done for every pixel! + + if ((bpp == 32) && (red_shift == 16) && (green_shift == 8) && + (blue_shift == 0)) + d->byteorder = bo32_ARGB; + else if ((bpp == 32) && (red_shift == 0) && (green_shift == 8) && + (blue_shift == 16)) + d->byteorder = bo32_BGRA; + else if ((bpp == 33) && (red_shift == 16) && (green_shift == 8) && + (blue_shift == 0)) + d->byteorder = bo32_BGRA; + else if ((bpp == 24) && (red_shift == 16) && (green_shift == 8) && + (blue_shift == 0)) + d->byteorder = bo24_RGB; + else if ((bpp == 24) && (red_shift == 0) && (green_shift == 8) && + (blue_shift == 16)) + d->byteorder = bo24_BGR; + else if ((bpp == 25) && (red_shift == 16) && (green_shift == 8) && + (blue_shift == 0)) + d->byteorder = bo24_BGR; + else if ((bpp == 16) && (red_shift == 11) && (green_shift == 5) && + (blue_shift == 0)) + d->byteorder = bo16_RGB_565; + else if ((bpp == 16) && (red_shift == 10) && (green_shift == 5) && + (blue_shift == 0)) + d->byteorder = bo16_RGB_555; + else if ((bpp == 17) && (red_shift == 11) && (green_shift == 5) && + (blue_shift == 0)) + d->byteorder = bo16_BGR_565; + else if ((bpp == 17) && (red_shift == 10) && (green_shift == 5) && + (blue_shift == 0)) + d->byteorder = bo16_BGR_555; + else if ((bpp == 8) || (bpp == 9)) + d->byteorder = bo8; + else + { + m_bShm = false; + kdWarning(290) << "Byte order not supported!" << endl; + kdWarning(290) << "red = " << red_shift + << ", green = " << green_shift + << ", blue = " << blue_shift << endl; + kdWarning(290) << "Please report to <jansen@kde.org>\n"; + } +#else + d->shmsize = 0; + d->ximage = 0; +#endif +} + + +KPixmapIO::~KPixmapIO() +{ + destroyXImage(); + destroyShmSegment(); +#ifdef HAVE_MITSHM + delete d->shminfo; +#endif + delete d; +} + + +QPixmap KPixmapIO::convertToPixmap(const QImage &img) +{ + int size = img.width() * img.height(); + if (m_bShm && (img.depth() > 1) && (d->bpp > 8) && (size > d->threshold)) + { + QPixmap dst(img.width(), img.height()); + putImage(&dst, 0, 0, &img); + return dst; + } else + { + QPixmap dst; + dst.convertFromImage(img); + return dst; + } + +} + + +QImage KPixmapIO::convertToImage(const QPixmap &pm) +{ + QImage image; + int size = pm.width() * pm.height(); + if (m_bShm && (d->bpp >= 8) && (size > d->threshold)) + image = getImage(&pm, 0, 0, pm.width(), pm.height()); + else + image = pm.convertToImage(); + return image; +} + + +void KPixmapIO::putImage(QPixmap *dst, const QPoint &offset, + const QImage *src) +{ + putImage(dst, offset.x(), offset.y(), src); +} + + +void KPixmapIO::putImage(QPixmap *dst, int dx, int dy, const QImage *src) +{ + int size = src->width() * src->height(); + bool fallback = true; + if (m_bShm && (src->depth() > 1) && (d->bpp > 8) && (size > d->threshold)) + { +#ifdef HAVE_MITSHM + if( initXImage(src->width(), src->height())) + { + convertToXImage(*src); + XShmPutImage(qt_xdisplay(), dst->handle(), qt_xget_temp_gc(qt_xscreen(), false), d->ximage, + dx, dy, 0, 0, src->width(), src->height(), false); + // coolo: do we really need this here? I see no good for it + XSync(qt_xdisplay(), false); + doneXImage(); + fallback = false; + } +#endif + } + if( fallback ) + { + QPixmap pix; + pix.convertFromImage(*src); + bitBlt(dst, dx, dy, &pix, 0, 0, pix.width(), pix.height()); + } +} + + +QImage KPixmapIO::getImage(const QPixmap *src, const QRect &rect) +{ + return getImage(src, rect.x(), rect.y(), rect.width(), rect.height()); +} + + +QImage KPixmapIO::getImage(const QPixmap *src, int sx, int sy, int sw, int sh) +{ + QImage image; + int size = src->width() * src->height(); + bool fallback = true; + if ((m_bShm) && (d->bpp >= 8) && (size > d->threshold)) + { +#ifdef HAVE_MITSHM + if( initXImage(sw, sh)) + { + XShmGetImage(qt_xdisplay(), src->handle(), d->ximage, sx, sy, AllPlanes); + image = convertFromXImage(); + doneXImage(); + fallback = false; + } +#endif + } + if( fallback ) + { + QPixmap pix(sw, sh); + bitBlt(&pix, 0, 0, src, sx, sy, sw, sh); + image = pix.convertToImage(); + } + return image; +} + + +#ifdef HAVE_MITSHM + +void KPixmapIO::preAllocShm(int size) +{ + destroyXImage(); + createShmSegment(size); +} + + +void KPixmapIO::setShmPolicy(int policy) +{ + switch (policy) + { + case ShmDontKeep: + d->shmpolicy = ShmDontKeep; + d->threshold = 5000; + break; + case ShmKeepAndGrow: + d->shmpolicy = ShmKeepAndGrow; + d->threshold = 2000; + break; + default: + break; + } +} + + +bool KPixmapIO::initXImage(int w, int h) +{ + if (d->ximage && (w == d->ximage->width) && (h == d->ximage->height)) + return true; + + if( !createXImage(w, h)) + return false; + int size = d->ximage->bytes_per_line * d->ximage->height; + if (size > d->shmsize) + { + if( !createShmSegment(size)) + { + destroyXImage(); + return false; + } + } + d->ximage->data = d->shminfo->shmaddr; + return true; +} + + +void KPixmapIO::doneXImage() +{ + if (d->shmpolicy == ShmDontKeep) + { + destroyXImage(); + destroyShmSegment(); + } +} + + +void KPixmapIO::destroyXImage() +{ + if (d->ximage) + { + XDestroyImage(d->ximage); + d->ximage = 0L; + } +} + + +bool KPixmapIO::createXImage(int w, int h) +{ + destroyXImage(); + d->ximage = XShmCreateImage(qt_xdisplay(), (Visual *) QPaintDevice::x11AppVisual(), + QPaintDevice::x11AppDepth(), ZPixmap, 0L, d->shminfo, w, h); + return d->ximage != None; +} + + +void KPixmapIO::destroyShmSegment() +{ + if (d->shmsize) + { + XShmDetach(qt_xdisplay(), d->shminfo); + shmdt(d->shminfo->shmaddr); + shmctl(d->shminfo->shmid, IPC_RMID, 0); + d->shmsize = 0; + } +} + +static bool use_xshm = true; +static unsigned long kpixmapio_serial; +static int (*old_errhandler)(Display *dpy, XErrorEvent *ev) = 0; + +static int kpixmapio_errorhandler(Display *dpy, XErrorEvent *ev) +{ + if(ev->serial == kpixmapio_serial) { + /* assuming that xshm errors mean it can't be used at all + (e.g. remote display) */ + use_xshm = false; + kdDebug(290) << "Disabling Xshm" << endl; + return 0; + } else { + // another error + return old_errhandler(dpy, ev); + } +} + +bool KPixmapIO::createShmSegment(int size) +{ + destroyShmSegment(); + d->shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0600); + if ( d->shminfo->shmid < 0) + { + kdWarning(290) << "Could not get shared memory segment.\n"; + m_bShm = false; + return false; + } + + d->shminfo->shmaddr = (char *) shmat(d->shminfo->shmid, 0, 0); + if (d->shminfo->shmaddr == (char *)-1) + { + kdWarning(290) << "Could not attach shared memory segment.\n"; + m_bShm = false; + shmctl(d->shminfo->shmid, IPC_RMID, 0); + return false; + } + + d->shminfo->readOnly = false; + + if (d->first_try) { + // make sure that we don't get errors of old stuff + XSync(qt_xdisplay(), False); + old_errhandler = XSetErrorHandler(kpixmapio_errorhandler); + kpixmapio_serial = NextRequest(qt_xdisplay()); + } + + if ( !XShmAttach(qt_xdisplay(), d->shminfo)) + { + kdWarning() << "X-Server could not attach shared memory segment.\n"; + m_bShm = false; + shmdt(d->shminfo->shmaddr); + shmctl(d->shminfo->shmid, IPC_RMID, 0); + } + + if (d->first_try) { + XSync(qt_xdisplay(), false); + + if (!use_xshm) + m_bShm = false; + + XSetErrorHandler(old_errhandler); + d->first_try = false; + } + d->shmsize = size; + + return m_bShm; +} + + +/* + * The following functions convertToXImage/convertFromXImage are a little + * long. This is because of speed, I want to get as much out of the inner + * loop as possible. + */ + +QImage KPixmapIO::convertFromXImage() +{ + int x, y; + int width = d->ximage->width, height = d->ximage->height; + int bpl = d->ximage->bytes_per_line; + char *data = d->ximage->data; + + QImage image; + if (d->bpp == 8) + { + image.create(width, height, 8); + + // Query color map. Don't remove unused entries as a speed + // optmization. + int i, ncells = 256; + XColor *cmap = new XColor[ncells]; + for (i=0; i<ncells; i++) + cmap[i].pixel = i; + XQueryColors(qt_xdisplay(), QPaintDevice::x11AppColormap(), + cmap, ncells); + image.setNumColors(ncells); + for (i=0; i<ncells; i++) + image.setColor(i, qRgb(cmap[i].red, cmap[i].green, cmap[i].blue >> 8)); + } else + image.create(width, height, 32); + + switch (d->byteorder) + { + + case bo8: + { + for (y=0; y<height; y++) + memcpy(image.scanLine(y), data + y*bpl, width); + break; + } + + case bo16_RGB_565: + case bo16_BGR_565: + { + Q_INT32 pixel, *src; + QRgb *dst, val; + for (y=0; y<height; y++) + { + src = (Q_INT32 *) (data + y*bpl); + dst = (QRgb *) image.scanLine(y); + for (x=0; x<width/2; x++) + { + pixel = *src++; + val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) | + ((pixel & 0x1f) << 3); + *dst++ = val; + pixel >>= 16; + val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) | + ((pixel & 0x1f) << 3); + *dst++ = val; + } + if (width%2) + { + pixel = *src++; + val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) | + ((pixel & 0x1f) << 3); + *dst++ = val; + } + } + break; + } + + case bo16_RGB_555: + case bo16_BGR_555: + { + Q_INT32 pixel, *src; + QRgb *dst, val; + for (y=0; y<height; y++) + { + src = (Q_INT32 *) (data + y*bpl); + dst = (QRgb *) image.scanLine(y); + for (x=0; x<width/2; x++) + { + pixel = *src++; + val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) | + ((pixel & 0x1f) << 3); + *dst++ = val; + pixel >>= 16; + val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) | + ((pixel & 0x1f) << 3); + *dst++ = val; + } + if (width%2) + { + pixel = *src++; + val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) | + ((pixel & 0x1f) << 3); + *dst++ = val; + } + } + break; + } + + case bo24_RGB: + { + char *src; + QRgb *dst; + int w1 = width/4; + Q_INT32 d1, d2, d3; + for (y=0; y<height; y++) + { + src = data + y*bpl; + dst = (QRgb *) image.scanLine(y); + for (x=0; x<w1; x++) + { + d1 = *((Q_INT32 *)src); + d2 = *((Q_INT32 *)src + 1); + d3 = *((Q_INT32 *)src + 2); + src += 12; + *dst++ = d1; + *dst++ = (d1 >> 24) | (d2 << 8); + *dst++ = (d3 << 16) | (d2 >> 16); + *dst++ = d3 >> 8; + } + for (x=w1*4; x<width; x++) + { + d1 = *src++ << 16; + d1 += *src++ << 8; + d1 += *src++; + *dst++ = d1; + } + } + break; + } + + case bo24_BGR: + { + char *src; + QRgb *dst; + int w1 = width/4; + Q_INT32 d1, d2, d3; + for (y=0; y<height; y++) + { + src = data + y*bpl; + dst = (QRgb *) image.scanLine(y); + for (x=0; x<w1; x++) + { + d1 = *((Q_INT32 *)src); + d2 = *((Q_INT32 *)src + 1); + d3 = *((Q_INT32 *)src + 2); + src += 12; + *dst++ = d1; + *dst++ = (d1 >> 24) | (d2 << 8); + *dst++ = (d3 << 16) | (d2 >> 16); + *dst++ = d3 >> 8; + } + for (x=w1*4; x<width; x++) + { + d1 = *src++; + d1 += *src++ << 8; + d1 += *src++ << 16; + *dst++ = d1; + } + } + break; + } + + case bo32_ARGB: + case bo32_BGRA: + { + for (y=0; y<height; y++) + memcpy(image.scanLine(y), data + y*bpl, width*4); + break; + } + + } + + return image; +} + + +void KPixmapIO::convertToXImage(const QImage &img) +{ + int x, y; + int width = d->ximage->width, height = d->ximage->height; + int bpl = d->ximage->bytes_per_line; + char *data = d->ximage->data; + + switch (d->byteorder) + { + + case bo16_RGB_555: + case bo16_BGR_555: + + if (img.depth() == 32) + { + QRgb *src, pixel; + Q_INT32 *dst, val; + for (y=0; y<height; y++) + { + src = (QRgb *) img.scanLine(y); + dst = (Q_INT32 *) (data + y*bpl); + for (x=0; x<width/2; x++) + { + pixel = *src++; + val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | + ((pixel & 0xff) >> 3); + pixel = *src++; + val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | + ((pixel & 0xff) >> 3)) << 16; + *dst++ = val; + } + if (width%2) + { + pixel = *src++; + *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 9) | + ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3); + } + } + } else + { + uchar *src; + Q_INT32 val, *dst; + QRgb pixel, *clut = img.colorTable(); + for (y=0; y<height; y++) + { + src = img.scanLine(y); + dst = (Q_INT32 *) (data + y*bpl); + for (x=0; x<width/2; x++) + { + pixel = clut[*src++]; + val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | + ((pixel & 0xff) >> 3); + pixel = clut[*src++]; + val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | + ((pixel & 0xff) >> 3)) << 16; + *dst++ = val; + } + if (width%2) + { + pixel = clut[*src++]; + *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 9) | + ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3); + } + } + } + break; + + case bo16_RGB_565: + case bo16_BGR_565: + + if (img.depth() == 32) + { + QRgb *src, pixel; + Q_INT32 *dst, val; + for (y=0; y<height; y++) + { + src = (QRgb *) img.scanLine(y); + dst = (Q_INT32 *) (data + y*bpl); + for (x=0; x<width/2; x++) + { + pixel = *src++; + val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | + ((pixel & 0xff) >> 3); + pixel = *src++; + val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | + ((pixel & 0xff) >> 3)) << 16; + *dst++ = val; + } + if (width%2) + { + pixel = *src++; + *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 8) | + ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3); + } + } + } else + { + uchar *src; + Q_INT32 val, *dst; + QRgb pixel, *clut = img.colorTable(); + for (y=0; y<height; y++) + { + src = img.scanLine(y); + dst = (Q_INT32 *) (data + y*bpl); + for (x=0; x<width/2; x++) + { + pixel = clut[*src++]; + val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | + ((pixel & 0xff) >> 3); + pixel = clut[*src++]; + val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | + ((pixel & 0xff) >> 3)) << 16; + *dst++ = val; + } + if (width%2) + { + pixel = clut[*src++]; + *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 8) | + ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3); + } + } + } + break; + + case bo24_RGB: + + if (img.depth() == 32) + { + char *dst; + int w1 = width/4; + QRgb *src, d1, d2, d3, d4; + for (y=0; y<height; y++) + { + src = (QRgb *) img.scanLine(y); + dst = data + y*bpl; + for (x=0; x<w1; x++) + { + d1 = (*src++ & 0xffffff); + d2 = (*src++ & 0xffffff); + d3 = (*src++ & 0xffffff); + d4 = (*src++ & 0xffffff); + *((Q_INT32 *)dst) = d1 | (d2 << 24); + *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); + *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); + dst += 12; + } + for (x=w1*4; x<width; x++) + { + d1 = *src++; + *dst++ = qRed(d1); + *dst++ = qGreen(d1); + *dst++ = qBlue(d1); + } + } + } else + { + uchar *src, *dst; + int w1 = width/4; + QRgb *clut = img.colorTable(), d1, d2, d3, d4; + for (y=0; y<height; y++) + { + src = img.scanLine(y); + dst = (uchar *) data + y*bpl; + for (x=0; x<w1; x++) + { + d1 = (clut[*src++] & 0xffffff); + d2 = (clut[*src++] & 0xffffff); + d3 = (clut[*src++] & 0xffffff); + d4 = (clut[*src++] & 0xffffff); + *((Q_INT32 *)dst) = d1 | (d2 << 24); + *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); + *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); + dst += 12; + } + for (x=w1*4; x<width; x++) + { + d1 = clut[*src++]; + *dst++ = qRed(d1); + *dst++ = qGreen(d1); + *dst++ = qBlue(d1); + } + } + } + break; + + case bo24_BGR: + + if (img.depth() == 32) + { + char *dst; + QRgb *src, d1, d2, d3, d4; + int w1 = width/4; + for (y=0; y<height; y++) + { + src = (QRgb *) img.scanLine(y); + dst = data + y*bpl; + for (x=0; x<w1; x++) + { + d1 = (*src++ & 0xffffff); + d2 = (*src++ & 0xffffff); + d3 = (*src++ & 0xffffff); + d4 = (*src++ & 0xffffff); + *((Q_INT32 *)dst) = d1 | (d2 << 24); + *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); + *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); + dst += 12; + } + for (x=w1*4; x<width; x++) + { + d1 = *src++; + *dst++ = qBlue(d1); + *dst++ = qGreen(d1); + *dst++ = qRed(d1); + } + } + } else + { + uchar *src, *dst; + int w1 = width/4; + QRgb *clut = img.colorTable(), d1, d2, d3, d4; + for (y=0; y<height; y++) + { + src = img.scanLine(y); + dst = (uchar *) data + y*bpl; + for (x=0; x<w1; x++) + { + d1 = (clut[*src++] & 0xffffff); + d2 = (clut[*src++] & 0xffffff); + d3 = (clut[*src++] & 0xffffff); + d4 = (clut[*src++] & 0xffffff); + *((Q_INT32 *)dst) = d1 | (d2 << 24); + *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); + *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); + dst += 12; + } + for (x=w1*4; x<width; x++) + { + d1 = clut[*src++]; + *dst++ = qBlue(d1); + *dst++ = qGreen(d1); + *dst++ = qRed(d1); + } + } + } + break; + + case bo32_ARGB: + case bo32_BGRA: + + if (img.depth() == 32) + { + for (y=0; y<height; y++) + memcpy(data + y*bpl, img.scanLine(y), width*4); + } else + { + uchar *src; + QRgb *dst, *clut = img.colorTable(); + for (y=0; y<height; y++) + { + src = img.scanLine(y); + dst = (QRgb *) (data + y*bpl); + for (x=0; x<width; x++) + *dst++ = clut[*src++]; + } + } + break; + + } +} + +#else + +void KPixmapIO::preAllocShm(int) {} +void KPixmapIO::setShmPolicy(int) {} +bool KPixmapIO::initXImage(int, int) { return false; } +void KPixmapIO::doneXImage() {} +bool KPixmapIO::createXImage(int, int) { return false; } +void KPixmapIO::destroyXImage() {} +bool KPixmapIO::createShmSegment(int) { return false; } +void KPixmapIO::destroyShmSegment() {} +QImage KPixmapIO::convertFromXImage() { return QImage(); } +void KPixmapIO::convertToXImage(const QImage &) {} + +#endif // HAVE_MITSHM |