kdeui Library API Documentation

kpixmapio.cpp

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