x11drv fix for bug#4506: page fault on read access
Rein Klazes
wijn at wanadoo.nl
Sat Feb 18 06:57:51 CST 2006
Hi,
Fixing bug #4506: unaligned 32bit access, can access one byte beyond the
pixel buffer.
Changelog:
dlls/x11drv : dib_convert.c
Avoid unaligned 32 bit reads, and reads beyond the input pixel buffer in
the convert_888_to_0888_* functions.
Rein.
-------------- next part --------------
--- wine/dlls/x11drv/dib_convert.c 2006-02-10 08:41:04.000000000 +0100
+++ mywine/dlls/x11drv/dib_convert.c 2006-02-16 08:41:52.000000000 +0100
@@ -818,37 +818,39 @@ static void convert_888_to_0888_asis(int
const void* srcbits, int srclinebytes,
void* dstbits, int dstlinebytes)
{
- const DWORD* srcpixel;
+ const BYTE* srcpixel;
DWORD* dstpixel;
+ DWORD prev, curr;
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=(const DWORD*)(((const char*)srcpixel)+3);
- *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */
+ curr = *(const DWORD*)( (int)srcpixel & 0xfffffffc);
+ for( x = 0; x < width; x++) {
+ switch( (int)srcpixel & 0x3) {
+ case 0:
+ curr = *(const DWORD*)( srcpixel);
+ *dstpixel = ( curr & 0x00ffffff); /* h1, g1, l1 */
+ break;
+ case 3:
+ prev = curr;
+ curr = *(const DWORD*)( srcpixel + 1);
+ *dstpixel = ( prev >> 24) | /* l2 */
+ ((curr << 8) & 0x00ffff00); /* h2, g2 */
+ break;
+ case 2:
+ prev = curr;
+ curr = *(const DWORD*)( srcpixel + 2);
+ *dstpixel = ( prev >> 16) | /* g3, l3 */
+ ((curr << 16) & 0x00ff0000); /* h3 */
+ break;
+ case 1:
+ *dstpixel = ( curr >> 8); /* h4, g4, l4 */
+ break;
+ }
+ dstpixel++;
+ srcpixel += 3;
}
srcbits = (const char*)srcbits + srclinebytes;
dstbits = (char*)dstbits + dstlinebytes;
@@ -859,46 +861,45 @@ static void convert_888_to_0888_reverse(
const void* srcbits, int srclinebytes,
void* dstbits, int dstlinebytes)
{
- const DWORD* srcpixel;
+ const BYTE* srcpixel;
DWORD* dstpixel;
+ DWORD prev, curr;
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=(const DWORD*)(((const char*)srcpixel)+3);
- *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */
- ( srcval & 0x00ff00) | /* g */
- ((srcval << 16) & 0xff0000); /* l */
+ curr = *(const DWORD*)( (int)srcpixel & 0xfffffffc);
+ for( x = 0; x < width; x++) {
+ switch( (int)srcpixel & 0x3) {
+ case 0:
+ curr = *(const DWORD*)( srcpixel);
+ *dstpixel = ((curr >> 16) & 0x0000ff) | /* h1 */
+ ( curr & 0x00ff00) | /* g1 */
+ ((curr << 16) & 0xff0000); /* l1 */
+ break;
+ case 3:
+ prev = curr;
+ curr = *(const DWORD*)( srcpixel + 1);
+ *dstpixel = ((prev >> 8) & 0xff0000) | /* l2 */
+ ((curr << 8) & 0x00ff00) | /* g2 */
+ ((curr >> 8) & 0x0000ff); /* h2 */
+ break;
+ case 2:
+ prev = curr;
+ curr = *(const DWORD*)( srcpixel + 2);
+ *dstpixel = ( prev & 0xff0000) | /* l3 */
+ ((prev >> 16) & 0x00ff00) | /* g3 */
+ ( curr & 0x0000ff); /* h3 */
+ break;
+ case 1:
+ *dstpixel = ((curr >> 24) & 0x0000ff) | /* h4 */
+ ((curr >> 8) & 0x00ff00) | /* g4 */
+ ((curr << 8) & 0xff0000); /* l4 */
+ break;
+ }
+ dstpixel++;
+ srcpixel += 3;
}
srcbits = (const char*)srcbits + srclinebytes;
dstbits = (char*)dstbits + dstlinebytes;
More information about the wine-patches
mailing list