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)
80 if (srclinebytes == dstlinebytes && srclinebytes == width)
82 memcpy(dstbits, srcbits, height * width);
86 for (y=0; y<height; y++) {
87 memcpy(dstbits, srcbits, width);
88 srcbits = (const char*)srcbits + srclinebytes;
89 dstbits = (char*)dstbits + dstlinebytes;
94 static void convert_555_reverse(int width, int height,
95 const void* srcbits, int srclinebytes,
96 void* dstbits, int dstlinebytes)
98 const DWORD* srcpixel;
102 for (y=0; y<height; y++) {
105 for (x=0; x<width/2; x++) {
106 /* Do 2 pixels at a time */
109 *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */
110 ( srcval & 0x03e003e0) | /* g */
111 ((srcval >> 10) & 0x001f001f); /* l */
114 /* And the the odd pixel */
116 srcval=*((const WORD*)srcpixel);
117 *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
118 ( srcval & 0x03e0) | /* g */
119 ((srcval >> 10) & 0x001f); /* l */
121 srcbits = (const char*)srcbits + srclinebytes;
122 dstbits = (char*)dstbits + dstlinebytes;
126 static void convert_555_to_565_asis(int width, int height,
127 const void* srcbits, int srclinebytes,
128 void* dstbits, int dstlinebytes)
130 const DWORD* srcpixel;
134 for (y=0; y<height; y++) {
137 for (x=0; x<width/2; x++) {
138 /* Do 2 pixels at a time */
141 *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */
142 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
143 ( srcval & 0x001f001f); /* l */
146 /* And the the odd pixel */
148 srcval=*((const WORD*)srcpixel);
149 *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
150 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
151 (srcval & 0x001f); /* l */
153 srcbits = (const char*)srcbits + srclinebytes;
154 dstbits = (char*)dstbits + dstlinebytes;
158 static void convert_555_to_565_reverse(int width, int height,
159 const void* srcbits, int srclinebytes,
160 void* dstbits, int dstlinebytes)
162 const DWORD* srcpixel;
166 for (y=0; y<height; y++) {
169 for (x=0; x<width/2; x++) {
170 /* Do 2 pixels at a time */
173 *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */
174 ((srcval << 1) & 0x07c007c0) | /* g */
175 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
176 ((srcval << 11) & 0xf800f800); /* l */
179 /* And the the odd pixel */
181 srcval=*((const WORD*)srcpixel);
182 *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */
183 ((srcval << 1) & 0x07c0) | /* g */
184 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
185 ((srcval << 11) & 0xf800); /* l */
187 srcbits = (const char*)srcbits + srclinebytes;
188 dstbits = (char*)dstbits + dstlinebytes;
192 static void convert_555_to_888_asis(int width, int height,
193 const void* srcbits, int srclinebytes,
194 void* dstbits, int dstlinebytes)
196 const WORD* srcpixel;
200 for (y=0; y<height; y++) {
203 for (x=0; x<width; x++) {
206 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
207 ((srcval >> 2) & 0x07); /* l - 3 bits */
208 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
209 ((srcval >> 7) & 0x07); /* g - 3 bits */
210 dstpixel[2]=((srcval >> 7) & 0xf8) | /* h */
211 ((srcval >> 12) & 0x07); /* h - 3 bits */
214 srcbits = (const char*)srcbits + srclinebytes;
215 dstbits = (char*)dstbits + dstlinebytes;
219 static void convert_555_to_888_reverse(int width, int height,
220 const void* srcbits, int srclinebytes,
221 void* dstbits, int dstlinebytes)
223 const WORD* srcpixel;
227 for (y=0; y<height; y++) {
230 for (x=0; x<width; x++) {
233 dstpixel[0]=((srcval >> 7) & 0xf8) | /* h */
234 ((srcval >> 12) & 0x07); /* h - 3 bits */
235 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
236 ((srcval >> 7) & 0x07); /* g - 3 bits */
237 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
238 ((srcval >> 2) & 0x07); /* l - 3 bits */
241 srcbits = (const char*)srcbits + srclinebytes;
242 dstbits = (char*)dstbits + dstlinebytes;
246 static void convert_555_to_0888_asis(int width, int height,
247 const void* srcbits, int srclinebytes,
248 void* dstbits, int dstlinebytes)
250 const WORD* srcpixel;
254 for (y=0; y<height; y++) {
257 for (x=0; x<width; x++) {
260 *dstpixel++=((srcval << 9) & 0xf80000) | /* h */
261 ((srcval << 4) & 0x070000) | /* h - 3 bits */
262 ((srcval << 6) & 0x00f800) | /* g */
263 ((srcval << 1) & 0x000700) | /* g - 3 bits */
264 ((srcval << 3) & 0x0000f8) | /* l */
265 ((srcval >> 2) & 0x000007); /* l - 3 bits */
267 srcbits = (const char*)srcbits + srclinebytes;
268 dstbits = (char*)dstbits + dstlinebytes;
272 static void convert_555_to_0888_reverse(int width, int height,
273 const void* srcbits, int srclinebytes,
274 void* dstbits, int dstlinebytes)
276 const WORD* srcpixel;
280 for (y=0; y<height; y++) {
283 for (x=0; x<width; x++) {
286 *dstpixel++=((srcval >> 7) & 0x0000f8) | /* h */
287 ((srcval >> 12) & 0x000007) | /* h - 3 bits */
288 ((srcval << 6) & 0x00f800) | /* g */
289 ((srcval << 1) & 0x000700) | /* g - 3 bits */
290 ((srcval << 19) & 0xf80000) | /* l */
291 ((srcval << 14) & 0x070000); /* l - 3 bits */
293 srcbits = (const char*)srcbits + srclinebytes;
294 dstbits = (char*)dstbits + dstlinebytes;
298 static void convert_5x5_to_any0888(int width, int height,
299 const void* srcbits, int srclinebytes,
300 WORD rsrc, WORD gsrc, WORD bsrc,
301 void* dstbits, int dstlinebytes,
302 DWORD rdst, DWORD gdst, DWORD bdst)
304 int rRightShift1,gRightShift1,bRightShift1;
305 int rRightShift2,gRightShift2,bRightShift2;
307 int rLeftShift,gLeftShift,bLeftShift;
308 const WORD* srcpixel;
312 /* Note, the source pixel value is shifted left by 16 bits so that
313 * we know we will always have to shift right to extract the components.
315 rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
316 gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
317 bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
318 rRightShift2=rRightShift1+5;
319 gRightShift2=gRightShift1+5;
320 bRightShift2=bRightShift1+5;
322 /* Green has 5 bits, like the others */
326 /* Green has 6 bits, not 5. Compensate. */
333 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
334 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
335 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
337 for (y=0; y<height; y++) {
340 for (x=0; x<width; x++) {
343 srcval=*srcpixel++ << 16;
344 red= ((srcval >> rRightShift1) & 0xf8) |
345 ((srcval >> rRightShift2) & 0x07);
346 green=((srcval >> gRightShift1) & gMask1) |
347 ((srcval >> gRightShift2) & gMask2);
348 blue= ((srcval >> bRightShift1) & 0xf8) |
349 ((srcval >> bRightShift2) & 0x07);
350 *dstpixel++=(red << rLeftShift) |
351 (green << gLeftShift) |
352 (blue << bLeftShift);
354 srcbits = (const char*)srcbits + srclinebytes;
355 dstbits = (char*)dstbits + dstlinebytes;
360 * 16 bits conversions
363 static void convert_565_reverse(int width, int height,
364 const void* srcbits, int srclinebytes,
365 void* dstbits, int dstlinebytes)
367 const DWORD* srcpixel;
371 for (y=0; y<height; y++) {
374 for (x=0; x<width/2; x++) {
375 /* Do 2 pixels at a time */
378 *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */
379 ( srcval & 0x07e007e0) | /* g */
380 ((srcval >> 11) & 0x001f001f); /* l */
383 /* And the the odd pixel */
385 srcval=*((const WORD*)srcpixel);
386 *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
387 ( srcval & 0x07e0) | /* g */
388 ((srcval >> 11) & 0x001f); /* l */
390 srcbits = (const char*)srcbits + srclinebytes;
391 dstbits = (char*)dstbits + dstlinebytes;
395 static void convert_565_to_555_asis(int width, int height,
396 const void* srcbits, int srclinebytes,
397 void* dstbits, int dstlinebytes)
399 const DWORD* srcpixel;
403 for (y=0; y<height; y++) {
406 for (x=0; x<width/2; x++) {
407 /* Do 2 pixels at a time */
410 *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */
411 ( srcval & 0x001f001f); /* l */
414 /* And the the odd pixel */
416 srcval=*((const WORD*)srcpixel);
417 *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
418 ( srcval & 0x001f); /* l */
420 srcbits = (const char*)srcbits + srclinebytes;
421 dstbits = (char*)dstbits + dstlinebytes;
425 static void convert_565_to_555_reverse(int width, int height,
426 const void* srcbits, int srclinebytes,
427 void* dstbits, int dstlinebytes)
429 const DWORD* srcpixel;
433 for (y=0; y<height; y++) {
436 for (x=0; x<width/2; x++) {
437 /* Do 2 pixels at a time */
440 *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */
441 ((srcval >> 1) & 0x03e003e0) | /* g */
442 ((srcval << 10) & 0x7c007c00); /* l */
445 /* And the the odd pixel */
447 srcval=*((const WORD*)srcpixel);
448 *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
449 ((srcval >> 1) & 0x03e0) | /* g */
450 ((srcval << 10) & 0x7c00); /* l */
452 srcbits = (const char*)srcbits + srclinebytes;
453 dstbits = (char*)dstbits + dstlinebytes;
457 static void convert_565_to_888_asis(int width, int height,
458 const void* srcbits, int srclinebytes,
459 void* dstbits, int dstlinebytes)
461 const WORD* srcpixel;
465 for (y=0; y<height; y++) {
468 for (x=0; x<width; x++) {
471 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
472 ((srcval >> 2) & 0x07); /* l - 3 bits */
473 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
474 ((srcval >> 9) & 0x03); /* g - 2 bits */
475 dstpixel[2]=((srcval >> 8) & 0xf8) | /* h */
476 ((srcval >> 13) & 0x07); /* h - 3 bits */
479 srcbits = (const char*)srcbits + srclinebytes;
480 dstbits = (char*)dstbits + dstlinebytes;
484 static void convert_565_to_888_reverse(int width, int height,
485 const void* srcbits, int srclinebytes,
486 void* dstbits, int dstlinebytes)
488 const WORD* srcpixel;
492 for (y=0; y<height; y++) {
495 for (x=0; x<width; x++) {
498 dstpixel[0]=((srcval >> 8) & 0xf8) | /* h */
499 ((srcval >> 13) & 0x07); /* h - 3 bits */
500 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
501 ((srcval >> 9) & 0x03); /* g - 2 bits */
502 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
503 ((srcval >> 2) & 0x07); /* l - 3 bits */
506 srcbits = (const char*)srcbits + srclinebytes;
507 dstbits = (char*)dstbits + dstlinebytes;
511 static void convert_565_to_0888_asis(int width, int height,
512 const void* srcbits, int srclinebytes,
513 void* dstbits, int dstlinebytes)
515 const WORD* srcpixel;
519 for (y=0; y<height; y++) {
522 for (x=0; x<width; x++) {
525 *dstpixel++=((srcval << 8) & 0xf80000) | /* h */
526 ((srcval << 3) & 0x070000) | /* h - 3 bits */
527 ((srcval << 5) & 0x00fc00) | /* g */
528 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
529 ((srcval << 3) & 0x0000f8) | /* l */
530 ((srcval >> 2) & 0x000007); /* l - 3 bits */
532 srcbits = (const char*)srcbits + srclinebytes;
533 dstbits = (char*)dstbits + dstlinebytes;
537 static void convert_565_to_0888_reverse(int width, int height,
538 const void* srcbits, int srclinebytes,
539 void* dstbits, int dstlinebytes)
541 const WORD* srcpixel;
545 for (y=0; y<height; y++) {
548 for (x=0; x<width; x++) {
551 *dstpixel++=((srcval >> 8) & 0x0000f8) | /* h */
552 ((srcval >> 13) & 0x000007) | /* h - 3 bits */
553 ((srcval << 5) & 0x00fc00) | /* g */
554 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
555 ((srcval << 19) & 0xf80000) | /* l */
556 ((srcval << 14) & 0x070000); /* l - 3 bits */
558 srcbits = (const char*)srcbits + srclinebytes;
559 dstbits = (char*)dstbits + dstlinebytes;
568 static void convert_888_asis(int width, int height,
569 const void* srcbits, int srclinebytes,
570 void* dstbits, int dstlinebytes)
576 if (srclinebytes == dstlinebytes && srclinebytes == width)
578 memcpy(dstbits, srcbits, height * width);
582 for (y=0; y<height; y++) {
583 memcpy(dstbits, srcbits, width);
584 srcbits = (const char*)srcbits + srclinebytes;
585 dstbits = (char*)dstbits + dstlinebytes;
590 static void convert_888_reverse(int width, int height,
591 const void* srcbits, int srclinebytes,
592 void* dstbits, int dstlinebytes)
594 const BYTE* srcpixel;
598 for (y=0; y<height; y++) {
601 for (x=0; x<width; x++) {
602 dstpixel[0]=srcpixel[2];
603 dstpixel[1]=srcpixel[1];
604 dstpixel[2]=srcpixel[0];
608 srcbits = (const char*)srcbits + srclinebytes;
609 dstbits = (char*)dstbits + dstlinebytes;
613 static void convert_888_to_555_asis(int width, int height,
614 const void* srcbits, int srclinebytes,
615 void* dstbits, int dstlinebytes)
617 const DWORD* srcpixel;
625 for (y=0; y<height; y++) {
628 for (x=0; x<width; x++) {
629 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
630 DWORD srcval1,srcval2;
632 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
633 ((srcval1 >> 6) & 0x03e0) | /* g1 */
634 ((srcval1 >> 9) & 0x7c00); /* h1 */
636 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
637 ((srcval2 << 2) & 0x03e0) | /* g2 */
638 ((srcval2 >> 1) & 0x7c00); /* h2 */
640 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
641 ((srcval2 >> 22) & 0x03e0) | /* g3 */
642 ((srcval1 << 7) & 0x7c00); /* h3 */
643 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
644 ((srcval1 >> 14) & 0x03e0) | /* g4 */
645 ((srcval1 >> 17) & 0x7c00); /* h4 */
649 /* And now up to 3 odd pixels */
650 srcbyte=(const BYTE*)srcpixel;
651 for (x=0; x<oddwidth; x++) {
653 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
654 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
655 dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */
659 srcbits = (const char*)srcbits + srclinebytes;
660 dstbits = (char*)dstbits + dstlinebytes;
664 static void convert_888_to_555_reverse(int width, int height,
665 const void* srcbits, int srclinebytes,
666 void* dstbits, int dstlinebytes)
668 const DWORD* srcpixel;
676 for (y=0; y<height; y++) {
679 for (x=0; x<width; x++) {
680 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
681 DWORD srcval1,srcval2;
683 dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */
684 ((srcval1 >> 6) & 0x03e0) | /* g1 */
685 ((srcval1 >> 19) & 0x001f); /* h1 */
687 dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
688 ((srcval2 << 2) & 0x03e0) | /* g2 */
689 ((srcval2 >> 11) & 0x001f); /* h2 */
691 dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */
692 ((srcval2 >> 22) & 0x03e0) | /* g3 */
693 ((srcval1 >> 3) & 0x001f); /* h3 */
694 dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */
695 ((srcval1 >> 14) & 0x03e0) | /* g4 */
696 ((srcval1 >> 27) & 0x001f); /* h4 */
700 /* And now up to 3 odd pixels */
701 srcbyte=(const BYTE*)srcpixel;
702 for (x=0; x<oddwidth; x++) {
704 dstval =((srcbyte[0] << 7) & 0x7c00); /* l */
705 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
706 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
710 srcbits = (const char*)srcbits + srclinebytes;
711 dstbits = (char*)dstbits + dstlinebytes;
715 static void convert_888_to_565_asis(int width, int height,
716 const void* srcbits, int srclinebytes,
717 void* dstbits, int dstlinebytes)
719 const DWORD* srcpixel;
727 for (y=0; y<height; y++) {
730 for (x=0; x<width; x++) {
731 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
732 DWORD srcval1,srcval2;
734 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
735 ((srcval1 >> 5) & 0x07e0) | /* g1 */
736 ((srcval1 >> 8) & 0xf800); /* h1 */
738 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
739 ((srcval2 << 3) & 0x07e0) | /* g2 */
740 ( srcval2 & 0xf800); /* h2 */
742 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
743 ((srcval2 >> 21) & 0x07e0) | /* g3 */
744 ((srcval1 << 8) & 0xf800); /* h3 */
745 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
746 ((srcval1 >> 13) & 0x07e0) | /* g4 */
747 ((srcval1 >> 16) & 0xf800); /* h4 */
751 /* And now up to 3 odd pixels */
752 srcbyte=(const BYTE*)srcpixel;
753 for (x=0; x<oddwidth; x++) {
755 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
756 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
757 dstval|=((srcbyte[2] << 8) & 0xf800); /* h */
761 srcbits = (const char*)srcbits + srclinebytes;
762 dstbits = (char*)dstbits + dstlinebytes;
766 static void convert_888_to_565_reverse(int width, int height,
767 const void* srcbits, int srclinebytes,
768 void* dstbits, int dstlinebytes)
770 const DWORD* srcpixel;
778 for (y=0; y<height; y++) {
781 for (x=0; x<width; x++) {
782 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
783 DWORD srcval1,srcval2;
785 dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */
786 ((srcval1 >> 5) & 0x07e0) | /* g1 */
787 ((srcval1 >> 19) & 0x001f); /* h1 */
789 dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
790 ((srcval2 << 3) & 0x07e0) | /* g2 */
791 ((srcval2 >> 11) & 0x001f); /* h2 */
793 dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */
794 ((srcval2 >> 21) & 0x07e0) | /* g3 */
795 ((srcval1 >> 3) & 0x001f); /* h3 */
796 dstpixel[3]=(srcval1 & 0xf800) | /* l4 */
797 ((srcval1 >> 13) & 0x07e0) | /* g4 */
798 ((srcval1 >> 27) & 0x001f); /* h4 */
802 /* And now up to 3 odd pixels */
803 srcbyte=(const BYTE*)srcpixel;
804 for (x=0; x<oddwidth; x++) {
806 dstval =((srcbyte[0] << 8) & 0xf800); /* l */
807 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
808 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
812 srcbits = (const char*)srcbits + srclinebytes;
813 dstbits = (char*)dstbits + dstlinebytes;
817 static void convert_888_to_0888_asis(int width, int height,
818 const void* srcbits, int srclinebytes,
819 void* dstbits, int dstlinebytes)
821 const DWORD* srcpixel;
828 for (y=0; y<height; y++) {
831 for (x=0; x<width; x++) {
832 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
833 DWORD srcval1,srcval2;
835 dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
837 dstpixel[1]=( srcval1 >> 24) | /* l2 */
838 ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
840 dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */
841 ((srcval1 << 16) & 0x00ff0000); /* h3 */
842 dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */
846 /* And now up to 3 odd pixels */
847 for (x=0; x<oddwidth; x++) {
850 srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
851 *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */
853 srcbits = (const char*)srcbits + srclinebytes;
854 dstbits = (char*)dstbits + dstlinebytes;
858 static void convert_888_to_0888_reverse(int width, int height,
859 const void* srcbits, int srclinebytes,
860 void* dstbits, int dstlinebytes)
862 const DWORD* srcpixel;
869 for (y=0; y<height; y++) {
872 for (x=0; x<width; x++) {
873 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
874 DWORD srcval1,srcval2;
877 dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
878 ( srcval1 & 0x00ff00) | /* g1 */
879 ((srcval1 << 16) & 0xff0000); /* l1 */
881 dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */
882 ((srcval2 << 8) & 0x00ff00) | /* g2 */
883 ((srcval2 >> 8) & 0x0000ff); /* h2 */
885 dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */
886 ((srcval2 >> 16) & 0x00ff00) | /* g3 */
887 ( srcval1 & 0x0000ff); /* h3 */
888 dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
889 ((srcval1 >> 8) & 0x00ff00) | /* g4 */
890 ((srcval1 << 8) & 0xff0000); /* l4 */
894 /* And now up to 3 odd pixels */
895 for (x=0; x<oddwidth; x++) {
898 srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
899 *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */
900 ( srcval & 0x00ff00) | /* g */
901 ((srcval << 16) & 0xff0000); /* l */
903 srcbits = (const char*)srcbits + srclinebytes;
904 dstbits = (char*)dstbits + dstlinebytes;
908 static void convert_rgb888_to_any0888(int width, int height,
909 const void* srcbits, int srclinebytes,
910 void* dstbits, int dstlinebytes,
911 DWORD rdst, DWORD gdst, DWORD bdst)
913 int rLeftShift,gLeftShift,bLeftShift;
914 const BYTE* srcpixel;
918 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
919 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
920 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
921 for (y=0; y<height; y++) {
924 for (x=0; x<width; x++) {
925 *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
926 (srcpixel[1] << gLeftShift) | /* g */
927 (srcpixel[2] << rLeftShift); /* r */
930 srcbits = (const char*)srcbits + srclinebytes;
931 dstbits = (char*)dstbits + dstlinebytes;
935 static void convert_bgr888_to_any0888(int width, int height,
936 const void* srcbits, int srclinebytes,
937 void* dstbits, int dstlinebytes,
938 DWORD rdst, DWORD gdst, DWORD bdst)
940 int rLeftShift,gLeftShift,bLeftShift;
941 const BYTE* srcpixel;
945 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
946 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
947 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
948 for (y=0; y<height; y++) {
951 for (x=0; x<width; x++) {
952 *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
953 (srcpixel[1] << gLeftShift) | /* g */
954 (srcpixel[2] << bLeftShift); /* b */
957 srcbits = (const char*)srcbits + srclinebytes;
958 dstbits = (char*)dstbits + dstlinebytes;
966 static void convert_0888_asis(int width, int height,
967 const void* srcbits, int srclinebytes,
968 void* dstbits, int dstlinebytes)
974 if (srclinebytes == dstlinebytes && srclinebytes == width)
976 memcpy(dstbits, srcbits, height * width);
980 for (y=0; y<height; y++) {
981 memcpy(dstbits, srcbits, width);
982 srcbits = (const char*)srcbits + srclinebytes;
983 dstbits = (char*)dstbits + dstlinebytes;
987 static void convert_0888_reverse(int width, int height,
988 const void* srcbits, int srclinebytes,
989 void* dstbits, int dstlinebytes)
991 const DWORD* srcpixel;
995 for (y=0; y<height; y++) {
998 for (x=0; x<width; x++) {
1001 *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1002 ( srcval & 0x0000ff00) | /* g */
1003 ((srcval >> 16) & 0x000000ff); /* l */
1005 srcbits = (const char*)srcbits + srclinebytes;
1006 dstbits = (char*)dstbits + dstlinebytes;
1010 static void convert_0888_any(int width, int height,
1011 const void* srcbits, int srclinebytes,
1012 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1013 void* dstbits, int dstlinebytes,
1014 DWORD rdst, DWORD gdst, DWORD bdst)
1016 int rRightShift,gRightShift,bRightShift;
1017 int rLeftShift,gLeftShift,bLeftShift;
1018 const DWORD* srcpixel;
1022 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1023 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1024 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1025 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1026 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1027 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1028 for (y=0; y<height; y++) {
1031 for (x=0; x<width; x++) {
1034 *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1035 (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1036 (((srcval >> bRightShift) & 0xff) << bLeftShift);
1038 srcbits = (const char*)srcbits + srclinebytes;
1039 dstbits = (char*)dstbits + dstlinebytes;
1043 static void convert_0888_to_555_asis(int width, int height,
1044 const void* srcbits, int srclinebytes,
1045 void* dstbits, int dstlinebytes)
1047 const DWORD* srcpixel;
1051 for (y=0; y<height; y++) {
1054 for (x=0; x<width; x++) {
1057 *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1058 ((srcval >> 6) & 0x03e0) | /* g */
1059 ((srcval >> 3) & 0x001f); /* l */
1061 srcbits = (const char*)srcbits + srclinebytes;
1062 dstbits = (char*)dstbits + dstlinebytes;
1066 static void convert_0888_to_555_reverse(int width, int height,
1067 const void* srcbits, int srclinebytes,
1068 void* dstbits, int dstlinebytes)
1070 const DWORD* srcpixel;
1074 for (y=0; y<height; y++) {
1077 for (x=0; x<width; x++) {
1080 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1081 ((srcval >> 6) & 0x03e0) | /* g */
1082 ((srcval << 7) & 0x7c00); /* l */
1084 srcbits = (const char*)srcbits + srclinebytes;
1085 dstbits = (char*)dstbits + dstlinebytes;
1089 static void convert_0888_to_565_asis(int width, int height,
1090 const void* srcbits, int srclinebytes,
1091 void* dstbits, int dstlinebytes)
1093 const DWORD* srcpixel;
1097 for (y=0; y<height; y++) {
1100 for (x=0; x<width; x++) {
1103 *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1104 ((srcval >> 5) & 0x07e0) | /* g */
1105 ((srcval >> 3) & 0x001f); /* l */
1107 srcbits = (const char*)srcbits + srclinebytes;
1108 dstbits = (char*)dstbits + dstlinebytes;
1112 static void convert_0888_to_565_reverse(int width, int height,
1113 const void* srcbits, int srclinebytes,
1114 void* dstbits, int dstlinebytes)
1116 const DWORD* srcpixel;
1120 for (y=0; y<height; y++) {
1123 for (x=0; x<width; x++) {
1126 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1127 ((srcval >> 5) & 0x07e0) | /* g */
1128 ((srcval << 8) & 0xf800); /* l */
1130 srcbits = (const char*)srcbits + srclinebytes;
1131 dstbits = (char*)dstbits + dstlinebytes;
1135 static void convert_any0888_to_5x5(int width, int height,
1136 const void* srcbits, int srclinebytes,
1137 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1138 void* dstbits, int dstlinebytes,
1139 WORD rdst, WORD gdst, WORD bdst)
1141 int rRightShift,gRightShift,bRightShift;
1142 int rLeftShift,gLeftShift,bLeftShift;
1143 const DWORD* srcpixel;
1147 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1148 * contains 0x11223344.
1149 * - first we shift 0x11223344 right by rRightShift to bring the most
1150 * significant bits of the red components in the bottom 5 (or 6) bits
1152 * - then we remove non red bits by anding with the modified rdst (0x1f)
1154 * - finally shift these bits left by rLeftShift so that they end up in
1158 rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1159 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1160 gRightShift+=(gdst==0x07e0?2:3);
1161 bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1163 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1164 rdst=rdst >> rLeftShift;
1165 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1166 gdst=gdst >> gLeftShift;
1167 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1168 bdst=bdst >> bLeftShift;
1170 for (y=0; y<height; y++) {
1173 for (x=0; x<width; x++) {
1176 *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1177 (((srcval >> gRightShift) & gdst) << gLeftShift) |
1178 (((srcval >> bRightShift) & bdst) << bLeftShift);
1180 srcbits = (const char*)srcbits + srclinebytes;
1181 dstbits = (char*)dstbits + dstlinebytes;
1185 static void convert_0888_to_888_asis(int width, int height,
1186 const void* srcbits, int srclinebytes,
1187 void* dstbits, int dstlinebytes)
1189 const DWORD* srcpixel;
1197 for (y=0; y<height; y++) {
1200 for (x=0; x<width; x++) {
1201 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1203 srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/
1204 *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */
1205 srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1206 *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */
1207 srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */
1208 *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */
1210 /* And now up to 3 odd pixels */
1211 dstbyte=(BYTE*)dstpixel;
1212 for (x=0; x<oddwidth; x++) {
1215 *((WORD*)dstbyte) = srcval; /* h, g */
1216 dstbyte+=sizeof(WORD);
1217 *dstbyte++=srcval >> 16; /* l */
1219 srcbits = (const char*)srcbits + srclinebytes;
1220 dstbits = (char*)dstbits + dstlinebytes;
1224 static void convert_0888_to_888_reverse(int width, int height,
1225 const void* srcbits, int srclinebytes,
1226 void* dstbits, int dstlinebytes)
1228 const DWORD* srcpixel;
1236 for (y=0; y<height; y++) {
1239 for (x=0; x<width; x++) {
1240 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1241 DWORD srcval1,srcval2;
1242 srcval1=*srcpixel++;
1243 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1244 ( srcval1 & 0x0000ff00) | /* g1 */
1245 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1246 srcval1=*srcpixel++;
1247 *dstpixel++=srcval2 |
1248 ((srcval1 << 8) & 0xff000000); /* h2 */
1249 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1250 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1251 srcval1=*srcpixel++;
1252 *dstpixel++=srcval2 |
1253 ( srcval1 & 0x00ff0000) | /* h3 */
1254 ((srcval1 << 16) & 0xff000000); /* g3 */
1255 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1256 srcval1=*srcpixel++;
1257 *dstpixel++=srcval2 |
1258 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1259 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1260 ( srcval1 << 24); /* l4 */
1262 /* And now up to 3 odd pixels */
1263 dstbyte=(BYTE*)dstpixel;
1264 for (x=0; x<oddwidth; x++) {
1267 *((WORD*)dstbyte)=((srcval >> 16) & 0x00ff) | /* h */
1268 (srcval & 0xff00); /* g */
1269 dstbyte += sizeof(WORD);
1270 *dstbyte++=srcval; /* l */
1272 srcbits = (const char*)srcbits + srclinebytes;
1273 dstbits = (char*)dstbits + dstlinebytes;
1277 static void convert_any0888_to_rgb888(int width, int height,
1278 const void* srcbits, int srclinebytes,
1279 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1280 void* dstbits, int dstlinebytes)
1282 int rRightShift,gRightShift,bRightShift;
1283 const DWORD* srcpixel;
1287 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1288 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1289 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1290 for (y=0; y<height; y++) {
1293 for (x=0; x<width; x++) {
1296 dstpixel[0]=(srcval >> bRightShift); /* b */
1297 dstpixel[1]=(srcval >> gRightShift); /* g */
1298 dstpixel[2]=(srcval >> rRightShift); /* r */
1301 srcbits = (const char*)srcbits + srclinebytes;
1302 dstbits = (char*)dstbits + dstlinebytes;
1306 static void convert_any0888_to_bgr888(int width, int height,
1307 const void* srcbits, int srclinebytes,
1308 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1309 void* dstbits, int dstlinebytes)
1311 int rRightShift,gRightShift,bRightShift;
1312 const DWORD* srcpixel;
1316 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1317 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1318 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1319 for (y=0; y<height; y++) {
1322 for (x=0; x<width; x++) {
1325 dstpixel[0]=(srcval >> rRightShift); /* r */
1326 dstpixel[1]=(srcval >> gRightShift); /* g */
1327 dstpixel[2]=(srcval >> bRightShift); /* b */
1330 srcbits = (const char*)srcbits + srclinebytes;
1331 dstbits = (char*)dstbits + dstlinebytes;
1335 const dib_conversions dib_normal = {
1337 convert_555_reverse,
1338 convert_555_to_565_asis,
1339 convert_555_to_565_reverse,
1340 convert_555_to_888_asis,
1341 convert_555_to_888_reverse,
1342 convert_555_to_0888_asis,
1343 convert_555_to_0888_reverse,
1344 convert_5x5_to_any0888,
1345 convert_565_reverse,
1346 convert_565_to_555_asis,
1347 convert_565_to_555_reverse,
1348 convert_565_to_888_asis,
1349 convert_565_to_888_reverse,
1350 convert_565_to_0888_asis,
1351 convert_565_to_0888_reverse,
1353 convert_888_reverse,
1354 convert_888_to_555_asis,
1355 convert_888_to_555_reverse,
1356 convert_888_to_565_asis,
1357 convert_888_to_565_reverse,
1358 convert_888_to_0888_asis,
1359 convert_888_to_0888_reverse,
1360 convert_rgb888_to_any0888,
1361 convert_bgr888_to_any0888,
1363 convert_0888_reverse,
1365 convert_0888_to_555_asis,
1366 convert_0888_to_555_reverse,
1367 convert_0888_to_565_asis,
1368 convert_0888_to_565_reverse,
1369 convert_any0888_to_5x5,
1370 convert_0888_to_888_asis,
1371 convert_0888_to_888_reverse,
1372 convert_any0888_to_rgb888,
1373 convert_any0888_to_bgr888