kdeui Library API Documentation

kpixmapio.cpp

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