Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

API cpp

Nicolas Gryman edited this page · 8 revisions

Under the hood, ribs implements some of its stuff in c++. The choice was made for 2 main reasons:

  • node does not offer image io by default, so we need to wrap native libraries for that.
  • Until asm.js lands in node, performance is way better in native than in JavaScript for algebra.

The native part holds image data and implement core operations. It uses OpenCV for image io and processing.

Classes

Image

The role of the Image class is to:

  • Be the front-end of the native part by being the only c++ binding, and thus minimize bindings surface.
  • Bridge c++ to JavaScript via v8.
  • Add an abstraction layer in order to avoid depending on OpenCV code in the JavaScript part.

It holds image's metadata and pixels data by indirectly exposing a cv::Mat object. cv::Mat is the equivalent of ribs::Image in OpenCV's world. Pixels are directly accessible in JavaScript with the [] operator.

It also exposes native operations via its methods.

Operation

All operations inherit from the Operation abstract class. It offer a basic asynchronous execution facility using libuv. It can be seen as a sort of specialized thread for image processing.

In the context of a server, processing images asynchronously is useful because it does not block 1 thread per request and allows more concurrency.

Operations must implement 4 steps:

  • Prepare [sync]: fetches image and parameters from JavaScript and prepares the operation.
  • Process [async]: the operation implementation. It produces an output that must be stored internally.
  • Value [sync]: must return the output value to JavaScript.
  • Cleanup [sync]: free memory, cleans stuff not necessary anymore.

Operation comes with a protected error member. Assign it if an error has occurred. The rest will be handled automatically.

ribs provides helper macros to implement an new operation seamlessly.

OPERATION(name, stub)

It declares a operation class that inherits from Operation. It is typically called in the header file of an operation.

Arguments
  • name: The name of the operation. It should be capitalized.
  • stub: A list of private members.
Example

This declares a ResizeOperation class:

OPERATION(Resize,
  Image*   image;
  v8::Persistent<v8::Object> imageHandle;
  uint32_t width;
  uint32_t height;
);

OPERATION_PREPARE(name, stub)

Code to be executed before the operation runs. It is a private method of your class and is typically called in the source file of an operation.

Arguments
  • name: The name of the operation. It should be capitalized.
  • stub: The code.
Example

This fetches image and parameters.

OPERATION_PREPARE(Resize, {
  // check against mandatory image input (from this)
  image = ObjectWrap::Unwrap<Image>(args.This());

  // create a persistent object during the process to avoid v8 to dispose the JavaScript image object.
  NanAssignPersistent(Object, imageHandle, args.This());

  // store width & height
  width  = args[0]->Uint32Value();
  height = args[1]->Uint32Value();
})

OPERATION_PROCESS(name, stub)

Code to be executed when the operation runs. It is a private method of your class and is typically called in the source file of an operation.

Note that you can't interact with v8 in this method as it is not thread safe.

Arguments
  • name: The name of the operation. It should be capitalized.
  • stub: The code.
Example

This resizes the image asynchronously.

OPERATION_PROCESS(Resize, {
  try {
    cv::Mat res;
    cv::resize(image->Matrix(), res, cv::Size(width, height), 0, 0);
    image->Matrix(res);
  }
  catch (const cv::Exception& e) {
    error = "operation error: resize";
  }
})

OPERATION_VALUE(name, stub)

Returns the produced JavaScript value, typically a reference to the image that has been processed. This is necessary because v8 is not thread safe. So this is here that return you object back to the JavaScript part.

Arguments
  • name: The name of the operation. It should be capitalized.
  • stub: The code.
Example

This returns an JavaScript reference to the processed image:

OPERATION_VALUE(Resize, {
  image->Sync(imageHandle);
  return NanPersistentToLocal(imageHandle);
})

OPERATION_CLEANUP(name, stub)

Code to be executed when the operation has run. It is a private method of your class and is typically called in the source file of an operation.

Arguments
  • name: The name of the operation. It should be capitalized.
  • stub: The code.
Example

This cleans data used by the operation.

OPERATION_CLEANUP(Resize, {
  if (!imageHandle.IsEmpty()) NanDisposePersistent(imageHandle);
})
Something went wrong with that request. Please try again.