1 /****************************************************************************
3 ** This file is based on sources of the Qt GUI Toolkit, used under the terms
4 ** of the GNU General Public License version 2 (see the original copyright
6 ** All further contributions to this file are (and are required to be)
7 ** licensed under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
11 ** The original Qt license header follows:
14 ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
16 ** This file is part of the kernel module of the Qt GUI Toolkit.
18 ** This file may be distributed under the terms of the Q Public License
19 ** as defined by Trolltech AS of Norway and appearing in the file
20 ** LICENSE.QPL included in the packaging of this file.
22 ** This file may be distributed and/or modified under the terms of the
23 ** GNU General Public License version 2 as published by the Free Software
24 ** Foundation and appearing in the file LICENSE.GPL included in the
25 ** packaging of this file.
27 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
28 ** licenses may use this file in accordance with the Qt Commercial License
29 ** Agreement provided with the Software.
31 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
32 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
34 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
35 ** information about Qt Commercial License Agreements.
36 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
37 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
39 ** Contact info@trolltech.com if any conditions of this licensing are
42 **********************************************************************/
44 #include <config-X11.h>
47 #define QT_MITSHM_CONVERSIONS
51 #include "qnamespace.h"
61 #ifdef QT_MITSHM_CONVERSIONS
62 #include <sys/types.h>
65 #include <X11/extensions/XShm.h>
68 // Returns position of highest bit set or -1 if none
69 static int highest_bit( uint v
)
72 uint b
= (uint
)1 << 31;
73 for ( i
=31; ((b
& v
) == 0) && i
>=0; i
-- )
78 // Returns position of lowest set bit in 'v' as an integer (0-31), or -1
79 static int lowest_bit( uint v
)
84 for (i
=0; ((v
& lb
) == 0) && i
<32; i
++, lb
<<=1);
85 return i
==32 ? -1 : i
;
88 // Counts the number of bits set in 'v'
89 static uint
n_bits( uint v
)
99 inline static void qSafeXDestroyImage( XImage
*x
)
108 #ifdef QT_MITSHM_CONVERSIONS
110 static bool qt_mitshm_error
= false;
111 static int qt_mitshm_errorhandler( Display
*, XErrorEvent
* )
113 qt_mitshm_error
= true;
117 static XImage
* qt_XShmCreateImage( Display
* dpy
, Visual
* visual
, unsigned int depth
,
118 int format
, int /*offset*/, char* /*data*/, unsigned int width
, unsigned int height
,
119 int /*bitmap_pad*/, int /*bytes_per_line*/, XShmSegmentInfo
* shminfo
)
121 if( width
* height
* depth
< 100*100*32 )
123 static int shm_inited
= -1;
124 if( shm_inited
== -1 ) {
125 if( XShmQueryExtension( dpy
))
130 if( shm_inited
== 0 )
132 XImage
* xi
= XShmCreateImage( dpy
, visual
, depth
, format
, NULL
, shminfo
, width
,
136 shminfo
->shmid
= shmget( IPC_PRIVATE
, xi
->bytes_per_line
* xi
->height
,
138 if( shminfo
->shmid
< 0 ) {
142 shminfo
->readOnly
= False
;
143 shminfo
->shmaddr
= (char*)shmat( shminfo
->shmid
, 0, 0 );
144 if( shminfo
->shmaddr
== (char*)-1 ) {
146 shmctl( shminfo
->shmid
, IPC_RMID
, 0 );
149 xi
->data
= shminfo
->shmaddr
;
150 #ifndef QT_MITSHM_RMID_IGNORES_REFCOUNT
151 // mark as deleted to automatically free the memory in case
152 // of a crash (but this doesn't work e.g. on Solaris)
153 shmctl( shminfo
->shmid
, IPC_RMID
, 0 );
155 if( shm_inited
== 1 ) { // first time
156 XErrorHandler old_h
= XSetErrorHandler( qt_mitshm_errorhandler
);
157 XShmAttach( dpy
, shminfo
);
160 XSetErrorHandler( old_h
);
161 if( qt_mitshm_error
) { // oops ... perhaps we are remote?
164 shmdt( shminfo
->shmaddr
);
165 #ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
166 shmctl( shminfo
->shmid
, IPC_RMID
, 0 );
171 XShmAttach( dpy
, shminfo
);
175 static void qt_XShmDestroyImage( XImage
* xi
, XShmSegmentInfo
* shminfo
)
177 XShmDetach( QPaintDevice::x11AppDisplay(), shminfo
);
179 shmdt( shminfo
->shmaddr
);
180 #ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
181 shmctl( shminfo
->shmid
, IPC_RMID
, 0 );
185 #endif // QT_MITSHM_CONVERSIONS
188 PixmapData
PP::convertFromImage( const QImage
&img
, int conversion_flags
)
190 if ( img
.isNull() ) {
191 #if defined(QT_CHECK_NULL)
192 qWarning( "QPixmap::convertFromImage: Cannot convert a null image" );
196 //# detach(); // detach other references
198 const uint w
= image
.width();
199 const uint h
= image
.height();
200 int d
= image
.depth();
201 const int dd
= x11Depth();
202 bool force_mono
= (dd
== 1 || //#*isQBitmap() ||
203 (conversion_flags
& Qt::ColorMode_Mask
)==MonoOnly
);
206 // get rid of the mask
210 // get rid of alpha pixmap
211 delete data
->alphapm
;
215 // must be monochrome
219 image
= image
.convertDepth( 1, conversion_flags
);
222 } else { // can be both
224 if ( d
> 8 && dd
<= 8 ) { // convert to 8 bit
225 if ( (conversion_flags
& DitherMode_Mask
) == AutoDither
)
226 conversion_flags
= (conversion_flags
& ~DitherMode_Mask
)
229 } else if ( (conversion_flags
& ColorMode_Mask
) == ColorOnly
) {
230 conv8
= d
== 1; // native depth wanted
231 } else if ( d
== 1 ) {
232 if ( image
.numColors() == 2 ) {
233 QRgb c0
= image
.color(0); // Auto: convert to best
234 QRgb c1
= image
.color(1);
235 conv8
= qMin(c0
,c1
) != qRgb(0,0,0) || qMax(c0
,c1
) != qRgb(255,255,255);
237 // eg. 1-color monochrome images (they do exist).
242 image
= image
.convertDepth( 8, conversion_flags
);
247 if ( d
== 1 ) { // 1 bit pixmap (bitmap)
250 if ( hd
) { // delete old X pixmap
252 #ifndef QT_NO_XFTFREETYPE
254 XftDrawDestroy( (XftDraw
*) rendhd
);
257 #endif // QT_NO_XFTFREETYPE
259 XFreePixmap( x11Display(), hd
);
262 // make sure image.color(0) == color0 (white) and image.color(1) == color1 (black)
263 if (image
.color(0) == Qt::black
.rgb() && image
.color(1) == Qt::white
.rgb()) {
264 image
.invertPixels();
265 image
.setColor(0, Qt::white
.rgb());
266 image
.setColor(1, Qt::black
.rgb());
272 int ibpl
= image
.bytesPerLine();
273 if ( image
.bitOrder() == QImage::BigEndian
|| bpl
!= ibpl
) {
274 tmp_bits
= new uchar
[bpl
*h
];
275 Q_CHECK_PTR( tmp_bits
);
276 bits
= (char *)tmp_bits
;
279 if ( image
.bitOrder() == QImage::BigEndian
) {
280 const uchar
*f
= qt_get_bitflip_array();
282 for ( y
=0; y
<h
; y
++ ) {
283 p
= image
.scanLine( y
);
286 while ( count
> 4 ) {
296 } else { // just copy
298 p
= image
.scanLine( 0 );
299 for ( y
=0; y
<h
; y
++ ) {
306 bits
= (char *)image
.bits();
309 hd
= (HANDLE
)XCreateBitmapFromData( x11Display(),
310 RootWindow(x11Display(), x11Screen() ),
313 #ifndef QT_NO_XFTFREETYPE
315 rendhd
= (HANDLE
) XftDrawCreateBitmap( x11Display(), hd
);
316 #endif // QT_NO_XFTFREETYPE
318 if ( tmp_bits
) // Avoid purify complaint
320 data
->w
= w
; data
->h
= h
; data
->d
= 1;
322 if ( image
.hasAlphaBuffer() ) {
324 m
= image
.createAlphaMask( conversion_flags
);
331 Display
*dpy
= x11Display();
332 Visual
*visual
= (Visual
*)x11Visual();
334 bool trucol
= (visual
->c_class
== TrueColor
);
335 int nbytes
= image
.numBytes();
337 int newbits_size
= 0;
338 #ifdef QT_MITSHM_CONVERSIONS
339 bool mitshm_ximage
= false;
340 XShmSegmentInfo shminfo
;
343 if ( trucol
) { // truecolor display
344 QRgb pix
[256]; // pixel translation table
345 const bool d8
= d
== 8;
346 const uint red_mask
= (uint
)visual
->red_mask
;
347 const uint green_mask
= (uint
)visual
->green_mask
;
348 const uint blue_mask
= (uint
)visual
->blue_mask
;
349 const int red_shift
= highest_bit( red_mask
) - 7;
350 const int green_shift
= highest_bit( green_mask
) - 7;
351 const int blue_shift
= highest_bit( blue_mask
) - 7;
352 const uint rbits
= highest_bit(red_mask
) - lowest_bit(red_mask
) + 1;
353 const uint gbits
= highest_bit(green_mask
) - lowest_bit(green_mask
) + 1;
354 const uint bbits
= highest_bit(blue_mask
) - lowest_bit(blue_mask
) + 1;
356 if ( d8
) { // setup pixel translation
357 QRgb
*ctable
= image
.colorTable();
358 for ( int i
=0; i
<image
.numColors(); i
++ ) {
359 int r
= qRed (ctable
[i
]);
360 int g
= qGreen(ctable
[i
]);
361 int b
= qBlue (ctable
[i
]);
362 r
= red_shift
> 0 ? r
<< red_shift
: r
>> -red_shift
;
363 g
= green_shift
> 0 ? g
<< green_shift
: g
>> -green_shift
;
364 b
= blue_shift
> 0 ? b
<< blue_shift
: b
>> -blue_shift
;
365 pix
[i
] = (b
& blue_mask
) | (g
& green_mask
) | (r
& red_mask
)
366 | ~(blue_mask
| green_mask
| red_mask
);
370 #ifdef QT_MITSHM_CONVERSIONS
371 xi
= qt_XShmCreateImage( dpy
, visual
, dd
, ZPixmap
, 0, 0, w
, h
, 32, 0, &shminfo
);
373 mitshm_ximage
= true;
374 newbits
= (uchar
*)xi
->data
;
378 xi
= XCreateImage( dpy
, visual
, dd
, ZPixmap
, 0, 0, w
, h
, 32, 0 );
380 if( newbits
== NULL
)
381 newbits
= (uchar
*)malloc( xi
->bytes_per_line
*h
);
382 Q_CHECK_PTR( newbits
);
383 if ( !newbits
) // no memory
385 int bppc
= xi
->bits_per_pixel
;
387 bool contig_bits
= n_bits(red_mask
) == rbits
&&
388 n_bits(green_mask
) == gbits
&&
389 n_bits(blue_mask
) == bbits
;
392 (conversion_flags
& Dither_Mask
) != ThresholdDither
&&
393 (conversion_flags
& DitherMode_Mask
) != AvoidDither
&&
396 // Can do it? (Contiguous bits?)
399 static bool init
=false;
400 static int D
[16][16];
401 if ( dither_tc
&& !init
) {
402 // I also contributed this code to XV - WWA.
404 The dither matrix, D, is obtained with this formula:
410 D2*n = [ 4*Dn 4*Dn+2*Un ]
411 [ 4*Dn+3*Un 4*Dn+1*Un ]
422 /* Expand using recursive definition given above */
423 for (n
=2; n
<16; n
*=2) {
424 for (i
=0; i
<n
; i
++) {
425 for (j
=0; j
<n
; j
++) {
429 D
[i
+n
][j
+n
]=D
[i
][j
]+1;
437 BPP16_8_3_M3
, BPP16_7_2_M3
, BPP16_MSB
, BPP16_LSB
,
438 BPP24_MSB
, BPP24_LSB
,
439 BPP32_16_8_0
, BPP32_MSB
, BPP32_LSB
442 if ( bppc
> 8 && xi
->byte_order
== LSBFirst
)
447 qSysInfo( &wordsize
, &bigendian
);
448 bool same_msb_lsb
= ( xi
->byte_order
== MSBFirst
) == ( bigendian
);
450 if( bppc
== 8 ) // 8 bit
452 else if( bppc
== 16 || bppc
== 17 ) { // 16 bit MSB/LSB
453 if( red_shift
== 8 && green_shift
== 3 && blue_shift
== -3
454 && !d8
&& same_msb_lsb
)
456 else if( red_shift
== 7 && green_shift
== 2 && blue_shift
== -3
457 && !d8
&& same_msb_lsb
)
460 mode
= bppc
== 17 ? BPP16_LSB
: BPP16_MSB
;
461 } else if( bppc
== 24 || bppc
== 25 ) { // 24 bit MSB/LSB
462 mode
= bppc
== 25 ? BPP24_LSB
: BPP24_MSB
;
463 } else if( bppc
== 32 || bppc
== 33 ) { // 32 bit MSB/LSB
464 if( red_shift
== 16 && green_shift
== 8 && blue_shift
== 0
465 && !d8
&& same_msb_lsb
)
468 mode
= bppc
== 33 ? BPP32_LSB
: BPP32_MSB
;
470 qFatal("Logic error 3");
474 if ( d8 ) pixel = pix[*src++]; \
476 int r = qRed ( *p ); \
477 int g = qGreen( *p ); \
478 int b = qBlue ( *p++ ); \
480 ? r << red_shift : r >> -red_shift; \
481 g = green_shift > 0 \
482 ? g << green_shift : g >> -green_shift; \
484 ? b << blue_shift : b >> -blue_shift; \
485 pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
486 | ~(blue_mask | green_mask | red_mask); \
489 // optimized case - no d8 case, shift only once instead of twice, mask only once instead of twice,
490 // use direct values instead of variables, and use only one statement
491 // (*p >> 16), (*p >> 8 ) and (*p) are qRed(),qGreen() and qBlue() without masking
492 // shifts have to be passed including the shift operator (e.g. '>>3'), because of the direction
493 #define GET_PIXEL_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask) \
494 int pixel = ((( *p >> 16 ) red_shift ) & red_mask ) \
495 | ((( *p >> 8 ) green_shift ) & green_mask ) \
496 | ((( *p ) blue_shift ) & blue_mask ); \
499 #define GET_PIXEL_DITHER_TC \
500 int r = qRed ( *p ); \
501 int g = qGreen( *p ); \
502 int b = qBlue ( *p++ ); \
503 const int thres = D[x%16][y%16]; \
504 if ( r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
506 r += (1<<(8-rbits)); \
507 if ( g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
509 g += (1<<(8-gbits)); \
510 if ( b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
512 b += (1<<(8-bbits)); \
514 ? r << red_shift : r >> -red_shift; \
515 g = green_shift > 0 \
516 ? g << green_shift : g >> -green_shift; \
518 ? b << blue_shift : b >> -blue_shift; \
519 int pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
521 // again, optimized case
522 // can't be optimized that much :(
523 #define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
525 const int thres = D[x%16][y%16]; \
526 int r = qRed ( *p ); \
527 if ( r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
529 r += (1<<(8-rbits)); \
530 int g = qGreen( *p ); \
531 if ( g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
533 g += (1<<(8-gbits)); \
534 int b = qBlue ( *p++ ); \
535 if ( b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
537 b += (1<<(8-bbits)); \
538 int pixel = (( r red_shift ) & red_mask ) \
539 | (( g green_shift ) & green_mask ) \
540 | (( b blue_shift ) & blue_mask );
542 #define CYCLE(body) \
543 for ( uint y=0; y<h; y++ ) { \
544 uchar* src = image.scanLine( y ); \
545 uchar* dst = newbits + xi->bytes_per_line*y; \
546 QRgb* p = (QRgb *)src; \
554 Q_INT16
* dst16
= (Q_INT16
*)dst
;
555 for ( uint x
=0; x
<w
; x
++ ) {
556 GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
563 Q_INT16
* dst16
= (Q_INT16
*)dst
;
564 for ( uint x
=0; x
<w
; x
++ ) {
565 GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
570 case BPP16_MSB
: // 16 bit MSB
572 for ( uint x
=0; x
<w
; x
++ ) {
574 *dst
++ = (pixel
>> 8);
579 case BPP16_LSB
: // 16 bit LSB
581 for ( uint x
=0; x
<w
; x
++ ) {
589 qFatal("Logic error");
596 for ( uint x
=0; x
<w
; x
++ ) {
597 int pixel
= pix
[*src
++];
604 Q_INT16
* dst16
= (Q_INT16
*)dst
;
605 for ( uint x
=0; x
<w
; x
++ ) {
606 GET_PIXEL_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f)
613 Q_INT16
* dst16
= (Q_INT16
*)dst
;
614 for ( uint x
=0; x
<w
; x
++ ) {
615 GET_PIXEL_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f)
620 case BPP16_MSB
: // 16 bit MSB
622 for ( uint x
=0; x
<w
; x
++ ) {
624 *dst
++ = (pixel
>> 8);
629 case BPP16_LSB
: // 16 bit LSB
631 for ( uint x
=0; x
<w
; x
++ ) {
638 case BPP24_MSB
: // 24 bit MSB
640 for ( uint x
=0; x
<w
; x
++ ) {
642 *dst
++ = pixel
>> 16;
648 case BPP24_LSB
: // 24 bit LSB
650 for ( uint x
=0; x
<w
; x
++ ) {
654 *dst
++ = pixel
>> 16;
660 memcpy( dst
, p
, w
* 4 );
663 case BPP32_MSB
: // 32 bit MSB
665 for ( uint x
=0; x
<w
; x
++ ) {
667 *dst
++ = pixel
>> 24;
668 *dst
++ = pixel
>> 16;
674 case BPP32_LSB
: // 32 bit LSB
676 for ( uint x
=0; x
<w
; x
++ ) {
680 *dst
++ = pixel
>> 16;
681 *dst
++ = pixel
>> 24;
686 qFatal("Logic error 2");
689 xi
->data
= (char *)newbits
;
692 if ( d
== 8 && !trucol
) { // 8 bit pixmap
693 int pop
[256]; // pixel popularity
695 if ( image
.numColors() == 0 )
696 image
.setNumColors( 1 );
698 memset( pop
, 0, sizeof(int)*256 ); // reset popularity array
700 for ( i
=0; i
<h
; i
++ ) { // for each scanline...
701 uchar
* p
= image
.scanLine( i
);
703 while ( p
< end
) // compute popularity
707 newbits
= (uchar
*)malloc( nbytes
); // copy image into newbits
708 newbits_size
= nbytes
;
709 Q_CHECK_PTR( newbits
);
710 if ( !newbits
) // no memory
713 memcpy( p
, image
.bits(), nbytes
); // copy image data into newbits
716 * The code below picks the most important colors. It is based on the
717 * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
720 struct PIX
{ // pixel sort element
721 uchar r
,g
,b
,n
; // color + pad
722 int use
; // popularity
723 int index
; // index in colormap
727 for ( i
=0; i
< (uint
) image
.numColors(); i
++ ) { // compute number of colors
731 for ( i
=image
.numColors(); i
<256; i
++ ) // ignore out-of-range pixels
734 // works since we make sure above to have at least
735 // one color in the image
739 PIX pixarr
[256]; // pixel array
740 PIX pixarr_sorted
[256]; // pixel array (sorted)
741 memset( pixarr
, 0, ncols
*sizeof(PIX
) );
742 PIX
*px
= &pixarr
[0];
745 Q_CHECK_PTR( pixarr
);
747 QRgb
* ctable
= image
.colorTable();
748 for ( i
=0; i
<256; i
++ ) { // init pixel array
750 px
->r
= qRed ( ctable
[i
] );
751 px
->g
= qGreen( ctable
[i
] );
752 px
->b
= qBlue ( ctable
[i
] );
755 if ( pop
[i
] > maxpop
) { // select most popular entry
760 px
->mindist
= 1000000;
765 pixarr_sorted
[0] = pixarr
[maxpix
];
766 pixarr
[maxpix
].use
= 0;
768 for ( i
=1; i
< (uint
) ncols
; i
++ ) { // sort pixels
769 int minpix
= -1, mindist
= -1;
770 px
= &pixarr_sorted
[i
-1];
775 if ( (i
& 1) || i
<10 ) { // sort on max distance
776 for ( int j
=0; j
<ncols
; j
++ ) {
779 dist
= (px
->r
- r
)*(px
->r
- r
) +
780 (px
->g
- g
)*(px
->g
- g
) +
781 (px
->b
- b
)*(px
->b
- b
);
782 if ( px
->mindist
> dist
)
784 if ( px
->mindist
> mindist
) {
785 mindist
= px
->mindist
;
790 } else { // sort on max popularity
791 for ( int j
=0; j
<ncols
; j
++ ) {
794 dist
= (px
->r
- r
)*(px
->r
- r
) +
795 (px
->g
- g
)*(px
->g
- g
) +
796 (px
->b
- b
)*(px
->b
- b
);
797 if ( px
->mindist
> dist
)
799 if ( px
->use
> mindist
) {
806 pixarr_sorted
[i
] = pixarr
[minpix
];
807 pixarr
[minpix
].use
= 0;
810 uint pix
[256]; // pixel translation table
811 px
= &pixarr_sorted
[0];
812 for ( i
=0; i
< (uint
) ncols
; i
++ ) { // allocate colors
813 QColor
c( px
->r
, px
->g
, px
->b
);
814 pix
[px
->index
] = c
.pixel(x11Screen());
819 for ( i
=0; i
< (uint
) nbytes
; i
++ ) { // translate pixels
825 if ( !xi
) { // X image not created
826 #ifdef QT_MITSHM_CONVERSIONS
827 xi
= qt_XShmCreateImage( dpy
, visual
, dd
, ZPixmap
, 0, 0, w
, h
, 32, 0, &shminfo
);
829 mitshm_ximage
= true;
832 xi
= XCreateImage( dpy
, visual
, dd
, ZPixmap
, 0, 0, w
, h
, 32, 0 );
833 if ( xi
->bits_per_pixel
== 16 ) { // convert 8 bpp ==> 16 bpp
835 int p2inc
= xi
->bytes_per_line
/sizeof(ushort
);
836 ushort
*newerbits
= (ushort
*)malloc( xi
->bytes_per_line
* h
);
837 newbits_size
= xi
->bytes_per_line
* h
;
838 Q_CHECK_PTR( newerbits
);
839 if ( !newerbits
) // no memory
842 for ( uint y
=0; y
<h
; y
++ ) { // OOPS: Do right byte order!!
843 p2
= newerbits
+ p2inc
*y
;
844 for ( uint x
=0; x
<w
; x
++ )
848 newbits
= (uchar
*)newerbits
;
849 } else if ( xi
->bits_per_pixel
!= 8 ) {
850 #if defined(QT_CHECK_RANGE)
851 qWarning( "QPixmap::convertFromImage: Display not supported "
852 "(bpp=%d)", xi
->bits_per_pixel
);
855 #ifdef QT_MITSHM_CONVERSIONS
856 if( newbits_size
> 0 && mitshm_ximage
) { // need to copy to shared memory
857 memcpy( xi
->data
, newbits
, newbits_size
);
859 newbits
= (uchar
*)xi
->data
;
863 xi
->data
= (char *)newbits
;
867 if ( hd
&& (width() != (int)w
|| height() != (int)h
|| this->depth() != dd
) ) {
869 #ifndef QT_NO_XFTFREETYPE
871 XftDrawDestroy( (XftDraw
*) rendhd
);
874 #endif // QT_NO_XFTFREETYPE
876 XFreePixmap( dpy
, hd
); // don't reuse old pixmap
881 PixmapData
* data
= &dat
;
883 Pixmap
& hd
= data
->hd
;
885 if ( !hd
) { // create new pixmap
886 hd
= (HANDLE
)XCreatePixmap( x11Display(),
887 RootWindow(x11Display(), x11Screen() ),
890 #ifndef QT_NO_XFTFREETYPE
892 if ( data
->d
== 1 ) {
893 rendhd
= (HANDLE
) XftDrawCreateBitmap( x11Display (), hd
);
895 rendhd
= (HANDLE
) XftDrawCreate( x11Display (), hd
,
896 (Visual
*) x11Visual(), x11Colormap() );
899 #endif // QT_NO_XFTFREETYPE
903 #ifdef QT_MITSHM_CONVERSIONS
905 XShmPutImage( dpy
, hd
, qt_xget_readonly_gc( x11Screen(), false ),
906 xi
, 0, 0, 0, 0, w
, h
, False
);
909 XPutImage( dpy
, hd
, qt_xget_readonly_gc( x11Screen(), false ),
910 xi
, 0, 0, 0, 0, w
, h
);
917 #ifdef QT_MITSHM_CONVERSIONS
918 bool mitshm_aximage
= false;
919 XShmSegmentInfo ashminfo
;
921 if ( image
.hasAlphaBuffer() ) {
925 m
= image
.createAlphaMask( conversion_flags
);
928 #ifndef QT_NO_XFTFREETYPE
929 // does this image have an alphamap (and not just a 1bpp mask)?
930 bool alphamap
= image
.depth() == 32;
931 if (image
.depth() == 8) {
932 const QRgb
* const rgb
= image
.colorTable();
933 for (int i
= 0, count
= image
.numColors(); i
< count
; ++i
) {
934 const int alpha
= qAlpha(rgb
[i
]);
935 if (alpha
!= 0 && alpha
!= 0xff) {
942 if (qt_use_xrender
&& qt_has_xft
&& alphamap
) {
943 data
->alphapm
= new QPixmap
; // create a null pixmap
946 data
->alphapm
->data
->w
= w
;
947 data
->alphapm
->data
->h
= h
;
948 data
->alphapm
->data
->d
= 8;
950 // create 8bpp pixmap and render picture
952 XCreatePixmap(x11Display(), RootWindow(x11Display(), x11Screen()),
955 data
->alphapm
->rendhd
=
956 (HANDLE
) XftDrawCreateAlpha( x11Display(), data
->alphapm
->hd
, 8 );
958 #ifdef QT_MITSHM_CONVERSIONS
959 axi
= qt_XShmCreateImage( x11Display(), (Visual
*)x11Visual(),
960 8, ZPixmap
, 0, 0, w
, h
, 8, 0, &ashminfo
);
962 mitshm_aximage
= true;
965 axi
= XCreateImage(x11Display(), (Visual
*) x11Visual(),
966 8, ZPixmap
, 0, 0, w
, h
, 8, 0);
969 if( axi
->data
==NULL
) {
970 // the data is deleted by qSafeXDestroyImage
971 axi
->data
= (char *) malloc(h
* axi
->bytes_per_line
);
972 Q_CHECK_PTR( axi
->data
);
974 char *aptr
= axi
->data
;
976 if (image
.depth() == 32) {
977 const int *iptr
= (const int *) image
.bits();
978 if( axi
->bytes_per_line
== (int)w
) {
981 *aptr
++ = *iptr
++ >> 24; // squirt
983 for (uint i
= 0; i
< h
; ++i
) {
984 for (uint j
= 0; j
< w
; ++j
)
985 *aptr
++ = *iptr
++ >> 24; // squirt
986 aptr
+= ( axi
->bytes_per_line
- w
);
989 } else if (image
.depth() == 8) {
990 const QRgb
* const rgb
= image
.colorTable();
991 for (uint y
= 0; y
< h
; ++y
) {
992 const uchar
*iptr
= image
.scanLine(y
);
993 for (uint x
= 0; x
< w
; ++x
)
994 *aptr
++ = qAlpha(rgb
[*iptr
++]);
995 aptr
+= ( axi
->bytes_per_line
- w
);
999 GC gc
= XCreateGC(x11Display(), data
->alphapm
->hd
, 0, 0);
1000 #ifdef QT_MITSHM_CONVERSIONS
1001 if( mitshm_aximage
)
1002 XShmPutImage( dpy
, data
->alphapm
->hd
, gc
, axi
, 0, 0, 0, 0, w
, h
, False
);
1005 XPutImage(dpy
, data
->alphapm
->hd
, gc
, axi
, 0, 0, 0, 0, w
, h
);
1006 XFreeGC(x11Display(), gc
);
1009 #endif // QT_NO_XFTFREETYPE
1013 #ifdef QT_MITSHM_CONVERSIONS
1014 if( mitshm_ximage
|| mitshm_aximage
)
1015 XSync( x11Display(), False
); // wait until processed
1018 if ( data
->optim
!= BestOptim
) { // throw away image
1019 #ifdef QT_MITSHM_CONVERSIONS
1021 qt_XShmDestroyImage( xi
, &shminfo
);
1024 qSafeXDestroyImage( xi
);
1026 } else { // keep ximage that we created
1027 #ifdef QT_MITSHM_CONVERSIONS
1028 if( mitshm_ximage
) { // copy the XImage?
1029 qt_XShmDestroyImage( xi
, &shminfo
);
1036 #ifdef QT_MITSHM_CONVERSIONS
1037 if( mitshm_aximage
)
1038 qt_XShmDestroyImage( axi
, &ashminfo
);
1041 qSafeXDestroyImage(axi
);