Charles (Chas) Williams
2015-Aug-21 13:10 UTC
[syslinux] [PATCH 2/2] core/graphics: fix lss16 parsing
getnybble() needs to return four bits at a time from every byte. During rle decode, rows are rounded to an integer number of bytes. The rle length needs to be able to hold values > 255. Signed-off-by: Chas Williams <3chas3 at gmail.com> --- core/graphics.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/core/graphics.c b/core/graphics.c index 1604ab4..011be4a 100644 --- a/core/graphics.c +++ b/core/graphics.c @@ -54,6 +54,9 @@ typedef struct { static lssheader_t LSSHeader; +static uint16_t buffer_empty = 1; +static int buffer; + #define LSSMagic LSSHeader.LSSMagic #define GraphXSize LSSHeader.GraphXSize #define GraphYSize LSSHeader.GraphYSize @@ -114,15 +117,17 @@ static int vgasetmode(void) static inline char getnybble(void) { - char data = getc(fd); - - if (data & 0x10) { - data &= 0x0F; - return data; + if (buffer_empty) { + buffer_empty = 0; + buffer = getc(fd); + if (buffer == -1) + printf("EOF!\n"); + } else { + buffer >>= 4; + buffer_empty = 1; } - data = getc(fd); - return (data & 0x0F); + return buffer & 0xF; } /* @@ -139,7 +144,9 @@ static void rledecode(uint8_t *out, size_t count) size_t size = count; uint8_t data; int i; + uint16_t rle_len; + buffer_empty = 1; again: for (i = 0; i < size; i++) { @@ -156,20 +163,20 @@ again: return; /* Start of run sequence */ - data = getnybble(); - if (data == 0) { + rle_len = getnybble(); + if (rle_len == 0) { /* long run */ uint8_t hi; - data = getnybble(); + rle_len = getnybble(); hi = getnybble(); hi <<= 4; - data |= hi; - data += 16; + rle_len |= hi; + rle_len += 16; } /* dorun */ - for (i = 0; i < data; i++) + for (i = 0; i < rle_len; i++) *out++ = prev_pixel; size -= i; @@ -249,7 +256,7 @@ __export void vgadisplayfile(FILE *_fd) /* Load the header */ while (size--) - *p = getc(fd); + *p++ = getc(fd); if (*p != EOF) { com32sys_t ireg, oreg; -- 2.1.0
Patrick Masotta
2015-Aug-22 07:56 UTC
[syslinux] [PATCH 2/2] core/graphics: fix lss16 parsing
>>>>getnybble() needs to return four bits at a time from every byte. During rle decode, rows are rounded to an integer number of bytes. The rle length needs to be able to hold values > 255. Signed-off-by: Chas Williams <3chas3 at gmail.com> <<<< I think this change is also already included in the patch quoted previously by Ady http://www.syslinux.org/archives/2015-July/023835.html -static inline char getnybble(void) +static inline char getnybble(uint8_t* last_nybble) { - char data = getc(fd); - if (data & 0x10) { - data &= 0x0F; - return data; - } + char data; + + if (*last_nybble & 0x10) + { + *last_nybble &= 0x0F; + return *last_nybble; + } data = getc(fd); + + *last_nybble= (data >>4) | 0x10; //Flag nibble already read + return (data & 0x0F); } Please take a moment and see what the quoted code does; it'll save you lot of time. Best, Patrick
Charles (Chas) Williams
2015-Aug-22 22:20 UTC
[syslinux] [PATCH 2/2] core/graphics: fix lss16 parsing
On Sat, 2015-08-22 at 00:56 -0700, Patrick Masotta wrote:> Please take a moment and see what the quoted code does; it'll save you lot of time.I wrote my versions before I knew about the other code. Unfortunately, that other code is a massive single patch and would be hard to review since it would be difficult to bisect should a bug be introduced. I will try to split the other patch into logical parts and submit as time permits.