-
-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add experimental JPEG 2000 support with OpenJPEG #61
Conversation
+1 for this PR |
I'm wondering if OpenJPEG support should be enabled with a flag on the |
Yes, I agree. Apart from for development testing purposes, I don't really see the need to be able to switch between codecs in this way. So, it would make more sense for the choice of JPEG2000 codec to be determined at the configure stage. |
|
||
if(!(fsrc = fopen(filename.c_str(), "rb"))) throw string("ERROR :: OpenJPEG :: openImage() :: failed to open file for reading"); | ||
filename = getFileName( currentX, currentY ); // Get file name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My C++ is rusty, but shouldn't there be a type definition string
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry -- apparently this was superceded...
I consider OpenJPEG support to be experimental. If there are no Kakadu files available, the build simply produces a server working with OpenJPEG (no need to set an environment variable). If Kakadu files are available, then this must be the default for compatibility reasons and because it is still much faster, but of course it must also be possible to test OpenJPEG. That's why I added the environment variable. Would it be better to select Kakadu / OpenJPEG via an URL option? Then it would be possible to compare both on the fly (without running two servers or restarting a single server with different environment settings)? |
It's much cleaner to do this by enabling (or disabling) the choice of decoder through the configure script. Sure, at the moment, Kakadu should be the default if available. If you want to test, you can always build a server with each decoder and run them in parallel, allowing you to compare them. |
@ruven, which coding style do you prefer for iipsrv? I noticed that the new files for OpenJPEG seem to use a different style (indentation with tabs, function brackets at line endings and more differences) and would like to add a patch which fixes the coding style. |
I rebased the PR and added three patches which fix compiler warnings. |
Now a patch which formats the code was added. |
+1 for this PR |
@acdha, was your last emoji intentional? What is wrong with the pull request? |
@stweil Sorry – I've been developing an allergy to "+1" comments but I should have stayed quiet about it |
@ruven, are you planning own code for OpenJPEG support, or do you want to use the code from this PR? If the later: is there anything which should be changed before pulling? I'm asking because I have more modifications for that issue in my queue. I can add them here if this is useful. |
Has the environment variable / compile flag issue been addressed? |
The current code still supports builds which support both Kakadu and OpenJPEG, with preference for Kakadu at run time and possible selection of OpenJPEG via environment. As without my PR, Kakadu needs to be configured explicitly. OpenJPEG is compiled automatically if it is found. The advantage of the current code is that Kakadu users will get Kakadu as usual and all other users will get OpenJPEG automatically. This also ensures best code coverage for the compilation (no code rotting) without the need for multiple builds. I have new commits in my local tree which add a configure option for OpenJPEG as well. Thus both Kakadu and OpenJPEG have to be enabled during configuration. |
Unfortunately, OpenJPEG doesn't have true region decoding, so it will always be quite slow. |
For whole images, the current OpenJPEG support for iipsrv is slow because of incomplete / old code (missing functions regionDecoding and old signature of OpenJPEGImage::getRegion). Depending on the image size, an improvement by a factor of 100 and more can be reached when fixing that. |
These files from git@github.com:moravianlibrary/iipsrv-openjpeg.git are needed to support JPEG 2000 using libopenjpeg instead of Kakadu. Information from the original commit: commit 9262068b8606c2a0699ee74fad4ec991d34c7715 Author: Daniel Secik <dsecik@gmail.com> Date: Tue Jun 9 18:04:46 2015 +0200 Initial commit Signed-off-by: Stefan Weil <sw@weilnetz.de>
* Remove whitespace at line endings * Remove empty line at end of file Signed-off-by: Stefan Weil <sw@weilnetz.de>
See this discussion: moravianlibrary/iipsrv-openjpeg#1 Signed-off-by: Stefan Weil <sw@weilnetz.de>
* Update OpenJPEGImage::openImage for latest iipsrv. Signed-off-by: Stefan Weil <sw@weilnetz.de>
* Add check for OpenJPEG JPEG2000 library (code mainly from moravianlibrary/iipsrv-openjpeg). * Use Kakadu by default (if available). OpenJPEG can be enforced by setting the environment variable USE_OPENJPEG=1. Signed-off-by: Stefan Weil <sw@weilnetz.de>
gcc reports these warnings: src/OpenJPEGImage.cc:174:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] for(; tmp_w > tile_width || tmp_h > tile_height; ++i){ ^ src/OpenJPEGImage.cc:174:36: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] for(; tmp_w > tile_width || tmp_h > tile_height; ++i){ ^ As raster_width, raster_height, tile_width and tile_height all are unsigned values, tmp_w and tmp_h should also be unsigned. Signed-off-by: Stefan Weil <sw@weilnetz.de>
gcc reports these warnings: src/OpenJPEGImage.cc:241:7: warning: variable ‘edge_x’ set but not used [-Wunused-but-set-variable] bool edge_x = false; // Alter the tile size if it's in the last column ^ src/OpenJPEGImage.cc:247:7: warning: variable ‘edge_y’ set but not used [-Wunused-but-set-variable] bool edge_y = false; // Alter the tile size if it's in the bottom row Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
cool. Thanks. |
Great, that's compiled now.. |
Now building and testing w/ Loris.. |
@calvinbutcher, may I use your docker images on Monday next week at ELAG 2016? |
@stweil By all means, though I'd keep an eye on the docker hub builds. The openjpeg builds are stable (https://hub.docker.com/r/bdlss/iipsrv-openjpeg-docker/builds/ and https://hub.docker.com/r/bdlss/loris-openjpeg-docker/builds/) However, the iipsrv-openjpeg image relies on an untagged release of stweil/iipsrv. Only the loris-openjpeg image is stable with tagged releases of OpenJPEG and Loris. If you can give me a tagged release of your iipsrv, I can put this in and test over the next day or so. It would simply make it more stable. Regarding the rest, I'm still having a little teething trouble with the iipsrv-grok docker image but I hope this to be sorted very soon. The loris-grok image: I still don't know yet if it's going to work. But again, I hope this will be sorted one way or the other in a day or two. @boxerab a tagged release of Grok 1.0 as it stands would make these, when finished, more stable. Sorry this reply is a bit wordy. In summary, tagged releases of Grok and stweil/iipsrv would help make these images more stable for use. Finally, I'd steer clear of the validation as apparently version 1.0.0 is out of whack with IIIF 2.0. It fails 7 out of 21 tests. |
Here is your tag: openjpeg-20160529. |
Nice, thank you :) I'll put that in both openjpeg and grok builds now.. Done, awaiting builds. |
@stweil just a heads up, someone here had some trouble rolling them out with vagrant. I'm using a virtualbox instance of Ubuntu 14.04 desktop. I've not had time to look into why. |
OK, iipsrv-openjpeg and loris-openjpeg builds are stable. I'm still working on the grok builds. Looks like Pillow doesn't like Grok. I just need to strip out the validation/Pillow requirement for iipsrv-grok and it'll be fine. That'll kill the loris-grok build, though. |
I've done some preliminary testing with your openjpeg-work branch with iipsrv (changing the default tile size to 256 to make it comparable to the Kakadu implementation) and for an image of size 7185x6217, doing tile requests (JTL command), I get similar timing results to those reported above: OpenJPEG: 428815 So, Grok is around 3x slower, while standard OpenJPEG is 4x slower than Kakadu. Where performance degrades significantly with respect to Kakadu is with larger images. However, for a larger image of size 15016x11741, I get: OpenJPEG: Crash! So, standard OpenJPEG is unusable, whereas Grok (I guess because of the region decoding that @boxerab added) works, but is around 20x slower than Kakadu, which has a similar decode time to smaller images. Note that these are the decode times for the core process() command in the OpenJPEGImage and KakaduImage classes in iipsrv. And to put all this into perspective, the same 15016x11741 image in TIFF format has a tile decode time of only 2445, so even Kakadu is significantly slower than TIFF by about a factor of 50! |
OpenJPEG has problems with large images, see for example uclouvain/openjpeg#730. Can I get your test image somewhere? |
@ruven thanks for testing. For large images, what do you think is a good target speed ratio relative to Kakaudu? Something greater than 1 :) @calvinbutcher I will create a tag. @stweil Ruven's test image is only 165 MB, so this is below the 1GB cutoff. I did do a fair bit of memory optimization in Grok, so it does use quite a bit less memory than OpenJPEG. |
That's why I am interested to know what caused the crash (and to fix it, of course). |
@boxerab Thanks. If they're going to be used at ELAG, this will make the docker images more stable. |
This particular one, no. But there's nothing special about it. It was converted from tiff using Kakadu with parameters including a precinct size of 256x256, a code block size of 64x64 and RPCL ordering.
In fact it was more a memory allocation problem than a seg fault type crash. I guess OpenJPEG tried to put the whole image into memory rather than just a region. |
@stweil The above are now stable with tagged releases of stweil/iipsrv and grok, so they should be reliable. Am still working on the loris-grok build but may be fixed by the end of play today. |
By the way, folks, I just discovered a bug in Grok's region decoding : the codec was performing the discrete wavelet transform for the entire image, rather than only for the region. This makes a big difference for large images. So, the latest version on master is now significantly faster when decoding a relatively small region inside a large single-tile image. |
Hi Ruven, Do you think this PR is ready for merging, or is there more work to be done? I think once it is merged in, we can get people testing it, and this will help identify areas for Thanks, |
I'm happy to merge this, but if I understood @stweil correctly, this PR is not in fact the latest version:
@stweil, are you ready to update or do a new pull request? |
@ruven, my latest code is now in PR #74. It adds the |
I guess this PR could be closed now ? |
@calvinbutcher hope you are enjoying the sun and cider. I just fixed a serious concurrency issue in Grok codec; should I move the tag so that docker image gets the bug-fixed version? |
Closing this PR. It is superseded by PR #74 (which will hopefully be merged soon). |
This pull request is for broader tests and further discussion.