Fork me on GitHub

Bytedeco makes native libraries available to the Java platform by offering ready-to-use bindings generated with the codeveloped JavaCPP technology. This, we hope, is the missing bridge between Java and C/C++, bringing compute-intensive science, multimedia, computer vision, deep learning, etc to the Java platform.

Core Technologies

  • JavaCPP [API] – A tool that can not only generate JNI code but also build native wrapper library files from an appropriate interface file written entirely in Java. It can also parse automatically C/C++ header files to produce the required Java interface files.

Prebuilt Java Bindings to C/C++ Libraries

These are part of a project that we call the JavaCPP Presets. Many coexist in the same GitHub repository, and all use JavaCPP to wrap predefined C/C++ libraries from open-source land. The bindings expose almost all of the relevant APIs and make them available in a portable and user-friendly fashion to any Java virtual machine (including Android), as if they were like any other normal Java libraries. We have presets for the following C/C++ libraries:

We will add more to this list as they are made, including those from outside the bytedeco/javacpp-presets repository.

Projects Leveraging the Presets Bindings

  • JavaCV [API] – Library based on the JavaCPP Presets that depends on commonly used native libraries in the field of computer vision to facilitate the development of those applications on the Java platform. It provides easy-to-use interfaces to grab frames from cameras and audio/video streams, process them, and record them back on disk or send them over the network.
  • JavaCV Examples – Collection of examples originally written in C++ for the book entitled OpenCV 2 Computer Vision Application Programming Cookbook by Robert Laganière, but ported to JavaCV and written in Scala.
  • ProCamCalib – Sample JavaCV application that can perform geometric and photometric calibration of a set of video projectors and color cameras.
  • ProCamTracker – Another sample JavaCV application that uses the calibration from ProCamCalib to implement a vision method that tracks a textured planar surface and realizes markerless interactive augmented reality with projection mapping.

More Project Information

Please refer to the contribute and download pages for more information about how to help out or obtain this software.

See the developer site on GitHub for more general information about the Bytedeco projects.

Latest News feed twitter

Moving to Java SE 7

October 25, 2015

A few months have already passed since the last release, encouraging us to create a new one, which we have just done! Version 1.1 of JavaCPP, JavaCPP Presets, JavaCV, ProCamCalib, and ProCamTracker are now available, and they depend on Java SE 7. We felt that since everyone is now comfortable with Java SE 8, it was time to drop compatibility with Java SE 6. :) Seriously, the main reason behind the change was to provide support for the try-with-resources construct, instead of relying solely on the garbage collector to imitate C++-like memory management semantics, aka “Resource Acquisition Is Initialization (RAII)”. This required making the Pointer class implement the AutoCloseable interface, a tiny but important interface. Many thanks to Adam Gibson and Cyprien Noel for having successfully convinced me to make this change. Android also provides that interface since version 4.0, covering more than 95% of all Android users at the time of this writing, according to Android Dashboards. So, the choice was not so hard to make after all, and JavaCPP now requires Android 4.0.

That said, what does try-with-resources gets us anyway? It provides a user-friendly way to release resources in a deterministic manner, something that a lot of C++ libraries take for granted. There is no guarantees that the garbage collector will ever run. It only cares about memory allocated on the Java heap, and if we allocate chunks of memory only from the native heap, it might decide to never run, a situation that can easily become problematic. Also, we cannot predict on which thread memory eventually gets deallocated. We cannot force any given thread used for an allocation to come back at some point for deallocation: It might disappear at any time without any warning. The point is, for more than a few reasons, people came up with this concept to provide services garbage collection was unable to provide. As a concrete example, in the traditional paradigm, there are occasions when we would write the following:

    MyPointer data = new MyPointer();
    try {
        // use data...
    } finally {
        data.deallocate();
    }

With try-with-resources, we can rewrite the logic above into a single statement like this:

    try (MyPointer data = new MyPointer()) {
        // use data ...
    }

A lot cleaner, and thus a lot less error-prone. Exceptions also behave better, but that is about the gist of it. By the way, this also works with native smart pointers such as boost::shared_ptr (Boost), std::shared_ptr (C++11), cv::Ptr (OpenCV), and others. JavaCPP provides a new transparent bridge to any such references by holding on to a set of two pointers for each native object: the actual pointer of the object to access the data and call functions, and an “owner pointer” corresponding to a smart pointer allocated on the heap, which gets accessed only during deallocation when applying the delete operator. Check the documentation of the @SharedPtr annotation and the associated C++ template SharedPtrAdapter for more information.

On top of that, Pointer now also checks for the “org.bytedeco.javacpp.nopointergc” system property, and if “true”, disables completely the garbage collector safety net, potentially saving a significant amount of time for some applications. To make sure that yours does not rely on the garbage collector for any deallocation, we have also added debug messages that are logged when a Pointer gets allocated, collected as garbage, and eventually deallocated. They can be captured by setting the “org.bytedeco.javacpp.logger” system property to “slf4j”, and by setting the log level to “debug”, for example, via the “org.slf4j.simpleLogger.defaultLogLevel” system property in the case of SimpleLogger from SL4J.

In closing, let us give credit where credit is due. Cyprien Noel was the one that not only brought up all these ideas, but helped to implement them, and tested them out for their own framework of Caffe-on-Spark. Discussions with Adam Gibson were also extremely fruitful, providing valuable feedback. They have since adopted JavaCPP for their own use as part of Deeplearning4j. Though grateful to them and everyone else who helped out, there is still much work to be done. If you are interested by where this is going, or would like to make your own recommendations and contributions, be sure to contact us via the mailing list from Google Groups, issues on GitHub, or the chat room at Gitter. Thank you for your interest, and enjoy!