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