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