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 = (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=*((WORD*)srcpixel);
109 *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
110 ( srcval & 0x03e0) | /* g */
111 ((srcval >> 10) & 0x001f); /* l */
113 srcbits = (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=*((WORD*)srcpixel);
141 *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
142 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
143 (srcval & 0x001f); /* l */
145 srcbits = (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=*((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 = (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 = (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 = (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 = (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 = (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 = (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=*((WORD*)srcpixel);
378 *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
379 ( srcval & 0x07e0) | /* g */
380 ((srcval >> 11) & 0x001f); /* l */
382 srcbits = (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=*((WORD*)srcpixel);
409 *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
410 ( srcval & 0x001f); /* l */
412 srcbits = (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=*((WORD*)srcpixel);
440 *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
441 ((srcval >> 1) & 0x03e0) | /* g */
442 ((srcval << 10) & 0x7c00); /* l */
444 srcbits = (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 = (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 = (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 = (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 = (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 = (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 = (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=(LPBYTE)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 = (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=(LPBYTE)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 = (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=(LPBYTE)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 = (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=(LPBYTE)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 = (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=(LPDWORD)(((char*)srcpixel)+3);
835 *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */
837 srcbits = (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=(LPDWORD)(((char*)srcpixel)+3);
883 *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */
884 ( srcval & 0x00ff00) | /* g */
885 ((srcval << 16) & 0xff0000); /* l */
887 srcbits = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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 = (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++=srcval >> 16; /* l */
1194 srcbits = (char*)srcbits + srclinebytes;
1195 dstbits = (char*)dstbits + dstlinebytes;
1199 static void convert_0888_to_888_reverse(int width, int height,
1200 const void* srcbits, int srclinebytes,
1201 void* dstbits, int dstlinebytes)
1203 const DWORD* srcpixel;
1211 for (y=0; y<height; y++) {
1214 for (x=0; x<width; x++) {
1215 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1216 DWORD srcval1,srcval2;
1217 srcval1=*srcpixel++;
1218 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1219 ( srcval1 & 0x0000ff00) | /* g1 */
1220 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1221 srcval1=*srcpixel++;
1222 *dstpixel++=srcval2 |
1223 ((srcval1 << 8) & 0xff000000); /* h2 */
1224 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1225 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1226 srcval1=*srcpixel++;
1227 *dstpixel++=srcval2 |
1228 ( srcval1 & 0x00ff0000) | /* h3 */
1229 ((srcval1 << 16) & 0xff000000); /* g3 */
1230 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1231 srcval1=*srcpixel++;
1232 *dstpixel++=srcval2 |
1233 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1234 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1235 ( srcval1 << 24); /* l4 */
1237 /* And now up to 3 odd pixels */
1238 dstbyte=(BYTE*)dstpixel;
1239 for (x=0; x<oddwidth; x++) {
1242 *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */
1243 (srcval & 0xff00); /* g */
1244 *dstbyte++=srcval; /* l */
1246 srcbits = (char*)srcbits + srclinebytes;
1247 dstbits = (char*)dstbits + dstlinebytes;
1251 static void convert_any0888_to_rgb888(int width, int height,
1252 const void* srcbits, int srclinebytes,
1253 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1254 void* dstbits, int dstlinebytes)
1256 int rRightShift,gRightShift,bRightShift;
1257 const DWORD* srcpixel;
1261 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1262 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1263 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1264 for (y=0; y<height; y++) {
1267 for (x=0; x<width; x++) {
1270 dstpixel[0]=(srcval >> bRightShift); /* b */
1271 dstpixel[1]=(srcval >> gRightShift); /* g */
1272 dstpixel[2]=(srcval >> rRightShift); /* r */
1275 srcbits = (char*)srcbits + srclinebytes;
1276 dstbits = (char*)dstbits + dstlinebytes;
1280 static void convert_any0888_to_bgr888(int width, int height,
1281 const void* srcbits, int srclinebytes,
1282 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1283 void* dstbits, int dstlinebytes)
1285 int rRightShift,gRightShift,bRightShift;
1286 const DWORD* srcpixel;
1290 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1291 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1292 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1293 for (y=0; y<height; y++) {
1296 for (x=0; x<width; x++) {
1299 dstpixel[0]=(srcval >> rRightShift); /* r */
1300 dstpixel[1]=(srcval >> gRightShift); /* g */
1301 dstpixel[2]=(srcval >> bRightShift); /* b */
1304 srcbits = (char*)srcbits + srclinebytes;
1305 dstbits = (char*)dstbits + dstlinebytes;
1309 const dib_conversions dib_normal = {
1311 convert_555_reverse,
1312 convert_555_to_565_asis,
1313 convert_555_to_565_reverse,
1314 convert_555_to_888_asis,
1315 convert_555_to_888_reverse,
1316 convert_555_to_0888_asis,
1317 convert_555_to_0888_reverse,
1318 convert_5x5_to_any0888,
1319 convert_565_reverse,
1320 convert_565_to_555_asis,
1321 convert_565_to_555_reverse,
1322 convert_565_to_888_asis,
1323 convert_565_to_888_reverse,
1324 convert_565_to_0888_asis,
1325 convert_565_to_0888_reverse,
1327 convert_888_reverse,
1328 convert_888_to_555_asis,
1329 convert_888_to_555_reverse,
1330 convert_888_to_565_asis,
1331 convert_888_to_565_reverse,
1332 convert_888_to_0888_asis,
1333 convert_888_to_0888_reverse,
1334 convert_rgb888_to_any0888,
1335 convert_bgr888_to_any0888,
1337 convert_0888_reverse,
1339 convert_0888_to_555_asis,
1340 convert_0888_to_555_reverse,
1341 convert_0888_to_565_asis,
1342 convert_0888_to_565_reverse,
1343 convert_any0888_to_5x5,
1344 convert_0888_to_888_asis,
1345 convert_0888_to_888_reverse,
1346 convert_any0888_to_rgb888,
1347 convert_any0888_to_bgr888