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.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:57:33 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001