Ignore RLE data that goes past the line end (found by Uwe Bonnes).
General cleanup of the RLE routines.
This commit is contained in:
parent
76598823d0
commit
c8f3fed5cb
@ -67,6 +67,13 @@ typedef struct
|
|||||||
} X11DRV_DIB_IMAGEBITS_DESCR;
|
} 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
|
* X11DRV_DIB_GetXImageWidthBytes
|
||||||
*
|
*
|
||||||
@ -855,70 +862,44 @@ static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
|
|||||||
int left, int *colors,
|
int left, int *colors,
|
||||||
XImage *bmpImage )
|
XImage *bmpImage )
|
||||||
{
|
{
|
||||||
int x = 0, c, length;
|
int x = 0, y = lines - 1, c, length;
|
||||||
const BYTE *begin = bits;
|
const BYTE *begin = bits;
|
||||||
|
|
||||||
lines--;
|
while (y >= 0)
|
||||||
|
{
|
||||||
while ((int)lines >= 0) {
|
|
||||||
length = *bits++;
|
length = *bits++;
|
||||||
if (length) { /* encoded */
|
if (length) { /* encoded */
|
||||||
c = *bits++;
|
c = *bits++;
|
||||||
while (length--) {
|
while (length--) {
|
||||||
if(x >= width) {
|
if (x >= width) break;
|
||||||
x = 0;
|
XPutPixel(bmpImage, x++, y, colors[c >> 4]);
|
||||||
if(--lines < 0)
|
if (!length--) break;
|
||||||
return;
|
if (x >= width) break;
|
||||||
}
|
XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
length = *bits++;
|
length = *bits++;
|
||||||
switch (length) {
|
switch (length)
|
||||||
case 0: /* eol */
|
{
|
||||||
|
case RLE_EOL:
|
||||||
x = 0;
|
x = 0;
|
||||||
lines--;
|
y--;
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case 1: /* eopicture */
|
case RLE_END:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2: /* delta */
|
case RLE_DELTA:
|
||||||
x += *bits++;
|
x += *bits++;
|
||||||
if(x >= width) {
|
y -= *bits++;
|
||||||
FIXME_(x11drv)("x-delta is too large?\n");
|
break;
|
||||||
return;
|
|
||||||
}
|
|
||||||
lines -= *bits++;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
default: /* absolute */
|
default: /* absolute */
|
||||||
while (length--) {
|
while (length--) {
|
||||||
c = *bits++;
|
c = *bits++;
|
||||||
if(x >= width) {
|
if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
|
||||||
x = 0;
|
if (!length--) break;
|
||||||
if(--lines < 0)
|
if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
|
||||||
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 ((bits - begin) & 1)
|
if ((bits - begin) & 1)
|
||||||
bits++;
|
bits++;
|
||||||
@ -1272,32 +1253,16 @@ static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
|
|||||||
* James A. Youngman <mbcstjy@afs.man.ac.uk>
|
* James A. Youngman <mbcstjy@afs.man.ac.uk>
|
||||||
* [JAY]
|
* [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,
|
static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
|
||||||
DWORD width, DWORD dstwidth,
|
DWORD width, DWORD dstwidth,
|
||||||
int left, int *colors,
|
int left, int *colors,
|
||||||
XImage *bmpImage )
|
XImage *bmpImage )
|
||||||
{
|
{
|
||||||
int x; /* X-positon on each line. Increases. */
|
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 */
|
const BYTE *pIn = bits; /* Pointer to current position in bits */
|
||||||
BYTE length; /* The length pf a run */
|
BYTE length; /* The length pf a run */
|
||||||
BYTE color_index; /* index into colors[] as read from bits */
|
|
||||||
BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
|
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
|
* 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;
|
x = 0;
|
||||||
line = lines-1;
|
y = lines - 1;
|
||||||
do
|
while (y >= 0)
|
||||||
{
|
{
|
||||||
length = *pIn++;
|
length = *pIn++;
|
||||||
|
|
||||||
@ -1325,18 +1290,8 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
|
|||||||
/*
|
/*
|
||||||
* [Run-Length] Encoded mode
|
* [Run-Length] Encoded mode
|
||||||
*/
|
*/
|
||||||
color_index = (*pIn++); /* Get the colour index. */
|
int color = colors[*pIn++];
|
||||||
color = colors[color_index];
|
while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
|
||||||
|
|
||||||
while(length--)
|
|
||||||
{
|
|
||||||
if (x>=dstwidth)
|
|
||||||
{
|
|
||||||
x=0;
|
|
||||||
line--;
|
|
||||||
}
|
|
||||||
XPutPixel(bmpImage, x++, line, color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1346,68 +1301,36 @@ static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
|
|||||||
escape_code = (*pIn++);
|
escape_code = (*pIn++);
|
||||||
switch(escape_code)
|
switch(escape_code)
|
||||||
{
|
{
|
||||||
case RleEol: /* =0, end of line */
|
case RLE_EOL:
|
||||||
{
|
|
||||||
x = 0;
|
x = 0;
|
||||||
line--;
|
y--;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case RleEnd: /* =1, end of bitmap */
|
case RLE_END:
|
||||||
{
|
/* Not all RLE8 bitmaps end with this code. For
|
||||||
/*
|
* example, Paint Shop Pro produces some that don't.
|
||||||
* Not all RLE8 bitmaps end with this
|
* That's (I think) what caused the previous
|
||||||
* code. For example, Paint Shop Pro
|
* implementation to fail. [JAY]
|
||||||
* produces some that don't. That's (I think)
|
|
||||||
* what caused the previous implementation to
|
|
||||||
* fail. [JAY]
|
|
||||||
*/
|
*/
|
||||||
line=-1; /* Cause exit from do loop. */
|
return;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case RleDelta: /* =2, a delta */
|
case RLE_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]
|
|
||||||
*/
|
|
||||||
x += (*pIn++);
|
x += (*pIn++);
|
||||||
line -= (*pIn++);
|
y -= (*pIn++);
|
||||||
if (line == 0)
|
|
||||||
{
|
|
||||||
TRACE("Delta to last line of bitmap "
|
|
||||||
"(wrongly?) causes loop exit\n");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default: /* >2, switch to absolute mode */
|
default: /* switch to absolute mode */
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Absolute Mode
|
|
||||||
*/
|
|
||||||
length = escape_code;
|
length = escape_code;
|
||||||
while (length--)
|
while (length--)
|
||||||
{
|
{
|
||||||
color_index = (*pIn++);
|
int color = colors[*pIn++];
|
||||||
if (x >= dstwidth)
|
if (x >= dstwidth)
|
||||||
{
|
{
|
||||||
x=0;
|
pIn += length;
|
||||||
line--;
|
break;
|
||||||
}
|
}
|
||||||
XPutPixel(bmpImage, x++, line,
|
XPutPixel(bmpImage, x++, y, color);
|
||||||
colors[color_index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you think for a moment you'll realise that the
|
* If you think for a moment you'll realise that the
|
||||||
* only time we could ever possibly read an odd
|
* 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
|
* need to worry about it. Everywhere else the
|
||||||
* bytes are always read in pairs. [JAY]
|
* bytes are always read in pairs. [JAY]
|
||||||
*/
|
*/
|
||||||
if (escape_code & 1)
|
if (escape_code & 1) pIn++; /* Throw away the pad byte. */
|
||||||
pIn++; /* Throw away the pad byte. */
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
} /* switch (escape_code) : Escape sequence */
|
} /* 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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user