00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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 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
00123
00124
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
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
00373
00374 use_xshm =
false;
00375
kdDebug(290) <<
"Disabling Xshm" <<
endl;
00376
return 0;
00377 }
else {
00378
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
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
00437
00438
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
00454
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