diff options
author | Jorge Arellano Cid <jcid@dillo.org> | 2009-05-08 16:39:19 -0400 |
---|---|---|
committer | Jorge Arellano Cid <jcid@dillo.org> | 2009-05-08 16:39:19 -0400 |
commit | c206e5e68a1e009df93cf9175d521a4c587158d1 (patch) | |
tree | 104c2e6611501b43e93acf1b65a7c3c8f18b6bd3 | |
parent | 7034881b87b53b087bae78aef8380e5258f68a24 (diff) |
Fix a memory leak when stopping an image-decoding process
-rw-r--r-- | src/dgif.h | 2 | ||||
-rw-r--r-- | src/dicache.c | 17 | ||||
-rw-r--r-- | src/dicache.h | 1 | ||||
-rw-r--r-- | src/djpeg.h | 2 | ||||
-rw-r--r-- | src/gif.c | 45 | ||||
-rw-r--r-- | src/jpeg.c | 27 | ||||
-rw-r--r-- | src/png.c | 33 |
7 files changed, 87 insertions, 40 deletions
@@ -10,7 +10,7 @@ extern "C" { void *a_Gif_new(DilloImage *Image, DilloUrl *url, int version); -void a_Gif_callback(int Op, CacheClient_t *Client); +void a_Gif_callback(int Op, void *data); #ifdef __cplusplus diff --git a/src/dicache.c b/src/dicache.c index 6ffa6559..2e5a442b 100644 --- a/src/dicache.c +++ b/src/dicache.c @@ -175,7 +175,7 @@ static void Dicache_remove(const DilloUrl *Url, int version) { DICacheNode *node; DICacheEntry *entry, *prev; - + _MSG("Dicache_remove url=%s\n", URL_STR(Url)); node = dList_find_sorted(CachedIMGs, Url, Dicache_node_by_url_cmp); prev = entry = (node) ? node->first : NULL; @@ -185,10 +185,15 @@ static void Dicache_remove(const DilloUrl *Url, int version) } if (entry) { + _MSG("Dicache_remove Decoder=%p DecoderData=%p\n", + entry->Decoder, entry->DecoderData); /* Eliminate this dicache entry */ dFree(entry->cmap); a_Bitvec_free(entry->BitVec); a_Imgbuf_unref(entry->v_imgbuf); + if (entry->Decoder) { + entry->Decoder(CA_Abort, entry->DecoderData); + } dicache_size_total -= entry->TotalSize; if (node->first == entry) { @@ -208,12 +213,13 @@ static void Dicache_remove(const DilloUrl *Url, int version) /* * Unrefs the counter of a dicache entry, and _if_ no DwImage is acessing - * this buffer, then we call Dicache_free to do the dirty job. + * this buffer, then we call Dicache_remove() to do the job. */ void a_Dicache_unref(const DilloUrl *Url, int version) { DICacheEntry *entry; + _MSG("a_Dicache_unref\n"); if ((entry = a_Dicache_get_entry(Url, version))) { if (--entry->RefCount == 0) { Dicache_remove(Url, version); @@ -419,9 +425,10 @@ static void *Dicache_image(int ImgType, const char *MimeType, void *Ptr, /* Repeated image */ a_Dicache_ref(DicEntry->url, DicEntry->version); } - DicEntry->Decoder = (ImgType == DIC_Png) ? a_Png_callback : - (ImgType == DIC_Gif) ? a_Gif_callback : - (ImgType == DIC_Jpeg) ? a_Jpeg_callback : NULL; + DicEntry->Decoder = (ImgType == DIC_Png) ? (CA_Callback_t)a_Png_callback : + (ImgType == DIC_Gif) ? (CA_Callback_t)a_Gif_callback : + (ImgType == DIC_Jpeg) ? (CA_Callback_t)a_Jpeg_callback: + NULL; *Data = DicEntry->DecoderData; *Call = (CA_Callback_t) a_Dicache_callback; diff --git a/src/dicache.h b/src/dicache.h index b4ef714d..b7bbb61c 100644 --- a/src/dicache.h +++ b/src/dicache.h @@ -60,7 +60,6 @@ void *a_Dicache_gif_image(const char *Type, void *Ptr, CA_Callback_t *Call, void *a_Dicache_jpeg_image(const char *Type, void *Ptr, CA_Callback_t *Call, void **Data); void a_Dicache_callback(int Op, CacheClient_t *Client); -void a_Dicache_callback2(int Op, CacheClient_t *Client); void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, uint_t width, uint_t height, DilloImgType type); diff --git a/src/djpeg.h b/src/djpeg.h index d88f5671..32419e4b 100644 --- a/src/djpeg.h +++ b/src/djpeg.h @@ -10,7 +10,7 @@ extern "C" { void *a_Jpeg_new(DilloImage *Image, DilloUrl *url, int version); -void a_Jpeg_callback(int Op, CacheClient_t *Client); +void a_Jpeg_callback(int Op, void *data); #ifdef __cplusplus @@ -153,6 +153,7 @@ static size_t Gif_process_bytes(DilloGif *gif, const uchar_t *buf, void *a_Gif_new(DilloImage *Image, DilloUrl *url, int version) { DilloGif *gif = dMalloc(sizeof(DilloGif)); + MSG("Gif_new: gif=%p\n", gif); gif->Image = Image; gif->url = url; @@ -174,15 +175,38 @@ void *a_Gif_new(DilloImage *Image, DilloUrl *url, int version) } /* + * Free the gif-decoding data structure. + */ +static void Gif_free(DilloGif *gif) +{ + int i; + + MSG("Gif_free: gif %p\n", gif); + + dFree(gif->linebuf); + if (gif->spill_lines != NULL) { + for (i = 0; i < gif->num_spill_lines_max; i++) + dFree(gif->spill_lines[i]); + dFree(gif->spill_lines); + } + dFree(gif); +} + +/* * This function is a cache client, it receives data from the cache * and dispatches it to the appropriate gif-processing functions */ -void a_Gif_callback(int Op, CacheClient_t *Client) +void a_Gif_callback(int Op, void *data) { - if (Op) - Gif_close(Client->CbData, Client); - else + if (Op == CA_Send) { + CacheClient_t *Client = data; Gif_write(Client->CbData, Client->Buf, Client->BufSize); + } else if (Op == CA_Close) { + CacheClient_t *Client = data; + Gif_close(Client->CbData, Client); + } else if (Op == CA_Abort) { + Gif_free(data); + } } /* @@ -217,20 +241,9 @@ static void Gif_write(DilloGif *gif, void *Buf, uint_t BufSize) */ static void Gif_close(DilloGif *gif, CacheClient_t *Client) { - int i; - _MSG("Gif_close: destroy gif %p\n", gif); - a_Dicache_close(gif->url, gif->version, Client); - - dFree(gif->linebuf); - - if (gif->spill_lines != NULL) { - for (i = 0; i < gif->num_spill_lines_max; i++) - dFree(gif->spill_lines[i]); - dFree(gif->spill_lines); - } - dFree(gif); + Gif_free(gif); } @@ -94,14 +94,23 @@ METHODDEF(void) Jpeg_errorexit (j_common_ptr cinfo) } /* + * Free the jpeg-decoding data structure. + */ +static void Jpeg_free(DilloJpeg *jpeg) +{ + MSG("Jpeg_free %p\n", jpeg); + jpeg_destroy_decompress(&(jpeg->cinfo)); + dFree(jpeg); +} + +/* * Finish the decoding process */ static void Jpeg_close(DilloJpeg *jpeg, CacheClient_t *Client) { _MSG("Jpeg_close\n"); a_Dicache_close(jpeg->url, jpeg->version, Client); - jpeg_destroy_decompress(&(jpeg->cinfo)); - dFree(jpeg); + Jpeg_free(jpeg); } /* @@ -174,6 +183,7 @@ void *a_Jpeg_new(DilloImage *Image, DilloUrl *url, int version) { my_source_mgr *src; DilloJpeg *jpeg = dMalloc(sizeof(*jpeg)); + MSG("Jpeg_new: jpeg=%p\n", jpeg); jpeg->Image = Image; jpeg->url = url; @@ -206,12 +216,17 @@ void *a_Jpeg_new(DilloImage *Image, DilloUrl *url, int version) return jpeg; } -void a_Jpeg_callback(int Op, CacheClient_t *Client) +void a_Jpeg_callback(int Op, void *data) { - if (Op) - Jpeg_close(Client->CbData, Client); - else + if (Op == CA_Send) { + CacheClient_t *Client = data; Jpeg_write(Client->CbData, Client->Buf, Client->BufSize); + } else if (Op == CA_Close) { + CacheClient_t *Client = data; + Jpeg_close(Client->CbData, Client); + } else if (Op == CA_Abort) { + Jpeg_free(data); + } } /* @@ -291,15 +291,12 @@ static void Png_dataend_callback(png_structp png_ptr, png_infop info_ptr) } /* - * Finish the decoding process (and free the memory) + * Free up the resources for this image. */ -static void Png_close(DilloPng *png, CacheClient_t *Client) +static void Png_free(DilloPng *png) { - _MSG("Png_close\n"); - /* Let dicache know decoding is over */ - a_Dicache_close(png->url, png->version, Client); + MSG("Png_free %p\n", png); - /* Free up the resources for this image */ dFree(png->image_data); dFree(png->row_pointers); dFree(png->linebuf); @@ -311,6 +308,17 @@ static void Png_close(DilloPng *png, CacheClient_t *Client) } /* + * Finish the decoding process (and free the memory) + */ +static void Png_close(DilloPng *png, CacheClient_t *Client) +{ + _MSG("Png_close\n"); + /* Let dicache know decoding is over */ + a_Dicache_close(png->url, png->version, Client); + Png_free(png); +} + +/* * Receive and process new chunks of PNG image data */ static void Png_write(DilloPng *png, void *Buf, uint_t BufSize) @@ -402,12 +410,16 @@ static void Png_write(DilloPng *png, void *Buf, uint_t BufSize) * failure. This means that you can't just wait for all the data to be * presented before starting conversion and display. */ -void a_Png_callback(int Op, CacheClient_t *Client) +void a_Png_callback(int Op, void *data) { - if (Op) { /* EOF */ - Png_close(Client->CbData, Client); - } else { + if (Op == CA_Send) { + CacheClient_t *Client = data; Png_write(Client->CbData, Client->Buf, Client->BufSize); + } else if (Op == CA_Close) { + CacheClient_t *Client = data; + Png_close(Client->CbData, Client); + } else if (Op == CA_Abort) { + Png_free(data); } } @@ -417,6 +429,7 @@ void a_Png_callback(int Op, CacheClient_t *Client) void *a_Png_new(DilloImage *Image, DilloUrl *url, int version) { DilloPng *png = dNew0(DilloPng, 1); + MSG("Png_new: png=%p\n", png); png->Image = Image; png->url = url; |