Merge pull request #68 from inmarket/master

Image Decoder Fixes
ugfx_release_2.6
Tectu 2013-05-09 06:41:57 -07:00
commit efa46eeb5a
3 changed files with 82 additions and 51 deletions

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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);