DIB Engine: fix MapModes for xxxBlt
[wine/hacks.git] / dlls / winex11.drv / dib_convert.c
blobc34e16c35d1189462f7734727b7bff189e992e53
1 /*
2 * DIB conversion routinues for cases where the source and destination
3 * have the same byte order.
5 * Copyright (C) 2001 Francois Gouget
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <stdlib.h>
26 #include "windef.h"
27 #include "x11drv.h"
30 /***********************************************************************
31 * X11DRV_DIB_Convert_*
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 at coordinates (x,y) then this is:
44 * image_ptr+x*bytes_per_pixel+y*bytes_per_line
45 * (with further adjustments for top-down/bottom-up images)
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.
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.
69 * 15 bit conversions
72 static void convert_5x5_asis(int width, int height,
73 const void* srcbits, int srclinebytes,
74 void* dstbits, int dstlinebytes)
76 int y;
78 width *= 2;
80 if (srclinebytes == dstlinebytes && srclinebytes == width)
82 memcpy(dstbits, srcbits, height * width);
83 return;
86 for (y=0; y<height; y++) {
87 memcpy(dstbits, srcbits, width);
88 srcbits = (const char*)srcbits + srclinebytes;
89 dstbits = (char*)dstbits + dstlinebytes;
94 static void convert_555_reverse(int width, int height,
95 const void* srcbits, int srclinebytes,
96 void* dstbits, int dstlinebytes)
98 const DWORD* srcpixel;
99 DWORD* dstpixel;
100 int x,y;
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 */
113 if (width&1) {
114 /* And then 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 */
121 srcbits = (const char*)srcbits + srclinebytes;
122 dstbits = (char*)dstbits + dstlinebytes;
126 static void convert_555_to_565_asis(int width, int height,
127 const void* srcbits, int srclinebytes,
128 void* dstbits, int dstlinebytes)
130 const DWORD* srcpixel;
131 DWORD* dstpixel;
132 int x,y;
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 */
145 if (width&1) {
146 /* And then 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 */
153 srcbits = (const char*)srcbits + srclinebytes;
154 dstbits = (char*)dstbits + dstlinebytes;
158 static void convert_555_to_565_reverse(int width, int height,
159 const void* srcbits, int srclinebytes,
160 void* dstbits, int dstlinebytes)
162 const DWORD* srcpixel;
163 DWORD* dstpixel;
164 int x,y;
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 */
178 if (width&1) {
179 /* And then 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 */
187 srcbits = (const char*)srcbits + srclinebytes;
188 dstbits = (char*)dstbits + dstlinebytes;
192 static void convert_555_to_888_asis(int width, int height,
193 const void* srcbits, int srclinebytes,
194 void* dstbits, int dstlinebytes)
196 const WORD* srcpixel;
197 BYTE* dstpixel;
198 int x,y;
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;
214 srcbits = (const char*)srcbits + srclinebytes;
215 dstbits = (char*)dstbits + dstlinebytes;
219 static void convert_555_to_888_reverse(int width, int height,
220 const void* srcbits, int srclinebytes,
221 void* dstbits, int dstlinebytes)
223 const WORD* srcpixel;
224 BYTE* dstpixel;
225 int x,y;
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;
241 srcbits = (const char*)srcbits + srclinebytes;
242 dstbits = (char*)dstbits + dstlinebytes;
246 static void convert_555_to_0888_asis(int width, int height,
247 const void* srcbits, int srclinebytes,
248 void* dstbits, int dstlinebytes)
250 const WORD* srcpixel;
251 DWORD* dstpixel;
252 int x,y;
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 */
267 srcbits = (const char*)srcbits + srclinebytes;
268 dstbits = (char*)dstbits + dstlinebytes;
272 static void convert_555_to_0888_reverse(int width, int height,
273 const void* srcbits, int srclinebytes,
274 void* dstbits, int dstlinebytes)
276 const WORD* srcpixel;
277 DWORD* dstpixel;
278 int x,y;
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 */
293 srcbits = (const char*)srcbits + srclinebytes;
294 dstbits = (char*)dstbits + dstlinebytes;
298 static void convert_5x5_to_any0888(int width, int height,
299 const void* srcbits, int srclinebytes,
300 WORD rsrc, WORD gsrc, WORD bsrc,
301 void* dstbits, int dstlinebytes,
302 DWORD rdst, DWORD gdst, DWORD bdst)
304 int rRightShift1,gRightShift1,bRightShift1;
305 int rRightShift2,gRightShift2,bRightShift2;
306 BYTE gMask1,gMask2;
307 int rLeftShift,gLeftShift,bLeftShift;
308 const WORD* srcpixel;
309 DWORD* dstpixel;
310 int x,y;
312 /* Note, the source pixel value is shifted left by 16 bits so that
313 * we know we will always have to shift right to extract the components.
315 rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
316 gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
317 bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
318 rRightShift2=rRightShift1+5;
319 gRightShift2=gRightShift1+5;
320 bRightShift2=bRightShift1+5;
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;
333 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
334 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
335 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
337 for (y=0; y<height; y++) {
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);
354 srcbits = (const char*)srcbits + srclinebytes;
355 dstbits = (char*)dstbits + dstlinebytes;
360 * 16 bits conversions
363 static void convert_565_reverse(int width, int height,
364 const void* srcbits, int srclinebytes,
365 void* dstbits, int dstlinebytes)
367 const DWORD* srcpixel;
368 DWORD* dstpixel;
369 int x,y;
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 */
382 if (width&1) {
383 /* And then 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 */
390 srcbits = (const char*)srcbits + srclinebytes;
391 dstbits = (char*)dstbits + dstlinebytes;
395 static void convert_565_to_555_asis(int width, int height,
396 const void* srcbits, int srclinebytes,
397 void* dstbits, int dstlinebytes)
399 const DWORD* srcpixel;
400 DWORD* dstpixel;
401 int x,y;
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 */
413 if (width&1) {
414 /* And then the odd pixel */
415 WORD srcval;
416 srcval=*((const WORD*)srcpixel);
417 *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
418 ( srcval & 0x001f); /* l */
420 srcbits = (const char*)srcbits + srclinebytes;
421 dstbits = (char*)dstbits + dstlinebytes;
425 static void convert_565_to_555_reverse(int width, int height,
426 const void* srcbits, int srclinebytes,
427 void* dstbits, int dstlinebytes)
429 const DWORD* srcpixel;
430 DWORD* dstpixel;
431 int x,y;
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 */
444 if (width&1) {
445 /* And then 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 */
452 srcbits = (const char*)srcbits + srclinebytes;
453 dstbits = (char*)dstbits + dstlinebytes;
457 static void convert_565_to_888_asis(int width, int height,
458 const void* srcbits, int srclinebytes,
459 void* dstbits, int dstlinebytes)
461 const WORD* srcpixel;
462 BYTE* dstpixel;
463 int x,y;
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;
479 srcbits = (const char*)srcbits + srclinebytes;
480 dstbits = (char*)dstbits + dstlinebytes;
484 static void convert_565_to_888_reverse(int width, int height,
485 const void* srcbits, int srclinebytes,
486 void* dstbits, int dstlinebytes)
488 const WORD* srcpixel;
489 BYTE* dstpixel;
490 int x,y;
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;
506 srcbits = (const char*)srcbits + srclinebytes;
507 dstbits = (char*)dstbits + dstlinebytes;
511 static void convert_565_to_0888_asis(int width, int height,
512 const void* srcbits, int srclinebytes,
513 void* dstbits, int dstlinebytes)
515 const WORD* srcpixel;
516 DWORD* dstpixel;
517 int x,y;
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 */
532 srcbits = (const char*)srcbits + srclinebytes;
533 dstbits = (char*)dstbits + dstlinebytes;
537 static void convert_565_to_0888_reverse(int width, int height,
538 const void* srcbits, int srclinebytes,
539 void* dstbits, int dstlinebytes)
541 const WORD* srcpixel;
542 DWORD* dstpixel;
543 int x,y;
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 */
558 srcbits = (const char*)srcbits + srclinebytes;
559 dstbits = (char*)dstbits + dstlinebytes;
565 * 24 bit conversions
568 static void convert_888_asis(int width, int height,
569 const void* srcbits, int srclinebytes,
570 void* dstbits, int dstlinebytes)
572 int y;
574 width *= 3;
576 if (srclinebytes == dstlinebytes && srclinebytes == width)
578 memcpy(dstbits, srcbits, height * width);
579 return;
582 for (y=0; y<height; y++) {
583 memcpy(dstbits, srcbits, width);
584 srcbits = (const char*)srcbits + srclinebytes;
585 dstbits = (char*)dstbits + dstlinebytes;
590 static void convert_888_reverse(int width, int height,
591 const void* srcbits, int srclinebytes,
592 void* dstbits, int dstlinebytes)
594 const BYTE* srcpixel;
595 BYTE* dstpixel;
596 int x,y;
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;
608 srcbits = (const char*)srcbits + srclinebytes;
609 dstbits = (char*)dstbits + dstlinebytes;
613 static void convert_888_to_555_asis(int width, int height,
614 const void* srcbits, int srclinebytes,
615 void* dstbits, int dstlinebytes)
617 const DWORD* srcpixel;
618 const BYTE* srcbyte;
619 WORD* dstpixel;
620 int x,y;
621 int oddwidth;
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;
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;
659 srcbits = (const char*)srcbits + srclinebytes;
660 dstbits = (char*)dstbits + dstlinebytes;
664 static void convert_888_to_555_reverse(int width, int height,
665 const void* srcbits, int srclinebytes,
666 void* dstbits, int dstlinebytes)
668 const DWORD* srcpixel;
669 const BYTE* srcbyte;
670 WORD* dstpixel;
671 int x,y;
672 int oddwidth;
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;
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;
710 srcbits = (const char*)srcbits + srclinebytes;
711 dstbits = (char*)dstbits + dstlinebytes;
715 static void convert_888_to_565_asis(int width, int height,
716 const void* srcbits, int srclinebytes,
717 void* dstbits, int dstlinebytes)
719 const DWORD* srcpixel;
720 const BYTE* srcbyte;
721 WORD* dstpixel;
722 int x,y;
723 int oddwidth;
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;
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;
761 srcbits = (const char*)srcbits + srclinebytes;
762 dstbits = (char*)dstbits + dstlinebytes;
766 static void convert_888_to_565_reverse(int width, int height,
767 const void* srcbits, int srclinebytes,
768 void* dstbits, int dstlinebytes)
770 const DWORD* srcpixel;
771 const BYTE* srcbyte;
772 WORD* dstpixel;
773 int x,y;
774 int oddwidth;
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;
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;
812 srcbits = (const char*)srcbits + srclinebytes;
813 dstbits = (char*)dstbits + dstlinebytes;
817 static void convert_888_to_0888_asis(int width, int height,
818 const void* srcbits, int srclinebytes,
819 void* dstbits, int dstlinebytes)
821 const DWORD* srcpixel;
822 DWORD* dstpixel;
823 int x,y;
824 int w1, w2, w3;
826 w1 = min( (INT_PTR)srcbits & 3, width);
827 w2 = ( width - w1) / 4;
828 w3 = ( width - w1) & 3;
829 for (y=0; y<height; y++) {
830 srcpixel=srcbits;
831 dstpixel=dstbits;
832 /* advance w1 pixels to make srcpixel 32 bit aligned */
833 srcpixel = (const DWORD*)((INT_PTR)srcpixel & ~3);
834 srcpixel += w1;
835 dstpixel += w1;
836 /* and do the w1 pixels */
837 x = w1;
838 if( x) {
839 dstpixel[ -1] = ( srcpixel[ -1] >> 8); /* h4, g4, l4 */
840 if( --x) {
841 dstpixel[ -2] = ( srcpixel[ -2] >> 16) | /* g3, l3 */
842 ((srcpixel[ -1] << 16) & 0x00ff0000); /* h3 */
843 if( --x) {
844 dstpixel[ -3] = ( srcpixel[ -3] >> 24) | /* l2 */
845 ((srcpixel[ -2] << 8) & 0x00ffff00); /* h2, g2 */
849 for (x=0; x < w2; x++) {
850 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
851 DWORD srcval1,srcval2;
852 srcval1=srcpixel[0];
853 dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
854 srcval2=srcpixel[1];
855 dstpixel[1]=( srcval1 >> 24) | /* l2 */
856 ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
857 srcval1=srcpixel[2];
858 dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */
859 ((srcval1 << 16) & 0x00ff0000); /* h3 */
860 dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */
861 srcpixel+=3;
862 dstpixel+=4;
864 /* do last w3 pixels */
865 x = w3;
866 if( x) {
867 dstpixel[0]=( srcpixel[0] & 0x00ffffff); /* h1, g1, l1 */
868 if( --x) {
869 dstpixel[1]=( srcpixel[0]>> 24) | /* l2 */
870 ((srcpixel[1]<< 8) & 0x00ffff00); /* h2, g2 */
871 if( --x) {
872 dstpixel[2]=( srcpixel[1]>> 16) | /* g3, l3 */
873 ((srcpixel[2]<< 16) & 0x00ff0000); /* h3 */
877 srcbits = (const char*)srcbits + srclinebytes;
878 dstbits = (char*)dstbits + dstlinebytes;
882 static void convert_888_to_0888_reverse(int width, int height,
883 const void* srcbits, int srclinebytes,
884 void* dstbits, int dstlinebytes)
886 const DWORD* srcpixel;
887 DWORD* dstpixel;
888 int x,y;
889 int w1, w2, w3;
891 w1 = min( (INT_PTR)srcbits & 3, width);
892 w2 = ( width - w1) / 4;
893 w3 = ( width - w1) & 3;
894 for (y=0; y<height; y++) {
895 srcpixel=srcbits;
896 dstpixel=dstbits;
897 /* advance w1 pixels to make srcpixel 32 bit aligned */
898 srcpixel = (const DWORD*)((INT_PTR)srcpixel & ~3);
899 srcpixel += w1;
900 dstpixel += w1;
901 /* and do the w1 pixels */
902 x = w1;
903 if( x) {
904 dstpixel[ -1]=((srcpixel[ -1] >> 24) & 0x0000ff) | /* h4 */
905 ((srcpixel[ -1] >> 8) & 0x00ff00) | /* g4 */
906 ((srcpixel[ -1] << 8) & 0xff0000); /* l4 */
907 if( --x) {
908 dstpixel[ -2]=( srcpixel[ -2] & 0xff0000) | /* l3 */
909 ((srcpixel[ -2] >> 16) & 0x00ff00) | /* g3 */
910 ( srcpixel[ -1] & 0x0000ff); /* h3 */
911 if( --x) {
912 dstpixel[ -3]=((srcpixel[ -3] >> 8) & 0xff0000) | /* l2 */
913 ((srcpixel[ -2] << 8) & 0x00ff00) | /* g2 */
914 ((srcpixel[ -2] >> 8) & 0x0000ff); /* h2 */
918 for (x=0; x < w2; x++) {
919 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
920 DWORD srcval1,srcval2;
922 srcval1=srcpixel[0];
923 dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
924 ( srcval1 & 0x00ff00) | /* g1 */
925 ((srcval1 << 16) & 0xff0000); /* l1 */
926 srcval2=srcpixel[1];
927 dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */
928 ((srcval2 << 8) & 0x00ff00) | /* g2 */
929 ((srcval2 >> 8) & 0x0000ff); /* h2 */
930 srcval1=srcpixel[2];
931 dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */
932 ((srcval2 >> 16) & 0x00ff00) | /* g3 */
933 ( srcval1 & 0x0000ff); /* h3 */
934 dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
935 ((srcval1 >> 8) & 0x00ff00) | /* g4 */
936 ((srcval1 << 8) & 0xff0000); /* l4 */
937 srcpixel+=3;
938 dstpixel+=4;
940 /* do last w3 pixels */
941 x = w3;
942 if( x) {
943 dstpixel[0]=((srcpixel[0] >> 16) & 0x0000ff) | /* h1 */
944 ( srcpixel[0] & 0x00ff00) | /* g1 */
945 ((srcpixel[0] << 16) & 0xff0000); /* l1 */
946 if( --x) {
947 dstpixel[1]=((srcpixel[0] >> 8) & 0xff0000) | /* l2 */
948 ((srcpixel[1] << 8) & 0x00ff00) | /* g2 */
949 ((srcpixel[1] >> 8) & 0x0000ff); /* h2 */
950 if( --x) {
951 dstpixel[2]=( srcpixel[1] & 0xff0000) | /* l3 */
952 ((srcpixel[1] >> 16) & 0x00ff00) | /* g3 */
953 ( srcpixel[2] & 0x0000ff); /* h3 */
957 srcbits = (const char*)srcbits + srclinebytes;
958 dstbits = (char*)dstbits + dstlinebytes;
962 static void convert_rgb888_to_any0888(int width, int height,
963 const void* srcbits, int srclinebytes,
964 void* dstbits, int dstlinebytes,
965 DWORD rdst, DWORD gdst, DWORD bdst)
967 int rLeftShift,gLeftShift,bLeftShift;
968 const BYTE* srcpixel;
969 DWORD* dstpixel;
970 int x,y;
972 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
973 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
974 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
975 for (y=0; y<height; y++) {
976 srcpixel=srcbits;
977 dstpixel=dstbits;
978 for (x=0; x<width; x++) {
979 *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
980 (srcpixel[1] << gLeftShift) | /* g */
981 (srcpixel[2] << rLeftShift); /* r */
982 srcpixel+=3;
984 srcbits = (const char*)srcbits + srclinebytes;
985 dstbits = (char*)dstbits + dstlinebytes;
989 static void convert_bgr888_to_any0888(int width, int height,
990 const void* srcbits, int srclinebytes,
991 void* dstbits, int dstlinebytes,
992 DWORD rdst, DWORD gdst, DWORD bdst)
994 int rLeftShift,gLeftShift,bLeftShift;
995 const BYTE* srcpixel;
996 DWORD* dstpixel;
997 int x,y;
999 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1000 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1001 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1002 for (y=0; y<height; y++) {
1003 srcpixel=srcbits;
1004 dstpixel=dstbits;
1005 for (x=0; x<width; x++) {
1006 *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
1007 (srcpixel[1] << gLeftShift) | /* g */
1008 (srcpixel[2] << bLeftShift); /* b */
1009 srcpixel+=3;
1011 srcbits = (const char*)srcbits + srclinebytes;
1012 dstbits = (char*)dstbits + dstlinebytes;
1017 * 32 bit conversions
1020 static void convert_0888_asis(int width, int height,
1021 const void* srcbits, int srclinebytes,
1022 void* dstbits, int dstlinebytes)
1024 int y;
1026 width *= 4;
1028 if (srclinebytes == dstlinebytes && srclinebytes == width)
1030 memcpy(dstbits, srcbits, height * width);
1031 return;
1034 for (y=0; y<height; y++) {
1035 memcpy(dstbits, srcbits, width);
1036 srcbits = (const char*)srcbits + srclinebytes;
1037 dstbits = (char*)dstbits + dstlinebytes;
1041 static void convert_0888_reverse(int width, int height,
1042 const void* srcbits, int srclinebytes,
1043 void* dstbits, int dstlinebytes)
1045 const DWORD* srcpixel;
1046 DWORD* dstpixel;
1047 int x,y;
1049 for (y=0; y<height; y++) {
1050 srcpixel=srcbits;
1051 dstpixel=dstbits;
1052 for (x=0; x<width; x++) {
1053 DWORD srcval;
1054 srcval=*srcpixel++;
1055 *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1056 ( srcval & 0x0000ff00) | /* g */
1057 ((srcval >> 16) & 0x000000ff); /* l */
1059 srcbits = (const char*)srcbits + srclinebytes;
1060 dstbits = (char*)dstbits + dstlinebytes;
1064 static void convert_0888_any(int width, int height,
1065 const void* srcbits, int srclinebytes,
1066 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1067 void* dstbits, int dstlinebytes,
1068 DWORD rdst, DWORD gdst, DWORD bdst)
1070 int rRightShift,gRightShift,bRightShift;
1071 int rLeftShift,gLeftShift,bLeftShift;
1072 const DWORD* srcpixel;
1073 DWORD* dstpixel;
1074 int x,y;
1076 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1077 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1078 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1079 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1080 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1081 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1082 for (y=0; y<height; y++) {
1083 srcpixel=srcbits;
1084 dstpixel=dstbits;
1085 for (x=0; x<width; x++) {
1086 DWORD srcval;
1087 srcval=*srcpixel++;
1088 *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1089 (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1090 (((srcval >> bRightShift) & 0xff) << bLeftShift);
1092 srcbits = (const char*)srcbits + srclinebytes;
1093 dstbits = (char*)dstbits + dstlinebytes;
1097 static void convert_0888_to_555_asis(int width, int height,
1098 const void* srcbits, int srclinebytes,
1099 void* dstbits, int dstlinebytes)
1101 const DWORD* srcpixel;
1102 WORD* dstpixel;
1103 int x,y;
1105 for (y=0; y<height; y++) {
1106 srcpixel=srcbits;
1107 dstpixel=dstbits;
1108 for (x=0; x<width; x++) {
1109 DWORD srcval;
1110 srcval=*srcpixel++;
1111 *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1112 ((srcval >> 6) & 0x03e0) | /* g */
1113 ((srcval >> 3) & 0x001f); /* l */
1115 srcbits = (const char*)srcbits + srclinebytes;
1116 dstbits = (char*)dstbits + dstlinebytes;
1120 static void convert_0888_to_555_reverse(int width, int height,
1121 const void* srcbits, int srclinebytes,
1122 void* dstbits, int dstlinebytes)
1124 const DWORD* srcpixel;
1125 WORD* dstpixel;
1126 int x,y;
1128 for (y=0; y<height; y++) {
1129 srcpixel=srcbits;
1130 dstpixel=dstbits;
1131 for (x=0; x<width; x++) {
1132 DWORD srcval;
1133 srcval=*srcpixel++;
1134 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1135 ((srcval >> 6) & 0x03e0) | /* g */
1136 ((srcval << 7) & 0x7c00); /* l */
1138 srcbits = (const char*)srcbits + srclinebytes;
1139 dstbits = (char*)dstbits + dstlinebytes;
1143 static void convert_0888_to_565_asis(int width, int height,
1144 const void* srcbits, int srclinebytes,
1145 void* dstbits, int dstlinebytes)
1147 const DWORD* srcpixel;
1148 WORD* dstpixel;
1149 int x,y;
1151 for (y=0; y<height; y++) {
1152 srcpixel=srcbits;
1153 dstpixel=dstbits;
1154 for (x=0; x<width; x++) {
1155 DWORD srcval;
1156 srcval=*srcpixel++;
1157 *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1158 ((srcval >> 5) & 0x07e0) | /* g */
1159 ((srcval >> 3) & 0x001f); /* l */
1161 srcbits = (const char*)srcbits + srclinebytes;
1162 dstbits = (char*)dstbits + dstlinebytes;
1166 static void convert_0888_to_565_reverse(int width, int height,
1167 const void* srcbits, int srclinebytes,
1168 void* dstbits, int dstlinebytes)
1170 const DWORD* srcpixel;
1171 WORD* dstpixel;
1172 int x,y;
1174 for (y=0; y<height; y++) {
1175 srcpixel=srcbits;
1176 dstpixel=dstbits;
1177 for (x=0; x<width; x++) {
1178 DWORD srcval;
1179 srcval=*srcpixel++;
1180 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1181 ((srcval >> 5) & 0x07e0) | /* g */
1182 ((srcval << 8) & 0xf800); /* l */
1184 srcbits = (const char*)srcbits + srclinebytes;
1185 dstbits = (char*)dstbits + dstlinebytes;
1189 static void convert_any0888_to_5x5(int width, int height,
1190 const void* srcbits, int srclinebytes,
1191 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1192 void* dstbits, int dstlinebytes,
1193 WORD rdst, WORD gdst, WORD bdst)
1195 int rRightShift,gRightShift,bRightShift;
1196 int rLeftShift,gLeftShift,bLeftShift;
1197 const DWORD* srcpixel;
1198 WORD* dstpixel;
1199 int x,y;
1201 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1202 * contains 0x11223344.
1203 * - first we shift 0x11223344 right by rRightShift to bring the most
1204 * significant bits of the red components in the bottom 5 (or 6) bits
1205 * -> 0x4488c
1206 * - then we remove non red bits by anding with the modified rdst (0x1f)
1207 * -> 0x0c
1208 * - finally shift these bits left by rLeftShift so that they end up in
1209 * the right place
1210 * -> 0x3000
1212 rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1213 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1214 gRightShift+=(gdst==0x07e0?2:3);
1215 bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1217 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1218 rdst=rdst >> rLeftShift;
1219 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1220 gdst=gdst >> gLeftShift;
1221 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1222 bdst=bdst >> bLeftShift;
1224 for (y=0; y<height; y++) {
1225 srcpixel=srcbits;
1226 dstpixel=dstbits;
1227 for (x=0; x<width; x++) {
1228 DWORD srcval;
1229 srcval=*srcpixel++;
1230 *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1231 (((srcval >> gRightShift) & gdst) << gLeftShift) |
1232 (((srcval >> bRightShift) & bdst) << bLeftShift);
1234 srcbits = (const char*)srcbits + srclinebytes;
1235 dstbits = (char*)dstbits + dstlinebytes;
1239 static void convert_0888_to_888_asis(int width, int height,
1240 const void* srcbits, int srclinebytes,
1241 void* dstbits, int dstlinebytes)
1243 const DWORD* srcpixel;
1244 DWORD* dstpixel;
1245 BYTE* dstbyte;
1246 int x,y;
1247 int oddwidth;
1249 oddwidth=width & 3;
1250 width=width/4;
1251 for (y=0; y<height; y++) {
1252 srcpixel=srcbits;
1253 dstpixel=dstbits;
1254 for (x=0; x<width; x++) {
1255 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1256 DWORD srcval;
1257 srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/
1258 *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */
1259 srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1260 *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */
1261 srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */
1262 *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */
1264 /* And now up to 3 odd pixels */
1265 dstbyte=(BYTE*)dstpixel;
1266 for (x=0; x<oddwidth; x++) {
1267 DWORD srcval;
1268 srcval=*srcpixel++;
1269 *((WORD*)dstbyte) = srcval; /* h, g */
1270 dstbyte+=sizeof(WORD);
1271 *dstbyte++=srcval >> 16; /* l */
1273 srcbits = (const char*)srcbits + srclinebytes;
1274 dstbits = (char*)dstbits + dstlinebytes;
1278 static void convert_0888_to_888_reverse(int width, int height,
1279 const void* srcbits, int srclinebytes,
1280 void* dstbits, int dstlinebytes)
1282 const DWORD* srcpixel;
1283 DWORD* dstpixel;
1284 BYTE* dstbyte;
1285 int x,y;
1286 int oddwidth;
1288 oddwidth=width & 3;
1289 width=width/4;
1290 for (y=0; y<height; y++) {
1291 srcpixel=srcbits;
1292 dstpixel=dstbits;
1293 for (x=0; x<width; x++) {
1294 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1295 DWORD srcval1,srcval2;
1296 srcval1=*srcpixel++;
1297 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1298 ( srcval1 & 0x0000ff00) | /* g1 */
1299 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1300 srcval1=*srcpixel++;
1301 *dstpixel++=srcval2 |
1302 ((srcval1 << 8) & 0xff000000); /* h2 */
1303 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1304 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1305 srcval1=*srcpixel++;
1306 *dstpixel++=srcval2 |
1307 ( srcval1 & 0x00ff0000) | /* h3 */
1308 ((srcval1 << 16) & 0xff000000); /* g3 */
1309 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1310 srcval1=*srcpixel++;
1311 *dstpixel++=srcval2 |
1312 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1313 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1314 ( srcval1 << 24); /* l4 */
1316 /* And now up to 3 odd pixels */
1317 dstbyte=(BYTE*)dstpixel;
1318 for (x=0; x<oddwidth; x++) {
1319 DWORD srcval;
1320 srcval=*srcpixel++;
1321 *((WORD*)dstbyte)=((srcval >> 16) & 0x00ff) | /* h */
1322 (srcval & 0xff00); /* g */
1323 dstbyte += sizeof(WORD);
1324 *dstbyte++=srcval; /* l */
1326 srcbits = (const char*)srcbits + srclinebytes;
1327 dstbits = (char*)dstbits + dstlinebytes;
1331 static void convert_any0888_to_rgb888(int width, int height,
1332 const void* srcbits, int srclinebytes,
1333 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1334 void* dstbits, int dstlinebytes)
1336 int rRightShift,gRightShift,bRightShift;
1337 const DWORD* srcpixel;
1338 BYTE* dstpixel;
1339 int x,y;
1341 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1342 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1343 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1344 for (y=0; y<height; y++) {
1345 srcpixel=srcbits;
1346 dstpixel=dstbits;
1347 for (x=0; x<width; x++) {
1348 DWORD srcval;
1349 srcval=*srcpixel++;
1350 dstpixel[0]=(srcval >> bRightShift); /* b */
1351 dstpixel[1]=(srcval >> gRightShift); /* g */
1352 dstpixel[2]=(srcval >> rRightShift); /* r */
1353 dstpixel+=3;
1355 srcbits = (const char*)srcbits + srclinebytes;
1356 dstbits = (char*)dstbits + dstlinebytes;
1360 static void convert_any0888_to_bgr888(int width, int height,
1361 const void* srcbits, int srclinebytes,
1362 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1363 void* dstbits, int dstlinebytes)
1365 int rRightShift,gRightShift,bRightShift;
1366 const DWORD* srcpixel;
1367 BYTE* dstpixel;
1368 int x,y;
1370 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1371 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1372 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1373 for (y=0; y<height; y++) {
1374 srcpixel=srcbits;
1375 dstpixel=dstbits;
1376 for (x=0; x<width; x++) {
1377 DWORD srcval;
1378 srcval=*srcpixel++;
1379 dstpixel[0]=(srcval >> rRightShift); /* r */
1380 dstpixel[1]=(srcval >> gRightShift); /* g */
1381 dstpixel[2]=(srcval >> bRightShift); /* b */
1382 dstpixel+=3;
1384 srcbits = (const char*)srcbits + srclinebytes;
1385 dstbits = (char*)dstbits + dstlinebytes;
1389 const dib_conversions dib_normal = {
1390 convert_5x5_asis,
1391 convert_555_reverse,
1392 convert_555_to_565_asis,
1393 convert_555_to_565_reverse,
1394 convert_555_to_888_asis,
1395 convert_555_to_888_reverse,
1396 convert_555_to_0888_asis,
1397 convert_555_to_0888_reverse,
1398 convert_5x5_to_any0888,
1399 convert_565_reverse,
1400 convert_565_to_555_asis,
1401 convert_565_to_555_reverse,
1402 convert_565_to_888_asis,
1403 convert_565_to_888_reverse,
1404 convert_565_to_0888_asis,
1405 convert_565_to_0888_reverse,
1406 convert_888_asis,
1407 convert_888_reverse,
1408 convert_888_to_555_asis,
1409 convert_888_to_555_reverse,
1410 convert_888_to_565_asis,
1411 convert_888_to_565_reverse,
1412 convert_888_to_0888_asis,
1413 convert_888_to_0888_reverse,
1414 convert_rgb888_to_any0888,
1415 convert_bgr888_to_any0888,
1416 convert_0888_asis,
1417 convert_0888_reverse,
1418 convert_0888_any,
1419 convert_0888_to_555_asis,
1420 convert_0888_to_555_reverse,
1421 convert_0888_to_565_asis,
1422 convert_0888_to_565_reverse,
1423 convert_any0888_to_5x5,
1424 convert_0888_to_888_asis,
1425 convert_0888_to_888_reverse,
1426 convert_any0888_to_rgb888,
1427 convert_any0888_to_bgr888