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

10
src/Image.h

@ -31,14 +31,14 @@ 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); }
void loadSurface(); cairo_status_t loadSurface();
void loadPNG(); cairo_status_t loadPNG();
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
void loadJPEG(); cairo_status_t loadJPEG();
#endif #endif
void error(TryCatch &try_catch); void error(Local<Value> error);
void loaded(); void loaded();
void load(); cairo_status_t load();
Image(); Image();
enum { enum {

Loading…
Cancel
Save