Browse Source

Add clearData method to handle reassignment of src, and clean up mime data memory handling.

v1.x
c-spencer 13 years ago
parent
commit
4c5962b90e
  1. 92
      src/Image.cc
  2. 5
      src/Image.h

92
src/Image.cc

@ -127,6 +127,30 @@ Image::GetSource(Local<String>, const AccessorInfo &info) {
return scope.Close(String::New(img->filename ? img->filename : ""));
}
/*
* Clean up assets and variables.
*/
void
Image::clearData() {
if (_surface) {
cairo_surface_destroy(_surface);
V8::AdjustAmountOfExternalAllocatedMemory(-_data_len);
_data_len = 0;
_surface = NULL;
}
free(_data);
_data = NULL;
width = height = 0;
free(filename);
filename = NULL;
state = DEFAULT;
}
/*
* Set src path.
*/
@ -137,6 +161,8 @@ Image::SetSource(Local<String>, Local<Value> val, const AccessorInfo &info) {
Image *img = ObjectWrap::Unwrap<Image>(info.This());
cairo_status_t status = CAIRO_STATUS_READ_ERROR;
img->clearData();
// url string
if (val->IsString()) {
String::AsciiValue src(val);
@ -270,10 +296,6 @@ Image::Image() {
filename = NULL;
_data = NULL;
_data_len = 0;
#if CAIRO_VERSION_MINOR >= 10
_mime_data = NULL;
_mime_data_len = 0;
#endif
_surface = NULL;
width = height = 0;
state = DEFAULT;
@ -284,21 +306,7 @@ Image::Image() {
*/
Image::~Image() {
if (_surface) {
V8::AdjustAmountOfExternalAllocatedMemory(-_data_len);
cairo_surface_destroy(_surface);
}
free(_data);
#if CAIRO_VERSION_MINOR >= 10
if (_mime_data) {
V8::AdjustAmountOfExternalAllocatedMemory(-_mime_data_len);
free(_mime_data);
}
#endif
free(filename);
clearData();
}
/*
@ -326,7 +334,6 @@ Image::loaded() {
width = cairo_image_surface_get_width(_surface);
height = cairo_image_surface_get_height(_surface);
_data_len = height * cairo_image_surface_get_stride(_surface);
// TODO: adjust accordingly when re-assigned src
V8::AdjustAmountOfExternalAllocatedMemory(_data_len);
if (!onload.IsEmpty()) {
@ -757,17 +764,42 @@ Image::decodeJPEGBufferIntoMimeSurface(uint8_t *buf, unsigned len) {
return assignDataAsMime(buf, len, CAIRO_MIME_TYPE_JPEG);
}
/*
* Helper function for disposing of a mime data closure.
*/
void
clearMimeData(void *closure) {
V8::AdjustAmountOfExternalAllocatedMemory(-((read_closure_t *)closure)->len);
free(((read_closure_t *) closure)->buf);
free(closure);
}
/*
* Assign a given buffer as mime data against the surface.
* The provided buffer will be copied, and the copy will
* be automatically freed when the surface is destroyed.
*/
cairo_status_t
Image::assignDataAsMime(uint8_t *data, int len, const char *mime_type) {
_mime_data = (uint8_t *) malloc(len);
if (!_mime_data) return CAIRO_STATUS_NO_MEMORY;
uint8_t *mime_data = (uint8_t *) malloc(len);
if (!mime_data) return CAIRO_STATUS_NO_MEMORY;
V8::AdjustAmountOfExternalAllocatedMemory(len);
read_closure_t *mime_closure = (read_closure_t *) malloc(sizeof(read_closure_t));
if (!mime_closure) {
free(mime_data);
return CAIRO_STATUS_NO_MEMORY;
}
memcpy(_mime_data, data, len);
_mime_data_len = len;
memcpy(mime_data, data, len);
return cairo_surface_set_mime_data(_surface, mime_type, _mime_data, _mime_data_len, free, _mime_data);
mime_closure->buf = mime_data;
mime_closure->len = len;
V8::AdjustAmountOfExternalAllocatedMemory(len);
return cairo_surface_set_mime_data(_surface, mime_type, mime_data, len, clearMimeData, mime_closure);
}
#endif
@ -803,8 +835,6 @@ cairo_status_t
Image::loadJPEG(FILE *stream) {
cairo_status_t status;
printf("loadJPEG\n");
if (data_mode == DATA_IMAGE) { // Can lazily read in the JPEG.
// JPEG setup
struct jpeg_decompress_struct info;
@ -836,12 +866,6 @@ Image::loadJPEG(FILE *stream) {
fread(buf, len, 1, stream);
fclose(stream);
status = loadJPEGFromBuffer(buf, len);
if (status) {
free(buf);
return status;
}
switch (data_mode) {
case DATA_IMAGE: // Can't be this, but compiler warning.
case DATA_IMAGE_AND_MIME:

5
src/Image.h

@ -45,6 +45,7 @@ class Image: public node::ObjectWrap {
cairo_status_t loadFromBuffer(uint8_t *buf, unsigned len);
cairo_status_t loadPNGFromBuffer(uint8_t *buf);
cairo_status_t loadPNG();
void clearData();
#ifdef HAVE_GIF
cairo_status_t loadGIFFromBuffer(uint8_t *buf, unsigned len);
cairo_status_t loadGIF(FILE *stream);
@ -88,10 +89,6 @@ class Image: public node::ObjectWrap {
cairo_surface_t *_surface;
uint8_t *_data;
int _data_len;
#if CAIRO_VERSION_MINOR >= 10
uint8_t *_mime_data;
int _mime_data_len;
#endif
~Image();
};

Loading…
Cancel
Save