Browse Source

Fixed Image::error(), reports FatalException() unless .onerror is present

v1.x
Tj Holowaychuk 14 years ago
parent
commit
00df2707e9
  1. 51
      src/Image.cc
  2. 8
      src/Image.h

51
src/Image.cc

@ -189,9 +189,11 @@ Image::load() {
void void
Image::loadSync() { Image::loadSync() {
cairo_status_t status = loadSurface(); TryCatch try_catch;
if (status) { loadSurface();
error(Canvas::Error(status));
if (try_catch.HasCaught()) {
error(try_catch);
} else { } else {
loaded(); loaded();
} }
@ -211,7 +213,7 @@ Image::loaded() {
onload->Call(Context::GetCurrent()->Global(), 0, NULL); onload->Call(Context::GetCurrent()->Global(), 0, NULL);
onload.Dispose(); onload.Dispose();
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
error(try_catch.Exception()); error(try_catch);
} }
} }
} }
@ -221,10 +223,12 @@ Image::loaded() {
*/ */
void void
Image::error(Local<Value> err) { Image::error(TryCatch &try_catch) {
HandleScope scope; HandleScope scope;
if (!onerror.IsEmpty()) { if (onerror.IsEmpty()) {
Local<Value> argv[1] = { err }; FatalException(try_catch);
} else {
Local<Value> argv[1] = { try_catch.Exception() };
onerror->Call(Context::GetCurrent()->Global(), 1, argv); onerror->Call(Context::GetCurrent()->Global(), 1, argv);
onerror.Dispose(); onerror.Dispose();
} }
@ -238,7 +242,7 @@ Image::error(Local<Value> err) {
* TODO: use node IO or at least thread pool * TODO: use node IO or at least thread pool
*/ */
cairo_status_t Handle<Value>
Image::loadSurface() { Image::loadSurface() {
switch (extension(filename)) { switch (extension(filename)) {
case Image::PNG: return loadPNG(); case Image::PNG: return loadPNG();
@ -246,19 +250,24 @@ Image::loadSurface() {
case Image::JPEG: return loadJPEG(); case Image::JPEG: return loadJPEG();
#endif #endif
} }
return CAIRO_STATUS_READ_ERROR; return ThrowException(Exception::Error(String::New("failed to load image")));
} }
/* /*
* Load PNG. * Load PNG.
*/ */
cairo_status_t Handle<Value>
Image::loadPNG() { Image::loadPNG() {
_surface = cairo_image_surface_create_from_png(filename); _surface = cairo_image_surface_create_from_png(filename);
width = cairo_image_surface_get_width(_surface); width = cairo_image_surface_get_width(_surface);
height = cairo_image_surface_get_height(_surface); height = cairo_image_surface_get_height(_surface);
return cairo_surface_status(_surface); cairo_status_t status = cairo_surface_status(_surface);
if (status) {
return ThrowException(Canvas::Error(status));
} else {
return Undefined();
}
} }
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
@ -267,17 +276,13 @@ Image::loadPNG() {
* Load JPEG, convert RGB to ARGB. * Load JPEG, convert RGB to ARGB.
*/ */
cairo_status_t Handle<Value>
Image::loadJPEG() { Image::loadJPEG() {
FILE *stream = fopen(filename, "r"); FILE *stream = fopen(filename, "r");
// Generalized errors // Generalized errors
if (!stream) { if (!stream) {
switch (errno) { return ThrowException(ErrnoException(errno, "fopen"));
case ENOMEM: return CAIRO_STATUS_NO_MEMORY;
case ENOENT: return CAIRO_STATUS_FILE_NOT_FOUND;
default: return CAIRO_STATUS_READ_ERROR;
}
} }
// JPEG setup // JPEG setup
@ -294,10 +299,10 @@ Image::loadJPEG() {
// Data alloc // Data alloc
int stride = width * 4; int stride = width * 4;
uint8_t *data = (uint8_t *) malloc(width * height * 4); uint8_t *data = (uint8_t *) malloc(width * height * 4);
if (!data) return CAIRO_STATUS_NO_MEMORY; if (!data) return ThrowException(Canvas::Error(CAIRO_STATUS_NO_MEMORY));
uint8_t *src = (uint8_t *) malloc(width * 3); uint8_t *src = (uint8_t *) malloc(width * 3);
if (!src) return CAIRO_STATUS_NO_MEMORY; if (!src) return ThrowException(Canvas::Error(CAIRO_STATUS_NO_MEMORY));
// Copy RGB -> ARGB // Copy RGB -> ARGB
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
@ -327,8 +332,12 @@ Image::loadJPEG() {
jpeg_finish_decompress(&info); jpeg_finish_decompress(&info);
jpeg_destroy_decompress(&info); jpeg_destroy_decompress(&info);
cairo_status_t status = cairo_surface_status(_surface); cairo_status_t status = cairo_surface_status(_surface);
if (status) free(data); if (status) {
return status; free(data);
return ThrowException(Canvas::Error(status));
} else {
return Undefined();
}
} }
#endif #endif

8
src/Image.h

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

Loading…
Cancel
Save