From 50b904edd71e4e9e5a3780cf05cd3a14c3b64773 Mon Sep 17 00:00:00 2001 From: Jason Rose Date: Wed, 14 Aug 2013 17:15:29 -0700 Subject: [PATCH 1/4] Deallocating both onload and onerror handlers. --- src/Image.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Image.cc b/src/Image.cc index 72c5df5..cbb41db 100644 --- a/src/Image.cc +++ b/src/Image.cc @@ -346,6 +346,11 @@ Image::loaded() { if (onload != NULL) { onload->Call(0, NULL); delete onload; + onload = NULL; + } + if (onerror != NULL) { + delete onerror; + onerror = NULL; } } @@ -360,6 +365,11 @@ Image::error(Local err) { Local argv[1] = { err }; onerror->Call(1, argv); delete onerror; + onerror = NULL; + } + if (onload != NULL) { + delete onload; + onload = NULL; } } From 9ce2d8ebec9e52c8bf6ade4df7f5a41ec81a9d11 Mon Sep 17 00:00:00 2001 From: Jason Rose Date: Thu, 15 Aug 2013 17:23:01 -0700 Subject: [PATCH 2/4] Freeing custom buffer created during canvas jpeg streaming. --- src/JPEGStream.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/JPEGStream.h b/src/JPEGStream.h index 0e0738c..041b950 100644 --- a/src/JPEGStream.h +++ b/src/JPEGStream.h @@ -95,6 +95,13 @@ jpeg_closure_dest(j_compress_ptr cinfo, closure_t * closure, int bufsize){ cinfo->dest->free_in_buffer = dest->bufsize; } +void +jpeg_free_custom_allocations(j_compress_ptr cinfo){ + closure_destination_mgr * dest; + dest = (closure_destination_mgr *) cinfo->dest; + free(dest->buffer); +} + void write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, bool progressive, closure_t *closure){ int w = cairo_image_surface_get_width(surface); @@ -136,6 +143,7 @@ write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, bool pr sl++; } free(dst); + jpeg_free_custom_allocations(&cinfo); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); } From 1219a151bc4cf14f8d6897d1b0eb0fba7072a0b0 Mon Sep 17 00:00:00 2001 From: King Koopa Date: Mon, 26 Aug 2013 21:26:56 +0300 Subject: [PATCH 3/4] Testing... --- src/Image.cc | 30 ++++++++++++++++-------------- src/JPEGStream.h | 7 +++++-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/Image.cc b/src/Image.cc index cbb41db..a748c6d 100644 --- a/src/Image.cc +++ b/src/Image.cc @@ -207,7 +207,7 @@ Image::loadFromBuffer(uint8_t *buf, unsigned len) { #endif #ifdef HAVE_JPEG #if CAIRO_VERSION_MINOR < 10 - if (isJPEG(buf)) return loadJPEGFromBuffer(buf, len); + if (isJPEG(buf)) return loadJPEGFromBuffer(buf, len); #else if (isJPEG(buf)) { if (DATA_IMAGE == data_mode) return loadJPEGFromBuffer(buf, len); @@ -314,6 +314,16 @@ Image::Image() { Image::~Image() { clearData(); + + if (onerror) { + delete onerror; + onerror = NULL; + } + + if (onload) { + delete onload; + onload = NULL; + } } /* @@ -348,10 +358,6 @@ Image::loaded() { delete onload; onload = NULL; } - if (onerror != NULL) { - delete onerror; - onerror = NULL; - } } /* @@ -367,15 +373,11 @@ Image::error(Local err) { delete onerror; onerror = NULL; } - if (onload != NULL) { - delete onload; - onload = NULL; - } } /* * Load cairo surface from the image src. - * + * * TODO: support more formats * TODO: use node IO or at least thread pool */ @@ -467,7 +469,7 @@ Image::loadGIF(FILE *stream) { if (fstat(fd, &s) < 0) { fclose(stream); return CAIRO_STATUS_READ_ERROR; - } + } uint8_t *buf = (uint8_t *) malloc(s.st_size); @@ -500,10 +502,10 @@ Image::loadGIFFromBuffer(uint8_t *buf, unsigned len) { #if GIFLIB_MAJOR >= 5 int errorcode; if ((gif = DGifOpen((void*) &gifd, read_gif_from_memory, &errorcode)) == NULL) - return CAIRO_STATUS_READ_ERROR; + return CAIRO_STATUS_READ_ERROR; #else if ((gif = DGifOpen((void*) &gifd, read_gif_from_memory)) == NULL) - return CAIRO_STATUS_READ_ERROR; + return CAIRO_STATUS_READ_ERROR; #endif if (GIF_OK != DGifSlurp(gif)) { @@ -710,7 +712,7 @@ Image::decodeJPEGIntoSurface(jpeg_decompress_struct *args) { *pixel = 255 << 24 | src[bx + 0] << 16 | src[bx + 1] << 8 - | src[bx + 2]; + | src[bx + 2]; } } } diff --git a/src/JPEGStream.h b/src/JPEGStream.h index 041b950..12b8058 100644 --- a/src/JPEGStream.h +++ b/src/JPEGStream.h @@ -80,7 +80,7 @@ jpeg_closure_dest(j_compress_ptr cinfo, closure_t * closure, int bufsize){ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(closure_destination_mgr)); } - + dest = (closure_destination_mgr *) cinfo->dest; cinfo->dest->init_destination = &init_closure_destination; @@ -99,7 +99,10 @@ void jpeg_free_custom_allocations(j_compress_ptr cinfo){ closure_destination_mgr * dest; dest = (closure_destination_mgr *) cinfo->dest; - free(dest->buffer); + if (dest->buffer) { + free(dest->buffer); + dest->buffer = NULL; + } } void From 0bc1aaf38b78396c1a6cbd45d5167716ea0cea39 Mon Sep 17 00:00:00 2001 From: King Koopa Date: Sun, 1 Sep 2013 14:40:53 +0300 Subject: [PATCH 4/4] Added scopes. --- src/Image.cc | 4 ++-- src/JPEGStream.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Image.cc b/src/Image.cc index a748c6d..d5e8ac9 100644 --- a/src/Image.cc +++ b/src/Image.cc @@ -572,9 +572,9 @@ Image::loadGIFFromBuffer(uint8_t *buf, unsigned len) { dst_data++; src_data++; } - } + } } - } else { + } else { // Image is interlaced so that it streams nice over 14.4k and 28.8k modems :) // We first load in 1/8 of the image, followed by another 1/8, followed by // 1/4 and finally the remaining 1/2. diff --git a/src/JPEGStream.h b/src/JPEGStream.h index 12b8058..34e0c27 100644 --- a/src/JPEGStream.h +++ b/src/JPEGStream.h @@ -30,6 +30,7 @@ init_closure_destination(j_compress_ptr cinfo){ boolean empty_closure_output_buffer(j_compress_ptr cinfo){ + NanScope(); closure_destination_mgr *dest = (closure_destination_mgr *) cinfo->dest; Local buf = NanNewBufferHandle((char *)dest->buffer, dest->bufsize); Local argv[3] = { @@ -45,6 +46,7 @@ empty_closure_output_buffer(j_compress_ptr cinfo){ void term_closure_destination(j_compress_ptr cinfo){ + NanScope(); closure_destination_mgr *dest = (closure_destination_mgr *) cinfo->dest; /* emit remaining data */ size_t remaining = dest->bufsize - cinfo->dest->free_in_buffer; @@ -146,8 +148,8 @@ write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, bool pr sl++; } free(dst); - jpeg_free_custom_allocations(&cinfo); jpeg_finish_compress(&cinfo); + jpeg_free_custom_allocations(&cinfo); jpeg_destroy_compress(&cinfo); }