Commit c8f3fed5 authored by Alexandre Julliard's avatar Alexandre Julliard

Ignore RLE data that goes past the line end (found by Uwe Bonnes).

General cleanup of the RLE routines.
parent 76598823
......@@ -67,6 +67,13 @@ typedef struct
} X11DRV_DIB_IMAGEBITS_DESCR;
enum Rle_EscapeCodes
{
RLE_EOL = 0, /* End of line */
RLE_END = 1, /* End of bitmap */
RLE_DELTA = 2 /* Delta */
};
/***********************************************************************
* X11DRV_DIB_GetXImageWidthBytes
*
......@@ -855,70 +862,44 @@ static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
int left, int *colors,
XImage *bmpImage )
{
int x = 0, c, length;
int x = 0, y = lines - 1, c, length;
const BYTE *begin = bits;
lines--;
while ((int)lines >= 0) {
while (y >= 0)
{
length = *bits++;
if (length) { /* encoded */
c = *bits++;
while (length--) {
if(x >= width) {
x = 0;
if(--lines < 0)
return;
}
XPutPixel(bmpImage, x++, lines, colors[c >>4]);
if (length) {
length--;
if(x >= width) {
x = 0;
if(--lines < 0)
return;
}
XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
}
if (x >= width) break;
XPutPixel(bmpImage, x++, y, colors[c >> 4]);
if (!length--) break;
if (x >= width) break;
XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
}
} else {
length = *bits++;
switch (length) {
case 0: /* eol */
switch (length)
{
case RLE_EOL:
x = 0;
lines--;
continue;
y--;
break;
case 1: /* eopicture */
case RLE_END:
return;
case 2: /* delta */
case RLE_DELTA:
x += *bits++;
if(x >= width) {
FIXME_(x11drv)("x-delta is too large?\n");
return;
}
lines -= *bits++;
continue;
y -= *bits++;
break;
default: /* absolute */
while (length--) {
c = *bits++;
if(x >= width) {
x = 0;
if(--lines < 0)
return;
}
XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
if (length) {
length--;
if(x >= width) {
x = 0;
if(--lines < 0)
return;
}
XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
}
if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
if (!length--) break;
if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
}
if ((bits - begin) & 1)
bits++;
......@@ -1272,32 +1253,16 @@ static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
* James A. Youngman <mbcstjy@afs.man.ac.uk>
* [JAY]
*/
enum Rle8_EscapeCodes
{
/*
* Apologies for polluting your file's namespace...
*/
RleEol = 0, /* End of line */
RleEnd = 1, /* End of bitmap */
RleDelta = 2 /* Delta */
};
static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
DWORD width, DWORD dstwidth,
int left, int *colors,
XImage *bmpImage )
{
int x; /* X-positon on each line. Increases. */
int line; /* Line #. Starts at lines-1, decreases */
int y; /* Line #. Starts at lines-1, decreases */
const BYTE *pIn = bits; /* Pointer to current position in bits */
BYTE length; /* The length pf a run */
BYTE color_index; /* index into colors[] as read from bits */
BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
int color; /* value of colour[color_index] */
if (lines == 0) /* Let's hope this doesn't happen. */
return;
/*
* Note that the bitmap data is stored by Windows starting at the
......@@ -1307,8 +1272,8 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
*/
x = 0;
line = lines-1;
do
y = lines - 1;
while (y >= 0)
{
length = *pIn++;
......@@ -1325,18 +1290,8 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
/*
* [Run-Length] Encoded mode
*/
color_index = (*pIn++); /* Get the colour index. */
color = colors[color_index];
while(length--)
{
if (x>=dstwidth)
{
x=0;
line--;
}
XPutPixel(bmpImage, x++, line, color);
}
int color = colors[*pIn++];
while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
}
else
{
......@@ -1346,68 +1301,36 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
escape_code = (*pIn++);
switch(escape_code)
{
case RleEol: /* =0, end of line */
{
case RLE_EOL:
x = 0;
line--;
y--;
break;
}
case RleEnd: /* =1, end of bitmap */
{
/*
* Not all RLE8 bitmaps end with this
* code. For example, Paint Shop Pro
* produces some that don't. That's (I think)
* what caused the previous implementation to
* fail. [JAY]
case RLE_END:
/* Not all RLE8 bitmaps end with this code. For
* example, Paint Shop Pro produces some that don't.
* That's (I think) what caused the previous
* implementation to fail. [JAY]
*/
line=-1; /* Cause exit from do loop. */
break;
}
return;
case RleDelta: /* =2, a delta */
{
/*
* Note that deltaing to line 0
* will cause an exit from the loop,
* which may not be what is intended.
* The fact that there is a delta in the bits
* almost certainly implies that there is data
* to follow. You may feel that we should
* jump to the top of the loop to avoid exiting
* in this case.
*
* TODO: Decide what to do here in that case. [JAY]
*/
case RLE_DELTA:
x += (*pIn++);
line -= (*pIn++);
if (line == 0)
{
TRACE("Delta to last line of bitmap "
"(wrongly?) causes loop exit\n");
}
y -= (*pIn++);
break;
}
default: /* >2, switch to absolute mode */
{
/*
* Absolute Mode
*/
default: /* switch to absolute mode */
length = escape_code;
while(length--)
while (length--)
{
color_index = (*pIn++);
if (x>=dstwidth)
int color = colors[*pIn++];
if (x >= dstwidth)
{
x=0;
line--;
pIn += length;
break;
}
XPutPixel(bmpImage, x++, line,
colors[color_index]);
XPutPixel(bmpImage, x++, y, color);
}
/*
* If you think for a moment you'll realise that the
* only time we could ever possibly read an odd
......@@ -1417,25 +1340,10 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
* need to worry about it. Everywhere else the
* bytes are always read in pairs. [JAY]
*/
if (escape_code & 1)
pIn++; /* Throw away the pad byte. */
if (escape_code & 1) pIn++; /* Throw away the pad byte. */
break;
}
} /* switch (escape_code) : Escape sequence */
} /* process either an encoded sequence or an escape sequence */
/* We expect to come here more than once per line. */
} while (line >= 0); /* Do this until the bitmap is filled */
/*
* Everybody comes here at the end.
* Check how we exited the loop and print a message if it's a bit odd.
* [JAY]
*/
if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
{
TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
"bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
}
}
}
......
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