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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 at coordinates (x,y) then this is:
44 * image_ptr+x*bytes_per_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;
826 w1 = min( (INT_PTR)srcbits & 3, width);
827 w2 = ( width - w1) / 4;
828 w3 = ( width - w1) & 3;
829 for (y=0; y<height; y++) {
832 /* advance w1 pixels to make srcpixel 32 bit aligned */
833 srcpixel = (const DWORD*)((INT_PTR)srcpixel & ~3);
836 /* and do the w1 pixels */
839 dstpixel[ -1] = ( srcpixel[ -1] >> 8); /* h4, g4, l4 */
841 dstpixel[ -2] = ( srcpixel[ -2] >> 16) | /* g3, l3 */
842 ((srcpixel[ -1] << 16) & 0x00ff0000); /* h3 */
844 dstpixel[ -3] = ( srcpixel[ -3] >> 24) | /* l2 */
845 ((srcpixel[ -2] << 8) & 0x00ffff00); /* h2, g2 */
849 for (x=0; x < w2; x++) {
850 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
851 DWORD srcval1,srcval2;
853 dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
855 dstpixel[1]=( srcval1 >> 24) | /* l2 */
856 ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
858 dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */
859 ((srcval1 << 16) & 0x00ff0000); /* h3 */
860 dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */
864 /* do last w3 pixels */
867 dstpixel[0]=( srcpixel[0] & 0x00ffffff); /* h1, g1, l1 */
869 dstpixel[1]=( srcpixel[0]>> 24) | /* l2 */
870 ((srcpixel[1]<< 8) & 0x00ffff00); /* h2, g2 */
872 dstpixel[2]=( srcpixel[1]>> 16) | /* g3, l3 */
873 ((srcpixel[2]<< 16) & 0x00ff0000); /* h3 */
877 srcbits = (const char*)srcbits + srclinebytes;
878 dstbits = (char*)dstbits + dstlinebytes;
882 static void convert_888_to_0888_reverse(int width, int height,
883 const void* srcbits, int srclinebytes,
884 void* dstbits, int dstlinebytes)
886 const DWORD* srcpixel;
891 w1 = min( (INT_PTR)srcbits & 3, width);
892 w2 = ( width - w1) / 4;
893 w3 = ( width - w1) & 3;
894 for (y=0; y<height; y++) {
897 /* advance w1 pixels to make srcpixel 32 bit aligned */
898 srcpixel = (const DWORD*)((INT_PTR)srcpixel & ~3);
901 /* and do the w1 pixels */
904 dstpixel[ -1]=((srcpixel[ -1] >> 24) & 0x0000ff) | /* h4 */
905 ((srcpixel[ -1] >> 8) & 0x00ff00) | /* g4 */
906 ((srcpixel[ -1] << 8) & 0xff0000); /* l4 */
908 dstpixel[ -2]=( srcpixel[ -2] & 0xff0000) | /* l3 */
909 ((srcpixel[ -2] >> 16) & 0x00ff00) | /* g3 */
910 ( srcpixel[ -1] & 0x0000ff); /* h3 */
912 dstpixel[ -3]=((srcpixel[ -3] >> 8) & 0xff0000) | /* l2 */
913 ((srcpixel[ -2] << 8) & 0x00ff00) | /* g2 */
914 ((srcpixel[ -2] >> 8) & 0x0000ff); /* h2 */
918 for (x=0; x < w2; x++) {
919 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
920 DWORD srcval1,srcval2;
923 dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
924 ( srcval1 & 0x00ff00) | /* g1 */
925 ((srcval1 << 16) & 0xff0000); /* l1 */
927 dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */
928 ((srcval2 << 8) & 0x00ff00) | /* g2 */
929 ((srcval2 >> 8) & 0x0000ff); /* h2 */
931 dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */
932 ((srcval2 >> 16) & 0x00ff00) | /* g3 */
933 ( srcval1 & 0x0000ff); /* h3 */
934 dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
935 ((srcval1 >> 8) & 0x00ff00) | /* g4 */
936 ((srcval1 << 8) & 0xff0000); /* l4 */
940 /* do last w3 pixels */
943 dstpixel[0]=((srcpixel[0] >> 16) & 0x0000ff) | /* h1 */
944 ( srcpixel[0] & 0x00ff00) | /* g1 */
945 ((srcpixel[0] << 16) & 0xff0000); /* l1 */
947 dstpixel[1]=((srcpixel[0] >> 8) & 0xff0000) | /* l2 */
948 ((srcpixel[1] << 8) & 0x00ff00) | /* g2 */
949 ((srcpixel[1] >> 8) & 0x0000ff); /* h2 */
951 dstpixel[2]=( srcpixel[1] & 0xff0000) | /* l3 */
952 ((srcpixel[1] >> 16) & 0x00ff00) | /* g3 */
953 ( srcpixel[2] & 0x0000ff); /* h3 */
957 srcbits = (const char*)srcbits + srclinebytes;
958 dstbits = (char*)dstbits + dstlinebytes;
962 static void convert_rgb888_to_any0888(int width, int height,
963 const void* srcbits, int srclinebytes,
964 void* dstbits, int dstlinebytes,
965 DWORD rdst, DWORD gdst, DWORD bdst)
967 int rLeftShift,gLeftShift,bLeftShift;
968 const BYTE* srcpixel;
972 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
973 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
974 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
975 for (y=0; y<height; y++) {
978 for (x=0; x<width; x++) {
979 *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
980 (srcpixel[1] << gLeftShift) | /* g */
981 (srcpixel[2] << rLeftShift); /* r */
984 srcbits = (const char*)srcbits + srclinebytes;
985 dstbits = (char*)dstbits + dstlinebytes;
989 static void convert_bgr888_to_any0888(int width, int height,
990 const void* srcbits, int srclinebytes,
991 void* dstbits, int dstlinebytes,
992 DWORD rdst, DWORD gdst, DWORD bdst)
994 int rLeftShift,gLeftShift,bLeftShift;
995 const BYTE* srcpixel;
999 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1000 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1001 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1002 for (y=0; y<height; y++) {
1005 for (x=0; x<width; x++) {
1006 *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
1007 (srcpixel[1] << gLeftShift) | /* g */
1008 (srcpixel[2] << bLeftShift); /* b */
1011 srcbits = (const char*)srcbits + srclinebytes;
1012 dstbits = (char*)dstbits + dstlinebytes;
1017 * 32 bit conversions
1020 static void convert_0888_asis(int width, int height,
1021 const void* srcbits, int srclinebytes,
1022 void* dstbits, int dstlinebytes)
1028 if (srclinebytes == dstlinebytes && srclinebytes == width)
1030 memcpy(dstbits, srcbits, height * width);
1034 for (y=0; y<height; y++) {
1035 memcpy(dstbits, srcbits, width);
1036 srcbits = (const char*)srcbits + srclinebytes;
1037 dstbits = (char*)dstbits + dstlinebytes;
1041 static void convert_0888_reverse(int width, int height,
1042 const void* srcbits, int srclinebytes,
1043 void* dstbits, int dstlinebytes)
1045 const DWORD* srcpixel;
1049 for (y=0; y<height; y++) {
1052 for (x=0; x<width; x++) {
1055 *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1056 ( srcval & 0x0000ff00) | /* g */
1057 ((srcval >> 16) & 0x000000ff); /* l */
1059 srcbits = (const char*)srcbits + srclinebytes;
1060 dstbits = (char*)dstbits + dstlinebytes;
1064 static void convert_0888_any(int width, int height,
1065 const void* srcbits, int srclinebytes,
1066 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1067 void* dstbits, int dstlinebytes,
1068 DWORD rdst, DWORD gdst, DWORD bdst)
1070 int rRightShift,gRightShift,bRightShift;
1071 int rLeftShift,gLeftShift,bLeftShift;
1072 const DWORD* srcpixel;
1076 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1077 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1078 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1079 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1080 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1081 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1082 for (y=0; y<height; y++) {
1085 for (x=0; x<width; x++) {
1088 *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1089 (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1090 (((srcval >> bRightShift) & 0xff) << bLeftShift);
1092 srcbits = (const char*)srcbits + srclinebytes;
1093 dstbits = (char*)dstbits + dstlinebytes;
1097 static void convert_0888_to_555_asis(int width, int height,
1098 const void* srcbits, int srclinebytes,
1099 void* dstbits, int dstlinebytes)
1101 const DWORD* srcpixel;
1105 for (y=0; y<height; y++) {
1108 for (x=0; x<width; x++) {
1111 *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1112 ((srcval >> 6) & 0x03e0) | /* g */
1113 ((srcval >> 3) & 0x001f); /* l */
1115 srcbits = (const char*)srcbits + srclinebytes;
1116 dstbits = (char*)dstbits + dstlinebytes;
1120 static void convert_0888_to_555_reverse(int width, int height,
1121 const void* srcbits, int srclinebytes,
1122 void* dstbits, int dstlinebytes)
1124 const DWORD* srcpixel;
1128 for (y=0; y<height; y++) {
1131 for (x=0; x<width; x++) {
1134 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1135 ((srcval >> 6) & 0x03e0) | /* g */
1136 ((srcval << 7) & 0x7c00); /* l */
1138 srcbits = (const char*)srcbits + srclinebytes;
1139 dstbits = (char*)dstbits + dstlinebytes;
1143 static void convert_0888_to_565_asis(int width, int height,
1144 const void* srcbits, int srclinebytes,
1145 void* dstbits, int dstlinebytes)
1147 const DWORD* srcpixel;
1151 for (y=0; y<height; y++) {
1154 for (x=0; x<width; x++) {
1157 *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1158 ((srcval >> 5) & 0x07e0) | /* g */
1159 ((srcval >> 3) & 0x001f); /* l */
1161 srcbits = (const char*)srcbits + srclinebytes;
1162 dstbits = (char*)dstbits + dstlinebytes;
1166 static void convert_0888_to_565_reverse(int width, int height,
1167 const void* srcbits, int srclinebytes,
1168 void* dstbits, int dstlinebytes)
1170 const DWORD* srcpixel;
1174 for (y=0; y<height; y++) {
1177 for (x=0; x<width; x++) {
1180 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1181 ((srcval >> 5) & 0x07e0) | /* g */
1182 ((srcval << 8) & 0xf800); /* l */
1184 srcbits = (const char*)srcbits + srclinebytes;
1185 dstbits = (char*)dstbits + dstlinebytes;
1189 static void convert_any0888_to_5x5(int width, int height,
1190 const void* srcbits, int srclinebytes,
1191 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1192 void* dstbits, int dstlinebytes,
1193 WORD rdst, WORD gdst, WORD bdst)
1195 int rRightShift,gRightShift,bRightShift;
1196 int rLeftShift,gLeftShift,bLeftShift;
1197 const DWORD* srcpixel;
1201 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1202 * contains 0x11223344.
1203 * - first we shift 0x11223344 right by rRightShift to bring the most
1204 * significant bits of the red components in the bottom 5 (or 6) bits
1206 * - then we remove non red bits by anding with the modified rdst (0x1f)
1208 * - finally shift these bits left by rLeftShift so that they end up in
1212 rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1213 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1214 gRightShift+=(gdst==0x07e0?2:3);
1215 bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1217 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1218 rdst=rdst >> rLeftShift;
1219 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1220 gdst=gdst >> gLeftShift;
1221 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1222 bdst=bdst >> bLeftShift;
1224 for (y=0; y<height; y++) {
1227 for (x=0; x<width; x++) {
1230 *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1231 (((srcval >> gRightShift) & gdst) << gLeftShift) |
1232 (((srcval >> bRightShift) & bdst) << bLeftShift);
1234 srcbits = (const char*)srcbits + srclinebytes;
1235 dstbits = (char*)dstbits + dstlinebytes;
1239 static void convert_0888_to_888_asis(int width, int height,
1240 const void* srcbits, int srclinebytes,
1241 void* dstbits, int dstlinebytes)
1243 const DWORD* srcpixel;
1251 for (y=0; y<height; y++) {
1254 for (x=0; x<width; x++) {
1255 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1257 srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/
1258 *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */
1259 srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1260 *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */
1261 srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */
1262 *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */
1264 /* And now up to 3 odd pixels */
1265 dstbyte=(BYTE*)dstpixel;
1266 for (x=0; x<oddwidth; x++) {
1269 *((WORD*)dstbyte) = srcval; /* h, g */
1270 dstbyte+=sizeof(WORD);
1271 *dstbyte++=srcval >> 16; /* l */
1273 srcbits = (const char*)srcbits + srclinebytes;
1274 dstbits = (char*)dstbits + dstlinebytes;
1278 static void convert_0888_to_888_reverse(int width, int height,
1279 const void* srcbits, int srclinebytes,
1280 void* dstbits, int dstlinebytes)
1282 const DWORD* srcpixel;
1290 for (y=0; y<height; y++) {
1293 for (x=0; x<width; x++) {
1294 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1295 DWORD srcval1,srcval2;
1296 srcval1=*srcpixel++;
1297 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1298 ( srcval1 & 0x0000ff00) | /* g1 */
1299 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1300 srcval1=*srcpixel++;
1301 *dstpixel++=srcval2 |
1302 ((srcval1 << 8) & 0xff000000); /* h2 */
1303 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1304 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1305 srcval1=*srcpixel++;
1306 *dstpixel++=srcval2 |
1307 ( srcval1 & 0x00ff0000) | /* h3 */
1308 ((srcval1 << 16) & 0xff000000); /* g3 */
1309 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1310 srcval1=*srcpixel++;
1311 *dstpixel++=srcval2 |
1312 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1313 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1314 ( srcval1 << 24); /* l4 */
1316 /* And now up to 3 odd pixels */
1317 dstbyte=(BYTE*)dstpixel;
1318 for (x=0; x<oddwidth; x++) {
1321 *((WORD*)dstbyte)=((srcval >> 16) & 0x00ff) | /* h */
1322 (srcval & 0xff00); /* g */
1323 dstbyte += sizeof(WORD);
1324 *dstbyte++=srcval; /* l */
1326 srcbits = (const char*)srcbits + srclinebytes;
1327 dstbits = (char*)dstbits + dstlinebytes;
1331 static void convert_any0888_to_rgb888(int width, int height,
1332 const void* srcbits, int srclinebytes,
1333 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1334 void* dstbits, int dstlinebytes)
1336 int rRightShift,gRightShift,bRightShift;
1337 const DWORD* srcpixel;
1341 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1342 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1343 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1344 for (y=0; y<height; y++) {
1347 for (x=0; x<width; x++) {
1350 dstpixel[0]=(srcval >> bRightShift); /* b */
1351 dstpixel[1]=(srcval >> gRightShift); /* g */
1352 dstpixel[2]=(srcval >> rRightShift); /* r */
1355 srcbits = (const char*)srcbits + srclinebytes;
1356 dstbits = (char*)dstbits + dstlinebytes;
1360 static void convert_any0888_to_bgr888(int width, int height,
1361 const void* srcbits, int srclinebytes,
1362 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1363 void* dstbits, int dstlinebytes)
1365 int rRightShift,gRightShift,bRightShift;
1366 const DWORD* srcpixel;
1370 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1371 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1372 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1373 for (y=0; y<height; y++) {
1376 for (x=0; x<width; x++) {
1379 dstpixel[0]=(srcval >> rRightShift); /* r */
1380 dstpixel[1]=(srcval >> gRightShift); /* g */
1381 dstpixel[2]=(srcval >> bRightShift); /* b */
1384 srcbits = (const char*)srcbits + srclinebytes;
1385 dstbits = (char*)dstbits + dstlinebytes;
1389 const dib_conversions dib_normal = {
1391 convert_555_reverse,
1392 convert_555_to_565_asis,
1393 convert_555_to_565_reverse,
1394 convert_555_to_888_asis,
1395 convert_555_to_888_reverse,
1396 convert_555_to_0888_asis,
1397 convert_555_to_0888_reverse,
1398 convert_5x5_to_any0888,
1399 convert_565_reverse,
1400 convert_565_to_555_asis,
1401 convert_565_to_555_reverse,
1402 convert_565_to_888_asis,
1403 convert_565_to_888_reverse,
1404 convert_565_to_0888_asis,
1405 convert_565_to_0888_reverse,
1407 convert_888_reverse,
1408 convert_888_to_555_asis,
1409 convert_888_to_555_reverse,
1410 convert_888_to_565_asis,
1411 convert_888_to_565_reverse,
1412 convert_888_to_0888_asis,
1413 convert_888_to_0888_reverse,
1414 convert_rgb888_to_any0888,
1415 convert_bgr888_to_any0888,
1417 convert_0888_reverse,
1419 convert_0888_to_555_asis,
1420 convert_0888_to_555_reverse,
1421 convert_0888_to_565_asis,
1422 convert_0888_to_565_reverse,
1423 convert_any0888_to_5x5,
1424 convert_0888_to_888_asis,
1425 convert_0888_to_888_reverse,
1426 convert_any0888_to_rgb888,
1427 convert_any0888_to_bgr888