<div dir="ltr">Hi,<div>  >> Its design was the most important source of inspiration for ImgLib2.</div><div>  Thanks for this information.</div><div>  When I read ImgLib2, I have a impression that its design has some similar with other library.</div>
<div>  Now I know this library is VIGRA :)</div><div><br></div><div>  By the way, I can not access <a href="http://hci.iwr.uni-heidelberg.de/vigra/%E2%80%8E">http://hci.iwr.uni-heidelberg.de/vigra</a>/ currently. Do others have this problem?   </div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/10/17 Johannes Schindelin <span dir="ltr"><<a href="mailto:Johannes.Schindelin@gmx.de" target="_blank">Johannes.Schindelin@gmx.de</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Ullrich,<br>
<br>
a little background information for everybody else: Ullrich is the<br>
inventor and maintainer of VIGRA, an incredibly powerful C++ library to<br>
process and analyze images. Its design was the most important source of<br>
inspiration for ImgLib2. As a consequence, I was really delighted to meet<br>
Ullrich at the EuBIAS meeting in Barcelona last week. Among other things,<br>
we talked extensively about ways to interoperate between ImgLib2 and<br>
VIGRA, and the lack of support in VIGRA to read file formats via the<br>
Bio-Formats library.<br>
<br>
Also at that meeting, I got into contact with the OpenMole project, and in<br>
particular with Mark Hammons who not only explained patiently the benefits<br>
of the Scala language to me, but also pointed out the existence of the<br>
Avian VM, a small, embeddable, BSD-licensed Java Virtual Machine written<br>
in C++, with a tiny Just-In-Time compiler, just enough to make it a<br>
practical choice for running limited Java inside a C++ program/library:<br>
<a href="http://oss.readytalk.com/avian/" target="_blank">http://oss.readytalk.com/avian/</a><br>
<br>
It is actually very, very, *very* limited, as I found out when I tried to<br>
get it to run the bfconvert tool of Bio-Formats.<br>
<br>
But I did get it to run bfconvert. To be precise, in my hands, the 5MB<br>
executable compiled from my fork of Avian was able to run my<br>
(minimally-diverging) Bio-Formats v4.4.8 fork's<br>
loci.formats.tools.ImageConverter class to convert Fiji's icon.png (my<br>
standard example) to a .tiff file (although the colors are off, but<br>
running the same example with plain Java results in a byte-identical<br>
file).<br>
<br>
Although it is too early for proper benchmarking, things seem to be<br>
comparable between Java and Avian: while Java is slightly faster in what<br>
time(1) calls "real" time (~0.54s vs ~0.72s), in terms of "user" time<br>
roles are reversed (~0.70s vs ~0.63s). Roughly the same holds true for the<br>
dynamic Avian executable (which is only 11K and links to Avian's libjvm.so<br>
weighing in with a whopping 1.2M). The major benefit will most likely be<br>
space: linking to libjvm.so should be enough, the standard Java classes<br>
are included therein. So you can get Java support in VIGRA (or any other<br>
C++ project) by adding a library that is slightly larger than one<br>
megabyte.<br>
<br>
Now to some more detailed explanations about the challenges I faced, for<br>
the technically-inclined.<br>
<br>
On the Bio-Formats side, there are two major and one minor (and one micro)<br>
issue:<br>
<br>
- to enable logging, Bio-Formats uses a cute hack called<br>
  ReflectedUniverse, which is basically a scripting language for Java<br>
  itself. However, it uses regular expressions, something that Avian's<br>
  class library does not yet support.<br>
<br>
- Bio-Formats uses a concurrent hashmap in loci.common.Location.<br>
  Concurrency (JSR-166) is not supported by Avian's class library yet.<br>
<br>
- in loci.formats.gui.LegacyQTTools, the value of the java.library.path<br>
  property is used without checking whether the property is null (unset).<br>
<br>
- some debug logging in Bio-Formats uses String.format() (not yet<br>
  supported by Avian's class library).<br>
<br>
All of these issues could be worked around in the code calling<br>
Bio-Formats: there is no need to use the ImageConverter class (which<br>
enables the logging), the concurrent hashmap could be faked by extending<br>
the non-concurrent hashmap (and just not bothering with the concurrency<br>
because we will most likely instantiate one VM per Bio-Formats call), the<br>
java.library.path property could be initialized to a dummy value and the<br>
logging could be switched off completely.<br>
<br>
On the Avian side, I am happy to report that I only had to extend the<br>
class library (apart from one bug fix that I will contribute upstream<br>
later this week). In particular, I had to<br>
<br>
- make RandomAccessFile support writing<br>
<br>
- provide three dummy AWT classes because Bio-Formats actually links to<br>
  them, but does not use them by default<br>
<br>
- provide a couple of interfaces and exceptions that were not yet included<br>
  in Avian<br>
<br>
- implement a minimal java.io.DataOutputStream<br>
<br>
- provide a FileChannel for RandomAccessFiles (i.e. implement getChannel)<br>
<br>
- implement java.lang.Boolean's parse(String) method<br>
<br>
- implement java.lang.Character's isISOControl(char) method<br>
<br>
- implement fake byte order methods for ByteBuffers (they are hardcoded to<br>
  big endian, but that is what Bio-Formats required in my test)<br>
<br>
- provide a dummy SimpleDateFormat which actually does not work, but does<br>
  not need to<br>
<br>
- add toString(long[]) to java.util.Arrays<br>
<br>
- teach Avian's pseudo regular expressions about "\\", i.e. the backslash<br>
<br>
For the moment, all of these changes are contained in hodge podge<br>
work-in-progress commits which I will clean up over the next few days. You<br>
can see them here (the linked pages will update whenever I get around to<br>
clean up the commits):<br>
<br>
<a href="https://github.com/dscho/avian/compare/bio-formats" target="_blank">https://github.com/dscho/avian/compare/bio-formats</a><br>
<a href="https://github.com/dscho/bioformats/compare/v4.4.8...avian" target="_blank">https://github.com/dscho/bioformats/compare/v4.4.8...avian</a><br>
<br>
Since VIGRA and ImgLib2 share design concepts, and since SCIFIO supports<br>
ImgLib2 natively, I think that my plan to extend the test to SCIFIO after<br>
cleaning up my Avian fork is sound.<br>
<br>
Once that is done, I will add unit tests that our trusty Jenkins will run<br>
whenever SCIFIO (or Avian) changes, to ensure that things continue to<br>
work. These unit tests will be extended as needed, e.g. when someone finds<br>
out that an important use case requires more changes in Avian, still.<br>
<br>
This way to call Bio-Formats and SCIFIO could become the default C++ entry<br>
point into those libraries.<br>
<br>
Summary: I showed that Bio-Formats/SCIFIO support for VIGRA and other C++<br>
libraries is feasible through the BSD-licensed embeddable Java virtual<br>
machine "Avian". I am confident that I can clean up my patches this week<br>
still, to be contributed to the Avian project.<br>
<br>
Ciao,<br>
Johannes<br>
<br>
_______________________________________________<br>
ImageJ-devel mailing list<br>
<a href="mailto:ImageJ-devel@imagej.net">ImageJ-devel@imagej.net</a><br>
<a href="http://imagej.net/mailman/listinfo/imagej-devel" target="_blank">http://imagej.net/mailman/listinfo/imagej-devel</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Yili Zhao
</div>