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 == 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
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
00375
00376 use_xshm =
false;
00377
kdDebug(290) <<
"Disabling Xshm" <<
endl;
00378
return 0;
00379 }
else {
00380
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
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
00439
00440
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
00456
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