From 734ef12fdfcf5a654d18633ef497cbcf8c912a25 Mon Sep 17 00:00:00 2001 From: Andrew Hannam Date: Thu, 9 May 2013 23:39:38 +1000 Subject: [PATCH] Image Decoder Fixes Fixes to memory allocation for BMP and NATIVE Fixes to source offset images for GIF --- src/gdisp/image_bmp.c | 1 - src/gdisp/image_gif.c | 115 ++++++++++++++++++++++++--------------- src/gdisp/image_native.c | 17 +++--- 3 files changed, 82 insertions(+), 51 deletions(-) diff --git a/src/gdisp/image_bmp.c b/src/gdisp/image_bmp.c index 4f4084c9..be97eb39 100644 --- a/src/gdisp/image_bmp.c +++ b/src/gdisp/image_bmp.c @@ -787,7 +787,6 @@ gdispImageError gdispImageCache_BMP(gdispImage *img) { priv->frame0cache = (pixel_t *)gdispImageAlloc(img, len); if (!priv->frame0cache) return GDISP_IMAGE_ERR_NOMEMORY; - img->membytes += len; /* Read the entire bitmap into cache */ img->io.fns->seek(&img->io, priv->frame0pos); diff --git a/src/gdisp/image_gif.c b/src/gdisp/image_gif.c index f06dcca2..3bf745cb 100644 --- a/src/gdisp/image_gif.c +++ b/src/gdisp/image_gif.c @@ -876,11 +876,10 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) { // We have a transparent pixel - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } - gcnt = 0; continue; } priv->buf[gcnt++] = cache->palette[col]; @@ -892,9 +891,9 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ } // We have finished the line - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break; } } @@ -931,11 +930,10 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) { // We have a transparent pixel - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } - gcnt = 0; continue; } priv->buf[gcnt++] = decode->palette[col]; @@ -944,13 +942,20 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ gdispBlitAreaEx(x+mx-gcnt+1, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; } + continue; + } + // We have finished the visible area - dump the buffer to the display + switch(gcnt) { + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } } // We have finished the line - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break; } } // Every 8th row starting at row 4 @@ -971,11 +976,10 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) { // We have a transparent pixel - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } - gcnt = 0; continue; } priv->buf[gcnt++] = decode->palette[col]; @@ -984,13 +988,20 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ gdispBlitAreaEx(x+mx-gcnt+1, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; } + continue; + } + // We have finished the visible area - dump the buffer to the display + switch(gcnt) { + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } } // We have finished the line - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break; } } // Every 4th row starting at row 2 @@ -1011,11 +1022,10 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) { // We have a transparent pixel - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } - gcnt = 0; continue; } priv->buf[gcnt++] = decode->palette[col]; @@ -1024,13 +1034,20 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ gdispBlitAreaEx(x+mx-gcnt+1, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; } + continue; + } + // We have finished the visible area - dump the buffer to the display + switch(gcnt) { + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } } // We have finished the line - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break; } } // Every 2nd row starting at row 1 @@ -1051,11 +1068,10 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) { // We have a transparent pixel - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } - gcnt = 0; continue; } priv->buf[gcnt++] = decode->palette[col]; @@ -1064,13 +1080,20 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ gdispBlitAreaEx(x+mx-gcnt+1, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; } + continue; + } + // We have finished the visible area - dump the buffer to the display + switch(gcnt) { + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } } // We have finished the line - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break; } } } else { @@ -1092,26 +1115,32 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_ if ((priv->frame.flags & GIFL_TRANSPARENT) && col == priv->frame.paltrans) { // We have a transparent pixel - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } - gcnt = 0; continue; } priv->buf[gcnt++] = decode->palette[col]; if (gcnt >= BLIT_BUFFER_SIZE) { // We have run out of buffer - dump it to the display - gdispBlitAreaEx(x+mx-gcnt+1, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); + gdispBlitAreaEx(x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; } + continue; + } + // We have finished the visible area - dump the buffer to the display + switch(gcnt) { + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break; } } // We have finished the line - dump the buffer to the display switch(gcnt) { - case 0: break; - case 1: gdispDrawPixel(x+mx-gcnt, y+my, priv->buf[0]); break; - default: gdispBlitAreaEx(x+mx-gcnt, y+my, gcnt, 1, 0, 0, gcnt, priv->buf); break; + case 0: break; + case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break; + default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break; } } } diff --git a/src/gdisp/image_native.c b/src/gdisp/image_native.c index 8c03e63e..43a342cc 100644 --- a/src/gdisp/image_native.c +++ b/src/gdisp/image_native.c @@ -24,6 +24,12 @@ #define HEADER_SIZE 8 #define FRAME0POS (HEADER_SIZE) +/** + * Helper Routines Needed + */ +void *gdispImageAlloc(gdispImage *img, size_t sz); +void gdispImageFree(gdispImage *img, void *ptr, size_t sz); + typedef struct gdispImagePrivate { pixel_t *frame0cache; pixel_t buf[BLIT_BUFFER_SIZE]; @@ -48,9 +54,8 @@ gdispImageError gdispImageOpen_NATIVE(gdispImage *img) { img->height = (((uint16_t)hdr[4])<<8) | (hdr[5]); if (img->width < 1 || img->height < 1) return GDISP_IMAGE_ERR_BADDATA; - if (!(img->priv = (gdispImagePrivate *)chHeapAlloc(NULL, sizeof(gdispImagePrivate)))) + if (!(img->priv = (gdispImagePrivate *)gdispImageAlloc(img, sizeof(gdispImagePrivate)))) return GDISP_IMAGE_ERR_NOMEMORY; - img->membytes = sizeof(gdispImagePrivate); img->priv->frame0cache = 0; return GDISP_IMAGE_ERR_OK; @@ -59,11 +64,10 @@ gdispImageError gdispImageOpen_NATIVE(gdispImage *img) { void gdispImageClose_NATIVE(gdispImage *img) { if (img->priv) { if (img->priv->frame0cache) - chHeapFree((void *)img->priv->frame0cache); - chHeapFree((void *)img->priv); + gdispImageFree(img, (void *)img->priv->frame0cache, img->width * img->height * sizeof(pixel_t)); + gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate)); img->priv = 0; } - img->membytes = 0; img->io.fns->close(&img->io); } @@ -76,10 +80,9 @@ gdispImageError gdispImageCache_NATIVE(gdispImage *img) { /* We need to allocate the cache */ len = img->width * img->height * sizeof(pixel_t); - img->priv->frame0cache = (pixel_t *)chHeapAlloc(NULL, len); + img->priv->frame0cache = (pixel_t *)gdispImageAlloc(img, len); if (!img->priv->frame0cache) return GDISP_IMAGE_ERR_NOMEMORY; - img->membytes += len; /* Read the entire bitmap into cache */ img->io.fns->seek(&img->io, FRAME0POS);