gif viewer: remove max frames count constraint

Change-Id: I0be2f86234cfc5fd4ab6bb21fb918e507c608f2f
Reviewed-on: http://gerrit.rockbox.org/380
Reviewed-by: Thomas Martitz <kugel@rockbox.org>
Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
This commit is contained in:
Marcin Bukat 2013-01-15 21:51:46 +01:00
parent 1501df045f
commit 071c95be70
3 changed files with 53 additions and 24 deletions

View file

@ -31,9 +31,11 @@ static struct gif_decoder decoder;
static char print[32]; /* use a common snprintf() buffer */ static char print[32]; /* use a common snprintf() buffer */
/* decompressed image in the possible sizes (1,2,4,8), wasting the other */ /* pointers to decompressed frame in the possible sizes ds = (1,2,4,8)
/* max 32 frames */ * basicaly equivalent to *disp[n][4] where n is the number of frames
static unsigned char *disp[GIF_MAX_FRAMES][9]; * in gif file. The matrix is allocated after decoded frames.
*/
static unsigned char **disp;
static unsigned char *disp_buf; static unsigned char *disp_buf;
#if defined(HAVE_LCD_COLOR) #if defined(HAVE_LCD_COLOR)
@ -81,10 +83,7 @@ static int load_image(char *filename, struct image_info *info,
struct gif_decoder *p_decoder = &decoder; struct gif_decoder *p_decoder = &decoder;
unsigned char *memory, *memory_max; unsigned char *memory, *memory_max;
size_t memory_size; size_t memory_size, img_size, disp_size;
/* cleanup */
memset(&disp, 0, sizeof(disp));
/* align buffer */ /* align buffer */
memory = (unsigned char *)((intptr_t)(buf + 3) & ~3); memory = (unsigned char *)((intptr_t)(buf + 3) & ~3);
@ -153,18 +152,50 @@ static int load_image(char *filename, struct image_info *info,
info->frames_count = p_decoder->frames_count; info->frames_count = p_decoder->frames_count;
info->delay = p_decoder->delay; info->delay = p_decoder->delay;
//p_decoder->native_img_size = (p_decoder->native_img_size + 3) & ~3; /* check mem constraints
disp_buf = p_decoder->mem + * each frame can have 4 scaled versions with ds = (1,2,4,8)
((p_decoder->native_img_size*p_decoder->frames_count + 3) & ~3); */
img_size = (p_decoder->native_img_size*p_decoder->frames_count + 3) & ~3;
disp_size = (sizeof(unsigned char *)*p_decoder->frames_count*4 + 3) & ~3;
if (memory_size < img_size + disp_size)
{
/* No memory to allocate disp matrix */
rb->splashf(HZ, "%s", GifErrorString(D_GIF_ERR_NOT_ENOUGH_MEM));
return PLUGIN_ERROR;
}
disp = (unsigned char **)(p_decoder->mem + img_size);
disp_buf = (unsigned char *)disp + disp_size;
*buf_size = memory_max - disp_buf; *buf_size = memory_max - disp_buf;
/* set all pointers to NULL initially */
memset(disp, 0, sizeof(unsigned char *)*p_decoder->frames_count*4);
return PLUGIN_OK; return PLUGIN_OK;
} }
/* small helper to convert scalling factor ds
* into disp[frame][] array index
*/
static int ds2index(int ds)
{
int index = 0;
ds >>= 1;
while (ds)
{
index++;
ds >>=1;
}
return index;
}
static int get_image(struct image_info *info, int frame, int ds) static int get_image(struct image_info *info, int frame, int ds)
{ {
unsigned char **p_disp = &disp[frame][ds]; /* short cut */ unsigned char **p_disp = disp + frame*4 + ds2index(ds);
struct gif_decoder *p_decoder = &decoder; struct gif_decoder *p_decoder = &decoder;
info->width = p_decoder->width / ds; info->width = p_decoder->width / ds;
@ -192,14 +223,20 @@ static int get_image(struct image_info *info, int frame, int ds)
if (disp_buf + size >= p_decoder->mem + p_decoder->mem_size) if (disp_buf + size >= p_decoder->mem + p_decoder->mem_size)
{ {
/* have to discard the current */ /* have to discard scaled versions */
int i; for (int i=0; i<p_decoder->frames_count; i++)
for (i=1; i<=8; i++) {
disp[frame][i] = NULL; /* invalidate all bitmaps */ /* leave unscaled pointer allone,
* set rest to NULL
*/
p_disp = disp + i*4 + 1;
memset(p_disp, 0, 3*sizeof(unsigned char *));
}
/* start again from the beginning of the buffer */ /* start again from the beginning of the buffer */
disp_buf = p_decoder->mem + disp_buf = p_decoder->mem +
p_decoder->native_img_size*p_decoder->frames_count; p_decoder->native_img_size*p_decoder->frames_count +
sizeof(unsigned char *)*p_decoder->frames_count*4;
} }
*p_disp = disp_buf; *p_disp = disp_buf;

View file

@ -351,12 +351,6 @@ void gif_decode(struct gif_decoder *d,
} }
d->frames_count++; d->frames_count++;
if (d->frames_count > GIF_MAX_FRAMES)
{
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
return;
}
} }
break; break;

View file

@ -18,8 +18,6 @@
* *
****************************************************************************/ ****************************************************************************/
#define GIF_MAX_FRAMES 32
struct gif_decoder { struct gif_decoder {
unsigned char *mem; unsigned char *mem;
size_t mem_size; size_t mem_size;