kdeui Library API Documentation

kpixmapio.cpp

00001 /* vi: ts=8 sts=4 sw=4
00002  *
00003  * $Id: kpixmapio.cpp,v 1.29 2003/09/03 15:33:18 schroder Exp $
00004  *
00005  * This file is part of the KDE project, module kdeui.
00006  * Copyright (C) 2000 Geert Jansen <jansen@kde.org>.
00007  *
00008  * You can Freely distribute this program under the GNU Library General
00009  * Public License. See the file "COPYING.LIB" for the exact licensing terms.
00010  *
00011  * kpixmapio.cpp: Fast pixmap <-> image conversion.
00012  */
00013 
00014 #include "config.h"
00015 
00016 #include <sys/types.h>
00017 #include <sys/ipc.h>
00018 #include <sys/shm.h>
00019 
00020 #include <qimage.h>
00021 #include <qpixmap.h>
00022 #include <qcolor.h>
00023 #include <qglobal.h>
00024 
00025 #include <kglobal.h>
00026 #include <kconfig.h>
00027 #include <kdebug.h>
00028 #include "kpixmapio.h"
00029 
00030 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00031 #include <X11/X.h> // schroder
00032 #include <X11/Xlib.h> // schroder
00033 #include <X11/Xutil.h> // schroder
00034 #ifdef HAVE_MITSHM
00035 #include <X11/extensions/XShm.h> // schroder
00036 #endif
00037 #ifdef __osf__
00038 extern "C" int XShmQueryExtension(Display *display);
00039 #endif
00040 #else
00041 #undef HAVE_MITSHM
00042 #endif
00043 
00044 // d pointer
00045 
00046 struct KPixmapIOPrivate
00047 {
00048     int shmsize;
00049     int shmpolicy;
00050     int threshold;
00051     int bpp;
00052     int byteorder;
00053 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00054     XImage *ximage;
00055 #ifdef HAVE_MITSHM
00056     XShmSegmentInfo *shminfo;
00057     bool first_try;
00058 #endif
00059 #else
00060     void *ximage;
00061 #endif
00062 };
00063 
00064 
00065 //  From Qt: Returns the position of the lowest set bit in val.
00066 
00067 typedef unsigned char uchar;
00068 typedef unsigned int uint;
00069 
00070 #ifdef HAVE_MITSHM
00071 static int lowest_bit(uint val)
00072 {
00073     int i;
00074     uint test = 1;
00075     for (i=0; ((val & test) == 0) && i<32; i++, test<<=1);
00076     return (i == 32) ? -1 : i;
00077 }
00078 #endif
00079 
00080 /*** KPixmapIO ***/
00081 
00082 KPixmapIO::KPixmapIO()
00083 {
00084     m_bShm = false;
00085     d = new KPixmapIOPrivate;
00086 
00087 #ifdef HAVE_MITSHM
00088     setShmPolicy(ShmDontKeep);
00089     KConfig *config = KGlobal::config();
00090     if (!config->readBoolEntry("UseMitShm", true))
00091     return;
00092 
00093     int ignore;
00094     if (XQueryExtension(qt_xdisplay(), "MIT-SHM", &ignore, &ignore, &ignore))
00095     {
00096     if (XShmQueryExtension(qt_xdisplay()))
00097         m_bShm = true;
00098     }
00099     if (!m_bShm)
00100     {
00101     kdDebug(290) << k_lineinfo << "MIT-SHM not available!\n";
00102         d->ximage = 0;
00103     d->shminfo = 0;
00104     d->shmsize = 0;
00105     return;
00106     }
00107 
00108     // Sort out bit format. Create a temporary XImage for this.
00109     d->shminfo = new XShmSegmentInfo;
00110     d->ximage = XShmCreateImage(qt_xdisplay(), (Visual *) QPaintDevice::x11AppVisual(),
00111         QPaintDevice::x11AppDepth(), ZPixmap, 0L, d->shminfo, 10, 10);
00112     d->bpp = d->ximage->bits_per_pixel;
00113     d->first_try = true;
00114     int bpp = d->bpp;
00115     if (d->ximage->byte_order == LSBFirst)
00116     bpp++;
00117     int red_shift = lowest_bit(d->ximage->red_mask);
00118     int green_shift = lowest_bit(d->ximage->green_mask);
00119     int blue_shift = lowest_bit(d->ximage->blue_mask);
00120     XDestroyImage(d->ximage); d->ximage = 0L;
00121     d->shmsize = 0;
00122 
00123     // Offer discrete possibilities for the bitformat. Each will have its
00124     // own routine. The general algorithm using bitshifts is much too slow;
00125     // this has to be done for every pixel!
00126 
00127     if ((bpp == 32) && (red_shift == 16) && (green_shift == 8) &&
00128         (blue_shift == 0))
00129     d->byteorder = bo32_ARGB;
00130     else if ((bpp == 33) && (red_shift == 16) && (green_shift == 8) &&
00131         (blue_shift == 0))
00132     d->byteorder = bo32_BGRA;
00133     else if ((bpp == 24) && (red_shift == 16) && (green_shift == 8) &&
00134         (blue_shift == 0))
00135     d->byteorder = bo24_RGB;
00136     else if ((bpp == 25) && (red_shift == 16) && (green_shift == 8) &&
00137         (blue_shift == 0))
00138     d->byteorder = bo24_BGR;
00139     else if ((bpp == 16) && (red_shift == 11) && (green_shift == 5) &&
00140         (blue_shift == 0))
00141     d->byteorder = bo16_RGB_565;
00142     else if ((bpp == 16) && (red_shift == 10) && (green_shift == 5) &&
00143         (blue_shift == 0))
00144     d->byteorder = bo16_RGB_555;
00145     else if ((bpp == 17) && (red_shift == 11) && (green_shift == 5) &&
00146         (blue_shift == 0))
00147     d->byteorder = bo16_BGR_565;
00148     else if ((bpp == 17) && (red_shift == 10) && (green_shift == 5) &&
00149         (blue_shift == 0))
00150     d->byteorder = bo16_BGR_555;
00151     else if ((bpp == 8) || (bpp == 9))
00152     d->byteorder = bo8;
00153     else
00154     {
00155     m_bShm = false;
00156     kdWarning(290) << "Byte order not supported!" << endl;
00157     kdWarning(290) << "red = " << red_shift
00158         << ", green = " << green_shift
00159         << ", blue = " << blue_shift << endl;
00160     kdWarning(290) << "Please report to <jansen@kde.org>\n";
00161     }
00162 #else
00163     d->shmsize = 0;
00164     d->ximage = 0;
00165 #endif
00166 }
00167 
00168 
00169 KPixmapIO::~KPixmapIO()
00170 {
00171     destroyXImage();
00172     destroyShmSegment();
00173 #ifdef HAVE_MITSHM
00174     delete d->shminfo;
00175 #endif
00176     delete d;
00177 }
00178 
00179 
00180 QPixmap KPixmapIO::convertToPixmap(const QImage &img)
00181 {
00182     int size = img.width() * img.height();
00183     if (m_bShm && (img.depth() > 1) && (d->bpp > 8) && (size > d->threshold))
00184     {
00185     QPixmap dst(img.width(), img.height());
00186     putImage(&dst, 0, 0, &img);
00187     return dst;
00188     } else
00189     {
00190     QPixmap dst;
00191     dst.convertFromImage(img);
00192     return dst;
00193     }
00194 
00195 }
00196 
00197 
00198 QImage KPixmapIO::convertToImage(const QPixmap &pm)
00199 {
00200     QImage image;
00201     int size = pm.width() * pm.height();
00202     if (m_bShm && (d->bpp >= 8) && (size > d->threshold))
00203     image = getImage(&pm, 0, 0, pm.width(), pm.height());
00204     else
00205     image = pm.convertToImage();
00206     return image;
00207 }
00208 
00209 
00210 void KPixmapIO::putImage(QPixmap *dst, const QPoint &offset,
00211     const QImage *src)
00212 {
00213     putImage(dst, offset.x(), offset.y(), src);
00214 }
00215 
00216 
00217 void KPixmapIO::putImage(QPixmap *dst, int dx, int dy, const QImage *src)
00218 {
00219     int size = src->width() * src->height();
00220     bool fallback = true;
00221     if (m_bShm && (src->depth() > 1) && (d->bpp > 8) && (size > d->threshold))
00222     {
00223 #ifdef HAVE_MITSHM
00224     if( initXImage(src->width(), src->height()))
00225     {
00226         convertToXImage(*src);
00227         XShmPutImage(qt_xdisplay(), dst->handle(), qt_xget_temp_gc(qt_xscreen(), false), d->ximage,
00228             dx, dy, 0, 0, src->width(), src->height(), false);
00229             // coolo: do we really need this here? I see no good for it
00230         XSync(qt_xdisplay(), false);
00231         doneXImage();
00232         fallback  = false;
00233     }
00234 #endif
00235     }
00236     if( fallback )
00237     {
00238     QPixmap pix;
00239     pix.convertFromImage(*src);
00240     bitBlt(dst, dx, dy, &pix, 0, 0, pix.width(), pix.height());
00241     }
00242 }
00243 
00244 
00245 QImage KPixmapIO::getImage(const QPixmap *src, const QRect &rect)
00246 {
00247     return getImage(src, rect.x(), rect.y(), rect.width(), rect.height());
00248 }
00249 
00250 
00251 QImage KPixmapIO::getImage(const QPixmap *src, int sx, int sy, int sw, int sh)
00252 {
00253     QImage image;
00254     int size = src->width() * src->height();
00255     bool fallback = true;
00256     if ((m_bShm) && (d->bpp >= 8) && (size > d->threshold))
00257     {
00258 #ifdef HAVE_MITSHM
00259     if( initXImage(sw, sh))
00260     {
00261         XShmGetImage(qt_xdisplay(), src->handle(), d->ximage, sx, sy, AllPlanes);
00262         image = convertFromXImage();
00263         doneXImage();
00264         fallback = false;
00265     }
00266 #endif
00267     }
00268     if( fallback )
00269     {
00270     QPixmap pix(sw, sh);
00271     bitBlt(&pix, 0, 0, src, sx, sy, sw, sh);
00272     image = pix.convertToImage();
00273     }
00274     return image;
00275 }
00276 
00277 
00278 #ifdef HAVE_MITSHM
00279 
00280 void KPixmapIO::preAllocShm(int size)
00281 {
00282     destroyXImage();
00283     createShmSegment(size);
00284 }
00285 
00286 
00287 void KPixmapIO::setShmPolicy(int policy)
00288 {
00289     switch (policy)
00290     {
00291     case ShmDontKeep:
00292     d->shmpolicy = ShmDontKeep;
00293     d->threshold = 5000;
00294     break;
00295     case ShmKeepAndGrow:
00296     d->shmpolicy = ShmKeepAndGrow;
00297     d->threshold = 2000;
00298     break;
00299     default:
00300     break;
00301     }
00302 }
00303 
00304 
00305 bool KPixmapIO::initXImage(int w, int h)
00306 {
00307     if (d->ximage && (w == d->ximage->width) && (h == d->ximage->height))
00308     return true;
00309 
00310     if( !createXImage(w, h))
00311     return false;
00312     int size = d->ximage->bytes_per_line * d->ximage->height;
00313     if (size > d->shmsize)
00314     {
00315     if( !createShmSegment(size))
00316     {
00317         destroyXImage();
00318         return false;
00319     }
00320     }
00321     d->ximage->data = d->shminfo->shmaddr;
00322     return true;
00323 }
00324 
00325 
00326 void KPixmapIO::doneXImage()
00327 {
00328     if (d->shmpolicy == ShmDontKeep)
00329     {
00330     destroyXImage();
00331     destroyShmSegment();
00332     }
00333 }
00334 
00335 
00336 void KPixmapIO::destroyXImage()
00337 {
00338     if (d->ximage)
00339     {
00340     XDestroyImage(d->ximage);
00341     d->ximage = 0L;
00342     }
00343 }
00344 
00345 
00346 bool KPixmapIO::createXImage(int w, int h)
00347 {
00348     destroyXImage();
00349     d->ximage = XShmCreateImage(qt_xdisplay(), (Visual *) QPaintDevice::x11AppVisual(),
00350         QPaintDevice::x11AppDepth(), ZPixmap, 0L, d->shminfo, w, h);
00351     return d->ximage != None;
00352 }
00353 
00354 
00355 void KPixmapIO::destroyShmSegment()
00356 {
00357     if (d->shmsize)
00358     {
00359     XShmDetach(qt_xdisplay(), d->shminfo);
00360     shmdt(d->shminfo->shmaddr);
00361         shmctl(d->shminfo->shmid, IPC_RMID, 0);
00362     d->shmsize = 0;
00363     }
00364 }
00365 
00366 static bool use_xshm = true;
00367 static unsigned long kpixmapio_serial;
00368 static int (*old_errhandler)(Display *dpy, XErrorEvent *ev) = 0;
00369 
00370 static int kpixmapio_errorhandler(Display *dpy, XErrorEvent *ev)
00371 {
00372     if(ev->serial == kpixmapio_serial) {
00373         /* assuming that xshm errors mean it can't be used at all
00374            (e.g. remote display) */
00375         use_xshm = false;
00376         kdDebug(290) << "Disabling Xshm" << endl;
00377         return 0;
00378     } else {
00379         // another error
00380         return old_errhandler(dpy, ev);
00381     }
00382 }
00383 
00384 bool KPixmapIO::createShmSegment(int size)
00385 {
00386     destroyShmSegment();
00387     d->shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0600);
00388     if ( d->shminfo->shmid < 0)
00389     {
00390     kdWarning(290) << "Could not get shared memory segment.\n";
00391     m_bShm = false;
00392     return false;
00393     }
00394 
00395     d->shminfo->shmaddr = (char *) shmat(d->shminfo->shmid, 0, 0);
00396     if (d->shminfo->shmaddr == (char *)-1)
00397     {
00398     kdWarning(290) << "Could not attach shared memory segment.\n";
00399     m_bShm = false;
00400     shmctl(d->shminfo->shmid, IPC_RMID, 0);
00401     return false;
00402     }
00403 
00404     d->shminfo->readOnly = false;
00405 
00406     if (d->first_try) {
00407         // make sure that we don't get errors of old stuff
00408         XSync(qt_xdisplay(), False);
00409         old_errhandler = XSetErrorHandler(kpixmapio_errorhandler);
00410         kpixmapio_serial = NextRequest(qt_xdisplay());
00411     }
00412 
00413     if ( !XShmAttach(qt_xdisplay(), d->shminfo))
00414     {
00415     kdWarning() << "X-Server could not attach shared memory segment.\n";
00416     m_bShm = false;
00417     shmdt(d->shminfo->shmaddr);
00418     shmctl(d->shminfo->shmid, IPC_RMID, 0);
00419     }
00420 
00421     if (d->first_try) {
00422         XSync(qt_xdisplay(), false);
00423 
00424         if (!use_xshm)
00425             m_bShm = false;
00426 
00427         XSetErrorHandler(old_errhandler);
00428         d->first_try = false;
00429     }
00430     d->shmsize = size;
00431 
00432     return m_bShm;
00433 }
00434 
00435 
00436 /*
00437  * The following functions convertToXImage/convertFromXImage are a little
00438  * long. This is because of speed, I want to get as much out of the inner
00439  * loop as possible.
00440  */
00441 
00442 QImage KPixmapIO::convertFromXImage()
00443 {
00444     int x, y;
00445     int width = d->ximage->width, height = d->ximage->height;
00446     int bpl = d->ximage->bytes_per_line;
00447     char *data = d->ximage->data;
00448 
00449     QImage image;
00450     if (d->bpp == 8)
00451     {
00452     image.create(width, height, 8);
00453 
00454     // Query color map. Don't remove unused entries as a speed
00455     // optmization.
00456     int i, ncells = 256;
00457     XColor *cmap = new XColor[ncells];
00458     for (i=0; i<ncells; i++)
00459         cmap[i].pixel = i;
00460     XQueryColors(qt_xdisplay(), QPaintDevice::x11AppColormap(),
00461         cmap, ncells);
00462     image.setNumColors(ncells);
00463     for (i=0; i<ncells; i++)
00464         image.setColor(i, qRgb(cmap[i].red, cmap[i].green, cmap[i].blue >> 8));
00465     } else
00466     image.create(width, height, 32);
00467 
00468     switch (d->byteorder)
00469     {
00470 
00471     case bo8:
00472     {
00473     for (y=0; y<height; y++)
00474         memcpy(image.scanLine(y), data + y*bpl, width);
00475     break;
00476     }
00477 
00478     case bo16_RGB_565:
00479     case bo16_BGR_565:
00480     {
00481     Q_INT32 pixel, *src;
00482     QRgb *dst, val;
00483     for (y=0; y<height; y++)
00484     {
00485         src = (Q_INT32 *) (data + y*bpl);
00486         dst = (QRgb *) image.scanLine(y);
00487         for (x=0; x<width/2; x++)
00488         {
00489         pixel = *src++;
00490         val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) |
00491             ((pixel & 0x1f) << 3);
00492         *dst++ = val;
00493         pixel >>= 16;
00494         val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) |
00495             ((pixel & 0x1f) << 3);
00496         *dst++ = val;
00497         }
00498         if (width%2)
00499         {
00500         pixel = *src++;
00501         val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) |
00502             ((pixel & 0x1f) << 3);
00503         *dst++ = val;
00504         }
00505     }
00506     break;
00507     }
00508 
00509     case bo16_RGB_555:
00510     case bo16_BGR_555:
00511     {
00512     Q_INT32 pixel, *src;
00513     QRgb *dst, val;
00514     for (y=0; y<height; y++)
00515     {
00516         src = (Q_INT32 *) (data + y*bpl);
00517         dst = (QRgb *) image.scanLine(y);
00518         for (x=0; x<width/2; x++)
00519         {
00520         pixel = *src++;
00521         val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) |
00522             ((pixel & 0x1f) << 3);
00523         *dst++ = val;
00524         pixel >>= 16;
00525         val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) |
00526             ((pixel & 0x1f) << 3);
00527         *dst++ = val;
00528         }
00529         if (width%2)
00530         {
00531         pixel = *src++;
00532         val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) |
00533             ((pixel & 0x1f) << 3);
00534         *dst++ = val;
00535         }
00536     }
00537     break;
00538     }
00539 
00540     case bo24_RGB:
00541     {
00542     char *src;
00543     QRgb *dst;
00544     int w1 = width/4;
00545     Q_INT32 d1, d2, d3;
00546     for (y=0; y<height; y++)
00547     {
00548         src = data + y*bpl;
00549         dst = (QRgb *) image.scanLine(y);
00550         for (x=0; x<w1; x++)
00551         {
00552         d1 = *((Q_INT32 *)src);
00553         d2 = *((Q_INT32 *)src + 1);
00554         d3 = *((Q_INT32 *)src + 2);
00555         src += 12;
00556         *dst++ = d1;
00557         *dst++ = (d1 >> 24) | (d2 << 8);
00558         *dst++ = (d3 << 16) | (d2 >> 16);
00559         *dst++ = d3 >> 8;
00560         }
00561         for (x=w1*4; x<width; x++)
00562         {
00563         d1 = *src++ << 16;
00564         d1 += *src++ << 8;
00565         d1 += *src++;
00566         *dst++ = d1;
00567         }
00568     }
00569     break;
00570     }
00571 
00572     case bo24_BGR:
00573     {
00574     char *src;
00575     QRgb *dst;
00576     int w1 = width/4;
00577     Q_INT32 d1, d2, d3;
00578     for (y=0; y<height; y++)
00579     {
00580         src = data + y*bpl;
00581         dst = (QRgb *) image.scanLine(y);
00582         for (x=0; x<w1; x++)
00583         {
00584         d1 = *((Q_INT32 *)src);
00585         d2 = *((Q_INT32 *)src + 1);
00586         d3 = *((Q_INT32 *)src + 2);
00587         src += 12;
00588         *dst++ = d1;
00589         *dst++ = (d1 >> 24) | (d2 << 8);
00590         *dst++ = (d3 << 16) | (d2 >> 16);
00591         *dst++ = d3 >> 8;
00592         }
00593         for (x=w1*4; x<width; x++)
00594         {
00595         d1 = *src++;
00596         d1 += *src++ << 8;
00597         d1 += *src++ << 16;
00598         *dst++ = d1;
00599         }
00600     }
00601     break;
00602     }
00603 
00604     case bo32_ARGB:
00605     case bo32_BGRA:
00606     {
00607     for (y=0; y<height; y++)
00608         memcpy(image.scanLine(y), data + y*bpl, width*4);
00609     break;
00610     }
00611 
00612     }
00613 
00614     return image;
00615 }
00616 
00617 
00618 void KPixmapIO::convertToXImage(const QImage &img)
00619 {
00620     int x, y;
00621     int width = d->ximage->width, height = d->ximage->height;
00622     int bpl = d->ximage->bytes_per_line;
00623     char *data = d->ximage->data;
00624 
00625     switch (d->byteorder)
00626     {
00627 
00628     case bo16_RGB_555:
00629     case bo16_BGR_555:
00630 
00631     if (img.depth() == 32)
00632     {
00633         QRgb *src, pixel;
00634         Q_INT32 *dst, val;
00635         for (y=0; y<height; y++)
00636         {
00637         src = (QRgb *) img.scanLine(y);
00638         dst = (Q_INT32 *) (data + y*bpl);
00639         for (x=0; x<width/2; x++)
00640         {
00641             pixel = *src++;
00642             val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
00643                  ((pixel & 0xff) >> 3);
00644             pixel = *src++;
00645             val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
00646                 ((pixel & 0xff) >> 3)) << 16;
00647             *dst++ = val;
00648         }
00649         if (width%2)
00650         {
00651             pixel = *src++;
00652             *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 9) |
00653                 ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3);
00654         }
00655         }
00656     } else
00657     {
00658         uchar *src;
00659         Q_INT32 val, *dst;
00660         QRgb pixel, *clut = img.colorTable();
00661         for (y=0; y<height; y++)
00662         {
00663         src = img.scanLine(y);
00664         dst = (Q_INT32 *) (data + y*bpl);
00665         for (x=0; x<width/2; x++)
00666         {
00667             pixel = clut[*src++];
00668             val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
00669                 ((pixel & 0xff) >> 3);
00670             pixel = clut[*src++];
00671             val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
00672                 ((pixel & 0xff) >> 3)) << 16;
00673             *dst++ = val;
00674         }
00675         if (width%2)
00676         {
00677             pixel = clut[*src++];
00678             *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 9) |
00679                 ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3);
00680         }
00681         }
00682     }
00683     break;
00684 
00685     case bo16_RGB_565:
00686     case bo16_BGR_565:
00687 
00688     if (img.depth() == 32)
00689     {
00690         QRgb *src, pixel;
00691         Q_INT32 *dst, val;
00692         for (y=0; y<height; y++)
00693         {
00694         src = (QRgb *) img.scanLine(y);
00695         dst = (Q_INT32 *) (data + y*bpl);
00696         for (x=0; x<width/2; x++)
00697         {
00698             pixel = *src++;
00699             val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
00700                  ((pixel & 0xff) >> 3);
00701             pixel = *src++;
00702             val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
00703                 ((pixel & 0xff) >> 3)) << 16;
00704             *dst++ = val;
00705         }
00706         if (width%2)
00707         {
00708             pixel = *src++;
00709             *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 8) |
00710                 ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3);
00711         }
00712         }
00713     } else
00714     {
00715         uchar *src;
00716         Q_INT32 val, *dst;
00717         QRgb pixel, *clut = img.colorTable();
00718         for (y=0; y<height; y++)
00719         {
00720         src = img.scanLine(y);
00721         dst = (Q_INT32 *) (data + y*bpl);
00722         for (x=0; x<width/2; x++)
00723         {
00724             pixel = clut[*src++];
00725             val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
00726                 ((pixel & 0xff) >> 3);
00727             pixel = clut[*src++];
00728             val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
00729                 ((pixel & 0xff) >> 3)) << 16;
00730             *dst++ = val;
00731         }
00732         if (width%2)
00733         {
00734             pixel = clut[*src++];
00735             *((Q_INT16 *)dst) = ((pixel & 0xf80000) >> 8) |
00736                 ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3);
00737         }
00738         }
00739     }
00740     break;
00741 
00742     case bo24_RGB:
00743 
00744     if (img.depth() == 32)
00745     {
00746         char *dst;
00747         int w1 = width/4;
00748         QRgb *src, d1, d2, d3, d4;
00749         for (y=0; y<height; y++)
00750         {
00751         src = (QRgb *) img.scanLine(y);
00752         dst = data + y*bpl;
00753         for (x=0; x<w1; x++)
00754         {
00755             d1 = (*src++ & 0xffffff);
00756             d2 = (*src++ & 0xffffff);
00757             d3 = (*src++ & 0xffffff);
00758             d4 = (*src++ & 0xffffff);
00759             *((Q_INT32 *)dst) = d1 | (d2 << 24);
00760             *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
00761             *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
00762             dst += 12;
00763         }
00764         for (x=w1*4; x<width; x++)
00765         {
00766             d1 = *src++;
00767             *dst++ = qRed(d1);
00768             *dst++ = qGreen(d1);
00769             *dst++ = qBlue(d1);
00770         }
00771         }
00772     } else
00773     {
00774         uchar *src, *dst;
00775         int w1 = width/4;
00776         QRgb *clut = img.colorTable(), d1, d2, d3, d4;
00777         for (y=0; y<height; y++)
00778         {
00779         src = img.scanLine(y);
00780         dst = (uchar *) data + y*bpl;
00781         for (x=0; x<w1; x++)
00782         {
00783             d1 = (clut[*src++] & 0xffffff);
00784             d2 = (clut[*src++] & 0xffffff);
00785             d3 = (clut[*src++] & 0xffffff);
00786             d4 = (clut[*src++] & 0xffffff);
00787             *((Q_INT32 *)dst) = d1 | (d2 << 24);
00788             *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
00789             *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
00790             dst += 12;
00791         }
00792         for (x=w1*4; x<width; x++)
00793         {
00794             d1 = clut[*src++];
00795             *dst++ = qRed(d1);
00796             *dst++ = qGreen(d1);
00797             *dst++ = qBlue(d1);
00798         }
00799         }
00800     }
00801     break;
00802 
00803     case bo24_BGR:
00804 
00805     if (img.depth() == 32)
00806     {
00807         char *dst;
00808         QRgb *src, d1, d2, d3, d4;
00809         int w1 = width/4;
00810         for (y=0; y<height; y++)
00811         {
00812         src = (QRgb *) img.scanLine(y);
00813         dst = data + y*bpl;
00814         for (x=0; x<w1; x++)
00815         {
00816             d1 = (*src++ & 0xffffff);
00817             d2 = (*src++ & 0xffffff);
00818             d3 = (*src++ & 0xffffff);
00819             d4 = (*src++ & 0xffffff);
00820             *((Q_INT32 *)dst) = d1 | (d2 << 24);
00821             *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
00822             *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
00823             dst += 12;
00824         }
00825         for (x=w1*4; x<width; x++)
00826         {
00827             d1 = *src++;
00828             *dst++ = qBlue(d1);
00829             *dst++ = qGreen(d1);
00830             *dst++ = qRed(d1);
00831         }
00832         }
00833     } else
00834     {
00835         uchar *src, *dst;
00836         int w1 = width/4;
00837         QRgb *clut = img.colorTable(), d1, d2, d3, d4;
00838         for (y=0; y<height; y++)
00839         {
00840         src = img.scanLine(y);
00841         dst = (uchar *) data + y*bpl;
00842         for (x=0; x<w1; x++)
00843         {
00844             d1 = (clut[*src++] & 0xffffff);
00845             d2 = (clut[*src++] & 0xffffff);
00846             d3 = (clut[*src++] & 0xffffff);
00847             d4 = (clut[*src++] & 0xffffff);
00848             *((Q_INT32 *)dst) = d1 | (d2 << 24);
00849             *((Q_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
00850             *((Q_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
00851             dst += 12;
00852         }
00853         for (x=w1*4; x<width; x++)
00854         {
00855             d1 = clut[*src++];
00856             *dst++ = qBlue(d1);
00857             *dst++ = qGreen(d1);
00858             *dst++ = qRed(d1);
00859         }
00860         }
00861     }
00862     break;
00863 
00864     case bo32_ARGB:
00865     case bo32_BGRA:
00866 
00867     if (img.depth() == 32)
00868     {
00869         for (y=0; y<height; y++)
00870         memcpy(data + y*bpl, img.scanLine(y), width*4);
00871     } else
00872     {
00873         uchar *src;
00874         QRgb *dst, *clut = img.colorTable();
00875         for (y=0; y<height; y++)
00876         {
00877         src = img.scanLine(y);
00878         dst = (QRgb *) (data + y*bpl);
00879         for (x=0; x<width; x++)
00880             *dst++ = clut[*src++];
00881         }
00882     }
00883     break;
00884 
00885     }
00886 }
00887 
00888 #else
00889 
00890 void KPixmapIO::preAllocShm(int) {}
00891 void KPixmapIO::setShmPolicy(int) {}
00892 bool KPixmapIO::initXImage(int, int) { return false; }
00893 void KPixmapIO::doneXImage() {}
00894 bool KPixmapIO::createXImage(int, int) { return false; }
00895 void KPixmapIO::destroyXImage() {}
00896 bool KPixmapIO::createShmSegment(int) { return false; }
00897 void KPixmapIO::destroyShmSegment() {}
00898 QImage KPixmapIO::convertFromXImage() { return QImage(); }
00899 void KPixmapIO::convertToXImage(const QImage &) {}
00900 
00901 #endif // HAVE_MITSHM
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun May 16 22:02:07 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003