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