Browse Source

Fixed (kinda) img.src= error handling

v1.x
Tj Holowaychuk 14 years ago
parent
commit
89af08d30d
  1. 65
      src/Image.cc
  2. 10
      src/Image.h

65
src/Image.cc

@ -109,11 +109,10 @@ Image::SetSrc(Local<String>, Local<Value> val, const AccessorInfo &info) {
Image *img = ObjectWrap::Unwrap<Image>(info.This());
if (img->filename) free(img->filename);
img->filename = strdup(*src);
TryCatch try_catch;
img->load();
cairo_status_t status = img->load();
// TODO: this does not work... something funky going on
if (try_catch.HasCaught()) {
img->error(try_catch);
if (status) {
img->error(Canvas::Error(status));
} else {
V8::AdjustAmountOfExternalAllocatedMemory(4 * img->width * img->height);
img->loaded();
@ -192,12 +191,13 @@ Image::~Image() {
* Initiate image loading.
*/
void
cairo_status_t
Image::load() {
if (LOADING != state) {
state = LOADING;
loadSurface();
return loadSurface();
}
return CAIRO_STATUS_READ_ERROR;
}
/*
@ -214,7 +214,7 @@ Image::loaded() {
onload->Call(Context::GetCurrent()->Global(), 0, NULL);
onload.Dispose();
if (try_catch.HasCaught()) {
error(try_catch);
error(try_catch.Exception());
}
}
}
@ -224,17 +224,15 @@ Image::loaded() {
*/
void
Image::error(TryCatch &try_catch) {
Image::error(Local<Value> err) {
HandleScope scope;
if (onerror.IsEmpty()) {
FatalException(try_catch);
} else {
Local<Value> argv[1] = { try_catch.Exception() };
TryCatch try_catch2;
if (!onerror.IsEmpty()) {
Local<Value> argv[1] = { err };
TryCatch try_catch;
onerror->Call(Context::GetCurrent()->Global(), 1, argv);
onerror.Dispose();
if (try_catch2.HasCaught()) {
FatalException(try_catch2);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
}
}
@ -247,19 +245,17 @@ Image::error(TryCatch &try_catch) {
* TODO: use node IO or at least thread pool
*/
void
cairo_status_t
Image::loadSurface() {
switch (extension(filename)) {
case Image::PNG:
loadPNG();
break;
return loadPNG();
#ifdef HAVE_JPEG
case Image::JPEG:
loadJPEG();
break;
return loadJPEG();
#endif
default:
ThrowException(Exception::Error(String::New("failed to detect image format")));
return CAIRO_STATUS_READ_ERROR;
}
}
@ -267,16 +263,15 @@ Image::loadSurface() {
* Load PNG.
*/
void
cairo_status_t
Image::loadPNG() {
_surface = cairo_image_surface_create_from_png(filename);
cairo_status_t status = cairo_surface_status(_surface);
if (status) {
ThrowException(Canvas::Error(status));
} else {
if (!status) {
width = cairo_image_surface_get_width(_surface);
height = cairo_image_surface_get_height(_surface);
}
return status;
}
#ifdef HAVE_JPEG
@ -285,14 +280,10 @@ Image::loadPNG() {
* Load JPEG, convert RGB to ARGB.
*/
void
cairo_status_t
Image::loadJPEG() {
FILE *stream = fopen(filename, "r");
// Generalized errors
if (!stream) {
ThrowException(ErrnoException(errno, "fopen"));
}
if (!stream) return CAIRO_STATUS_READ_ERROR;
// JPEG setup
struct jpeg_decompress_struct info;
@ -308,16 +299,12 @@ Image::loadJPEG() {
// Data alloc
int stride = width * 4;
uint8_t *data = (uint8_t *) malloc(width * height * 4);
if (!data) {
ThrowException(Canvas::Error(CAIRO_STATUS_NO_MEMORY));
return;
}
if (!data) return CAIRO_STATUS_NO_MEMORY;
uint8_t *src = (uint8_t *) malloc(width * 3);
if (!src) {
free(data);
ThrowException(Canvas::Error(CAIRO_STATUS_NO_MEMORY));
return;
return CAIRO_STATUS_NO_MEMORY;
}
// Copy RGB -> ARGB
@ -351,8 +338,10 @@ Image::loadJPEG() {
if (status) {
free(data);
ThrowException(Canvas::Error(status));
return status;
}
return CAIRO_STATUS_SUCCESS;
}
#endif

10
src/Image.h

@ -31,14 +31,14 @@ class Image: public node::ObjectWrap {
inline cairo_surface_t *surface(){ return _surface; }
inline uint8_t *data(){ return cairo_image_surface_get_data(_surface); }
inline int stride(){ return cairo_image_surface_get_stride(_surface); }
void loadSurface();
void loadPNG();
cairo_status_t loadSurface();
cairo_status_t loadPNG();
#ifdef HAVE_JPEG
void loadJPEG();
cairo_status_t loadJPEG();
#endif
void error(TryCatch &try_catch);
void error(Local<Value> error);
void loaded();
void load();
cairo_status_t load();
Image();
enum {

Loading…
Cancel
Save