Commit 883e0b0e authored by Rein Klazes's avatar Rein Klazes Committed by Alexandre Julliard

x11drv: Avoid unaligned 32 bit reads, and reads beyond the input pixel

buffer in the convert_888_to_0888_* functions.
parent ac3be957
...@@ -821,18 +821,36 @@ static void convert_888_to_0888_asis(int width, int height, ...@@ -821,18 +821,36 @@ static void convert_888_to_0888_asis(int width, int height,
const DWORD* srcpixel; const DWORD* srcpixel;
DWORD* dstpixel; DWORD* dstpixel;
int x,y; int x,y;
int oddwidth; int w1, w2, w3;
oddwidth=width & 3; w1 = min( (INT_PTR)srcbits & 3, width);
width=width/4; w2 = ( width - w1) / 4;
w3 = ( width - w1) & 3;
for (y=0; y<height; y++) { for (y=0; y<height; y++) {
srcpixel=srcbits; srcpixel=srcbits;
dstpixel=dstbits; dstpixel=dstbits;
for (x=0; x<width; x++) { /* advance w1 pixels to make srcpixel 32 bit alignd */
srcpixel = (const DWORD*)((INT_PTR)srcpixel & ~3);
srcpixel += w1;
dstpixel += w1;
/* and do the w1 pixels */
x = w1;
if( x) {
dstpixel[ -1] = ( srcpixel[ -1] >> 8); /* h4, g4, l4 */
if( --x) {
dstpixel[ -2] = ( srcpixel[ -2] >> 16) | /* g3, l3 */
((srcpixel[ -1] << 16) & 0x00ff0000); /* h3 */
if( --x) {
dstpixel[ -3] = ( srcpixel[ -3] >> 24) | /* l2 */
((srcpixel[ -2] << 8) & 0x00ffff00); /* h2, g2 */
}
}
}
for (x=0; x < w2; x++) {
/* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
DWORD srcval1,srcval2; DWORD srcval1,srcval2;
srcval1=srcpixel[0]; srcval1=srcpixel[0];
dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */ dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
srcval2=srcpixel[1]; srcval2=srcpixel[1];
dstpixel[1]=( srcval1 >> 24) | /* l2 */ dstpixel[1]=( srcval1 >> 24) | /* l2 */
((srcval2 << 8) & 0x00ffff00); /* h2, g2 */ ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
...@@ -843,12 +861,18 @@ static void convert_888_to_0888_asis(int width, int height, ...@@ -843,12 +861,18 @@ static void convert_888_to_0888_asis(int width, int height,
srcpixel+=3; srcpixel+=3;
dstpixel+=4; dstpixel+=4;
} }
/* And now up to 3 odd pixels */ /* do last w3 pixels */
for (x=0; x<oddwidth; x++) { x = w3;
DWORD srcval; if( x) {
srcval=*srcpixel; dstpixel[0]=( srcpixel[0] & 0x00ffffff); /* h1, g1, l1 */
srcpixel=(const DWORD*)(((const char*)srcpixel)+3); if( --x) {
*dstpixel++=( srcval & 0x00ffffff); /* h, g, l */ dstpixel[1]=( srcpixel[0]>> 24) | /* l2 */
((srcpixel[1]<< 8) & 0x00ffff00); /* h2, g2 */
if( --x) {
dstpixel[2]=( srcpixel[1]>> 16) | /* g3, l3 */
((srcpixel[2]<< 16) & 0x00ff0000); /* h3 */
}
}
} }
srcbits = (const char*)srcbits + srclinebytes; srcbits = (const char*)srcbits + srclinebytes;
dstbits = (char*)dstbits + dstlinebytes; dstbits = (char*)dstbits + dstlinebytes;
...@@ -862,14 +886,36 @@ static void convert_888_to_0888_reverse(int width, int height, ...@@ -862,14 +886,36 @@ static void convert_888_to_0888_reverse(int width, int height,
const DWORD* srcpixel; const DWORD* srcpixel;
DWORD* dstpixel; DWORD* dstpixel;
int x,y; int x,y;
int oddwidth; int w1, w2, w3;
oddwidth=width & 3; w1 = min( (INT_PTR)srcbits & 3, width);
width=width/4; w2 = ( width - w1) / 4;
w3 = ( width - w1) & 3;
for (y=0; y<height; y++) { for (y=0; y<height; y++) {
srcpixel=srcbits; srcpixel=srcbits;
dstpixel=dstbits; dstpixel=dstbits;
for (x=0; x<width; x++) { /* advance w1 pixels to make srcpixel 32 bit alignd */
srcpixel = (const DWORD*)((INT_PTR)srcpixel & ~3);
srcpixel += w1;
dstpixel += w1;
/* and do the w1 pixels */
x = w1;
if( x) {
dstpixel[ -1]=((srcpixel[ -1] >> 24) & 0x0000ff) | /* h4 */
((srcpixel[ -1] >> 8) & 0x00ff00) | /* g4 */
((srcpixel[ -1] << 8) & 0xff0000); /* l4 */
if( --x) {
dstpixel[ -2]=( srcpixel[ -2] & 0xff0000) | /* l3 */
((srcpixel[ -2] >> 16) & 0x00ff00) | /* g3 */
( srcpixel[ -1] & 0x0000ff); /* h3 */
if( --x) {
dstpixel[ -3]=((srcpixel[ -3] >> 8) & 0xff0000) | /* l2 */
((srcpixel[ -2] << 8) & 0x00ff00) | /* g2 */
((srcpixel[ -2] >> 8) & 0x0000ff); /* h2 */
}
}
}
for (x=0; x < w2; x++) {
/* Do 4 pixels at a time: 3 dwords in and 4 dwords out */ /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
DWORD srcval1,srcval2; DWORD srcval1,srcval2;
...@@ -891,14 +937,22 @@ static void convert_888_to_0888_reverse(int width, int height, ...@@ -891,14 +937,22 @@ static void convert_888_to_0888_reverse(int width, int height,
srcpixel+=3; srcpixel+=3;
dstpixel+=4; dstpixel+=4;
} }
/* And now up to 3 odd pixels */ /* do last w3 pixels */
for (x=0; x<oddwidth; x++) { x = w3;
DWORD srcval; if( x) {
srcval=*srcpixel; dstpixel[0]=((srcpixel[0] >> 16) & 0x0000ff) | /* h1 */
srcpixel=(const DWORD*)(((const char*)srcpixel)+3); ( srcpixel[0] & 0x00ff00) | /* g1 */
*dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */ ((srcpixel[0] << 16) & 0xff0000); /* l1 */
( srcval & 0x00ff00) | /* g */ if( --x) {
((srcval << 16) & 0xff0000); /* l */ dstpixel[1]=((srcpixel[0] >> 8) & 0xff0000) | /* l2 */
((srcpixel[1] << 8) & 0x00ff00) | /* g2 */
((srcpixel[1] >> 8) & 0x0000ff); /* h2 */
if( --x) {
dstpixel[2]=( srcpixel[1] & 0xff0000) | /* l3 */
((srcpixel[1] >> 16) & 0x00ff00) | /* g3 */
( srcpixel[2] & 0x0000ff); /* h3 */
}
}
} }
srcbits = (const char*)srcbits + srclinebytes; srcbits = (const char*)srcbits + srclinebytes;
dstbits = (char*)dstbits + dstlinebytes; dstbits = (char*)dstbits + dstlinebytes;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment