• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

kpixmapio.cpp

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

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal