kdeui Library API Documentation

kpixmapio.cpp

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