kdeui Library API Documentation

kpixmapio.cpp

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