comctl32/tests: Use SHIL_SYSSMALL instead of LARGE, and compare with system metrics.
[wine] / dlls / winex11.drv / dib_src_swap.c
1 /*
2  * DIB conversion routinues for cases where the source
3  * has non-native byte order.
4  *
5  * Copyright (C) 2003 Huw Davies
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25
26 #include "windef.h"
27 #include "x11drv.h"
28
29
30 #define FLIP_WORD(x) \
31  ( *(x)  = ( (*(x) & 0xff) << 8) | \
32    ( (*(x) & 0xff00) >> 8) )
33
34 #define FLIP_TWO_WORDS(x) \
35  ( *(x)  = ( (*(x) & 0x00ff00ff) << 8) | \
36    ( (*(x) & 0xff00ff00) >> 8) )
37
38 #define FLIP_DWORD(x) \
39  ( *(x)  = ( (*(x) & 0xff) << 24) | \
40    ( (*(x) & 0xff00) << 8) | \
41    ( (*(x) & 0xff0000) >> 8) | \
42    ( (*(x) & 0xff000000) >> 24) )
43
44
45
46 /*
47  * 15 bit conversions
48  */
49
50 static void convert_5x5_asis_src_byteswap(int width, int height,
51                                           const void* srcbits, int srclinebytes,
52                                           void* dstbits, int dstlinebytes)
53 {
54     int x, y;
55     const DWORD *srcpixel;
56     DWORD *dstpixel;
57
58     for (y=0; y<height; y++) {
59         srcpixel=srcbits;
60         dstpixel=dstbits;
61         for(x = 0; x < width/2; x++) {
62             /* Do 2 pixels at a time */
63             DWORD srcval = *srcpixel++;
64             *dstpixel++=((srcval << 8) & 0xff00ff00) |
65                         ((srcval >> 8) & 0x00ff00ff);
66         }
67         if(width&1) {
68             /* And the odd pixel */
69             WORD srcval = *(const WORD*)srcpixel;
70             *(WORD*)dstpixel = ((srcval << 8) & 0xff00) |
71                                ((srcval >> 8) & 0x00ff);
72         }
73         srcbits = (const char*)srcbits + srclinebytes;
74         dstbits = (char*)dstbits + dstlinebytes;
75     }
76 }
77
78 static void convert_555_reverse_src_byteswap(int width, int height,
79                                              const void* srcbits, int srclinebytes,
80                                              void* dstbits, int dstlinebytes)
81 {
82     const DWORD* srcpixel;
83     DWORD* dstpixel;
84     int x,y;
85
86     for (y=0; y<height; y++) {
87         srcpixel=srcbits;
88         dstpixel=dstbits;
89         for (x=0; x<width/2; x++) {
90             /* Do 2 pixels at a time */
91             DWORD srcval;
92             srcval=*srcpixel++;
93             *dstpixel++=((srcval >>  2) & 0x001f001f) | /* h */
94                         ((srcval <<  8) & 0x03000300) | /* g - 2 bits */
95                         ((srcval >>  8) & 0x00e000e0) | /* g - 3 bits */
96                         ((srcval <<  2) & 0x7c007c00);  /* l */
97         }
98         if (width&1) {
99             /* And then the odd pixel */
100             WORD srcval;
101             srcval=*((const WORD*)srcpixel);
102             *((WORD*)dstpixel)=((srcval >>  2) & 0x001f) | /* h */
103                                ((srcval <<  8) & 0x0300) | /* g - 2 bits */
104                                ((srcval >>  8) & 0x00e0) | /* g - 3 bits */
105                                ((srcval <<  2) & 0x7c00);  /* l */
106         }
107         srcbits = (const char*)srcbits + srclinebytes;
108         dstbits = (char*)dstbits + dstlinebytes;
109     }
110 }
111
112 static void convert_555_to_565_asis_src_byteswap(int width, int height,
113                                                  const void* srcbits, int srclinebytes,
114                                                  void* dstbits, int dstlinebytes)
115 {
116     const DWORD* srcpixel;
117     DWORD* dstpixel;
118     int x,y;
119
120     for (y=0; y<height; y++) {
121         srcpixel=srcbits;
122         dstpixel=dstbits;
123         for (x=0; x<width/2; x++) {
124             /* Do 2 pixels at a time */
125             DWORD srcval;
126             srcval=*srcpixel++;
127             *dstpixel++=((srcval << 9) & 0xfe00fe00) | /* h, g - 2 bits*/
128                         ((srcval >> 7) & 0x01c001c0) | /* g - 3 bits */
129                         ((srcval << 4) & 0x00200020) | /* g - 1 bit */
130                         ((srcval >> 8) & 0x001f001f);  /* l */
131         }
132         if (width&1) {
133             /* And then the odd pixel */
134             WORD srcval;
135             srcval=*((const WORD*)srcpixel);
136             *((WORD*)dstpixel)=((srcval << 9) & 0xfe00) | /* h, g - 2bits*/
137                                ((srcval >> 7) & 0x01c0) | /* g - 3 bits */
138                                ((srcval << 4) & 0x0020) | /* g - 1 bit */
139                                ((srcval >> 8) & 0x001f);  /* l */
140         }
141         srcbits = (const char*)srcbits + srclinebytes;
142         dstbits = (char*)dstbits + dstlinebytes;
143     }
144 }
145
146 static void convert_555_to_565_reverse_src_byteswap(int width, int height,
147                                                     const void* srcbits, int srclinebytes,
148                                                     void* dstbits, int dstlinebytes)
149 {
150     const DWORD* srcpixel;
151     DWORD* dstpixel;
152     int x,y;
153
154     for (y=0; y<height; y++) {
155         srcpixel=srcbits;
156         dstpixel=dstbits;
157         for (x=0; x<width/2; x++) {
158             /* Do 2 pixels at a time */
159             DWORD srcval;
160             srcval=*srcpixel++;
161              *dstpixel++=((srcval >>  2) & 0x001f001f) | /* h */
162                          ((srcval <<  9) & 0x06000600) | /* g - 2 bits*/
163                          ((srcval >>  7) & 0x01c001c0) | /* g - 3 bits */
164                          ((srcval <<  4) & 0x00200020) | /* g - 1 bits */
165                          ((srcval <<  3) & 0xf800f800);  /* l */
166         }
167         if (width&1) {
168             /* And then the odd pixel */
169             WORD srcval;
170             srcval=*((const WORD*)srcpixel);
171             *((WORD*)dstpixel)=((srcval >>  2) & 0x001f) | /* h */
172                                ((srcval <<  9) & 0x0600) | /* g - 2 bits  */
173                                ((srcval >>  7) & 0x01c0) | /* g - 3 bits */
174                                ((srcval <<  4) & 0x0020) | /* g - 1 bit */
175                                ((srcval <<  3) & 0xf800);  /* l */
176         }
177         srcbits = (const char*)srcbits + srclinebytes;
178         dstbits = (char*)dstbits + dstlinebytes;
179     }
180 }
181
182 static void convert_555_to_888_asis_src_byteswap(int width, int height,
183                                                  const void* srcbits, int srclinebytes,
184                                                  void* dstbits, int dstlinebytes)
185 {
186     const WORD* srcpixel;
187     BYTE* dstpixel;
188     int x,y;
189
190     for (y=0; y<height; y++) {
191         srcpixel=srcbits;
192         dstpixel=dstbits;
193         for (x=0; x<width; x++) {
194             WORD srcval;
195             srcval=*srcpixel++;
196             dstpixel[0]=((srcval >>  5) & 0xf8) | /* l */
197                         ((srcval >> 10) & 0x07);  /* l - 3 bits */
198             dstpixel[1]=((srcval <<  6) & 0xc0) | /* g - 2 bits */
199                         ((srcval >> 10) & 0x38) | /* g - 3 bits */
200                         ((srcval <<  1) & 0x06) | /* g - 2 bits */
201                         ((srcval >> 15) & 0x01);  /* g - 1 bit */
202             dstpixel[2]=((srcval <<  1) & 0xf8) | /* h */
203                         ((srcval >>  4) & 0x07);  /* h - 3 bits */
204             dstpixel+=3;
205         }
206         srcbits = (const char*)srcbits + srclinebytes;
207         dstbits = (char*)dstbits + dstlinebytes;
208     }
209 }
210
211 static void convert_555_to_888_reverse_src_byteswap(int width, int height,
212                                                     const void* srcbits, int srclinebytes,
213                                                     void* dstbits, int dstlinebytes)
214 {
215     const WORD* srcpixel;
216     BYTE* dstpixel;
217     int x,y;
218
219     for (y=0; y<height; y++) {
220         srcpixel=srcbits;
221         dstpixel=dstbits;
222         for (x=0; x<width; x++) {
223             WORD srcval;
224             srcval=*srcpixel++;
225             dstpixel[0]=((srcval <<  1) & 0xf8) | /* h */
226                         ((srcval >>  4) & 0x07);  /* h - 3 bits */
227             dstpixel[1]=((srcval <<  6) & 0xc0) | /* g - 2 bits */
228                         ((srcval >> 10) & 0x38) | /* g - 3 bits */
229                         ((srcval <<  1) & 0x06) | /* g - 2 bits */
230                         ((srcval >> 15) & 0x01);  /* g - 1 bits */
231             dstpixel[2]=((srcval >>  5) & 0xf8) | /* l */
232                         ((srcval >> 10) & 0x07);  /* l - 3 bits */
233             dstpixel+=3;
234         }
235         srcbits = (const char*)srcbits + srclinebytes;
236         dstbits = (char*)dstbits + dstlinebytes;
237     }
238 }
239
240 static void convert_555_to_0888_asis_src_byteswap(int width, int height,
241                                                   const void* srcbits, int srclinebytes,
242                                                   void* dstbits, int dstlinebytes)
243 {
244     const WORD* srcpixel;
245     DWORD* dstpixel;
246     int x,y;
247
248     for (y=0; y<height; y++) {
249         srcpixel=srcbits;
250         dstpixel=dstbits;
251         for (x=0; x<width; x++) {
252             WORD srcval;
253             srcval=*srcpixel++;
254             *dstpixel++=((srcval << 17) & 0xf80000) | /* h */
255                         ((srcval << 12) & 0x070000) | /* h - 3 bits */
256                         ((srcval << 14) & 0x00c000) | /* g - 2 bits */
257                         ((srcval >>  2) & 0x003800) | /* g - 3 bits */
258                         ((srcval <<  9) & 0x000600) | /* g - 2 bits */
259                         ((srcval >>  7) & 0x000100) | /* g - 1 bit */
260                         ((srcval >>  5) & 0x0000f8) | /* l */
261                         ((srcval >> 10) & 0x000007);  /* l - 3 bits */
262         }
263         srcbits = (const char*)srcbits + srclinebytes;
264         dstbits = (char*)dstbits + dstlinebytes;
265     }
266 }
267
268 static void convert_555_to_0888_reverse_src_byteswap(int width, int height,
269                                                      const void* srcbits, int srclinebytes,
270                                                      void* dstbits, int dstlinebytes)
271 {
272     const WORD* srcpixel;
273     DWORD* dstpixel;
274     int x,y;
275
276     for (y=0; y<height; y++) {
277         srcpixel=srcbits;
278         dstpixel=dstbits;
279         for (x=0; x<width; x++) {
280             WORD srcval;
281             srcval=*srcpixel++;
282             *dstpixel++=((srcval <<  1) & 0x0000f8) | /* h */
283                         ((srcval >>  4) & 0x000007) | /* h - 3 bits */
284                         ((srcval << 14) & 0x00c000) | /* g - 2 bits */
285                         ((srcval >>  2) & 0x003800) | /* g - 3 bits */
286                         ((srcval <<  9) & 0x000600) | /* g - 2 bits */
287                         ((srcval >>  7) & 0x000100) | /* g - 1 bit */
288                         ((srcval << 11) & 0xf80000) | /* l */
289                         ((srcval <<  6) & 0x070000);  /* l - 3 bits */
290         }
291         srcbits = (const char*)srcbits + srclinebytes;
292         dstbits = (char*)dstbits + dstlinebytes;
293     }
294 }
295
296 static void convert_5x5_to_any0888_src_byteswap(int width, int height,
297                                                 const void* srcbits, int srclinebytes,
298                                                 WORD rsrc, WORD gsrc, WORD bsrc,
299                                                 void* dstbits, int dstlinebytes,
300                                                 DWORD rdst, DWORD gdst, DWORD bdst)
301 {
302     int rRightShift1,gRightShift1,bRightShift1;
303     int rRightShift2,gRightShift2,bRightShift2;
304     BYTE gMask1,gMask2;
305     int rLeftShift,gLeftShift,bLeftShift;
306     const WORD* srcpixel;
307     DWORD* dstpixel;
308     int x,y;
309
310     /* Note, the source pixel value is shifted left by 16 bits so that
311      * we know we will always have to shift right to extract the components.
312      */
313     rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
314     gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
315     bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
316     rRightShift2=rRightShift1+5;
317     gRightShift2=gRightShift1+5;
318     bRightShift2=bRightShift1+5;
319     if (gsrc==0x03e0) {
320         /* Green has 5 bits, like the others */
321         gMask1=0xf8;
322         gMask2=0x07;
323     } else {
324         /* Green has 6 bits, not 5. Compensate. */
325         gRightShift1++;
326         gRightShift2+=2;
327         gMask1=0xfc;
328         gMask2=0x03;
329     }
330
331     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
332     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
333     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
334
335     for (y=0; y<height; y++) {
336         srcpixel=srcbits;
337         dstpixel=dstbits;
338         for (x=0; x<width; x++) {
339             DWORD srcval;
340             BYTE red,green,blue;
341             srcval=*srcpixel++ << 16;
342             FLIP_TWO_WORDS(&srcval);
343
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_src_byteswap(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 <<  3) & 0xf800f800) | /* l */
379                         ((srcval <<  8) & 0x07000700) | /* g - 3 bits */
380                         ((srcval >>  8) & 0x00e000e0) | /* g - 3 bits */
381                         ((srcval >>  3) & 0x001f001f);  /* h */
382         }
383         if (width&1) {
384             /* And then the odd pixel */
385             WORD srcval;
386             srcval=*((const WORD*)srcpixel);
387             *((WORD*)dstpixel)=((srcval <<  3) & 0xf800) | /* l */
388                                ((srcval <<  8) & 0x0700) | /* g - 3 bits */
389                                ((srcval >>  8) & 0x00e0) | /* g - 3 bits */
390                                ((srcval >>  3) & 0x001f);  /* h */
391         }
392         srcbits = (const char*)srcbits + srclinebytes;
393         dstbits = (char*)dstbits + dstlinebytes;
394     }
395 }
396
397 static void convert_565_to_555_asis_src_byteswap(int width, int height,
398                                                  const void* srcbits, int srclinebytes,
399                                                  void* dstbits, int dstlinebytes)
400 {
401     const DWORD* srcpixel;
402     DWORD* dstpixel;
403     int x,y;
404
405     for (y=0; y<height; y++) {
406         srcpixel=srcbits;
407         dstpixel=dstbits;
408         for (x=0; x<width/2; x++) {
409             /* Do 2 pixels at a time */
410             DWORD srcval;
411             srcval=*srcpixel++;
412             *dstpixel++=((srcval << 7) & 0x7f807f80) | /* h, g - 3 bits */
413                         ((srcval >> 9) & 0x00600060) | /* g - 2 bits */
414                         ((srcval >> 8) & 0x001f001f);  /* l */
415         }
416         if (width&1) {
417             /* And then the odd pixel */
418             WORD srcval;
419             srcval=*((const WORD*)srcpixel);
420             *((WORD*)dstpixel)=((srcval << 7) & 0x7f80) | /* h, g - 3 bits */
421                                ((srcval >> 9) & 0x0060) | /* g - 2 bits */
422                                ((srcval >> 8) & 0x001f);  /* l */
423         }
424         srcbits = (const char*)srcbits + srclinebytes;
425         dstbits = (char*)dstbits + dstlinebytes;
426     }
427 }
428
429 static void convert_565_to_555_reverse_src_byteswap(int width, int height,
430                                                     const void* srcbits, int srclinebytes,
431                                                     void* dstbits, int dstlinebytes)
432 {
433     const DWORD* srcpixel;
434     DWORD* dstpixel;
435     int x,y;
436
437     for (y=0; y<height; y++) {
438         srcpixel=srcbits;
439         dstpixel=dstbits;
440         for (x=0; x<width/2; x++) {
441             /* Do 2 pixels at a time */
442             DWORD srcval;
443             srcval=*srcpixel++;
444             *dstpixel++=((srcval >>  3) & 0x001f001f) | /* h */
445                         ((srcval >>  9) & 0x00600060) | /* g - 2 bits */
446                         ((srcval <<  7) & 0x03800380) | /* g - 3 bits */
447                         ((srcval <<  2) & 0x7c007c00);  /* l */
448         }
449         if (width&1) {
450             /* And then the odd pixel */
451             WORD srcval;
452             srcval=*((const WORD*)srcpixel);
453             *((WORD*)dstpixel)=((srcval >>  3) & 0x001f) | /* h */
454                                ((srcval >>  9) & 0x0060) | /* g - 2 bits */
455                                ((srcval <<  7) & 0x0380) | /* g - 3 bits */
456                                ((srcval <<  2) & 0x7c00);  /* l */
457         }
458         srcbits = (const char*)srcbits + srclinebytes;
459         dstbits = (char*)dstbits + dstlinebytes;
460     }
461 }
462
463 static void convert_565_to_888_asis_src_byteswap(int width, int height,
464                                                  const void* srcbits, int srclinebytes,
465                                                  void* dstbits, int dstlinebytes)
466 {
467     const WORD* srcpixel;
468     BYTE* dstpixel;
469     int x,y;
470
471     for (y=0; y<height; y++) {
472         srcpixel=srcbits;
473         dstpixel=dstbits;
474         for (x=0; x<width; x++) {
475             WORD srcval;
476             srcval=*srcpixel++;
477             dstpixel[0]=((srcval >>  5) & 0xf8) | /* l */
478                         ((srcval >> 10) & 0x07);  /* l - 3 bits */
479             dstpixel[1]=((srcval <<  5) & 0xe0) | /* g - 3 bits */
480                         ((srcval >> 11) & 0x1c) | /* g - 3 bits */
481                         ((srcval >>  1) & 0x03);  /* g - 2 bits */
482             dstpixel[2]=((srcval >>  0) & 0xf8) | /* h */
483                         ((srcval >>  5) & 0x07);  /* h - 3 bits */
484             dstpixel+=3;
485         }
486         srcbits = (const char*)srcbits + srclinebytes;
487         dstbits = (char*)dstbits + dstlinebytes;
488     }
489 }
490
491 static void convert_565_to_888_reverse_src_byteswap(int width, int height,
492                                                     const void* srcbits, int srclinebytes,
493                                                     void* dstbits, int dstlinebytes)
494 {
495     const WORD* srcpixel;
496     BYTE* dstpixel;
497     int x,y;
498
499     for (y=0; y<height; y++) {
500         srcpixel=srcbits;
501         dstpixel=dstbits;
502         for (x=0; x<width; x++) {
503             WORD srcval;
504             srcval=*srcpixel++;
505             dstpixel[0]=((srcval >>  0) & 0xf8) | /* h */
506                         ((srcval >>  5) & 0x07);  /* h - 3 bits */
507             dstpixel[1]=((srcval <<  5) & 0xe0) | /* g - 3 bits */
508                         ((srcval >> 11) & 0x1c) | /* g - 3 bits */
509                         ((srcval >>  1) & 0x03);  /* g - 2 bits */
510             dstpixel[2]=((srcval >>  5) & 0xf8) | /* l */
511                         ((srcval >> 10) & 0x07);  /* l - 3 bits */
512             dstpixel+=3;
513         }
514         srcbits = (const char*)srcbits + srclinebytes;
515         dstbits = (char*)dstbits + dstlinebytes;
516     }
517 }
518
519 static void convert_565_to_0888_asis_src_byteswap(int width, int height,
520                                                   const void* srcbits, int srclinebytes,
521                                                   void* dstbits, int dstlinebytes)
522 {
523     const WORD* srcpixel;
524     DWORD* dstpixel;
525     int x,y;
526
527     for (y=0; y<height; y++) {
528         srcpixel=srcbits;
529         dstpixel=dstbits;
530         for (x=0; x<width; x++) {
531             WORD srcval;
532             srcval=*srcpixel++;
533             *dstpixel++=((srcval << 16) & 0xf80000) | /* h */
534                         ((srcval << 11) & 0x070000) | /* h - 3 bits */
535                         ((srcval << 13) & 0x00e000) | /* g - 3 bits */
536                         ((srcval >>  3) & 0x001c00) | /* g - 3 bits */
537                         ((srcval <<  7) & 0x000300) | /* g - 2 bits */
538                         ((srcval >>  5) & 0x0000f8) | /* l */
539                         ((srcval >> 10) & 0x000007);  /* l - 3 bits */
540         }
541         srcbits = (const char*)srcbits + srclinebytes;
542         dstbits = (char*)dstbits + dstlinebytes;
543     }
544 }
545
546 static void convert_565_to_0888_reverse_src_byteswap(int width, int height,
547                                                      const void* srcbits, int srclinebytes,
548                                                      void* dstbits, int dstlinebytes)
549 {
550     const WORD* srcpixel;
551     DWORD* dstpixel;
552     int x,y;
553
554     for (y=0; y<height; y++) {
555         srcpixel=srcbits;
556         dstpixel=dstbits;
557         for (x=0; x<width; x++) {
558             WORD srcval;
559             srcval=*srcpixel++;
560             *dstpixel++=((srcval >>  0) & 0x0000f8) | /* h */
561                         ((srcval >>  5) & 0x000007) | /* h - 3 bits */
562                         ((srcval << 13) & 0x00e000) | /* g - 3 bits */
563                         ((srcval >>  3) & 0x001c00) | /* g - 3 bits */
564                         ((srcval <<  7) & 0x000300) | /* g - 2 bits */
565                         ((srcval << 11) & 0xf80000) | /* l */
566                         ((srcval <<  6) & 0x070000);  /* l - 3 bits */
567         }
568         srcbits = (const char*)srcbits + srclinebytes;
569         dstbits = (char*)dstbits + dstlinebytes;
570     }
571 }
572
573 /*
574  * 24 bit conversions
575  */
576
577 static void convert_888_asis_src_byteswap(int width, int height,
578                                           const void* srcbits, int srclinebytes,
579                                           void* dstbits, int dstlinebytes)
580 {
581     int x, y;
582
583     for (y=0; y<height; y++) {
584         for(x = 0; x < ((width+1)*3/4); x++) {
585             DWORD srcval = *((const DWORD*)srcbits + x);
586             *((DWORD*)dstbits + x) = ((srcval << 24) & 0xff000000) |
587                                      ((srcval <<  8) & 0x00ff0000) |
588                                      ((srcval >>  8) & 0x0000ff00) |
589                                      ((srcval >> 24) & 0x000000ff);
590         }
591         srcbits = (const char*)srcbits + srclinebytes;
592         dstbits = (char*)dstbits + dstlinebytes;
593     }
594 }
595
596 static void convert_888_reverse_src_byteswap(int width, int height,
597                                              const void* srcbits, int srclinebytes,
598                                              void* dstbits, int dstlinebytes)
599 {
600     const DWORD* srcpixel;
601     DWORD* dstpixel;
602     DWORD srcarray[3];
603     int x,y;
604     int oddwidth = width & 3;
605
606     width = width/4;
607
608     for (y=0; y<height; y++) {
609         srcpixel=srcbits;
610         dstpixel=dstbits;
611         for (x=0; x<width; x++) {
612             /* Do 4 pixels at a time: 3 dwords in and 3 dwords out */
613             *dstpixel++= ((srcpixel[0] >>  8) & 0x00ffffff) | /* l1, g1, h1 */
614                          ((srcpixel[1] <<  8) & 0xff000000);  /* h2 */
615             *dstpixel++= ((srcpixel[1] >> 24) & 0x000000ff) | /* g2 */
616                          ((srcpixel[0] <<  8) & 0x0000ff00) | /* l2 */
617                          ((srcpixel[2] >>  8) & 0x00ff0000) | /* h3 */
618                          ((srcpixel[1] << 24) & 0xff000000);  /* g3 */
619             *dstpixel++= ((srcpixel[1] >>  8) & 0x000000ff) | /* l3 */
620                          ((srcpixel[2] <<  8) & 0xffffff00);  /* l4, g4, h4 */
621             srcpixel+=3;
622         }
623         /* And now up to 3 odd pixels */
624         if(oddwidth) {
625             BYTE *dstbyte, *srcbyte;
626             memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD));
627             dstbyte = (LPBYTE)dstpixel;
628             srcbyte = (LPBYTE)srcarray;
629             for (x=0; x<oddwidth; x++) {
630                 FLIP_DWORD(srcarray+x);
631                 dstbyte[0] = srcbyte[2];
632                 dstbyte[1] = srcbyte[1];
633                 dstbyte[2] = srcbyte[0];
634                 srcbyte+=3;
635                 dstbyte+=3;
636             }
637         }
638
639         srcbits = (const char*)srcbits + srclinebytes;
640         dstbits = (char*)dstbits + dstlinebytes;
641     }
642 }
643
644 static void convert_888_to_555_asis_src_byteswap(int width, int height,
645                                                  const void* srcbits, int srclinebytes,
646                                                  void* dstbits, int dstlinebytes)
647 {
648     const DWORD* srcpixel;
649     const BYTE* srcbyte;
650     WORD* dstpixel;
651     DWORD srcarray[3];
652     int x,y;
653     int oddwidth;
654
655     oddwidth=width & 3;
656     width=width/4;
657     for (y=0; y<height; y++) {
658         srcpixel=srcbits;
659         dstpixel=dstbits;
660         for (x=0; x<width; x++) {
661             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
662             DWORD srcval1,srcval2;
663             srcval1=srcpixel[0];
664             FLIP_DWORD(&srcval1);
665             dstpixel[0]=((srcval1 >>  3) & 0x001f) | /* l1 */
666                         ((srcval1 >>  6) & 0x03e0) | /* g1 */
667                         ((srcval1 >>  9) & 0x7c00);  /* h1 */
668             srcval2=srcpixel[1];
669             FLIP_DWORD(&srcval2);
670             dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
671                         ((srcval2 <<  2) & 0x03e0) | /* g2 */
672                         ((srcval2 >>  1) & 0x7c00);  /* h2 */
673             srcval1=srcpixel[2];
674             FLIP_DWORD(&srcval1);
675             dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
676                         ((srcval2 >> 22) & 0x03e0) | /* g3 */
677                         ((srcval1 <<  7) & 0x7c00);  /* h3 */
678             dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
679                         ((srcval1 >> 14) & 0x03e0) | /* g4 */
680                         ((srcval1 >> 17) & 0x7c00);  /* h4 */
681             srcpixel+=3;
682             dstpixel+=4;
683         }
684         /* And now up to 3 odd pixels */
685         if(oddwidth) {
686             memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD));
687             srcbyte = (LPBYTE)srcarray;
688             for (x=0; x<oddwidth; x++) {
689                 WORD dstval;
690                 FLIP_DWORD(srcarray+x);
691
692                 dstval =((srcbyte[0] >> 3) & 0x001f);    /* l */
693                 dstval|=((srcbyte[1] << 2) & 0x03e0);    /* g */
694                 dstval|=((srcbyte[2] << 7) & 0x7c00);    /* h */
695                 *dstpixel++=dstval;
696                 srcbyte+=3;
697             }
698         }
699         srcbits = (const char*)srcbits + srclinebytes;
700         dstbits = (char*)dstbits + dstlinebytes;
701     }
702 }
703
704 static void convert_888_to_555_reverse_src_byteswap(int width, int height,
705                                                     const void* srcbits, int srclinebytes,
706                                                     void* dstbits, int dstlinebytes)
707 {
708     const DWORD* srcpixel;
709     const BYTE* srcbyte;
710     WORD* dstpixel;
711     DWORD srcarray[3];
712     int x,y;
713     int oddwidth;
714
715     oddwidth=width & 3;
716     width=width/4;
717     for (y=0; y<height; y++) {
718         srcpixel=srcbits;
719         dstpixel=dstbits;
720         for (x=0; x<width; x++) {
721             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
722             DWORD srcval1,srcval2;
723             srcval1=srcpixel[0];
724             FLIP_DWORD(&srcval1);
725             dstpixel[0]=((srcval1 <<  7) & 0x7c00) | /* l1 */
726                         ((srcval1 >>  6) & 0x03e0) | /* g1 */
727                         ((srcval1 >> 19) & 0x001f);  /* h1 */
728             srcval2=srcpixel[1];
729             FLIP_DWORD(&srcval2);
730             dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
731                         ((srcval2 <<  2) & 0x03e0) | /* g2 */
732                         ((srcval2 >> 11) & 0x001f);  /* h2 */
733             srcval1=srcpixel[2];
734             FLIP_DWORD(&srcval1);
735             dstpixel[2]=((srcval2 >>  9) & 0x7c00) | /* l3 */
736                         ((srcval2 >> 22) & 0x03e0) | /* g3 */
737                         ((srcval1 >>  3) & 0x001f);  /* h3 */
738             dstpixel[3]=((srcval1 >>  1) & 0x7c00) | /* l4 */
739                         ((srcval1 >> 14) & 0x03e0) | /* g4 */
740                         ((srcval1 >> 27) & 0x001f);  /* h4 */
741             srcpixel+=3;
742             dstpixel+=4;
743         }
744         /* And now up to 3 odd pixels */
745         if(oddwidth) {
746             memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD));
747             srcbyte = (LPBYTE)srcarray;
748             for (x=0; x<oddwidth; x++) {
749                 WORD dstval;
750                 FLIP_DWORD(srcarray+x);
751                 dstval =((srcbyte[0] << 7) & 0x7c00);    /* l */
752                 dstval|=((srcbyte[1] << 2) & 0x03e0);    /* g */
753                 dstval|=((srcbyte[2] >> 3) & 0x001f);    /* h */
754                 *dstpixel++=dstval;
755                 srcbyte+=3;
756             }
757         }
758         srcbits = (const char*)srcbits + srclinebytes;
759         dstbits = (char*)dstbits + dstlinebytes;
760     }
761 }
762
763 static void convert_888_to_565_asis_src_byteswap(int width, int height,
764                                                  const void* srcbits, int srclinebytes,
765                                                  void* dstbits, int dstlinebytes)
766 {
767     const DWORD* srcpixel;
768     const BYTE* srcbyte;
769     WORD* dstpixel;
770     DWORD srcarray[3];
771     int x,y;
772     int oddwidth;
773
774     oddwidth=width & 3;
775     width=width/4;
776     for (y=0; y<height; y++) {
777         srcpixel=srcbits;
778         dstpixel=dstbits;
779         for (x=0; x<width; x++) {
780             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
781             DWORD srcval1,srcval2;
782             srcval1=srcpixel[0];
783             FLIP_DWORD(&srcval1);
784             dstpixel[0]=((srcval1 >>  3) & 0x001f) | /* l1 */
785                         ((srcval1 >>  5) & 0x07e0) | /* g1 */
786                         ((srcval1 >>  8) & 0xf800);  /* h1 */
787             srcval2=srcpixel[1];
788             FLIP_DWORD(&srcval2);
789             dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
790                         ((srcval2 <<  3) & 0x07e0) | /* g2 */
791                         ( srcval2        & 0xf800);  /* h2 */
792             srcval1=srcpixel[2];
793             FLIP_DWORD(&srcval1);
794             dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
795                         ((srcval2 >> 21) & 0x07e0) | /* g3 */
796                         ((srcval1 <<  8) & 0xf800);  /* h3 */
797             dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
798                         ((srcval1 >> 13) & 0x07e0) | /* g4 */
799                         ((srcval1 >> 16) & 0xf800);  /* h4 */
800             srcpixel+=3;
801             dstpixel+=4;
802         }
803         /* And now up to 3 odd pixels */
804         if(oddwidth) {
805             memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD));
806             srcbyte = (LPBYTE)srcarray;
807             for (x=0; x<oddwidth; x++) {
808                 WORD dstval;
809                 FLIP_DWORD(srcarray+x);
810                 dstval =((srcbyte[0] >> 3) & 0x001f);    /* l */
811                 dstval|=((srcbyte[1] << 3) & 0x07e0);    /* g */
812                 dstval|=((srcbyte[2] << 8) & 0xf800);    /* h */
813                 *dstpixel++=dstval;
814                 srcbyte+=3;
815             }
816         }
817         srcbits = (const char*)srcbits + srclinebytes;
818         dstbits = (char*)dstbits + dstlinebytes;
819     }
820 }
821
822 static void convert_888_to_565_reverse_src_byteswap(int width, int height,
823                                                     const void* srcbits, int srclinebytes,
824                                                     void* dstbits, int dstlinebytes)
825 {
826     const DWORD* srcpixel;
827     const BYTE* srcbyte;
828     WORD* dstpixel;
829     DWORD srcarray[3];
830     int x,y;
831     int oddwidth;
832
833     oddwidth=width & 3;
834     width=width/4;
835     for (y=0; y<height; y++) {
836         srcpixel=srcbits;
837         dstpixel=dstbits;
838         for (x=0; x<width; x++) {
839             /* Do 4 pixels at a time: 3 dwords in and 4 words out */
840             DWORD srcval1,srcval2;
841             srcval1=srcpixel[0];
842             FLIP_DWORD(&srcval1);
843             dstpixel[0]=((srcval1 <<  8) & 0xf800) | /* l1 */
844                         ((srcval1 >>  5) & 0x07e0) | /* g1 */
845                         ((srcval1 >> 19) & 0x001f);  /* h1 */
846             srcval2=srcpixel[1];
847             FLIP_DWORD(&srcval2);
848             dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
849                         ((srcval2 <<  3) & 0x07e0) | /* g2 */
850                         ((srcval2 >> 11) & 0x001f);  /* h2 */
851             srcval1=srcpixel[2];
852             FLIP_DWORD(&srcval1);
853             dstpixel[2]=((srcval2 >>  8) & 0xf800) | /* l3 */
854                         ((srcval2 >> 21) & 0x07e0) | /* g3 */
855                         ((srcval1 >>  3) & 0x001f);  /* h3 */
856             dstpixel[3]=(srcval1         & 0xf800) | /* l4 */
857                         ((srcval1 >> 13) & 0x07e0) | /* g4 */
858                         ((srcval1 >> 27) & 0x001f);  /* h4 */
859             srcpixel+=3;
860             dstpixel+=4;
861         }
862         /* And now up to 3 odd pixels */
863         if(oddwidth) {
864             memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD));
865             srcbyte = (LPBYTE)srcarray;
866             for (x=0; x<oddwidth; x++) {
867                 WORD dstval;
868                 FLIP_DWORD(srcarray+x);
869                 dstval =((srcbyte[0] << 8) & 0xf800);    /* l */
870                 dstval|=((srcbyte[1] << 3) & 0x07e0);    /* g */
871                 dstval|=((srcbyte[2] >> 3) & 0x001f);    /* h */
872                 *dstpixel++=dstval;
873                 srcbyte+=3;
874             }
875         }
876         srcbits = (const char*)srcbits + srclinebytes;
877         dstbits = (char*)dstbits + dstlinebytes;
878     }
879 }
880
881 static void convert_888_to_0888_asis_src_byteswap(int width, int height,
882                                                   const void* srcbits, int srclinebytes,
883                                                   void* dstbits, int dstlinebytes)
884 {
885     const DWORD* srcpixel;
886     DWORD* dstpixel;
887     DWORD srcarray[3];
888     int x,y;
889     int oddwidth;
890
891     oddwidth=width & 3;
892     width=width/4;
893     for (y=0; y<height; y++) {
894         srcpixel=srcbits;
895         dstpixel=dstbits;
896         for (x=0; x<width; x++) {
897             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
898             DWORD srcval1,srcval2;
899             srcval1=srcpixel[0];
900             FLIP_DWORD(&srcval1);
901             dstpixel[0]=( srcval1        & 0x00ffffff);  /* h1, g1, l1 */
902             srcval2=srcpixel[1];
903             FLIP_DWORD(&srcval2);
904             dstpixel[1]=( srcval1 >> 24) |              /* l2 */
905                         ((srcval2 <<  8) & 0x00ffff00); /* h2, g2 */
906             srcval1=srcpixel[2];
907             FLIP_DWORD(&srcval1);
908             dstpixel[2]=( srcval2 >> 16) |              /* g3, l3 */
909                         ((srcval1 << 16) & 0x00ff0000); /* h3 */
910             dstpixel[3]=( srcval1 >>  8);               /* h4, g4, l4 */
911             srcpixel+=3;
912             dstpixel+=4;
913         }
914         /* And now up to 3 odd pixels */
915         if(oddwidth) {
916             memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD));
917             srcpixel = srcarray;
918             for (x=0; x<oddwidth; x++) {
919                 DWORD srcval;
920                 FLIP_DWORD(srcarray+x);
921                 srcval=*srcpixel;
922                 srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
923                 *dstpixel++=( srcval         & 0x00ffffff); /* h, g, l */
924             }
925         }
926         srcbits = (const char*)srcbits + srclinebytes;
927         dstbits = (char*)dstbits + dstlinebytes;
928     }
929 }
930
931 static void convert_888_to_0888_reverse_src_byteswap(int width, int height,
932                                                      const void* srcbits, int srclinebytes,
933                                                      void* dstbits, int dstlinebytes)
934 {
935     const DWORD* srcpixel;
936     DWORD* dstpixel;
937     DWORD srcarray[3];
938     int x,y;
939     int oddwidth;
940
941     oddwidth=width & 3;
942     width=width/4;
943     for (y=0; y<height; y++) {
944         srcpixel=srcbits;
945         dstpixel=dstbits;
946         for (x=0; x<width; x++) {
947             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
948             DWORD srcval1,srcval2;
949
950             srcval1=srcpixel[0];
951             FLIP_DWORD(&srcval1);
952             dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
953                         ( srcval1        & 0x00ff00) | /* g1 */
954                         ((srcval1 << 16) & 0xff0000);  /* l1 */
955             srcval2=srcpixel[1];
956             FLIP_DWORD(&srcval2);
957             dstpixel[1]=((srcval1 >>  8) & 0xff0000) | /* l2 */
958                         ((srcval2 <<  8) & 0x00ff00) | /* g2 */
959                         ((srcval2 >>  8) & 0x0000ff);  /* h2 */
960             srcval1=srcpixel[2];
961             FLIP_DWORD(&srcval1);
962             dstpixel[2]=( srcval2        & 0xff0000) | /* l3 */
963                         ((srcval2 >> 16) & 0x00ff00) | /* g3 */
964                         ( srcval1        & 0x0000ff);  /* h3 */
965             dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
966                         ((srcval1 >>  8) & 0x00ff00) | /* g4 */
967                         ((srcval1 <<  8) & 0xff0000);  /* l4 */
968             srcpixel+=3;
969             dstpixel+=4;
970         }
971         /* And now up to 3 odd pixels */
972         if(oddwidth) {
973             memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD));
974             srcpixel = srcarray;
975             for (x=0; x<oddwidth; x++) {
976                 DWORD srcval;
977                 FLIP_DWORD(srcarray+x);
978                 srcval=*srcpixel;
979                 srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
980                 *dstpixel++=((srcval  >> 16) & 0x0000ff) | /* h */
981                             ( srcval         & 0x00ff00) | /* g */
982                             ((srcval  << 16) & 0xff0000);  /* l */
983             }
984         }
985         srcbits = (const char*)srcbits + srclinebytes;
986         dstbits = (char*)dstbits + dstlinebytes;
987     }
988 }
989
990 static void convert_rgb888_to_any0888_src_byteswap(int width, int height,
991                                                    const void* srcbits, int srclinebytes,
992                                                    void* dstbits, int dstlinebytes,
993                                                    DWORD rdst, DWORD gdst, DWORD bdst)
994 {
995     int rLeftShift,gLeftShift,bLeftShift;
996     const DWORD* srcpixel;
997     DWORD* dstpixel;
998     int x,y;
999     DWORD srcarray[3];
1000
1001     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1002     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1003     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1004     for (y=0; y<height; y++) {
1005         srcpixel=srcbits;
1006         dstpixel=dstbits;
1007         for (x=0; x<width/4; x++) {
1008             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1009             DWORD srcval1, srcval2;
1010             srcval1=*srcpixel++;
1011             *dstpixel++=(((srcval1 >> 24) & 0xff) << bLeftShift) | /* b1 */
1012                         (((srcval1 >> 16) & 0xff) << gLeftShift) | /* g1 */
1013                         (((srcval1 >>  8) & 0xff) << rLeftShift);  /* r1 */
1014             srcval2=*srcpixel++;
1015             *dstpixel++=(((srcval1 >>  0) & 0xff) << bLeftShift) | /* b2 */
1016                         (((srcval2 >> 24) & 0xff) << gLeftShift) | /* g2 */
1017                         (((srcval2 >> 16) & 0xff) << rLeftShift);  /* r2 */
1018             srcval1=*srcpixel++;
1019             *dstpixel++=(((srcval2 >>  8) & 0xff) << bLeftShift) | /* b3 */
1020                         (((srcval2 >>  0) & 0xff) << gLeftShift) | /* g3 */
1021                         (((srcval1 >> 24) & 0xff) << rLeftShift);  /* r3 */
1022             *dstpixel++=(((srcval1 >> 16) & 0xff) << bLeftShift) | /* b4 */
1023                         (((srcval1 >>  8) & 0xff) << gLeftShift) | /* g4 */
1024                         (((srcval1 >>  0) & 0xff) << rLeftShift);  /* r4 */
1025         }
1026         /* And now up to 3 odd pixels */
1027         if(width&3) {
1028             memcpy(srcarray,srcpixel,width&3*sizeof(DWORD));
1029             srcpixel = srcarray;
1030             for (x=0; x < (width&3); x++) {
1031                 DWORD srcval;
1032                 FLIP_DWORD(srcarray+x);
1033                 srcval=*srcpixel;
1034                 srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
1035                 *dstpixel++=(((srcval >>  0) & 0xff) << bLeftShift) | /* b */
1036                             (((srcval >>  8) & 0xff) << gLeftShift) | /* g */
1037                             (((srcval >> 16) & 0xff) << rLeftShift);  /* r */
1038             }
1039         }
1040         srcbits = (const char*)srcbits + srclinebytes;
1041         dstbits = (char*)dstbits + dstlinebytes;
1042     }
1043 }
1044
1045 static void convert_bgr888_to_any0888_src_byteswap(int width, int height,
1046                                                    const void* srcbits, int srclinebytes,
1047                                                    void* dstbits, int dstlinebytes,
1048                                                    DWORD rdst, DWORD gdst, DWORD bdst)
1049 {
1050     int rLeftShift,gLeftShift,bLeftShift;
1051     const DWORD* srcpixel;
1052     DWORD* dstpixel;
1053     int x,y;
1054     DWORD srcarray[3];
1055
1056     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1057     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1058     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1059     for (y=0; y<height; y++) {
1060         srcpixel=srcbits;
1061         dstpixel=dstbits;
1062         for (x=0; x<width/4; x++) {
1063             /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1064             DWORD srcval1, srcval2;
1065             srcval1=*srcpixel++;
1066             *dstpixel++=(((srcval1 >> 24) & 0xff) << rLeftShift) | /* r1 */
1067                         (((srcval1 >> 16) & 0xff) << gLeftShift) | /* g1 */
1068                         (((srcval1 >>  8) & 0xff) << bLeftShift);  /* b1 */
1069             srcval2=*srcpixel++;
1070             *dstpixel++=(((srcval1 >>  0) & 0xff) << rLeftShift) | /* r2 */
1071                         (((srcval2 >> 24) & 0xff) << gLeftShift) | /* g2 */
1072                         (((srcval2 >> 16) & 0xff) << bLeftShift);  /* b2 */
1073             srcval1=*srcpixel++;
1074             *dstpixel++=(((srcval2 >>  8) & 0xff) << rLeftShift) | /* r3 */
1075                         (((srcval2 >>  0) & 0xff) << gLeftShift) | /* g3 */
1076                         (((srcval1 >> 24) & 0xff) << bLeftShift);  /* b3 */
1077             *dstpixel++=(((srcval1 >> 16) & 0xff) << rLeftShift) | /* r4 */
1078                         (((srcval1 >>  8) & 0xff) << gLeftShift) | /* g4 */
1079                         (((srcval1 >>  0) & 0xff) << bLeftShift);  /* b4 */
1080         }
1081         /* And now up to 3 odd pixels */
1082         if(width&3) {
1083             memcpy(srcarray,srcpixel,width&3*sizeof(DWORD));
1084             srcpixel = srcarray;
1085             for (x=0; x < (width&3); x++) {
1086                 DWORD srcval;
1087                 FLIP_DWORD(srcarray+x);
1088                 srcval=*srcpixel;
1089                 srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
1090                 *dstpixel++=(((srcval >>  0) & 0xff) << rLeftShift) | /* r */
1091                             (((srcval >>  8) & 0xff) << gLeftShift) | /* g */
1092                             (((srcval >> 16) & 0xff) << bLeftShift);  /* b */
1093             }
1094         }
1095         srcbits = (const char*)srcbits + srclinebytes;
1096         dstbits = (char*)dstbits + dstlinebytes;
1097     }
1098 }
1099
1100
1101 /*
1102  * 32 bit conversions
1103  */
1104
1105 static void convert_0888_asis_src_byteswap(int width, int height,
1106                                            const void* srcbits, int srclinebytes,
1107                                            void* dstbits, int dstlinebytes)
1108 {
1109     int x, y;
1110
1111     for (y=0; y<height; y++) {
1112         for(x = 0; x < width; x++) {
1113             DWORD srcval = *((const DWORD*)srcbits + x);
1114             *((DWORD*)dstbits + x) = ((srcval << 24) & 0xff000000) |
1115                                      ((srcval <<  8) & 0x00ff0000) |
1116                                      ((srcval >>  8) & 0x0000ff00) |
1117                                      ((srcval >> 24) & 0x000000ff);
1118         }
1119         srcbits = (const char*)srcbits + srclinebytes;
1120         dstbits = (char*)dstbits + dstlinebytes;
1121     }
1122 }
1123
1124 static void convert_0888_reverse_src_byteswap(int width, int height,
1125                                               const void* srcbits, int srclinebytes,
1126                                               void* dstbits, int dstlinebytes)
1127 {
1128     const DWORD* srcpixel;
1129     DWORD* dstpixel;
1130     int x,y;
1131
1132     for (y=0; y<height; y++) {
1133         srcpixel=srcbits;
1134         dstpixel=dstbits;
1135         for (x=0; x<width; x++) {
1136             DWORD srcval;
1137             srcval=*srcpixel++;
1138             *dstpixel++=((srcval >> 8) & 0x00ffffff);
1139         }
1140         srcbits = (const char*)srcbits + srclinebytes;
1141         dstbits = (char*)dstbits + dstlinebytes;
1142     }
1143 }
1144
1145 static void convert_0888_any_src_byteswap(int width, int height,
1146                                           const void* srcbits, int srclinebytes,
1147                                           DWORD rsrc, DWORD gsrc, DWORD bsrc,
1148                                           void* dstbits, int dstlinebytes,
1149                                           DWORD rdst, DWORD gdst, DWORD bdst)
1150 {
1151     int rRightShift,gRightShift,bRightShift;
1152     int rLeftShift,gLeftShift,bLeftShift;
1153     const DWORD* srcpixel;
1154     DWORD* dstpixel;
1155     int x,y;
1156
1157     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1158     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1159     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1160     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1161     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1162     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1163     for (y=0; y<height; y++) {
1164         srcpixel=srcbits;
1165         dstpixel=dstbits;
1166         for (x=0; x<width; x++) {
1167             DWORD srcval;
1168             srcval=*srcpixel++;
1169             FLIP_DWORD(&srcval);
1170             *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1171                         (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1172                         (((srcval >> bRightShift) & 0xff) << bLeftShift);
1173         }
1174         srcbits = (const char*)srcbits + srclinebytes;
1175         dstbits = (char*)dstbits + dstlinebytes;
1176     }
1177 }
1178
1179 static void convert_0888_to_555_asis_src_byteswap(int width, int height,
1180                                                   const void* srcbits, int srclinebytes,
1181                                                   void* dstbits, int dstlinebytes)
1182 {
1183     const DWORD* srcpixel;
1184     WORD* dstpixel;
1185     int x,y;
1186
1187     for (y=0; y<height; y++) {
1188         srcpixel=srcbits;
1189         dstpixel=dstbits;
1190         for (x=0; x<width; x++) {
1191             DWORD srcval;
1192             srcval=*srcpixel++;
1193             *dstpixel++=((srcval >>  1) & 0x7c00) | /* h */
1194                         ((srcval >> 14) & 0x03e0) | /* g */
1195                         ((srcval >> 27) & 0x001f);  /* l */
1196         }
1197         srcbits = (const char*)srcbits + srclinebytes;
1198         dstbits = (char*)dstbits + dstlinebytes;
1199     }
1200 }
1201
1202 static void convert_0888_to_555_reverse_src_byteswap(int width, int height,
1203                                                      const void* srcbits, int srclinebytes,
1204                                                      void* dstbits, int dstlinebytes)
1205 {
1206     const DWORD* srcpixel;
1207     WORD* dstpixel;
1208     int x,y;
1209
1210     for (y=0; y<height; y++) {
1211         srcpixel=srcbits;
1212         dstpixel=dstbits;
1213         for (x=0; x<width; x++) {
1214             DWORD srcval;
1215             srcval=*srcpixel++;
1216             *dstpixel++=((srcval >> 11) & 0x001f) | /* h */
1217                         ((srcval >> 14) & 0x03e0) | /* g */
1218                         ((srcval >> 17) & 0x7c00);  /* l */
1219         }
1220         srcbits = (const char*)srcbits + srclinebytes;
1221         dstbits = (char*)dstbits + dstlinebytes;
1222     }
1223 }
1224
1225 static void convert_0888_to_565_asis_src_byteswap(int width, int height,
1226                                                   const void* srcbits, int srclinebytes,
1227                                                   void* dstbits, int dstlinebytes)
1228 {
1229     const DWORD* srcpixel;
1230     WORD* dstpixel;
1231     int x,y;
1232
1233     for (y=0; y<height; y++) {
1234         srcpixel=srcbits;
1235         dstpixel=dstbits;
1236         for (x=0; x<width; x++) {
1237             DWORD srcval;
1238             srcval=*srcpixel++;
1239             *dstpixel++=((srcval >>  0) & 0xf800) | /* h */
1240                         ((srcval >> 13) & 0x07e0) | /* g */
1241                         ((srcval >> 27) & 0x001f);  /* l */
1242         }
1243         srcbits = (const char*)srcbits + srclinebytes;
1244         dstbits = (char*)dstbits + dstlinebytes;
1245     }
1246 }
1247
1248 static void convert_0888_to_565_reverse_src_byteswap(int width, int height,
1249                                                      const void* srcbits, int srclinebytes,
1250                                                      void* dstbits, int dstlinebytes)
1251 {
1252     const DWORD* srcpixel;
1253     WORD* dstpixel;
1254     int x,y;
1255
1256     for (y=0; y<height; y++) {
1257         srcpixel=srcbits;
1258         dstpixel=dstbits;
1259         for (x=0; x<width; x++) {
1260             DWORD srcval;
1261             srcval=*srcpixel++;
1262             *dstpixel++=((srcval >> 11) & 0x001f) | /* h */
1263                         ((srcval >> 13) & 0x07e0) | /* g */
1264                         ((srcval >> 16) & 0xf800);  /* l */
1265         }
1266         srcbits = (const char*)srcbits + srclinebytes;
1267         dstbits = (char*)dstbits + dstlinebytes;
1268     }
1269 }
1270
1271 static void convert_any0888_to_5x5_src_byteswap(int width, int height,
1272                                                 const void* srcbits, int srclinebytes,
1273                                                 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1274                                                 void* dstbits, int dstlinebytes,
1275                                                 WORD rdst, WORD gdst, WORD bdst)
1276 {
1277     int rRightShift,gRightShift,bRightShift;
1278     int rLeftShift,gLeftShift,bLeftShift;
1279     const DWORD* srcpixel;
1280     WORD* dstpixel;
1281     int x,y;
1282
1283     /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1284      * contains 0x11223344.
1285      * - first we shift 0x11223344 right by rRightShift to bring the most
1286      *   significant bits of the red components in the bottom 5 (or 6) bits
1287      *   -> 0x4488c
1288      * - then we remove non red bits by anding with the modified rdst (0x1f)
1289      *   -> 0x0c
1290      * - finally shift these bits left by rLeftShift so that they end up in
1291      *   the right place
1292      *   -> 0x3000
1293      */
1294     rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1295     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1296     gRightShift+=(gdst==0x07e0?2:3);
1297     bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1298
1299     rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1300     rdst=rdst >> rLeftShift;
1301     gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1302     gdst=gdst >> gLeftShift;
1303     bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1304     bdst=bdst >> bLeftShift;
1305
1306     for (y=0; y<height; y++) {
1307         srcpixel=srcbits;
1308         dstpixel=dstbits;
1309         for (x=0; x<width; x++) {
1310             DWORD srcval;
1311             srcval=*srcpixel++;
1312             FLIP_DWORD(&srcval);
1313             *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1314                         (((srcval >> gRightShift) & gdst) << gLeftShift) |
1315                         (((srcval >> bRightShift) & bdst) << bLeftShift);
1316         }
1317         srcbits = (const char*)srcbits + srclinebytes;
1318         dstbits = (char*)dstbits + dstlinebytes;
1319     }
1320 }
1321
1322 static void convert_0888_to_888_asis_src_byteswap(int width, int height,
1323                                                   const void* srcbits, int srclinebytes,
1324                                                   void* dstbits, int dstlinebytes)
1325 {
1326     const DWORD* srcpixel;
1327     DWORD* dstpixel;
1328     BYTE* dstbyte;
1329     int x,y;
1330     int oddwidth;
1331
1332     oddwidth=width & 3;
1333     width=width/4;
1334     for (y=0; y<height; y++) {
1335         srcpixel=srcbits;
1336         dstpixel=dstbits;
1337         for (x=0; x<width; x++) {
1338             /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1339             DWORD srcval1, srcval2;
1340             srcval1 = *srcpixel++;
1341             srcval2 = *srcpixel++;
1342             *dstpixel++= ((srcval1 >> 24) & 0x000000ff) | /* l1 */
1343                          ((srcval1 >>  8) & 0x0000ff00) | /* g1 */
1344                          ((srcval1 <<  8) & 0x00ff0000) | /* h1 */
1345                          ( srcval2        & 0xff000000);  /* l2 */
1346             srcval1 = *srcpixel++;
1347             *dstpixel++= ((srcval2 >> 16) & 0x000000ff) | /* g2 */
1348                          ( srcval2        & 0x0000ff00) | /* h2 */
1349                          ((srcval1 >>  8) & 0x00ff0000) | /* l3 */
1350                          ((srcval1 <<  8) & 0xff000000);  /* g3 */
1351             srcval2 = *srcpixel++;
1352             *dstpixel++= ((srcval1 >>  8) & 0x000000ff) | /* h3 */
1353                          ((srcval2 >> 16) & 0x0000ff00) | /* l4 */
1354                          ( srcval2        & 0x00ff0000) | /* g4 */
1355                          ((srcval2 << 16) & 0xff000000);  /* h4 */
1356         }
1357         /* And now up to 3 odd pixels */
1358         dstbyte=(BYTE*)dstpixel;
1359         for (x=0; x<oddwidth; x++) {
1360             DWORD srcval;
1361             srcval=*srcpixel++;
1362             FLIP_DWORD(&srcval);
1363             *((WORD*)dstbyte)=srcval;                   /* h, g */
1364             dstbyte+=sizeof(WORD);
1365             *dstbyte++=srcval >> 16;                    /* l */
1366         }
1367         srcbits = (const char*)srcbits + srclinebytes;
1368         dstbits = (char*)dstbits + dstlinebytes;
1369     }
1370 }
1371
1372 static void convert_0888_to_888_reverse_src_byteswap(int width, int height,
1373                                                      const void* srcbits, int srclinebytes,
1374                                                      void* dstbits, int dstlinebytes)
1375 {
1376     const DWORD* srcpixel;
1377     DWORD* dstpixel;
1378     BYTE* dstbyte;
1379     int x,y;
1380     int oddwidth;
1381
1382     oddwidth=width & 3;
1383     width=width/4;
1384     for (y=0; y<height; y++) {
1385         srcpixel=srcbits;
1386         dstpixel=dstbits;
1387         for (x=0; x<width; x++) {
1388             /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1389             DWORD srcval1,srcval2;
1390             srcval1=*srcpixel++;
1391             srcval2=    ((srcval1 >> 8 ) & 0x00ffffff); /* l1, g1, h1 */
1392             srcval1=*srcpixel++;
1393             *dstpixel++=srcval2 |
1394                         ((srcval1 << 16) & 0xff000000);  /* h2 */
1395             srcval2=    ((srcval1 >> 16) & 0x0000ffff);  /* l2, g2 */
1396             srcval1=*srcpixel++;
1397             *dstpixel++=srcval2 |
1398                         ((srcval1 <<  8) & 0xffff0000);  /* g3, h3 */
1399             srcval2=    ((srcval1 >> 24) & 0x000000ff);  /* l3 */
1400             srcval1=*srcpixel++;
1401             *dstpixel++=srcval2 |
1402                         srcval1;                         /* l4, g4, h4 */
1403         }
1404         /* And now up to 3 odd pixels */
1405         dstbyte=(BYTE*)dstpixel;
1406         for (x=0; x<oddwidth; x++) {
1407             DWORD srcval;
1408             srcval=*srcpixel++;
1409             *((WORD*)dstbyte)=((srcval >> 8) & 0xffff); /* g, h */
1410             dstbyte+=sizeof(WORD);
1411             *dstbyte++= srcval >> 24;                     /* l */
1412         }
1413         srcbits = (const char*)srcbits + srclinebytes;
1414         dstbits = (char*)dstbits + dstlinebytes;
1415     }
1416 }
1417
1418 static void convert_any0888_to_rgb888_src_byteswap(int width, int height,
1419                                                    const void* srcbits, int srclinebytes,
1420                                                    DWORD rsrc, DWORD gsrc, DWORD bsrc,
1421                                                    void* dstbits, int dstlinebytes)
1422 {
1423     int rRightShift,gRightShift,bRightShift;
1424     const DWORD* srcpixel;
1425     BYTE* dstpixel;
1426     int x,y;
1427
1428     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1429     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1430     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1431     for (y=0; y<height; y++) {
1432         srcpixel=srcbits;
1433         dstpixel=dstbits;
1434         for (x=0; x<width; x++) {
1435             DWORD srcval;
1436             srcval=*srcpixel++;
1437             FLIP_DWORD(&srcval);
1438             dstpixel[0]=(srcval >> bRightShift); /* b */
1439             dstpixel[1]=(srcval >> gRightShift); /* g */
1440             dstpixel[2]=(srcval >> rRightShift); /* r */
1441             dstpixel+=3;
1442         }
1443         srcbits = (const char*)srcbits + srclinebytes;
1444         dstbits = (char*)dstbits + dstlinebytes;
1445     }
1446 }
1447
1448 static void convert_any0888_to_bgr888_src_byteswap(int width, int height,
1449                                                    const void* srcbits, int srclinebytes,
1450                                                    DWORD rsrc, DWORD gsrc, DWORD bsrc,
1451                                                    void* dstbits, int dstlinebytes)
1452 {
1453     int rRightShift,gRightShift,bRightShift;
1454     const DWORD* srcpixel;
1455     BYTE* dstpixel;
1456     int x,y;
1457
1458     rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1459     gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1460     bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1461     for (y=0; y<height; y++) {
1462         srcpixel=srcbits;
1463         dstpixel=dstbits;
1464         for (x=0; x<width; x++) {
1465             DWORD srcval;
1466             srcval=*srcpixel++;
1467             FLIP_DWORD(&srcval);
1468             dstpixel[0]=(srcval >> rRightShift); /* r */
1469             dstpixel[1]=(srcval >> gRightShift); /* g */
1470             dstpixel[2]=(srcval >> bRightShift); /* b */
1471             dstpixel+=3;
1472         }
1473         srcbits = (const char*)srcbits + srclinebytes;
1474         dstbits = (char*)dstbits + dstlinebytes;
1475     }
1476 }
1477
1478
1479 const dib_conversions dib_src_byteswap = {
1480     convert_5x5_asis_src_byteswap,
1481     convert_555_reverse_src_byteswap,
1482     convert_555_to_565_asis_src_byteswap,
1483     convert_555_to_565_reverse_src_byteswap,
1484     convert_555_to_888_asis_src_byteswap,
1485     convert_555_to_888_reverse_src_byteswap,
1486     convert_555_to_0888_asis_src_byteswap,
1487     convert_555_to_0888_reverse_src_byteswap,
1488     convert_5x5_to_any0888_src_byteswap,
1489     convert_565_reverse_src_byteswap,
1490     convert_565_to_555_asis_src_byteswap,
1491     convert_565_to_555_reverse_src_byteswap,
1492     convert_565_to_888_asis_src_byteswap,
1493     convert_565_to_888_reverse_src_byteswap,
1494     convert_565_to_0888_asis_src_byteswap,
1495     convert_565_to_0888_reverse_src_byteswap,
1496     convert_888_asis_src_byteswap,
1497     convert_888_reverse_src_byteswap,
1498     convert_888_to_555_asis_src_byteswap,
1499     convert_888_to_555_reverse_src_byteswap,
1500     convert_888_to_565_asis_src_byteswap,
1501     convert_888_to_565_reverse_src_byteswap,
1502     convert_888_to_0888_asis_src_byteswap,
1503     convert_888_to_0888_reverse_src_byteswap,
1504     convert_rgb888_to_any0888_src_byteswap,
1505     convert_bgr888_to_any0888_src_byteswap,
1506     convert_0888_asis_src_byteswap,
1507     convert_0888_reverse_src_byteswap,
1508     convert_0888_any_src_byteswap,
1509     convert_0888_to_555_asis_src_byteswap,
1510     convert_0888_to_555_reverse_src_byteswap,
1511     convert_0888_to_565_asis_src_byteswap,
1512     convert_0888_to_565_reverse_src_byteswap,
1513     convert_any0888_to_5x5_src_byteswap,
1514     convert_0888_to_888_asis_src_byteswap,
1515     convert_0888_to_888_reverse_src_byteswap,
1516     convert_any0888_to_rgb888_src_byteswap,
1517     convert_any0888_to_bgr888_src_byteswap
1518 };