| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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

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