diff --git a/binding.gyp b/binding.gyp index 6d810ac..aa089a6 100755 --- a/binding.gyp +++ b/binding.gyp @@ -21,7 +21,8 @@ # For windows ,'include_dirs': [ - '", "dependencies": { - "buffers": "0.1.1" + "buffers": "0.1.1", + "nan": "^1.3.0" }, "version": "0.7.0", "devDependencies": { diff --git a/src/BackgroundSubtractor.cc b/src/BackgroundSubtractor.cc index a982416..3841cab 100644 --- a/src/BackgroundSubtractor.cc +++ b/src/BackgroundSubtractor.cc @@ -1,6 +1,7 @@ #include "BackgroundSubtractor.h" #include "Matrix.h" #include +#include #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4 @@ -8,22 +9,23 @@ Persistent BackgroundSubtractorWrap::constructor; void BackgroundSubtractorWrap::Init(Handle target) { - HandleScope scope; + NanScope(); // Constructor - constructor = Persistent::New(FunctionTemplate::New(BackgroundSubtractorWrap::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("BackgroundSubtractor")); + Local ctor = NanNew(BackgroundSubtractorWrap::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("BackgroundSubtractor")); - NODE_SET_METHOD(constructor, "createMOG", CreateMOG); - NODE_SET_PROTOTYPE_METHOD(constructor, "applyMOG", ApplyMOG); + NODE_SET_METHOD(ctor, "createMOG", CreateMOG); + NODE_SET_PROTOTYPE_METHOD(ctor, "applyMOG", ApplyMOG); - target->Set(String::NewSymbol("BackgroundSubtractor"), constructor->GetFunction()); + target->Set(NanNew("BackgroundSubtractor"), ctor->GetFunction()); + }; -Handle -BackgroundSubtractorWrap::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(BackgroundSubtractorWrap::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0) JSTHROW_TYPE("Cannot Instantiate without new") @@ -34,12 +36,11 @@ BackgroundSubtractorWrap::New(const Arguments &args) { pt->Wrap(args.This()); - return args.This(); + NanReturnValue(args.This()); } -Handle -BackgroundSubtractorWrap::CreateMOG(const Arguments &args) { - HandleScope scope; +NAN_METHOD(BackgroundSubtractorWrap::CreateMOG) { + NanScope(); int history = 200; int nmixtures = 5; @@ -53,18 +54,17 @@ BackgroundSubtractorWrap::CreateMOG(const Arguments &args) { DOUBLE_FROM_ARGS(noiseSigma, 3) } - Local n = BackgroundSubtractorWrap::constructor->GetFunction()->NewInstance(); + Local n = NanNew(BackgroundSubtractorWrap::constructor)->GetFunction()->NewInstance(); cv::Ptr bg; BackgroundSubtractorWrap *pt = new BackgroundSubtractorWrap(bg); pt->Wrap(n); - return n; + NanReturnValue( n ); }; //Fetch foreground mask -Handle -BackgroundSubtractorWrap::ApplyMOG(const Arguments &args) { +NAN_METHOD(BackgroundSubtractorWrap::ApplyMOG) { SETUP_FUNCTION(BackgroundSubtractorWrap) @@ -73,15 +73,15 @@ BackgroundSubtractorWrap::ApplyMOG(const Arguments &args) { Local argv[2]; if(args.Length() == 0){ - argv[0] = String::New("Input image missing"); - argv[1] = Local::New(Null()); - cb->Call(Context::GetCurrent()->Global(), 2, argv); - return scope.Close(Undefined()); + argv[0] = NanNew("Input image missing"); + argv[1] = NanNull(); + cb->Call(NanGetCurrentContext()->Global(), 2, argv); + NanReturnUndefined(); } try{ - Local fgMask = Matrix::constructor->GetFunction()->NewInstance(); + Local fgMask = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(fgMask); @@ -100,7 +100,7 @@ BackgroundSubtractorWrap::ApplyMOG(const Arguments &args) { } if (mat.empty()){ - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Error loading file"))); + return NanThrowTypeError("Error loading file"); } cv::Mat _fgMask; @@ -110,22 +110,22 @@ BackgroundSubtractorWrap::ApplyMOG(const Arguments &args) { mat.release(); - argv[0] = Local::New(Null()); + argv[0] = NanNull(); argv[1] = fgMask; TryCatch try_catch; - cb->Call(Context::GetCurrent()->Global(), 2, argv); + cb->Call(NanGetCurrentContext()->Global(), 2, argv); if (try_catch.HasCaught()) { FatalException(try_catch); } - return scope.Close(v8::Undefined()); + NanReturnUndefined(); } catch( cv::Exception& e ){ const char* err_msg = e.what(); - return v8::ThrowException(v8::Exception::Error(v8::String::New(err_msg))); + NanThrowError(err_msg); } }; @@ -134,4 +134,4 @@ BackgroundSubtractorWrap::BackgroundSubtractorWrap(cv::Ptr constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); BackgroundSubtractorWrap(cv::Ptr bg); - static Handle CreateMOG(const v8::Arguments&); - static Handle ApplyMOG(const v8::Arguments&); + static NAN_METHOD(CreateMOG); + static NAN_METHOD(ApplyMOG); }; -#endif \ No newline at end of file +#endif diff --git a/src/CamShift.cc b/src/CamShift.cc index 15fd628..788a1a4 100644 --- a/src/CamShift.cc +++ b/src/CamShift.cc @@ -12,24 +12,26 @@ Persistent TrackedObject::constructor; void TrackedObject::Init(Handle target) { - HandleScope scope; + NanScope(); // Constructor - constructor = Persistent::New(FunctionTemplate::New(TrackedObject::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("TrackedObject")); + Local ctor = NanNew(TrackedObject::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("TrackedObject")); + // Prototype //Local proto = constructor->PrototypeTemplate(); - NODE_SET_PROTOTYPE_METHOD(constructor, "track", Track); - target->Set(String::NewSymbol("TrackedObject"), constructor->GetFunction()); + NODE_SET_PROTOTYPE_METHOD(ctor, "track", Track); + + target->Set(NanNew("TrackedObject"), ctor->GetFunction()); }; -Handle -TrackedObject::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(TrackedObject::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0){ JSTHROW_TYPE("Cannot Instantiate without new") @@ -53,8 +55,8 @@ TrackedObject::New(const Arguments &args) { if (args[2]->IsObject()){ Local opts = args[2]->ToObject(); - if (opts->Get(String::New("channel"))->IsString()){ - v8::String::Utf8Value c(opts->Get(String::New("channel"))->ToString()); + if (opts->Get(NanNew("channel"))->IsString()){ + v8::String::Utf8Value c(opts->Get(NanNew("channel"))->ToString()); std::string cc = std::string(*c); if (cc == "hue" || cc == "h"){ @@ -75,7 +77,7 @@ TrackedObject::New(const Arguments &args) { to->Wrap(args.This()); - return args.This(); + NanReturnValue(args.This()); } @@ -120,13 +122,12 @@ TrackedObject::TrackedObject(cv::Mat image, cv::Rect rect, int chan){ -Handle -TrackedObject::Track(const v8::Arguments& args){ +NAN_METHOD(TrackedObject::Track){ SETUP_FUNCTION(TrackedObject) if (args.Length() != 1){ - v8::ThrowException(v8::Exception::TypeError(v8::String::New("track takes an image param"))); - return Undefined(); + NanThrowTypeError("track takes an image param"); + NanReturnUndefined(); } @@ -137,7 +138,7 @@ TrackedObject::Track(const v8::Arguments& args){ self->prev_rect.y <0 || self->prev_rect.width <= 1 || self->prev_rect.height <= 1){ - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("OPENCV ERROR: prev rectangle is illogical"))); + return NanThrowTypeError("OPENCV ERROR: prev rectangle is illogical"); } update_chann_image(self, im->mat); @@ -167,25 +168,24 @@ TrackedObject::Track(const v8::Arguments& args){ self->prev_rect = backup_prev_rect; } - - v8::Local arr = v8::Array::New(4); + v8::Local arr = NanNew(4); - arr->Set(0, Number::New(bounds.x)); - arr->Set(1, Number::New(bounds.y)); - arr->Set(2, Number::New(bounds.x + bounds.width)); - arr->Set(3, Number::New(bounds.y + bounds.height)); + arr->Set(0, NanNew(bounds.x)); + arr->Set(1, NanNew(bounds.y)); + arr->Set(2, NanNew(bounds.x + bounds.width)); + arr->Set(3, NanNew(bounds.y + bounds.height)); /* cv::Point2f pts[4]; r.points(pts); for (int i=0; i<8; i+=2){ - arr->Set(i, Number::New(pts[i].x)); - arr->Set(i+1, Number::New(pts[i].y)); + arr->Set(i, NanNew(pts[i].x)); + arr->Set(i+1, NanNew(pts[i].y)); } */ - return scope.Close(arr); + NanReturnValue(arr); } diff --git a/src/CamShift.h b/src/CamShift.h index 649a65f..d421fef 100644 --- a/src/CamShift.h +++ b/src/CamShift.h @@ -14,7 +14,7 @@ class TrackedObject: public node::ObjectWrap { static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); TrackedObject(cv::Mat image, cv::Rect rect, int channel); diff --git a/src/CascadeClassifierWrap.cc b/src/CascadeClassifierWrap.cc index 0fc8d28..d2f8871 100755 --- a/src/CascadeClassifierWrap.cc +++ b/src/CascadeClassifierWrap.cc @@ -1,78 +1,123 @@ #include "CascadeClassifierWrap.h" #include "OpenCV.h" #include "Matrix.h" +#include -void AsyncDetectMultiScale(uv_work_t *req); -void AfterAsyncDetectMultiScale(uv_work_t *req); - Persistent CascadeClassifierWrap::constructor; void CascadeClassifierWrap::Init(Handle target) { - HandleScope scope; + NanScope(); - // Constructor - constructor = Persistent::New(FunctionTemplate::New(CascadeClassifierWrap::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("CascadeClassifier")); + Local ctor = NanNew(CascadeClassifierWrap::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("CascadeClassifier")); // Prototype //Local proto = constructor->PrototypeTemplate(); - NODE_SET_PROTOTYPE_METHOD(constructor, "detectMultiScale", DetectMultiScale); + NODE_SET_PROTOTYPE_METHOD(ctor, "detectMultiScale", DetectMultiScale); - - - target->Set(String::NewSymbol("CascadeClassifier"), constructor->GetFunction()); + target->Set(NanNew("CascadeClassifier"), ctor->GetFunction()); }; -Handle -CascadeClassifierWrap::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(CascadeClassifierWrap::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0) - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new"))); + NanThrowTypeError("Cannot instantiate without new"); CascadeClassifierWrap *pt = new CascadeClassifierWrap(*args[0]); pt->Wrap(args.This()); - return args.This(); + NanReturnValue( args.This() ); } CascadeClassifierWrap::CascadeClassifierWrap(v8::Value* fileName){ std::string filename; - filename = std::string(*v8::String::AsciiValue(fileName->ToString())); + filename = std::string(*NanAsciiString(fileName->ToString())); if (!cc.load(filename.c_str())){ - v8::ThrowException(v8::Exception::TypeError(v8::String::New("Error loading file"))); + NanThrowTypeError("Error loading file"); } } -struct classifier_baton_t { - CascadeClassifierWrap *cc; - Persistent cb; - Matrix *im; - double scale; - int neighbors; - int minw; - int minh; - int sleep_for; - std::vector res; - uv_work_t request; + + +class AsyncDetectMultiScale : public NanAsyncWorker { + public: + AsyncDetectMultiScale(NanCallback *callback, CascadeClassifierWrap *cc, Matrix* im, double scale, int neighbors, int minw, int minh, int sleep_for) : NanAsyncWorker(callback), cc(cc), im(im), scale(scale), neighbors(neighbors), minw(minw), minh(minh), sleep_for(sleep_for) {} + ~AsyncDetectMultiScale() {} + + void Execute () { + std::vector objects; + + cv::Mat gray; + + if(this->im->mat.channels() != 1) + cvtColor(this->im->mat, gray, CV_BGR2GRAY); + + equalizeHist( gray, gray); + this->cc->cc.detectMultiScale(gray, objects, this->scale, this->neighbors, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(this->minw, this->minh)); + + res = objects; + } + + void HandleOKCallback () { + NanScope(); + // this->matrix->Unref(); + + v8::Local arr = NanNew(this->res.size()); + + for(unsigned int i = 0; i < this->res.size(); i++ ){ + v8::Local x = NanNew(); + x->Set(NanNew("x"), NanNew(this->res[i].x)); + x->Set(NanNew("y"), NanNew(this->res[i].y)); + x->Set(NanNew("width"), NanNew(this->res[i].width)); + x->Set(NanNew("height"), NanNew(this->res[i].height)); + arr->Set(i, x); + } + + //argv[1] = arr; + Local argv[] = { + NanNull() + , arr + }; + + TryCatch try_catch; + callback->Call(2, argv); + if (try_catch.HasCaught()) { + FatalException(try_catch); + } + + } + + private: + CascadeClassifierWrap *cc; + Matrix* im; + double scale; + int neighbors; + int minw; + int minh; + int sleep_for; + std::vector res; + }; -Handle -CascadeClassifierWrap::DetectMultiScale(const v8::Arguments& args){ - HandleScope scope; + + +NAN_METHOD(CascadeClassifierWrap::DetectMultiScale){ + NanScope(); CascadeClassifierWrap *self = ObjectWrap::Unwrap(args.This()); if (args.Length() < 2){ - v8::ThrowException(v8::Exception::TypeError(v8::String::New("detectMultiScale takes at least 2 args"))); + NanThrowTypeError("detectMultiScale takes at least 2 args"); } Matrix *im = ObjectWrap::Unwrap(args[0]->ToObject()); @@ -94,87 +139,9 @@ CascadeClassifierWrap::DetectMultiScale(const v8::Arguments& args){ } - classifier_baton_t *baton = new classifier_baton_t(); - baton->cc = self; - baton->cb = Persistent::New(cb); - baton->im = im; - baton->scale = scale; - baton->neighbors = neighbors; - baton->minw = minw; - baton->minh = minh; - baton->sleep_for = 1; - baton->request.data = baton; -// self->Ref(); - -// eio_custom(EIO_DetectMultiScale, EIO_PRI_DEFAULT, EIO_AfterDetectMultiScale, baton); -// ev_ref(EV_DEFAULT_UC); - - uv_queue_work(uv_default_loop(), &baton->request, AsyncDetectMultiScale, (uv_after_work_cb)AfterAsyncDetectMultiScale); - - return Undefined(); - + NanCallback *callback = new NanCallback(cb.As()); + NanAsyncQueueWorker( new AsyncDetectMultiScale(callback, self, im, scale, neighbors, minw, minh, 1) ); + NanReturnUndefined(); + } - - -void AsyncDetectMultiScale(uv_work_t *req) { - classifier_baton_t *baton = static_cast(req->data); - -// sleep(baton->sleep_for); - - std::vector objects; - - cv::Mat gray; - - if(baton->im->mat.channels() != 1) - cvtColor(baton->im->mat, gray, CV_BGR2GRAY); - - - equalizeHist( gray, gray); - baton->cc->cc.detectMultiScale(gray, objects, baton->scale, baton->neighbors, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(baton->minw, baton->minh)); - - baton->res = objects; - - -} - -void AfterAsyncDetectMultiScale(uv_work_t *req) { - - HandleScope scope; - classifier_baton_t *baton = static_cast(req->data); -// ev_unref(EV_DEFAULT_UC); -// baton->cc->Unref(); - - Local argv[2]; - - argv[0] = Local::New(Null()); - - - v8::Local arr = v8::Array::New(baton->res.size()); - - for(unsigned int i = 0; i < baton->res.size(); i++ ){ - v8::Local x = v8::Object::New(); - x->Set(v8::String::New("x"), v8::Number::New(baton->res[i].x)); - x->Set(v8::String::New("y"), v8::Number::New(baton->res[i].y)); - x->Set(v8::String::New("width"), v8::Number::New(baton->res[i].width)); - x->Set(v8::String::New("height"), v8::Number::New(baton->res[i].height)); - arr->Set(i, x); - } - - argv[1] = arr; - - TryCatch try_catch; - - baton->cb->Call(Context::GetCurrent()->Global(), 2, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - baton->cb.Dispose(); - - delete baton; - -// return 0; -} - diff --git a/src/CascadeClassifierWrap.h b/src/CascadeClassifierWrap.h index fa42309..36972d9 100755 --- a/src/CascadeClassifierWrap.h +++ b/src/CascadeClassifierWrap.h @@ -6,13 +6,14 @@ class CascadeClassifierWrap: public node::ObjectWrap { static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); CascadeClassifierWrap(v8::Value* fileName); - //static Handle LoadHaarClassifierCascade(const v8::Arguments&); + //static Handle LoadHaarClassifierCascade(const v8::Arguments&); + + static NAN_METHOD(DetectMultiScale); - static Handle DetectMultiScale(const v8::Arguments&); static void EIO_DetectMultiScale(uv_work_t *req); static int EIO_AfterDetectMultiScale(uv_work_t *req); diff --git a/src/Contours.cc b/src/Contours.cc index 54ec81c..d89f140 100755 --- a/src/Contours.cc +++ b/src/Contours.cc @@ -1,5 +1,6 @@ #include "Contours.h" #include "OpenCV.h" +#include #include @@ -8,62 +9,54 @@ v8::Persistent Contour::constructor; void Contour::Init(Handle target) { - HandleScope scope; + NanScope(); - //Class - v8::Local m = v8::FunctionTemplate::New(New); - m->SetClassName(v8::String::NewSymbol("Contours")); - - // Constructor - constructor = Persistent::New(m); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("Contours")); + //Class/contructor + Local ctor = NanNew(Contour::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("Contours")); + // Prototype //Local proto = constructor->PrototypeTemplate(); - - - NODE_SET_PROTOTYPE_METHOD(constructor, "point", Point); - NODE_SET_PROTOTYPE_METHOD(constructor, "points", Points); - NODE_SET_PROTOTYPE_METHOD(constructor, "size", Size); - NODE_SET_PROTOTYPE_METHOD(constructor, "cornerCount", CornerCount); - NODE_SET_PROTOTYPE_METHOD(constructor, "area", Area); - NODE_SET_PROTOTYPE_METHOD(constructor, "arcLength", ArcLength); - NODE_SET_PROTOTYPE_METHOD(constructor, "approxPolyDP", ApproxPolyDP); - NODE_SET_PROTOTYPE_METHOD(constructor, "convexHull", ConvexHull); - NODE_SET_PROTOTYPE_METHOD(constructor, "boundingRect", BoundingRect); - NODE_SET_PROTOTYPE_METHOD(constructor, "minAreaRect", MinAreaRect); - NODE_SET_PROTOTYPE_METHOD(constructor, "isConvex", IsConvex); - NODE_SET_PROTOTYPE_METHOD(constructor, "moments", Moments); + NODE_SET_PROTOTYPE_METHOD(ctor, "point", Point); + NODE_SET_PROTOTYPE_METHOD(ctor, "size", Size); + NODE_SET_PROTOTYPE_METHOD(ctor, "cornerCount", CornerCount); + NODE_SET_PROTOTYPE_METHOD(ctor, "area", Area); + NODE_SET_PROTOTYPE_METHOD(ctor, "arcLength", ArcLength); + NODE_SET_PROTOTYPE_METHOD(ctor, "approxPolyDP", ApproxPolyDP); + NODE_SET_PROTOTYPE_METHOD(ctor, "convexHull", ConvexHull); + NODE_SET_PROTOTYPE_METHOD(ctor, "boundingRect", BoundingRect); + NODE_SET_PROTOTYPE_METHOD(ctor, "minAreaRect", MinAreaRect); + NODE_SET_PROTOTYPE_METHOD(ctor, "isConvex", IsConvex); + NODE_SET_PROTOTYPE_METHOD(ctor, "moments", Moments); NODE_SET_PROTOTYPE_METHOD(constructor, "hierarchy", Hierarchy); NODE_SET_PROTOTYPE_METHOD(constructor, "serialize", Serialize); NODE_SET_PROTOTYPE_METHOD(constructor, "deserialize", Deserialize); - target->Set(String::NewSymbol("Contours"), m->GetFunction()); + target->Set(NanNew("Contours"), ctor->GetFunction()); }; -Handle -Contour::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0) - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot instantiate without new"))); + NanThrowTypeError("Cannot instantiate without new"); Contour *contours; contours = new Contour; contours->Wrap(args.Holder()); - return scope.Close(args.Holder()); + NanReturnValue(args.Holder()); } Contour::Contour(): ObjectWrap() { } - -Handle -Contour::Point(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::Point) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); @@ -71,13 +64,14 @@ Contour::Point(const Arguments &args) { cv::Point point = self->contours[pos][index]; - Local data = Object::New(); - data->Set(String::NewSymbol("x"), Number::New(point.x)); - data->Set(String::NewSymbol("y"), Number::New(point.y)); + Local data = NanNew(); + data->Set(NanNew("x"), NanNew(point.x)); + data->Set(NanNew("y"), NanNew(point.y)); - return scope.Close(data); + NanReturnValue(data); } +<<<<<<< HEAD Handle Contour::Points(const Arguments &args) { HandleScope scope; @@ -99,56 +93,55 @@ Contour::Points(const Arguments &args) { return scope.Close(data); } +======= +>>>>>>> a42033ac96f3a3506c62b5add536074ffa0801e8 // FIXME: this sould better be called "Length" as ``Contours`` is an Array like structure // also, this would allow to use ``Size`` for the function returning the number of corners // in the contour for better consistency with OpenCV. -Handle -Contour::Size(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::Size) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); - return scope.Close(Number::New(self->contours.size())); + NanReturnValue(NanNew(self->contours.size())); } -Handle -Contour::CornerCount(const Arguments &args) { - HandleScope scope; + +NAN_METHOD(Contour::CornerCount) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); - return scope.Close(Number::New(self->contours[pos].size())); + NanReturnValue(NanNew(self->contours[pos].size())); } -Handle -Contour::Area(const Arguments &args) { - HandleScope scope; + +NAN_METHOD(Contour::Area) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); - //return scope.Close(Number::New(contourArea(self->contours))); - return scope.Close(Number::New(contourArea(cv::Mat(self->contours[pos])))); + //NanReturnValue(NanNew(contourArea(self->contours))); + NanReturnValue(NanNew(contourArea(cv::Mat(self->contours[pos])))); } -Handle -Contour::ArcLength(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::ArcLength) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); bool isClosed = args[1]->BooleanValue(); - return scope.Close(Number::New(arcLength(cv::Mat(self->contours[pos]), isClosed))); + NanReturnValue(NanNew(arcLength(cv::Mat(self->contours[pos]), isClosed))); } -Handle -Contour::ApproxPolyDP(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::ApproxPolyDP) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); @@ -159,13 +152,12 @@ Contour::ApproxPolyDP(const Arguments &args) { approxPolyDP(cv::Mat(self->contours[pos]), approxed, epsilon, isClosed); approxed.copyTo(self->contours[pos]); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Contour::ConvexHull(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::ConvexHull) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); @@ -176,81 +168,77 @@ Contour::ConvexHull(const Arguments &args) { cv::convexHull(cv::Mat(self->contours[pos]), hull, clockwise); hull.copyTo(self->contours[pos]); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Contour::BoundingRect(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::BoundingRect) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); cv::Rect bounding = cv::boundingRect(cv::Mat(self->contours[pos])); - Local rect = Object::New(); + Local rect = NanNew(); - rect->Set(String::NewSymbol("x"), Number::New(bounding.x)); - rect->Set(String::NewSymbol("y"), Number::New(bounding.y)); - rect->Set(String::NewSymbol("width"), Number::New(bounding.width)); - rect->Set(String::NewSymbol("height"), Number::New(bounding.height)); + rect->Set(NanNew("x"), NanNew(bounding.x)); + rect->Set(NanNew("y"), NanNew(bounding.y)); + rect->Set(NanNew("width"), NanNew(bounding.width)); + rect->Set(NanNew("height"), NanNew(bounding.height)); - return scope.Close(rect); + NanReturnValue(rect); } -Handle -Contour::MinAreaRect(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::MinAreaRect) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); cv::RotatedRect minimum = cv::minAreaRect(cv::Mat(self->contours[pos])); - Local rect = Object::New(); - rect->Set(String::NewSymbol("angle"), Number::New(minimum.angle)); + Local rect = NanNew(); + rect->Set(NanNew("angle"), NanNew(minimum.angle)); - Local size = Object::New(); - size->Set(String::NewSymbol("height"), Number::New(minimum.size.height)); - size->Set(String::NewSymbol("width"), Number::New(minimum.size.width)); - rect->Set(String::NewSymbol("size"), size); + Local size = NanNew(); + size->Set(NanNew("height"), NanNew(minimum.size.height)); + size->Set(NanNew("width"), NanNew(minimum.size.width)); + rect->Set(NanNew("size"), size); - Local center = Object::New(); - center->Set(String::NewSymbol("x"), Number::New(minimum.center.x)); - center->Set(String::NewSymbol("y"), Number::New(minimum.center.y)); + Local center = NanNew(); + center->Set(NanNew("x"), NanNew(minimum.center.x)); + center->Set(NanNew("y"), NanNew(minimum.center.y)); - v8::Local points = v8::Array::New(4); + v8::Local points = NanNew(4); cv::Point2f rect_points[4]; minimum.points(rect_points); for (unsigned int i=0; i<4; i++){ - Local point = Object::New(); - point->Set(String::NewSymbol("x"), Number::New(rect_points[i].x)); - point->Set(String::NewSymbol("y"), Number::New(rect_points[i].y)); + Local point = NanNew(); + point->Set(NanNew("x"), NanNew(rect_points[i].x)); + point->Set(NanNew("y"), NanNew(rect_points[i].y)); points->Set(i, point); } - rect->Set(String::NewSymbol("points"), points); + rect->Set(NanNew("points"), points); - return scope.Close(rect); + NanReturnValue(rect); } -Handle -Contour::IsConvex(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::IsConvex) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); - return scope.Close(Boolean::New(isContourConvex(cv::Mat(self->contours[pos])))); + NanReturnValue(NanNew(isContourConvex(cv::Mat(self->contours[pos])))); } -Handle -Contour::Moments(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Contour::Moments) { + NanScope(); Contour *self = ObjectWrap::Unwrap(args.This()); int pos = args[0]->NumberValue(); @@ -258,14 +246,14 @@ Contour::Moments(const Arguments &args) { /// Get the moments cv::Moments mu = moments( self->contours[pos], false ); - Local res = Object::New(); + Local res = NanNew(); - res->Set(String::NewSymbol("m00"), Number::New(mu.m00)); - res->Set(String::NewSymbol("m10"), Number::New(mu.m10)); - res->Set(String::NewSymbol("m01"), Number::New(mu.m01)); - res->Set(String::NewSymbol("m11"), Number::New(mu.m11)); + res->Set(NanNew("m00"), NanNew(mu.m00)); + res->Set(NanNew("m10"), NanNew(mu.m10)); + res->Set(NanNew("m01"), NanNew(mu.m01)); + res->Set(NanNew("m11"), NanNew(mu.m11)); - return scope.Close(res); + NanReturnValue(res); } Handle @@ -373,4 +361,4 @@ Contour::Deserialize(const Arguments &args) { self->hierarchy = hierarchy_res; return scope.Close(v8::Null()); -} \ No newline at end of file +} diff --git a/src/Contours.h b/src/Contours.h index 548e0e9..72a82d7 100755 --- a/src/Contours.h +++ b/src/Contours.h @@ -11,25 +11,22 @@ class Contour: public node::ObjectWrap { static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); + + Contour(); + + JSFUNC(Point) + JSFUNC(Points) + JSFUNC(Size) + JSFUNC(CornerCount) + JSFUNC(Area) + JSFUNC(ArcLength) + JSFUNC(ApproxPolyDP) + JSFUNC(ConvexHull) + JSFUNC(BoundingRect) + JSFUNC(MinAreaRect) + JSFUNC(IsConvex) + JSFUNC(Moments) - Contour(); - - //JSFUNC(Size) - static Handle Point(const v8::Arguments&); - static Handle Points(const v8::Arguments&); - static Handle Size(const v8::Arguments&); - static Handle CornerCount(const v8::Arguments&); - static Handle Area(const v8::Arguments&); - static Handle ArcLength(const v8::Arguments&); - static Handle ApproxPolyDP(const v8::Arguments&); - static Handle ConvexHull(const v8::Arguments&); - static Handle BoundingRect(const v8::Arguments&); - static Handle MinAreaRect(const v8::Arguments&); - static Handle IsConvex(const v8::Arguments&); - static Handle Moments(const v8::Arguments&); - static Handle Hierarchy(const v8::Arguments&); - static Handle Serialize(const v8::Arguments&); - static Handle Deserialize(const v8::Arguments&); }; diff --git a/src/FaceRecognizer.cc b/src/FaceRecognizer.cc index 44a954d..fcf203f 100644 --- a/src/FaceRecognizer.cc +++ b/src/FaceRecognizer.cc @@ -4,6 +4,7 @@ #if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4 #include "Matrix.h" +#include #define EIGEN 0 #define LBPH 1 @@ -13,7 +14,7 @@ cv::Mat fromMatrixOrFilename(Local v){ cv::Mat im; if (v->IsString()){ - std::string filename = std::string(*v8::String::AsciiValue(v->ToString())); + std::string filename = std::string(*NanAsciiString(v->ToString())); im = cv::imread(filename); //std::cout<< im.size(); } else { @@ -31,31 +32,31 @@ Persistent FaceRecognizerWrap::constructor; void FaceRecognizerWrap::Init(Handle target) { - HandleScope scope; + NanScope(); // Constructor - constructor = Persistent::New(FunctionTemplate::New(FaceRecognizerWrap::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("FaceRecognizer")); + Local ctor = NanNew(FaceRecognizerWrap::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("FaceRecognizer")); - NODE_SET_METHOD(constructor, "createLBPHFaceRecognizer", CreateLBPH); - NODE_SET_METHOD(constructor, "createEigenFaceRecognizer", CreateEigen); - NODE_SET_METHOD(constructor, "createFisherFaceRecognizer", CreateFisher); + NODE_SET_METHOD(ctor, "createLBPHFaceRecognizer", CreateLBPH); + NODE_SET_METHOD(ctor, "createEigenFaceRecognizer", CreateEigen); + NODE_SET_METHOD(ctor, "createFisherFaceRecognizer", CreateFisher); - NODE_SET_PROTOTYPE_METHOD(constructor, "trainSync", TrainSync); - NODE_SET_PROTOTYPE_METHOD(constructor, "updateSync", UpdateSync); - NODE_SET_PROTOTYPE_METHOD(constructor, "predictSync", PredictSync); - NODE_SET_PROTOTYPE_METHOD(constructor, "saveSync", SaveSync); - NODE_SET_PROTOTYPE_METHOD(constructor, "loadSync", LoadSync); + NODE_SET_PROTOTYPE_METHOD(ctor, "trainSync", TrainSync); + NODE_SET_PROTOTYPE_METHOD(ctor, "updateSync", UpdateSync); + NODE_SET_PROTOTYPE_METHOD(ctor, "predictSync", PredictSync); + NODE_SET_PROTOTYPE_METHOD(ctor, "saveSync", SaveSync); + NODE_SET_PROTOTYPE_METHOD(ctor, "loadSync", LoadSync); - NODE_SET_PROTOTYPE_METHOD(constructor, "getMat", GetMat); + NODE_SET_PROTOTYPE_METHOD(ctor, "getMat", GetMat); - target->Set(String::NewSymbol("FaceRecognizer"), constructor->GetFunction()); + target->Set(NanNew("FaceRecognizer"), ctor->GetFunction()); }; -Handle -FaceRecognizerWrap::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(FaceRecognizerWrap::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0) JSTHROW_TYPE("Cannot Instantiate without new") @@ -65,12 +66,11 @@ FaceRecognizerWrap::New(const Arguments &args) { FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, LBPH); pt->Wrap(args.This()); - return args.This(); + NanReturnValue(args.This()); } -Handle -FaceRecognizerWrap::CreateLBPH(const Arguments &args) { - HandleScope scope; +NAN_METHOD(FaceRecognizerWrap::CreateLBPH) { + NanScope(); int radius = 1; int neighbors = 8; @@ -84,7 +84,7 @@ FaceRecognizerWrap::CreateLBPH(const Arguments &args) { INT_FROM_ARGS(grid_y, 3) DOUBLE_FROM_ARGS(threshold, 4) - Local n = FaceRecognizerWrap::constructor->GetFunction()->NewInstance(); + Local n = NanNew(FaceRecognizerWrap::constructor)->GetFunction()->NewInstance(); cv::Ptr f = cv::createLBPHFaceRecognizer( radius, neighbors, grid_x, grid_y, threshold @@ -92,12 +92,11 @@ FaceRecognizerWrap::CreateLBPH(const Arguments &args) { FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, LBPH); pt->Wrap(n); - return n; + NanReturnValue( n ); } -Handle -FaceRecognizerWrap::CreateEigen(const Arguments &args) { - HandleScope scope; +NAN_METHOD(FaceRecognizerWrap::CreateEigen) { + NanScope(); int components = 0; double threshold = DBL_MAX; @@ -105,7 +104,7 @@ FaceRecognizerWrap::CreateEigen(const Arguments &args) { INT_FROM_ARGS(components, 0) DOUBLE_FROM_ARGS(threshold, 1) - Local n = FaceRecognizerWrap::constructor->GetFunction()->NewInstance(); + Local n = NanNew(FaceRecognizerWrap::constructor)->GetFunction()->NewInstance(); cv::Ptr f = cv::createEigenFaceRecognizer( components, threshold @@ -113,12 +112,11 @@ FaceRecognizerWrap::CreateEigen(const Arguments &args) { FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, EIGEN); pt->Wrap(n); - return n; + NanReturnValue( n ); } -Handle -FaceRecognizerWrap::CreateFisher(const Arguments &args) { - HandleScope scope; +NAN_METHOD(FaceRecognizerWrap::CreateFisher) { + NanScope(); int components = 0; double threshold = DBL_MAX; @@ -126,7 +124,7 @@ FaceRecognizerWrap::CreateFisher(const Arguments &args) { INT_FROM_ARGS(components, 0) DOUBLE_FROM_ARGS(threshold, 1) - Local n = FaceRecognizerWrap::constructor->GetFunction()->NewInstance(); + Local n = NanNew(FaceRecognizerWrap::constructor)->GetFunction()->NewInstance(); cv::Ptr f = cv::createFisherFaceRecognizer( components, threshold @@ -134,7 +132,7 @@ FaceRecognizerWrap::CreateFisher(const Arguments &args) { FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, FISHER); pt->Wrap(n); - return n; + NanReturnValue( n ); } @@ -144,15 +142,20 @@ FaceRecognizerWrap::FaceRecognizerWrap(cv::Ptr f, int type){ } -Handle UnwrapTrainingData(const Arguments& args, cv::vector* images, cv::vector* labels){ +Handle UnwrapTrainingData(_NAN_METHOD_ARGS_TYPE args, cv::vector* images, cv::vector* labels){ + + if (args.Length() < 1 || !args[0]->IsArray()){ JSTHROW("FaceRecognizer.train takes a list of [ label, image] tuples") } // Iterate through [[label, image], ...] etc, and add matrix / label to vectors - const Local tuples = v8::Array::Cast(*args[0]); + //const + //Local tuples = v8::Array::Cast(*args[0]); + const Local tuples = Local::Cast(args[0]); + const uint32_t length = tuples->Length(); for (uint32_t i=0 ; i val = tuples->Get(i); @@ -161,7 +164,7 @@ Handle UnwrapTrainingData(const Arguments& args, cv::vector* ima JSTHROW("train takes a list of [label, image] tuples") } - Local valarr = v8::Array::Cast(*val); + Local valarr = Local::Cast(val); if (valarr->Length() != 2 || !valarr->Get(0)->IsInt32()){ JSTHROW("train takes a list of [label, image] tuples") @@ -174,11 +177,11 @@ Handle UnwrapTrainingData(const Arguments& args, cv::vector* ima labels->push_back(label); images->push_back(im); } - return v8::Undefined(); + return NanUndefined(); } -Handle -FaceRecognizerWrap::TrainSync(const Arguments& args){ + +NAN_METHOD(FaceRecognizerWrap::TrainSync){ SETUP_FUNCTION(FaceRecognizerWrap) cv::vector images; @@ -186,16 +189,15 @@ FaceRecognizerWrap::TrainSync(const Arguments& args){ Handle exception = UnwrapTrainingData(args, &images, &labels); if (!exception->IsUndefined()){ - return exception; + NanReturnValue(exception);//FIXME: not too sure about returning exceptions like this } self->rec->train(images, labels); - return scope.Close(v8::Undefined()); + NanReturnUndefined(); } -Handle -FaceRecognizerWrap::UpdateSync(const Arguments& args){ +NAN_METHOD(FaceRecognizerWrap::UpdateSync){ SETUP_FUNCTION(FaceRecognizerWrap) @@ -212,17 +214,16 @@ FaceRecognizerWrap::UpdateSync(const Arguments& args){ Handle exception = UnwrapTrainingData(args, &images, &labels); if (!exception->IsUndefined()){ - return exception; + JSTHROW( exception ); } self->rec->update(images, labels); - return scope.Close(v8::Undefined()); + NanReturnUndefined(); } -Handle -FaceRecognizerWrap::PredictSync(const Arguments& args){ +NAN_METHOD(FaceRecognizerWrap::PredictSync){ SETUP_FUNCTION(FaceRecognizerWrap) cv::Mat im = fromMatrixOrFilename(args[0]);//TODO CHECK! @@ -233,50 +234,47 @@ FaceRecognizerWrap::PredictSync(const Arguments& args){ double confidence = 0.0; self->rec->predict(im, predictedLabel, confidence); - v8::Local res = v8::Object::New(); - res->Set(v8::String::New("id"), v8::Number::New(predictedLabel)); - res->Set(v8::String::New("confidence"), v8::Number::New(confidence)); + v8::Local res = NanNew(); + res->Set(NanNew("id"), NanNew(predictedLabel)); + res->Set(NanNew("confidence"), NanNew(confidence)); - return scope.Close(res); + NanReturnValue(res); } -Handle -FaceRecognizerWrap::SaveSync(const Arguments& args){ +NAN_METHOD(FaceRecognizerWrap::SaveSync){ SETUP_FUNCTION(FaceRecognizerWrap) if (!args[0]->IsString()){ JSTHROW("Save takes a filename") } - std::string filename = std::string(*v8::String::AsciiValue(args[0]->ToString())); + std::string filename = std::string(*NanAsciiString(args[0]->ToString())); self->rec->save(filename); - return v8::Undefined(); + NanReturnUndefined(); } -Handle -FaceRecognizerWrap::LoadSync(const Arguments& args){ +NAN_METHOD(FaceRecognizerWrap::LoadSync){ SETUP_FUNCTION(FaceRecognizerWrap) if (!args[0]->IsString()){ JSTHROW("Load takes a filename") } - std::string filename = std::string(*v8::String::AsciiValue(args[0]->ToString())); + std::string filename = std::string(*NanAsciiString(args[0]->ToString())); self->rec->load(filename); - return v8::Undefined(); + NanReturnUndefined(); } -Handle -FaceRecognizerWrap::GetMat(const Arguments& args){ +NAN_METHOD(FaceRecognizerWrap::GetMat){ SETUP_FUNCTION(FaceRecognizerWrap) if (!args[0]->IsString()){ JSTHROW("getMat takes a key") } - std::string key = std::string(*v8::String::AsciiValue(args[0]->ToString())); + std::string key = std::string(*NanAsciiString(args[0]->ToString())); cv::Mat m = self->rec->getMat(key); - Local im = Matrix::constructor->GetFunction()->NewInstance(); + Local im = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(im); img->mat = m; - return im; + NanReturnValue( im ); } diff --git a/src/FaceRecognizer.h b/src/FaceRecognizer.h index 55404b7..07a5afd 100644 --- a/src/FaceRecognizer.h +++ b/src/FaceRecognizer.h @@ -11,7 +11,7 @@ class FaceRecognizerWrap: public node::ObjectWrap { static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); FaceRecognizerWrap(cv::Ptr f, int type); diff --git a/src/HighGUI.cc b/src/HighGUI.cc index 9c057fd..f2160b9 100644 --- a/src/HighGUI.cc +++ b/src/HighGUI.cc @@ -7,26 +7,25 @@ Persistent NamedWindow::constructor; void NamedWindow::Init(Handle target) { - HandleScope scope; + NanScope(); // Constructor - constructor = Persistent::New(FunctionTemplate::New(NamedWindow::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("NamedWindow")); + Local ctor = NanNew(NamedWindow::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("NamedWindow")); // Prototype - //Local proto = constructor->PrototypeTemplate(); - - NODE_SET_PROTOTYPE_METHOD(constructor, "show", Show); - NODE_SET_PROTOTYPE_METHOD(constructor, "destroy", Destroy); - NODE_SET_PROTOTYPE_METHOD(constructor, "blockingWaitKey", BlockingWaitKey); - target->Set(String::NewSymbol("NamedWindow"), constructor->GetFunction()); + NODE_SET_PROTOTYPE_METHOD(ctor, "show", Show); + NODE_SET_PROTOTYPE_METHOD(ctor, "destroy", Destroy); + NODE_SET_PROTOTYPE_METHOD(ctor, "blockingWaitKey", BlockingWaitKey); + + target->Set(NanNew("NamedWindow"), ctor->GetFunction()); }; -Handle -NamedWindow::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(NamedWindow::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0){ JSTHROW_TYPE("Cannot Instantiate without new") @@ -34,13 +33,13 @@ NamedWindow::New(const Arguments &args) { NamedWindow* win; if (args.Length() == 1){ - win = new NamedWindow(std::string(*v8::String::AsciiValue(args[0]->ToString())), 0); + win = new NamedWindow(std::string(*NanAsciiString(args[0]->ToString())), 0); } else if (args.Length() == 2){ - win = new NamedWindow(std::string(*v8::String::AsciiValue(args[0]->ToString())), 0); + win = new NamedWindow(std::string(*NanAsciiString(args[0]->ToString())), 0); } win->Wrap(args.Holder()); - return scope.Close(args.Holder()); + NanReturnValue(args.Holder()); } @@ -51,26 +50,23 @@ NamedWindow::NamedWindow(const std::string& name, int f){ } -Handle -NamedWindow::Show(const v8::Arguments& args){ +NAN_METHOD(NamedWindow::Show){ SETUP_FUNCTION(NamedWindow) Matrix *im = ObjectWrap::Unwrap(args[0]->ToObject()); cv::imshow(self->winname, im->mat); - return scope.Close(args.Holder()); + NanReturnValue(args.Holder()); } -Handle -NamedWindow::Destroy(const v8::Arguments& args){ +NAN_METHOD(NamedWindow::Destroy){ SETUP_FUNCTION(NamedWindow) cv::destroyWindow(self->winname); - return scope.Close(args.Holder()); + NanReturnValue(args.Holder()); } -Handle -NamedWindow::BlockingWaitKey(const v8::Arguments& args){ - HandleScope scope; +NAN_METHOD(NamedWindow::BlockingWaitKey){ + NanScope(); //SETUP_FUNCTION(NamedWindow) int time = 0; @@ -84,5 +80,5 @@ NamedWindow::BlockingWaitKey(const v8::Arguments& args){ int res = cv::waitKey(time); - return scope.Close(Number::New(res)); + NanReturnValue(NanNew(res)); } diff --git a/src/HighGUI.h b/src/HighGUI.h index 61b5033..3a18e81 100644 --- a/src/HighGUI.h +++ b/src/HighGUI.h @@ -6,10 +6,9 @@ class NamedWindow: public node::ObjectWrap { std::string winname; int flags; - static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); NamedWindow(const std::string& winname, int flags); diff --git a/src/Matrix.cc b/src/Matrix.cc index 62fc153..00eb783 100755 --- a/src/Matrix.cc +++ b/src/Matrix.cc @@ -1,6 +1,7 @@ #include "Contours.h" #include "Matrix.h" #include "OpenCV.h" +#include v8::Persistent Matrix::constructor; @@ -10,122 +11,110 @@ cv::Rect* setRect(Local objRect); void Matrix::Init(Handle target) { - HandleScope scope; + NanScope(); //Class - v8::Local m = v8::FunctionTemplate::New(New); - m->SetClassName(v8::String::NewSymbol("Matrix")); + Local ctor = NanNew(Matrix::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("Matrix")); - // Constructor - constructor = Persistent::New(m); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("Matrix")); + // Prototype + NODE_SET_PROTOTYPE_METHOD(ctor, "row", Row); + NODE_SET_PROTOTYPE_METHOD(ctor, "col", Col); - // Prototype - //Local proto = constructor->PrototypeTemplate(); + NODE_SET_PROTOTYPE_METHOD(ctor, "pixelRow", PixelRow); + NODE_SET_PROTOTYPE_METHOD(ctor, "pixelCol", PixelCol); + NODE_SET_PROTOTYPE_METHOD(ctor, "empty", Empty); + NODE_SET_PROTOTYPE_METHOD(ctor, "get", Get); + NODE_SET_PROTOTYPE_METHOD(ctor, "set", Set); + NODE_SET_PROTOTYPE_METHOD(ctor, "pixel", Pixel); + NODE_SET_PROTOTYPE_METHOD(ctor, "width", Width); + NODE_SET_PROTOTYPE_METHOD(ctor, "height", Height); + NODE_SET_PROTOTYPE_METHOD(ctor, "size", Size); + NODE_SET_PROTOTYPE_METHOD(ctor, "clone", Clone); + NODE_SET_PROTOTYPE_METHOD(ctor, "toBuffer", ToBuffer); + NODE_SET_PROTOTYPE_METHOD(ctor, "toBufferAsync", ToBufferAsync); + NODE_SET_PROTOTYPE_METHOD(ctor, "ellipse", Ellipse); + NODE_SET_PROTOTYPE_METHOD(ctor, "rectangle", Rectangle); + NODE_SET_PROTOTYPE_METHOD(ctor, "line", Line); + NODE_SET_PROTOTYPE_METHOD(ctor, "save", Save); + NODE_SET_PROTOTYPE_METHOD(ctor, "saveAsync", SaveAsync); + NODE_SET_PROTOTYPE_METHOD(ctor, "resize", Resize); + NODE_SET_PROTOTYPE_METHOD(ctor, "rotate", Rotate); + NODE_SET_PROTOTYPE_METHOD(ctor, "copyTo", CopyTo); + NODE_SET_PROTOTYPE_METHOD(ctor, "pyrDown", PyrDown); + NODE_SET_PROTOTYPE_METHOD(ctor, "pyrUp", PyrUp); + NODE_SET_PROTOTYPE_METHOD(ctor, "channels", Channels); - NODE_SET_PROTOTYPE_METHOD(constructor, "row", Row); - NODE_SET_PROTOTYPE_METHOD(constructor, "col", Col); + NODE_SET_PROTOTYPE_METHOD(ctor, "convertGrayscale", ConvertGrayscale); + NODE_SET_PROTOTYPE_METHOD(ctor, "convertHSVscale", ConvertHSVscale); + NODE_SET_PROTOTYPE_METHOD(ctor, "gaussianBlur", GaussianBlur); + NODE_SET_PROTOTYPE_METHOD(ctor, "medianBlur", MedianBlur); + NODE_SET_PROTOTYPE_METHOD(ctor, "bilateralFilter", BilateralFilter); + NODE_SET_PROTOTYPE_METHOD(ctor, "copy", Copy); + NODE_SET_PROTOTYPE_METHOD(ctor, "flip", Flip); + NODE_SET_PROTOTYPE_METHOD(ctor, "roi", ROI); + NODE_SET_PROTOTYPE_METHOD(ctor, "ptr", Ptr); + NODE_SET_PROTOTYPE_METHOD(ctor, "absDiff", AbsDiff); + NODE_SET_PROTOTYPE_METHOD(ctor, "addWeighted", AddWeighted); + NODE_SET_PROTOTYPE_METHOD(ctor, "bitwiseXor", BitwiseXor); + NODE_SET_PROTOTYPE_METHOD(ctor, "bitwiseNot", BitwiseNot); + NODE_SET_PROTOTYPE_METHOD(ctor, "bitwiseAnd", BitwiseAnd); + NODE_SET_PROTOTYPE_METHOD(ctor, "countNonZero", CountNonZero); + NODE_SET_PROTOTYPE_METHOD(ctor, "canny", Canny); + NODE_SET_PROTOTYPE_METHOD(ctor, "dilate", Dilate); + NODE_SET_PROTOTYPE_METHOD(ctor, "erode", Erode); - NODE_SET_PROTOTYPE_METHOD(constructor, "pixelRow", PixelRow); - NODE_SET_PROTOTYPE_METHOD(constructor, "pixelCol", PixelCol); + NODE_SET_PROTOTYPE_METHOD(ctor, "findContours", FindContours); + NODE_SET_PROTOTYPE_METHOD(ctor, "drawContour", DrawContour); + NODE_SET_PROTOTYPE_METHOD(ctor, "drawAllContours", DrawAllContours); - NODE_SET_PROTOTYPE_METHOD(constructor, "empty", Empty); - NODE_SET_PROTOTYPE_METHOD(constructor, "get", Get); - NODE_SET_PROTOTYPE_METHOD(constructor, "set", Set); - NODE_SET_PROTOTYPE_METHOD(constructor, "pixel", Pixel); - NODE_SET_PROTOTYPE_METHOD(constructor, "width", Width); - NODE_SET_PROTOTYPE_METHOD(constructor, "height", Height); - NODE_SET_PROTOTYPE_METHOD(constructor, "size", Size); - NODE_SET_PROTOTYPE_METHOD(constructor, "clone", Clone); - NODE_SET_PROTOTYPE_METHOD(constructor, "toBuffer", ToBuffer); - NODE_SET_PROTOTYPE_METHOD(constructor, "toBufferAsync", ToBufferAsync); - NODE_SET_PROTOTYPE_METHOD(constructor, "ellipse", Ellipse); - NODE_SET_PROTOTYPE_METHOD(constructor, "rectangle", Rectangle); - NODE_SET_PROTOTYPE_METHOD(constructor, "line", Line); - NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save); - NODE_SET_PROTOTYPE_METHOD(constructor, "saveAsync", SaveAsync); - NODE_SET_PROTOTYPE_METHOD(constructor, "resize", Resize); - NODE_SET_PROTOTYPE_METHOD(constructor, "rotate", Rotate); - NODE_SET_PROTOTYPE_METHOD(constructor, "copyTo", CopyTo); - NODE_SET_PROTOTYPE_METHOD(constructor, "pyrDown", PyrDown); - NODE_SET_PROTOTYPE_METHOD(constructor, "pyrUp", PyrUp); - NODE_SET_PROTOTYPE_METHOD(constructor, "channels", Channels); + NODE_SET_PROTOTYPE_METHOD(ctor, "goodFeaturesToTrack", GoodFeaturesToTrack); + NODE_SET_PROTOTYPE_METHOD(ctor, "houghLinesP", HoughLinesP); - NODE_SET_PROTOTYPE_METHOD(constructor, "crop", Crop); + NODE_SET_PROTOTYPE_METHOD(ctor, "inRange", inRange); + NODE_SET_PROTOTYPE_METHOD(ctor, "adjustROI", AdjustROI); + NODE_SET_PROTOTYPE_METHOD(ctor, "locateROI", LocateROI); - NODE_SET_PROTOTYPE_METHOD(constructor, "convertGrayscale", ConvertGrayscale); - NODE_SET_PROTOTYPE_METHOD(constructor, "convertHSVscale", ConvertHSVscale); - NODE_SET_PROTOTYPE_METHOD(constructor, "gaussianBlur", GaussianBlur); - NODE_SET_PROTOTYPE_METHOD(constructor, "medianBlur", MedianBlur); - NODE_SET_PROTOTYPE_METHOD(constructor, "bilateralFilter", BilateralFilter); - NODE_SET_PROTOTYPE_METHOD(constructor, "copy", Copy); - NODE_SET_PROTOTYPE_METHOD(constructor, "flip", Flip); - NODE_SET_PROTOTYPE_METHOD(constructor, "roi", ROI); - NODE_SET_PROTOTYPE_METHOD(constructor, "ptr", Ptr); - NODE_SET_PROTOTYPE_METHOD(constructor, "absDiff", AbsDiff); - NODE_SET_PROTOTYPE_METHOD(constructor, "addWeighted", AddWeighted); - NODE_SET_PROTOTYPE_METHOD(constructor, "bitwiseXor", BitwiseXor); - NODE_SET_PROTOTYPE_METHOD(constructor, "bitwiseNot", BitwiseNot); - NODE_SET_PROTOTYPE_METHOD(constructor, "bitwiseAnd", BitwiseAnd); - NODE_SET_PROTOTYPE_METHOD(constructor, "countNonZero", CountNonZero); - NODE_SET_PROTOTYPE_METHOD(constructor, "canny", Canny); - NODE_SET_PROTOTYPE_METHOD(constructor, "dilate", Dilate); - NODE_SET_PROTOTYPE_METHOD(constructor, "erode", Erode); + NODE_SET_PROTOTYPE_METHOD(ctor, "threshold", Threshold); + NODE_SET_PROTOTYPE_METHOD(ctor, "adaptiveThreshold", AdaptiveThreshold); + NODE_SET_PROTOTYPE_METHOD(ctor, "meanStdDev", MeanStdDev); - NODE_SET_PROTOTYPE_METHOD(constructor, "findContours", FindContours); - NODE_SET_PROTOTYPE_METHOD(constructor, "drawContour", DrawContour); - NODE_SET_PROTOTYPE_METHOD(constructor, "drawAllContours", DrawAllContours); + NODE_SET_PROTOTYPE_METHOD(ctor, "cvtColor", CvtColor); + NODE_SET_PROTOTYPE_METHOD(ctor, "split", Split); + NODE_SET_PROTOTYPE_METHOD(ctor, "merge", Merge); + NODE_SET_PROTOTYPE_METHOD(ctor, "equalizeHist", EqualizeHist); - NODE_SET_PROTOTYPE_METHOD(constructor, "goodFeaturesToTrack", GoodFeaturesToTrack); - NODE_SET_PROTOTYPE_METHOD(constructor, "houghLinesP", HoughLinesP); + NODE_SET_PROTOTYPE_METHOD(ctor, "floodFill", FloodFill); - NODE_SET_PROTOTYPE_METHOD(constructor, "inRange", inRange); - NODE_SET_PROTOTYPE_METHOD(constructor, "adjustROI", AdjustROI); - NODE_SET_PROTOTYPE_METHOD(constructor, "locateROI", LocateROI); + NODE_SET_PROTOTYPE_METHOD(ctor, "matchTemplate", MatchTemplate); + NODE_SET_PROTOTYPE_METHOD(ctor, "minMaxLoc", MinMaxLoc); - NODE_SET_PROTOTYPE_METHOD(constructor, "threshold", Threshold); - NODE_SET_PROTOTYPE_METHOD(constructor, "adaptiveThreshold", AdaptiveThreshold); - NODE_SET_PROTOTYPE_METHOD(constructor, "meanStdDev", MeanStdDev); + NODE_SET_PROTOTYPE_METHOD(ctor, "pushBack", PushBack); - NODE_SET_PROTOTYPE_METHOD(constructor, "cvtColor", CvtColor); - NODE_SET_PROTOTYPE_METHOD(constructor, "split", Split); - NODE_SET_PROTOTYPE_METHOD(constructor, "merge", Merge); - NODE_SET_PROTOTYPE_METHOD(constructor, "equalizeHist", EqualizeHist); + NODE_SET_PROTOTYPE_METHOD(ctor, "putText", PutText); + + NODE_SET_PROTOTYPE_METHOD(ctor, "getPerspectiveTransform", GetPerspectiveTransform); + NODE_SET_PROTOTYPE_METHOD(ctor, "warpPerspective", WarpPerspective); - NODE_SET_PROTOTYPE_METHOD(constructor, "floodFill", FloodFill); + NODE_SET_METHOD(ctor, "Zeros", Zeros); + NODE_SET_METHOD(ctor, "Ones", Ones); + NODE_SET_METHOD(ctor, "Eye", Eye); - NODE_SET_PROTOTYPE_METHOD(constructor, "matchTemplate", MatchTemplate); - NODE_SET_PROTOTYPE_METHOD(constructor, "minMaxLoc", MinMaxLoc); + NODE_SET_PROTOTYPE_METHOD(ctor, "copyWithMask", CopyWithMask); + NODE_SET_PROTOTYPE_METHOD(ctor, "setWithMask", SetWithMask); + NODE_SET_PROTOTYPE_METHOD(ctor, "meanWithMask", MeanWithMask); + NODE_SET_PROTOTYPE_METHOD(ctor, "shift", Shift); - NODE_SET_PROTOTYPE_METHOD(constructor, "pushBack", PushBack); - - NODE_SET_PROTOTYPE_METHOD(constructor, "putText", PutText); - - NODE_SET_PROTOTYPE_METHOD(constructor, "getPerspectiveTransform", GetPerspectiveTransform); - NODE_SET_PROTOTYPE_METHOD(constructor, "warpPerspective", WarpPerspective); - - NODE_SET_METHOD(constructor, "Zeros", Zeros); - NODE_SET_METHOD(constructor, "Ones", Ones); - NODE_SET_METHOD(constructor, "Eye", Eye); - - NODE_SET_PROTOTYPE_METHOD(constructor, "copyWithMask", CopyWithMask); - NODE_SET_PROTOTYPE_METHOD(constructor, "setWithMask", SetWithMask); - NODE_SET_PROTOTYPE_METHOD(constructor, "meanWithMask", MeanWithMask); - NODE_SET_PROTOTYPE_METHOD(constructor, "shift", Shift); - - - target->Set(String::NewSymbol("Matrix"), m->GetFunction()); + target->Set(NanNew("Matrix"), ctor->GetFunction()); }; - -Handle -Matrix::New(const Arguments &args) { - HandleScope scope; - +NAN_METHOD(Matrix::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0) - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot instantiate without new"))); + NanThrowTypeError("Cannot instantiate without new"); Matrix *mat; @@ -145,7 +134,7 @@ Matrix::New(const Arguments &args) { } mat->Wrap(args.Holder()); - return scope.Close(args.Holder()); + NanReturnValue(args.Holder()); } @@ -167,15 +156,12 @@ Matrix::Matrix(cv::Mat m, cv::Rect roi): ObjectWrap() { } -Handle -Matrix::Empty(const Arguments& args){ + +NAN_METHOD(Matrix::Empty){ SETUP_FUNCTION(Matrix) - - return scope.Close(Boolean::New(self->mat.empty())); + NanReturnValue(NanNew(self->mat.empty())); } - - double Matrix::DblGet(cv::Mat mat, int i, int j){ @@ -205,9 +191,7 @@ Matrix::DblGet(cv::Mat mat, int i, int j){ } - -Handle -Matrix::Pixel(const Arguments& args){ +NAN_METHOD(Matrix::Pixel){ SETUP_FUNCTION(Matrix) int y = args[0]->IntegerValue(); @@ -228,7 +212,7 @@ Matrix::Pixel(const Arguments& args){ else if(self->mat.channels() == 1) self->mat.at(y,x) = (uchar) objColor->Get(0)->IntegerValue(); - return scope.Close(args[2]->ToObject()); + NanReturnValue( args[2]->ToObject() ); }else{ if(self->mat.channels() == 3){ @@ -244,30 +228,34 @@ Matrix::Pixel(const Arguments& args){ uchar intensity = self->mat.at(y, x); return scope.Close(Number::New(intensity)); - } } + else{ + cv::Vec3b intensity = self->mat.at(y, x); - return scope.Close(Undefined()); + v8::Local arr = NanNew(3); + arr->Set(0, NanNew( intensity[0] )); + arr->Set(1, NanNew( intensity[1] )); + arr->Set(2, NanNew( intensity[2] )); + NanReturnValue( arr ); + } + NanReturnUndefined(); //double val = Matrix::DblGet(t, i, j); - //return scope.Close(Number::New(val)); + //NanReturnValue(NanNew(val)); } - -Handle -Matrix::Get(const Arguments& args){ +NAN_METHOD(Matrix::Get){ SETUP_FUNCTION(Matrix) int i = args[0]->IntegerValue(); int j = args[1]->IntegerValue(); double val = Matrix::DblGet(self->mat, i, j); - return scope.Close(Number::New(val)); + NanReturnValue( NanNew(val) ); } -Handle -Matrix::Set(const Arguments& args){ +NAN_METHOD(Matrix::Set){ SETUP_FUNCTION(Matrix) int i = args[0]->IntegerValue(); @@ -296,34 +284,32 @@ Matrix::Set(const Arguments& args){ } else { - return v8::ThrowException(v8::Exception::TypeError(String::New("Invalid number of arguments"))); + NanThrowTypeError( "Invalid number of arguments" ); } + + NanReturnUndefined(); +} - return scope.Close(Undefined()); +NAN_METHOD(Matrix::Size){ + SETUP_FUNCTION(Matrix) + + v8::Local arr = NanNew(2); + arr->Set(0, NanNew(self->mat.size().height)); + arr->Set(1, NanNew(self->mat.size().width)); + + NanReturnValue(arr); } -Handle -Matrix::Size(const Arguments& args){ +NAN_METHOD(Matrix::Clone){ SETUP_FUNCTION(Matrix) - - v8::Local arr = v8::Array::New(2); - arr->Set(0, Number::New(self->mat.size().height)); - arr->Set(1, Number::New(self->mat.size().width)); - - return scope.Close(arr); -} - - -Handle -Matrix::Clone(const Arguments& args){ - SETUP_FUNCTION(Matrix) - - Local im_h = Matrix::constructor->GetFunction()->NewInstance(); + + Local im_h = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *m = ObjectWrap::Unwrap(im_h); m->mat = self->mat.clone(); - return scope.Close(im_h); + NanReturnValue(im_h); } Handle @@ -351,100 +337,94 @@ Matrix::Crop(const Arguments& args){ } } -Handle -Matrix::Row(const Arguments& args){ +NAN_METHOD(Matrix::Row){ SETUP_FUNCTION(Matrix) int width = self->mat.size().width; int y = args[0]->IntegerValue(); - v8::Local arr = v8::Array::New(width); + v8::Local arr = NanNew(width); for (int x=0; xmat, y, x); - arr->Set(x, Number::New(v)); + arr->Set(x, NanNew(v)); } - return scope.Close(arr); + NanReturnValue(arr); } -Handle - Matrix::PixelRow(const Arguments& args){ +NAN_METHOD(Matrix::PixelRow){ SETUP_FUNCTION(Matrix) int width = self->mat.size().width; int y = args[0]->IntegerValue(); - v8::Local arr = v8::Array::New(width * 3); + v8::Local arr = NanNew(width * 3); for (int x=0; xmat.at(y, x); int offset = x * 3; - arr->Set(offset , Number::New((double)pixel.val[0])); - arr->Set(offset + 1, Number::New((double)pixel.val[1])); - arr->Set(offset + 2, Number::New((double)pixel.val[2])); + arr->Set(offset , NanNew((double)pixel.val[0])); + arr->Set(offset + 1, NanNew((double)pixel.val[1])); + arr->Set(offset + 2, NanNew((double)pixel.val[2])); + } + + NanReturnValue(arr); } - return scope.Close(arr); -} -Handle -Matrix::Col(const Arguments& args){ +NAN_METHOD(Matrix::Col){ SETUP_FUNCTION(Matrix) int height = self->mat.size().height; int x = args[0]->IntegerValue(); - v8::Local arr = v8::Array::New(height); + v8::Local arr = NanNew(height); for (int y=0; ymat, y, x); - arr->Set(y, Number::New(v)); + arr->Set(y, NanNew(v)); } - return scope.Close(arr); + NanReturnValue(arr); } -Handle -Matrix::PixelCol(const Arguments& args){ +NAN_METHOD(Matrix::PixelCol){ SETUP_FUNCTION(Matrix) int height = self->mat.size().height; int x = args[0]->IntegerValue(); - v8::Local arr = v8::Array::New(height * 3); + v8::Local arr = NanNew(height * 3); for (int y=0; ymat.at(y, x); int offset = y * 3; - arr->Set(offset , Number::New((double)pixel.val[0])); - arr->Set(offset + 1, Number::New((double)pixel.val[1])); - arr->Set(offset + 2, Number::New((double)pixel.val[2])); + arr->Set(offset , NanNew((double)pixel.val[0])); + arr->Set(offset + 1, NanNew((double)pixel.val[1])); + arr->Set(offset + 2, NanNew((double)pixel.val[2])); } - return scope.Close(arr); + NanReturnValue(arr); } -Handle -Matrix::Width(const Arguments& args){ + +NAN_METHOD(Matrix::Width){ SETUP_FUNCTION(Matrix) - return scope.Close(Number::New(self->mat.size().width)); + NanReturnValue(NanNew(self->mat.size().width)); } -Handle -Matrix::Height(const Arguments& args){ +NAN_METHOD(Matrix::Height){ SETUP_FUNCTION(Matrix) - return scope.Close(Number::New(self->mat.size().height)); + NanReturnValue(NanNew(self->mat.size().height)); } -Handle -Matrix::Channels(const Arguments& args){ +NAN_METHOD(Matrix::Channels){ SETUP_FUNCTION(Matrix) - return scope.Close(Number::New(self->mat.channels())); + NanReturnValue(NanNew(self->mat.channels())); } -Handle -Matrix::ToBuffer(const v8::Arguments& args){ +NAN_METHOD(Matrix::ToBuffer){ SETUP_FUNCTION(Matrix) if ((args.Length() > 0) && (args[0]->IsFunction())) { @@ -466,18 +446,18 @@ Matrix::ToBuffer(const v8::Arguments& args){ // Get this options argument v8::Handle options = v8::Handle::Cast(args[0]); // If the extension (image format) is provided - if (options->Has(v8::String::New("ext"))) { - v8::String::Utf8Value str ( options->Get(v8::String::New("ext"))->ToString() ); + if (options->Has(NanNew("ext"))) { + v8::String::Utf8Value str ( options->Get(NanNew("ext"))->ToString() ); std::string str2 = std::string(*str); ext = (const char *) str2.c_str(); } - if (options->Has(v8::String::New("jpegQuality"))) { - int compression = options->Get(v8::String::New("jpegQuality"))->IntegerValue(); + if (options->Has(NanNew("jpegQuality"))) { + int compression = options->Get(NanNew("jpegQuality"))->IntegerValue(); params.push_back(CV_IMWRITE_JPEG_QUALITY); params.push_back(compression); } - if (options->Has(v8::String::New("pngCompression"))) { - int compression = options->Get(v8::String::New("pngCompression"))->IntegerValue(); + if (options->Has(NanNew("pngCompression"))) { + int compression = options->Get(NanNew("pngCompression"))->IntegerValue(); params.push_back(CV_IMWRITE_PNG_COMPRESSION); params.push_back(compression); } @@ -486,131 +466,113 @@ Matrix::ToBuffer(const v8::Arguments& args){ std::vector vec(0); - // We use operator * before the "ext" variable, because it converts v8::String::AsciiValue to char * + cv::imencode(ext, self->mat, vec, params); - node::Buffer *buf = node::Buffer::New(vec.size()); - uchar* data = (uchar*) Buffer::Data(buf); - memcpy(data, &vec[0], vec.size()); - - v8::Local globalObj = v8::Context::GetCurrent()->Global(); - v8::Local bufferConstructor = v8::Local::Cast(globalObj->Get(v8::String::New("Buffer"))); - v8::Handle constructorArgs[3] = {buf->handle_, v8::Integer::New(vec.size()), v8::Integer::New(0)}; + Local buf = NanNewBufferHandle(vec.size()); + uchar* data = (uchar*) Buffer::Data(buf); + memcpy(data, &vec[0], vec.size()); + + v8::Local globalObj = NanGetCurrentContext()->Global(); + v8::Local bufferConstructor = v8::Local::Cast(globalObj->Get(NanNew("Buffer"))); + v8::Handle constructorArgs[3] = {buf, NanNew(vec.size()), NanNew(0)}; v8::Local actualBuffer = bufferConstructor->NewInstance(3, constructorArgs); - return scope.Close(actualBuffer); + NanReturnValue(actualBuffer); } -struct matrixToBuffer_baton_t { - Matrix *mm; - Persistent cb; - std::vector res; - std::vector params; +class AsyncToBufferWorker : public NanAsyncWorker { + public: + AsyncToBufferWorker(NanCallback *callback, Matrix* matrix, string ext, vector params ) + : NanAsyncWorker(callback), matrix(matrix), ext(ext), params(params) {} + ~AsyncToBufferWorker() {} + + void Execute () { + std::vector vec(0); + + //std::vector params(0);//CV_IMWRITE_JPEG_QUALITY 90 + + cv::imencode(ext, this->matrix->mat, vec, this->params); + + res = vec; + } + + void HandleOKCallback () { + NanScope(); + + Local buf = NanNewBufferHandle(res.size()); + uchar* data = (uchar*) Buffer::Data(buf); + memcpy(data, &res[0], res.size()); + + v8::Local globalObj = NanGetCurrentContext()->Global(); + v8::Local bufferConstructor = v8::Local::Cast(globalObj->Get(NanNew("Buffer"))); + v8::Handle constructorArgs[3] = {buf, NanNew(res.size()), NanNew(0)}; + v8::Local actualBuffer = bufferConstructor->NewInstance(3, constructorArgs); + + + Local argv[] = { + NanNull() + , actualBuffer + }; + + TryCatch try_catch; + callback->Call(2, argv); + if (try_catch.HasCaught()) { + FatalException(try_catch); + } + + } + + private: + Matrix* matrix; std::string ext; - uv_work_t request; + std::vector params; + std::vector res; }; -void AsyncToBufferAsync(uv_work_t *req); -void AfterAsyncToBufferAsync(uv_work_t *req); -Handle -Matrix::ToBufferAsync(const v8::Arguments& args){ +NAN_METHOD(Matrix::ToBufferAsync){ SETUP_FUNCTION(Matrix) REQ_FUN_ARG(0, cb); - - matrixToBuffer_baton_t *baton = new matrixToBuffer_baton_t(); - - std::string ext = std::string(".jpg"); + std::vector params; + // See if the options argument is passed if ((args.Length() > 1) && (args[1]->IsObject())) { // Get this options argument v8::Handle options = v8::Handle::Cast(args[1]); // If the extension (image format) is provided - if (options->Has(v8::String::New("ext"))) { - v8::String::Utf8Value str ( options->Get(v8::String::New("ext"))->ToString() ); + if (options->Has(NanNew("ext"))) { + v8::String::Utf8Value str ( options->Get(NanNew("ext"))->ToString() ); std::string str2 = std::string(*str); ext = str2; } - if (options->Has(v8::String::New("jpegQuality"))) { - int compression = options->Get(v8::String::New("jpegQuality"))->IntegerValue(); - baton->params.push_back(CV_IMWRITE_JPEG_QUALITY); - baton->params.push_back(compression); - } - if (options->Has(v8::String::New("pngCompression"))) { - int compression = options->Get(v8::String::New("pngCompression"))->IntegerValue(); - baton->params.push_back(CV_IMWRITE_PNG_COMPRESSION); - baton->params.push_back(compression); + if (options->Has(NanNew("jpegQuality"))) { + int compression = options->Get(NanNew("jpegQuality"))->IntegerValue(); + params.push_back(CV_IMWRITE_JPEG_QUALITY); + params.push_back(compression); } + if (options->Has(NanNew("pngCompression"))) { + int compression = options->Get(NanNew("pngCompression"))->IntegerValue(); + params.push_back(CV_IMWRITE_PNG_COMPRESSION); + params.push_back(compression); + } } - baton->ext = ext; - baton->mm = self; - baton->cb = Persistent::New(cb); - baton->request.data = baton; + + NanCallback *callback = new NanCallback(cb.As()); - uv_queue_work(uv_default_loop(), &baton->request, AsyncToBufferAsync, (uv_after_work_cb)AfterAsyncToBufferAsync); - - return Undefined(); -} - -void AsyncToBufferAsync(uv_work_t *req) { - matrixToBuffer_baton_t *baton = static_cast(req->data); - - std::vector vec(0); - //std::vector params(0);//CV_IMWRITE_JPEG_QUALITY 90 - - const char * ext = (const char *) baton->ext.c_str(); - cv::imencode(ext, baton->mm->mat, vec, baton->params); - - - baton->res = vec; -} - -void AfterAsyncToBufferAsync(uv_work_t *req) { - - HandleScope scope; - matrixToBuffer_baton_t *baton = static_cast(req->data); -// ev_unref(EV_DEFAULT_UC); -// baton->cc->Unref(); - - Local argv[2]; - - argv[0] = Local::New(Null()); - - node::Buffer *buf = node::Buffer::New(baton->res.size()); - uchar* data = (uchar*) Buffer::Data(buf); - memcpy(data, &baton->res[0], baton->res.size()); - - v8::Local globalObj = v8::Context::GetCurrent()->Global(); - v8::Local bufferConstructor = v8::Local::Cast(globalObj->Get(v8::String::New("Buffer"))); - v8::Handle constructorArgs[3] = {buf->handle_, v8::Integer::New(baton->res.size()), v8::Integer::New(0)}; - v8::Local actualBuffer = bufferConstructor->NewInstance(3, constructorArgs); - - argv[1] = actualBuffer; - - TryCatch try_catch; - - baton->cb->Call(Context::GetCurrent()->Global(), 2, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - baton->cb.Dispose(); - - delete baton; - -// return 0; + NanAsyncQueueWorker(new AsyncToBufferWorker(callback, self, ext, params)); + + NanReturnUndefined(); } -Handle -Matrix::Ellipse(const v8::Arguments& args){ +NAN_METHOD(Matrix::Ellipse){ SETUP_FUNCTION(Matrix) int x = 0; @@ -627,36 +589,36 @@ Matrix::Ellipse(const v8::Arguments& args){ if(args[0]->IsObject()) { v8::Handle options = v8::Handle::Cast(args[0]); - if (options->Has(v8::String::New("center"))) { - Local center = options->Get(v8::String::NewSymbol("center"))->ToObject(); - x = center->Get(v8::String::NewSymbol("x"))->Uint32Value(); - y = center->Get(v8::String::NewSymbol("y"))->Uint32Value(); + if (options->Has(NanNew("center"))) { + Local center = options->Get(NanNew("center"))->ToObject(); + x = center->Get(NanNew("x"))->Uint32Value(); + y = center->Get(NanNew("y"))->Uint32Value(); } - if (options->Has(v8::String::New("axes"))) { - Local axes = options->Get(v8::String::NewSymbol("axes"))->ToObject(); - width = axes->Get(v8::String::NewSymbol("width"))->Uint32Value(); - height = axes->Get(v8::String::NewSymbol("height"))->Uint32Value(); + if (options->Has(NanNew("axes"))) { + Local axes = options->Get(NanNew("axes"))->ToObject(); + width = axes->Get(NanNew("width"))->Uint32Value(); + height = axes->Get(NanNew("height"))->Uint32Value(); } - if (options->Has(v8::String::New("thickness"))) { - thickness = options->Get(v8::String::NewSymbol("thickness"))->Uint32Value(); + if (options->Has(NanNew("thickness"))) { + thickness = options->Get(NanNew("thickness"))->Uint32Value(); } - if (options->Has(v8::String::New("angle"))) { - angle = options->Get(v8::String::NewSymbol("angle"))->NumberValue(); + if (options->Has(NanNew("angle"))) { + angle = options->Get(NanNew("angle"))->NumberValue(); } - if (options->Has(v8::String::New("startAngle"))) { - startAngle = options->Get(v8::String::NewSymbol("startAngle"))->NumberValue(); + if (options->Has(NanNew("startAngle"))) { + startAngle = options->Get(NanNew("startAngle"))->NumberValue(); } - if (options->Has(v8::String::New("endAngle"))) { - endAngle = options->Get(v8::String::NewSymbol("endAngle"))->NumberValue(); + if (options->Has(NanNew("endAngle"))) { + endAngle = options->Get(NanNew("endAngle"))->NumberValue(); } - if (options->Has(v8::String::New("lineType"))) { - lineType = options->Get(v8::String::NewSymbol("lineType"))->Uint32Value(); + if (options->Has(NanNew("lineType"))) { + lineType = options->Get(NanNew("lineType"))->Uint32Value(); } - if (options->Has(v8::String::New("shift"))) { - shift = options->Get(v8::String::NewSymbol("shift"))->Uint32Value(); + if (options->Has(NanNew("shift"))) { + shift = options->Get(NanNew("shift"))->Uint32Value(); } - if (options->Has(v8::String::New("color"))) { - Local objColor = options->Get(v8::String::NewSymbol("color"))->ToObject(); + if (options->Has(NanNew("color"))) { + Local objColor = options->Get(NanNew("color"))->ToObject(); color = setColor(objColor); } } else { @@ -675,13 +637,12 @@ Matrix::Ellipse(const v8::Arguments& args){ } cv::ellipse(self->mat, cv::Point(x, y), cv::Size(width, height), angle, startAngle, endAngle, color, thickness, lineType, shift); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::Rectangle(const Arguments& args) { +NAN_METHOD(Matrix::Rectangle) { SETUP_FUNCTION(Matrix) @@ -710,11 +671,10 @@ Matrix::Rectangle(const Arguments& args) { cv::rectangle(self->mat, cv::Point(x, y), cv::Point(x+width, y+height), color, thickness); } - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::Line(const Arguments& args) { +NAN_METHOD(Matrix::Line) { SETUP_FUNCTION(Matrix) @@ -743,11 +703,11 @@ Matrix::Line(const Arguments& args) { cv::line(self->mat, cv::Point(x1, y1), cv::Point(x2, y2), color, thickness); } - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::Save(const v8::Arguments& args) { + +NAN_METHOD(Matrix::Save) { SETUP_FUNCTION(Matrix) if (args.Length() > 1) { @@ -755,75 +715,69 @@ Matrix::Save(const v8::Arguments& args) { } if (!args[0]->IsString()) - return v8::ThrowException(v8::Exception::TypeError(String::New("filename required"))); + NanThrowTypeError("filename required"); - String::AsciiValue filename(args[0]); + NanAsciiString filename(args[0]); int res = cv::imwrite(*filename, self->mat); - return scope.Close(Number::New(res)); + NanReturnValue(NanNew(res)); } -struct save_baton_t { - Matrix *mm; - Persistent cb; - std::string filename; - int res; - uv_work_t request; +//All this is for async save, see here for nan example: https://github.com/rvagg/nan/blob/c579ae858ae3208d7e702e8400042ba9d48fa64b/examples/async_pi_estimate/async.cc +class AsyncSaveWorker : public NanAsyncWorker { + public: + AsyncSaveWorker(NanCallback *callback, Matrix* matrix, char* filename) + : NanAsyncWorker(callback), matrix(matrix), filename(filename) {} + ~AsyncSaveWorker() {} + + // Executed inside the worker-thread. + // It is not safe to access V8, or V8 data structures + // here, so everything we need for input and output + // should go on `this`. + void Execute () { + res = cv::imwrite(this->filename, this->matrix->mat); + } + + // Executed when the async work is complete + // this function will be run inside the main event loop + // so it is safe to use V8 again + void HandleOKCallback () { + NanScope(); + + Local argv[] = { + NanNull() + , NanNew(res) + }; + + TryCatch try_catch; + callback->Call(2, argv); + if (try_catch.HasCaught()) { + FatalException(try_catch); + } + } + + private: + Matrix* matrix; + char* filename; + int res; }; -void DoSaveAsync(uv_work_t *req); -void AfterSaveAsync(uv_work_t *req); -Handle -Matrix::SaveAsync(const v8::Arguments& args){ + +NAN_METHOD(Matrix::SaveAsync){ SETUP_FUNCTION(Matrix) if (!args[0]->IsString()) - return v8::ThrowException(v8::Exception::TypeError(String::New("filename required"))); + NanThrowTypeError("filename required"); - String::AsciiValue filename(args[0]); + NanAsciiString filename(args[0]); REQ_FUN_ARG(1, cb); + + NanCallback *callback = new NanCallback(cb.As()); + NanAsyncQueueWorker(new AsyncSaveWorker(callback, self, *filename)); - save_baton_t *baton = new save_baton_t(); - baton->mm = self; - baton->cb = Persistent::New(cb); - baton->filename = *filename; - baton->request.data = baton; - - uv_queue_work(uv_default_loop(), &baton->request, DoSaveAsync, (uv_after_work_cb)AfterSaveAsync); - - return Undefined(); -} - - -void DoSaveAsync(uv_work_t *req) { - save_baton_t *baton = static_cast(req->data); - - int res = cv::imwrite(baton->filename.c_str(), baton->mm->mat); - baton->res = res; -} - -void AfterSaveAsync(uv_work_t *req) { - HandleScope scope; - save_baton_t *baton = static_cast(req->data); - - Local argv[2]; // (err, result) - - argv[0] = Local::New(Null()); - argv[1] = Number::New(baton->res); - - TryCatch try_catch; - - baton->cb->Call(Context::GetCurrent()->Global(), 2, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - baton->cb.Dispose(); - - delete baton; + NanReturnUndefined(); } Handle @@ -858,29 +812,27 @@ Matrix::Ones(const v8::Arguments& args){ return scope.Close(im_h); } -Handle -Matrix::Eye(const v8::Arguments& args){ - HandleScope scope; +NAN_METHOD(Matrix::Eye){ + NanScope(); int w = args[0]->Uint32Value(); int h = args[1]->Uint32Value(); int type = (args.Length() > 2) ? args[2]->IntegerValue() : CV_64FC1; - Local im_h = Matrix::constructor->GetFunction()->NewInstance(); + Local im_h = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(im_h); cv::Mat mat = cv::Mat::eye(w, h, type); img->mat = mat; - return scope.Close(im_h); + NanReturnValue(im_h); } -Handle -Matrix::ConvertGrayscale(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::ConvertGrayscale) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); if(self->mat.channels() != 3) - return v8::ThrowException(String::New("Image is no 3-channel")); + NanThrowError("Image is no 3-channel"); cv::Mat gray; @@ -888,32 +840,30 @@ Matrix::ConvertGrayscale(const v8::Arguments& args) { gray.copyTo(self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::ConvertHSVscale(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::ConvertHSVscale) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); if(self->mat.channels() != 3) - return v8::ThrowException(String::New("Image is no 3-channel")); + NanThrowError("Image is no 3-channel"); cv::Mat hsv; cv::cvtColor(self->mat, hsv, CV_BGR2HSV); hsv.copyTo(self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::GaussianBlur(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::GaussianBlur) { + NanScope(); cv::Size ksize; - cv::Mat blurred; + cv::Mat blurred; Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -922,16 +872,14 @@ Matrix::GaussianBlur(const v8::Arguments& args) { } else { if(!args[0]->IsArray()) { - return ThrowException(Exception::TypeError(String::New( - "'ksize' argument must be a 2 double array"))); + NanThrowTypeError("'ksize' argument must be a 2 double array"); } Local array = args[0]->ToObject(); // TODO: Length check Local x = array->Get(0); Local y = array->Get(1); if(!x->IsNumber() || !y->IsNumber()) { - return ThrowException(Exception::TypeError(String::New( - "'ksize' argument must be a 2 double array"))); + NanThrowTypeError("'ksize' argument must be a 2 double array"); } ksize = cv::Size(x->NumberValue(), y->NumberValue()); } @@ -939,13 +887,12 @@ Matrix::GaussianBlur(const v8::Arguments& args) { cv::GaussianBlur(self->mat, blurred, ksize, 0); blurred.copyTo(self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::MedianBlur(const v8::Arguments &args) { - HandleScope scope; +NAN_METHOD(Matrix::MedianBlur) { + NanScope(); cv::Mat blurred; int ksize = 3; Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -953,24 +900,21 @@ Matrix::MedianBlur(const v8::Arguments &args) { if (args[0]->IsNumber()) { ksize = args[0]->IntegerValue(); if ((ksize % 2) == 0) { - return ThrowException(Exception::TypeError(String::New( - "'ksize' argument must be a positive odd integer"))); + NanThrowTypeError("'ksize' argument must be a positive odd integer"); } } else { - return ThrowException(Exception::TypeError(String::New( - "'ksize' argument must be a positive odd integer"))); + NanThrowTypeError("'ksize' argument must be a positive odd integer"); } cv::medianBlur(self->mat, blurred, ksize); blurred.copyTo(self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::BilateralFilter(const v8::Arguments &args) { - HandleScope scope; +NAN_METHOD(Matrix::BilateralFilter) { + NanScope(); cv::Mat filtered; int d = 15; double sigmaColor = 80; @@ -981,8 +925,7 @@ Matrix::BilateralFilter(const v8::Arguments &args) { if (args.Length() != 0) { if (args.Length() < 3 || args.Length() > 4) { - return ThrowException(Exception::TypeError(String::New( - "BilateralFilter takes 0, 3, or 4 arguments"))); + NanThrowTypeError("BilateralFilter takes 0, 3, or 4 arguments"); } else { d = args[0]->IntegerValue(); sigmaColor = args[1]->NumberValue(); @@ -996,58 +939,53 @@ Matrix::BilateralFilter(const v8::Arguments &args) { cv::bilateralFilter(self->mat, filtered, d, sigmaColor, sigmaSpace, borderType); filtered.copyTo(self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::Copy(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Copy) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); - Local img_to_return = Matrix::constructor->GetFunction()->NewInstance(); + Local img_to_return = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(img_to_return); self->mat.copyTo(img->mat); - return scope.Close(img_to_return); + NanReturnValue(img_to_return); } -Handle -Matrix::Flip(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Flip) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); if ( args.Length() < 1 || !args[0]->IsInt32() ) { - return v8::ThrowException(Exception::TypeError(String::New( - "Flip requires an integer flipCode argument (0 = X axis, positive = Y axis, negative = both axis)"))); + NanThrowTypeError("Flip requires an integer flipCode argument (0 = X axis, positive = Y axis, negative = both axis)"); } int flipCode = args[0]->ToInt32()->Value(); - Local img_to_return = Matrix::constructor->GetFunction()->NewInstance(); + Local img_to_return = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(img_to_return); cv::flip(self->mat, img->mat, flipCode); - return scope.Close(img_to_return); + NanReturnValue(img_to_return); } -Handle -Matrix::ROI(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::ROI) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); if ( args.Length() != 4 ) { - return v8::ThrowException(Exception::TypeError(String::New( - "ROI requires x,y,w,h arguments"))); + NanThrowTypeError("ROI requires x,y,w,h arguments"); } // although it's an image to return, it is in fact a pointer to ROI of parent matrix - Local img_to_return = Matrix::constructor->GetFunction()->NewInstance(); + Local img_to_return = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(img_to_return); int x = args[0]->IntegerValue(); @@ -1058,32 +996,27 @@ Matrix::ROI(const v8::Arguments& args) { cv::Mat roi(self->mat, cv::Rect(x,y,w,h)); img->mat = roi; - return scope.Close(img_to_return); + NanReturnValue(img_to_return); } -Handle -Matrix::Ptr(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Ptr) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); int line = args[0]->Uint32Value(); - char* data = self->mat.ptr(line); //uchar* data = self->mat.data; /* char *mydata = "Random raw data\0"; */ - node::Buffer *return_buffer = Buffer::New((char *)data, self->mat.step); - return scope.Close( return_buffer->handle_ ); - -// return Undefined(); + Local return_buffer = NanNewBufferHandle((char*)data, self->mat.step); + NanReturnValue( return_buffer ); +// NanReturnUndefined(); } - -Handle -Matrix::AbsDiff(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::AbsDiff) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -1092,12 +1025,11 @@ Matrix::AbsDiff(const v8::Arguments& args) { cv::absdiff(src1->mat, src2->mat, self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::AddWeighted(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::AddWeighted) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -1111,12 +1043,11 @@ Matrix::AddWeighted(const v8::Arguments& args) { cv::addWeighted(src1->mat, alpha, src2->mat, beta, gamma, self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::BitwiseXor(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::BitwiseXor) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -1125,12 +1056,11 @@ Matrix::BitwiseXor(const v8::Arguments& args) { cv::bitwise_xor(src1->mat, src2->mat, self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::BitwiseNot(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::BitwiseNot) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -1138,12 +1068,11 @@ Matrix::BitwiseNot(const v8::Arguments& args) { cv::bitwise_not(self->mat, dst->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::BitwiseAnd(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::BitwiseAnd) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -1152,32 +1081,29 @@ Matrix::BitwiseAnd(const v8::Arguments& args) { cv::bitwise_and(src1->mat, src2->mat, self->mat); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::CountNonZero(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::CountNonZero) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); double count = (double)cv::countNonZero(self->mat); - return scope.Close(v8::Number::New(count)); + NanReturnValue(NanNew(count)); } -/*Handle -Matrix::Split(const v8::Arguments& args) { - HandleScope scope; +/*NAN_METHOD(Matrix::Split) { + NanScope(); //Matrix *self = ObjectWrap::Unwrap(args.This()); - return scope.Close(v8::Null()); + NanReturnNull(); }*/ -Handle -Matrix::Canny(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Canny) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); int lowThresh = args[0]->NumberValue(); @@ -1185,37 +1111,35 @@ Matrix::Canny(const v8::Arguments& args) { cv::Canny(self->mat, self->mat, lowThresh, highThresh); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::Dilate(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Dilate) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); int niters = args[0]->NumberValue(); cv::dilate(self->mat, self->mat, cv::Mat(), cv::Point(-1, -1), niters); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::Erode(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Erode) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); int niters = args[0]->NumberValue(); cv::erode(self->mat, self->mat, cv::Mat(), cv::Point(-1, -1), niters); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::FindContours(const v8::Arguments& args) { - SETUP_FUNCTION(Matrix) + +NAN_METHOD(Matrix::FindContours) { + NanScope(); int mode = CV_RETR_LIST; int chain = CV_CHAIN_APPROX_SIMPLE; @@ -1228,17 +1152,17 @@ Matrix::FindContours(const v8::Arguments& args) { if (args[1]->IsNumber()) chain = args[1]->IntegerValue(); } - Local conts_to_return = Contour::constructor->GetFunction()->NewInstance(); - Contour *contours = ObjectWrap::Unwrap(conts_to_return); + Local conts_to_return= NanNew(Contour::constructor)->GetFunction()->NewInstance(); + Contour *contours = ObjectWrap::Unwrap(conts_to_return); - cv::findContours(self->mat, contours->contours, contours->hierarchy, mode, chain); + NanReturnValue(conts_to_return); - return scope.Close(conts_to_return); + return scope.Close(conts_to_return); } -Handle -Matrix::DrawContour(const v8::Arguments& args) { - HandleScope scope; + +NAN_METHOD(Matrix::DrawContour) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); Contour *cont = ObjectWrap::Unwrap(args[0]->ToObject()); @@ -1255,13 +1179,12 @@ Matrix::DrawContour(const v8::Arguments& args) { cv::drawContours(self->mat, cont->contours, pos, color, thickness); - return Undefined(); + NanReturnUndefined(); } -Handle -Matrix::DrawAllContours(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::DrawAllContours) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); Contour *cont = ObjectWrap::Unwrap(args[0]->ToObject()); @@ -1278,12 +1201,12 @@ Matrix::DrawAllContours(const v8::Arguments& args) { cv::drawContours(self->mat, cont->contours, -1, color, thickness); - return Undefined(); + NanReturnUndefined(); } -Handle -Matrix::GoodFeaturesToTrack(const v8::Arguments& args) { - HandleScope scope; + +NAN_METHOD(Matrix::GoodFeaturesToTrack) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); std::vector corners; @@ -1295,23 +1218,23 @@ Matrix::GoodFeaturesToTrack(const v8::Arguments& args) { cv::goodFeaturesToTrack(gray, corners, 500, 0.01, 10); - v8::Local arr = v8::Array::New(corners.size()); + v8::Local arr = NanNew(corners.size()); for (unsigned int i=0; i pt = v8::Array::New(2); - pt->Set(0, Number::New((double) corners[i].x)); - pt->Set(1, Number::New((double) corners[i].y)); + v8::Local pt = NanNew(2); + pt->Set(0, NanNew((double) corners[i].x)); + pt->Set(1, NanNew((double) corners[i].y)); arr->Set(i, pt); } - return scope.Close(arr); + NanReturnValue(arr); } -Handle -Matrix::HoughLinesP(const v8::Arguments& args) { - HandleScope scope; + +NAN_METHOD(Matrix::HoughLinesP) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); double rho = args.Length() < 1 ? 1 : args[0]->NumberValue(); @@ -1328,19 +1251,19 @@ Matrix::HoughLinesP(const v8::Arguments& args) { // cv::Canny(gray, gray, 50, 200, 3); cv::HoughLinesP(gray, lines, rho, theta, threshold, minLineLength, maxLineGap); - v8::Local arr = v8::Array::New(lines.size()); + v8::Local arr = NanNew(lines.size()); for (unsigned int i=0; i pt = v8::Array::New(4); - pt->Set(0, Number::New((double) lines[i][0])); - pt->Set(1, Number::New((double) lines[i][1])); - pt->Set(2, Number::New((double) lines[i][2])); - pt->Set(3, Number::New((double) lines[i][3])); + v8::Local pt = NanNew(4); + pt->Set(0, NanNew((double) lines[i][0])); + pt->Set(1, NanNew((double) lines[i][1])); + pt->Set(2, NanNew((double) lines[i][2])); + pt->Set(3, NanNew((double) lines[i][3])); arr->Set(i, pt); } - return scope.Close(arr); + NanReturnValue(arr); } @@ -1380,9 +1303,8 @@ cv::Rect* setRect(Local objRect) { } -Handle -Matrix::Resize(const v8::Arguments& args){ - HandleScope scope; +NAN_METHOD(Matrix::Resize){ + NanScope(); int x = args[0]->Uint32Value(); int y = args[1]->Uint32Value(); @@ -1402,13 +1324,12 @@ Matrix::Resize(const v8::Arguments& args){ self->mat = res; - return scope.Close(Undefined()); + NanReturnUndefined(); } -Handle -Matrix::Rotate(const v8::Arguments& args){ - HandleScope scope; +NAN_METHOD(Matrix::Rotate){ + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); cv::Mat rotMatrix(2, 3, CV_32FC1); @@ -1424,7 +1345,7 @@ Matrix::Rotate(const v8::Arguments& args){ && (args.Length() == 1); if (rightOrStraight) { int angle2 = ((int)angle) % 360; - if (!angle2) { return scope.Close(Undefined()); } + if (!angle2) { NanReturnUndefined(); } if (angle2 < 0) { angle2 += 360; } // See if we do right angle rotation, we transpose the matrix: if (angle2 % 180) { @@ -1439,8 +1360,7 @@ Matrix::Rotate(const v8::Arguments& args){ // If clockwise, flip around the y-axis if (angle2 == 270) { mode = 1; } cv::flip(self->mat, self->mat, mode); - - return scope.Close(Undefined()); + NanReturnUndefined(); } //------------- @@ -1454,32 +1374,29 @@ Matrix::Rotate(const v8::Arguments& args){ ~self->mat; self->mat = res; - return scope.Close(Undefined()); + NanReturnUndefined(); } -Handle -Matrix::PyrDown(const v8::Arguments& args){ +NAN_METHOD(Matrix::PyrDown){ SETUP_FUNCTION(Matrix) cv::pyrDown(self->mat, self->mat); - return scope.Close(v8::Undefined()); + NanReturnUndefined(); } -Handle -Matrix::PyrUp(const v8::Arguments& args){ +NAN_METHOD(Matrix::PyrUp){ SETUP_FUNCTION(Matrix) cv::pyrUp(self->mat, self->mat); - return scope.Close(v8::Undefined()); + NanReturnUndefined(); } -Handle -Matrix::inRange(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::inRange) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); /*if(self->mat.channels() != 3) - return v8::ThrowException(String::New("Image is no 3-channel"));*/ + NanThrowError(String::New("Image is no 3-channel"));*/ if(args[0]->IsArray() && args[1]->IsArray()) { Local args_lowerb = args[0]->ToObject(); @@ -1497,11 +1414,10 @@ Matrix::inRange(const v8::Arguments& args) { } - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::AdjustROI(const v8::Arguments& args) { +NAN_METHOD(Matrix::AdjustROI) { SETUP_FUNCTION(Matrix) int dtop = args[0]->Uint32Value(); int dbottom = args[1]->Uint32Value(); @@ -1510,12 +1426,11 @@ Matrix::AdjustROI(const v8::Arguments& args) { self->mat.adjustROI(dtop, dbottom, dleft, dright); - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::LocateROI(const v8::Arguments& args) { +NAN_METHOD(Matrix::LocateROI) { SETUP_FUNCTION(Matrix) cv::Size wholeSize; @@ -1523,17 +1438,18 @@ Matrix::LocateROI(const v8::Arguments& args) { self->mat.locateROI(wholeSize, ofs); - v8::Local arr = v8::Array::New(4); - arr->Set(0, Number::New(wholeSize.width)); - arr->Set(1, Number::New(wholeSize.height)); - arr->Set(2, Number::New(ofs.x)); - arr->Set(3, Number::New(ofs.y)); + v8::Local arr = NanNew(4); + arr->Set(0, NanNew(wholeSize.width)); + arr->Set(1, NanNew(wholeSize.height)); + arr->Set(2, NanNew(ofs.x)); + arr->Set(3, NanNew(ofs.y)); - return scope.Close(arr); + NanReturnValue(arr); } -Handle -Matrix::Threshold(const v8::Arguments& args) { + + +NAN_METHOD(Matrix::Threshold) { SETUP_FUNCTION(Matrix) double threshold = args[0]->NumberValue(); @@ -1542,7 +1458,7 @@ Matrix::Threshold(const v8::Arguments& args) { int typ = cv::THRESH_BINARY; if (args.Length() == 3){ // typ = args[2]->IntegerValue(); - String::AsciiValue typstr(args[2]); + NanAsciiString typstr(args[2]); if (strcmp(*typstr, "Binary") == 0){ typ=0; } @@ -1561,18 +1477,16 @@ Matrix::Threshold(const v8::Arguments& args) { } - - Local img_to_return = Matrix::constructor->GetFunction()->NewInstance(); + Local img_to_return = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(img_to_return); self->mat.copyTo(img->mat); cv::threshold(self->mat, img->mat, threshold, maxVal, typ); - return scope.Close(img_to_return); + NanReturnValue(img_to_return); } -Handle -Matrix::AdaptiveThreshold(const v8::Arguments& args) { +NAN_METHOD(Matrix::AdaptiveThreshold) { SETUP_FUNCTION(Matrix) double maxVal = args[0]->NumberValue(); @@ -1581,32 +1495,31 @@ Matrix::AdaptiveThreshold(const v8::Arguments& args) { double blockSize = args[3]->NumberValue(); double C = args[4]->NumberValue(); - Local img_to_return = Matrix::constructor->GetFunction()->NewInstance(); + Local img_to_return = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(img_to_return); self->mat.copyTo(img->mat); cv::adaptiveThreshold(self->mat, img->mat, maxVal, adaptiveMethod, thresholdType, blockSize, C); - return scope.Close(img_to_return); + NanReturnValue(img_to_return); } -Handle -Matrix::MeanStdDev(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::MeanStdDev) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); - Local mean = Matrix::constructor->GetFunction()->NewInstance(); + Local mean = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *m_mean = ObjectWrap::Unwrap(mean); - Local stddev = Matrix::constructor->GetFunction()->NewInstance(); + Local stddev = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *m_stddev = ObjectWrap::Unwrap(stddev); cv::meanStdDev(self->mat, m_mean->mat, m_stddev->mat); - Local data = Object::New(); - data->Set(String::NewSymbol("mean"), mean); - data->Set(String::NewSymbol("stddev"), stddev); - return scope.Close(data); + Local data = NanNew(); + data->Set(NanNew("mean"), mean); + data->Set(NanNew("stddev"), stddev); + NanReturnValue(data); } @@ -1619,9 +1532,8 @@ Matrix::MeanStdDev(const v8::Arguments& args) { // Note, x,y and width and height of our image must be so that // our.width + x <= destination.width (and the same for y and height) // both x and y must be >= 0 -Handle -Matrix::CopyTo(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::CopyTo) { + NanScope(); Matrix * self = ObjectWrap::Unwrap(args.This()); int width = self->mat.size().width; @@ -1637,7 +1549,7 @@ Matrix::CopyTo(const v8::Arguments& args) { cv::Mat dstROI = cv::Mat(dest->mat, cv::Rect(x, y, width, height)); self->mat.copyTo(dstROI); - return scope.Close(Undefined()); + NanReturnUndefined(); } @@ -1645,9 +1557,8 @@ Matrix::CopyTo(const v8::Arguments& args) { // @author SergeMv // Does in-place color transformation // img.cvtColor('CV_BGR2YCrCb'); -Handle -Matrix::CvtColor(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::CvtColor) { + NanScope(); Matrix * self = ObjectWrap::Unwrap(args.This()); @@ -1683,21 +1594,19 @@ Matrix::CvtColor(const v8::Arguments& args) { else if (!strcmp(sTransform, "CV_BayerGR2BGR")) { iTransform = CV_BayerGR2BGR; } else { iTransform = 0; // to avoid compiler warning - return v8::ThrowException(Exception::TypeError(String::New( - "Conversion code is unsupported"))); + NanThrowTypeError("Conversion code is unsupported"); } cv::cvtColor(self->mat, self->mat, iTransform); - return scope.Close(Undefined()); + NanReturnUndefined(); } // @author SergeMv // arrChannels = img.split(); -Handle -Matrix::Split(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Split) { + NanScope(); Matrix * self = ObjectWrap::Unwrap(args.This()); @@ -1710,29 +1619,27 @@ Matrix::Split(const v8::Arguments& args) { } cv::split(self->mat, channels); - - v8::Local arrChannels = v8::Array::New(size); + unsigned int size = channels.size(); + v8::Local arrChannels = NanNew(size); for (unsigned int i = 0; i < size; i++) { - Local matObject = Matrix::constructor->GetFunction()->NewInstance(); + Local matObject = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix * m = ObjectWrap::Unwrap(matObject); m->mat = channels[i]; arrChannels->Set(i, matObject); } - return scope.Close(arrChannels); + NanReturnValue(arrChannels); } // @author SergeMv // img.merge(arrChannels); -Handle -Matrix::Merge(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::Merge) { + NanScope(); Matrix * self = ObjectWrap::Unwrap(args.This()); if (!args[0]->IsArray()) { - return v8::ThrowException(Exception::TypeError(String::New( - "The argument must be an array"))); + NanThrowTypeError("The argument must be an array"); } v8::Handle jsChannels = v8::Handle::Cast(args[0]); @@ -1744,28 +1651,25 @@ Matrix::Merge(const v8::Arguments& args) { } cv::merge(vChannels, self->mat); - return scope.Close(Undefined()); + NanReturnUndefined(); } // @author SergeMv // Equalizes histogram // img.equalizeHist() -Handle -Matrix::EqualizeHist(const v8::Arguments& args) { - HandleScope scope; - +NAN_METHOD(Matrix::EqualizeHist) { + NanScope(); Matrix * self = ObjectWrap::Unwrap(args.This()); cv::equalizeHist(self->mat, self->mat); - return scope.Close(Undefined()); + NanReturnUndefined(); } -Handle -Matrix::FloodFill(const Arguments& args){ +NAN_METHOD(Matrix::FloodFill){ SETUP_FUNCTION(Matrix) - //obj->Get(v8::String::NewSymbol("x")) + //obj->Get(NanNew("x")) //int cv::floodFill(cv::InputOutputArray, cv::Point, cv::Scalar, cv::Rect*, cv::Scalar, cv::Scalar, int) @@ -1784,22 +1688,35 @@ Matrix::FloodFill(const Arguments& args){ Local obj = args[0]->ToObject(); - int ret = cv::floodFill(self->mat, setPoint(obj->Get(v8::String::NewSymbol("seedPoint"))->ToObject()) - , setColor(obj->Get(v8::String::NewSymbol("newColor"))->ToObject()) - , obj->Get(v8::String::NewSymbol("rect"))->IsUndefined() ? 0 : setRect(obj->Get(v8::String::NewSymbol("rect"))->ToObject()) - , setColor(obj->Get(v8::String::NewSymbol("loDiff"))->ToObject()) - , setColor(obj->Get(v8::String::NewSymbol("upDiff"))->ToObject()) + int ret = cv::floodFill(self->mat, setPoint(obj->Get(NanNew("seedPoint"))->ToObject()) + , setColor(obj->Get(NanNew("newColor"))->ToObject()) + , obj->Get(NanNew("rect"))->IsUndefined() ? 0 : setRect(obj->Get(NanNew("rect"))->ToObject()) + , setColor(obj->Get(NanNew("loDiff"))->ToObject()) + , setColor(obj->Get(NanNew("upDiff"))->ToObject()) , 4 ); - return scope.Close(Number::New( ret )); + NanReturnValue(NanNew( ret )); } // @author ytham // Match Template filter -// Usage: output = input.matchTemplate(templateMatrix, method); -Handle -Matrix::MatchTemplate(const v8::Arguments& args) { +// Usage: output = input.matchTemplate("templateFileString", method); +NAN_METHOD(Matrix::MatchTemplate) { + NanScope(); + + Matrix *self = ObjectWrap::Unwrap(args.This()); + + v8::String::Utf8Value args0(args[0]->ToString()); + std::string filename = std::string(*args0); + cv::Mat templ; + templ = cv::imread(filename, CV_8S); + + Local out = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *m_out = ObjectWrap::Unwrap(out); + int cols = self->mat.cols - templ.cols + 1; + int rows = self->mat.rows - templ.rows + 1; + m_out->mat.create(cols, rows, CV_32FC1); /* TM_SQDIFF =0 @@ -1810,29 +1727,17 @@ Matrix::MatchTemplate(const v8::Arguments& args) { TM_CCOEFF_NORMED =5 */ - HandleScope scope; - - Matrix *self = ObjectWrap::Unwrap(args.This()); - Matrix *templ = ObjectWrap::Unwrap(args[0]->ToObject()); - - Local out = Matrix::constructor->GetFunction()->NewInstance(); - Matrix *m_out = ObjectWrap::Unwrap(out); - int cols = self->mat.cols - templ->mat.cols + 1; - int rows = self->mat.rows - templ->mat.rows + 1; - m_out->mat.create(cols, rows, CV_32FC1); - int method = (args.Length() < 2) ? (int)cv::TM_CCORR_NORMED : args[1]->Uint32Value(); cv::matchTemplate(self->mat, templ->mat, m_out->mat, method); - return scope.Close(out); + NanReturnValue(out); } // @author ytham // Min/Max location -Handle -Matrix::MinMaxLoc(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::MinMaxLoc) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -1840,37 +1745,36 @@ Matrix::MinMaxLoc(const v8::Arguments& args) { cv::minMaxLoc(self->mat, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat() ); - Local v_minVal = v8::Number::New(minVal); - Local v_maxVal = v8::Number::New(maxVal); - Local v_minLoc_x = v8::Number::New(minLoc.x); - Local v_minLoc_y = v8::Number::New(minLoc.y); - Local v_maxLoc_x = v8::Number::New(maxLoc.x); - Local v_maxLoc_y = v8::Number::New(maxLoc.y); + Local v_minVal = NanNew(minVal); + Local v_maxVal = NanNew(maxVal); + Local v_minLoc_x = NanNew(minLoc.x); + Local v_minLoc_y = NanNew(minLoc.y); + Local v_maxLoc_x = NanNew(maxLoc.x); + Local v_maxLoc_y = NanNew(maxLoc.y); - Local o_minLoc = Object::New(); - o_minLoc->Set(String::NewSymbol("x"), v_minLoc_x); - o_minLoc->Set(String::NewSymbol("y"), v_minLoc_y); + Local o_minLoc = NanNew(); + o_minLoc->Set(NanNew("x"), v_minLoc_x); + o_minLoc->Set(NanNew("y"), v_minLoc_y); - Local o_maxLoc = Object::New(); - o_maxLoc->Set(String::NewSymbol("x"), v_maxLoc_x); - o_maxLoc->Set(String::NewSymbol("y"), v_maxLoc_y); + Local o_maxLoc = NanNew(); + o_maxLoc->Set(NanNew("x"), v_maxLoc_x); + o_maxLoc->Set(NanNew("y"), v_maxLoc_y); // Output result object - Local result = Object::New(); - result->Set(String::NewSymbol("minVal"), v_minVal); - result->Set(String::NewSymbol("maxVal"), v_maxVal); - result->Set(String::NewSymbol("minLoc"), o_minLoc); - result->Set(String::NewSymbol("maxLoc"), o_maxLoc); + Local result = NanNew(); + result->Set(NanNew("minVal"), v_minVal); + result->Set(NanNew("maxVal"), v_maxVal); + result->Set(NanNew("minLoc"), o_minLoc); + result->Set(NanNew("maxLoc"), o_maxLoc); - return scope.Close(result); + NanReturnValue(result); } // @author ytham // Pushes some matrix (argument) the back of a matrix (self) -Handle -Matrix::PushBack(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::PushBack) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); @@ -1878,25 +1782,23 @@ Matrix::PushBack(const v8::Arguments& args) { self->mat.push_back(m_input->mat); - return scope.Close(args.This()); + NanReturnValue(args.This()); } -Handle -Matrix::PutText(const v8::Arguments& args) { - HandleScope scope; +NAN_METHOD(Matrix::PutText) { + NanScope(); Matrix *self = ObjectWrap::Unwrap(args.This()); - - v8::String::AsciiValue textString(args[0]); - char *text = (char *) malloc(textString.length() + 1); - strcpy(text, *textString); + NanAsciiString textString(args[0]);//FIXME: might cause issues, see here https://github.com/rvagg/nan/pull/152 + char *text = *textString; //(char *) malloc(textString.length() + 1); + //strcpy(text, *textString); int x = args[1]->IntegerValue(); int y = args[2]->IntegerValue(); - v8::String::AsciiValue fontString(args[3]); - char *font = (char *) malloc(fontString.length() + 1); - strcpy(font, *fontString); + NanAsciiString fontString(args[3]); + char *font = *fontString;//(char *) malloc(fontString.length() + 1); + //strcpy(font, *fontString); int constFont = cv::FONT_HERSHEY_SIMPLEX; if (!strcmp(font, "HERSEY_SIMPLEX")) { constFont = cv::FONT_HERSHEY_SIMPLEX; } @@ -1920,12 +1822,12 @@ Matrix::PutText(const v8::Arguments& args) { cv::putText(self->mat, text, cv::Point(x, y), constFont, scale, color, 2); - return scope.Close(Undefined()); + NanReturnUndefined(); } -Handle -Matrix::GetPerspectiveTransform(const v8::Arguments& args) { - HandleScope scope; + +NAN_METHOD(Matrix::GetPerspectiveTransform) { + NanScope(); // extract quad args Local srcArray = args[0]->ToObject(); @@ -1938,15 +1840,15 @@ Matrix::GetPerspectiveTransform(const v8::Arguments& args) { tgt_corners[i] = cvPoint(tgtArray->Get(i*2)->IntegerValue(),tgtArray->Get(i*2+1)->IntegerValue()); } - Local xfrm = Matrix::constructor->GetFunction()->NewInstance(); + Local xfrm = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *xfrmmat = ObjectWrap::Unwrap(xfrm); xfrmmat->mat = cv::getPerspectiveTransform(src_corners, tgt_corners); - return scope.Close(xfrm); + NanReturnValue(xfrm); } -Handle -Matrix::WarpPerspective(const v8::Arguments& args) { + +NAN_METHOD(Matrix::WarpPerspective) { SETUP_FUNCTION(Matrix) Matrix *xfrm = ObjectWrap::Unwrap(args[0]->ToObject()); @@ -1971,11 +1873,10 @@ Matrix::WarpPerspective(const v8::Arguments& args) { ~self->mat; self->mat = res; - return scope.Close(v8::Null()); + NanReturnNull(); } -Handle -Matrix::CopyWithMask(const v8::Arguments& args) { +NAN_METHOD(Matrix::CopyWithMask) { SETUP_FUNCTION(Matrix) // param 0 - destination image: @@ -1985,12 +1886,11 @@ Matrix::CopyWithMask(const v8::Arguments& args) { self->mat.copyTo(dest->mat,mask->mat); - return scope.Close(Undefined()); + NanReturnUndefined(); } -Handle -Matrix::SetWithMask(const v8::Arguments& args) { +NAN_METHOD(Matrix::SetWithMask) { SETUP_FUNCTION(Matrix) // param 0 - target value: @@ -2005,27 +1905,25 @@ Matrix::SetWithMask(const v8::Arguments& args) { self->mat.setTo(newvals,mask->mat); - return scope.Close(Undefined()); + NanReturnUndefined(); } -Handle -Matrix::MeanWithMask(const v8::Arguments& args) { +NAN_METHOD(Matrix::MeanWithMask) { SETUP_FUNCTION(Matrix) // param 0 - mask. same size as src and dest Matrix *mask = ObjectWrap::Unwrap(args[0]->ToObject()); cv::Scalar means = cv::mean(self->mat, mask->mat); - v8::Local arr = v8::Array::New(3); - arr->Set(0, Number::New( means[0] )); - arr->Set(1, Number::New( means[1] )); - arr->Set(2, Number::New( means[2] )); + v8::Local arr = NanNew(3); + arr->Set(0, NanNew( means[0] )); + arr->Set(1, NanNew( means[1] )); + arr->Set(2, NanNew( means[2] )); - return scope.Close(arr); + NanReturnValue(arr); } -Handle -Matrix::Shift(const v8::Arguments& args){ +NAN_METHOD(Matrix::Shift){ SETUP_FUNCTION(Matrix) cv::Mat res; @@ -2055,5 +1953,5 @@ Matrix::Shift(const v8::Arguments& args){ ~self->mat; self->mat = res; - return scope.Close(Undefined()); + NanReturnUndefined(); } diff --git a/src/Matrix.h b/src/Matrix.h index 791636b..535134f 100755 --- a/src/Matrix.h +++ b/src/Matrix.h @@ -6,7 +6,7 @@ class Matrix: public node::ObjectWrap { cv::Mat mat; static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); Matrix(); Matrix(cv::Mat other, cv::Rect roi); Matrix(int rows, int cols); diff --git a/src/OpenCV.cc b/src/OpenCV.cc index 37b886f..bb8635f 100755 --- a/src/OpenCV.cc +++ b/src/OpenCV.cc @@ -1,30 +1,29 @@ #include "OpenCV.h" #include "Matrix.h" +#include void OpenCV::Init(Handle target) { - HandleScope scope; - + NanScope(); // Version string. char out [21]; int n = sprintf(out, "%i.%i", CV_MAJOR_VERSION, CV_MINOR_VERSION); - target->Set(String::NewSymbol("version"), String::New(out, n)); + target->Set(NanNew("version"), NanNew(out, n)); NODE_SET_METHOD(target, "readImage", ReadImage); } - -Handle -OpenCV::ReadImage(const Arguments &args) { - HandleScope scope; +NAN_METHOD(OpenCV::ReadImage) { + NanEscapableScope(); try{ - Local im_h = Matrix::constructor->GetFunction()->NewInstance(); + Local im_h = NanNew(Matrix::constructor)->GetFunction()->NewInstance(); Matrix *img = ObjectWrap::Unwrap(im_h); + cv::Mat mat; REQ_FUN_ARG(1, cb); @@ -38,7 +37,7 @@ OpenCV::ReadImage(const Arguments &args) { } else if (args[0]->IsString()) { - std::string filename = std::string(*v8::String::AsciiValue(args[0]->ToString())); + std::string filename = std::string(*NanAsciiString(args[0]->ToString())); mat = cv::imread(filename); } else if (Buffer::HasInstance(args[0])){ @@ -49,7 +48,7 @@ OpenCV::ReadImage(const Arguments &args) { mat = cv::imdecode(*mbuf, -1); if (mat.empty()){ - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Error loading file"))); + NanThrowTypeError("Error loading file"); } } @@ -57,23 +56,21 @@ OpenCV::ReadImage(const Arguments &args) { Local argv[2]; - argv[0] = Local::New(Null()); + argv[0] = NanNull(); argv[1] = im_h; TryCatch try_catch; - cb->Call(Context::GetCurrent()->Global(), 2, argv); + cb->Call(NanGetCurrentContext()->Global(), 2, argv); if (try_catch.HasCaught()) { FatalException(try_catch); } - return Undefined(); + NanReturnUndefined(); } catch( cv::Exception& e ){ const char* err_msg = e.what(); - return v8::ThrowException(v8::Exception::Error(v8::String::New(err_msg))); + NanThrowError(err_msg); } }; - - diff --git a/src/OpenCV.h b/src/OpenCV.h index 83a3cc7..ea1ca83 100755 --- a/src/OpenCV.h +++ b/src/OpenCV.h @@ -9,29 +9,30 @@ #include #include #include +#include using namespace v8; using namespace node; #define REQ_FUN_ARG(I, VAR) \ if (args.Length() <= (I) || !args[I]->IsFunction()) \ - return v8::ThrowException(v8::Exception::TypeError( \ - String::New("Argument " #I " must be a function"))); \ + return NanThrowTypeError("Argument " #I " must be a function"); \ Local VAR = Local::Cast(args[I]); #define SETUP_FUNCTION(TYP) \ - HandleScope scope; \ + NanScope(); \ TYP *self = ObjectWrap::Unwrap(args.This()); #define JSFUNC(NAME) \ - static Handle NAME(const Arguments& args); + static NAN_METHOD(NAME); #define JSTHROW_TYPE(ERR) \ - return v8::ThrowException(v8::Exception::TypeError(v8::String::New(ERR))); + NanThrowTypeError( ERR ); + #define JSTHROW(ERR) \ - return v8::ThrowException(v8::Exception::Error(v8::String::New(ERR))); + NanThrowError( ERR ); #define INT_FROM_ARGS(NAME, IND) \ @@ -48,10 +49,10 @@ class OpenCV: public node::ObjectWrap{ public: static void Init(Handle target); - static Handle ReadImage(const v8::Arguments&); - + static NAN_METHOD(ReadImage); }; + #endif diff --git a/src/Point.cc b/src/Point.cc index 9b5afa6..328f78c 100755 --- a/src/Point.cc +++ b/src/Point.cc @@ -6,65 +6,63 @@ v8::Persistent Point::constructor; void Point::Init(Handle target) { - HandleScope scope; + NanScope(); // Constructor - constructor = Persistent::New(FunctionTemplate::New(Point::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("Point")); - - // Prototype - Local proto = constructor->PrototypeTemplate(); - proto->SetAccessor(String::NewSymbol("x"), GetX, RaiseImmutable); - proto->SetAccessor(String::NewSymbol("y"), GetY, RaiseImmutable); + Local ctor = NanNew(Point::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("Point")); - NODE_SET_PROTOTYPE_METHOD(constructor, "dot", Dot); + // Prototype + Local proto = ctor->PrototypeTemplate(); + proto->SetAccessor(NanNew("x"), GetX, RaiseImmutable); + proto->SetAccessor(NanNew("y"), GetY, RaiseImmutable); + + + NODE_SET_PROTOTYPE_METHOD(ctor, "dot", Dot); - target->Set(String::NewSymbol("Point"), constructor->GetFunction()); + target->Set(NanNew("Point"), ctor->GetFunction()); }; -Handle -Point::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(Point::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0) - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new"))); + return NanThrowTypeError("Cannot Instantiate without new"); double x = 0, y = 0; if (args[0]->IsNumber()) x = args[0]->NumberValue(); if (args[1]->IsNumber()) y = args[1]->NumberValue(); Point *pt = new Point(x, y); pt->Wrap(args.This()); - return args.This(); + NanReturnValue(args.This()); } -Handle -Point::GetX(Local prop, const AccessorInfo &info) { - HandleScope scope; - Point *pt = ObjectWrap::Unwrap(info.This()); - return scope.Close(Number::New(pt->point.x)); +NAN_GETTER(Point::GetX){ + NanScope(); + Point *pt = ObjectWrap::Unwrap(args.This()); + NanReturnValue(NanNew(pt->point.x)); } -Handle -Point::GetY(Local prop, const AccessorInfo &info) { - HandleScope scope; - Point *pt = ObjectWrap::Unwrap(info.This()); - return scope.Close(Number::New(pt->point.y)); +NAN_GETTER(Point::GetY){ + NanScope(); + Point *pt = ObjectWrap::Unwrap(args.This()); + NanReturnValue(NanNew(pt->point.y)); } -void -Point::RaiseImmutable(Local property, Local value, const AccessorInfo& info) { - v8::ThrowException(v8::Exception::TypeError(v8::String::New("Point is immutable"))); -} -Handle -Point::Dot(const v8::Arguments& args){ - HandleScope scope; +NAN_SETTER(Point::RaiseImmutable){ + NanThrowTypeError("Point is immutable"); +} + +NAN_METHOD(Point::Dot){ + NanScope(); Point *p1 = ObjectWrap::Unwrap(args.This()); Point *p2 = ObjectWrap::Unwrap(args[0]->ToObject()); // Since V 2.3 Native Dot no longer supported - return scope.Close(Number::New(p1->point.x * p2->point.x + p1->point.y * p2->point.y)); + NanReturnValue(NanNew(p1->point.x * p2->point.x + p1->point.y * p2->point.y)); } diff --git a/src/Point.h b/src/Point.h index 988c66f..ca8b218 100755 --- a/src/Point.h +++ b/src/Point.h @@ -7,13 +7,13 @@ class Point: public node::ObjectWrap { CvPoint2D32f point; static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); Point(double x, double y); - - static Handle GetX(Local prop, const AccessorInfo &info); - static Handle GetY(Local prop, const AccessorInfo &info); - static void RaiseImmutable(Local property, Local value, const AccessorInfo& info); - static Handle Dot(const v8::Arguments&); - + + static NAN_GETTER(GetX); + static NAN_GETTER(GetY); + static NAN_SETTER(RaiseImmutable); + + static NAN_METHOD(Dot); }; diff --git a/src/VideoCaptureWrap.cc b/src/VideoCaptureWrap.cc index 904a70e..89b17c0 100755 --- a/src/VideoCaptureWrap.cc +++ b/src/VideoCaptureWrap.cc @@ -6,9 +6,6 @@ using namespace std; -void AsyncRead(uv_work_t *req); -void AfterAsyncRead(uv_work_t *req); - v8::Persistent VideoCaptureWrap::constructor; struct videocapture_baton { @@ -23,30 +20,32 @@ struct videocapture_baton { void VideoCaptureWrap::Init(Handle target) { - HandleScope scope; + NanScope(); - // Constructor - constructor = Persistent::New(FunctionTemplate::New(VideoCaptureWrap::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("VideoCapture")); - - // Prototype + //Class + Local ctor = NanNew(VideoCaptureWrap::New); + NanAssignPersistent(constructor, ctor); + ctor->InstanceTemplate()->SetInternalFieldCount(1); + ctor->SetClassName(NanNew("VideoCapture")); + + // Prototype //Local proto = constructor->PrototypeTemplate(); - NODE_SET_PROTOTYPE_METHOD(constructor, "read", Read); - NODE_SET_PROTOTYPE_METHOD(constructor, "setWidth", SetWidth); - NODE_SET_PROTOTYPE_METHOD(constructor, "setHeight", SetHeight); - NODE_SET_PROTOTYPE_METHOD(constructor, "setPosition", SetPosition); + NODE_SET_PROTOTYPE_METHOD(ctor, "read", Read); + NODE_SET_PROTOTYPE_METHOD(ctor, "setWidth", SetWidth); + NODE_SET_PROTOTYPE_METHOD(ctor, "setHeight", SetHeight); + NODE_SET_PROTOTYPE_METHOD(ctor, "setPosition", SetPosition); + NODE_SET_PROTOTYPE_METHOD(ctor, "close", Close); + NODE_SET_PROTOTYPE_METHOD(ctor, "ReadSync", ReadSync); - target->Set(String::NewSymbol("VideoCapture"), constructor->GetFunction()); + target->Set(NanNew("VideoCapture"), ctor->GetFunction()); }; -Handle -VideoCaptureWrap::New(const Arguments &args) { - HandleScope scope; +NAN_METHOD(VideoCaptureWrap::New) { + NanScope(); if (args.This()->InternalFieldCount() == 0) - return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new"))); + return NanThrowTypeError("Cannot Instantiate without new"); VideoCaptureWrap *v; @@ -54,131 +53,161 @@ VideoCaptureWrap::New(const Arguments &args) { v = new VideoCaptureWrap(args[0]->NumberValue()); } else { //TODO - assumes that we have string, verify - v = new VideoCaptureWrap(std::string(*v8::String::AsciiValue(args[0]->ToString()))); + v = new VideoCaptureWrap(std::string(*NanAsciiString(args[0]->ToString()))); } v->Wrap(args.This()); - return args.This(); + NanReturnValue(args.This()); } VideoCaptureWrap::VideoCaptureWrap(int device){ - HandleScope scope; + NanScope(); cap.open(device); if(!cap.isOpened()){ - v8::ThrowException(v8::Exception::Error(String::New("Camera could not be opened"))); + NanThrowError("Camera could not be opened"); } } VideoCaptureWrap::VideoCaptureWrap(const std::string& filename){ - HandleScope scope; + NanScope(); cap.open(filename); // TODO! At the moment this only takes a full path - do relative too. if(!cap.isOpened()){ - v8::ThrowException(v8::Exception::Error(String::New("Video file could not be opened (opencv reqs. non relative paths)"))); + NanThrowError("Video file could not be opened (opencv reqs. non relative paths)"); } } -Handle -VideoCaptureWrap::SetWidth(const Arguments &args){ +NAN_METHOD(VideoCaptureWrap::SetWidth){ - HandleScope scope; + NanScope(); VideoCaptureWrap *v = ObjectWrap::Unwrap(args.This()); if(args.Length() != 1) - return scope.Close(Undefined()); + NanReturnUndefined(); int w = args[0]->IntegerValue(); if(v->cap.isOpened()) v->cap.set(CV_CAP_PROP_FRAME_WIDTH, w); - return scope.Close(Undefined()); + NanReturnUndefined(); } -Handle -VideoCaptureWrap::SetHeight(const Arguments &args){ +NAN_METHOD(VideoCaptureWrap::SetHeight){ - HandleScope scope; + NanScope(); VideoCaptureWrap *v = ObjectWrap::Unwrap(args.This()); if(args.Length() != 1) - return scope.Close(Undefined()); + NanReturnUndefined(); int h = args[0]->IntegerValue(); v->cap.set(CV_CAP_PROP_FRAME_HEIGHT, h); - return Undefined(); + NanReturnUndefined(); } -Handle -VideoCaptureWrap::SetPosition(const Arguments &args){ +NAN_METHOD(VideoCaptureWrap::SetPosition){ - HandleScope scope; + NanScope(); VideoCaptureWrap *v = ObjectWrap::Unwrap(args.This()); if(args.Length() != 1) - return scope.Close(Undefined()); + NanReturnUndefined(); int pos = args[0]->IntegerValue(); v->cap.set(CV_CAP_PROP_POS_FRAMES, pos); - return Undefined(); + NanReturnUndefined(); } -Handle -VideoCaptureWrap::Read(const Arguments &args) { +NAN_METHOD(VideoCaptureWrap::Close){ - HandleScope scope; + NanScope(); + VideoCaptureWrap *v = ObjectWrap::Unwrap(args.This()); + + v->cap.release(); + + NanReturnUndefined(); +} + + +class AsyncVCWorker : public NanAsyncWorker { + public: + AsyncVCWorker(NanCallback *callback, VideoCaptureWrap* vc, Matrix* matrix) + : NanAsyncWorker(callback), vc(vc), matrix(matrix) {} + ~AsyncVCWorker() {} + + // Executed inside the worker-thread. + // It is not safe to access V8, or V8 data structures + // here, so everything we need for input and output + // should go on `this`. + void Execute () { + this->vc->cap.read(matrix->mat); + } + + // Executed when the async work is complete + // this function will be run inside the main event loop + // so it is safe to use V8 again + void HandleOKCallback () { + NanScope(); + + Local im_to_return= NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *img = ObjectWrap::Unwrap(im_to_return); + cv::Mat mat; + mat = this->matrix->mat; + img->mat = mat; + + Local argv[] = { + NanNull() + , im_to_return + }; + + TryCatch try_catch; + callback->Call(2, argv); + if (try_catch.HasCaught()) { + FatalException(try_catch); + } + } + + private: + VideoCaptureWrap *vc; + Matrix* matrix; + int res; +}; + + + +NAN_METHOD(VideoCaptureWrap::Read) { + + NanScope(); VideoCaptureWrap *v = ObjectWrap::Unwrap(args.This()); REQ_FUN_ARG(0, cb); - videocapture_baton *baton = new videocapture_baton(); - baton->vc = v; - baton->cb = Persistent::New(cb); - baton->im = new Matrix(); - baton->request.data = baton; - - uv_queue_work(uv_default_loop(), &baton->request, AsyncRead, (uv_after_work_cb)AfterAsyncRead); - return Undefined(); - -} - -void AsyncRead(uv_work_t *req) { - videocapture_baton *baton = static_cast(req->data); - - baton->vc->cap.read(baton->im->mat); + NanCallback *callback = new NanCallback(cb.As()); + NanAsyncQueueWorker(new AsyncVCWorker(callback, v, new Matrix())); + + NanReturnUndefined(); } -void AfterAsyncRead(uv_work_t *req) { +NAN_METHOD(VideoCaptureWrap::ReadSync) { - HandleScope scope; + NanScope(); + VideoCaptureWrap *v = ObjectWrap::Unwrap(args.This()); - videocapture_baton *baton = static_cast(req->data); + Local im_to_return= NanNew(Matrix::constructor)->GetFunction()->NewInstance(); + Matrix *img = ObjectWrap::Unwrap(im_to_return); - Local im_to_return= Matrix::constructor->GetFunction()->NewInstance(); - Matrix *img = ObjectWrap::Unwrap(im_to_return); - cv::Mat mat; - mat = baton->im->mat; - - img->mat = mat; - Local argv[2]; - - argv[0] = Local::New(Null()); - argv[1] = im_to_return; - - baton->cb->Call(Context::GetCurrent()->Global(), 2, argv); - baton->cb.Dispose(); - - delete baton->im; - delete baton; + v->cap.read(img->mat); + NanReturnValue(im_to_return); } diff --git a/src/VideoCaptureWrap.h b/src/VideoCaptureWrap.h index b239273..02c2cf8 100755 --- a/src/VideoCaptureWrap.h +++ b/src/VideoCaptureWrap.h @@ -6,22 +6,24 @@ class VideoCaptureWrap: public node::ObjectWrap { static Persistent constructor; static void Init(Handle target); - static Handle New(const Arguments &args); + static NAN_METHOD(New); VideoCaptureWrap(const std::string& filename); VideoCaptureWrap(int device); - static Handle Read(const v8::Arguments&); + static NAN_METHOD(Read); + static NAN_METHOD(ReadSync); //(Optional) For setting width and height of the input video stream - static Handle SetWidth(const v8::Arguments&); - static Handle SetHeight(const v8::Arguments&); + static NAN_METHOD(SetWidth); + static NAN_METHOD(SetHeight); // to set frame position - static Handle SetPosition(const v8::Arguments&); + static NAN_METHOD(SetPosition); + static NAN_METHOD(GetFrameAt); - static Handle GetFrameAt(const v8::Arguments&); - + //close the stream + static NAN_METHOD(Close); }; diff --git a/src/init.cc b/src/init.cc index fa3a05a..eb8b79a 100755 --- a/src/init.cc +++ b/src/init.cc @@ -1,4 +1,5 @@ #include "OpenCV.h" + #include "Point.h" #include "Matrix.h" #include "CascadeClassifierWrap.h" @@ -12,8 +13,9 @@ extern "C" void init(Handle target) { - HandleScope scope; + NanScope(); OpenCV::Init(target); + Point::Init(target); Matrix::Init(target); CascadeClassifierWrap::Init(target);