kdeui Library API Documentation

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