kpixmapio.cpp
00001 /* vi: ts=8 sts=4 sw=4 00002 * 00003 * 00004 * This file is part of the KDE project, module tdeui. 00005 * Copyright (C) 2000 Geert Jansen <jansen@kde.org>. 00006 * 00007 * You can Freely distribute this program under the GNU Library General 00008 * Public License. See the file "COPYING.LIB" for the exact licensing terms. 00009 * 00010 * kpixmapio.cpp: Fast pixmap <-> image conversion. 00011 */ 00012 00013 #include "kpixmapio.h" 00014 #include "config.h" 00015 00016 #include <tqimage.h> 00017 #include <tqpixmap.h> 00018 #include <tqcolor.h> 00019 #include <tqglobal.h> 00020 00021 #include <tdeglobal.h> 00022 #include <tdeconfig.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 // d pointer 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 // From Qt: Returns the position of the lowest set bit in val. 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 /*** KPixmapIO ***/ 00082 00083 KPixmapIO::KPixmapIO() 00084 { 00085 m_bShm = false; 00086 d = new KPixmapIOPrivate; 00087 00088 #ifdef HAVE_MITSHM 00089 setShmPolicy(ShmDontKeep); 00090 TDEConfig *config = TDEGlobal::config(); 00091 if (!config->readBoolEntry("UseMitShm", true)) 00092 return; 00093 00094 int ignore; 00095 if (XQueryExtension(tqt_xdisplay(), "MIT-SHM", &ignore, &ignore, &ignore)) 00096 { 00097 if (XShmQueryExtension(tqt_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 // Sort out bit format. Create a temporary XImage for this. 00110 d->shminfo = new XShmSegmentInfo; 00111 d->ximage = XShmCreateImage(tqt_xdisplay(), (Visual *) TQPaintDevice::x11AppVisual(), 00112 TQPaintDevice::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 // Offer discrete possibilities for the bitformat. Each will have its 00125 // own routine. The general algorithm using bitshifts is much too slow; 00126 // this has to be done for every pixel! 00127 00128 if ((bpp == 32) && (red_shift == 16) && (green_shift == 8) && 00129 (blue_shift == 0)) 00130 d->byteorder = bo32_ARGB; 00131 else if ((bpp == 32) && (red_shift == 0) && (green_shift == 8) && 00132 (blue_shift == 16)) 00133 d->byteorder = bo32_BGRA; 00134 else if ((bpp == 33) && (red_shift == 16) && (green_shift == 8) && 00135 (blue_shift == 0)) 00136 d->byteorder = bo32_BGRA; 00137 else if ((bpp == 24) && (red_shift == 16) && (green_shift == 8) && 00138 (blue_shift == 0)) 00139 d->byteorder = bo24_RGB; 00140 else if ((bpp == 24) && (red_shift == 0) && (green_shift == 8) && 00141 (blue_shift == 16)) 00142 d->byteorder = bo24_BGR; 00143 else if ((bpp == 25) && (red_shift == 16) && (green_shift == 8) && 00144 (blue_shift == 0)) 00145 d->byteorder = bo24_BGR; 00146 else if ((bpp == 16) && (red_shift == 11) && (green_shift == 5) && 00147 (blue_shift == 0)) 00148 d->byteorder = bo16_RGB_565; 00149 else if ((bpp == 16) && (red_shift == 10) && (green_shift == 5) && 00150 (blue_shift == 0)) 00151 d->byteorder = bo16_RGB_555; 00152 else if ((bpp == 17) && (red_shift == 11) && (green_shift == 5) && 00153 (blue_shift == 0)) 00154 d->byteorder = bo16_BGR_565; 00155 else if ((bpp == 17) && (red_shift == 10) && (green_shift == 5) && 00156 (blue_shift == 0)) 00157 d->byteorder = bo16_BGR_555; 00158 else if ((bpp == 8) || (bpp == 9)) 00159 d->byteorder = bo8; 00160 else 00161 { 00162 m_bShm = false; 00163 kdWarning(290) << "Byte order not supported!" << endl; 00164 kdWarning(290) << "red = " << red_shift 00165 << ", green = " << green_shift 00166 << ", blue = " << blue_shift << endl; 00167 kdWarning(290) << "Please report to <jansen@kde.org>\n"; 00168 } 00169 #else 00170 d->shmsize = 0; 00171 d->ximage = 0; 00172 #endif 00173 } 00174 00175 00176 KPixmapIO::~KPixmapIO() 00177 { 00178 destroyXImage(); 00179 destroyShmSegment(); 00180 #ifdef HAVE_MITSHM 00181 delete d->shminfo; 00182 #endif 00183 delete d; 00184 } 00185 00186 00187 TQPixmap KPixmapIO::convertToPixmap(const TQImage &img) 00188 { 00189 int size = img.width() * img.height(); 00190 if (m_bShm && (img.depth() > 1) && (d->bpp > 8) && (size > d->threshold)) 00191 { 00192 TQPixmap dst(img.width(), img.height()); 00193 putImage(&dst, 0, 0, &img); 00194 return dst; 00195 } else 00196 { 00197 TQPixmap dst; 00198 dst.convertFromImage(img); 00199 return dst; 00200 } 00201 00202 } 00203 00204 00205 TQImage KPixmapIO::convertToImage(const TQPixmap &pm) 00206 { 00207 TQImage image; 00208 int size = pm.width() * pm.height(); 00209 if (m_bShm && (d->bpp >= 8) && (size > d->threshold)) 00210 image = getImage(&pm, 0, 0, pm.width(), pm.height()); 00211 else 00212 image = pm.convertToImage(); 00213 return image; 00214 } 00215 00216 00217 void KPixmapIO::putImage(TQPixmap *dst, const TQPoint &offset, 00218 const TQImage *src) 00219 { 00220 putImage(dst, offset.x(), offset.y(), src); 00221 } 00222 00223 00224 void KPixmapIO::putImage(TQPixmap *dst, int dx, int dy, const TQImage *src) 00225 { 00226 int size = src->width() * src->height(); 00227 bool fallback = true; 00228 if (m_bShm && (src->depth() > 1) && (d->bpp > 8) && (size > d->threshold)) 00229 { 00230 #ifdef HAVE_MITSHM 00231 if( initXImage(src->width(), src->height())) 00232 { 00233 convertToXImage(*src); 00234 XShmPutImage(tqt_xdisplay(), dst->handle(), tqt_xget_temp_gc(tqt_xscreen(), false), d->ximage, 00235 dx, dy, 0, 0, src->width(), src->height(), false); 00236 // coolo: do we really need this here? I see no good for it 00237 XSync(tqt_xdisplay(), false); 00238 doneXImage(); 00239 fallback = false; 00240 } 00241 #endif 00242 } 00243 if( fallback ) 00244 { 00245 TQPixmap pix; 00246 pix.convertFromImage(*src); 00247 bitBlt(dst, dx, dy, &pix, 0, 0, pix.width(), pix.height()); 00248 } 00249 } 00250 00251 00252 TQImage KPixmapIO::getImage(const TQPixmap *src, const TQRect &rect) 00253 { 00254 return getImage(src, rect.x(), rect.y(), rect.width(), rect.height()); 00255 } 00256 00257 00258 TQImage KPixmapIO::getImage(const TQPixmap *src, int sx, int sy, int sw, int sh) 00259 { 00260 TQImage image; 00261 int size = src->width() * src->height(); 00262 bool fallback = true; 00263 if ((m_bShm) && (d->bpp >= 8) && (size > d->threshold)) 00264 { 00265 #ifdef HAVE_MITSHM 00266 if( initXImage(sw, sh)) 00267 { 00268 XShmGetImage(tqt_xdisplay(), src->handle(), d->ximage, sx, sy, AllPlanes); 00269 image = convertFromXImage(); 00270 doneXImage(); 00271 fallback = false; 00272 } 00273 #endif 00274 } 00275 if( fallback ) 00276 { 00277 TQPixmap pix(sw, sh); 00278 bitBlt(&pix, 0, 0, src, sx, sy, sw, sh); 00279 image = pix.convertToImage(); 00280 } 00281 return image; 00282 } 00283 00284 00285 #ifdef HAVE_MITSHM 00286 00287 void KPixmapIO::preAllocShm(int size) 00288 { 00289 destroyXImage(); 00290 createShmSegment(size); 00291 } 00292 00293 00294 void KPixmapIO::setShmPolicy(int policy) 00295 { 00296 switch (policy) 00297 { 00298 case ShmDontKeep: 00299 d->shmpolicy = ShmDontKeep; 00300 d->threshold = 5000; 00301 break; 00302 case ShmKeepAndGrow: 00303 d->shmpolicy = ShmKeepAndGrow; 00304 d->threshold = 2000; 00305 break; 00306 default: 00307 break; 00308 } 00309 } 00310 00311 00312 bool KPixmapIO::initXImage(int w, int h) 00313 { 00314 if (d->ximage && (w == d->ximage->width) && (h == d->ximage->height)) 00315 return true; 00316 00317 if( !createXImage(w, h)) 00318 return false; 00319 int size = d->ximage->bytes_per_line * d->ximage->height; 00320 if (size > d->shmsize) 00321 { 00322 if( !createShmSegment(size)) 00323 { 00324 destroyXImage(); 00325 return false; 00326 } 00327 } 00328 d->ximage->data = d->shminfo->shmaddr; 00329 return true; 00330 } 00331 00332 00333 void KPixmapIO::doneXImage() 00334 { 00335 if (d->shmpolicy == ShmDontKeep) 00336 { 00337 destroyXImage(); 00338 destroyShmSegment(); 00339 } 00340 } 00341 00342 00343 void KPixmapIO::destroyXImage() 00344 { 00345 if (d->ximage) 00346 { 00347 XDestroyImage(d->ximage); 00348 d->ximage = 0L; 00349 } 00350 } 00351 00352 00353 bool KPixmapIO::createXImage(int w, int h) 00354 { 00355 destroyXImage(); 00356 d->ximage = XShmCreateImage(tqt_xdisplay(), (Visual *) TQPaintDevice::x11AppVisual(), 00357 TQPaintDevice::x11AppDepth(), ZPixmap, 0L, d->shminfo, w, h); 00358 return d->ximage != None; 00359 } 00360 00361 00362 void KPixmapIO::destroyShmSegment() 00363 { 00364 if (d->shmsize) 00365 { 00366 XShmDetach(tqt_xdisplay(), d->shminfo); 00367 shmdt(d->shminfo->shmaddr); 00368 shmctl(d->shminfo->shmid, IPC_RMID, 0); 00369 d->shmsize = 0; 00370 } 00371 } 00372 00373 static bool use_xshm = true; 00374 static unsigned long kpixmapio_serial; 00375 static int (*old_errhandler)(Display *dpy, XErrorEvent *ev) = 0; 00376 00377 static int kpixmapio_errorhandler(Display *dpy, XErrorEvent *ev) 00378 { 00379 if(ev->serial == kpixmapio_serial) { 00380 /* assuming that xshm errors mean it can't be used at all 00381 (e.g. remote display) */ 00382 use_xshm = false; 00383 kdDebug(290) << "Disabling Xshm" << endl; 00384 return 0; 00385 } else { 00386 // another error 00387 return old_errhandler(dpy, ev); 00388 } 00389 } 00390 00391 bool KPixmapIO::createShmSegment(int size) 00392 { 00393 destroyShmSegment(); 00394 d->shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0600); 00395 if ( d->shminfo->shmid < 0) 00396 { 00397 kdWarning(290) << "Could not get shared memory segment.\n"; 00398 m_bShm = false; 00399 return false; 00400 } 00401 00402 d->shminfo->shmaddr = (char *) shmat(d->shminfo->shmid, 0, 0); 00403 if (d->shminfo->shmaddr == (char *)-1) 00404 { 00405 kdWarning(290) << "Could not attach shared memory segment.\n"; 00406 m_bShm = false; 00407 shmctl(d->shminfo->shmid, IPC_RMID, 0); 00408 return false; 00409 } 00410 00411 d->shminfo->readOnly = false; 00412 00413 if (d->first_try) { 00414 // make sure that we don't get errors of old stuff 00415 XSync(tqt_xdisplay(), False); 00416 old_errhandler = XSetErrorHandler(kpixmapio_errorhandler); 00417 kpixmapio_serial = NextRequest(tqt_xdisplay()); 00418 } 00419 00420 if ( !XShmAttach(tqt_xdisplay(), d->shminfo)) 00421 { 00422 kdWarning() << "X-Server could not attach shared memory segment.\n"; 00423 m_bShm = false; 00424 shmdt(d->shminfo->shmaddr); 00425 shmctl(d->shminfo->shmid, IPC_RMID, 0); 00426 } 00427 00428 if (d->first_try) { 00429 XSync(tqt_xdisplay(), false); 00430 00431 if (!use_xshm) 00432 m_bShm = false; 00433 00434 XSetErrorHandler(old_errhandler); 00435 d->first_try = false; 00436 } 00437 d->shmsize = size; 00438 00439 return m_bShm; 00440 } 00441 00442 00443 /* 00444 * The following functions convertToXImage/convertFromXImage are a little 00445 * long. This is because of speed, I want to get as much out of the inner 00446 * loop as possible. 00447 */ 00448 00449 TQImage KPixmapIO::convertFromXImage() 00450 { 00451 int x, y; 00452 int width = d->ximage->width, height = d->ximage->height; 00453 int bpl = d->ximage->bytes_per_line; 00454 char *data = d->ximage->data; 00455 00456 TQImage image; 00457 if (d->bpp == 8) 00458 { 00459 image.create(width, height, 8); 00460 00461 // Query color map. Don't remove unused entries as a speed 00462 // optmization. 00463 int i, ncells = 256; 00464 XColor *cmap = new XColor[ncells]; 00465 for (i=0; i<ncells; i++) 00466 cmap[i].pixel = i; 00467 XQueryColors(tqt_xdisplay(), TQPaintDevice::x11AppColormap(), 00468 cmap, ncells); 00469 image.setNumColors(ncells); 00470 for (i=0; i<ncells; i++) 00471 image.setColor(i, tqRgb(cmap[i].red, cmap[i].green, cmap[i].blue >> 8)); 00472 } else 00473 image.create(width, height, 32); 00474 00475 switch (d->byteorder) 00476 { 00477 00478 case bo8: 00479 { 00480 for (y=0; y<height; y++) 00481 memcpy(image.scanLine(y), data + y*bpl, width); 00482 break; 00483 } 00484 00485 case bo16_RGB_565: 00486 case bo16_BGR_565: 00487 { 00488 TQ_INT32 pixel, *src; 00489 TQRgb *dst, val; 00490 for (y=0; y<height; y++) 00491 { 00492 src = (TQ_INT32 *) (data + y*bpl); 00493 dst = (TQRgb *) image.scanLine(y); 00494 for (x=0; x<width/2; x++) 00495 { 00496 pixel = *src++; 00497 val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) | 00498 ((pixel & 0x1f) << 3); 00499 *dst++ = val; 00500 pixel >>= 16; 00501 val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) | 00502 ((pixel & 0x1f) << 3); 00503 *dst++ = val; 00504 } 00505 if (width%2) 00506 { 00507 pixel = *src++; 00508 val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) | 00509 ((pixel & 0x1f) << 3); 00510 *dst++ = val; 00511 } 00512 } 00513 break; 00514 } 00515 00516 case bo16_RGB_555: 00517 case bo16_BGR_555: 00518 { 00519 TQ_INT32 pixel, *src; 00520 TQRgb *dst, val; 00521 for (y=0; y<height; y++) 00522 { 00523 src = (TQ_INT32 *) (data + y*bpl); 00524 dst = (TQRgb *) image.scanLine(y); 00525 for (x=0; x<width/2; x++) 00526 { 00527 pixel = *src++; 00528 val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) | 00529 ((pixel & 0x1f) << 3); 00530 *dst++ = val; 00531 pixel >>= 16; 00532 val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) | 00533 ((pixel & 0x1f) << 3); 00534 *dst++ = val; 00535 } 00536 if (width%2) 00537 { 00538 pixel = *src++; 00539 val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) | 00540 ((pixel & 0x1f) << 3); 00541 *dst++ = val; 00542 } 00543 } 00544 break; 00545 } 00546 00547 case bo24_RGB: 00548 { 00549 char *src; 00550 TQRgb *dst; 00551 int w1 = width/4; 00552 TQ_INT32 d1, d2, d3; 00553 for (y=0; y<height; y++) 00554 { 00555 src = data + y*bpl; 00556 dst = (TQRgb *) image.scanLine(y); 00557 for (x=0; x<w1; x++) 00558 { 00559 d1 = *((TQ_INT32 *)src); 00560 d2 = *((TQ_INT32 *)src + 1); 00561 d3 = *((TQ_INT32 *)src + 2); 00562 src += 12; 00563 *dst++ = d1; 00564 *dst++ = (d1 >> 24) | (d2 << 8); 00565 *dst++ = (d3 << 16) | (d2 >> 16); 00566 *dst++ = d3 >> 8; 00567 } 00568 for (x=w1*4; x<width; x++) 00569 { 00570 d1 = *src++ << 16; 00571 d1 += *src++ << 8; 00572 d1 += *src++; 00573 *dst++ = d1; 00574 } 00575 } 00576 break; 00577 } 00578 00579 case bo24_BGR: 00580 { 00581 char *src; 00582 TQRgb *dst; 00583 int w1 = width/4; 00584 TQ_INT32 d1, d2, d3; 00585 for (y=0; y<height; y++) 00586 { 00587 src = data + y*bpl; 00588 dst = (TQRgb *) image.scanLine(y); 00589 for (x=0; x<w1; x++) 00590 { 00591 d1 = *((TQ_INT32 *)src); 00592 d2 = *((TQ_INT32 *)src + 1); 00593 d3 = *((TQ_INT32 *)src + 2); 00594 src += 12; 00595 *dst++ = d1; 00596 *dst++ = (d1 >> 24) | (d2 << 8); 00597 *dst++ = (d3 << 16) | (d2 >> 16); 00598 *dst++ = d3 >> 8; 00599 } 00600 for (x=w1*4; x<width; x++) 00601 { 00602 d1 = *src++; 00603 d1 += *src++ << 8; 00604 d1 += *src++ << 16; 00605 *dst++ = d1; 00606 } 00607 } 00608 break; 00609 } 00610 00611 case bo32_ARGB: 00612 case bo32_BGRA: 00613 { 00614 for (y=0; y<height; y++) 00615 memcpy(image.scanLine(y), data + y*bpl, width*4); 00616 break; 00617 } 00618 00619 } 00620 00621 return image; 00622 } 00623 00624 00625 void KPixmapIO::convertToXImage(const TQImage &img) 00626 { 00627 int x, y; 00628 int width = d->ximage->width, height = d->ximage->height; 00629 int bpl = d->ximage->bytes_per_line; 00630 char *data = d->ximage->data; 00631 00632 switch (d->byteorder) 00633 { 00634 00635 case bo16_RGB_555: 00636 case bo16_BGR_555: 00637 00638 if (img.depth() == 32) 00639 { 00640 TQRgb *src, pixel; 00641 TQ_INT32 *dst, val; 00642 for (y=0; y<height; y++) 00643 { 00644 src = (TQRgb *) img.scanLine(y); 00645 dst = (TQ_INT32 *) (data + y*bpl); 00646 for (x=0; x<width/2; x++) 00647 { 00648 pixel = *src++; 00649 val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | 00650 ((pixel & 0xff) >> 3); 00651 pixel = *src++; 00652 val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | 00653 ((pixel & 0xff) >> 3)) << 16; 00654 *dst++ = val; 00655 } 00656 if (width%2) 00657 { 00658 pixel = *src++; 00659 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 9) | 00660 ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3); 00661 } 00662 } 00663 } else 00664 { 00665 uchar *src; 00666 TQ_INT32 val, *dst; 00667 TQRgb pixel, *clut = img.tqcolorTable(); 00668 for (y=0; y<height; y++) 00669 { 00670 src = const_cast<TQImage&>(img).scanLine(y); 00671 dst = (TQ_INT32 *) (data + y*bpl); 00672 for (x=0; x<width/2; x++) 00673 { 00674 pixel = clut[*src++]; 00675 val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | 00676 ((pixel & 0xff) >> 3); 00677 pixel = clut[*src++]; 00678 val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) | 00679 ((pixel & 0xff) >> 3)) << 16; 00680 *dst++ = val; 00681 } 00682 if (width%2) 00683 { 00684 pixel = clut[*src++]; 00685 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 9) | 00686 ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3); 00687 } 00688 } 00689 } 00690 break; 00691 00692 case bo16_RGB_565: 00693 case bo16_BGR_565: 00694 00695 if (img.depth() == 32) 00696 { 00697 TQRgb *src, pixel; 00698 TQ_INT32 *dst, val; 00699 for (y=0; y<height; y++) 00700 { 00701 src = (TQRgb *) img.scanLine(y); 00702 dst = (TQ_INT32 *) (data + y*bpl); 00703 for (x=0; x<width/2; x++) 00704 { 00705 pixel = *src++; 00706 val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | 00707 ((pixel & 0xff) >> 3); 00708 pixel = *src++; 00709 val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | 00710 ((pixel & 0xff) >> 3)) << 16; 00711 *dst++ = val; 00712 } 00713 if (width%2) 00714 { 00715 pixel = *src++; 00716 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 8) | 00717 ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3); 00718 } 00719 } 00720 } else 00721 { 00722 uchar *src; 00723 TQ_INT32 val, *dst; 00724 TQRgb pixel, *clut = img.tqcolorTable(); 00725 for (y=0; y<height; y++) 00726 { 00727 src = const_cast<TQImage&>(img).scanLine(y); 00728 dst = (TQ_INT32 *) (data + y*bpl); 00729 for (x=0; x<width/2; x++) 00730 { 00731 pixel = clut[*src++]; 00732 val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | 00733 ((pixel & 0xff) >> 3); 00734 pixel = clut[*src++]; 00735 val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) | 00736 ((pixel & 0xff) >> 3)) << 16; 00737 *dst++ = val; 00738 } 00739 if (width%2) 00740 { 00741 pixel = clut[*src++]; 00742 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 8) | 00743 ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3); 00744 } 00745 } 00746 } 00747 break; 00748 00749 case bo24_RGB: 00750 00751 if (img.depth() == 32) 00752 { 00753 char *dst; 00754 int w1 = width/4; 00755 TQRgb *src, d1, d2, d3, d4; 00756 for (y=0; y<height; y++) 00757 { 00758 src = (TQRgb *) img.scanLine(y); 00759 dst = data + y*bpl; 00760 for (x=0; x<w1; x++) 00761 { 00762 d1 = (*src++ & 0xffffff); 00763 d2 = (*src++ & 0xffffff); 00764 d3 = (*src++ & 0xffffff); 00765 d4 = (*src++ & 0xffffff); 00766 *((TQ_INT32 *)dst) = d1 | (d2 << 24); 00767 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); 00768 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); 00769 dst += 12; 00770 } 00771 for (x=w1*4; x<width; x++) 00772 { 00773 d1 = *src++; 00774 *dst++ = tqRed(d1); 00775 *dst++ = tqGreen(d1); 00776 *dst++ = tqBlue(d1); 00777 } 00778 } 00779 } else 00780 { 00781 uchar *src, *dst; 00782 int w1 = width/4; 00783 TQRgb *clut = img.tqcolorTable(), d1, d2, d3, d4; 00784 for (y=0; y<height; y++) 00785 { 00786 src = const_cast<TQImage&>(img).scanLine(y); 00787 dst = (uchar *) data + y*bpl; 00788 for (x=0; x<w1; x++) 00789 { 00790 d1 = (clut[*src++] & 0xffffff); 00791 d2 = (clut[*src++] & 0xffffff); 00792 d3 = (clut[*src++] & 0xffffff); 00793 d4 = (clut[*src++] & 0xffffff); 00794 *((TQ_INT32 *)dst) = d1 | (d2 << 24); 00795 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); 00796 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); 00797 dst += 12; 00798 } 00799 for (x=w1*4; x<width; x++) 00800 { 00801 d1 = clut[*src++]; 00802 *dst++ = tqRed(d1); 00803 *dst++ = tqGreen(d1); 00804 *dst++ = tqBlue(d1); 00805 } 00806 } 00807 } 00808 break; 00809 00810 case bo24_BGR: 00811 00812 if (img.depth() == 32) 00813 { 00814 char *dst; 00815 TQRgb *src, d1, d2, d3, d4; 00816 int w1 = width/4; 00817 for (y=0; y<height; y++) 00818 { 00819 src = (TQRgb *) img.scanLine(y); 00820 dst = data + y*bpl; 00821 for (x=0; x<w1; x++) 00822 { 00823 d1 = (*src++ & 0xffffff); 00824 d2 = (*src++ & 0xffffff); 00825 d3 = (*src++ & 0xffffff); 00826 d4 = (*src++ & 0xffffff); 00827 *((TQ_INT32 *)dst) = d1 | (d2 << 24); 00828 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); 00829 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); 00830 dst += 12; 00831 } 00832 for (x=w1*4; x<width; x++) 00833 { 00834 d1 = *src++; 00835 *dst++ = tqBlue(d1); 00836 *dst++ = tqGreen(d1); 00837 *dst++ = tqRed(d1); 00838 } 00839 } 00840 } else 00841 { 00842 uchar *src, *dst; 00843 int w1 = width/4; 00844 TQRgb *clut = img.tqcolorTable(), d1, d2, d3, d4; 00845 for (y=0; y<height; y++) 00846 { 00847 src = const_cast<TQImage&>(img).scanLine(y); 00848 dst = (uchar *) data + y*bpl; 00849 for (x=0; x<w1; x++) 00850 { 00851 d1 = (clut[*src++] & 0xffffff); 00852 d2 = (clut[*src++] & 0xffffff); 00853 d3 = (clut[*src++] & 0xffffff); 00854 d4 = (clut[*src++] & 0xffffff); 00855 *((TQ_INT32 *)dst) = d1 | (d2 << 24); 00856 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16); 00857 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16); 00858 dst += 12; 00859 } 00860 for (x=w1*4; x<width; x++) 00861 { 00862 d1 = clut[*src++]; 00863 *dst++ = tqBlue(d1); 00864 *dst++ = tqGreen(d1); 00865 *dst++ = tqRed(d1); 00866 } 00867 } 00868 } 00869 break; 00870 00871 case bo32_ARGB: 00872 case bo32_BGRA: 00873 00874 if (img.depth() == 32) 00875 { 00876 for (y=0; y<height; y++) 00877 memcpy(data + y*bpl, img.scanLine(y), width*4); 00878 } else 00879 { 00880 uchar *src; 00881 TQRgb *dst, *clut = img.tqcolorTable(); 00882 for (y=0; y<height; y++) 00883 { 00884 src = const_cast<TQImage&>(img).scanLine(y); 00885 dst = (TQRgb *) (data + y*bpl); 00886 for (x=0; x<width; x++) 00887 *dst++ = clut[*src++]; 00888 } 00889 } 00890 break; 00891 00892 } 00893 } 00894 00895 #else 00896 00897 void KPixmapIO::preAllocShm(int) {} 00898 void KPixmapIO::setShmPolicy(int) {} 00899 bool KPixmapIO::initXImage(int, int) { return false; } 00900 void KPixmapIO::doneXImage() {} 00901 bool KPixmapIO::createXImage(int, int) { return false; } 00902 void KPixmapIO::destroyXImage() {} 00903 bool KPixmapIO::createShmSegment(int) { return false; } 00904 void KPixmapIO::destroyShmSegment() {} 00905 TQImage KPixmapIO::convertFromXImage() { return TQImage(); } 00906 void KPixmapIO::convertToXImage(const TQImage &) {} 00907 00908 #endif // HAVE_MITSHM