# kdeui Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kpixmapio.cpp

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

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:20 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003