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