summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-05-08 16:39:19 -0400
committerJorge Arellano Cid <jcid@dillo.org>2009-05-08 16:39:19 -0400
commitc206e5e68a1e009df93cf9175d521a4c587158d1 (patch)
tree104c2e6611501b43e93acf1b65a7c3c8f18b6bd3 /src
parent7034881b87b53b087bae78aef8380e5258f68a24 (diff)
Fix a memory leak when stopping an image-decoding process
Diffstat (limited to 'src')
-rw-r--r--src/dgif.h2
-rw-r--r--src/dicache.c17
-rw-r--r--src/dicache.h1
-rw-r--r--src/djpeg.h2
-rw-r--r--src/gif.c45
-rw-r--r--src/jpeg.c27
-rw-r--r--src/png.c33
7 files changed, 87 insertions, 40 deletions
diff --git a/src/dgif.h b/src/dgif.h
index d4980e54..ec36812d 100644
--- a/src/dgif.h
+++ b/src/dgif.h
@@ -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
diff --git a/src/gif.c b/src/gif.c
index 2301b648..85e57584 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -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);
}
diff --git a/src/jpeg.c b/src/jpeg.c
index 9d611ba8..c8a1accf 100644
--- a/src/jpeg.c
+++ b/src/jpeg.c
@@ -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);
+ }
}
/*
diff --git a/src/png.c b/src/png.c
index b6900db1..fac64b8d 100644
--- a/src/png.c
+++ b/src/png.c
@@ -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;