Mercurial > dillo_port1.3
changeset 1085:d6767b7bdf93
Fix a memory leak when stopping an image-decoding process
author | Jorge Arellano Cid <jcid@dillo.org> |
---|---|
date | Fri, 08 May 2009 16:39:19 -0400 |
parents | 4d3828de8290 |
children | 23edfb792c5e |
files | src/dgif.h src/dicache.c src/dicache.h src/djpeg.h src/gif.c src/jpeg.c src/png.c |
diffstat | 7 files changed, 87 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/src/dgif.h Thu May 07 16:35:03 2009 -0400 +++ b/src/dgif.h Fri May 08 16:39:19 2009 -0400 @@ -10,7 +10,7 @@ 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
--- a/src/dicache.c Thu May 07 16:35:03 2009 -0400 +++ b/src/dicache.c Fri May 08 16:39:19 2009 -0400 @@ -175,7 +175,7 @@ { 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 @@ } 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 @@ /* * 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 @@ /* 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;
--- a/src/dicache.h Thu May 07 16:35:03 2009 -0400 +++ b/src/dicache.h Fri May 08 16:39:19 2009 -0400 @@ -60,7 +60,6 @@ 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);
--- a/src/djpeg.h Thu May 07 16:35:03 2009 -0400 +++ b/src/djpeg.h Fri May 08 16:39:19 2009 -0400 @@ -10,7 +10,7 @@ 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
--- a/src/gif.c Thu May 07 16:35:03 2009 -0400 +++ b/src/gif.c Fri May 08 16:39:19 2009 -0400 @@ -153,6 +153,7 @@ 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 @@ } /* + * 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) + 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 - Gif_write(Client->CbData, Client->Buf, Client->BufSize); + } else if (Op == CA_Abort) { + Gif_free(data); + } } /* @@ -217,20 +241,9 @@ */ 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); }
--- a/src/jpeg.c Thu May 07 16:35:03 2009 -0400 +++ b/src/jpeg.c Fri May 08 16:39:19 2009 -0400 @@ -94,14 +94,23 @@ } /* + * 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 @@ { 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 @@ return jpeg; } -void a_Jpeg_callback(int Op, CacheClient_t *Client) +void a_Jpeg_callback(int Op, void *data) { - if (Op) + 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 - Jpeg_write(Client->CbData, Client->Buf, Client->BufSize); + } else if (Op == CA_Abort) { + Jpeg_free(data); + } } /*
--- a/src/png.c Thu May 07 16:35:03 2009 -0400 +++ b/src/png.c Fri May 08 16:39:19 2009 -0400 @@ -291,15 +291,12 @@ } /* - * 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 @@ } /* + * 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 @@ * 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 */ + 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 { - Png_write(Client->CbData, Client->Buf, Client->BufSize); + } else if (Op == CA_Abort) { + Png_free(data); } } @@ -417,6 +429,7 @@ 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;