ntdll: Implement DVD_ReadStructure.
[wine] / dlls / x11drv / dib_convert.c
1 /*
2  * DIB conversion routinues for cases where the source and destination
3  * have the same byte order.
4  *
5  * Copyright (C) 2001 Francois Gouget
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25
26 #include "windef.h"
27 #include "x11drv.h"
28
29
30 /***********************************************************************
31  *           X11DRV_DIB_Convert_*
32  *
33  * All X11DRV_DIB_Convert_Xxx functions take at least the following
34  * parameters:
35  * - width
36  *   This is the width in pixel of the surface to copy. This may be less
37  *   than the full width of the image.
38  * - height
39  *   The number of lines to copy. This may be less than the full height
40  *   of the image. This is always >0.
41  * - srcbits
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)
46  * - srclinebytes
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.
49  * - dstbits
50  *   Same as srcbits but for the destination
51  * - dstlinebytes
52  *   Same as srclinebytes but for the destination.
53  *
54  * Notes:
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.
65  */
66
67
68 /*
69  * 15 bit conversions
70  */
71
72 static void convert_5x5_asis(int width, int height,
73                              const void* srcbits, int srclinebytes,
74                              void* dstbits, int dstlinebytes)
75 {
76     int y;
77
78     width *= 2;
79
80     if (srclinebytes == dstlinebytes && srclinebytes == width)
81     {
82         memcpy(dstbits, srcbits, height * width);
83         return;
84     }
85
86     for (y=0; y<height; y++) {
87         memcpy(dstbits, srcbits, width);
88         srcbits = (const char*)srcbits + srclinebytes;
89         dstbits = (char*)dstbits + dstlinebytes;
90     }
91 }
92
93
94 static void convert_555_reverse(int width, int height,
95                                 const void* srcbits, int srclinebytes,
96                                 void* dstbits, int dstlinebytes)
97 {
98     const DWORD* srcpixel;
99     DWORD* dstpixel;
100     int x,y;
101
102     for (y=0; y<height; y++) {
103         srcpixel=srcbits;
104         dstpixel=dstbits;
105         for (x=0; x<width/2; x++) {
106             /* Do 2 pixels at a time */
107             DWORD srcval;
108             srcval=*srcpixel++;
109             *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */
110                         ( srcval        & 0x03e003e0) | /* g */
111                         ((srcval >> 10) & 0x001f001f);  /* l */
112         }
113         if (width&1) {
114             /* And the the odd pixel */
115             WORD srcval;
116             srcval=*((const WORD*)srcpixel);
117             *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
118                                ( srcval        & 0x03e0) | /* g */
119                                ((srcval >> 10) & 0x001f);  /* l */
120         }
121         srcbits = (const char*)srcbits + srclinebytes;
122         dstbits = (char*)dstbits + dstlinebytes;
123     }
124 }
125
126 static void convert_555_to_565_asis(int width, int height,
127                                     const void* srcbits, int srclinebytes,
128                                     void* dstbits, int dstlinebytes)
129 {
130     const DWORD* srcpixel;
131     DWORD* dstpixel;
132     int x,y;
133
134     for (y=0; y<height; y++) {
135         srcpixel=srcbits;
136         dstpixel=dstbits;
137         for (x=0; x<width/2; x++) {
138             /* Do 2 pixels at a time */
139             DWORD srcval;
140             srcval=*srcpixel++;
141             *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */
142                         ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
143                         ( srcval       & 0x001f001f);  /* l */
144         }
145         if (width&1) {
146             /* And the the odd pixel */
147             WORD srcval;
148             srcval=*((const WORD*)srcpixel);
149             *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
150                                ((srcval >> 4) & 0x0020) | /* g - 1 bit */
151                                 (srcval       & 0x001f);  /* l */
152         }
153         srcbits = (const char*)srcbits + srclinebytes;
154         dstbits = (char*)dstbits + dstlinebytes;
155     }
156 }
157
158 static void convert_555_to_565_reverse(int width, int height,
159                                        const void* srcbits, int srclinebytes,
160                                        void* dstbits, int dstlinebytes)
161 {
162     const DWORD* srcpixel;
163     DWORD* dstpixel;
164     int x,y;
165
166     for (y=0; y<height; y++) {
167         srcpixel=srcbits;
168         dstpixel=dstbits;
169         for (x=0; x<width/2; x++) {
170             /* Do 2 pixels at a time */
171             DWORD srcval;
172             srcval=*srcpixel++;
173             *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */
174                         ((srcval <<  1) & 0x07c007c0) | /* g */
175                         ((srcval >>  4) & 0x00200020) | /* g - 1 bit */
176                         ((srcval << 11) & 0xf800f800);  /* l */
177         }
178         if (width&1) {
179             /* And the the odd pixel */
180             WORD srcval;
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 */
186         }
187         srcbits = (const char*)srcbits + srclinebytes;
188         dstbits = (char*)dstbits + dstlinebytes;
189     }
190 }
191
192 static void convert_555_to_888_asis(int width, int height,
193                                     const void* srcbits, int srclinebytes,
194                                     void* dstbits, int dstlinebytes)
195 {
196     const WORD* srcpixel;
197     BYTE* dstpixel;
198     int x,y;
199
200     for (y=0; y<height; y++) {
201         srcpixel=srcbits;
202         dstpixel=dstbits;
203         for (x=0; x<width; x++) {
204             WORD srcval;
205             srcval=*srcpixel++;
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 */
212             dstpixel+=3;
213         }
214         srcbits = (const char*)srcbits + srclinebytes;
215         dstbits = (char*)dstbits + dstlinebytes;
216     }
217 }
218
219 static void convert_555_to_888_reverse(int width, int height,
220                                        const void* srcbits, int srclinebytes,
221                                        void* dstbits, int dstlinebytes)
222 {
223     const WORD* srcpixel;
224     BYTE* dstpixel;
225     int x,y;
226
227     for (y=0; y<height; y++) {
228         srcpixel=srcbits;
229         dstpixel=dstbits;
230         for (x=0; x<width; x++) {
231             WORD srcval;
232             srcval=*srcpixel++;
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 */
239             dstpixel+=3;
240         }
241         srcbits = (const char*)srcbits + srclinebytes;
242         dstbits = (char*)dstbits + dstlinebytes;
243     }
244 }
245
246 static void convert_555_to_0888_asis(int width, int height,
247                                      const void* srcbits, int srclinebytes,
248                                      void* dstbits, int dstlinebytes)
249 {
250     const WORD* srcpixel;
251     DWORD* dstpixel;
252     int x,y;
253
254     for (y=0; y<height; y++) {
255         srcpixel=srcbits;
256         dstpixel=dstbits;
257         for (x=0; x<width; x++) {
258             WORD srcval;
259             srcval=*srcpixel++;
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 */
266         }
267         srcbits = (const char*)srcbits + srclinebytes;
268         dstbits = (char*)dstbits + dstlinebytes;
269     }
270 }
271
272 static void convert_555_to_0888_reverse(int width, int height,
273                                         const void* srcbits, int srclinebytes,
274                                         void* dstbits, int dstlinebytes)
275 {
276     const WORD* srcpixel;
277     DWORD* dstpixel;
278     int x,y;
279
280     for (y=0; y<height; y++) {
281         srcpixel=srcbits;
282         dstpixel=dstbits;
283         for (x=0; x<width; x++) {
284             WORD srcval;
285             srcval=*srcpixel++;
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 */
292         }
293         srcbits = (const char*)srcbits + srclinebytes;
294         dstbits = (char*)dstbits + dstlinebytes;
295     }
296 }
297
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)
303 {
304     int rRightShift1,gRightShift1,bRightShift1;
305     int rRightShift2,gRightShift2,bRightShift2;
306     BYTE gMask1,gMask2;
307     int rLeftShift,gLeftShift,bLeftShift;
308     const WORD* srcpixel;
309     DWORD* dstpixel;
310     int x,y;
311
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.
314      */
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;
321     if (gsrc==0x03e0) {
322         /* Green has 5 bits, like the others */
323         gMask1=0xf8;
324         gMask2=0x07;
325     } else {
326         /* Green has 6 bits, not 5. Compensate. */
327         gRightShift1++;
328         gRightShift2+=2;
329         gMask1=0xfc;
330         gMask2=0x03;
331     }
332
333     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
334     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
335     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
336
337     for (y=0; y<height; y++) {
338         srcpixel=srcbits;
339         dstpixel=dstbits;
340         for (x=0; x<width; x++) {
341             DWORD srcval;
342             BYTE red,green,blue;
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);
353         }
354         srcbits = (const char*)srcbits + srclinebytes;
355         dstbits = (char*)dstbits + dstlinebytes;
356     }
357 }
358
359 /*
360  * 16 bits conversions
361  */
362
363 static void convert_565_reverse(int width, int height,
364                                 const void* srcbits, int srclinebytes,
365                                 void* dstbits, int dstlinebytes)
366 {
367     const DWORD* srcpixel;
368     DWORD* dstpixel;
369     int x,y;
370
371     for (y=0; y<height; y++) {
372         srcpixel=srcbits;
373         dstpixel=dstbits;
374         for (x=0; x<width/2; x++) {
375             /* Do 2 pixels at a time */
376             DWORD srcval;
377             srcval=*srcpixel++;
378             *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */
379                         ( srcval        & 0x07e007e0) | /* g */
380                         ((srcval >> 11) & 0x001f001f);  /* l */
381         }
382         if (width&1) {
383             /* And the the odd pixel */
384             WORD srcval;
385             srcval=*((const WORD*)srcpixel);
386             *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
387                                ( srcval        & 0x07e0) | /* g */
388                                ((srcval >> 11) & 0x001f);  /* l */
389         }
390         srcbits = (const char*)srcbits + srclinebytes;
391         dstbits = (char*)dstbits + dstlinebytes;
392     }
393 }
394
395 static void convert_565_to_555_asis(int width, int height,
396                                     const void* srcbits, int srclinebytes,
397                                     void* dstbits, int dstlinebytes)
398 {
399     const DWORD* srcpixel;
400     DWORD* dstpixel;
401     int x,y;
402
403     for (y=0; y<height; y++) {
404         srcpixel=srcbits;
405         dstpixel=dstbits;
406         for (x=0; x<width/2; x++) {
407             /* Do 2 pixels at a time */
408             DWORD srcval;
409             srcval=*srcpixel++;
410             *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */
411                         ( srcval       & 0x001f001f);  /* l */
412         }
413         if (width&1) {
414             /* And the the odd pixel */
415             WORD srcval;
416             srcval=*((const WORD*)srcpixel);
417             *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
418                                ( srcval       & 0x001f);  /* l */
419         }
420         srcbits = (const char*)srcbits + srclinebytes;
421         dstbits = (char*)dstbits + dstlinebytes;
422     }
423 }
424
425 static void convert_565_to_555_reverse(int width, int height,
426                                        const void* srcbits, int srclinebytes,
427                                        void* dstbits, int dstlinebytes)
428 {
429     const DWORD* srcpixel;
430     DWORD* dstpixel;
431     int x,y;
432
433     for (y=0; y<height; y++) {
434         srcpixel=srcbits;
435         dstpixel=dstbits;
436         for (x=0; x<width/2; x++) {
437             /* Do 2 pixels at a time */
438             DWORD srcval;
439             srcval=*srcpixel++;
440             *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */
441                         ((srcval >>  1) & 0x03e003e0) | /* g */
442                         ((srcval << 10) & 0x7c007c00);  /* l */
443         }
444         if (width&1) {
445             /* And the the odd pixel */
446             WORD srcval;
447             srcval=*((const WORD*)srcpixel);
448             *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
449                                ((srcval >>  1) & 0x03e0) | /* g */
450                                ((srcval << 10) & 0x7c00);  /* l */
451         }
452         srcbits = (const char*)srcbits + srclinebytes;
453         dstbits = (char*)dstbits + dstlinebytes;
454     }
455 }
456
457 static void convert_565_to_888_asis(int width, int height,
458                                     const void* srcbits, int srclinebytes,
459                                     void* dstbits, int dstlinebytes)
460 {
461     const WORD* srcpixel;
462     BYTE* dstpixel;
463     int x,y;
464
465     for (y=0; y<height; y++) {
466         srcpixel=srcbits;
467         dstpixel=dstbits;
468         for (x=0; x<width; x++) {
469             WORD srcval;
470             srcval=*srcpixel++;
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 */
477             dstpixel+=3;
478         }
479         srcbits = (const char*)srcbits + srclinebytes;
480         dstbits = (char*)dstbits + dstlinebytes;
481     }
482 }
483
484 static void convert_565_to_888_reverse(int width, int height,
485                                        const void* srcbits, int srclinebytes,
486                                        void* dstbits, int dstlinebytes)
487 {
488     const WORD* srcpixel;
489     BYTE* dstpixel;
490     int x,y;
491
492     for (y=0; y<height; y++) {
493         srcpixel=srcbits;
494         dstpixel=dstbits;
495         for (x=0; x<width; x++) {
496             WORD srcval;
497             srcval=*srcpixel++;
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 */
504             dstpixel+=3;
505         }
506         srcbits = (const char*)srcbits + srclinebytes;
507         dstbits = (char*)dstbits + dstlinebytes;
508     }
509 }
510
511 static void convert_565_to_0888_asis(int width, int height,
512                                      const void* srcbits, int srclinebytes,
513                                      void* dstbits, int dstlinebytes)
514 {
515     const WORD* srcpixel;
516     DWORD* dstpixel;
517     int x,y;
518
519     for (y=0; y<height; y++) {
520         srcpixel=srcbits;
521         dstpixel=dstbits;
522         for (x=0; x<width; x++) {
523             WORD srcval;
524             srcval=*srcpixel++;
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 */
531         }
532         srcbits = (const char*)srcbits + srclinebytes;
533         dstbits = (char*)dstbits + dstlinebytes;
534     }
535 }
536
537 static void convert_565_to_0888_reverse(int width, int height,
538                                         const void* srcbits, int srclinebytes,
539                                         void* dstbits, int dstlinebytes)
540 {
541     const WORD* srcpixel;
542     DWORD* dstpixel;
543     int x,y;
544
545     for (y=0; y<height; y++) {
546         srcpixel=srcbits;
547         dstpixel=dstbits;
548         for (x=0; x<width; x++) {
549             WORD srcval;
550             srcval=*srcpixel++;
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 */
557         }
558         srcbits = (const char*)srcbits + srclinebytes;
559         dstbits = (char*)dstbits + dstlinebytes;
560     }
561 }
562
563
564 /*
565  * 24 bit conversions
566  */
567
568 static void convert_888_asis(int width, int height,
569                              const void* srcbits, int srclinebytes,
570                              void* dstbits, int dstlinebytes)
571 {
572     int y;
573
574     width *= 3;
575
576     if (srclinebytes == dstlinebytes && srclinebytes == width)
577     {
578         memcpy(dstbits, srcbits, height * width);
579         return;
580     }
581
582     for (y=0; y<height; y++) {
583         memcpy(dstbits, srcbits, width);
584         srcbits = (const char*)srcbits + srclinebytes;
585         dstbits = (char*)dstbits + dstlinebytes;
586     }
587 }
588
589
590 static void convert_888_reverse(int width, int height,
591                                 const void* srcbits, int srclinebytes,
592                                 void* dstbits, int dstlinebytes)
593 {
594     const BYTE* srcpixel;
595     BYTE* dstpixel;
596     int x,y;
597
598     for (y=0; y<height; y++) {
599         srcpixel=srcbits;
600         dstpixel=dstbits;
601         for (x=0; x<width; x++) {
602             dstpixel[0]=srcpixel[2];
603             dstpixel[1]=srcpixel[1];
604             dstpixel[2]=srcpixel[0];
605             srcpixel+=3;
606             dstpixel+=3;
607         }
608         srcbits = (const char*)srcbits + srclinebytes;
609         dstbits = (char*)dstbits + dstlinebytes;
610     }
611 }
612
613 static void convert_888_to_555_asis(int width, int height,
614                                     const void* srcbits, int srclinebytes,
615                                     void* dstbits, int dstlinebytes)
616 {
617     const DWORD* srcpixel;
618     const BYTE* srcbyte;
619     WORD* dstpixel;
620     int x,y;
621     int oddwidth;
622
623     oddwidth=width & 3;
624     width=width/4;
625     for (y=0; y<height; y++) {
626         srcpixel=srcbits;
627         dstpixel=dstbits;
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;
631             srcval1=srcpixel[0];
632             dstpixel[0]=((srcval1 >>  3) & 0x001f) | /* l1 */
633                         ((srcval1 >>  6) & 0x03e0) | /* g1 */
634                         ((srcval1 >>  9) & 0x7c00);  /* h1 */
635             srcval2=srcpixel[1];
636             dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
637                         ((srcval2 <<  2) & 0x03e0) | /* g2 */
638                         ((srcval2 >>  1) & 0x7c00);  /* h2 */
639             srcval1=srcpixel[2];
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 */
646             srcpixel+=3;
647             dstpixel+=4;
648         }
649         /* And now up to 3 odd pixels */
650         srcbyte=(const BYTE*)srcpixel;
651         for (x=0; x<oddwidth; x++) {
652             WORD dstval;
653             dstval =((srcbyte[0] >> 3) & 0x001f);    /* l */
654             dstval|=((srcbyte[1] << 2) & 0x03e0);    /* g */
655             dstval|=((srcbyte[2] << 7) & 0x7c00);    /* h */
656             *dstpixel++=dstval;
657             srcbyte+=3;
658         }
659         srcbits = (const char*)srcbits + srclinebytes;
660         dstbits = (char*)dstbits + dstlinebytes;
661     }
662 }
663
664 static void convert_888_to_555_reverse(int width, int height,
665                                        const void* srcbits, int srclinebytes,
666                                        void* dstbits, int dstlinebytes)
667 {
668     const DWORD* srcpixel;
669     const BYTE* srcbyte;
670     WORD* dstpixel;
671     int x,y;
672     int oddwidth;
673
674     oddwidth=width & 3;
675     width=width/4;
676     for (y=0; y<height; y++) {
677         srcpixel=srcbits;
678         dstpixel=dstbits;
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;
682             srcval1=srcpixel[0];
683             dstpixel[0]=((srcval1 <<  7) & 0x7c00) | /* l1 */
684                         ((srcval1 >>  6) & 0x03e0) | /* g1 */
685                         ((srcval1 >> 19) & 0x001f);  /* h1 */
686             srcval2=srcpixel[1];
687             dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
688                         ((srcval2 <<  2) & 0x03e0) | /* g2 */
689                         ((srcval2 >> 11) & 0x001f);  /* h2 */
690             srcval1=srcpixel[2];
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 */
697             srcpixel+=3;
698             dstpixel+=4;
699         }
700         /* And now up to 3 odd pixels */
701         srcbyte=(const BYTE*)srcpixel;
702         for (x=0; x<oddwidth; x++) {
703             WORD dstval;
704             dstval =((srcbyte[0] << 7) & 0x7c00);    /* l */
705             dstval|=((srcbyte[1] << 2) & 0x03e0);    /* g */
706             dstval|=((srcbyte[2] >> 3) & 0x001f);    /* h */
707             *dstpixel++=dstval;
708             srcbyte+=3;
709         }
710         srcbits = (const char*)srcbits + srclinebytes;
711         dstbits = (char*)dstbits + dstlinebytes;
712     }
713 }
714
715 static void convert_888_to_565_asis(int width, int height,
716                                     const void* srcbits, int srclinebytes,
717                                     void* dstbits, int dstlinebytes)
718 {
719     const DWORD* srcpixel;
720     const BYTE* srcbyte;
721     WORD* dstpixel;
722     int x,y;
723     int oddwidth;
724
725     oddwidth=width & 3;
726     width=width/4;
727     for (y=0; y<height; y++) {
728         srcpixel=srcbits;
729         dstpixel=dstbits;
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;
733             srcval1=srcpixel[0];
734             dstpixel[0]=((srcval1 >>  3) & 0x001f) | /* l1 */
735                         ((srcval1 >>  5) & 0x07e0) | /* g1 */
736                         ((srcval1 >>  8) & 0xf800);  /* h1 */
737             srcval2=srcpixel[1];
738             dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
739                         ((srcval2 <<  3) & 0x07e0) | /* g2 */
740                         ( srcval2        & 0xf800);  /* h2 */
741             srcval1=srcpixel[2];
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 */
748             srcpixel+=3;
749             dstpixel+=4;
750         }
751         /* And now up to 3 odd pixels */
752         srcbyte=(const BYTE*)srcpixel;
753         for (x=0; x<oddwidth; x++) {
754             WORD dstval;
755             dstval =((srcbyte[0] >> 3) & 0x001f);    /* l */
756             dstval|=((srcbyte[1] << 3) & 0x07e0);    /* g */
757             dstval|=((srcbyte[2] << 8) & 0xf800);    /* h */
758             *dstpixel++=dstval;
759             srcbyte+=3;
760         }
761         srcbits = (const char*)srcbits + srclinebytes;
762         dstbits = (char*)dstbits + dstlinebytes;
763     }
764 }
765
766 static void convert_888_to_565_reverse(int width, int height,
767                                        const void* srcbits, int srclinebytes,
768                                        void* dstbits, int dstlinebytes)
769 {
770     const DWORD* srcpixel;
771     const BYTE* srcbyte;
772     WORD* dstpixel;
773     int x,y;
774     int oddwidth;
775
776     oddwidth=width & 3;
777     width=width/4;
778     for (y=0; y<height; y++) {
779         srcpixel=srcbits;
780         dstpixel=dstbits;
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;
784             srcval1=srcpixel[0];
785             dstpixel[0]=((srcval1 <<  8) & 0xf800) | /* l1 */
786                         ((srcval1 >>  5) & 0x07e0) | /* g1 */
787                         ((srcval1 >> 19) & 0x001f);  /* h1 */
788             srcval2=srcpixel[1];
789             dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
790                         ((srcval2 <<  3) & 0x07e0) | /* g2 */
791                         ((srcval2 >> 11) & 0x001f);  /* h2 */
792             srcval1=srcpixel[2];
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 */
799             srcpixel+=3;
800             dstpixel+=4;
801         }
802         /* And now up to 3 odd pixels */
803         srcbyte=(const BYTE*)srcpixel;
804         for (x=0; x<oddwidth; x++) {
805             WORD dstval;
806             dstval =((srcbyte[0] << 8) & 0xf800);    /* l */
807             dstval|=((srcbyte[1] << 3) & 0x07e0);    /* g */
808             dstval|=((srcbyte[2] >> 3) & 0x001f);    /* h */
809             *dstpixel++=dstval;
810             srcbyte+=3;
811         }
812         srcbits = (const char*)srcbits + srclinebytes;
813         dstbits = (char*)dstbits + dstlinebytes;
814     }
815 }
816
817 static void convert_888_to_0888_asis(int width, int height,
818                                      const void* srcbits, int srclinebytes,
819                                      void* dstbits, int dstlinebytes)
820 {
821     const DWORD* srcpixel;
822     DWORD* dstpixel;
823     int x,y;
824     int oddwidth;
825
826     oddwidth=width & 3;
827     width=width/4;
828     for (y=0; y<height; y++) {
829         srcpixel=srcbits;
830         dstpixel=dstbits;
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;
834             srcval1=srcpixel[0];
835             dstpixel[0]=( srcval1        & 0x00ffffff);  /* h1, g1, l1 */
836             srcval2=srcpixel[1];
837             dstpixel[1]=( srcval1 >> 24) |              /* l2 */
838                         ((srcval2 <<  8) & 0x00ffff00); /* h2, g2 */
839             srcval1=srcpixel[2];
840             dstpixel[2]=( srcval2 >> 16) |              /* g3, l3 */
841                         ((srcval1 << 16) & 0x00ff0000); /* h3 */
842             dstpixel[3]=( srcval1 >>  8);               /* h4, g4, l4 */
843             srcpixel+=3;
844             dstpixel+=4;
845         }
846         /* And now up to 3 odd pixels */
847         for (x=0; x<oddwidth; x++) {
848             DWORD srcval;
849             srcval=*srcpixel;
850             srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
851             *dstpixel++=( srcval         & 0x00ffffff); /* h, g, l */
852         }
853         srcbits = (const char*)srcbits + srclinebytes;
854         dstbits = (char*)dstbits + dstlinebytes;
855     }
856 }
857
858 static void convert_888_to_0888_reverse(int width, int height,
859                                         const void* srcbits, int srclinebytes,
860                                         void* dstbits, int dstlinebytes)
861 {
862     const DWORD* srcpixel;
863     DWORD* dstpixel;
864     int x,y;
865     int oddwidth;
866
867     oddwidth=width & 3;
868     width=width/4;
869     for (y=0; y<height; y++) {
870         srcpixel=srcbits;
871         dstpixel=dstbits;
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;
875
876             srcval1=srcpixel[0];
877             dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
878                         ( srcval1        & 0x00ff00) | /* g1 */
879                         ((srcval1 << 16) & 0xff0000);  /* l1 */
880             srcval2=srcpixel[1];
881             dstpixel[1]=((srcval1 >>  8) & 0xff0000) | /* l2 */
882                         ((srcval2 <<  8) & 0x00ff00) | /* g2 */
883                         ((srcval2 >>  8) & 0x0000ff);  /* h2 */
884             srcval1=srcpixel[2];
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 */
891             srcpixel+=3;
892             dstpixel+=4;
893         }
894         /* And now up to 3 odd pixels */
895         for (x=0; x<oddwidth; x++) {
896             DWORD srcval;
897             srcval=*srcpixel;
898             srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
899             *dstpixel++=((srcval  >> 16) & 0x0000ff) | /* h */
900                         ( srcval         & 0x00ff00) | /* g */
901                         ((srcval  << 16) & 0xff0000);  /* l */
902         }
903         srcbits = (const char*)srcbits + srclinebytes;
904         dstbits = (char*)dstbits + dstlinebytes;
905     }
906 }
907
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)
912 {
913     int rLeftShift,gLeftShift,bLeftShift;
914     const BYTE* srcpixel;
915     DWORD* dstpixel;
916     int x,y;
917
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++) {
922         srcpixel=srcbits;
923         dstpixel=dstbits;
924         for (x=0; x<width; x++) {
925             *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
926                         (srcpixel[1] << gLeftShift) | /* g */
927                         (srcpixel[2] << rLeftShift);  /* r */
928             srcpixel+=3;
929         }
930         srcbits = (const char*)srcbits + srclinebytes;
931         dstbits = (char*)dstbits + dstlinebytes;
932     }
933 }
934
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)
939 {
940     int rLeftShift,gLeftShift,bLeftShift;
941     const BYTE* srcpixel;
942     DWORD* dstpixel;
943     int x,y;
944
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++) {
949         srcpixel=srcbits;
950         dstpixel=dstbits;
951         for (x=0; x<width; x++) {
952             *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
953                         (srcpixel[1] << gLeftShift) | /* g */
954                         (srcpixel[2] << bLeftShift);  /* b */
955             srcpixel+=3;
956         }
957         srcbits = (const char*)srcbits + srclinebytes;
958         dstbits = (char*)dstbits + dstlinebytes;
959     }
960 }
961
962 /*
963  * 32 bit conversions
964  */
965
966 static void convert_0888_asis(int width, int height,
967                               const void* srcbits, int srclinebytes,
968                               void* dstbits, int dstlinebytes)
969 {
970     int y;
971
972     width *= 4;
973
974     if (srclinebytes == dstlinebytes && srclinebytes == width)
975     {
976         memcpy(dstbits, srcbits, height * width);
977         return;
978     }
979
980     for (y=0; y<height; y++) {
981         memcpy(dstbits, srcbits, width);
982         srcbits = (const char*)srcbits + srclinebytes;
983         dstbits = (char*)dstbits + dstlinebytes;
984     }
985 }
986
987 static void convert_0888_reverse(int width, int height,
988                                  const void* srcbits, int srclinebytes,
989                                  void* dstbits, int dstlinebytes)
990 {
991     const DWORD* srcpixel;
992     DWORD* dstpixel;
993     int x,y;
994
995     for (y=0; y<height; y++) {
996         srcpixel=srcbits;
997         dstpixel=dstbits;
998         for (x=0; x<width; x++) {
999             DWORD srcval;
1000             srcval=*srcpixel++;
1001             *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1002                         ( srcval        & 0x0000ff00) | /* g */
1003                         ((srcval >> 16) & 0x000000ff);  /* l */
1004         }
1005         srcbits = (const char*)srcbits + srclinebytes;
1006         dstbits = (char*)dstbits + dstlinebytes;
1007     }
1008 }
1009
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)
1015 {
1016     int rRightShift,gRightShift,bRightShift;
1017     int rLeftShift,gLeftShift,bLeftShift;
1018     const DWORD* srcpixel;
1019     DWORD* dstpixel;
1020     int x,y;
1021
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++) {
1029         srcpixel=srcbits;
1030         dstpixel=dstbits;
1031         for (x=0; x<width; x++) {
1032             DWORD srcval;
1033             srcval=*srcpixel++;
1034             *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1035                         (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1036                         (((srcval >> bRightShift) & 0xff) << bLeftShift);
1037         }
1038         srcbits = (const char*)srcbits + srclinebytes;
1039         dstbits = (char*)dstbits + dstlinebytes;
1040     }
1041 }
1042
1043 static void convert_0888_to_555_asis(int width, int height,
1044                                      const void* srcbits, int srclinebytes,
1045                                      void* dstbits, int dstlinebytes)
1046 {
1047     const DWORD* srcpixel;
1048     WORD* dstpixel;
1049     int x,y;
1050
1051     for (y=0; y<height; y++) {
1052         srcpixel=srcbits;
1053         dstpixel=dstbits;
1054         for (x=0; x<width; x++) {
1055             DWORD srcval;
1056             srcval=*srcpixel++;
1057             *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1058                         ((srcval >> 6) & 0x03e0) | /* g */
1059                         ((srcval >> 3) & 0x001f);  /* l */
1060         }
1061         srcbits = (const char*)srcbits + srclinebytes;
1062         dstbits = (char*)dstbits + dstlinebytes;
1063     }
1064 }
1065
1066 static void convert_0888_to_555_reverse(int width, int height,
1067                                         const void* srcbits, int srclinebytes,
1068                                         void* dstbits, int dstlinebytes)
1069 {
1070     const DWORD* srcpixel;
1071     WORD* dstpixel;
1072     int x,y;
1073
1074     for (y=0; y<height; y++) {
1075         srcpixel=srcbits;
1076         dstpixel=dstbits;
1077         for (x=0; x<width; x++) {
1078             DWORD srcval;
1079             srcval=*srcpixel++;
1080             *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1081                         ((srcval >>  6) & 0x03e0) | /* g */
1082                         ((srcval <<  7) & 0x7c00);  /* l */
1083         }
1084         srcbits = (const char*)srcbits + srclinebytes;
1085         dstbits = (char*)dstbits + dstlinebytes;
1086     }
1087 }
1088
1089 static void convert_0888_to_565_asis(int width, int height,
1090                                      const void* srcbits, int srclinebytes,
1091                                      void* dstbits, int dstlinebytes)
1092 {
1093     const DWORD* srcpixel;
1094     WORD* dstpixel;
1095     int x,y;
1096
1097     for (y=0; y<height; y++) {
1098         srcpixel=srcbits;
1099         dstpixel=dstbits;
1100         for (x=0; x<width; x++) {
1101             DWORD srcval;
1102             srcval=*srcpixel++;
1103             *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1104                         ((srcval >> 5) & 0x07e0) | /* g */
1105                         ((srcval >> 3) & 0x001f);  /* l */
1106         }
1107         srcbits = (const char*)srcbits + srclinebytes;
1108         dstbits = (char*)dstbits + dstlinebytes;
1109     }
1110 }
1111
1112 static void convert_0888_to_565_reverse(int width, int height,
1113                                         const void* srcbits, int srclinebytes,
1114                                         void* dstbits, int dstlinebytes)
1115 {
1116     const DWORD* srcpixel;
1117     WORD* dstpixel;
1118     int x,y;
1119
1120     for (y=0; y<height; y++) {
1121         srcpixel=srcbits;
1122         dstpixel=dstbits;
1123         for (x=0; x<width; x++) {
1124             DWORD srcval;
1125             srcval=*srcpixel++;
1126             *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1127                         ((srcval >>  5) & 0x07e0) | /* g */
1128                         ((srcval <<  8) & 0xf800);  /* l */
1129         }
1130         srcbits = (const char*)srcbits + srclinebytes;
1131         dstbits = (char*)dstbits + dstlinebytes;
1132     }
1133 }
1134
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)
1140 {
1141     int rRightShift,gRightShift,bRightShift;
1142     int rLeftShift,gLeftShift,bLeftShift;
1143     const DWORD* srcpixel;
1144     WORD* dstpixel;
1145     int x,y;
1146
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
1151      *   -> 0x4488c
1152      * - then we remove non red bits by anding with the modified rdst (0x1f)
1153      *   -> 0x0c
1154      * - finally shift these bits left by rLeftShift so that they end up in
1155      *   the right place
1156      *   -> 0x3000
1157      */
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;
1162
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;
1169
1170     for (y=0; y<height; y++) {
1171         srcpixel=srcbits;
1172         dstpixel=dstbits;
1173         for (x=0; x<width; x++) {
1174             DWORD srcval;
1175             srcval=*srcpixel++;
1176             *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1177                         (((srcval >> gRightShift) & gdst) << gLeftShift) |
1178                         (((srcval >> bRightShift) & bdst) << bLeftShift);
1179         }
1180         srcbits = (const char*)srcbits + srclinebytes;
1181         dstbits = (char*)dstbits + dstlinebytes;
1182     }
1183 }
1184
1185 static void convert_0888_to_888_asis(int width, int height,
1186                                      const void* srcbits, int srclinebytes,
1187                                      void* dstbits, int dstlinebytes)
1188 {
1189     const DWORD* srcpixel;
1190     DWORD* dstpixel;
1191     BYTE* dstbyte;
1192     int x,y;
1193     int oddwidth;
1194
1195     oddwidth=width & 3;
1196     width=width/4;
1197     for (y=0; y<height; y++) {
1198         srcpixel=srcbits;
1199         dstpixel=dstbits;
1200         for (x=0; x<width; x++) {
1201             /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1202             DWORD srcval;
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 */
1209         }
1210         /* And now up to 3 odd pixels */
1211         dstbyte=(BYTE*)dstpixel;
1212         for (x=0; x<oddwidth; x++) {
1213             DWORD srcval;
1214             srcval=*srcpixel++;
1215             *((WORD*)dstbyte) = srcval;                 /* h, g */
1216             dstbyte+=sizeof(WORD);
1217             *dstbyte++=srcval >> 16;                    /* l */
1218         }
1219         srcbits = (const char*)srcbits + srclinebytes;
1220         dstbits = (char*)dstbits + dstlinebytes;
1221     }
1222 }
1223
1224 static void convert_0888_to_888_reverse(int width, int height,
1225                                         const void* srcbits, int srclinebytes,
1226                                         void* dstbits, int dstlinebytes)
1227 {
1228     const DWORD* srcpixel;
1229     DWORD* dstpixel;
1230     BYTE* dstbyte;
1231     int x,y;
1232     int oddwidth;
1233
1234     oddwidth=width & 3;
1235     width=width/4;
1236     for (y=0; y<height; y++) {
1237         srcpixel=srcbits;
1238         dstpixel=dstbits;
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 */
1261         }
1262         /* And now up to 3 odd pixels */
1263         dstbyte=(BYTE*)dstpixel;
1264         for (x=0; x<oddwidth; x++) {
1265             DWORD srcval;
1266             srcval=*srcpixel++;
1267             *((WORD*)dstbyte)=((srcval >> 16) & 0x00ff) | /* h */
1268                               (srcval         & 0xff00);  /* g */
1269             dstbyte += sizeof(WORD);
1270             *dstbyte++=srcval;                              /* l */
1271         }
1272         srcbits = (const char*)srcbits + srclinebytes;
1273         dstbits = (char*)dstbits + dstlinebytes;
1274     }
1275 }
1276
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)
1281 {
1282     int rRightShift,gRightShift,bRightShift;
1283     const DWORD* srcpixel;
1284     BYTE* dstpixel;
1285     int x,y;
1286
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++) {
1291         srcpixel=srcbits;
1292         dstpixel=dstbits;
1293         for (x=0; x<width; x++) {
1294             DWORD srcval;
1295             srcval=*srcpixel++;
1296             dstpixel[0]=(srcval >> bRightShift); /* b */
1297             dstpixel[1]=(srcval >> gRightShift); /* g */
1298             dstpixel[2]=(srcval >> rRightShift); /* r */
1299             dstpixel+=3;
1300         }
1301         srcbits = (const char*)srcbits + srclinebytes;
1302         dstbits = (char*)dstbits + dstlinebytes;
1303     }
1304 }
1305
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)
1310 {
1311     int rRightShift,gRightShift,bRightShift;
1312     const DWORD* srcpixel;
1313     BYTE* dstpixel;
1314     int x,y;
1315
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++) {
1320         srcpixel=srcbits;
1321         dstpixel=dstbits;
1322         for (x=0; x<width; x++) {
1323             DWORD srcval;
1324             srcval=*srcpixel++;
1325             dstpixel[0]=(srcval >> rRightShift); /* r */
1326             dstpixel[1]=(srcval >> gRightShift); /* g */
1327             dstpixel[2]=(srcval >> bRightShift); /* b */
1328             dstpixel+=3;
1329         }
1330         srcbits = (const char*)srcbits + srclinebytes;
1331         dstbits = (char*)dstbits + dstlinebytes;
1332     }
1333 }
1334
1335 const dib_conversions dib_normal = {
1336     convert_5x5_asis,
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,
1352     convert_888_asis,
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,
1362     convert_0888_asis,
1363     convert_0888_reverse,
1364     convert_0888_any,
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
1374 };