2 * DIB conversion routinues for cases where the source and destination
3 * have the same byte order.
5 * Copyright (C) 2001 Francois Gouget
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 /***********************************************************************
31 * X11DRV_DIB_Convert_*
33 * All X11DRV_DIB_Convert_Xxx functions take at least the following
36 * This is the width in pixel of the surface to copy. This may be less
37 * than the full width of the image.
39 * The number of lines to copy. This may be less than the full height
40 * of the image. This is always >0.
42 * Points to the first byte containing data to be copied. If the source
43 * surface starts are coordinates (x,y) then this is:
44 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
45 * (with further adjustments for top-down/bottom-up images)
47 * This is the number of bytes per line. It may be >0 or <0 depending on
48 * whether this is a top-down or bottom-up image.
50 * Same as srcbits but for the destination
52 * Same as srclinebytes but for the destination.
55 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
56 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
57 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
58 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
59 * - Rgb formats are those for which the masks are such that:
60 * red_mask > green_mask > blue_mask
61 * - Bgr formats are those for which the masks sort in the other direction.
62 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
63 * so the comments use h, g, l to mean respectively the source color in the
64 * high bits, the green, and the source color in the low bits.
72 static void convert_5x5_asis(int width
, int height
,
73 const void* srcbits
, int srclinebytes
,
74 void* dstbits
, int dstlinebytes
)
78 for (y
=0; y
<height
; y
++) {
79 memcpy(dstbits
, srcbits
, width
*2);
80 srcbits
= (const char*)srcbits
+ srclinebytes
;
81 dstbits
= (char*)dstbits
+ dstlinebytes
;
86 static void convert_555_reverse(int width
, int height
,
87 const void* srcbits
, int srclinebytes
,
88 void* dstbits
, int dstlinebytes
)
90 const DWORD
* srcpixel
;
94 for (y
=0; y
<height
; y
++) {
97 for (x
=0; x
<width
/2; x
++) {
98 /* Do 2 pixels at a time */
101 *dstpixel
++=((srcval
<< 10) & 0x7c007c00) | /* h */
102 ( srcval
& 0x03e003e0) | /* g */
103 ((srcval
>> 10) & 0x001f001f); /* l */
106 /* And the the odd pixel */
108 srcval
=*((const WORD
*)srcpixel
);
109 *((WORD
*)dstpixel
)=((srcval
<< 10) & 0x7c00) | /* h */
110 ( srcval
& 0x03e0) | /* g */
111 ((srcval
>> 10) & 0x001f); /* l */
113 srcbits
= (const char*)srcbits
+ srclinebytes
;
114 dstbits
= (char*)dstbits
+ dstlinebytes
;
118 static void convert_555_to_565_asis(int width
, int height
,
119 const void* srcbits
, int srclinebytes
,
120 void* dstbits
, int dstlinebytes
)
122 const DWORD
* srcpixel
;
126 for (y
=0; y
<height
; y
++) {
129 for (x
=0; x
<width
/2; x
++) {
130 /* Do 2 pixels at a time */
133 *dstpixel
++=((srcval
<< 1) & 0xffc0ffc0) | /* h, g */
134 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
135 ( srcval
& 0x001f001f); /* l */
138 /* And the the odd pixel */
140 srcval
=*((const WORD
*)srcpixel
);
141 *((WORD
*)dstpixel
)=((srcval
<< 1) & 0xffc0) | /* h, g */
142 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
143 (srcval
& 0x001f); /* l */
145 srcbits
= (const char*)srcbits
+ srclinebytes
;
146 dstbits
= (char*)dstbits
+ dstlinebytes
;
150 static void convert_555_to_565_reverse(int width
, int height
,
151 const void* srcbits
, int srclinebytes
,
152 void* dstbits
, int dstlinebytes
)
154 const DWORD
* srcpixel
;
158 for (y
=0; y
<height
; y
++) {
161 for (x
=0; x
<width
/2; x
++) {
162 /* Do 2 pixels at a time */
165 *dstpixel
++=((srcval
>> 10) & 0x001f001f) | /* h */
166 ((srcval
<< 1) & 0x07c007c0) | /* g */
167 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
168 ((srcval
<< 11) & 0xf800f800); /* l */
171 /* And the the odd pixel */
173 srcval
=*((const WORD
*)srcpixel
);
174 *((WORD
*)dstpixel
)=((srcval
>> 10) & 0x001f) | /* h */
175 ((srcval
<< 1) & 0x07c0) | /* g */
176 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
177 ((srcval
<< 11) & 0xf800); /* l */
179 srcbits
= (const char*)srcbits
+ srclinebytes
;
180 dstbits
= (char*)dstbits
+ dstlinebytes
;
184 static void convert_555_to_888_asis(int width
, int height
,
185 const void* srcbits
, int srclinebytes
,
186 void* dstbits
, int dstlinebytes
)
188 const WORD
* srcpixel
;
192 for (y
=0; y
<height
; y
++) {
195 for (x
=0; x
<width
; x
++) {
198 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
199 ((srcval
>> 2) & 0x07); /* l - 3 bits */
200 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
201 ((srcval
>> 7) & 0x07); /* g - 3 bits */
202 dstpixel
[2]=((srcval
>> 7) & 0xf8) | /* h */
203 ((srcval
>> 12) & 0x07); /* h - 3 bits */
206 srcbits
= (const char*)srcbits
+ srclinebytes
;
207 dstbits
= (char*)dstbits
+ dstlinebytes
;
211 static void convert_555_to_888_reverse(int width
, int height
,
212 const void* srcbits
, int srclinebytes
,
213 void* dstbits
, int dstlinebytes
)
215 const WORD
* srcpixel
;
219 for (y
=0; y
<height
; y
++) {
222 for (x
=0; x
<width
; x
++) {
225 dstpixel
[0]=((srcval
>> 7) & 0xf8) | /* h */
226 ((srcval
>> 12) & 0x07); /* h - 3 bits */
227 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
228 ((srcval
>> 7) & 0x07); /* g - 3 bits */
229 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
230 ((srcval
>> 2) & 0x07); /* l - 3 bits */
233 srcbits
= (const char*)srcbits
+ srclinebytes
;
234 dstbits
= (char*)dstbits
+ dstlinebytes
;
238 static void convert_555_to_0888_asis(int width
, int height
,
239 const void* srcbits
, int srclinebytes
,
240 void* dstbits
, int dstlinebytes
)
242 const WORD
* srcpixel
;
246 for (y
=0; y
<height
; y
++) {
249 for (x
=0; x
<width
; x
++) {
252 *dstpixel
++=((srcval
<< 9) & 0xf80000) | /* h */
253 ((srcval
<< 4) & 0x070000) | /* h - 3 bits */
254 ((srcval
<< 6) & 0x00f800) | /* g */
255 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
256 ((srcval
<< 3) & 0x0000f8) | /* l */
257 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
259 srcbits
= (const char*)srcbits
+ srclinebytes
;
260 dstbits
= (char*)dstbits
+ dstlinebytes
;
264 static void convert_555_to_0888_reverse(int width
, int height
,
265 const void* srcbits
, int srclinebytes
,
266 void* dstbits
, int dstlinebytes
)
268 const WORD
* srcpixel
;
272 for (y
=0; y
<height
; y
++) {
275 for (x
=0; x
<width
; x
++) {
278 *dstpixel
++=((srcval
>> 7) & 0x0000f8) | /* h */
279 ((srcval
>> 12) & 0x000007) | /* h - 3 bits */
280 ((srcval
<< 6) & 0x00f800) | /* g */
281 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
282 ((srcval
<< 19) & 0xf80000) | /* l */
283 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
285 srcbits
= (const char*)srcbits
+ srclinebytes
;
286 dstbits
= (char*)dstbits
+ dstlinebytes
;
290 static void convert_5x5_to_any0888(int width
, int height
,
291 const void* srcbits
, int srclinebytes
,
292 WORD rsrc
, WORD gsrc
, WORD bsrc
,
293 void* dstbits
, int dstlinebytes
,
294 DWORD rdst
, DWORD gdst
, DWORD bdst
)
296 int rRightShift1
,gRightShift1
,bRightShift1
;
297 int rRightShift2
,gRightShift2
,bRightShift2
;
299 int rLeftShift
,gLeftShift
,bLeftShift
;
300 const WORD
* srcpixel
;
304 /* Note, the source pixel value is shifted left by 16 bits so that
305 * we know we will always have to shift right to extract the components.
307 rRightShift1
=16+X11DRV_DIB_MaskToShift(rsrc
)-3;
308 gRightShift1
=16+X11DRV_DIB_MaskToShift(gsrc
)-3;
309 bRightShift1
=16+X11DRV_DIB_MaskToShift(bsrc
)-3;
310 rRightShift2
=rRightShift1
+5;
311 gRightShift2
=gRightShift1
+5;
312 bRightShift2
=bRightShift1
+5;
314 /* Green has 5 bits, like the others */
318 /* Green has 6 bits, not 5. Compensate. */
325 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
326 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
327 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
329 for (y
=0; y
<height
; y
++) {
332 for (x
=0; x
<width
; x
++) {
335 srcval
=*srcpixel
++ << 16;
336 red
= ((srcval
>> rRightShift1
) & 0xf8) |
337 ((srcval
>> rRightShift2
) & 0x07);
338 green
=((srcval
>> gRightShift1
) & gMask1
) |
339 ((srcval
>> gRightShift2
) & gMask2
);
340 blue
= ((srcval
>> bRightShift1
) & 0xf8) |
341 ((srcval
>> bRightShift2
) & 0x07);
342 *dstpixel
++=(red
<< rLeftShift
) |
343 (green
<< gLeftShift
) |
344 (blue
<< bLeftShift
);
346 srcbits
= (const char*)srcbits
+ srclinebytes
;
347 dstbits
= (char*)dstbits
+ dstlinebytes
;
352 * 16 bits conversions
355 static void convert_565_reverse(int width
, int height
,
356 const void* srcbits
, int srclinebytes
,
357 void* dstbits
, int dstlinebytes
)
359 const DWORD
* srcpixel
;
363 for (y
=0; y
<height
; y
++) {
366 for (x
=0; x
<width
/2; x
++) {
367 /* Do 2 pixels at a time */
370 *dstpixel
++=((srcval
<< 11) & 0xf800f800) | /* h */
371 ( srcval
& 0x07e007e0) | /* g */
372 ((srcval
>> 11) & 0x001f001f); /* l */
375 /* And the the odd pixel */
377 srcval
=*((const WORD
*)srcpixel
);
378 *((WORD
*)dstpixel
)=((srcval
<< 11) & 0xf800) | /* h */
379 ( srcval
& 0x07e0) | /* g */
380 ((srcval
>> 11) & 0x001f); /* l */
382 srcbits
= (const char*)srcbits
+ srclinebytes
;
383 dstbits
= (char*)dstbits
+ dstlinebytes
;
387 static void convert_565_to_555_asis(int width
, int height
,
388 const void* srcbits
, int srclinebytes
,
389 void* dstbits
, int dstlinebytes
)
391 const DWORD
* srcpixel
;
395 for (y
=0; y
<height
; y
++) {
398 for (x
=0; x
<width
/2; x
++) {
399 /* Do 2 pixels at a time */
402 *dstpixel
++=((srcval
>> 1) & 0x7fe07fe0) | /* h, g */
403 ( srcval
& 0x001f001f); /* l */
406 /* And the the odd pixel */
408 srcval
=*((const WORD
*)srcpixel
);
409 *((WORD
*)dstpixel
)=((srcval
>> 1) & 0x7fe0) | /* h, g */
410 ( srcval
& 0x001f); /* l */
412 srcbits
= (const char*)srcbits
+ srclinebytes
;
413 dstbits
= (char*)dstbits
+ dstlinebytes
;
417 static void convert_565_to_555_reverse(int width
, int height
,
418 const void* srcbits
, int srclinebytes
,
419 void* dstbits
, int dstlinebytes
)
421 const DWORD
* srcpixel
;
425 for (y
=0; y
<height
; y
++) {
428 for (x
=0; x
<width
/2; x
++) {
429 /* Do 2 pixels at a time */
432 *dstpixel
++=((srcval
>> 11) & 0x001f001f) | /* h */
433 ((srcval
>> 1) & 0x03e003e0) | /* g */
434 ((srcval
<< 10) & 0x7c007c00); /* l */
437 /* And the the odd pixel */
439 srcval
=*((const WORD
*)srcpixel
);
440 *((WORD
*)dstpixel
)=((srcval
>> 11) & 0x001f) | /* h */
441 ((srcval
>> 1) & 0x03e0) | /* g */
442 ((srcval
<< 10) & 0x7c00); /* l */
444 srcbits
= (const char*)srcbits
+ srclinebytes
;
445 dstbits
= (char*)dstbits
+ dstlinebytes
;
449 static void convert_565_to_888_asis(int width
, int height
,
450 const void* srcbits
, int srclinebytes
,
451 void* dstbits
, int dstlinebytes
)
453 const WORD
* srcpixel
;
457 for (y
=0; y
<height
; y
++) {
460 for (x
=0; x
<width
; x
++) {
463 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
464 ((srcval
>> 2) & 0x07); /* l - 3 bits */
465 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
466 ((srcval
>> 9) & 0x03); /* g - 2 bits */
467 dstpixel
[2]=((srcval
>> 8) & 0xf8) | /* h */
468 ((srcval
>> 13) & 0x07); /* h - 3 bits */
471 srcbits
= (const char*)srcbits
+ srclinebytes
;
472 dstbits
= (char*)dstbits
+ dstlinebytes
;
476 static void convert_565_to_888_reverse(int width
, int height
,
477 const void* srcbits
, int srclinebytes
,
478 void* dstbits
, int dstlinebytes
)
480 const WORD
* srcpixel
;
484 for (y
=0; y
<height
; y
++) {
487 for (x
=0; x
<width
; x
++) {
490 dstpixel
[0]=((srcval
>> 8) & 0xf8) | /* h */
491 ((srcval
>> 13) & 0x07); /* h - 3 bits */
492 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
493 ((srcval
>> 9) & 0x03); /* g - 2 bits */
494 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
495 ((srcval
>> 2) & 0x07); /* l - 3 bits */
498 srcbits
= (const char*)srcbits
+ srclinebytes
;
499 dstbits
= (char*)dstbits
+ dstlinebytes
;
503 static void convert_565_to_0888_asis(int width
, int height
,
504 const void* srcbits
, int srclinebytes
,
505 void* dstbits
, int dstlinebytes
)
507 const WORD
* srcpixel
;
511 for (y
=0; y
<height
; y
++) {
514 for (x
=0; x
<width
; x
++) {
517 *dstpixel
++=((srcval
<< 8) & 0xf80000) | /* h */
518 ((srcval
<< 3) & 0x070000) | /* h - 3 bits */
519 ((srcval
<< 5) & 0x00fc00) | /* g */
520 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
521 ((srcval
<< 3) & 0x0000f8) | /* l */
522 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
524 srcbits
= (const char*)srcbits
+ srclinebytes
;
525 dstbits
= (char*)dstbits
+ dstlinebytes
;
529 static void convert_565_to_0888_reverse(int width
, int height
,
530 const void* srcbits
, int srclinebytes
,
531 void* dstbits
, int dstlinebytes
)
533 const WORD
* srcpixel
;
537 for (y
=0; y
<height
; y
++) {
540 for (x
=0; x
<width
; x
++) {
543 *dstpixel
++=((srcval
>> 8) & 0x0000f8) | /* h */
544 ((srcval
>> 13) & 0x000007) | /* h - 3 bits */
545 ((srcval
<< 5) & 0x00fc00) | /* g */
546 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
547 ((srcval
<< 19) & 0xf80000) | /* l */
548 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
550 srcbits
= (const char*)srcbits
+ srclinebytes
;
551 dstbits
= (char*)dstbits
+ dstlinebytes
;
560 static void convert_888_asis(int width
, int height
,
561 const void* srcbits
, int srclinebytes
,
562 void* dstbits
, int dstlinebytes
)
566 for (y
=0; y
<height
; y
++) {
567 memcpy(dstbits
, srcbits
, width
*3);
568 srcbits
= (const char*)srcbits
+ srclinebytes
;
569 dstbits
= (char*)dstbits
+ dstlinebytes
;
574 static void convert_888_reverse(int width
, int height
,
575 const void* srcbits
, int srclinebytes
,
576 void* dstbits
, int dstlinebytes
)
578 const BYTE
* srcpixel
;
582 for (y
=0; y
<height
; y
++) {
585 for (x
=0; x
<width
; x
++) {
586 dstpixel
[0]=srcpixel
[2];
587 dstpixel
[1]=srcpixel
[1];
588 dstpixel
[2]=srcpixel
[0];
592 srcbits
= (const char*)srcbits
+ srclinebytes
;
593 dstbits
= (char*)dstbits
+ dstlinebytes
;
597 static void convert_888_to_555_asis(int width
, int height
,
598 const void* srcbits
, int srclinebytes
,
599 void* dstbits
, int dstlinebytes
)
601 const DWORD
* srcpixel
;
609 for (y
=0; y
<height
; y
++) {
612 for (x
=0; x
<width
; x
++) {
613 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
614 DWORD srcval1
,srcval2
;
616 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
617 ((srcval1
>> 6) & 0x03e0) | /* g1 */
618 ((srcval1
>> 9) & 0x7c00); /* h1 */
620 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
621 ((srcval2
<< 2) & 0x03e0) | /* g2 */
622 ((srcval2
>> 1) & 0x7c00); /* h2 */
624 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
625 ((srcval2
>> 22) & 0x03e0) | /* g3 */
626 ((srcval1
<< 7) & 0x7c00); /* h3 */
627 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
628 ((srcval1
>> 14) & 0x03e0) | /* g4 */
629 ((srcval1
>> 17) & 0x7c00); /* h4 */
633 /* And now up to 3 odd pixels */
634 srcbyte
=(const BYTE
*)srcpixel
;
635 for (x
=0; x
<oddwidth
; x
++) {
637 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
638 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
639 dstval
|=((srcbyte
[2] << 7) & 0x7c00); /* h */
643 srcbits
= (const char*)srcbits
+ srclinebytes
;
644 dstbits
= (char*)dstbits
+ dstlinebytes
;
648 static void convert_888_to_555_reverse(int width
, int height
,
649 const void* srcbits
, int srclinebytes
,
650 void* dstbits
, int dstlinebytes
)
652 const DWORD
* srcpixel
;
660 for (y
=0; y
<height
; y
++) {
663 for (x
=0; x
<width
; x
++) {
664 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
665 DWORD srcval1
,srcval2
;
667 dstpixel
[0]=((srcval1
<< 7) & 0x7c00) | /* l1 */
668 ((srcval1
>> 6) & 0x03e0) | /* g1 */
669 ((srcval1
>> 19) & 0x001f); /* h1 */
671 dstpixel
[1]=((srcval1
>> 17) & 0x7c00) | /* l2 */
672 ((srcval2
<< 2) & 0x03e0) | /* g2 */
673 ((srcval2
>> 11) & 0x001f); /* h2 */
675 dstpixel
[2]=((srcval2
>> 9) & 0x7c00) | /* l3 */
676 ((srcval2
>> 22) & 0x03e0) | /* g3 */
677 ((srcval1
>> 3) & 0x001f); /* h3 */
678 dstpixel
[3]=((srcval1
>> 1) & 0x7c00) | /* l4 */
679 ((srcval1
>> 14) & 0x03e0) | /* g4 */
680 ((srcval1
>> 27) & 0x001f); /* h4 */
684 /* And now up to 3 odd pixels */
685 srcbyte
=(const BYTE
*)srcpixel
;
686 for (x
=0; x
<oddwidth
; x
++) {
688 dstval
=((srcbyte
[0] << 7) & 0x7c00); /* l */
689 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
690 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
694 srcbits
= (const char*)srcbits
+ srclinebytes
;
695 dstbits
= (char*)dstbits
+ dstlinebytes
;
699 static void convert_888_to_565_asis(int width
, int height
,
700 const void* srcbits
, int srclinebytes
,
701 void* dstbits
, int dstlinebytes
)
703 const DWORD
* srcpixel
;
711 for (y
=0; y
<height
; y
++) {
714 for (x
=0; x
<width
; x
++) {
715 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
716 DWORD srcval1
,srcval2
;
718 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
719 ((srcval1
>> 5) & 0x07e0) | /* g1 */
720 ((srcval1
>> 8) & 0xf800); /* h1 */
722 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
723 ((srcval2
<< 3) & 0x07e0) | /* g2 */
724 ( srcval2
& 0xf800); /* h2 */
726 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
727 ((srcval2
>> 21) & 0x07e0) | /* g3 */
728 ((srcval1
<< 8) & 0xf800); /* h3 */
729 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
730 ((srcval1
>> 13) & 0x07e0) | /* g4 */
731 ((srcval1
>> 16) & 0xf800); /* h4 */
735 /* And now up to 3 odd pixels */
736 srcbyte
=(const BYTE
*)srcpixel
;
737 for (x
=0; x
<oddwidth
; x
++) {
739 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
740 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
741 dstval
|=((srcbyte
[2] << 8) & 0xf800); /* h */
745 srcbits
= (const char*)srcbits
+ srclinebytes
;
746 dstbits
= (char*)dstbits
+ dstlinebytes
;
750 static void convert_888_to_565_reverse(int width
, int height
,
751 const void* srcbits
, int srclinebytes
,
752 void* dstbits
, int dstlinebytes
)
754 const DWORD
* srcpixel
;
762 for (y
=0; y
<height
; y
++) {
765 for (x
=0; x
<width
; x
++) {
766 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
767 DWORD srcval1
,srcval2
;
769 dstpixel
[0]=((srcval1
<< 8) & 0xf800) | /* l1 */
770 ((srcval1
>> 5) & 0x07e0) | /* g1 */
771 ((srcval1
>> 19) & 0x001f); /* h1 */
773 dstpixel
[1]=((srcval1
>> 16) & 0xf800) | /* l2 */
774 ((srcval2
<< 3) & 0x07e0) | /* g2 */
775 ((srcval2
>> 11) & 0x001f); /* h2 */
777 dstpixel
[2]=((srcval2
>> 8) & 0xf800) | /* l3 */
778 ((srcval2
>> 21) & 0x07e0) | /* g3 */
779 ((srcval1
>> 3) & 0x001f); /* h3 */
780 dstpixel
[3]=(srcval1
& 0xf800) | /* l4 */
781 ((srcval1
>> 13) & 0x07e0) | /* g4 */
782 ((srcval1
>> 27) & 0x001f); /* h4 */
786 /* And now up to 3 odd pixels */
787 srcbyte
=(const BYTE
*)srcpixel
;
788 for (x
=0; x
<oddwidth
; x
++) {
790 dstval
=((srcbyte
[0] << 8) & 0xf800); /* l */
791 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
792 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
796 srcbits
= (const char*)srcbits
+ srclinebytes
;
797 dstbits
= (char*)dstbits
+ dstlinebytes
;
801 static void convert_888_to_0888_asis(int width
, int height
,
802 const void* srcbits
, int srclinebytes
,
803 void* dstbits
, int dstlinebytes
)
805 const DWORD
* srcpixel
;
812 for (y
=0; y
<height
; y
++) {
815 for (x
=0; x
<width
; x
++) {
816 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
817 DWORD srcval1
,srcval2
;
819 dstpixel
[0]=( srcval1
& 0x00ffffff); /* h1, g1, l1 */
821 dstpixel
[1]=( srcval1
>> 24) | /* l2 */
822 ((srcval2
<< 8) & 0x00ffff00); /* h2, g2 */
824 dstpixel
[2]=( srcval2
>> 16) | /* g3, l3 */
825 ((srcval1
<< 16) & 0x00ff0000); /* h3 */
826 dstpixel
[3]=( srcval1
>> 8); /* h4, g4, l4 */
830 /* And now up to 3 odd pixels */
831 for (x
=0; x
<oddwidth
; x
++) {
834 srcpixel
=(const DWORD
*)(((const char*)srcpixel
)+3);
835 *dstpixel
++=( srcval
& 0x00ffffff); /* h, g, l */
837 srcbits
= (const char*)srcbits
+ srclinebytes
;
838 dstbits
= (char*)dstbits
+ dstlinebytes
;
842 static void convert_888_to_0888_reverse(int width
, int height
,
843 const void* srcbits
, int srclinebytes
,
844 void* dstbits
, int dstlinebytes
)
846 const DWORD
* srcpixel
;
853 for (y
=0; y
<height
; y
++) {
856 for (x
=0; x
<width
; x
++) {
857 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
858 DWORD srcval1
,srcval2
;
861 dstpixel
[0]=((srcval1
>> 16) & 0x0000ff) | /* h1 */
862 ( srcval1
& 0x00ff00) | /* g1 */
863 ((srcval1
<< 16) & 0xff0000); /* l1 */
865 dstpixel
[1]=((srcval1
>> 8) & 0xff0000) | /* l2 */
866 ((srcval2
<< 8) & 0x00ff00) | /* g2 */
867 ((srcval2
>> 8) & 0x0000ff); /* h2 */
869 dstpixel
[2]=( srcval2
& 0xff0000) | /* l3 */
870 ((srcval2
>> 16) & 0x00ff00) | /* g3 */
871 ( srcval1
& 0x0000ff); /* h3 */
872 dstpixel
[3]=((srcval1
>> 24) & 0x0000ff) | /* h4 */
873 ((srcval1
>> 8) & 0x00ff00) | /* g4 */
874 ((srcval1
<< 8) & 0xff0000); /* l4 */
878 /* And now up to 3 odd pixels */
879 for (x
=0; x
<oddwidth
; x
++) {
882 srcpixel
=(const DWORD
*)(((const char*)srcpixel
)+3);
883 *dstpixel
++=((srcval
>> 16) & 0x0000ff) | /* h */
884 ( srcval
& 0x00ff00) | /* g */
885 ((srcval
<< 16) & 0xff0000); /* l */
887 srcbits
= (const char*)srcbits
+ srclinebytes
;
888 dstbits
= (char*)dstbits
+ dstlinebytes
;
892 static void convert_rgb888_to_any0888(int width
, int height
,
893 const void* srcbits
, int srclinebytes
,
894 void* dstbits
, int dstlinebytes
,
895 DWORD rdst
, DWORD gdst
, DWORD bdst
)
897 int rLeftShift
,gLeftShift
,bLeftShift
;
898 const BYTE
* srcpixel
;
902 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
903 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
904 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
905 for (y
=0; y
<height
; y
++) {
908 for (x
=0; x
<width
; x
++) {
909 *dstpixel
++=(srcpixel
[0] << bLeftShift
) | /* b */
910 (srcpixel
[1] << gLeftShift
) | /* g */
911 (srcpixel
[2] << rLeftShift
); /* r */
914 srcbits
= (const char*)srcbits
+ srclinebytes
;
915 dstbits
= (char*)dstbits
+ dstlinebytes
;
919 static void convert_bgr888_to_any0888(int width
, int height
,
920 const void* srcbits
, int srclinebytes
,
921 void* dstbits
, int dstlinebytes
,
922 DWORD rdst
, DWORD gdst
, DWORD bdst
)
924 int rLeftShift
,gLeftShift
,bLeftShift
;
925 const BYTE
* srcpixel
;
929 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
930 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
931 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
932 for (y
=0; y
<height
; y
++) {
935 for (x
=0; x
<width
; x
++) {
936 *dstpixel
++=(srcpixel
[0] << rLeftShift
) | /* r */
937 (srcpixel
[1] << gLeftShift
) | /* g */
938 (srcpixel
[2] << bLeftShift
); /* b */
941 srcbits
= (const char*)srcbits
+ srclinebytes
;
942 dstbits
= (char*)dstbits
+ dstlinebytes
;
950 static void convert_0888_asis(int width
, int height
,
951 const void* srcbits
, int srclinebytes
,
952 void* dstbits
, int dstlinebytes
)
956 for (y
=0; y
<height
; y
++) {
957 memcpy(dstbits
, srcbits
, width
*4);
958 srcbits
= (const char*)srcbits
+ srclinebytes
;
959 dstbits
= (char*)dstbits
+ dstlinebytes
;
963 static void convert_0888_reverse(int width
, int height
,
964 const void* srcbits
, int srclinebytes
,
965 void* dstbits
, int dstlinebytes
)
967 const DWORD
* srcpixel
;
971 for (y
=0; y
<height
; y
++) {
974 for (x
=0; x
<width
; x
++) {
977 *dstpixel
++=((srcval
<< 16) & 0x00ff0000) | /* h */
978 ( srcval
& 0x0000ff00) | /* g */
979 ((srcval
>> 16) & 0x000000ff); /* l */
981 srcbits
= (const char*)srcbits
+ srclinebytes
;
982 dstbits
= (char*)dstbits
+ dstlinebytes
;
986 static void convert_0888_any(int width
, int height
,
987 const void* srcbits
, int srclinebytes
,
988 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
989 void* dstbits
, int dstlinebytes
,
990 DWORD rdst
, DWORD gdst
, DWORD bdst
)
992 int rRightShift
,gRightShift
,bRightShift
;
993 int rLeftShift
,gLeftShift
,bLeftShift
;
994 const DWORD
* srcpixel
;
998 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
999 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1000 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1001 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1002 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1003 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1004 for (y
=0; y
<height
; y
++) {
1007 for (x
=0; x
<width
; x
++) {
1010 *dstpixel
++=(((srcval
>> rRightShift
) & 0xff) << rLeftShift
) |
1011 (((srcval
>> gRightShift
) & 0xff) << gLeftShift
) |
1012 (((srcval
>> bRightShift
) & 0xff) << bLeftShift
);
1014 srcbits
= (const char*)srcbits
+ srclinebytes
;
1015 dstbits
= (char*)dstbits
+ dstlinebytes
;
1019 static void convert_0888_to_555_asis(int width
, int height
,
1020 const void* srcbits
, int srclinebytes
,
1021 void* dstbits
, int dstlinebytes
)
1023 const DWORD
* srcpixel
;
1027 for (y
=0; y
<height
; y
++) {
1030 for (x
=0; x
<width
; x
++) {
1033 *dstpixel
++=((srcval
>> 9) & 0x7c00) | /* h */
1034 ((srcval
>> 6) & 0x03e0) | /* g */
1035 ((srcval
>> 3) & 0x001f); /* l */
1037 srcbits
= (const char*)srcbits
+ srclinebytes
;
1038 dstbits
= (char*)dstbits
+ dstlinebytes
;
1042 static void convert_0888_to_555_reverse(int width
, int height
,
1043 const void* srcbits
, int srclinebytes
,
1044 void* dstbits
, int dstlinebytes
)
1046 const DWORD
* srcpixel
;
1050 for (y
=0; y
<height
; y
++) {
1053 for (x
=0; x
<width
; x
++) {
1056 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1057 ((srcval
>> 6) & 0x03e0) | /* g */
1058 ((srcval
<< 7) & 0x7c00); /* l */
1060 srcbits
= (const char*)srcbits
+ srclinebytes
;
1061 dstbits
= (char*)dstbits
+ dstlinebytes
;
1065 static void convert_0888_to_565_asis(int width
, int height
,
1066 const void* srcbits
, int srclinebytes
,
1067 void* dstbits
, int dstlinebytes
)
1069 const DWORD
* srcpixel
;
1073 for (y
=0; y
<height
; y
++) {
1076 for (x
=0; x
<width
; x
++) {
1079 *dstpixel
++=((srcval
>> 8) & 0xf800) | /* h */
1080 ((srcval
>> 5) & 0x07e0) | /* g */
1081 ((srcval
>> 3) & 0x001f); /* l */
1083 srcbits
= (const char*)srcbits
+ srclinebytes
;
1084 dstbits
= (char*)dstbits
+ dstlinebytes
;
1088 static void convert_0888_to_565_reverse(int width
, int height
,
1089 const void* srcbits
, int srclinebytes
,
1090 void* dstbits
, int dstlinebytes
)
1092 const DWORD
* srcpixel
;
1096 for (y
=0; y
<height
; y
++) {
1099 for (x
=0; x
<width
; x
++) {
1102 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1103 ((srcval
>> 5) & 0x07e0) | /* g */
1104 ((srcval
<< 8) & 0xf800); /* l */
1106 srcbits
= (const char*)srcbits
+ srclinebytes
;
1107 dstbits
= (char*)dstbits
+ dstlinebytes
;
1111 static void convert_any0888_to_5x5(int width
, int height
,
1112 const void* srcbits
, int srclinebytes
,
1113 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1114 void* dstbits
, int dstlinebytes
,
1115 WORD rdst
, WORD gdst
, WORD bdst
)
1117 int rRightShift
,gRightShift
,bRightShift
;
1118 int rLeftShift
,gLeftShift
,bLeftShift
;
1119 const DWORD
* srcpixel
;
1123 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1124 * contains 0x11223344.
1125 * - first we shift 0x11223344 right by rRightShift to bring the most
1126 * significant bits of the red components in the bottom 5 (or 6) bits
1128 * - then we remove non red bits by anding with the modified rdst (0x1f)
1130 * - finally shift these bits left by rLeftShift so that they end up in
1134 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
)+3;
1135 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1136 gRightShift
+=(gdst
==0x07e0?2:3);
1137 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
)+3;
1139 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1140 rdst
=rdst
>> rLeftShift
;
1141 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1142 gdst
=gdst
>> gLeftShift
;
1143 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1144 bdst
=bdst
>> bLeftShift
;
1146 for (y
=0; y
<height
; y
++) {
1149 for (x
=0; x
<width
; x
++) {
1152 *dstpixel
++=(((srcval
>> rRightShift
) & rdst
) << rLeftShift
) |
1153 (((srcval
>> gRightShift
) & gdst
) << gLeftShift
) |
1154 (((srcval
>> bRightShift
) & bdst
) << bLeftShift
);
1156 srcbits
= (const char*)srcbits
+ srclinebytes
;
1157 dstbits
= (char*)dstbits
+ dstlinebytes
;
1161 static void convert_0888_to_888_asis(int width
, int height
,
1162 const void* srcbits
, int srclinebytes
,
1163 void* dstbits
, int dstlinebytes
)
1165 const DWORD
* srcpixel
;
1173 for (y
=0; y
<height
; y
++) {
1176 for (x
=0; x
<width
; x
++) {
1177 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1179 srcval
=((*srcpixel
++) & 0x00ffffff); /* h1, g1, l1*/
1180 *dstpixel
++=srcval
| ((*srcpixel
) << 24); /* h2 */
1181 srcval
=((*srcpixel
++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1182 *dstpixel
++=srcval
| ((*srcpixel
) << 16); /* h3, g3 */
1183 srcval
=((*srcpixel
++ >> 16) & 0x000000ff); /* l3 */
1184 *dstpixel
++=srcval
| ((*srcpixel
++) << 8); /* h4, g4, l4 */
1186 /* And now up to 3 odd pixels */
1187 dstbyte
=(BYTE
*)dstpixel
;
1188 for (x
=0; x
<oddwidth
; x
++) {
1191 *((WORD
*)dstbyte
) = srcval
; /* h, g */
1192 dstbyte
+=sizeof(WORD
);
1193 *dstbyte
++=srcval
>> 16; /* l */
1195 srcbits
= (const char*)srcbits
+ srclinebytes
;
1196 dstbits
= (char*)dstbits
+ dstlinebytes
;
1200 static void convert_0888_to_888_reverse(int width
, int height
,
1201 const void* srcbits
, int srclinebytes
,
1202 void* dstbits
, int dstlinebytes
)
1204 const DWORD
* srcpixel
;
1212 for (y
=0; y
<height
; y
++) {
1215 for (x
=0; x
<width
; x
++) {
1216 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1217 DWORD srcval1
,srcval2
;
1218 srcval1
=*srcpixel
++;
1219 srcval2
= ((srcval1
>> 16) & 0x000000ff) | /* h1 */
1220 ( srcval1
& 0x0000ff00) | /* g1 */
1221 ((srcval1
<< 16) & 0x00ff0000); /* l1 */
1222 srcval1
=*srcpixel
++;
1223 *dstpixel
++=srcval2
|
1224 ((srcval1
<< 8) & 0xff000000); /* h2 */
1225 srcval2
= ((srcval1
>> 8) & 0x000000ff) | /* g2 */
1226 ((srcval1
<< 8) & 0x0000ff00); /* l2 */
1227 srcval1
=*srcpixel
++;
1228 *dstpixel
++=srcval2
|
1229 ( srcval1
& 0x00ff0000) | /* h3 */
1230 ((srcval1
<< 16) & 0xff000000); /* g3 */
1231 srcval2
= ( srcval1
& 0x000000ff); /* l3 */
1232 srcval1
=*srcpixel
++;
1233 *dstpixel
++=srcval2
|
1234 ((srcval1
>> 8) & 0x0000ff00) | /* h4 */
1235 ((srcval1
<< 8) & 0x00ff0000) | /* g4 */
1236 ( srcval1
<< 24); /* l4 */
1238 /* And now up to 3 odd pixels */
1239 dstbyte
=(BYTE
*)dstpixel
;
1240 for (x
=0; x
<oddwidth
; x
++) {
1243 *((WORD
*)dstbyte
)=((srcval
>> 16) & 0x00ff) | /* h */
1244 (srcval
& 0xff00); /* g */
1245 dstbyte
+= sizeof(WORD
);
1246 *dstbyte
++=srcval
; /* l */
1248 srcbits
= (const char*)srcbits
+ srclinebytes
;
1249 dstbits
= (char*)dstbits
+ dstlinebytes
;
1253 static void convert_any0888_to_rgb888(int width
, int height
,
1254 const void* srcbits
, int srclinebytes
,
1255 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1256 void* dstbits
, int dstlinebytes
)
1258 int rRightShift
,gRightShift
,bRightShift
;
1259 const DWORD
* srcpixel
;
1263 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1264 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1265 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1266 for (y
=0; y
<height
; y
++) {
1269 for (x
=0; x
<width
; x
++) {
1272 dstpixel
[0]=(srcval
>> bRightShift
); /* b */
1273 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1274 dstpixel
[2]=(srcval
>> rRightShift
); /* r */
1277 srcbits
= (const char*)srcbits
+ srclinebytes
;
1278 dstbits
= (char*)dstbits
+ dstlinebytes
;
1282 static void convert_any0888_to_bgr888(int width
, int height
,
1283 const void* srcbits
, int srclinebytes
,
1284 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1285 void* dstbits
, int dstlinebytes
)
1287 int rRightShift
,gRightShift
,bRightShift
;
1288 const DWORD
* srcpixel
;
1292 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1293 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1294 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1295 for (y
=0; y
<height
; y
++) {
1298 for (x
=0; x
<width
; x
++) {
1301 dstpixel
[0]=(srcval
>> rRightShift
); /* r */
1302 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1303 dstpixel
[2]=(srcval
>> bRightShift
); /* b */
1306 srcbits
= (const char*)srcbits
+ srclinebytes
;
1307 dstbits
= (char*)dstbits
+ dstlinebytes
;
1311 const dib_conversions dib_normal
= {
1313 convert_555_reverse
,
1314 convert_555_to_565_asis
,
1315 convert_555_to_565_reverse
,
1316 convert_555_to_888_asis
,
1317 convert_555_to_888_reverse
,
1318 convert_555_to_0888_asis
,
1319 convert_555_to_0888_reverse
,
1320 convert_5x5_to_any0888
,
1321 convert_565_reverse
,
1322 convert_565_to_555_asis
,
1323 convert_565_to_555_reverse
,
1324 convert_565_to_888_asis
,
1325 convert_565_to_888_reverse
,
1326 convert_565_to_0888_asis
,
1327 convert_565_to_0888_reverse
,
1329 convert_888_reverse
,
1330 convert_888_to_555_asis
,
1331 convert_888_to_555_reverse
,
1332 convert_888_to_565_asis
,
1333 convert_888_to_565_reverse
,
1334 convert_888_to_0888_asis
,
1335 convert_888_to_0888_reverse
,
1336 convert_rgb888_to_any0888
,
1337 convert_bgr888_to_any0888
,
1339 convert_0888_reverse
,
1341 convert_0888_to_555_asis
,
1342 convert_0888_to_555_reverse
,
1343 convert_0888_to_565_asis
,
1344 convert_0888_to_565_reverse
,
1345 convert_any0888_to_5x5
,
1346 convert_0888_to_888_asis
,
1347 convert_0888_to_888_reverse
,
1348 convert_any0888_to_rgb888
,
1349 convert_any0888_to_bgr888