forked from len0rd/rockbox
ImageViewer: Fix FS#13329 (GIF File handle/memory leaks)
Change-Id: Ib3ef22716c8ba35c7bb78231ca4f5c7155f16018
This commit is contained in:
parent
f379e1dbb3
commit
8f063d49c2
3 changed files with 40 additions and 16 deletions
|
|
@ -132,6 +132,8 @@ static int load_image(char *filename, struct image_info *info,
|
||||||
time = *rb->current_tick - time;
|
time = *rb->current_tick - time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gif_decoder_destroy_memory_pool(p_decoder);
|
||||||
|
|
||||||
if (!iv->running_slideshow && !p_decoder->error)
|
if (!iv->running_slideshow && !p_decoder->error)
|
||||||
{
|
{
|
||||||
rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
|
rb->snprintf(print, sizeof(print), " %ld.%02ld sec ", time/HZ, time%HZ);
|
||||||
|
|
@ -142,6 +144,9 @@ static int load_image(char *filename, struct image_info *info,
|
||||||
|
|
||||||
if (p_decoder->error)
|
if (p_decoder->error)
|
||||||
{
|
{
|
||||||
|
if (p_decoder->error == D_GIF_ERR_NOT_ENOUGH_MEM)
|
||||||
|
return PLUGIN_OUTOFMEM;
|
||||||
|
|
||||||
rb->splashf(HZ, "%s", GifErrorString(p_decoder->error));
|
rb->splashf(HZ, "%s", GifErrorString(p_decoder->error));
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -157,12 +162,9 @@ static int load_image(char *filename, struct image_info *info,
|
||||||
img_size = (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;
|
disp_size = (sizeof(unsigned char *)*p_decoder->frames_count*4 + 3) & ~3;
|
||||||
|
|
||||||
|
/* No memory to allocate disp matrix */
|
||||||
if (memory_size < img_size + disp_size)
|
if (memory_size < img_size + disp_size)
|
||||||
{
|
return PLUGIN_OUTOFMEM;
|
||||||
/* 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 = (unsigned char **)(p_decoder->mem + img_size);
|
||||||
disp_buf = (unsigned char *)disp + disp_size;
|
disp_buf = (unsigned char *)disp + disp_size;
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,11 @@ void gif_decoder_init(struct gif_decoder *d, void *mem, size_t size)
|
||||||
init_memory_pool(d->mem_size, d->mem);
|
init_memory_pool(d->mem_size, d->mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gif_decoder_destroy_memory_pool(struct gif_decoder *d)
|
||||||
|
{
|
||||||
|
destroy_memory_pool(d->mem);
|
||||||
|
}
|
||||||
|
|
||||||
void gif_open(char *filename, struct gif_decoder *d)
|
void gif_open(char *filename, struct gif_decoder *d)
|
||||||
{
|
{
|
||||||
if ((GifFile = DGifOpenFileName(filename, &d->error)) == NULL)
|
if ((GifFile = DGifOpenFileName(filename, &d->error)) == NULL)
|
||||||
|
|
@ -181,6 +186,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
{
|
{
|
||||||
/* error allocating temp space */
|
/* error allocating temp space */
|
||||||
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
|
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
|
||||||
|
DGifCloseFile(GifFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +202,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (pixels_buffer[0] == NULL)
|
if (pixels_buffer[0] == NULL)
|
||||||
{
|
{
|
||||||
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
|
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global background color */
|
/* Global background color */
|
||||||
|
|
@ -215,7 +221,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
|
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (RecordType)
|
switch (RecordType)
|
||||||
|
|
@ -225,7 +231,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (DGifGetImageDesc(GifFile) == GIF_ERROR)
|
if (DGifGetImageDesc(GifFile) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Image Position relative to canvas */
|
/* Image Position relative to canvas */
|
||||||
|
|
@ -239,7 +245,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
GifFile->SColorMap == NULL)
|
GifFile->SColorMap == NULL)
|
||||||
{
|
{
|
||||||
d->error = D_GIF_ERR_NO_COLOR_MAP;
|
d->error = D_GIF_ERR_NO_COLOR_MAP;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
|
|
@ -247,7 +253,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
GifFile->Image.Top+GifFile->Image.Height>GifFile->SHeight)
|
GifFile->Image.Top+GifFile->Image.Height>GifFile->SHeight)
|
||||||
{
|
{
|
||||||
d->error = D_GIF_ERR_DATA_TOO_BIG;
|
d->error = D_GIF_ERR_DATA_TOO_BIG;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GifFile->Image.GCB &&
|
if (GifFile->Image.GCB &&
|
||||||
|
|
@ -275,7 +281,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
|
if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gif2pixels(Line, pixels_buffer[buf_idx],
|
gif2pixels(Line, pixels_buffer[buf_idx],
|
||||||
|
|
@ -294,7 +300,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
|
if (DGifGetLine(GifFile, Line, Width) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gif2pixels(Line, pixels_buffer[buf_idx],
|
gif2pixels(Line, pixels_buffer[buf_idx],
|
||||||
|
|
@ -310,7 +316,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
{
|
{
|
||||||
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
|
d->error = D_GIF_ERR_NOT_ENOUGH_MEM;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bm.data = out + d->native_img_size*d->frames_count;
|
bm.data = out + d->native_img_size*d->frames_count;
|
||||||
|
|
@ -350,7 +356,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
GIF_ERROR)
|
GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExtCode == GRAPHICS_EXT_FUNC_CODE)
|
if (ExtCode == GRAPHICS_EXT_FUNC_CODE)
|
||||||
|
|
@ -364,7 +370,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
GifFile->Image.GCB) == GIF_ERROR)
|
GifFile->Image.GCB) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
d->delay = GifFile->Image.GCB->DelayTime;
|
d->delay = GifFile->Image.GCB->DelayTime;
|
||||||
}
|
}
|
||||||
|
|
@ -375,7 +381,7 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR)
|
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
return;
|
goto free_and_return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -391,6 +397,10 @@ void gif_decode(struct gif_decoder *d,
|
||||||
if (DGifCloseFile(GifFile) == GIF_ERROR)
|
if (DGifCloseFile(GifFile) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
d->error = GifFile->Error;
|
d->error = GifFile->Error;
|
||||||
|
free(pixels_buffer[0]);
|
||||||
|
if (pixels_buffer[1])
|
||||||
|
free(pixels_buffer[1]);
|
||||||
|
free(Line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -472,4 +482,15 @@ void gif_decode(struct gif_decoder *d,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return;
|
||||||
|
|
||||||
|
free_and_return:
|
||||||
|
if (Line)
|
||||||
|
free(Line);
|
||||||
|
if (pixels_buffer[0])
|
||||||
|
free(pixels_buffer[0]);
|
||||||
|
if (pixels_buffer[1])
|
||||||
|
free(pixels_buffer[1]);
|
||||||
|
DGifCloseFile(GifFile);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ struct gif_decoder {
|
||||||
};
|
};
|
||||||
|
|
||||||
void gif_decoder_init(struct gif_decoder *decoder, void *mem, size_t size);
|
void gif_decoder_init(struct gif_decoder *decoder, void *mem, size_t size);
|
||||||
|
void gif_decoder_destroy_memory_pool(struct gif_decoder *d);
|
||||||
void gif_open(char *filename, struct gif_decoder *d);
|
void gif_open(char *filename, struct gif_decoder *d);
|
||||||
void gif_decode(struct gif_decoder *d, void (*pf_progress)(int current, int total));
|
void gif_decode(struct gif_decoder *d, void (*pf_progress)(int current, int total));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue