Permalink
Browse files

dynamic jpeg stack is now async

  • Loading branch information...
pkrumins committed Aug 13, 2010
1 parent 47b2af1 commit 2f94fe9ec7c7c41ab15fdee24eb24d5cb255ced2
Showing with 112 additions and 9 deletions.
  1. +106 −6 src/dynamic_jpeg_stack.cpp
  2. +6 −3 src/dynamic_jpeg_stack.h
View
@@ -18,7 +18,8 @@ DynamicJpegStack::Initialize(v8::Handle<v8::Object> target)
Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(t, "encode", JpegEncode);
NODE_SET_PROTOTYPE_METHOD(t, "encode", JpegEncodeAsync);
NODE_SET_PROTOTYPE_METHOD(t, "encodeSync", JpegEncodeSync);
NODE_SET_PROTOTYPE_METHOD(t, "push", Push);
NODE_SET_PROTOTYPE_METHOD(t, "reset", Reset);
NODE_SET_PROTOTYPE_METHOD(t, "setBackground", SetBackground);
@@ -38,7 +39,7 @@ DynamicJpegStack::~DynamicJpegStack()
}
void
DynamicJpegStack::UpdateOptimalDimension(int x, int y, int w, int h)
DynamicJpegStack::update_optimal_dimension(int x, int y, int w, int h)
{
if (dyn_rect.x == -1 || x < dyn_rect.x)
dyn_rect.x = x;
@@ -60,7 +61,7 @@ DynamicJpegStack::UpdateOptimalDimension(int x, int y, int w, int h)
}
Handle<Value>
DynamicJpegStack::JpegEncode()
DynamicJpegStack::JpegEncodeSync()
{
HandleScope scope;
@@ -80,7 +81,7 @@ DynamicJpegStack::JpegEncode()
void
DynamicJpegStack::Push(unsigned char *data_buf, int x, int y, int w, int h)
{
UpdateOptimalDimension(x, y, w, h);
update_optimal_dimension(x, y, w, h);
int start = y*bg_width*3 + x*3;
@@ -238,11 +239,11 @@ DynamicJpegStack::New(const Arguments &args)
}
Handle<Value>
DynamicJpegStack::JpegEncode(const Arguments &args)
DynamicJpegStack::JpegEncodeSync(const Arguments &args)
{
HandleScope scope;
DynamicJpegStack *jpeg = ObjectWrap::Unwrap<DynamicJpegStack>(args.This());
return jpeg->JpegEncode();
return scope.Close(jpeg->JpegEncodeSync());
}
Handle<Value>
@@ -374,3 +375,102 @@ DynamicJpegStack::SetQuality(const Arguments &args)
return Undefined();
}
int
DynamicJpegStack::EIO_JpegEncode(eio_req *req)
{
encode_request *enc_req = (encode_request *)req->data;
DynamicJpegStack *jpeg = (DynamicJpegStack *)enc_req->jpeg_obj;
try {
Rect &dyn_rect = jpeg->dyn_rect;
JpegEncoder encoder(jpeg->data, jpeg->bg_width, jpeg->bg_height, jpeg->quality, BUF_RGB);
encoder.setRect(Rect(dyn_rect.x, dyn_rect.y, dyn_rect.w, dyn_rect.h));
encoder.encode();
enc_req->jpeg_len = encoder.get_jpeg_len();
enc_req->jpeg = (char *)malloc(sizeof(*enc_req->jpeg)*enc_req->jpeg_len);
if (!enc_req->jpeg) {
enc_req->error = strdup("malloc in DynamicJpegStack::EIO_JpegEncode failed.");
return 0;
}
else {
memcpy(enc_req->jpeg, encoder.get_jpeg(), enc_req->jpeg_len);
}
}
catch (const char *err) {
enc_req->error = strdup(err);
}
return 0;
}
int
DynamicJpegStack::EIO_JpegEncodeAfter(eio_req *req)
{
HandleScope scope;
ev_unref(EV_DEFAULT_UC);
encode_request *enc_req = (encode_request *)req->data;
DynamicJpegStack *jpeg = (DynamicJpegStack *)enc_req->jpeg_obj;
Handle<Value> argv[3];
if (enc_req->error) {
argv[0] = Undefined();
argv[1] = Undefined();
argv[2] = ErrorException(enc_req->error);
}
else {
argv[0] = Local<Value>::New(Encode(enc_req->jpeg, enc_req->jpeg_len, BINARY));
argv[1] = jpeg->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->jpeg);
free(enc_req->error);
jpeg->Unref();
free(enc_req);
return 0;
}
Handle<Value>
DynamicJpegStack::JpegEncodeAsync(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]);
DynamicJpegStack *jpeg = ObjectWrap::Unwrap<DynamicJpegStack>(args.This());
encode_request *enc_req = (encode_request *)malloc(sizeof(*enc_req));
if (!enc_req)
return VException("malloc in DynamicJpegStack::JpegEncodeAsync failed.");
enc_req->callback = Persistent<Function>::New(callback);
enc_req->jpeg_obj = jpeg;
enc_req->jpeg = NULL;
enc_req->jpeg_len = 0;
enc_req->error = NULL;
eio_custom(EIO_JpegEncode, EIO_PRI_DEFAULT, EIO_JpegEncodeAfter, enc_req);
ev_ref(EV_DEFAULT_UC);
jpeg->Ref();
return Undefined();
}
View
@@ -19,13 +19,15 @@ class DynamicJpegStack : public node::ObjectWrap {
int bg_width, bg_height; // background width and height after setBackground
Rect dyn_rect; // rect of dynamic push area (updated after each push)
void UpdateOptimalDimension(int x, int y, int w, int h);
void update_optimal_dimension(int x, int y, int w, int h);
static int EIO_JpegEncode(eio_req *req);
static int EIO_JpegEncodeAfter(eio_req *req);
public:
DynamicJpegStack(buffer_type bbuf_type);
~DynamicJpegStack();
v8::Handle<v8::Value> JpegEncode();
v8::Handle<v8::Value> JpegEncodeSync();
void Push(unsigned char *data_buf, int x, int y, int w, int h);
void SetBackground(unsigned char *data_buf, int w, int h);
void SetQuality(int q);
@@ -34,7 +36,8 @@ class DynamicJpegStack : public node::ObjectWrap {
static void Initialize(v8::Handle<v8::Object> target);
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static v8::Handle<v8::Value> JpegEncode(const v8::Arguments &args);
static v8::Handle<v8::Value> JpegEncodeSync(const v8::Arguments &args);
static v8::Handle<v8::Value> JpegEncodeAsync(const v8::Arguments &args);
static v8::Handle<v8::Value> Push(const v8::Arguments &args);
static v8::Handle<v8::Value> SetBackground(const v8::Arguments &args);
static v8::Handle<v8::Value> SetQuality(const v8::Arguments &args);

0 comments on commit 2f94fe9

Please sign in to comment.