Handle<Value> DynamicPngStack::PngEncodeAsync(const Arguments &args) { HandleScope scope; if (args.Length() != 1) return VException("One argument required - callback function."); if (!args[0]->IsFunction()) return VException("First argument must be a function."); Local<Function> callback = Local<Function>::Cast(args[0]); DynamicPngStack *png = ObjectWrap::Unwrap<DynamicPngStack>(args.This()); encode_request *enc_req = (encode_request *)malloc(sizeof(*enc_req)); if (!enc_req) return VException("malloc in DynamicPngStack::PngEncodeAsync failed."); enc_req->callback = Persistent<Function>::New(callback); enc_req->png_obj = png; enc_req->png = NULL; enc_req->png_len = 0; enc_req->error = NULL; eio_custom(EIO_PngEncode, EIO_PRI_DEFAULT, EIO_PngEncodeAfter, enc_req); ev_ref(EV_DEFAULT_UC); png->Ref(); return Undefined(); }
Handle<Value> DynamicPngStack::PngEncodeAsync(const Arguments &args) { HandleScope scope; if (args.Length() != 1) return VException("One argument required - callback function."); if (!args[0]->IsFunction()) return VException("First argument must be a function."); Local<Function> callback = Local<Function>::Cast(args[0]); DynamicPngStack *png = ObjectWrap::Unwrap<DynamicPngStack>(args.This()); encode_request *enc_req = (encode_request *)malloc(sizeof(*enc_req)); if (!enc_req) return VException("malloc in DynamicPngStack::PngEncodeAsync failed."); enc_req->callback = Persistent<Function>::New(callback); enc_req->png_obj = png; enc_req->png = NULL; enc_req->png_len = 0; enc_req->error = NULL; uv_work_t* req = new uv_work_t; req->data = enc_req; uv_queue_work(uv_default_loop(), req, UV_PngEncode, (uv_after_work_cb)UV_PngEncodeAfter); png->Ref(); return Undefined(); }
int DynamicPngStack::EIO_PngEncode(eio_req *req) { encode_request *enc_req = (encode_request *)req->data; DynamicPngStack *png = (DynamicPngStack *)enc_req->png_obj; std::pair<Point, Point> optimal = png->optimal_dimension(); Point top = optimal.first, bot = optimal.second; // printf("width, height: %d, %d\n", bot.x - top.x, bot.y - top.y); png->offset = top; png->width = bot.x - top.x; png->height = bot.y - top.y; unsigned char *data = (unsigned char*)malloc(sizeof(*data) * png->width * png->height * 4); if (!data) { enc_req->error = strdup("malloc failed in DynamicPngStack::EIO_PngEncode."); return 0; } memset(data, 0xFF, png->width*png->height*4); png->construct_png_data(data, top); buffer_type pbt = (png->buf_type == BUF_BGR || png->buf_type == BUF_BGRA) ? BUF_BGRA : BUF_RGBA; try { PngEncoder encoder(data, png->width, png->height, pbt); encoder.encode(); free(data); enc_req->png_len = encoder.get_png_len(); enc_req->png = (char *)malloc(sizeof(*enc_req->png)*enc_req->png_len); if (!enc_req->png) { enc_req->error = strdup("malloc in DynamicPngStack::EIO_PngEncode failed."); return 0; } else { memcpy(enc_req->png, encoder.get_png(), enc_req->png_len); } } catch (const char *err) { enc_req->error = strdup(err); } return 0; }
int DynamicPngStack::EIO_PngEncodeAfter(eio_req *req) { HandleScope scope; ev_unref(EV_DEFAULT_UC); encode_request *enc_req = (encode_request *)req->data; DynamicPngStack *png = (DynamicPngStack *)enc_req->png_obj; Handle<Value> argv[3]; if (enc_req->error) { argv[0] = Undefined(); argv[1] = Undefined(); argv[2] = ErrorException(enc_req->error); } else { Buffer *buf = Buffer::New(enc_req->png_len); memcpy(BufferData(buf), enc_req->png, enc_req->png_len); argv[0] = buf->handle_; argv[1] = png->Dimensions(); argv[2] = Undefined(); } TryCatch try_catch; // don't quite see the necessity of this enc_req->callback->Call(Context::GetCurrent()->Global(), 3, argv); if (try_catch.HasCaught()) FatalException(try_catch); enc_req->callback.Dispose(); free(enc_req->png); free(enc_req->error); png->Unref(); free(enc_req); return 0; }