Huw Davies <huw@xxxxxxxxxxxxxxx> Add support for display of dibs on MSB XServers. -- Huw Davies huw@xxxxxxxxxxxxxxx Index: dlls/x11drv/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/x11drv/Makefile.in,v retrieving revision 1.33 diff -u -r1.33 Makefile.in --- dlls/x11drv/Makefile.in 16 Oct 2003 00:21:42 -0000 1.33 +++ dlls/x11drv/Makefile.in 10 Nov 2003 16:25:08 -0000 @@ -22,9 +22,12 @@ $(TOPOBJDIR)/graphics/x11drv/pen.c \ $(TOPOBJDIR)/graphics/x11drv/text.c \ $(TOPOBJDIR)/graphics/x11drv/xfont.c \ - desktop.c \ clipboard.c \ + desktop.c \ dga2.c \ + dib_convert.c \ + dib_convert_di.c \ + dib_convert_si.c \ event.c \ keyboard.c \ mouse.c \ Index: dlls/x11drv/x11drv.h =================================================================== RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v retrieving revision 1.6 diff -u -r1.6 x11drv.h --- dlls/x11drv/x11drv.h 16 Oct 2003 00:21:42 -0000 1.6 +++ dlls/x11drv/x11drv.h 10 Nov 2003 16:25:08 -0000 @@ -509,4 +509,137 @@ unsigned int nmodes, int reserve_depths); + + +typedef struct { + void (*Convert_5x5_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_565_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_5x5_to_any0888)(int width, int height, + const void* srcbits, int srclinebytes, + WORD rsrc, WORD gsrc, WORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_555_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_555_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_565_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_rgb888_to_any0888)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_bgr888_to_any0888)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_any)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_0888_to_555_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_565_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_any0888_to_5x5)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + WORD rdst, WORD gdst, WORD bdst); + void (*Convert_0888_to_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_any0888_to_rgb888)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes); + void (*Convert_any0888_to_bgr888)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes); +} dib_conversions; + +extern dib_conversions dib_normal, dib_src_invert, dib_dst_invert; + +extern INT X11DRV_DIB_MaskToShift(DWORD mask); + #endif /* __WINE_X11DRV_H */ Index: graphics/x11drv/dib.c =================================================================== RCS file: /home/wine/wine/graphics/x11drv/dib.c,v retrieving revision 1.112 diff -u -r1.112 dib.c --- graphics/x11drv/dib.c 9 Nov 2003 00:34:43 -0000 1.112 +++ graphics/x11drv/dib.c 10 Nov 2003 16:25:09 -0000 @@ -324,7 +324,7 @@ * Returns the by how many bits to shift a given color so that it is * in the proper position. */ -static INT X11DRV_DIB_MaskToShift(DWORD mask) +INT X11DRV_DIB_MaskToShift(DWORD mask) { int shift; @@ -340,1256 +340,6 @@ } /*********************************************************************** - * X11DRV_DIB_Convert_any_asis - * - * All X11DRV_DIB_Convert_Xxx functions take at least the following - * parameters: - * - width - * This is the width in pixel of the surface to copy. This may be less - * than the full width of the image. - * - height - * The number of lines to copy. This may be less than the full height - * of the image. This is always >0. - * - srcbits - * Points to the first byte containing data to be copied. If the source - * surface starts are coordinates (x,y) then this is: - * image_ptr+x*bytes_pre_pixel+y*bytes_per_line - * (with further adjustments for top-down/bottom-up images) - * - srclinebytes - * This is the number of bytes per line. It may be >0 or <0 depending on - * whether this is a top-down or bottom-up image. - * - dstbits - * Same as srcbits but for the destination - * - dstlinebytes - * Same as srclinebytes but for the destination. - * - * Notes: - * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555, - * rgb565, bgr565, rgb888 and any 32bit (0888) format. - * The supported XImage (Bmp) formats are: pal1, pal4, pal8, - * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888. - * - Rgb formats are those for which the masks are such that: - * red_mask > green_mask > blue_mask - * - Bgr formats are those for which the masks sort in the other direction. - * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions - * so the comments use h, g, l to mean respectively the source color in the - * high bits, the green, and the source color in the low bits. - */ -static void X11DRV_DIB_Convert_any_asis(int width, int height, - int bytes_per_pixel, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - int y; - - width*=bytes_per_pixel; - for (y=0; y<height; y++) { - memcpy(dstbits, srcbits, width); - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -/* - * 15 bit conversions - */ - -static void X11DRV_DIB_Convert_555_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width/2; x++) { - /* Do 2 pixels at a time */ - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */ - ( srcval & 0x03e003e0) | /* g */ - ((srcval >> 10) & 0x001f001f); /* l */ - } - if (width&1) { - /* And the the odd pixel */ - WORD srcval; - srcval=*((WORD*)srcpixel); - *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */ - ( srcval & 0x03e0) | /* g */ - ((srcval >> 10) & 0x001f); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_555_to_565_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width/2; x++) { - /* Do 2 pixels at a time */ - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */ - ((srcval >> 4) & 0x00200020) | /* g - 1 bit */ - ( srcval & 0x001f001f); /* l */ - } - if (width&1) { - /* And the the odd pixel */ - WORD srcval; - srcval=*((WORD*)srcpixel); - *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */ - ((srcval >> 4) & 0x0020) | /* g - 1 bit */ - (srcval & 0x001f); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_555_to_565_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width/2; x++) { - /* Do 2 pixels at a time */ - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */ - ((srcval << 1) & 0x07c007c0) | /* g */ - ((srcval >> 4) & 0x00200020) | /* g - 1 bit */ - ((srcval << 11) & 0xf800f800); /* l */ - } - if (width&1) { - /* And the the odd pixel */ - WORD srcval; - srcval=*((WORD*)srcpixel); - *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */ - ((srcval << 1) & 0x07c0) | /* g */ - ((srcval >> 4) & 0x0020) | /* g - 1 bit */ - ((srcval << 11) & 0xf800); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_555_to_888_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - BYTE* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - dstpixel[0]=((srcval << 3) & 0xf8) | /* l */ - ((srcval >> 2) & 0x07); /* l - 3 bits */ - dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */ - ((srcval >> 7) & 0x07); /* g - 3 bits */ - dstpixel[2]=((srcval >> 7) & 0xf8) | /* h */ - ((srcval >> 12) & 0x07); /* h - 3 bits */ - dstpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_555_to_888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - BYTE* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - dstpixel[0]=((srcval >> 7) & 0xf8) | /* h */ - ((srcval >> 12) & 0x07); /* h - 3 bits */ - dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */ - ((srcval >> 7) & 0x07); /* g - 3 bits */ - dstpixel[2]=((srcval << 3) & 0xf8) | /* l */ - ((srcval >> 2) & 0x07); /* l - 3 bits */ - dstpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_555_to_0888_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval << 9) & 0xf80000) | /* h */ - ((srcval << 4) & 0x070000) | /* h - 3 bits */ - ((srcval << 6) & 0x00f800) | /* g */ - ((srcval << 1) & 0x000700) | /* g - 3 bits */ - ((srcval << 3) & 0x0000f8) | /* l */ - ((srcval >> 2) & 0x000007); /* l - 3 bits */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_555_to_0888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 7) & 0x0000f8) | /* h */ - ((srcval >> 12) & 0x000007) | /* h - 3 bits */ - ((srcval << 6) & 0x00f800) | /* g */ - ((srcval << 1) & 0x000700) | /* g - 3 bits */ - ((srcval << 19) & 0xf80000) | /* l */ - ((srcval << 14) & 0x070000); /* l - 3 bits */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_5x5_to_any0888(int width, int height, - const void* srcbits, int srclinebytes, - WORD rsrc, WORD gsrc, WORD bsrc, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst) -{ - int rRightShift1,gRightShift1,bRightShift1; - int rRightShift2,gRightShift2,bRightShift2; - BYTE gMask1,gMask2; - int rLeftShift,gLeftShift,bLeftShift; - const WORD* srcpixel; - DWORD* dstpixel; - int x,y; - - /* Note, the source pixel value is shifted left by 16 bits so that - * we know we will always have to shift right to extract the components. - */ - rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3; - gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3; - bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3; - rRightShift2=rRightShift1+5; - gRightShift2=gRightShift1+5; - bRightShift2=bRightShift1+5; - if (gsrc==0x03e0) { - /* Green has 5 bits, like the others */ - gMask1=0xf8; - gMask2=0x07; - } else { - /* Green has 6 bits, not 5. Compensate. */ - gRightShift1++; - gRightShift2+=2; - gMask1=0xfc; - gMask2=0x03; - } - - rLeftShift=X11DRV_DIB_MaskToShift(rdst); - gLeftShift=X11DRV_DIB_MaskToShift(gdst); - bLeftShift=X11DRV_DIB_MaskToShift(bdst); - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - BYTE red,green,blue; - srcval=*srcpixel++ << 16; - red= ((srcval >> rRightShift1) & 0xf8) | - ((srcval >> rRightShift2) & 0x07); - green=((srcval >> gRightShift1) & gMask1) | - ((srcval >> gRightShift2) & gMask2); - blue= ((srcval >> bRightShift1) & 0xf8) | - ((srcval >> bRightShift2) & 0x07); - *dstpixel++=(red << rLeftShift) | - (green << gLeftShift) | - (blue << bLeftShift); - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -/* - * 16 bits conversions - */ - -static void X11DRV_DIB_Convert_565_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width/2; x++) { - /* Do 2 pixels at a time */ - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */ - ( srcval & 0x07e007e0) | /* g */ - ((srcval >> 11) & 0x001f001f); /* l */ - } - if (width&1) { - /* And the the odd pixel */ - WORD srcval; - srcval=*((WORD*)srcpixel); - *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */ - ( srcval & 0x07e0) | /* g */ - ((srcval >> 11) & 0x001f); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_565_to_555_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width/2; x++) { - /* Do 2 pixels at a time */ - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */ - ( srcval & 0x001f001f); /* l */ - } - if (width&1) { - /* And the the odd pixel */ - WORD srcval; - srcval=*((WORD*)srcpixel); - *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */ - ( srcval & 0x001f); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_565_to_555_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width/2; x++) { - /* Do 2 pixels at a time */ - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */ - ((srcval >> 1) & 0x03e003e0) | /* g */ - ((srcval << 10) & 0x7c007c00); /* l */ - } - if (width&1) { - /* And the the odd pixel */ - WORD srcval; - srcval=*((WORD*)srcpixel); - *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */ - ((srcval >> 1) & 0x03e0) | /* g */ - ((srcval << 10) & 0x7c00); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_565_to_888_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - BYTE* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - dstpixel[0]=((srcval << 3) & 0xf8) | /* l */ - ((srcval >> 2) & 0x07); /* l - 3 bits */ - dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */ - ((srcval >> 9) & 0x03); /* g - 2 bits */ - dstpixel[2]=((srcval >> 8) & 0xf8) | /* h */ - ((srcval >> 13) & 0x07); /* h - 3 bits */ - dstpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_565_to_888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - BYTE* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - dstpixel[0]=((srcval >> 8) & 0xf8) | /* h */ - ((srcval >> 13) & 0x07); /* h - 3 bits */ - dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */ - ((srcval >> 9) & 0x03); /* g - 2 bits */ - dstpixel[2]=((srcval << 3) & 0xf8) | /* l */ - ((srcval >> 2) & 0x07); /* l - 3 bits */ - dstpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_565_to_0888_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval << 8) & 0xf80000) | /* h */ - ((srcval << 3) & 0x070000) | /* h - 3 bits */ - ((srcval << 5) & 0x00fc00) | /* g */ - ((srcval >> 1) & 0x000300) | /* g - 2 bits */ - ((srcval << 3) & 0x0000f8) | /* l */ - ((srcval >> 2) & 0x000007); /* l - 3 bits */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_565_to_0888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const WORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - WORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 8) & 0x0000f8) | /* h */ - ((srcval >> 13) & 0x000007) | /* h - 3 bits */ - ((srcval << 5) & 0x00fc00) | /* g */ - ((srcval >> 1) & 0x000300) | /* g - 2 bits */ - ((srcval << 19) & 0xf80000) | /* l */ - ((srcval << 14) & 0x070000); /* l - 3 bits */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -/* - * 24 bit conversions - */ - -static void X11DRV_DIB_Convert_888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const BYTE* srcpixel; - BYTE* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - dstpixel[0]=srcpixel[2]; - dstpixel[1]=srcpixel[1]; - dstpixel[2]=srcpixel[0]; - srcpixel+=3; - dstpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_888_to_555_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - const BYTE* srcbyte; - WORD* dstpixel; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 3 dwords in and 4 words out */ - DWORD srcval1,srcval2; - srcval1=srcpixel[0]; - dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */ - ((srcval1 >> 6) & 0x03e0) | /* g1 */ - ((srcval1 >> 9) & 0x7c00); /* h1 */ - srcval2=srcpixel[1]; - dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */ - ((srcval2 << 2) & 0x03e0) | /* g2 */ - ((srcval2 >> 1) & 0x7c00); /* h2 */ - srcval1=srcpixel[2]; - dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */ - ((srcval2 >> 22) & 0x03e0) | /* g3 */ - ((srcval1 << 7) & 0x7c00); /* h3 */ - dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */ - ((srcval1 >> 14) & 0x03e0) | /* g4 */ - ((srcval1 >> 17) & 0x7c00); /* h4 */ - srcpixel+=3; - dstpixel+=4; - } - /* And now up to 3 odd pixels */ - srcbyte=(LPBYTE)srcpixel; - for (x=0; x<oddwidth; x++) { - WORD dstval; - dstval =((srcbyte[0] >> 3) & 0x001f); /* l */ - dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */ - dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */ - *dstpixel++=dstval; - srcbyte+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_888_to_555_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - const BYTE* srcbyte; - WORD* dstpixel; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 3 dwords in and 4 words out */ - DWORD srcval1,srcval2; - srcval1=srcpixel[0]; - dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */ - ((srcval1 >> 6) & 0x03e0) | /* g1 */ - ((srcval1 >> 19) & 0x001f); /* h1 */ - srcval2=srcpixel[1]; - dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */ - ((srcval2 << 2) & 0x03e0) | /* g2 */ - ((srcval2 >> 11) & 0x001f); /* h2 */ - srcval1=srcpixel[2]; - dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */ - ((srcval2 >> 22) & 0x03e0) | /* g3 */ - ((srcval1 >> 3) & 0x001f); /* h3 */ - dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */ - ((srcval1 >> 14) & 0x03e0) | /* g4 */ - ((srcval1 >> 27) & 0x001f); /* h4 */ - srcpixel+=3; - dstpixel+=4; - } - /* And now up to 3 odd pixels */ - srcbyte=(LPBYTE)srcpixel; - for (x=0; x<oddwidth; x++) { - WORD dstval; - dstval =((srcbyte[0] << 7) & 0x7c00); /* l */ - dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */ - dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */ - *dstpixel++=dstval; - srcbyte+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_888_to_565_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - const BYTE* srcbyte; - WORD* dstpixel; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 3 dwords in and 4 words out */ - DWORD srcval1,srcval2; - srcval1=srcpixel[0]; - dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */ - ((srcval1 >> 5) & 0x07e0) | /* g1 */ - ((srcval1 >> 8) & 0xf800); /* h1 */ - srcval2=srcpixel[1]; - dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */ - ((srcval2 << 3) & 0x07e0) | /* g2 */ - ( srcval2 & 0xf800); /* h2 */ - srcval1=srcpixel[2]; - dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */ - ((srcval2 >> 21) & 0x07e0) | /* g3 */ - ((srcval1 << 8) & 0xf800); /* h3 */ - dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */ - ((srcval1 >> 13) & 0x07e0) | /* g4 */ - ((srcval1 >> 16) & 0xf800); /* h4 */ - srcpixel+=3; - dstpixel+=4; - } - /* And now up to 3 odd pixels */ - srcbyte=(LPBYTE)srcpixel; - for (x=0; x<oddwidth; x++) { - WORD dstval; - dstval =((srcbyte[0] >> 3) & 0x001f); /* l */ - dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */ - dstval|=((srcbyte[2] << 8) & 0xf800); /* h */ - *dstpixel++=dstval; - srcbyte+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_888_to_565_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - const BYTE* srcbyte; - WORD* dstpixel; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 3 dwords in and 4 words out */ - DWORD srcval1,srcval2; - srcval1=srcpixel[0]; - dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */ - ((srcval1 >> 5) & 0x07e0) | /* g1 */ - ((srcval1 >> 19) & 0x001f); /* h1 */ - srcval2=srcpixel[1]; - dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */ - ((srcval2 << 3) & 0x07e0) | /* g2 */ - ((srcval2 >> 11) & 0x001f); /* h2 */ - srcval1=srcpixel[2]; - dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */ - ((srcval2 >> 21) & 0x07e0) | /* g3 */ - ((srcval1 >> 3) & 0x001f); /* h3 */ - dstpixel[3]=(srcval1 & 0xf800) | /* l4 */ - ((srcval1 >> 13) & 0x07e0) | /* g4 */ - ((srcval1 >> 27) & 0x001f); /* h4 */ - srcpixel+=3; - dstpixel+=4; - } - /* And now up to 3 odd pixels */ - srcbyte=(LPBYTE)srcpixel; - for (x=0; x<oddwidth; x++) { - WORD dstval; - dstval =((srcbyte[0] << 8) & 0xf800); /* l */ - dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */ - dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */ - *dstpixel++=dstval; - srcbyte+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_888_to_0888_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ - DWORD srcval1,srcval2; - srcval1=srcpixel[0]; - dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */ - srcval2=srcpixel[1]; - dstpixel[1]=( srcval1 >> 24) | /* l2 */ - ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */ - srcval1=srcpixel[2]; - dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */ - ((srcval1 << 16) & 0x00ff0000); /* h3 */ - dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */ - srcpixel+=3; - dstpixel+=4; - } - /* And now up to 3 odd pixels */ - for (x=0; x<oddwidth; x++) { - DWORD srcval; - srcval=*srcpixel; - srcpixel=(LPDWORD)(((char*)srcpixel)+3); - *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_888_to_0888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ - DWORD srcval1,srcval2; - - srcval1=srcpixel[0]; - dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */ - ( srcval1 & 0x00ff00) | /* g1 */ - ((srcval1 << 16) & 0xff0000); /* l1 */ - srcval2=srcpixel[1]; - dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */ - ((srcval2 << 8) & 0x00ff00) | /* g2 */ - ((srcval2 >> 8) & 0x0000ff); /* h2 */ - srcval1=srcpixel[2]; - dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */ - ((srcval2 >> 16) & 0x00ff00) | /* g3 */ - ( srcval1 & 0x0000ff); /* h3 */ - dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */ - ((srcval1 >> 8) & 0x00ff00) | /* g4 */ - ((srcval1 << 8) & 0xff0000); /* l4 */ - srcpixel+=3; - dstpixel+=4; - } - /* And now up to 3 odd pixels */ - for (x=0; x<oddwidth; x++) { - DWORD srcval; - srcval=*srcpixel; - srcpixel=(LPDWORD)(((char*)srcpixel)+3); - *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */ - ( srcval & 0x00ff00) | /* g */ - ((srcval << 16) & 0xff0000); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_rgb888_to_any0888(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst) -{ - int rLeftShift,gLeftShift,bLeftShift; - const BYTE* srcpixel; - DWORD* dstpixel; - int x,y; - - rLeftShift=X11DRV_DIB_MaskToShift(rdst); - gLeftShift=X11DRV_DIB_MaskToShift(gdst); - bLeftShift=X11DRV_DIB_MaskToShift(bdst); - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */ - (srcpixel[1] << gLeftShift) | /* g */ - (srcpixel[2] << rLeftShift); /* r */ - srcpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_bgr888_to_any0888(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst) -{ - int rLeftShift,gLeftShift,bLeftShift; - const BYTE* srcpixel; - DWORD* dstpixel; - int x,y; - - rLeftShift=X11DRV_DIB_MaskToShift(rdst); - gLeftShift=X11DRV_DIB_MaskToShift(gdst); - bLeftShift=X11DRV_DIB_MaskToShift(bdst); - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */ - (srcpixel[1] << gLeftShift) | /* g */ - (srcpixel[2] << bLeftShift); /* b */ - srcpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -/* - * 32 bit conversions - */ - -static void X11DRV_DIB_Convert_0888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */ - ( srcval & 0x0000ff00) | /* g */ - ((srcval >> 16) & 0x000000ff); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_0888_any(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst) -{ - int rRightShift,gRightShift,bRightShift; - int rLeftShift,gLeftShift,bLeftShift; - const DWORD* srcpixel; - DWORD* dstpixel; - int x,y; - - rRightShift=X11DRV_DIB_MaskToShift(rsrc); - gRightShift=X11DRV_DIB_MaskToShift(gsrc); - bRightShift=X11DRV_DIB_MaskToShift(bsrc); - rLeftShift=X11DRV_DIB_MaskToShift(rdst); - gLeftShift=X11DRV_DIB_MaskToShift(gdst); - bLeftShift=X11DRV_DIB_MaskToShift(bdst); - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) | - (((srcval >> gRightShift) & 0xff) << gLeftShift) | - (((srcval >> bRightShift) & 0xff) << bLeftShift); - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_0888_to_555_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - WORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */ - ((srcval >> 6) & 0x03e0) | /* g */ - ((srcval >> 3) & 0x001f); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_0888_to_555_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - WORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 19) & 0x001f) | /* h */ - ((srcval >> 6) & 0x03e0) | /* g */ - ((srcval << 7) & 0x7c00); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_0888_to_565_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - WORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 8) & 0xf800) | /* h */ - ((srcval >> 5) & 0x07e0) | /* g */ - ((srcval >> 3) & 0x001f); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_0888_to_565_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - WORD* dstpixel; - int x,y; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=((srcval >> 19) & 0x001f) | /* h */ - ((srcval >> 5) & 0x07e0) | /* g */ - ((srcval << 8) & 0xf800); /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_any0888_to_5x5(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes, - WORD rdst, WORD gdst, WORD bdst) -{ - int rRightShift,gRightShift,bRightShift; - int rLeftShift,gLeftShift,bLeftShift; - const DWORD* srcpixel; - WORD* dstpixel; - int x,y; - - /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel - * contains 0x11223344. - * - first we shift 0x11223344 right by rRightShift to bring the most - * significant bits of the red components in the bottom 5 (or 6) bits - * -> 0x4488c - * - then we remove non red bits by anding with the modified rdst (0x1f) - * -> 0x0c - * - finally shift these bits left by rLeftShift so that they end up in - * the right place - * -> 0x3000 - */ - rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3; - gRightShift=X11DRV_DIB_MaskToShift(gsrc); - gRightShift+=(gdst==0x07e0?2:3); - bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3; - - rLeftShift=X11DRV_DIB_MaskToShift(rdst); - rdst=rdst >> rLeftShift; - gLeftShift=X11DRV_DIB_MaskToShift(gdst); - gdst=gdst >> gLeftShift; - bLeftShift=X11DRV_DIB_MaskToShift(bdst); - bdst=bdst >> bLeftShift; - - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) | - (((srcval >> gRightShift) & gdst) << gLeftShift) | - (((srcval >> bRightShift) & bdst) << bLeftShift); - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_0888_to_888_asis(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - BYTE* dstbyte; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ - DWORD srcval; - srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/ - *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */ - srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */ - *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */ - srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */ - *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */ - } - /* And now up to 3 odd pixels */ - dstbyte=(BYTE*)dstpixel; - for (x=0; x<oddwidth; x++) { - DWORD srcval; - srcval=*srcpixel++; - *((WORD*)dstbyte)++=srcval; /* h, g */ - *dstbyte++=srcval >> 16; /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_0888_to_888_reverse(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes) -{ - const DWORD* srcpixel; - DWORD* dstpixel; - BYTE* dstbyte; - int x,y; - int oddwidth; - - oddwidth=width & 3; - width=width/4; - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ - DWORD srcval1,srcval2; - srcval1=*srcpixel++; - srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */ - ( srcval1 & 0x0000ff00) | /* g1 */ - ((srcval1 << 16) & 0x00ff0000); /* l1 */ - srcval1=*srcpixel++; - *dstpixel++=srcval2 | - ((srcval1 << 8) & 0xff000000); /* h2 */ - srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */ - ((srcval1 << 8) & 0x0000ff00); /* l2 */ - srcval1=*srcpixel++; - *dstpixel++=srcval2 | - ( srcval1 & 0x00ff0000) | /* h3 */ - ((srcval1 << 16) & 0xff000000); /* g3 */ - srcval2= ( srcval1 & 0x000000ff); /* l3 */ - srcval1=*srcpixel++; - *dstpixel++=srcval2 | - ((srcval1 >> 8) & 0x0000ff00) | /* h4 */ - ((srcval1 << 8) & 0x00ff0000) | /* g4 */ - ( srcval1 << 24); /* l4 */ - } - /* And now up to 3 odd pixels */ - dstbyte=(BYTE*)dstpixel; - for (x=0; x<oddwidth; x++) { - DWORD srcval; - srcval=*srcpixel++; - *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */ - (srcval & 0xff00); /* g */ - *dstbyte++=srcval; /* l */ - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_any0888_to_rgb888(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes) -{ - int rRightShift,gRightShift,bRightShift; - const DWORD* srcpixel; - BYTE* dstpixel; - int x,y; - - rRightShift=X11DRV_DIB_MaskToShift(rsrc); - gRightShift=X11DRV_DIB_MaskToShift(gsrc); - bRightShift=X11DRV_DIB_MaskToShift(bsrc); - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - dstpixel[0]=(srcval >> bRightShift); /* b */ - dstpixel[1]=(srcval >> gRightShift); /* g */ - dstpixel[2]=(srcval >> rRightShift); /* r */ - dstpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -static void X11DRV_DIB_Convert_any0888_to_bgr888(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes) -{ - int rRightShift,gRightShift,bRightShift; - const DWORD* srcpixel; - BYTE* dstpixel; - int x,y; - - rRightShift=X11DRV_DIB_MaskToShift(rsrc); - gRightShift=X11DRV_DIB_MaskToShift(gsrc); - bRightShift=X11DRV_DIB_MaskToShift(bsrc); - for (y=0; y<height; y++) { - srcpixel=srcbits; - dstpixel=dstbits; - for (x=0; x<width; x++) { - DWORD srcval; - srcval=*srcpixel++; - dstpixel[0]=(srcval >> rRightShift); /* r */ - dstpixel[1]=(srcval >> gRightShift); /* g */ - dstpixel[2]=(srcval >> bRightShift); /* b */ - dstpixel+=3; - } - srcbits = (char*)srcbits + srclinebytes; - dstbits = (char*)dstbits + dstlinebytes; - } -} - -/*********************************************************************** * X11DRV_DIB_SetImageBits_1 * * SetDIBits for a 1-bit deep DIB. @@ -2976,6 +1726,7 @@ { DWORD x; int h; + dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_invert; if (lines < 0 ) { @@ -2999,14 +1750,14 @@ if (rSrc==bmpImage->red_mask) { /* ==== rgb 555 dib -> rgb 555 bmp ==== */ /* ==== bgr 555 dib -> bgr 555 bmp ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,2, + convs->Convert_5x5_asis + (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else if (rSrc==bmpImage->blue_mask) { /* ==== rgb 555 dib -> bgr 555 bmp ==== */ /* ==== bgr 555 dib -> rgb 555 bmp ==== */ - X11DRV_DIB_Convert_555_reverse + convs->Convert_555_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3015,14 +1766,14 @@ if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) { /* ==== rgb 565 dib -> rgb 555 bmp ==== */ /* ==== bgr 565 dib -> bgr 555 bmp ==== */ - X11DRV_DIB_Convert_565_to_555_asis + convs->Convert_565_to_555_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 565 dib -> bgr 555 bmp ==== */ /* ==== bgr 565 dib -> rgb 555 bmp ==== */ - X11DRV_DIB_Convert_565_to_555_reverse + convs->Convert_565_to_555_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3033,14 +1784,14 @@ if (rSrc==bmpImage->red_mask) { /* ==== rgb 565 dib -> rgb 565 bmp ==== */ /* ==== bgr 565 dib -> bgr 565 bmp ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,2, + convs->Convert_5x5_asis + (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 565 dib -> bgr 565 bmp ==== */ /* ==== bgr 565 dib -> rgb 565 bmp ==== */ - X11DRV_DIB_Convert_565_reverse + convs->Convert_565_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3049,14 +1800,14 @@ if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) { /* ==== rgb 555 dib -> rgb 565 bmp ==== */ /* ==== bgr 555 dib -> bgr 565 bmp ==== */ - X11DRV_DIB_Convert_555_to_565_asis + convs->Convert_555_to_565_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 555 dib -> bgr 565 bmp ==== */ /* ==== bgr 555 dib -> rgb 565 bmp ==== */ - X11DRV_DIB_Convert_555_to_565_reverse + convs->Convert_555_to_565_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3083,14 +1834,14 @@ if (gSrc==0x03e0) { /* ==== rgb 555 dib -> rgb 888 bmp ==== */ /* ==== bgr 555 dib -> bgr 888 bmp ==== */ - X11DRV_DIB_Convert_555_to_888_asis + convs->Convert_555_to_888_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 565 dib -> rgb 888 bmp ==== */ /* ==== bgr 565 dib -> bgr 888 bmp ==== */ - X11DRV_DIB_Convert_565_to_888_asis + convs->Convert_565_to_888_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3099,14 +1850,14 @@ if (gSrc==0x03e0) { /* ==== rgb 555 dib -> bgr 888 bmp ==== */ /* ==== bgr 555 dib -> rgb 888 bmp ==== */ - X11DRV_DIB_Convert_555_to_888_reverse + convs->Convert_555_to_888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 565 dib -> bgr 888 bmp ==== */ /* ==== bgr 565 dib -> rgb 888 bmp ==== */ - X11DRV_DIB_Convert_565_to_888_reverse + convs->Convert_565_to_888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3131,14 +1882,14 @@ if (gSrc==0x03e0) { /* ==== rgb 555 dib -> rgb 0888 bmp ==== */ /* ==== bgr 555 dib -> bgr 0888 bmp ==== */ - X11DRV_DIB_Convert_555_to_0888_asis + convs->Convert_555_to_0888_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 565 dib -> rgb 0888 bmp ==== */ /* ==== bgr 565 dib -> bgr 0888 bmp ==== */ - X11DRV_DIB_Convert_565_to_0888_asis + convs->Convert_565_to_0888_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3147,14 +1898,14 @@ if (gSrc==0x03e0) { /* ==== rgb 555 dib -> bgr 0888 bmp ==== */ /* ==== bgr 555 dib -> rgb 0888 bmp ==== */ - X11DRV_DIB_Convert_555_to_0888_reverse + convs->Convert_555_to_0888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 565 dib -> bgr 0888 bmp ==== */ /* ==== bgr 565 dib -> rgb 0888 bmp ==== */ - X11DRV_DIB_Convert_565_to_0888_reverse + convs->Convert_565_to_0888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3240,6 +1991,7 @@ { DWORD x; int h; + dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_invert; DWORD linebytes = dibpitch; @@ -3264,14 +2016,14 @@ if (rDst==bmpImage->red_mask) { /* ==== rgb 555 bmp -> rgb 555 dib ==== */ /* ==== bgr 555 bmp -> bgr 555 dib ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,2, + convs->Convert_5x5_asis + (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 555 bmp -> bgr 555 dib ==== */ /* ==== bgr 555 bmp -> rgb 555 dib ==== */ - X11DRV_DIB_Convert_555_reverse + convs->Convert_555_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3280,14 +2032,14 @@ if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) { /* ==== rgb 555 bmp -> rgb 565 dib ==== */ /* ==== bgr 555 bmp -> bgr 565 dib ==== */ - X11DRV_DIB_Convert_555_to_565_asis + convs->Convert_555_to_565_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 555 bmp -> bgr 565 dib ==== */ /* ==== bgr 555 bmp -> rgb 565 dib ==== */ - X11DRV_DIB_Convert_555_to_565_reverse + convs->Convert_555_to_565_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3298,14 +2050,14 @@ if (rDst == bmpImage->red_mask) { /* ==== rgb 565 bmp -> rgb 565 dib ==== */ /* ==== bgr 565 bmp -> bgr 565 dib ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,2, + convs->Convert_5x5_asis + (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 565 bmp -> bgr 565 dib ==== */ /* ==== bgr 565 bmp -> rgb 565 dib ==== */ - X11DRV_DIB_Convert_565_reverse + convs->Convert_565_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3314,14 +2066,14 @@ if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) { /* ==== rgb 565 bmp -> rgb 555 dib ==== */ /* ==== bgr 565 bmp -> bgr 555 dib ==== */ - X11DRV_DIB_Convert_565_to_555_asis + convs->Convert_565_to_555_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 565 bmp -> bgr 555 dib ==== */ /* ==== bgr 565 bmp -> rgb 555 dib ==== */ - X11DRV_DIB_Convert_565_to_555_reverse + convs->Convert_565_to_555_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3347,14 +2099,14 @@ if (gDst==0x03e0) { /* ==== rgb 888 bmp -> rgb 555 dib ==== */ /* ==== bgr 888 bmp -> bgr 555 dib ==== */ - X11DRV_DIB_Convert_888_to_555_asis + convs->Convert_888_to_555_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 888 bmp -> rgb 565 dib ==== */ /* ==== rgb 888 bmp -> rgb 565 dib ==== */ - X11DRV_DIB_Convert_888_to_565_asis + convs->Convert_888_to_565_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3363,14 +2115,14 @@ if (gDst==0x03e0) { /* ==== rgb 888 bmp -> bgr 555 dib ==== */ /* ==== bgr 888 bmp -> rgb 555 dib ==== */ - X11DRV_DIB_Convert_888_to_555_reverse + convs->Convert_888_to_555_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 888 bmp -> bgr 565 dib ==== */ /* ==== bgr 888 bmp -> rgb 565 dib ==== */ - X11DRV_DIB_Convert_888_to_565_reverse + convs->Convert_888_to_565_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3394,14 +2146,14 @@ if (gDst==0x03e0) { /* ==== rgb 0888 bmp -> rgb 555 dib ==== */ /* ==== bgr 0888 bmp -> bgr 555 dib ==== */ - X11DRV_DIB_Convert_0888_to_555_asis + convs->Convert_0888_to_555_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 0888 bmp -> rgb 565 dib ==== */ /* ==== bgr 0888 bmp -> bgr 565 dib ==== */ - X11DRV_DIB_Convert_0888_to_565_asis + convs->Convert_0888_to_565_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3410,14 +2162,14 @@ if (gDst==0x03e0) { /* ==== rgb 0888 bmp -> bgr 555 dib ==== */ /* ==== bgr 0888 bmp -> rgb 555 dib ==== */ - X11DRV_DIB_Convert_0888_to_555_reverse + convs->Convert_0888_to_555_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 0888 bmp -> bgr 565 dib ==== */ /* ==== bgr 0888 bmp -> rgb 565 dib ==== */ - X11DRV_DIB_Convert_0888_to_565_reverse + convs->Convert_0888_to_565_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3566,6 +2318,7 @@ { DWORD x; int h; + dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_invert; if (lines < 0 ) { @@ -3589,14 +2342,14 @@ } else if (rSrc==bmpImage->red_mask) { /* ==== rgb 888 dib -> rgb 888 bmp ==== */ /* ==== bgr 888 dib -> bgr 888 bmp ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,3, + convs->Convert_888_asis + (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 888 dib -> bgr 888 bmp ==== */ /* ==== bgr 888 dib -> rgb 888 bmp ==== */ - X11DRV_DIB_Convert_888_reverse + convs->Convert_888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3618,14 +2371,14 @@ } else if (rSrc==bmpImage->red_mask) { /* ==== rgb 888 dib -> rgb 0888 bmp ==== */ /* ==== bgr 888 dib -> bgr 0888 bmp ==== */ - X11DRV_DIB_Convert_888_to_0888_asis + convs->Convert_888_to_0888_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== rgb 888 dib -> bgr 0888 bmp ==== */ /* ==== bgr 888 dib -> rgb 0888 bmp ==== */ - X11DRV_DIB_Convert_888_to_0888_reverse + convs->Convert_888_to_0888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3646,7 +2399,7 @@ (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) { /* ==== rgb 888 dib -> rgb 555 bmp ==== */ /* ==== bgr 888 dib -> bgr 555 bmp ==== */ - X11DRV_DIB_Convert_888_to_555_asis + convs->Convert_888_to_555_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3654,7 +2407,7 @@ (bSrc==0xff && bmpImage->blue_mask==0x7f00)) { /* ==== rgb 888 dib -> bgr 555 bmp ==== */ /* ==== bgr 888 dib -> rgb 555 bmp ==== */ - X11DRV_DIB_Convert_888_to_555_reverse + convs->Convert_888_to_555_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3666,7 +2419,7 @@ (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) { /* ==== rgb 888 dib -> rgb 565 bmp ==== */ /* ==== bgr 888 dib -> bgr 565 bmp ==== */ - X11DRV_DIB_Convert_888_to_565_asis + convs->Convert_888_to_565_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3674,7 +2427,7 @@ (bSrc==0xff && bmpImage->blue_mask==0xf800)) { /* ==== rgb 888 dib -> bgr 565 bmp ==== */ /* ==== bgr 888 dib -> rgb 565 bmp ==== */ - X11DRV_DIB_Convert_888_to_565_reverse + convs->Convert_888_to_565_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3731,6 +2484,7 @@ { DWORD x; int h; + dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_invert; if (lines < 0 ) { @@ -3753,14 +2507,14 @@ } else if (rDst==bmpImage->red_mask) { /* ==== rgb 888 bmp -> rgb 888 dib ==== */ /* ==== bgr 888 bmp -> bgr 888 dib ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,3, + convs->Convert_888_asis + (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 888 bmp -> bgr 888 dib ==== */ /* ==== bgr 888 bmp -> rgb 888 dib ==== */ - X11DRV_DIB_Convert_888_reverse + convs->Convert_888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3781,14 +2535,14 @@ } else if (rDst==bmpImage->red_mask) { /* ==== rgb 888 bmp -> rgb 0888 dib ==== */ /* ==== bgr 888 bmp -> bgr 0888 dib ==== */ - X11DRV_DIB_Convert_0888_to_888_asis + convs->Convert_0888_to_888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== rgb 888 bmp -> bgr 0888 dib ==== */ /* ==== bgr 888 bmp -> rgb 0888 dib ==== */ - X11DRV_DIB_Convert_0888_to_888_reverse + convs->Convert_0888_to_888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3808,7 +2562,7 @@ (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) { /* ==== rgb 555 bmp -> rgb 888 dib ==== */ /* ==== bgr 555 bmp -> bgr 888 dib ==== */ - X11DRV_DIB_Convert_555_to_888_asis + convs->Convert_555_to_888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3816,7 +2570,7 @@ (bDst==0xff && bmpImage->blue_mask==0x7f00)) { /* ==== rgb 555 bmp -> bgr 888 dib ==== */ /* ==== bgr 555 bmp -> rgb 888 dib ==== */ - X11DRV_DIB_Convert_555_to_888_reverse + convs->Convert_555_to_888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3828,7 +2582,7 @@ (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) { /* ==== rgb 565 bmp -> rgb 888 dib ==== */ /* ==== bgr 565 bmp -> bgr 888 dib ==== */ - X11DRV_DIB_Convert_565_to_888_asis + convs->Convert_565_to_888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3836,7 +2590,7 @@ (bDst==0xff && bmpImage->blue_mask==0xf800)) { /* ==== rgb 565 bmp -> bgr 888 dib ==== */ /* ==== bgr 565 bmp -> rgb 888 dib ==== */ - X11DRV_DIB_Convert_565_to_888_reverse + convs->Convert_565_to_888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -3945,6 +2699,7 @@ { DWORD x, *ptr; int h; + dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_invert; if (lines < 0 ) { @@ -3967,7 +2722,7 @@ if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) { /* ==== rgb 0888 dib -> rgb 888 bmp ==== */ /* ==== bgr 0888 dib -> bgr 888 bmp ==== */ - X11DRV_DIB_Convert_0888_to_888_asis + convs->Convert_0888_to_888_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -3978,20 +2733,20 @@ } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) { /* ==== rgb 0888 dib -> bgr 888 bmp ==== */ /* ==== bgr 0888 dib -> rgb 888 bmp ==== */ - X11DRV_DIB_Convert_0888_to_888_reverse + convs->Convert_0888_to_888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else if (bmpImage->blue_mask==0xff) { /* ==== any 0888 dib -> rgb 888 bmp ==== */ - X11DRV_DIB_Convert_any0888_to_rgb888 + convs->Convert_any0888_to_rgb888 (dstwidth,lines, srcbits,linebytes, rSrc,gSrc,bSrc, dstbits,-bmpImage->bytes_per_line); } else { /* ==== any 0888 dib -> bgr 888 bmp ==== */ - X11DRV_DIB_Convert_any0888_to_bgr888 + convs->Convert_any0888_to_bgr888 (dstwidth,lines, srcbits,linebytes, rSrc,gSrc,bSrc, @@ -4012,8 +2767,8 @@ if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) { /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */ /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,4, + convs->Convert_0888_asis + (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else if (bmpImage->green_mask!=0x00ff00 || @@ -4023,13 +2778,13 @@ } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) { /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */ /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */ - X11DRV_DIB_Convert_0888_reverse + convs->Convert_0888_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else { /* ==== any 0888 dib -> any 0888 bmp ==== */ - X11DRV_DIB_Convert_0888_any + convs->Convert_0888_any (dstwidth,lines, srcbits,linebytes, rSrc,gSrc,bSrc, @@ -4042,7 +2797,7 @@ /* the tests below assume sane bmpImage masks */ } else { /* ==== any 0888 dib -> any 0888 bmp ==== */ - X11DRV_DIB_Convert_0888_any + convs->Convert_0888_any (dstwidth,lines, srcbits,linebytes, rSrc,gSrc,bSrc, @@ -4064,13 +2819,13 @@ if (bmpImage->green_mask==0x03e0) { if (bmpImage->red_mask==0x7f00) { /* ==== rgb 0888 dib -> rgb 555 bmp ==== */ - X11DRV_DIB_Convert_0888_to_555_asis + convs->Convert_0888_to_555_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else if (bmpImage->blue_mask==0x7f00) { /* ==== rgb 0888 dib -> bgr 555 bmp ==== */ - X11DRV_DIB_Convert_0888_to_555_reverse + convs->Convert_0888_to_555_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -4080,13 +2835,13 @@ } else if (bmpImage->green_mask==0x07e0) { if (bmpImage->red_mask==0xf800) { /* ==== rgb 0888 dib -> rgb 565 bmp ==== */ - X11DRV_DIB_Convert_0888_to_565_asis + convs->Convert_0888_to_565_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else if (bmpImage->blue_mask==0xf800) { /* ==== rgb 0888 dib -> bgr 565 bmp ==== */ - X11DRV_DIB_Convert_0888_to_565_reverse + convs->Convert_0888_to_565_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -4100,13 +2855,13 @@ if (bmpImage->green_mask==0x03e0) { if (bmpImage->blue_mask==0x7f00) { /* ==== bgr 0888 dib -> bgr 555 bmp ==== */ - X11DRV_DIB_Convert_0888_to_555_asis + convs->Convert_0888_to_555_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else if (bmpImage->red_mask==0x7f00) { /* ==== bgr 0888 dib -> rgb 555 bmp ==== */ - X11DRV_DIB_Convert_0888_to_555_reverse + convs->Convert_0888_to_555_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -4116,13 +2871,13 @@ } else if (bmpImage->green_mask==0x07e0) { if (bmpImage->blue_mask==0xf800) { /* ==== bgr 0888 dib -> bgr 565 bmp ==== */ - X11DRV_DIB_Convert_0888_to_565_asis + convs->Convert_0888_to_565_asis (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); } else if (bmpImage->red_mask==0xf800) { /* ==== bgr 0888 dib -> rgb 565 bmp ==== */ - X11DRV_DIB_Convert_0888_to_565_reverse + convs->Convert_0888_to_565_reverse (dstwidth,lines, srcbits,linebytes, dstbits,-bmpImage->bytes_per_line); @@ -4137,7 +2892,7 @@ (bmpImage->red_mask==0x7f00 || bmpImage->blue_mask==0x7f00)) { /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */ - X11DRV_DIB_Convert_any0888_to_5x5 + convs->Convert_any0888_to_5x5 (dstwidth,lines, srcbits,linebytes, rSrc,gSrc,bSrc, @@ -4147,7 +2902,7 @@ (bmpImage->red_mask==0xf800 || bmpImage->blue_mask==0xf800)) { /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */ - X11DRV_DIB_Convert_any0888_to_5x5 + convs->Convert_any0888_to_5x5 (dstwidth,lines, srcbits,linebytes, rSrc,gSrc,bSrc, @@ -4212,6 +2967,7 @@ DWORD x; int h; BYTE *bits; + dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_invert; if (lines < 0 ) { @@ -4233,7 +2989,7 @@ if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) { /* ==== rgb 888 bmp -> rgb 0888 dib ==== */ /* ==== bgr 888 bmp -> bgr 0888 dib ==== */ - X11DRV_DIB_Convert_888_to_0888_asis + convs->Convert_888_to_0888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -4244,20 +3000,20 @@ } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) { /* ==== rgb 888 bmp -> bgr 0888 dib ==== */ /* ==== bgr 888 bmp -> rgb 0888 dib ==== */ - X11DRV_DIB_Convert_888_to_0888_reverse + convs->Convert_888_to_0888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else if (bmpImage->blue_mask==0xff) { /* ==== rgb 888 bmp -> any 0888 dib ==== */ - X11DRV_DIB_Convert_rgb888_to_any0888 + convs->Convert_rgb888_to_any0888 (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes, rDst,gDst,bDst); } else { /* ==== bgr 888 bmp -> any 0888 dib ==== */ - X11DRV_DIB_Convert_bgr888_to_any0888 + convs->Convert_bgr888_to_any0888 (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes, @@ -4277,8 +3033,8 @@ if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) { /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */ /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */ - X11DRV_DIB_Convert_any_asis - (dstwidth,lines,4, + convs->Convert_0888_asis + (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else if (bmpImage->green_mask!=0x00ff00 || @@ -4288,13 +3044,13 @@ } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) { /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */ /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */ - X11DRV_DIB_Convert_0888_reverse + convs->Convert_0888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else { /* ==== any 0888 bmp -> any 0888 dib ==== */ - X11DRV_DIB_Convert_0888_any + convs->Convert_0888_any (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask, @@ -4307,7 +3063,7 @@ /* the tests below assume sane bmpImage masks */ } else { /* ==== any 0888 bmp -> any 0888 dib ==== */ - X11DRV_DIB_Convert_0888_any + convs->Convert_0888_any (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask, @@ -4328,13 +3084,13 @@ if (bmpImage->green_mask==0x03e0) { if (bmpImage->red_mask==0x7f00) { /* ==== rgb 555 bmp -> rgb 0888 dib ==== */ - X11DRV_DIB_Convert_555_to_0888_asis + convs->Convert_555_to_0888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else if (bmpImage->blue_mask==0x7f00) { /* ==== bgr 555 bmp -> rgb 0888 dib ==== */ - X11DRV_DIB_Convert_555_to_0888_reverse + convs->Convert_555_to_0888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -4344,13 +3100,13 @@ } else if (bmpImage->green_mask==0x07e0) { if (bmpImage->red_mask==0xf800) { /* ==== rgb 565 bmp -> rgb 0888 dib ==== */ - X11DRV_DIB_Convert_565_to_0888_asis + convs->Convert_565_to_0888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else if (bmpImage->blue_mask==0xf800) { /* ==== bgr 565 bmp -> rgb 0888 dib ==== */ - X11DRV_DIB_Convert_565_to_0888_reverse + convs->Convert_565_to_0888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -4364,13 +3120,13 @@ if (bmpImage->green_mask==0x03e0) { if (bmpImage->blue_mask==0x7f00) { /* ==== bgr 555 bmp -> bgr 0888 dib ==== */ - X11DRV_DIB_Convert_555_to_0888_asis + convs->Convert_555_to_0888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else if (bmpImage->red_mask==0x7f00) { /* ==== rgb 555 bmp -> bgr 0888 dib ==== */ - X11DRV_DIB_Convert_555_to_0888_reverse + convs->Convert_555_to_0888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -4380,13 +3136,13 @@ } else if (bmpImage->green_mask==0x07e0) { if (bmpImage->blue_mask==0xf800) { /* ==== bgr 565 bmp -> bgr 0888 dib ==== */ - X11DRV_DIB_Convert_565_to_0888_asis + convs->Convert_565_to_0888_asis (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); } else if (bmpImage->red_mask==0xf800) { /* ==== rgb 565 bmp -> bgr 0888 dib ==== */ - X11DRV_DIB_Convert_565_to_0888_reverse + convs->Convert_565_to_0888_reverse (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, dstbits,linebytes); @@ -4401,7 +3157,7 @@ (bmpImage->red_mask==0x7f00 || bmpImage->blue_mask==0x7f00)) { /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */ - X11DRV_DIB_Convert_5x5_to_any0888 + convs->Convert_5x5_to_any0888 (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask, @@ -4411,7 +3167,7 @@ (bmpImage->red_mask==0xf800 || bmpImage->blue_mask==0xf800)) { /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */ - X11DRV_DIB_Convert_5x5_to_any0888 + convs->Convert_5x5_to_any0888 (dstwidth,lines, srcbits,-bmpImage->bytes_per_line, bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask, --- /dev/null 2003-01-30 10:24:37.000000000 +0000 +++ dlls/x11drv/dib_convert.c 2003-11-10 15:55:18.000000000 +0000 @@ -0,0 +1,1348 @@ +/* + * DIB conversion routinues for cases where the source and destination + * have the same byte order. + * + * Copyright (C) 2001 Francois Gouget + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdlib.h> + +#include "wine/debug.h" +#include "windef.h" +#include "config.h" +#include "x11drv.h" + + +/*********************************************************************** + * X11DRV_DIB_Convert_* + * + * All X11DRV_DIB_Convert_Xxx functions take at least the following + * parameters: + * - width + * This is the width in pixel of the surface to copy. This may be less + * than the full width of the image. + * - height + * The number of lines to copy. This may be less than the full height + * of the image. This is always >0. + * - srcbits + * Points to the first byte containing data to be copied. If the source + * surface starts are coordinates (x,y) then this is: + * image_ptr+x*bytes_pre_pixel+y*bytes_per_line + * (with further adjustments for top-down/bottom-up images) + * - srclinebytes + * This is the number of bytes per line. It may be >0 or <0 depending on + * whether this is a top-down or bottom-up image. + * - dstbits + * Same as srcbits but for the destination + * - dstlinebytes + * Same as srclinebytes but for the destination. + * + * Notes: + * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555, + * rgb565, bgr565, rgb888 and any 32bit (0888) format. + * The supported XImage (Bmp) formats are: pal1, pal4, pal8, + * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888. + * - Rgb formats are those for which the masks are such that: + * red_mask > green_mask > blue_mask + * - Bgr formats are those for which the masks sort in the other direction. + * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions + * so the comments use h, g, l to mean respectively the source color in the + * high bits, the green, and the source color in the low bits. + */ + + +/* + * 15 bit conversions + */ + +static void convert_5x5_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int y; + + for (y=0; y<height; y++) { + memcpy(dstbits, srcbits, width*2); + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + + +static void convert_555_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */ + ( srcval & 0x03e003e0) | /* g */ + ((srcval >> 10) & 0x001f001f); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */ + ( srcval & 0x03e0) | /* g */ + ((srcval >> 10) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_565_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */ + ((srcval >> 4) & 0x00200020) | /* g - 1 bit */ + ( srcval & 0x001f001f); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */ + ((srcval >> 4) & 0x0020) | /* g - 1 bit */ + (srcval & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_565_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */ + ((srcval << 1) & 0x07c007c0) | /* g */ + ((srcval >> 4) & 0x00200020) | /* g - 1 bit */ + ((srcval << 11) & 0xf800f800); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */ + ((srcval << 1) & 0x07c0) | /* g */ + ((srcval >> 4) & 0x0020) | /* g - 1 bit */ + ((srcval << 11) & 0xf800); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval << 3) & 0xf8) | /* l */ + ((srcval >> 2) & 0x07); /* l - 3 bits */ + dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */ + ((srcval >> 7) & 0x07); /* g - 3 bits */ + dstpixel[2]=((srcval >> 7) & 0xf8) | /* h */ + ((srcval >> 12) & 0x07); /* h - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval >> 7) & 0xf8) | /* h */ + ((srcval >> 12) & 0x07); /* h - 3 bits */ + dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */ + ((srcval >> 7) & 0x07); /* g - 3 bits */ + dstpixel[2]=((srcval << 3) & 0xf8) | /* l */ + ((srcval >> 2) & 0x07); /* l - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_0888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 9) & 0xf80000) | /* h */ + ((srcval << 4) & 0x070000) | /* h - 3 bits */ + ((srcval << 6) & 0x00f800) | /* g */ + ((srcval << 1) & 0x000700) | /* g - 3 bits */ + ((srcval << 3) & 0x0000f8) | /* l */ + ((srcval >> 2) & 0x000007); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_0888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 7) & 0x0000f8) | /* h */ + ((srcval >> 12) & 0x000007) | /* h - 3 bits */ + ((srcval << 6) & 0x00f800) | /* g */ + ((srcval << 1) & 0x000700) | /* g - 3 bits */ + ((srcval << 19) & 0xf80000) | /* l */ + ((srcval << 14) & 0x070000); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_5x5_to_any0888(int width, int height, + const void* srcbits, int srclinebytes, + WORD rsrc, WORD gsrc, WORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rRightShift1,gRightShift1,bRightShift1; + int rRightShift2,gRightShift2,bRightShift2; + BYTE gMask1,gMask2; + int rLeftShift,gLeftShift,bLeftShift; + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + /* Note, the source pixel value is shifted left by 16 bits so that + * we know we will always have to shift right to extract the components. + */ + rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3; + gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3; + bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3; + rRightShift2=rRightShift1+5; + gRightShift2=gRightShift1+5; + bRightShift2=bRightShift1+5; + if (gsrc==0x03e0) { + /* Green has 5 bits, like the others */ + gMask1=0xf8; + gMask2=0x07; + } else { + /* Green has 6 bits, not 5. Compensate. */ + gRightShift1++; + gRightShift2+=2; + gMask1=0xfc; + gMask2=0x03; + } + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + BYTE red,green,blue; + srcval=*srcpixel++ << 16; + red= ((srcval >> rRightShift1) & 0xf8) | + ((srcval >> rRightShift2) & 0x07); + green=((srcval >> gRightShift1) & gMask1) | + ((srcval >> gRightShift2) & gMask2); + blue= ((srcval >> bRightShift1) & 0xf8) | + ((srcval >> bRightShift2) & 0x07); + *dstpixel++=(red << rLeftShift) | + (green << gLeftShift) | + (blue << bLeftShift); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +/* + * 16 bits conversions + */ + +static void convert_565_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */ + ( srcval & 0x07e007e0) | /* g */ + ((srcval >> 11) & 0x001f001f); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */ + ( srcval & 0x07e0) | /* g */ + ((srcval >> 11) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_555_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */ + ( srcval & 0x001f001f); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */ + ( srcval & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_555_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */ + ((srcval >> 1) & 0x03e003e0) | /* g */ + ((srcval << 10) & 0x7c007c00); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */ + ((srcval >> 1) & 0x03e0) | /* g */ + ((srcval << 10) & 0x7c00); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval << 3) & 0xf8) | /* l */ + ((srcval >> 2) & 0x07); /* l - 3 bits */ + dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */ + ((srcval >> 9) & 0x03); /* g - 2 bits */ + dstpixel[2]=((srcval >> 8) & 0xf8) | /* h */ + ((srcval >> 13) & 0x07); /* h - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval >> 8) & 0xf8) | /* h */ + ((srcval >> 13) & 0x07); /* h - 3 bits */ + dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */ + ((srcval >> 9) & 0x03); /* g - 2 bits */ + dstpixel[2]=((srcval << 3) & 0xf8) | /* l */ + ((srcval >> 2) & 0x07); /* l - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_0888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 8) & 0xf80000) | /* h */ + ((srcval << 3) & 0x070000) | /* h - 3 bits */ + ((srcval << 5) & 0x00fc00) | /* g */ + ((srcval >> 1) & 0x000300) | /* g - 2 bits */ + ((srcval << 3) & 0x0000f8) | /* l */ + ((srcval >> 2) & 0x000007); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_0888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 8) & 0x0000f8) | /* h */ + ((srcval >> 13) & 0x000007) | /* h - 3 bits */ + ((srcval << 5) & 0x00fc00) | /* g */ + ((srcval >> 1) & 0x000300) | /* g - 2 bits */ + ((srcval << 19) & 0xf80000) | /* l */ + ((srcval << 14) & 0x070000); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + + +/* + * 24 bit conversions + */ + +static void convert_888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int y; + + for (y=0; y<height; y++) { + memcpy(dstbits, srcbits, width*3); + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + + +static void convert_888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const BYTE* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + dstpixel[0]=srcpixel[2]; + dstpixel[1]=srcpixel[1]; + dstpixel[2]=srcpixel[0]; + srcpixel+=3; + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_555_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */ + ((srcval1 >> 6) & 0x03e0) | /* g1 */ + ((srcval1 >> 9) & 0x7c00); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */ + ((srcval2 << 2) & 0x03e0) | /* g2 */ + ((srcval2 >> 1) & 0x7c00); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */ + ((srcval2 >> 22) & 0x03e0) | /* g3 */ + ((srcval1 << 7) & 0x7c00); /* h3 */ + dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */ + ((srcval1 >> 14) & 0x03e0) | /* g4 */ + ((srcval1 >> 17) & 0x7c00); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] >> 3) & 0x001f); /* l */ + dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */ + dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_555_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */ + ((srcval1 >> 6) & 0x03e0) | /* g1 */ + ((srcval1 >> 19) & 0x001f); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */ + ((srcval2 << 2) & 0x03e0) | /* g2 */ + ((srcval2 >> 11) & 0x001f); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */ + ((srcval2 >> 22) & 0x03e0) | /* g3 */ + ((srcval1 >> 3) & 0x001f); /* h3 */ + dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */ + ((srcval1 >> 14) & 0x03e0) | /* g4 */ + ((srcval1 >> 27) & 0x001f); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] << 7) & 0x7c00); /* l */ + dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */ + dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_565_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */ + ((srcval1 >> 5) & 0x07e0) | /* g1 */ + ((srcval1 >> 8) & 0xf800); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */ + ((srcval2 << 3) & 0x07e0) | /* g2 */ + ( srcval2 & 0xf800); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */ + ((srcval2 >> 21) & 0x07e0) | /* g3 */ + ((srcval1 << 8) & 0xf800); /* h3 */ + dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */ + ((srcval1 >> 13) & 0x07e0) | /* g4 */ + ((srcval1 >> 16) & 0xf800); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] >> 3) & 0x001f); /* l */ + dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */ + dstval|=((srcbyte[2] << 8) & 0xf800); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_565_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */ + ((srcval1 >> 5) & 0x07e0) | /* g1 */ + ((srcval1 >> 19) & 0x001f); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */ + ((srcval2 << 3) & 0x07e0) | /* g2 */ + ((srcval2 >> 11) & 0x001f); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */ + ((srcval2 >> 21) & 0x07e0) | /* g3 */ + ((srcval1 >> 3) & 0x001f); /* h3 */ + dstpixel[3]=(srcval1 & 0xf800) | /* l4 */ + ((srcval1 >> 13) & 0x07e0) | /* g4 */ + ((srcval1 >> 27) & 0x001f); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] << 8) & 0xf800); /* l */ + dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */ + dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_0888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */ + srcval2=srcpixel[1]; + dstpixel[1]=( srcval1 >> 24) | /* l2 */ + ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */ + srcval1=srcpixel[2]; + dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */ + ((srcval1 << 16) & 0x00ff0000); /* h3 */ + dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_0888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1,srcval2; + + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */ + ( srcval1 & 0x00ff00) | /* g1 */ + ((srcval1 << 16) & 0xff0000); /* l1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */ + ((srcval2 << 8) & 0x00ff00) | /* g2 */ + ((srcval2 >> 8) & 0x0000ff); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */ + ((srcval2 >> 16) & 0x00ff00) | /* g3 */ + ( srcval1 & 0x0000ff); /* h3 */ + dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */ + ((srcval1 >> 8) & 0x00ff00) | /* g4 */ + ((srcval1 << 8) & 0xff0000); /* l4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */ + ( srcval & 0x00ff00) | /* g */ + ((srcval << 16) & 0xff0000); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_rgb888_to_any0888(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rLeftShift,gLeftShift,bLeftShift; + const BYTE* srcpixel; + DWORD* dstpixel; + int x,y; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */ + (srcpixel[1] << gLeftShift) | /* g */ + (srcpixel[2] << rLeftShift); /* r */ + srcpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_bgr888_to_any0888(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rLeftShift,gLeftShift,bLeftShift; + const BYTE* srcpixel; + DWORD* dstpixel; + int x,y; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */ + (srcpixel[1] << gLeftShift) | /* g */ + (srcpixel[2] << bLeftShift); /* b */ + srcpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +/* + * 32 bit conversions + */ + +static void convert_0888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int y; + + for (y=0; y<height; y++) { + memcpy(dstbits, srcbits, width*4); + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */ + ( srcval & 0x0000ff00) | /* g */ + ((srcval >> 16) & 0x000000ff); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_any(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rRightShift,gRightShift,bRightShift; + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) | + (((srcval >> gRightShift) & 0xff) << gLeftShift) | + (((srcval >> bRightShift) & 0xff) << bLeftShift); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_555_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */ + ((srcval >> 6) & 0x03e0) | /* g */ + ((srcval >> 3) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_555_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 19) & 0x001f) | /* h */ + ((srcval >> 6) & 0x03e0) | /* g */ + ((srcval << 7) & 0x7c00); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_565_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 8) & 0xf800) | /* h */ + ((srcval >> 5) & 0x07e0) | /* g */ + ((srcval >> 3) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_565_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 19) & 0x001f) | /* h */ + ((srcval >> 5) & 0x07e0) | /* g */ + ((srcval << 8) & 0xf800); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_5x5(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + WORD rdst, WORD gdst, WORD bdst) +{ + int rRightShift,gRightShift,bRightShift; + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel + * contains 0x11223344. + * - first we shift 0x11223344 right by rRightShift to bring the most + * significant bits of the red components in the bottom 5 (or 6) bits + * -> 0x4488c + * - then we remove non red bits by anding with the modified rdst (0x1f) + * -> 0x0c + * - finally shift these bits left by rLeftShift so that they end up in + * the right place + * -> 0x3000 + */ + rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3; + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + gRightShift+=(gdst==0x07e0?2:3); + bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + rdst=rdst >> rLeftShift; + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + gdst=gdst >> gLeftShift; + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + bdst=bdst >> bLeftShift; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) | + (((srcval >> gRightShift) & gdst) << gLeftShift) | + (((srcval >> bRightShift) & bdst) << bLeftShift); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_888_asis(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + BYTE* dstbyte; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ + DWORD srcval; + srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/ + *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */ + srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */ + *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */ + srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */ + *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */ + } + /* And now up to 3 odd pixels */ + dstbyte=(BYTE*)dstpixel; + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel++; + *((WORD*)dstbyte)++=srcval; /* h, g */ + *dstbyte++=srcval >> 16; /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_888_reverse(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + BYTE* dstbyte; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ + DWORD srcval1,srcval2; + srcval1=*srcpixel++; + srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */ + ( srcval1 & 0x0000ff00) | /* g1 */ + ((srcval1 << 16) & 0x00ff0000); /* l1 */ + srcval1=*srcpixel++; + *dstpixel++=srcval2 | + ((srcval1 << 8) & 0xff000000); /* h2 */ + srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */ + ((srcval1 << 8) & 0x0000ff00); /* l2 */ + srcval1=*srcpixel++; + *dstpixel++=srcval2 | + ( srcval1 & 0x00ff0000) | /* h3 */ + ((srcval1 << 16) & 0xff000000); /* g3 */ + srcval2= ( srcval1 & 0x000000ff); /* l3 */ + srcval1=*srcpixel++; + *dstpixel++=srcval2 | + ((srcval1 >> 8) & 0x0000ff00) | /* h4 */ + ((srcval1 << 8) & 0x00ff0000) | /* g4 */ + ( srcval1 << 24); /* l4 */ + } + /* And now up to 3 odd pixels */ + dstbyte=(BYTE*)dstpixel; + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel++; + *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */ + (srcval & 0xff00); /* g */ + *dstbyte++=srcval; /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_rgb888(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes) +{ + int rRightShift,gRightShift,bRightShift; + const DWORD* srcpixel; + BYTE* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + dstpixel[0]=(srcval >> bRightShift); /* b */ + dstpixel[1]=(srcval >> gRightShift); /* g */ + dstpixel[2]=(srcval >> rRightShift); /* r */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_bgr888(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes) +{ + int rRightShift,gRightShift,bRightShift; + const DWORD* srcpixel; + BYTE* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + dstpixel[0]=(srcval >> rRightShift); /* r */ + dstpixel[1]=(srcval >> gRightShift); /* g */ + dstpixel[2]=(srcval >> bRightShift); /* b */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +dib_conversions dib_normal = { + convert_5x5_asis, + convert_555_reverse, + convert_555_to_565_asis, + convert_555_to_565_reverse, + convert_555_to_888_asis, + convert_555_to_888_reverse, + convert_555_to_0888_asis, + convert_555_to_0888_reverse, + convert_5x5_to_any0888, + convert_565_reverse, + convert_565_to_555_asis, + convert_565_to_555_reverse, + convert_565_to_888_asis, + convert_565_to_888_reverse, + convert_565_to_0888_asis, + convert_565_to_0888_reverse, + convert_888_asis, + convert_888_reverse, + convert_888_to_555_asis, + convert_888_to_555_reverse, + convert_888_to_565_asis, + convert_888_to_565_reverse, + convert_888_to_0888_asis, + convert_888_to_0888_reverse, + convert_rgb888_to_any0888, + convert_bgr888_to_any0888, + convert_0888_asis, + convert_0888_reverse, + convert_0888_any, + convert_0888_to_555_asis, + convert_0888_to_555_reverse, + convert_0888_to_565_asis, + convert_0888_to_565_reverse, + convert_any0888_to_5x5, + convert_0888_to_888_asis, + convert_0888_to_888_reverse, + convert_any0888_to_rgb888, + convert_any0888_to_bgr888 +}; --- /dev/null 2003-01-30 10:24:37.000000000 +0000 +++ dlls/x11drv/dib_convert_di.c 2003-11-10 15:55:18.000000000 +0000 @@ -0,0 +1,1575 @@ +/* + * DIB conversion routinues for cases where the destination + * has non-native byte order. + * + * Copyright (C) 2003 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdlib.h> + +#include "wine/debug.h" +#include "windef.h" +#include "config.h" +#include "x11drv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(bitmap); + +#define FLIP_WORD(x) \ + ( *(x) = ( (*(x) & 0xff) << 8) | \ + ( (*(x) & 0xff00) >> 8) ) + +#define FLIP_TWO_WORDS(x) \ + ( *(x) = ( (*(x) & 0x00ff00ff) << 8) | \ + ( (*(x) & 0xff00ff00) >> 8) ) + +#define FLIP_DWORD(x) \ + ( *(x) = ( (*(x) & 0xff) << 24) | \ + ( (*(x) & 0xff00) << 8) | \ + ( (*(x) & 0xff0000) >> 8) | \ + ( (*(x) & 0xff000000) >> 24) ) + + +/* + * 15 bit conversions + */ + +static void convert_5x5_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int x, y; + const DWORD *srcpixel; + DWORD *dstpixel; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for(x = 0; x < width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval = *srcpixel++; + *dstpixel++=((srcval << 8) & 0xff00ff00) | + ((srcval >> 8) & 0x00ff00ff); + } + if(width&1) { + /* And the odd pixel */ + WORD srcval = *(WORD*)srcpixel; + *(WORD*)dstpixel = ((srcval << 8) & 0xff00) | + ((srcval >> 8) & 0x00ff); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 2) & 0x1f001f00) | /* h */ + ((srcval >> 8) & 0x00030003) | /* g - 2 bits */ + ((srcval << 8) & 0xe000e000) | /* g - 3 bits */ + ((srcval << 2) & 0x007c007c); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 2) & 0x1f00) | /* h */ + ((srcval >> 8) & 0x0003) | /* g - 2 bits */ + ((srcval << 8) & 0xe000) | /* g - 3 bits */ + ((srcval << 2) & 0x007c); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_565_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 7) & 0x00ff00ff) | /* h, g - 3 bits */ + ((srcval << 9) & 0xc000c000) | /* g - 2 bits */ + ((srcval << 4) & 0x20002000) | /* g - 1 bits */ + ((srcval << 8) & 0x1f001f00); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 7) & 0x00ff) | /* h, g - 3 bits */ + ((srcval << 9) & 0xc000) | /* g - 2 bits */ + ((srcval << 4) & 0x2000) | /* g - 1 bit */ + ((srcval << 8) & 0x1f00); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_565_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 2) & 0x1f001f00) | /* h */ + ((srcval >> 7) & 0x00070007) | /* g - 3 bits */ + ((srcval << 9) & 0xc000c000) | /* g - 2 bits */ + ((srcval << 4) & 0x20002000) | /* g - 1 bit */ + ((srcval << 3) & 0x00f800f8); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 2) & 0x1f00) | /* h */ + ((srcval >> 7) & 0x0007) | /* g - 3 bits */ + ((srcval << 9) & 0xc000) | /* g - 2 bits */ + ((srcval << 4) & 0x2000) | /* g - 1 bit */ + ((srcval << 3) & 0x00f8); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/4; x++) { + /* Do 4 pixels at a time. 4 words in 3 dwords out */ + DWORD srcval1, srcval2; + srcval1=(DWORD)*srcpixel++; + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 27) & 0xf8000000) | /* l1 */ + ((srcval1 << 22) & 0x07000000) | /* l1 - 3 bits */ + ((srcval1 << 14) & 0x00f80000) | /* g1 */ + ((srcval1 << 9) & 0x00070000) | /* g1 - 3 bits */ + ((srcval1 << 1) & 0x0000f800) | /* h1 */ + ((srcval1 >> 4) & 0x00070000) | /* h1 - 3 bits */ + ((srcval2 << 3) & 0x000000f8) | /* l2 */ + ((srcval2 >> 2) & 0x00000007); /* l2 - 3 bits */ + srcval1=(DWORD)*srcpixel++; + *dstpixel++= ((srcval2 << 22) & 0xf8000000) | /* g2 */ + ((srcval2 << 17) & 0x07000000) | /* g2 - 3 bits */ + ((srcval2 << 9) & 0x00f80000) | /* h2 */ + ((srcval2 << 4) & 0x00070000) | /* h2 - 3 bits */ + ((srcval1 << 11) & 0x0000f800) | /* l3 */ + ((srcval1 << 6) & 0x00000700) | /* l3 - 3 bits */ + ((srcval1 >> 2) & 0x000000f8) | /* g3 */ + ((srcval1 >> 7) & 0x00000007); /* g3 - 3 bits */ + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 17) & 0xf8000000) | /* h3 */ + ((srcval1 << 12) & 0x07000000) | /* h3 - 3 bits */ + ((srcval2 << 19) & 0x00f80000) | /* l4 */ + ((srcval2 << 14) & 0x00070000) | /* l4 - 3 bits */ + ((srcval2 << 6) & 0x0000f800) | /* g4 */ + ((srcval2 << 1) & 0x00000700) | /* g4 - 3 bits */ + ((srcval2 >> 7) & 0x000000f8) | /* h4 */ + ((srcval2 >> 12) & 0x00000007); /* h4 - 3 bits */ + } + if(width&3) { + BYTE *dstbyte = (BYTE*)dstpixel; + DWORD srcval; + for(x = 0; x < (width&3); x++) { + srcval = *srcpixel++; + dstbyte[0] = ((srcval << 3) & 0xf8) | ((srcval >> 2) & 0x07); + dstbyte[1] = ((srcval >> 2) & 0xf8) | ((srcval >> 7) & 0x07); + dstbyte[2] = ((srcval >> 7) & 0xf8) | ((srcval >> 12) & 0x07); + dstbyte+=3; + if(x > 0) + FLIP_DWORD(dstpixel + x - 1); + } + FLIP_DWORD(dstpixel + x - 1); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/4; x++) { + /* Do 4 pixels at a time. 4 words in 3 dwords out */ + DWORD srcval1, srcval2; + srcval1=(DWORD)*srcpixel++; + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 17) & 0xf8000000) | /* h1 */ + ((srcval1 << 12) & 0x07000000) | /* h1 - 3 bits */ + ((srcval1 << 14) & 0x00f80000) | /* g1 */ + ((srcval1 << 9) & 0x00070000) | /* g1 - 3 bits */ + ((srcval1 << 11) & 0x0000f800) | /* l1 */ + ((srcval1 << 6) & 0x00070000) | /* l1 - 3 bits */ + ((srcval2 >> 7) & 0x000000f8) | /* h2 */ + ((srcval2 >> 12) & 0x00000007); /* h2 - 3 bits */ + srcval1=(DWORD)*srcpixel++; + *dstpixel++= ((srcval2 << 22) & 0xf8000000) | /* g2 */ + ((srcval2 << 17) & 0x07000000) | /* g2 - 3 bits */ + ((srcval2 << 19) & 0x00f80000) | /* l2 */ + ((srcval2 << 14) & 0x00070000) | /* l2 - 3 bits */ + ((srcval1 << 1) & 0x0000f800) | /* h3 */ + ((srcval1 >> 4) & 0x00000700) | /* h3 - 3 bits */ + ((srcval1 >> 2) & 0x000000f8) | /* g3 */ + ((srcval1 >> 7) & 0x00000007); /* g3 - 3 bits */ + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 27) & 0xf8000000) | /* l3 */ + ((srcval1 << 22) & 0x07000000) | /* l3 - 3 bits */ + ((srcval2 << 9) & 0x00f80000) | /* h4 */ + ((srcval2 << 4) & 0x00070000) | /* h4 - 3 bits */ + ((srcval2 << 6) & 0x0000f800) | /* g4 */ + ((srcval2 << 1) & 0x00000700) | /* g4 - 3 bits */ + ((srcval2 << 3) & 0x000000f8) | /* l4 */ + ((srcval2 >> 2) & 0x00000007); /* l4 - 3 bits */ + } + if(width&3) { + BYTE *dstbyte = (BYTE*)dstpixel; + DWORD srcval; + for(x = 0; x < (width&3); x++) { + srcval = *srcpixel++; + dstbyte[2] = ((srcval << 3) & 0xf8) | ((srcval >> 2) & 0x07); + dstbyte[1] = ((srcval >> 2) & 0xf8) | ((srcval >> 7) & 0x07); + dstbyte[0] = ((srcval >> 7) & 0xf8) | ((srcval >> 12) & 0x07); + dstbyte+=3; + if(x > 0) + FLIP_DWORD(dstpixel + x - 1); + } + FLIP_DWORD(dstpixel + x - 1); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_0888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 1) & 0x0000f800) | /* h */ + ((srcval >> 4) & 0x00000700) | /* h - 3 bits */ + ((srcval << 14) & 0x00f80000) | /* g */ + ((srcval << 9) & 0x00070000) | /* g - 3 bits */ + ((srcval << 27) & 0xf8000000) | /* l */ + ((srcval << 22) & 0x07000000); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_0888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 17) & 0xf8000000) | /* h */ + ((srcval << 12) & 0x07000000) | /* h - 3 bits */ + ((srcval << 14) & 0x00f80000) | /* g */ + ((srcval << 9) & 0x00070000) | /* g - 3 bits */ + ((srcval << 11) & 0x0000f800) | /* l */ + ((srcval << 6) & 0x00000700); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_5x5_to_any0888_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + WORD rsrc, WORD gsrc, WORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rRightShift1,gRightShift1,bRightShift1; + int rRightShift2,gRightShift2,bRightShift2; + BYTE gMask1,gMask2; + int rLeftShift,gLeftShift,bLeftShift; + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + /* Note, the source pixel value is shifted left by 16 bits so that + * we know we will always have to shift right to extract the components. + */ + rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3; + gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3; + bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3; + rRightShift2=rRightShift1+5; + gRightShift2=gRightShift1+5; + bRightShift2=bRightShift1+5; + if (gsrc==0x03e0) { + /* Green has 5 bits, like the others */ + gMask1=0xf8; + gMask2=0x07; + } else { + /* Green has 6 bits, not 5. Compensate. */ + gRightShift1++; + gRightShift2+=2; + gMask1=0xfc; + gMask2=0x03; + } + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + BYTE red,green,blue; + srcval=*srcpixel++ << 16; + red= ((srcval >> rRightShift1) & 0xf8) | + ((srcval >> rRightShift2) & 0x07); + green=((srcval >> gRightShift1) & gMask1) | + ((srcval >> gRightShift2) & gMask2); + blue= ((srcval >> bRightShift1) & 0xf8) | + ((srcval >> bRightShift2) & 0x07); + *dstpixel =(red << rLeftShift) | + (green << gLeftShift) | + (blue << bLeftShift); + FLIP_DWORD(dstpixel); + dstpixel++; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +/* + * 16 bits conversions + */ + +static void convert_565_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 3) & 0x1f001f00) | /* h */ + ((srcval >> 8) & 0x00070007) | /* g - 3 bits */ + ((srcval << 8) & 0xe000e000) | /* g - 3 bits */ + ((srcval << 3) & 0x00f800f8); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 3) & 0x1f00) | /* h */ + ((srcval >> 8) & 0x0007) | /* g - 3 bits */ + ((srcval << 8) & 0xe000) | /* g - 3 bits */ + ((srcval << 3) & 0x00f8); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_555_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 7) & 0xe000e000) | /* g - 3 bits */ + ((srcval << 8) & 0x1f001f00) | /* l */ + ((srcval >> 9) & 0x007f007f); /* h, g - 2 bits */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 7) & 0xe000) | /* g - 3 bits*/ + ((srcval << 8) & 0x1f00) | /* l */ + ((srcval >> 9) & 0x007f); /* h, g - 2 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_555_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 7) & 0xe000e000) | /* g - 3 bits */ + ((srcval >> 3) & 0x1f001f00) | /* l */ + ((srcval << 2) & 0x007c007c) | /* h */ + ((srcval >> 9) & 0x00030003); /* g - 2 bits */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 7) & 0xe000) | /* g - 3 bits */ + ((srcval >> 3) & 0x1f00) | /* l */ + ((srcval << 2) & 0x007c) | /* h */ + ((srcval >> 9) & 0x0003); /* g - 2 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/4; x++) { + /* Do 4 pixels at a time. 4 words in 3 dwords out */ + DWORD srcval1, srcval2; + srcval1=(DWORD)*srcpixel++; + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 27) & 0xf8000000) | /* l1 */ + ((srcval1 << 22) & 0x07000000) | /* l1 - 3 bits */ + ((srcval1 << 13) & 0x00fc0000) | /* g1 */ + ((srcval1 << 7) & 0x00030000) | /* g1 - 2 bits */ + ((srcval1 << 0) & 0x0000f800) | /* h1 */ + ((srcval1 >> 5) & 0x00070000) | /* h1 - 3 bits */ + ((srcval2 << 3) & 0x000000f8) | /* l2 */ + ((srcval2 >> 2) & 0x00000007); /* l2 - 3 bits */ + srcval1=(DWORD)*srcpixel++; + *dstpixel++= ((srcval2 << 21) & 0xfc000000) | /* g2 */ + ((srcval2 << 15) & 0x03000000) | /* g2 - 2 bits */ + ((srcval2 << 8) & 0x00f80000) | /* h2 */ + ((srcval2 << 3) & 0x00070000) | /* h2 - 3 bits */ + ((srcval1 << 11) & 0x0000f800) | /* l3 */ + ((srcval1 << 6) & 0x00000700) | /* l3 - 3 bits */ + ((srcval1 >> 3) & 0x000000fc) | /* g3 */ + ((srcval1 >> 9) & 0x00000003); /* g3 - 2 bits */ + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 16) & 0xf8000000) | /* h3 */ + ((srcval1 << 11) & 0x07000000) | /* h3 - 3 bits */ + ((srcval2 << 19) & 0x00f80000) | /* l4 */ + ((srcval2 << 14) & 0x00070000) | /* l4 - 3 bits */ + ((srcval2 << 5) & 0x0000fc00) | /* g4 */ + ((srcval2 >> 1) & 0x00000300) | /* g4 - 2 bits */ + ((srcval2 >> 8) & 0x000000f8) | /* h4 */ + ((srcval2 >> 13) & 0x00000007); /* h4 - 3 bits */ + } + if(width&3) { + BYTE *dstbyte = (BYTE*)dstpixel; + DWORD srcval; + for(x = 0; x < (width&3); x++) { + srcval = *srcpixel++; + dstbyte[0] = ((srcval << 3) & 0xf8) | ((srcval >> 2) & 0x07); + dstbyte[1] = ((srcval >> 3) & 0xfc) | ((srcval >> 9) & 0x03); + dstbyte[2] = ((srcval >> 8) & 0xf8) | ((srcval >> 13) & 0x07); + dstbyte+=3; + if(x > 0) + FLIP_DWORD(dstpixel + x - 1); + } + FLIP_DWORD(dstpixel + x - 1); + } + + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/4; x++) { + /* Do 4 pixels at a time. 4 words in 3 dwords out */ + DWORD srcval1, srcval2; + srcval1=(DWORD)*srcpixel++; + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 16) & 0xf8000000) | /* h1 */ + ((srcval1 << 11) & 0x07000000) | /* h1 - 3 bits */ + ((srcval1 << 13) & 0x00fc0000) | /* g1 */ + ((srcval1 << 7) & 0x00030000) | /* g1 - 2 bits */ + ((srcval1 << 11) & 0x0000f800) | /* l1 */ + ((srcval1 << 6) & 0x00070000) | /* l1 - 3 bits */ + ((srcval2 >> 8) & 0x000000f8) | /* h2 */ + ((srcval2 >> 13) & 0x00000007); /* h2 - 3 bits */ + srcval1=(DWORD)*srcpixel++; + *dstpixel++= ((srcval2 << 21) & 0xfc000000) | /* g2 */ + ((srcval2 << 15) & 0x03000000) | /* g2 - 2 bits */ + ((srcval2 << 19) & 0x00f80000) | /* l2 */ + ((srcval2 << 14) & 0x00070000) | /* l2 - 3 bits */ + ((srcval1 << 0) & 0x0000f800) | /* h3 */ + ((srcval1 >> 5) & 0x00000700) | /* h3 - 3 bits */ + ((srcval1 >> 3) & 0x000000fc) | /* g3 */ + ((srcval1 >> 9) & 0x00000003); /* g3 - 2 bits */ + srcval2=(DWORD)*srcpixel++; + *dstpixel++= ((srcval1 << 27) & 0xf8000000) | /* l3 */ + ((srcval1 << 22) & 0x07000000) | /* l3 - 3 bits */ + ((srcval2 << 8) & 0x00f80000) | /* h4 */ + ((srcval2 << 3) & 0x00070000) | /* h4 - 3 bits */ + ((srcval2 << 5) & 0x0000fc00) | /* g4 */ + ((srcval2 >> 1) & 0x00000700) | /* g4 - 2 bits */ + ((srcval2 << 3) & 0x000000f8) | /* l4 */ + ((srcval2 >> 2) & 0x00000007); /* l4 - 3 bits */ + } + if(width&3) { + BYTE *dstbyte = (BYTE*)dstpixel; + DWORD srcval; + for(x = 0; x < (width&3); x++) { + srcval = *srcpixel++; + dstbyte[2] = ((srcval << 3) & 0xf8) | ((srcval >> 2) & 0x07); + dstbyte[1] = ((srcval >> 3) & 0xfc) | ((srcval >> 9) & 0x03); + dstbyte[0] = ((srcval >> 8) & 0xf8) | ((srcval >> 13) & 0x07); + dstbyte+=3; + if(x > 0) + FLIP_DWORD(dstpixel + x - 1); + } + FLIP_DWORD(dstpixel + x - 1); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_0888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 0) & 0x0000f800) | /* h */ + ((srcval >> 5) & 0x00000700) | /* h - 3 bits */ + ((srcval << 13) & 0x00fc0000) | /* g */ + ((srcval << 7) & 0x00030000) | /* g - 2 bits */ + ((srcval << 27) & 0xf8000000) | /* l */ + ((srcval << 22) & 0x07000000); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_0888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 16) & 0xf8000000) | /* h */ + ((srcval << 11) & 0x07000000) | /* h - 3 bits */ + ((srcval << 13) & 0x00fc0000) | /* g */ + ((srcval << 7) & 0x00030000) | /* g - 2 bits */ + ((srcval << 11) & 0x0000f800) | /* l */ + ((srcval << 6) & 0x00000700); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +/* + * 24 bit conversions + */ + +static void convert_888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int x, y; + + for (y=0; y<height; y++) { + for(x = 0; x < ((width+1)*3/4); x++) { + DWORD srcval = *((DWORD*)srcbits + x); + *((DWORD*)dstbits + x) = ((srcval << 24) & 0xff000000) | + ((srcval << 8) & 0x00ff0000) | + ((srcval >> 8) & 0x0000ff00) | + ((srcval >> 24) & 0x000000ff); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/4; x++) { + /* Do 4 pixels at a time. 3 dwords in 3 dwords out */ + *dstpixel++=((srcpixel[0] << 8) & 0xffffff00) | /* h1, g1, l1 */ + ((srcpixel[1] >> 8) & 0x000000ff); /* h2 */ + *dstpixel++=((srcpixel[1] << 24) & 0xff000000) | /* g2 */ + ((srcpixel[0] >> 8) & 0x00ff0000) | /* l2 */ + ((srcpixel[2] << 8) & 0x0000ff00) | /* h3 */ + ((srcpixel[0] >> 24) & 0x000000ff); /* g3 */ + *dstpixel++=((srcpixel[1] << 8) & 0xff000000) | /* l3 */ + ((srcpixel[2] >> 8) & 0x00ffffff); /* h4, g4, l4 */ + srcpixel+=3; + } + if(width&3) { + BYTE *dstbyte = (BYTE*)dstpixel; + const BYTE *srcbyte = (BYTE*)srcpixel; + for(x = 0; x < (width&3); x++) { + dstbyte[2] = srcbyte[0]; + dstbyte[1] = srcbyte[1]; + dstbyte[0] = srcbyte[2]; + dstbyte+=3; + srcbyte+=3; + if(x > 0) + FLIP_DWORD(dstpixel + x - 1); + } + FLIP_DWORD(dstpixel + x - 1); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_555_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 << 5) & 0x1f00) | /* l1 */ + ((srcval1 >> 14) & 0x0003) | /* g1 - 2 bits */ + ((srcval1 << 2) & 0xe000) | /* g1 - 3 bits */ + ((srcval1 >> 17) & 0x007c); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 19) & 0x1f00) | /* l2 */ + ((srcval2 >> 6) & 0x0003) | /* g2 - 2 bits */ + ((srcval2 << 10) & 0xe000) | /* g2 - 3 bits */ + ((srcval2 >> 9) & 0x007c); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 11) & 0x1f00) | /* l3 */ + ((srcval2 >> 30) & 0x0003) | /* g3 - 2 bits */ + ((srcval2 >> 14) & 0xe000) | /* g3 - 3 bits */ + ((srcval1 >> 1) & 0x007c); /* h3 */ + dstpixel[3]=((srcval1 >> 3) & 0x1f00) | /* l4 */ + ((srcval1 >> 22) & 0x0003) | /* g4 - 2 bits */ + ((srcval1 >> 6) & 0xe000) | /* g4 - 3 bits */ + ((srcval1 >> 17) & 0x007c); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] << 5) & 0x1f00); /* l */ + dstval|=((srcbyte[1] >> 6) & 0x0003); /* g - 2 bits */ + dstval|=((srcbyte[1] << 10) & 0xe000); /* g - 3 bits */ + dstval|=((srcbyte[2] >> 1) & 0x007c); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_555_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 >> 1) & 0x007c) | /* l1 */ + ((srcval1 >> 14) & 0x0003) | /* g1 - 2 bits */ + ((srcval1 << 2) & 0xe000) | /* g1 - 3 bits */ + ((srcval1 >> 11) & 0x1f00); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 25) & 0x007c) | /* l2 */ + ((srcval2 >> 6) & 0x0003) | /* g2 - 2 bits */ + ((srcval2 << 10) & 0xe000) | /* g2 - 3 bits */ + ((srcval2 >> 3) & 0x1f00); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 17) & 0x007c) | /* l3 */ + ((srcval2 >> 30) & 0x0003) | /* g3 - 2 bits */ + ((srcval2 >> 14) & 0xe000) | /* g3 - 3 bits */ + ((srcval1 << 5) & 0x1f00); /* h3 */ + dstpixel[3]=((srcval1 >> 9) & 0x007c) | /* l4 */ + ((srcval1 >> 22) & 0x0003) | /* g4 - 2 bits */ + ((srcval1 >> 6) & 0xe000) | /* g4 - 3 bits */ + ((srcval1 >> 19) & 0x1f00); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] >> 1) & 0x007c); /* l */ + dstval|=((srcbyte[1] >> 6) & 0x0003); /* g - 2 bits */ + dstval|=((srcbyte[1] << 10) & 0xe000); /* g - 3 bits */ + dstval|=((srcbyte[2] << 5) & 0x1f00); /* h */ + FLIP_WORD(&dstval); + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_565_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 << 5) & 0x1f00) | /* l1 */ + ((srcval1 >> 13) & 0x0007) | /* g1 - 3 bits */ + ((srcval1 << 3) & 0xe000) | /* g1 - 3 bits */ + ((srcval1 >> 16) & 0x00f8); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 19) & 0x1f00) | /* l2 */ + ((srcval2 >> 5) & 0x0007) | /* g2 - 3 bits */ + ((srcval2 << 11) & 0xe000) | /* g2 - 3 bits */ + ((srcval2 >> 8) & 0x00f8); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 11) & 0x1f00) | /* l3 */ + ((srcval2 >> 29) & 0x0007) | /* g3 - 3 bits */ + ((srcval2 >> 13) & 0xe000) | /* g3 - 3 bits */ + ((srcval1 << 0) & 0x00f8); /* h3 */ + dstpixel[3]=((srcval1 >> 3) & 0x1f00) | /* l4 */ + ((srcval1 >> 21) & 0x0007) | /* g4 - 3 bits */ + ((srcval1 >> 5) & 0xe000) | /* g4 - 3 bits */ + ((srcval1 >> 24) & 0x00f8); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] << 5) & 0x1f00); /* l */ + dstval|=((srcbyte[1] >> 5) & 0x0007); /* g - 3 bits */ + dstval|=((srcbyte[1] << 11) & 0xe000); /* g - 3 bits */ + dstval|=((srcbyte[2] << 0) & 0x00f8); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_565_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + dstpixel[0]=((srcval1 >> 0) & 0x00f8) | /* l1 */ + ((srcval1 >> 13) & 0x0007) | /* g1 - 3 bits */ + ((srcval1 << 3) & 0xe000) | /* g1 - 3 bits */ + ((srcval1 >> 11) & 0x1f00); /* h1 */ + srcval2=srcpixel[1]; + dstpixel[1]=((srcval1 >> 24) & 0x00f8) | /* l2 */ + ((srcval2 >> 5) & 0x0007) | /* g2 - 3 bits */ + ((srcval2 << 11) & 0xe000) | /* g2 - 3 bits */ + ((srcval2 >> 3) & 0x1f00); /* h2 */ + srcval1=srcpixel[2]; + dstpixel[2]=((srcval2 >> 16) & 0x00f8) | /* l3 */ + ((srcval2 >> 29) & 0x0007) | /* g3 - 3 bits */ + ((srcval2 >> 13) & 0xe000) | /* g3 - 3 bits */ + ((srcval1 << 5) & 0x1f00); /* h3 */ + dstpixel[3]=((srcval1 >> 8) & 0x00f8) | /* l4 */ + ((srcval1 >> 21) & 0x0007) | /* g4 - 3 bits */ + ((srcval1 >> 5) & 0xe000) | /* g4 - 3 bits */ + ((srcval1 >> 19) & 0x1f00); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + srcbyte=(LPBYTE)srcpixel; + for (x=0; x<oddwidth; x++) { + WORD dstval; + dstval =((srcbyte[0] << 0) & 0x00f8); /* l */ + dstval|=((srcbyte[1] >> 5) & 0x0007); /* g - 3 bits */ + dstval|=((srcbyte[1] << 11) & 0xe000); /* g - 3 bits */ + dstval|=((srcbyte[2] << 5) & 0x1f00); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_0888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1,srcval2; + srcval1=*srcpixel++; + *dstpixel++=((srcval1 << 24) & 0xff000000) | /* l1 */ + ((srcval1 << 8) & 0x00ff0000) | /* g1 */ + ((srcval1 >> 8) & 0x0000ff00); /* h1 */ + srcval2=*srcpixel++; + *dstpixel++=((srcval1 << 0) & 0xff000000) | /* l2 */ + ((srcval2 << 16) & 0x00ff0000) | /* g2 */ + ((srcval2 << 0) & 0x0000ff00); /* h2 */ + srcval1=*srcpixel++; + *dstpixel++=((srcval2 << 8) & 0xff000000) | /* l3 */ + ((srcval2 >> 8) & 0x00ff0000) | /* g3 */ + ((srcval1 << 8) & 0x0000ff00); /* h3 */ + *dstpixel++=((srcval1 << 16) & 0xff000000) | /* l4 */ + ((srcval1 << 0) & 0x00ff0000) | /* g4 */ + ((srcval1 >> 16) & 0x0000ff00); /* h4 */ + } + /* And now up to 3 odd pixels */ + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=((srcval << 24) & 0xff000000) | /* l */ + ((srcval << 8) & 0x00ff0000) | /* g */ + ((srcval >> 8) & 0x0000ff00); /* h */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_0888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1,srcval2; + + srcval1=*srcpixel++; + *dstpixel++=((srcval1 << 8) & 0xffffff00); /* h1, g1, l1 */ + srcval2=*srcpixel++; + *dstpixel++=((srcval2 << 16) & 0xffff0000) | /* h2, g2 */ + ((srcval1 >> 16) & 0x0000ff00); /* l2 */ + srcval1=*srcpixel++; + *dstpixel++=((srcval1 << 24) & 0xff000000) | /* h3 */ + ((srcval2 >> 8) & 0x00ffff00); /* g3, l3 */ + *dstpixel++=((srcval1 >> 0) & 0xffffff00); /* h4, g4, l4 */ + } + /* And now up to 3 odd pixels */ + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=((srcval << 8) & 0xffffff00); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_rgb888_to_any0888_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rLeftShift,gLeftShift,bLeftShift; + const BYTE* srcpixel; + DWORD* dstpixel; + int x,y; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + *dstpixel =(srcpixel[0] << bLeftShift) | /* b */ + (srcpixel[1] << gLeftShift) | /* g */ + (srcpixel[2] << rLeftShift); /* r */ + FLIP_DWORD(dstpixel); + dstpixel++; + srcpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_bgr888_to_any0888_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rLeftShift,gLeftShift,bLeftShift; + const BYTE* srcpixel; + DWORD* dstpixel; + int x,y; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + *dstpixel =(srcpixel[0] << rLeftShift) | /* r */ + (srcpixel[1] << gLeftShift) | /* g */ + (srcpixel[2] << bLeftShift); /* b */ + FLIP_DWORD(dstpixel); + dstpixel++; + srcpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +/* + * 32 bit conversions + */ + +static void convert_0888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int x, y; + + for (y=0; y<height; y++) { + for(x = 0; x < width; x++) { + DWORD srcval = *((DWORD*)srcbits + x); + *((DWORD*)dstbits + x) = ((srcval << 24) & 0xff000000) | + ((srcval << 8) & 0x00ff0000) | + ((srcval >> 8) & 0x0000ff00) | + ((srcval >> 24) & 0x000000ff); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + + +static void convert_0888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 8) & 0xffffff00); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_any_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rRightShift,gRightShift,bRightShift; + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel =(((srcval >> rRightShift) & 0xff) << rLeftShift) | + (((srcval >> gRightShift) & 0xff) << gLeftShift) | + (((srcval >> bRightShift) & 0xff) << bLeftShift); + FLIP_DWORD(dstpixel); + dstpixel++; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_555_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel =((srcval >> 17) & 0x007c) | /* h */ + ((srcval >> 14) & 0x0003) | /* g - 2 bits */ + ((srcval << 2) & 0xe000) | /* g - 3 bits */ + ((srcval << 5) & 0x1f00); /* l */ + dstpixel++; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_555_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel =((srcval >> 11) & 0x1f00) | /* h */ + ((srcval >> 6) & 0x0003) | /* g - 2 bits */ + ((srcval << 2) & 0xe000) | /* g - 3 bits */ + ((srcval >> 1) & 0x7c00); /* l */ + dstpixel++; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_565_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 16) & 0x00f8) | /* h */ + ((srcval >> 13) & 0x0007) | /* g - 3 bits */ + ((srcval << 3) & 0xe000) | /* g - 3 bits */ + ((srcval << 5) & 0x1f00); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_565_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 11) & 0x1f00) | /* h */ + ((srcval >> 13) & 0x0007) | /* g - 3 bits */ + ((srcval << 3) & 0xe000) | /* g - 3 bits */ + ((srcval << 0) & 0x00f8); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_5x5_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + WORD rdst, WORD gdst, WORD bdst) +{ + int rRightShift,gRightShift,bRightShift; + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel + * contains 0x11223344. + * - first we shift 0x11223344 right by rRightShift to bring the most + * significant bits of the red components in the bottom 5 (or 6) bits + * -> 0x4488c + * - then we remove non red bits by anding with the modified rdst (0x1f) + * -> 0x0c + * - finally shift these bits left by rLeftShift so that they end up in + * the right place + * -> 0x3000 + */ + rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3; + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + gRightShift+=(gdst==0x07e0?2:3); + bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + rdst=rdst >> rLeftShift; + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + gdst=gdst >> gLeftShift; + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + bdst=bdst >> bLeftShift; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel =(((srcval >> rRightShift) & rdst) << rLeftShift) | + (((srcval >> gRightShift) & gdst) << gLeftShift) | + (((srcval >> bRightShift) & bdst) << bLeftShift); + FLIP_WORD(dstpixel); + dstpixel++; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_888_asis_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ + DWORD srcval1, srcval2; + srcval1=*srcpixel++; + srcval2=*srcpixel++; + *dstpixel++=((srcval1 << 24) & 0xff000000) | /* l1 */ + ((srcval1 << 8) & 0x00ff0000) | /* g1 */ + ((srcval1 >> 8) & 0x0000ff00) | /* h1 */ + ((srcval2 >> 0) & 0x000000ff); /* l2 */ + srcval1=*srcpixel++; + *dstpixel++=((srcval2 << 16) & 0xff000000) | /* g2 */ + ((srcval2 << 0) & 0x00ff0000) | /* h2 */ + ((srcval1 << 8) & 0x0000ff00) | /* l3 */ + ((srcval1 >> 8) & 0x000000ff); /* g3 */ + srcval2=*srcpixel++; + *dstpixel++=((srcval1 << 8) & 0xff000000) | /* h3 */ + ((srcval2 << 16) & 0x00ff0000) | /* l4 */ + ((srcval2 << 0) & 0x0000ff00) | /* g4 */ + ((srcval2 >> 16) & 0x000000ff); /* h4 */ + } + /* And now up to 3 odd pixels */ + if(width&3) { + BYTE *dstbyte = (BYTE*)dstpixel; + const BYTE *srcbyte = (BYTE*)srcpixel; + for(x = 0; x < (width&3); x++) { + dstbyte[0] = srcbyte[0]; + dstbyte[1] = srcbyte[1]; + dstbyte[2] = srcbyte[2]; + dstbyte+=3; + srcbyte+=4; + if(x > 0) + FLIP_DWORD(dstpixel + x - 1); + } + FLIP_DWORD(dstpixel + x - 1); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_888_reverse_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ + DWORD srcval1,srcval2; + srcval1=*srcpixel++; + srcval2=*srcpixel++; + *dstpixel++=((srcval1 << 8) & 0xffffff00) | /* h1, g1, l1 */ + ((srcval2 >> 16) & 0x000000ff); /* h2 */ + srcval1=*srcpixel++; + *dstpixel++=((srcval2 << 16) & 0xffff0000) | /* g2, l2 */ + ((srcval1 >> 8) & 0x0000ffff); /* h3, g3 */ + srcval2=*srcpixel++; + *dstpixel++=((srcval1 << 24) & 0xff000000) | /* l3 */ + ((srcval2 << 0) & 0x00ffffff); /* h4, g4, l4 */ + } + /* And now up to 3 odd pixels */ + if(width&3) { + BYTE *dstbyte = (BYTE*)dstpixel; + const BYTE *srcbyte = (BYTE*)srcpixel; + for(x = 0; x < (width&3); x++) { + dstbyte[2] = srcbyte[0]; + dstbyte[1] = srcbyte[1]; + dstbyte[0] = srcbyte[2]; + dstbyte+=3; + srcbyte+=4; + if(x > 0) + FLIP_DWORD(dstpixel + x - 1); + } + FLIP_DWORD(dstpixel + x - 1); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_rgb888_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes) +{ + int rRightShift,gRightShift,bRightShift; + const DWORD* srcpixel; + BYTE* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + dstpixel[0]=(srcval >> bRightShift); /* b */ + dstpixel[1]=(srcval >> gRightShift); /* g */ + dstpixel[2]=(srcval >> rRightShift); /* r */ + if(x&3) + FLIP_DWORD((DWORD*)(dstpixel + x - 4)); + dstpixel+=3; + } + if(x&3) + FLIP_DWORD((DWORD*)(dstpixel + x - 4)); + + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_bgr888_dst_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes) +{ + int rRightShift,gRightShift,bRightShift; + const DWORD* srcpixel; + BYTE* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + dstpixel[0]=(srcval >> rRightShift); /* r */ + dstpixel[1]=(srcval >> gRightShift); /* g */ + dstpixel[2]=(srcval >> bRightShift); /* b */ + if(x&3) + FLIP_DWORD((DWORD*)(dstpixel + x - 4)); + dstpixel+=3; + } + if(x&3) + FLIP_DWORD((DWORD*)(dstpixel + x - 4)); + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +dib_conversions dib_dst_invert = { + convert_5x5_asis_dst_invert, + convert_555_reverse_dst_invert, + convert_555_to_565_asis_dst_invert, + convert_555_to_565_reverse_dst_invert, + convert_555_to_888_asis_dst_invert, + convert_555_to_888_reverse_dst_invert, + convert_555_to_0888_asis_dst_invert, + convert_555_to_0888_reverse_dst_invert, + convert_5x5_to_any0888_dst_invert, + convert_565_reverse_dst_invert, + convert_565_to_555_asis_dst_invert, + convert_565_to_555_reverse_dst_invert, + convert_565_to_888_asis_dst_invert, + convert_565_to_888_reverse_dst_invert, + convert_565_to_0888_asis_dst_invert, + convert_565_to_0888_reverse_dst_invert, + convert_888_asis_dst_invert, + convert_888_reverse_dst_invert, + convert_888_to_555_asis_dst_invert, + convert_888_to_555_reverse_dst_invert, + convert_888_to_565_asis_dst_invert, + convert_888_to_565_reverse_dst_invert, + convert_888_to_0888_asis_dst_invert, + convert_888_to_0888_reverse_dst_invert, + convert_rgb888_to_any0888_dst_invert, + convert_bgr888_to_any0888_dst_invert, + convert_0888_asis_dst_invert, + convert_0888_reverse_dst_invert, + convert_0888_any_dst_invert, + convert_0888_to_555_asis_dst_invert, + convert_0888_to_555_reverse_dst_invert, + convert_0888_to_565_asis_dst_invert, + convert_0888_to_565_reverse_dst_invert, + convert_any0888_to_5x5_dst_invert, + convert_0888_to_888_asis_dst_invert, + convert_0888_to_888_reverse_dst_invert, + convert_any0888_to_rgb888_dst_invert, + convert_any0888_to_bgr888_dst_invert +}; --- /dev/null 2003-01-30 10:24:37.000000000 +0000 +++ dlls/x11drv/dib_convert_si.c 2003-11-10 15:55:18.000000000 +0000 @@ -0,0 +1,1517 @@ +/* + * DIB conversion routinues for cases where the source + * has non-native byte order. + * + * Copyright (C) 2003 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <stdlib.h> + +#include "wine/debug.h" +#include "windef.h" +#include "config.h" +#include "x11drv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(bitmap); + + +#define FLIP_WORD(x) \ + ( *(x) = ( (*(x) & 0xff) << 8) | \ + ( (*(x) & 0xff00) >> 8) ) + +#define FLIP_TWO_WORDS(x) \ + ( *(x) = ( (*(x) & 0x00ff00ff) << 8) | \ + ( (*(x) & 0xff00ff00) >> 8) ) + +#define FLIP_DWORD(x) \ + ( *(x) = ( (*(x) & 0xff) << 24) | \ + ( (*(x) & 0xff00) << 8) | \ + ( (*(x) & 0xff0000) >> 8) | \ + ( (*(x) & 0xff000000) >> 24) ) + + + +/* + * 15 bit conversions + */ + +static void convert_5x5_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int x, y; + const DWORD *srcpixel; + DWORD *dstpixel; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for(x = 0; x < width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval = *srcpixel++; + *dstpixel++=((srcval << 8) & 0xff00ff00) | + ((srcval >> 8) & 0x00ff00ff); + } + if(width&1) { + /* And the odd pixel */ + WORD srcval = *(WORD*)srcpixel; + *(WORD*)dstpixel = ((srcval << 8) & 0xff00) | + ((srcval >> 8) & 0x00ff); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 2) & 0x001f001f) | /* h */ + ((srcval << 8) & 0x03000300) | /* g - 2 bits */ + ((srcval >> 8) & 0x00e000e0) | /* g - 3 bits */ + ((srcval << 2) & 0x7c007c00); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 2) & 0x001f) | /* h */ + ((srcval << 8) & 0x0300) | /* g - 2 bits */ + ((srcval >> 8) & 0x00e0) | /* g - 3 bits */ + ((srcval << 2) & 0x7c00); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_565_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 9) & 0xfe00fe00) | /* h, g - 2 bits*/ + ((srcval >> 7) & 0x01c001c0) | /* g - 3 bits */ + ((srcval << 4) & 0x00200020) | /* g - 1 bit */ + ((srcval >> 8) & 0x001f001f); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 9) & 0xfe00) | /* h, g - 2bits*/ + ((srcval >> 7) & 0x01c0) | /* g - 3 bits */ + ((srcval << 4) & 0x0020) | /* g - 1 bit */ + ((srcval >> 8) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_565_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 2) & 0x001f001f) | /* h */ + ((srcval << 9) & 0x06000600) | /* g - 2 bits*/ + ((srcval >> 7) & 0x01c001c0) | /* g - 3 bits */ + ((srcval << 4) & 0x00200020) | /* g - 1 bits */ + ((srcval << 3) & 0xf800f800); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 2) & 0x001f) | /* h */ + ((srcval << 9) & 0x0600) | /* g - 2 bits */ + ((srcval >> 7) & 0x01c0) | /* g - 3 bits */ + ((srcval << 4) & 0x0020) | /* g - 1 bit */ + ((srcval << 3) & 0xf800); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval >> 5) & 0xf8) | /* l */ + ((srcval >> 10) & 0x07); /* l - 3 bits */ + dstpixel[1]=((srcval << 6) & 0xc0) | /* g - 2 bits */ + ((srcval >> 10) & 0x38) | /* g - 3 bits */ + ((srcval << 1) & 0x06) | /* g - 2 bits */ + ((srcval >> 15) & 0x01); /* g - 1 bit */ + dstpixel[2]=((srcval << 1) & 0xf8) | /* h */ + ((srcval >> 4) & 0x07); /* h - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval << 1) & 0xf8) | /* h */ + ((srcval >> 4) & 0x07); /* h - 3 bits */ + dstpixel[1]=((srcval << 6) & 0xc0) | /* g - 2 bits */ + ((srcval >> 10) & 0x38) | /* g - 3 bits */ + ((srcval << 1) & 0x06) | /* g - 2 bits */ + ((srcval >> 15) & 0x01); /* g - 1 bits */ + dstpixel[2]=((srcval >> 5) & 0xf8) | /* l */ + ((srcval >> 10) & 0x07); /* l - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_0888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 17) & 0xf80000) | /* h */ + ((srcval << 12) & 0x070000) | /* h - 3 bits */ + ((srcval << 14) & 0x00c000) | /* g - 2 bits */ + ((srcval >> 2) & 0x003800) | /* g - 3 bits */ + ((srcval << 9) & 0x000600) | /* g - 2 bits */ + ((srcval >> 7) & 0x000100) | /* g - 1 bit */ + ((srcval >> 5) & 0x0000f8) | /* l */ + ((srcval >> 10) & 0x000007); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_555_to_0888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 1) & 0x0000f8) | /* h */ + ((srcval >> 4) & 0x000007) | /* h - 3 bits */ + ((srcval << 14) & 0x00c000) | /* g - 2 bits */ + ((srcval >> 2) & 0x003800) | /* g - 3 bits */ + ((srcval << 9) & 0x000600) | /* g - 2 bits */ + ((srcval >> 7) & 0x000100) | /* g - 1 bit */ + ((srcval << 11) & 0xf80000) | /* l */ + ((srcval << 6) & 0x070000); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_5x5_to_any0888_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + WORD rsrc, WORD gsrc, WORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rRightShift1,gRightShift1,bRightShift1; + int rRightShift2,gRightShift2,bRightShift2; + BYTE gMask1,gMask2; + int rLeftShift,gLeftShift,bLeftShift; + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + /* Note, the source pixel value is shifted left by 16 bits so that + * we know we will always have to shift right to extract the components. + */ + rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3; + gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3; + bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3; + rRightShift2=rRightShift1+5; + gRightShift2=gRightShift1+5; + bRightShift2=bRightShift1+5; + if (gsrc==0x03e0) { + /* Green has 5 bits, like the others */ + gMask1=0xf8; + gMask2=0x07; + } else { + /* Green has 6 bits, not 5. Compensate. */ + gRightShift1++; + gRightShift2+=2; + gMask1=0xfc; + gMask2=0x03; + } + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + BYTE red,green,blue; + srcval=*srcpixel++ << 16; + FLIP_TWO_WORDS(&srcval); + + red= ((srcval >> rRightShift1) & 0xf8) | + ((srcval >> rRightShift2) & 0x07); + green=((srcval >> gRightShift1) & gMask1) | + ((srcval >> gRightShift2) & gMask2); + blue= ((srcval >> bRightShift1) & 0xf8) | + ((srcval >> bRightShift2) & 0x07); + *dstpixel++=(red << rLeftShift) | + (green << gLeftShift) | + (blue << bLeftShift); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +/* + * 16 bits conversions + */ + +static void convert_565_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 3) & 0xf800f800) | /* l */ + ((srcval << 8) & 0x07000700) | /* g - 3 bits */ + ((srcval >> 8) & 0x00e000e0) | /* g - 3 bits */ + ((srcval >> 3) & 0x001f001f); /* h */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 3) & 0xf800) | /* l */ + ((srcval << 8) & 0x0700) | /* g - 3 bits */ + ((srcval >> 8) & 0x00e0) | /* g - 3 bits */ + ((srcval >> 3) & 0x001f); /* h */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_555_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 7) & 0x7f807f80) | /* h, g - 3 bits */ + ((srcval >> 9) & 0x00600060) | /* g - 2 bits */ + ((srcval >> 8) & 0x001f001f); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval << 7) & 0x7f80) | /* h, g - 3 bits */ + ((srcval >> 9) & 0x0060) | /* g - 2 bits */ + ((srcval >> 8) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_555_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/2; x++) { + /* Do 2 pixels at a time */ + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 3) & 0x001f001f) | /* h */ + ((srcval >> 9) & 0x00600060) | /* g - 2 bits */ + ((srcval << 7) & 0x03800380) | /* g - 3 bits */ + ((srcval << 2) & 0x7c007c00); /* l */ + } + if (width&1) { + /* And the the odd pixel */ + WORD srcval; + srcval=*((WORD*)srcpixel); + *((WORD*)dstpixel)=((srcval >> 3) & 0x001f) | /* h */ + ((srcval >> 9) & 0x0060) | /* g - 2 bits */ + ((srcval << 7) & 0x0380) | /* g - 3 bits */ + ((srcval << 2) & 0x7c00); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval >> 5) & 0xf8) | /* l */ + ((srcval >> 10) & 0x07); /* l - 3 bits */ + dstpixel[1]=((srcval << 5) & 0xe0) | /* g - 3 bits */ + ((srcval >> 11) & 0x1c) | /* g - 3 bits */ + ((srcval >> 1) & 0x03); /* g - 2 bits */ + dstpixel[2]=((srcval >> 0) & 0xf8) | /* h */ + ((srcval >> 5) & 0x07); /* h - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + BYTE* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + dstpixel[0]=((srcval >> 0) & 0xf8) | /* h */ + ((srcval >> 5) & 0x07); /* h - 3 bits */ + dstpixel[1]=((srcval << 5) & 0xe0) | /* g - 3 bits */ + ((srcval >> 11) & 0x1c) | /* g - 3 bits */ + ((srcval >> 1) & 0x03); /* g - 2 bits */ + dstpixel[2]=((srcval >> 5) & 0xf8) | /* l */ + ((srcval >> 10) & 0x07); /* l - 3 bits */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_0888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval << 16) & 0xf80000) | /* h */ + ((srcval << 11) & 0x070000) | /* h - 3 bits */ + ((srcval << 13) & 0x00e000) | /* g - 3 bits */ + ((srcval >> 3) & 0x001c00) | /* g - 3 bits */ + ((srcval << 7) & 0x000300) | /* g - 2 bits */ + ((srcval >> 5) & 0x0000f8) | /* l */ + ((srcval >> 10) & 0x000007); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_565_to_0888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const WORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + WORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 0) & 0x0000f8) | /* h */ + ((srcval >> 5) & 0x000007) | /* h - 3 bits */ + ((srcval << 13) & 0x00e000) | /* g - 3 bits */ + ((srcval >> 3) & 0x001c00) | /* g - 3 bits */ + ((srcval << 7) & 0x000300) | /* g - 2 bits */ + ((srcval << 11) & 0xf80000) | /* l */ + ((srcval << 6) & 0x070000); /* l - 3 bits */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +/* + * 24 bit conversions + */ + +static void convert_888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int x, y; + + for (y=0; y<height; y++) { + for(x = 0; x < ((width+1)*3/4); x++) { + DWORD srcval = *((DWORD*)srcbits + x); + *((DWORD*)dstbits + x) = ((srcval << 24) & 0xff000000) | + ((srcval << 8) & 0x00ff0000) | + ((srcval >> 8) & 0x0000ff00) | + ((srcval >> 24) & 0x000000ff); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + DWORD srcarray[3]; + int x,y; + int oddwidth = width & 3; + + width = width/4; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 3 dwords out */ + *dstpixel++= ((srcpixel[0] >> 8) & 0x00ffffff) | /* l1, g1, h1 */ + ((srcpixel[1] << 8) & 0xff000000); /* h2 */ + *dstpixel++= ((srcpixel[1] >> 24) & 0x000000ff) | /* g2 */ + ((srcpixel[0] << 8) & 0x0000ff00) | /* l2 */ + ((srcpixel[2] >> 8) & 0x00ff0000) | /* h3 */ + ((srcpixel[1] << 24) & 0xff000000); /* g3 */ + *dstpixel++= ((srcpixel[1] >> 8) & 0x000000ff) | /* l3 */ + ((srcpixel[2] << 8) & 0xffffff00); /* l4, g4, h4 */ + srcpixel+=3; + } + /* And now up to 3 odd pixels */ + if(oddwidth) { + BYTE *dstbyte, *srcbyte; + memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD)); + dstbyte = (LPBYTE)dstpixel; + srcbyte = (LPBYTE)srcarray; + for (x=0; x<oddwidth; x++) { + FLIP_DWORD(srcarray+x); + dstbyte[0] = srcbyte[2]; + dstbyte[1] = srcbyte[1]; + dstbyte[2] = srcbyte[0]; + srcbyte+=3; + dstbyte+=3; + } + } + + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_555_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + DWORD srcarray[3]; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + FLIP_DWORD(&srcval1); + dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */ + ((srcval1 >> 6) & 0x03e0) | /* g1 */ + ((srcval1 >> 9) & 0x7c00); /* h1 */ + srcval2=srcpixel[1]; + FLIP_DWORD(&srcval2); + dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */ + ((srcval2 << 2) & 0x03e0) | /* g2 */ + ((srcval2 >> 1) & 0x7c00); /* h2 */ + srcval1=srcpixel[2]; + FLIP_DWORD(&srcval1); + dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */ + ((srcval2 >> 22) & 0x03e0) | /* g3 */ + ((srcval1 << 7) & 0x7c00); /* h3 */ + dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */ + ((srcval1 >> 14) & 0x03e0) | /* g4 */ + ((srcval1 >> 17) & 0x7c00); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + if(oddwidth) { + memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD)); + srcbyte = (LPBYTE)srcarray; + for (x=0; x<oddwidth; x++) { + WORD dstval; + FLIP_DWORD(srcarray+x); + + dstval =((srcbyte[0] >> 3) & 0x001f); /* l */ + dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */ + dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_555_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + DWORD srcarray[3]; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + FLIP_DWORD(&srcval1); + dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */ + ((srcval1 >> 6) & 0x03e0) | /* g1 */ + ((srcval1 >> 19) & 0x001f); /* h1 */ + srcval2=srcpixel[1]; + FLIP_DWORD(&srcval2); + dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */ + ((srcval2 << 2) & 0x03e0) | /* g2 */ + ((srcval2 >> 11) & 0x001f); /* h2 */ + srcval1=srcpixel[2]; + FLIP_DWORD(&srcval1); + dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */ + ((srcval2 >> 22) & 0x03e0) | /* g3 */ + ((srcval1 >> 3) & 0x001f); /* h3 */ + dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */ + ((srcval1 >> 14) & 0x03e0) | /* g4 */ + ((srcval1 >> 27) & 0x001f); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + if(oddwidth) { + memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD)); + srcbyte = (LPBYTE)srcarray; + for (x=0; x<oddwidth; x++) { + WORD dstval; + FLIP_DWORD(srcarray+x); + dstval =((srcbyte[0] << 7) & 0x7c00); /* l */ + dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */ + dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_565_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + DWORD srcarray[3]; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + FLIP_DWORD(&srcval1); + dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */ + ((srcval1 >> 5) & 0x07e0) | /* g1 */ + ((srcval1 >> 8) & 0xf800); /* h1 */ + srcval2=srcpixel[1]; + FLIP_DWORD(&srcval2); + dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */ + ((srcval2 << 3) & 0x07e0) | /* g2 */ + ( srcval2 & 0xf800); /* h2 */ + srcval1=srcpixel[2]; + FLIP_DWORD(&srcval1); + dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */ + ((srcval2 >> 21) & 0x07e0) | /* g3 */ + ((srcval1 << 8) & 0xf800); /* h3 */ + dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */ + ((srcval1 >> 13) & 0x07e0) | /* g4 */ + ((srcval1 >> 16) & 0xf800); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + if(oddwidth) { + memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD)); + srcbyte = (LPBYTE)srcarray; + for (x=0; x<oddwidth; x++) { + WORD dstval; + FLIP_DWORD(srcarray+x); + dstval =((srcbyte[0] >> 3) & 0x001f); /* l */ + dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */ + dstval|=((srcbyte[2] << 8) & 0xf800); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_565_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + const BYTE* srcbyte; + WORD* dstpixel; + DWORD srcarray[3]; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 words out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + FLIP_DWORD(&srcval1); + dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */ + ((srcval1 >> 5) & 0x07e0) | /* g1 */ + ((srcval1 >> 19) & 0x001f); /* h1 */ + srcval2=srcpixel[1]; + FLIP_DWORD(&srcval2); + dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */ + ((srcval2 << 3) & 0x07e0) | /* g2 */ + ((srcval2 >> 11) & 0x001f); /* h2 */ + srcval1=srcpixel[2]; + FLIP_DWORD(&srcval1); + dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */ + ((srcval2 >> 21) & 0x07e0) | /* g3 */ + ((srcval1 >> 3) & 0x001f); /* h3 */ + dstpixel[3]=(srcval1 & 0xf800) | /* l4 */ + ((srcval1 >> 13) & 0x07e0) | /* g4 */ + ((srcval1 >> 27) & 0x001f); /* h4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + if(oddwidth) { + memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD)); + srcbyte = (LPBYTE)srcarray; + for (x=0; x<oddwidth; x++) { + WORD dstval; + FLIP_DWORD(srcarray+x); + dstval =((srcbyte[0] << 8) & 0xf800); /* l */ + dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */ + dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */ + *dstpixel++=dstval; + srcbyte+=3; + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_0888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + DWORD srcarray[3]; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1,srcval2; + srcval1=srcpixel[0]; + FLIP_DWORD(&srcval1); + dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */ + srcval2=srcpixel[1]; + FLIP_DWORD(&srcval2); + dstpixel[1]=( srcval1 >> 24) | /* l2 */ + ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */ + srcval1=srcpixel[2]; + FLIP_DWORD(&srcval1); + dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */ + ((srcval1 << 16) & 0x00ff0000); /* h3 */ + dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + if(oddwidth) { + memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD)); + srcpixel = srcarray; + for (x=0; x<oddwidth; x++) { + DWORD srcval; + FLIP_DWORD(srcarray+x); + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */ + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_888_to_0888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + DWORD srcarray[3]; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1,srcval2; + + srcval1=srcpixel[0]; + FLIP_DWORD(&srcval1); + dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */ + ( srcval1 & 0x00ff00) | /* g1 */ + ((srcval1 << 16) & 0xff0000); /* l1 */ + srcval2=srcpixel[1]; + FLIP_DWORD(&srcval2); + dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */ + ((srcval2 << 8) & 0x00ff00) | /* g2 */ + ((srcval2 >> 8) & 0x0000ff); /* h2 */ + srcval1=srcpixel[2]; + FLIP_DWORD(&srcval1); + dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */ + ((srcval2 >> 16) & 0x00ff00) | /* g3 */ + ( srcval1 & 0x0000ff); /* h3 */ + dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */ + ((srcval1 >> 8) & 0x00ff00) | /* g4 */ + ((srcval1 << 8) & 0xff0000); /* l4 */ + srcpixel+=3; + dstpixel+=4; + } + /* And now up to 3 odd pixels */ + if(oddwidth) { + memcpy(srcarray,srcpixel,oddwidth*sizeof(DWORD)); + srcpixel = srcarray; + for (x=0; x<oddwidth; x++) { + DWORD srcval; + FLIP_DWORD(srcarray+x); + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */ + ( srcval & 0x00ff00) | /* g */ + ((srcval << 16) & 0xff0000); /* l */ + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_rgb888_to_any0888_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + DWORD srcarray[3]; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/4; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1, srcval2; + srcval1=*srcpixel++; + *dstpixel++=(((srcval1 >> 24) & 0xff) << bLeftShift) | /* b1 */ + (((srcval1 >> 16) & 0xff) << gLeftShift) | /* g1 */ + (((srcval1 >> 8) & 0xff) << rLeftShift); /* r1 */ + srcval2=*srcpixel++; + *dstpixel++=(((srcval1 >> 0) & 0xff) << bLeftShift) | /* b2 */ + (((srcval2 >> 24) & 0xff) << gLeftShift) | /* g2 */ + (((srcval2 >> 16) & 0xff) << rLeftShift); /* r2 */ + srcval1=*srcpixel++; + *dstpixel++=(((srcval2 >> 8) & 0xff) << bLeftShift) | /* b3 */ + (((srcval2 >> 0) & 0xff) << gLeftShift) | /* g3 */ + (((srcval1 >> 24) & 0xff) << rLeftShift); /* r3 */ + *dstpixel++=(((srcval1 >> 16) & 0xff) << bLeftShift) | /* b4 */ + (((srcval1 >> 8) & 0xff) << gLeftShift) | /* g4 */ + (((srcval1 >> 0) & 0xff) << rLeftShift); /* r4 */ + } + /* And now up to 3 odd pixels */ + if(width&3) { + memcpy(srcarray,srcpixel,width&3*sizeof(DWORD)); + srcpixel = srcarray; + for (x=0; x < (width&3); x++) { + DWORD srcval; + FLIP_DWORD(srcarray+x); + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=(((srcval >> 0) & 0xff) << bLeftShift) | /* b */ + (((srcval >> 8) & 0xff) << gLeftShift) | /* g */ + (((srcval >> 16) & 0xff) << rLeftShift); /* r */ + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_bgr888_to_any0888_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + DWORD srcarray[3]; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width/4; x++) { + /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ + DWORD srcval1, srcval2; + srcval1=*srcpixel++; + *dstpixel++=(((srcval1 >> 24) & 0xff) << rLeftShift) | /* r1 */ + (((srcval1 >> 16) & 0xff) << gLeftShift) | /* g1 */ + (((srcval1 >> 8) & 0xff) << bLeftShift); /* b1 */ + srcval2=*srcpixel++; + *dstpixel++=(((srcval1 >> 0) & 0xff) << rLeftShift) | /* r2 */ + (((srcval2 >> 24) & 0xff) << gLeftShift) | /* g2 */ + (((srcval2 >> 16) & 0xff) << bLeftShift); /* b2 */ + srcval1=*srcpixel++; + *dstpixel++=(((srcval2 >> 8) & 0xff) << rLeftShift) | /* r3 */ + (((srcval2 >> 0) & 0xff) << gLeftShift) | /* g3 */ + (((srcval1 >> 24) & 0xff) << bLeftShift); /* b3 */ + *dstpixel++=(((srcval1 >> 16) & 0xff) << rLeftShift) | /* r4 */ + (((srcval1 >> 8) & 0xff) << gLeftShift) | /* g4 */ + (((srcval1 >> 0) & 0xff) << bLeftShift); /* b4 */ + } + /* And now up to 3 odd pixels */ + if(width&3) { + memcpy(srcarray,srcpixel,width&3*sizeof(DWORD)); + srcpixel = srcarray; + for (x=0; x < (width&3); x++) { + DWORD srcval; + FLIP_DWORD(srcarray+x); + srcval=*srcpixel; + srcpixel=(LPDWORD)(((char*)srcpixel)+3); + *dstpixel++=(((srcval >> 0) & 0xff) << rLeftShift) | /* r */ + (((srcval >> 8) & 0xff) << gLeftShift) | /* g */ + (((srcval >> 16) & 0xff) << bLeftShift); /* b */ + } + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + + +/* + * 32 bit conversions + */ + +static void convert_0888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + int x, y; + + for (y=0; y<height; y++) { + for(x = 0; x < width; x++) { + DWORD srcval = *((DWORD*)srcbits + x); + *((DWORD*)dstbits + x) = ((srcval << 24) & 0xff000000) | + ((srcval << 8) & 0x00ff0000) | + ((srcval >> 8) & 0x0000ff00) | + ((srcval >> 24) & 0x000000ff); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 8) & 0x00ffffff); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_any_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst) +{ + int rRightShift,gRightShift,bRightShift; + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + DWORD* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + FLIP_DWORD(&srcval); + *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) | + (((srcval >> gRightShift) & 0xff) << gLeftShift) | + (((srcval >> bRightShift) & 0xff) << bLeftShift); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_555_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 1) & 0x7c00) | /* h */ + ((srcval >> 14) & 0x03e0) | /* g */ + ((srcval >> 27) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_555_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 11) & 0x001f) | /* h */ + ((srcval >> 14) & 0x03e0) | /* g */ + ((srcval >> 17) & 0x7c00); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_565_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 0) & 0xf800) | /* h */ + ((srcval >> 13) & 0x07e0) | /* g */ + ((srcval >> 27) & 0x001f); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_565_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + *dstpixel++=((srcval >> 11) & 0x001f) | /* h */ + ((srcval >> 13) & 0x07e0) | /* g */ + ((srcval >> 16) & 0xf800); /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_5x5_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + WORD rdst, WORD gdst, WORD bdst) +{ + int rRightShift,gRightShift,bRightShift; + int rLeftShift,gLeftShift,bLeftShift; + const DWORD* srcpixel; + WORD* dstpixel; + int x,y; + + /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel + * contains 0x11223344. + * - first we shift 0x11223344 right by rRightShift to bring the most + * significant bits of the red components in the bottom 5 (or 6) bits + * -> 0x4488c + * - then we remove non red bits by anding with the modified rdst (0x1f) + * -> 0x0c + * - finally shift these bits left by rLeftShift so that they end up in + * the right place + * -> 0x3000 + */ + rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3; + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + gRightShift+=(gdst==0x07e0?2:3); + bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3; + + rLeftShift=X11DRV_DIB_MaskToShift(rdst); + rdst=rdst >> rLeftShift; + gLeftShift=X11DRV_DIB_MaskToShift(gdst); + gdst=gdst >> gLeftShift; + bLeftShift=X11DRV_DIB_MaskToShift(bdst); + bdst=bdst >> bLeftShift; + + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + FLIP_DWORD(&srcval); + *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) | + (((srcval >> gRightShift) & gdst) << gLeftShift) | + (((srcval >> bRightShift) & bdst) << bLeftShift); + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_888_asis_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + BYTE* dstbyte; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ + DWORD srcval1, srcval2; + srcval1 = *srcpixel++; + srcval2 = *srcpixel++; + *dstpixel++= ((srcval1 >> 24) & 0x000000ff) | /* l1 */ + ((srcval1 >> 8) & 0x0000ff00) | /* g1 */ + ((srcval1 << 8) & 0x00ff0000) | /* h1 */ + ( srcval2 & 0xff000000); /* l2 */ + srcval1 = *srcpixel++; + *dstpixel++= ((srcval2 >> 16) & 0x000000ff) | /* g2 */ + ( srcval2 & 0x0000ff00) | /* h2 */ + ((srcval1 >> 8) & 0x00ff0000) | /* l3 */ + ((srcval1 << 8) & 0xff000000); /* g3 */ + srcval2 = *srcpixel++; + *dstpixel++= ((srcval1 >> 8) & 0x000000ff) | /* h3 */ + ((srcval2 >> 16) & 0x0000ff00) | /* l4 */ + ( srcval2 & 0x00ff0000) | /* g4 */ + ((srcval2 << 16) & 0xff000000); /* h4 */ + } + /* And now up to 3 odd pixels */ + dstbyte=(BYTE*)dstpixel; + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel++; + FLIP_DWORD(&srcval); + *((WORD*)dstbyte)++=srcval; /* h, g */ + *dstbyte++=srcval >> 16; /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_0888_to_888_reverse_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes) +{ + const DWORD* srcpixel; + DWORD* dstpixel; + BYTE* dstbyte; + int x,y; + int oddwidth; + + oddwidth=width & 3; + width=width/4; + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */ + DWORD srcval1,srcval2; + srcval1=*srcpixel++; + srcval2= ((srcval1 >> 8 ) & 0x00ffffff); /* l1, g1, h1 */ + srcval1=*srcpixel++; + *dstpixel++=srcval2 | + ((srcval1 << 16) & 0xff000000); /* h2 */ + srcval2= ((srcval1 >> 16) & 0x0000ffff); /* l2, g2 */ + srcval1=*srcpixel++; + *dstpixel++=srcval2 | + ((srcval1 << 8) & 0xffff0000); /* g3, h3 */ + srcval2= ((srcval1 >> 24) & 0x000000ff); /* l3 */ + srcval1=*srcpixel++; + *dstpixel++=srcval2 | + srcval1; /* l4, g4, h4 */ + } + /* And now up to 3 odd pixels */ + dstbyte=(BYTE*)dstpixel; + for (x=0; x<oddwidth; x++) { + DWORD srcval; + srcval=*srcpixel++; + *((WORD*)dstbyte)++=((srcval >> 8) & 0xffff); /* g, h */ + *dstbyte++= srcval >> 24; /* l */ + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_rgb888_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes) +{ + int rRightShift,gRightShift,bRightShift; + const DWORD* srcpixel; + BYTE* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + FLIP_DWORD(&srcval); + dstpixel[0]=(srcval >> bRightShift); /* b */ + dstpixel[1]=(srcval >> gRightShift); /* g */ + dstpixel[2]=(srcval >> rRightShift); /* r */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + +static void convert_any0888_to_bgr888_src_invert(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes) +{ + int rRightShift,gRightShift,bRightShift; + const DWORD* srcpixel; + BYTE* dstpixel; + int x,y; + + rRightShift=X11DRV_DIB_MaskToShift(rsrc); + gRightShift=X11DRV_DIB_MaskToShift(gsrc); + bRightShift=X11DRV_DIB_MaskToShift(bsrc); + for (y=0; y<height; y++) { + srcpixel=srcbits; + dstpixel=dstbits; + for (x=0; x<width; x++) { + DWORD srcval; + srcval=*srcpixel++; + FLIP_DWORD(&srcval); + dstpixel[0]=(srcval >> rRightShift); /* r */ + dstpixel[1]=(srcval >> gRightShift); /* g */ + dstpixel[2]=(srcval >> bRightShift); /* b */ + dstpixel+=3; + } + srcbits = (char*)srcbits + srclinebytes; + dstbits = (char*)dstbits + dstlinebytes; + } +} + + +dib_conversions dib_src_invert = { + convert_5x5_asis_src_invert, + convert_555_reverse_src_invert, + convert_555_to_565_asis_src_invert, + convert_555_to_565_reverse_src_invert, + convert_555_to_888_asis_src_invert, + convert_555_to_888_reverse_src_invert, + convert_555_to_0888_asis_src_invert, + convert_555_to_0888_reverse_src_invert, + convert_5x5_to_any0888_src_invert, + convert_565_reverse_src_invert, + convert_565_to_555_asis_src_invert, + convert_565_to_555_reverse_src_invert, + convert_565_to_888_asis_src_invert, + convert_565_to_888_reverse_src_invert, + convert_565_to_0888_asis_src_invert, + convert_565_to_0888_reverse_src_invert, + convert_888_asis_src_invert, + convert_888_reverse_src_invert, + convert_888_to_555_asis_src_invert, + convert_888_to_555_reverse_src_invert, + convert_888_to_565_asis_src_invert, + convert_888_to_565_reverse_src_invert, + convert_888_to_0888_asis_src_invert, + convert_888_to_0888_reverse_src_invert, + convert_rgb888_to_any0888_src_invert, + convert_bgr888_to_any0888_src_invert, + convert_0888_asis_src_invert, + convert_0888_reverse_src_invert, + convert_0888_any_src_invert, + convert_0888_to_555_asis_src_invert, + convert_0888_to_555_reverse_src_invert, + convert_0888_to_565_asis_src_invert, + convert_0888_to_565_reverse_src_invert, + convert_any0888_to_5x5_src_invert, + convert_0888_to_888_asis_src_invert, + convert_0888_to_888_reverse_src_invert, + convert_any0888_to_rgb888_src_invert, + convert_any0888_to_bgr888_src_invert +};