Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

dynamic jpeg stack is now async

  • Loading branch information...
commit 2f94fe9ec7c7c41ab15fdee24eb24d5cb255ced2 1 parent 47b2af1
@pkrumins authored
Showing with 112 additions and 9 deletions.
  1. +106 −6 src/dynamic_jpeg_stack.cpp
  2. +6 −3 src/dynamic_jpeg_stack.h
View
112 src/dynamic_jpeg_stack.cpp
@@ -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
9 src/dynamic_jpeg_stack.h
@@ -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);
Please sign in to comment.
Something went wrong with that request. Please try again.