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