| From 908a179726d010963f4fe1b57fb5f7bf590d7d64 Mon Sep 17 00:00:00 2001 |
| From: Kim Woelders <kim@woelders.dk> |
| Date: Tue, 31 Dec 2013 18:13:45 +0100 |
| Subject: [PATCH 2/5] GIF loader: Simplify error handling. |
| |
| Also: |
| - Fix memory leak when image data allocation fails. |
| - Some aux data arrays may as well be const. |
| --- |
| src/modules/loaders/loader_gif.c | 80 ++++++++++++++++------------------------ |
| 1 file changed, 32 insertions(+), 48 deletions(-) |
| |
| diff --git a/src/modules/loaders/loader_gif.c b/src/modules/loaders/loader_gif.c |
| index d1c2ae2..a39c860 100644 |
| --- a/src/modules/loaders/loader_gif.c |
| +++ b/src/modules/loaders/loader_gif.c |
| @@ -8,6 +8,9 @@ char |
| load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| char immediate_load) |
| { |
| + static const int intoffset[] = { 0, 4, 2, 1 }; |
| + static const int intjump[] = { 8, 8, 4, 2 }; |
| + int rc; |
| DATA32 *ptr; |
| GifFileType *gif; |
| GifRowType *rows; |
| @@ -16,8 +19,6 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| int i, j, done, bg, r, g, b, w = 0, h = 0; |
| float per = 0.0, per_inc; |
| int last_per = 0, last_y = 0; |
| - int intoffset[] = { 0, 4, 2, 1 }; |
| - int intjump[] = { 8, 8, 4, 2 }; |
| int transp; |
| int fd; |
| |
| @@ -49,6 +50,8 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| return 0; |
| } |
| |
| + rc = 0; /* Failure */ |
| + |
| do |
| { |
| if (DGifGetRecordType(gif, &rec) == GIF_ERROR) |
| @@ -66,37 +69,19 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| w = gif->Image.Width; |
| h = gif->Image.Height; |
| if (!IMAGE_DIMENSIONS_OK(w, h)) |
| - { |
| - DGifCloseFile(gif); |
| - return 0; |
| - } |
| - rows = malloc(h * sizeof(GifRowType *)); |
| + goto quit2; |
| + |
| + rows = calloc(h, sizeof(GifRowType *)); |
| if (!rows) |
| - { |
| - DGifCloseFile(gif); |
| - return 0; |
| - } |
| - for (i = 0; i < h; i++) |
| - { |
| - rows[i] = NULL; |
| - } |
| + goto quit2; |
| + |
| for (i = 0; i < h; i++) |
| { |
| rows[i] = malloc(w * sizeof(GifPixelType)); |
| if (!rows[i]) |
| - { |
| - DGifCloseFile(gif); |
| - for (i = 0; i < h; i++) |
| - { |
| - if (rows[i]) |
| - { |
| - free(rows[i]); |
| - } |
| - } |
| - free(rows); |
| - return 0; |
| - } |
| + goto quit; |
| } |
| + |
| if (gif->Image.Interlace) |
| { |
| for (i = 0; i < 4; i++) |
| @@ -135,6 +120,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| } |
| } |
| while (rec != TERMINATE_RECORD_TYPE); |
| + |
| if (transp >= 0) |
| { |
| SET_FLAG(im->flags, F_HAS_ALPHA); |
| @@ -143,6 +129,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| { |
| UNSET_FLAG(im->flags, F_HAS_ALPHA); |
| } |
| + |
| /* set the format string member to the lower-case full extension */ |
| /* name for the format - so example names would be: */ |
| /* "png", "jpeg", "tiff", "ppm", "pgm", "pbm", "gif", "xpm" ... */ |
| @@ -150,17 +137,15 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| im->h = h; |
| if (!im->format) |
| im->format = strdup("gif"); |
| + |
| if (im->loader || immediate_load || progress) |
| { |
| bg = gif->SBackGroundColor; |
| cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap); |
| im->data = (DATA32 *) malloc(sizeof(DATA32) * w * h); |
| if (!im->data) |
| - { |
| - DGifCloseFile(gif); |
| - free(rows); |
| - return 0; |
| - } |
| + goto quit; |
| + |
| ptr = im->data; |
| per_inc = 100.0 / (((float)w) * h); |
| for (i = 0; i < h; i++) |
| @@ -188,30 +173,29 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, |
| last_per = (int)per; |
| if (!(progress(im, (int)per, 0, last_y, w, i))) |
| { |
| - DGifCloseFile(gif); |
| - for (i = 0; i < h; i++) |
| - { |
| - free(rows[i]); |
| - } |
| - free(rows); |
| - return 2; |
| + rc = 2; |
| + goto quit; |
| } |
| last_y = i; |
| } |
| } |
| } |
| + |
| + if (progress) |
| + progress(im, 100, 0, last_y, w, h); |
| } |
| - if (progress) |
| - { |
| - progress(im, 100, 0, last_y, w, h); |
| - } |
| - DGifCloseFile(gif); |
| + |
| + rc = 1; /* Success */ |
| + |
| + quit: |
| for (i = 0; i < h; i++) |
| - { |
| - free(rows[i]); |
| - } |
| + free(rows[i]); |
| free(rows); |
| - return 1; |
| + |
| + quit2: |
| + DGifCloseFile(gif); |
| + |
| + return rc; |
| } |
| |
| void |
| -- |
| 2.3.1 |
| |