Description
xdmx
2007-09-02 18:20:49 UTC
Someone also wrote some working code in QT4: http://linuxfr.org/comments/861256,1.html (Though he does not guarantee that it is exactly the same algorithm.) I voted for this request because it is one of the most awesome features I've ever seen. Wow! *** This bug has been confirmed by popular vote. *** An implementation is available at http://diit.sourceforge.net/dirt.html Gilles Summary of the pano-tools thread http://www.nabble.com/smart-resizer----now-a-Photoshop-plugin-tf4426241.html There is also a gimp plugin http://web.tiscali.it/carlobaldassi/ (installation as non-root does not work out-of-the-box, but otherwise ok) and a non-source windows and linux version http://www.thegedanken.com/retarget/ (which on linux needs libwxgtk2.8-0, which I don't have ;-) (Of course you can buy a photoshop plugin for $95 http://picutel.com/index.html ;-) Bernhard Rode pointed out this one htp://sourceforge.net/project/showfiles.php?group_id=207056 on the mailing list. *** Bug 150671 has been marked as a duplicate of this bug. *** To be precise, the right source code to use where algorithm to resize image is, can be take in this package : http://sourceforge.net/project/showfiles.php?group_id=207056&package_id=248124&release_id=544657 Code is pure C Ansi. It must be adapted to support 16 bits color depth. I recommend to backport this code in digiKam core (as digikam/libs/seamstress) and : - Convert C Ansi code to C++. - To use Digikam::DImg class as image data container. - Implement 16 bits color depth support. - Identify all parameters suitable by end users with this tool - Make a small test program in command line to resize an image. - When all is fine with algorithm, add a new option to current Resize Image tool of Image Editor with all identified parameters - Implemented the the option in tool using the new C++ code from digiKam core. Note : It not need to implement a new Image Editor plugin. The current Resize tool just need to be patched. If somebody is interested to do it, let's me hear... Gilles I just tried Arachnee : it is great. It would be very nice to have this tool incoporated inside Digikam. Isn't it easier to patch the lib to deal with 16 bits instead of reimplementing within Digikam ? It would be nice to have a qt interface to select and deselect regions of the picture as in the gtk tool. http://sourceforge.net/projects/c-a-i-r/ (library) http://code.google.com/p/seam-carving-gui/ (qt4 gui) Good and fast, OS-independant. But that is gplv3 only, although it might be possible to contact the authors. Hello, I am a student in University Louis Pasteur of Strasbourg (France) and my second semester project is to work on the different library which using seam carving for image resizing. Me and another student are working to find the best one, making some test, patch the lib to deal with 16 bits images and create a GUI plugin for digikam. We have chosen three different library for our experiment: - Seamstress - Liquid Rescale - C-A-I-R Our results: Seamstress can't extend images and is too slow with big ones. C-A-I-R have some trouble with specific images (ball became square). But Liquid Rescale don't have any problem and is fast. That's why for us the best one is Liquid Rescale (which is already used in GIMP). So we are interested to develop this library and create a GUI for the Digikam software. NB: This projet is corresponding in any point to the google summer of code one. Thanks. Some references: http://liblqr.wikidot.com/ (The library) http://liquidrescale.wikidot.com/ (The plugin for GIMP) Created attachment 32540 [details]
Patch for Digikam (Content Aware Resizing GUI, works with LQR)
For my studies, I have made a content aware resizing plugin for Digikam (previous comment). Please notice that you will need to have installed the LQR library (http://liblqr.wikidot.com/). This plugin works for now only for 8-bits images. I will surely continue to work on it, so you can tell me any bug or wish. Thanks. Thanks Julien, I know already your work. Julien Nardoux has contacted me about... I will review your code. The most important point is to support 16 bits color depth. digiKam DImg image container support this color depth. It's very important to be able to use your code with 16 bits image as RAW. Where is the limitation in your patch ? It's in your code on in lqr library ? Anyway, Thanks for your job. Gilles Caulier In fact, LQR should support 16 bits color depth, but it seems to have a bug : when I try to call the function wich let me work on 16 bits images, it fails, saying that this function is undefined. I will look for the solution when I will have some free times. Julien I propose to place your code in svn trunk (digiKam 0.11). It's fine for you ? you have 2 solutions: ask to KDE svn account, or continue to make patch against svn trunk... There are some points to fix in your code, as to use multithreading interface from digiKam core to compute resizement of image. You pass QProgressBar in your code and it's not optimum. We have a delegate threaded code in DImg container for that. I will take a look... Gilles Caulier We need also a CMake module to find automatically LQR library and setup path and linkning configurations... Gilles Caulier Since there is no cmake module wich can find LQR library (as yous said), I think it is better that I continue make some patch for now. I have installed again the LQR library, it seems to work fine now (symbol functions are found). Therefore, my code doesn't work well. I will correct it. Ok, I note what you have said about the QProgressBar. Julien Andi, Julien, Here i have a version of plugin using an internal lqr library source code taken from liblqr libray git repository. This will be enough for the moment. we will study to use an external version of lqr later... I will commit this code in svn soon Gilles Andi, Julien, Code is here : http://websvn.kde.org/branches/work/~cgilles/contentawareresizing/ Just checkout it in digikam/imageplugins, and add : ADD_SUBDIRECTORY( contentawareresizing ) at end of digikam/imageplugins/CMakeLists.txt file to compile it. I have tested a little bit with some 8 bits images, but sound like the liquid rescale algorithm need to be set properlly to take a care of content. Try to resize this image (to convert to 8 bits): http://digikam3rdparty.free.fr/TEST_IMAGES/PNG/6-16bits-photo.png ...using non aspect ratio size, especially a large width. In theory, the kid must be untouched... and it's not the case... Gilles For me the image is not scaled correctly, too. I have a Gimp-Plugin based on LQR where you need to paint the objects you like to be unchanged. I don't know how to do this in digiKam where we have no such tools. The only thing you can do in the image editor is to draw a rectangle around ONE object (not many), but also when doing this the image is screwed up. Am I doing something wrong? For me every image gets "wavy", like it was sent through the liquify filter in Photoshop. Gilles, Your example is too difficult for the method. Julien Pontabry did not implement (yet) the possibility to paint on the objects to change the energy function by marking green and red regions to set the energy to +infinity and -infinity respectively. In your example, the background has way too much information ! as much as the kid so the algorithm does not know you want to save the kid ;-) We could think of improving the energy function to give a higher energy to pixel whose color is near skin tones, but this may generate bad results in some other cases... Julien Narboux To Julien Pontabry, Multithreading is now implemented in svn : http://websvn.kde.org/branches/work/~cgilles/contentawareresizing/ Please use this code for the future improvements. Gilles To Andi, Can you take a look in current implementation if all is fine for you ? In ContentAwareResizeDlg destructor, if i delete ContentAwareResizer container, plugin crash. Debug backtrace is not suitable here. Can you see a better trace on your computer ? To Julien Pontabry, I have completed your code review. Please continue to work with current implementation from svn. TODO : - implement cancel operation with lqr lib. I cannot find how to do it. - 16 bits color depth support. - Alpha Channel support (not sure if it currently supported in your code). Thanks in advance Gilles I will take a look at it... Ok, I will work with svn's implementation. I noted the TODO list. I will first work on the 16 bits color depth support. It may be finished next week. Thanks ! PS: Great job for the Multithreading ! Running in valgrind, the plugin is not crashing anymore, but I guess we might have some threading problem here, maybe LQR is not reentrant? ==12257== Thread 5: ==12257== Mismatched free() / delete / delete [] ==12257== at 0x4023E3A: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) ==12257== by 0x737FA15: g_free (in /usr/lib/libglib-2.0.so.0.2000.0) ==12257== by 0xFD15C87: lqr_carver_inflate (lqr_carver.c:727) ==12257== by 0xFD153CE: lqr_carver_build_vsmap (lqr_carver.c:536) ==12257== by 0xFD14D60: lqr_carver_build_maps (lqr_carver.c:325) ==12257== by 0xFD17F66: lqr_carver_resize_width (lqr_carver.c:1560) ==12257== by 0xFD1839C: lqr_carver_resize (lqr_carver.c:1664) ==12257== by 0xFD0EA51: DigikamContentAwareResizingImagesPlugin::ContentAwareResizer::filterImage() (contentawareresizer.cpp:126) ==12257== by 0x40E01C6: Digikam::DImgThreadedFilter::startFilterDirectly() (dimgthreadedfilter.cpp:139) ==12257== by 0x40DEE9F: Digikam::DImgThreadedFilter::run() (dimgthreadedfilter.cpp:152) ==12257== by 0x50BC45D: (within /usr/lib/libQtCore.so.4.5.0) ==12257== by 0x52CC154: start_thread (in /lib/libpthread-2.9.so) ==12257== Address 0x14f5f028 is 0 bytes inside a block of size 751,184 alloc'd ==12257== at 0x402434E: operator new[](unsigned int) (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) ==12257== by 0x40A3543: Digikam::DImg::allocateData() (dimg.cpp:293) ==12257== by 0x40A4853: Digikam::DImg::putImageData(unsigned int, unsigned int, bool, bool, unsigned char*, bool) (dimg.cpp:219) ==12257== by 0x40A9B2C: Digikam::DImg::DImg(unsigned int, unsigned int, bool, bool, unsigned char*, bool) (dimg.cpp:113) ==12257== by 0x40A9BE7: Digikam::DImg::copyImageData() (dimg.cpp:941) ==12257== by 0x40DFDBC: Digikam::DImgThreadedFilter::DImgThreadedFilter(Digikam::DImg*, QObject*, QString const&) (dimgthreadedfilter.cpp:59) ==12257== by 0xFD0EE4A: DigikamContentAwareResizingImagesPlugin::ContentAwareResizer::ContentAwareResizer(Digikam::DImg*, unsigned int, unsigned int, QObject*) (contentawareresizer.cpp:68) ==12257== by 0xFD100E2: DigikamContentAwareResizingImagesPlugin::ContentAwareResizeDlg::slotOk() (contentawareresizedlg.cpp:393) ==12257== by 0xFD102B0: DigikamContentAwareResizingImagesPlugin::ContentAwareResizeDlg::slotButtonClicked(int) (contentawareresizedlg.cpp:229) ==12257== by 0x4AE4DC3: KDialog::qt_metacall(QMetaObject::Call, int, void**) (in /usr/lib/libkdeui.so.5.2.0) ==12257== by 0xFD13917: DigikamContentAwareResizingImagesPlugin::ContentAwareResizeDlg::qt_metacall(QMetaObject::Call, int, void**) (contentawareresizedlg.moc:72) ==12257== by 0x51C5268: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/libQtCore.so.4.5.0) ==12257== ==12257== Thread 1: ==12257== Invalid free() / delete / delete[] ==12257== at 0x402349A: operator delete[](void*) (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so) ==12257== by 0x40ADC73: Digikam::DImgPrivate::~DImgPrivate() (dimgprivate.h:60) ==12257== by 0x40ADDB6: Digikam::DSharedDataPointer<Digikam::DImgPrivate>::~DSharedDataPointer() (dshareddata.h:112) ==12257== by 0x40A4154: Digikam::DImg::~DImg() (dimg.cpp:158) ==12257== by 0x40DF45A: Digikam::DImgThreadedFilter::~DImgThreadedFilter() (dimgthreadedfilter.cpp:93) ==12257== by 0xFD0EC71: DigikamContentAwareResizingImagesPlugin::ContentAwareResizer::~ContentAwareResizer() (contentawareresizer.cpp:115) ==12257== by 0xFD10404: DigikamContentAwareResizingImagesPlugin::ContentAwareResizeDlg::~ContentAwareResizeDlg() (contentawareresizedlg.cpp:219) ==12257== by 0xFD0D126: ImagePlugin_ContentAwareResizing::slotContentAwareResizing() (imageplugin_contentawareresizing.cpp:73) ==12257== by 0xFD0E062: ImagePlugin_ContentAwareResizing::qt_metacall(QMetaObject::Call, int, void**) (imageplugin_contentawareresizing.moc:69) ==12257== by 0x51C5268: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/libQtCore.so.4.5.0) ==12257== by 0x51C567F: QMetaObject::activate(QObject*, QMetaObject const*, int, int, void**) (in /usr/lib/libQtCore.so.4.5.0) ==12257== by 0x554C7E0: QAction::triggered(bool) (in /usr/lib/libQtGui.so.4.5.0) ==12257== Address 0x14f5f028 is not stack'd, malloc'd or (recently) free'd When running in gdb you can see that DImg tries to free data that is already deleted (by the other thread?)... Andi Gilles, if I am not totally wrong I think the problem is this line, (contentawareresizer.cpp:93): d->carver = lqr_carver_new(m_orgImage.bits(), m_orgImage.width(), m_orgImage.height(), 4); We give this carver object a pointer to the DImg data, and I guess when the carver is destroyed, it cleans up the image data. DImg tries to free it (the data pointer is still valid), but the data is already gone. What do you think? Andi Andi, You have right. a copy of image data need to be paste to lqr library. It's not optimum, but there is no other way for the moment, i think... Gilles SVN commit 948753 by cgilles: make a deep copy of original image data pasted to lqr library. these data will be deleted by lqr. CCBUGS: 149485 M +1 -3 contentawareresizedlg.cpp M +8 -4 contentawareresizer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=948753 Gilles, maybe it is enough to delete the carver object with "delete d->carver" instead with this destroy method? It doesn't crash here, but I don't know if this is the right way. Maybe not... I just posted on the LQR forum to ask for other ways to destroy such a carver object. Andi SVN commit 948777 by cgilles: 16 bits color depth support. Do not work yet, and i don't know why... CCBUGS: 149485 M +12 -8 contentawareresizer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=948777 SVN commit 948796 by cgilles: great : now 16 bots color depth support work fine !!! CCBUGS: 149485 M +13 -25 contentawareresizer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=948796 Great job !! Thanks. Julien, Andi, lqr library has a problem to rescale 16 bits image : it give artifacts ! Look my comparison here : http://farm4.static.flickr.com/3416/3411750178_76585a8bd3_o.png Same image, PNG files, 8 and 16 bits. RGB ecoding is integer. Image is resized up horizontally and vertically to 200% Please report this problem to libsqr team. Thanks in advance Gilles Caulier Forget to said that libsqr code included in svn with plugin come from current libsqr git repository (> 0.3.0 version) Gilles Caulier (In reply to comment #17) > We need also a CMake module to find automatically LQR library and setup path > and linkning configurations... > > Gilles Caulier Gilles, I guess it is best to have LQR included in the plugin source. There is no way to install it on Windows (see their homepage), so writing a cmake detection module would be too much work I guess. We should keep it in the plugins dir... Andi SVN commit 949639 by cgilles: Liquid Rescale tool : now plugin use Image Editor Tool API. We can see preview of effect before to apply it on image ! CCBUGS: 149485 M +1 -1 CMakeLists.txt D contentawareresizedlg.cpp D contentawareresizedlg.h A contentawareresizetool.cpp contentawareresizedlg.cpp#949607 [License: GPL (v2+)] A contentawareresizetool.h contentawareresizedlg.h#949607 [License: GPL (v2+)] M +3 -4 imageplugin_contentawareresizing.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=949639 Wake up man !!!!!!!!! The vide demo is online : http://www.youtube.com/watch?v=5Sb1EajhYS8 Gilles Caulier Really Good Job !! I am working today on the option part of the plugin. You will be able to see it this afternoon ! Thanks, Julien Julien, Yesterday evening, I have already implemented Step and Rigidity options support in GUI. And whats about the 16 bits color depth artifact (look #36) ? It's really like a huge problem in lqr for the moment... Gilles Julien, New screenshot : http://farm4.static.flickr.com/3551/3417150165_a20fdac7b4_o.png Another very important point : _how_ to cancel lqr library processing ? I cannot find a way in source code. The goal is to be able to stop liquid rescale computation if user press Cancel or Stop button in GUI during processing please, please, please, contact lqr team, and try to find a issue for cancel and 16 bits color depth artifact, else, this plugin will be unsuitable, and bug report will be posted here about these problems... I have completed now all my fixes in your code. Feel free to patch liquid rescale tool like you want... Gilles Caulier Created attachment 32661 [details]
Liquid Rescale patch - some new options
Gilles,
I don't know yet how we could cancel lqr library processing. And I think there is something wrong when scanning 16 bits image produced by lqr. I don't yet what is wrong... But don't worry, I am looking for solutions !
I also join a patch. Now you can choose the gradient function (Some may have best results on some images...) and the resizing order (horizonally or vertically first). Some other options will be able soon.
Julien
SVN commit 950298 by cgilles: apply patch from Julien to add new options from LQR plugin CCBUGS: 149485 M +18 -3 contentawareresizer.cpp M +6 -1 contentawareresizer.h M +85 -48 contentawareresizetool.cpp M +11 -0 contentawareresizetool.h WebSVN link: http://websvn.kde.org/?view=rev&revision=950298 Julien, Warnings, your patch drop my last changes from svn, done today morning. Please, before to make changes, update code using "svn up" I will restore my last changes Gilles Julien, Old code restored in svn and merged with your patch. New screenshot : http://farm4.static.flickr.com/3315/3418588335_9a765ac911_o.png Gilles Caulier Julien, To make patch, please use "svn diff > mydiff.patch" against a fresh update of source code from KDE repository. Thanks in advance Gilles Caulier Gilles, Hmm that's really strange, my repository seems to be up to date... I will check it to see what is wrong. Julien Julien, If you do "svn up" from digikam root source code, "digikam/imageplugins/contentawareresizing" folder will not be updated because it come from another part of subversion repository. You need to go in "digikam/imageplugins/contentawareresizing" and run "svn up" again. I don't know how you have build your patch, but i'm sure that you have used an non-updated code against svn... Gilles Gilles, Yes that's right, I am sorry ! Thanks. Julien, In theory, when we resize several times the same picture with a decreasing amount of pixels (reduce by 100pixels, then by 90 pixels, etc). The first resize is slow, but the other should be quick because the visibility map is already computed by Lqr. To test this I replaced : lqr_carver_resize(d->carver, d->width, d->height); by : time_t h1, h2; time (&h1); lqr_carver_resize(d->carver, d->width, d->height); time (&h2); printf("Duration first resize %.2lf\n", difftime(h2,h1)); int i; for (i=1;i<100;i+=10) { time(&h1); lqr_carver_resize(d->carver, d->width+i, d->height+i); time(&h2); printf("Duration %.2lf\n", difftime(h2,h1)); }; The result I get is : Duration first resize 9,00 Duration 0,00 Duration 0,00 Duration 1,00 Duration 0,00 Duration 0,00 Duration 1,00 Duration 0,00 Duration 1,00 Duration 0,00 Duration 0,00 This means that the first resize takes 9 seconds, but the other ones take less than a second as expected. Their is something suboptimal in the plugin because if I click "try" several times it always takes 8 or 9 seconds. I do not undersand why. Is the constructor ContentAwareResizer::ContentAwareResizer called each time we click on "try" ? Julien Julien (pontabry), another point : to create patch you must run svn diff > mydiff.patch from "digikam/imageplugins/contentawareresizing",n ot "digikam" root folder. Gilles >I do not undersand why. Is the constructor
>ContentAwareResizer::ContentAwareResizer called each time we click on "try" ?
hum, i think yes...
Gilles
Gilles, When I do "svn up" in contentawareresizing folder, I get this message : "svn: Two top-level reports with no target". What does it mean ? >When I do "svn up" in contentawareresizing folder, I get this message :
>"svn: Two top-level reports with no target". What does it mean ?
well, No idea...
I recommend to remove all (digikam code) and:
1/ checkout digikam from trunk as well.
2/ checkout contentsawareresize folder from my svn home outside digikam.
3/ copy contentsawareresize folder in digikam/imageplugins
4/ change digikam/imageplugins/CMakeLists.txt to compile plugin
This is want i do in my computer.
Note : later, to include your code officially in digiKam, I will merge your plugin with current resize tool from editor core... But for the moment, code is not ready in resize tool for that. And it's not urgent...
Gilles
Good news! the author of Lqr as released a new version of the library: 0.3.1 which is supposed to fix the bug about 16bits pictures. He also told me that a function to stop computations will be available in the next release. Julien SVN commit 951013 by cgilles: update to lqr 0.3.1 CCBUGS: 149485 M +4 -4 lqr_base.h M +7 -7 lqr_carver.c WebSVN link: http://websvn.kde.org/?view=rev&revision=951013 Julien, Can you report to lqr library team to use /* ... */ to comment code in pure C Ansi and not // as in C++. I need to fix each time lqr code properlly before to include it in plugin. Look compilation errors : [ 91%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lqr_carver_bias.o In file included from /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_all.h:31, from /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:23: /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h:32: error: expected identifier or ‘(’ before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h:32: error: stray ‘#’ in program /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h:33: error: expected identifier or ‘(’ before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h:33: error: stray ‘#’ in program /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h:34: error: expected identifier or ‘(’ before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h:34: error: stray ‘#’ in program make[2]: *** [digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lqr_carver_bias.o] Error 1 make[1]: *** [digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/all] Error 2 make: *** [all] Error 2 [ 91%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lqr_carver.o /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c: In function ‘lqr_carver_build_mmap’: /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:406: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:424: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c: In function ‘lqr_carver_build_vsmap’: /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:513: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:524: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c: In function ‘lqr_carver_inflate’: /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:728: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:744: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c: In function ‘lqr_carver_update_mmap’: /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:937: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:939: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:940: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:955: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:987: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1002: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1013: error: expected expression before ‘/’ token /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1013: error: stray ‘#’ in program /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1040: error: stray ‘#’ in program /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c: In function ‘lqr_carver_build_vpath’: /mnt/data/devel/SVN/trunk/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1080: error: expected expression before ‘/’ token make[2]: *** [digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lqr_carver.o] Error 1 make[1]: *** [digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/all] Error 2 make: *** [all] Error 2 Thanks in advance Gilles Caulier Created attachment 32698 [details]
Patch to have quick preview
This patch adds a check box for quick preview. If quick preview is enabled the preview is computed on the scaled down version of the picture, otherwise it is computer on the original picture.
Julien
Julien, Why not to always work on preview in local and at end of course, working on original ? Can you see a difference between preview and original played with lqr library ? Gilles To Julien Pontabry, I have tested gimp plugin, and especially the way to set zones to preserve (mask). How we can do this without to make a complex gui ? We need absolutly this feature at least, because plugin give strange effect without (depending of image content of course). lqr team has planed to code something to automatize this job ? (or it's impossible to do ?) Gilles Gilles, The idea is to make a gui similar to seamcarving gui (http://code.google.com/p/seam-carving-gui/) without masks. One would paint in transparent green or transparent red on the preview image, the areas to be saved and deleted respectively. Julien Gilles, Concerning quick preview it seems to be quite correct with the examples I tried. But with some image with thin layers of pixels (think about a picture of a fence for exemple) it could be the case that the preview using scaled down version is very different from the normal version. Julien Gilles, As Julien said, the best way to preserve some zones in an image is to make binary colored mask (red/white for suppression, green/white for preservation) and use them when resizing. And I think Lqr lets us to use it in that way. The other way is to select (helped by the digikam selection tool) a part of the image (so this part will have a rectangular shape...). It may be possible to use this way with Lqr too. I am currently working on some research features about this algorithm, but I may be able to attach a new patch in the few next days. Julien. (In reply to comment #29) > You have right. a copy of image data need to be paste to lqr library. It's not > optimum, but there is no other way for the moment, i think... Gilles, why not introduce some flag to the DImg object that prevents the destructor from clearing the image data? There might be some other libraries in the future that free the image data by themselves (OpenCV) and so we would have to create a copy all the time we such a library. This will be a waste of memory, especially when processing RAW? We could set a flag (bool autoClearData = true), and when we use a lib that frees the data by itself, we just set the flag to false. Andi Andi, I'm agree in principle, but i'm not if flag is enough because image data are shared between DImg objects for memory optimization: DImg i1(...); DImg i2 = i1; i1 image data are shared with i2. If i1 is destroyed, i2 image become parent of i1 image data. There is a shared data manager written by Marcel at this place : http://lxr.kde.org/source/extragear/graphics/digikam/libs/dimg/dshareddata.h So, it must be more complicated to do. Ask details to Marcel. Gilles I just looked again at LQR, it wouldn't help here either. LQR takes the image data and manipulates it (also changes the size etc), so we really need to give the library a copy of the data. If I remember correctly, so does OpenCV... :-( So this really doesn't help... well it was just a quick thought :-) Andi Created attachment 32725 [details]
quick preview + improve option layout
SVN commit 951556 by cgilles: apply patch from Julien Nardoux for quick preview and new option layout. CCBUGS: 149485 M +3 -1 contentawareresizer.cpp M +54 -18 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=951556 Julien Nardoux, When a DImg container is allocated in local without to use "new" operator, you don't need to delete it. It will be done automatically. Gilles Julien, Never use tab in source code. It break all indentation and code become unreadble. use 4 spaces for one tab. Gilles Ok Gilles, I use tab because I use xemacs maybe I should move to Kdevelop ;-) Julien You can use kate editor. it's enough... Gilles (X)Emacs can use soft tabs, too :-) I mean one of the oldest programming editor should be capable of that... Andi Created attachment 32804 [details]
Content aware resizing patch - new option: mixed rescale
Hi everybody,
I have made a new patch. It gives a new option that allows you to perform "mixed rescale". This means combination of content aware resizing and standard resizing (smooth-scale).
Well, to use it, you have to check the corresponding check-box, and then you have to choose the percent of content aware resizing you want to apply. That's all.
I am working now on an automatic behavior of that option, and on preservation masks.
Julien.
Julien, I just tested your patch, it works fine when you apply the filter to the real image, but it does not work for the preview: I tried to reduce width by 50%, with only 1% of liquid rescale and I get a preview which seems to be computed only with liquid rescale. The final is ok though. I think instead of modifying both prepareEffect and prepareFinal, you could code this option in the contentawareresizer.cpp file. This would allow factorizing this part of code. I am not sure the check box is needed, maybe the slider alone is sufficient. Gilles, Andi what do you think ? You could change the range to go from 0 to 100% instead of 1 to 100%. Julien Narboux Julien, I thought about it again, and I think you can not do it in contentawareresizer as the carver would need to be updated... This is more complicated : we need to build the carver at first preview, rebuild the carver if the user change the "mix" slider, and not rebuild the carver if the user change only the size... Julien Narboux Created attachment 32809 [details]
Screenshot of the mixed rescale option
Julien,
That's really strange because it works fine for me. Look at the attachment.
Julien.
SVN commit 953093 by cgilles: apply patch from julien to add new option named "Mixed Rescale" CCBUGS: 149485 M +146 -63 contentawareresizetool.cpp M +1 -0 contentawareresizetool.h WebSVN link: http://websvn.kde.org/?view=rev&revision=953093 To Julien Pontabry, I'm agree with Julien Nardoux. I cannot see any difference with preview mode if i enable or not "mixed rescale" option. Or i missing something... Tip : when new option is added, please feel readSettings() and saveSettings() methods accordingly. Best Gilles Julien, I think I found the bug, it works when you change width but no height for me, I think the size of the preview is not the size of the image but the image of the image and black area, if you replace : int diff_w = stdRescaleP * (imTemp.width() - new_w); int diff_h = stdRescaleP * (imTemp.height() - new_h); with int diff_w = stdRescaleP * (w - new_w); int diff_h = stdRescaleP * (h - new_h); it seems to solve the bug. Julien That's right ! It worked only on the width, I didn't see it. Thanks for the solution :-) Julien. Julien Pontabry, Are you working to fix #82 ? Anyway, see below my tips to implement preservation masks. I think you want implement something like Gimp plugin here, with hands raised mask painting. Currently, your plugin use ImageWidget to draw preview. This widget do not support zoom/panning. It's another preview widget. I recommend to always use this widget at this moment. We have planed to merge and refactoring all preview widgets together, but later in this year. Especially, the goal is to have zoom/pan feature everywhere, for all image plugins preview (one preview widget for all tools in fact) So for the moment, we will playing with ImageWidget, which use ImageGuideWidget internally. Implementation is in digikam/libs/widgets/imageplugins. To implement preservation mask you must add 2 semi-transparent Pixmap to draw over preview image. On with Red color (to remove parts) and one green (to preserve parts). This pixmap will be display on over preview by updatePixmap() http://lxr.kde.org/source/extragear/graphics/digikam/libs/widgets/imageplugins/imageguidewidget.cpp#234 I recommend to patch this widget directly and not to subclass ImageWidget, because i will use mask tool with Inpainting plugin to solve this bugzilla entry : https://bugs.kde.org/show_bug.cgi?id=110920 Now, to draw mask over preview, you can take inspiration from Marcel code: http://lxr.kde.org/source/extragear/graphics/digikam/utilities/fuzzysearch/sketchwidget.cpp This widget is used to draw a sketch to perform fuzzy search over digiKam database : http://farm4.static.flickr.com/3235/2605584602_5049955cb6_o.png You can change pencil size and redo/undo feature is available. This is enough to paint mask. This want mean than sketch code must be implemented somewhere in ImageGuideWidget. Later, when we will merge all image plugins preview widgets, we will take a care about sketch code and all other features implemented. Marcel, Andi, what do you think about ? This plan is fine for you ? Gilles Created attachment 32858 [details]
Patch to solve preview bug, remove MixedRescaleBox
This patch solve preview problem. It removes mixed rescale box. Settings are disabled when Mixed rescale is set to 0%.
Well, Julien has just brought a patch to fix the #82. Gilles, thank you for your helpful tips ! I work on that part when I have some free time (may be soon) :-) (In reply to comment #84) > Marcel, Andi, what do you think about ? This plan is fine for you ? Yes, fine. Andi SVN commit 954546 by cgilles: Apply patch #32858 from Julien Nardoux CCBUGS: 149485 M +41 -49 contentawareresizetool.cpp M +1 -1 contentawareresizetool.h WebSVN link: http://websvn.kde.org/?view=rev&revision=954546 to Julien Pontabry, Additional info for #84 : With your new preview widget which support preservation masks, you need to work like this to format/pass masks to lqr : * From digkam thread : 1/ For preview widget get QPixmap mask. 2/ Convert it to QImage. 3/ Pass QImage reference to LQR thread. Note : Do not pass QPIxmap to a separate thread, it device depand class, it will not work. * In LQR thread : 1/ Resize QImage to right dimensions if final rendering is require. For preview we don't care. You can play in a separate thread with QImage, this class is re-entrant. 2/ Scan all pixels from QImage mask and create a formatted array for lqr library. Gilles Caulier SVN commit 954995 by cgilles: sync lqr library with current implementation from Git repository. Cancel function is now ready to use... CCBUGS: 149485 M +6 -4 lqr_base.h M +206 -41 lqr_carver.c M +2 -0 lqr_carver_bias.c M +15 -0 lqr_carver_list.c M +1 -0 lqr_carver_list_pub.h M +78 -49 lqr_carver_priv.h M +2 -0 lqr_carver_pub.h M +3 -0 lqr_carver_rigmask.c M +3 -0 lqr_vmap.c WebSVN link: http://websvn.kde.org/?view=rev&revision=954995 SVN commit 955009 by cgilles: Liquid Rescale Tool : implement cancelable operations CCBUGS: 149485 M +7 -0 contentawareresizer.cpp M +1 -0 contentawareresizer.h WebSVN link: http://websvn.kde.org/?view=rev&revision=955009 Created attachment 32887 [details]
Remove deep copy thanks to new Lqr function
Patch which use new Lqr function to tell Lqr not to preserve the picture. Remove deep copy which not needed any more.
Julien Narboux
SVN commit 955285 by cgilles: apply patch #32887 from Julien Nardoux CCBUGS: 149485 M +5 -5 contentawareresizer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=955285 to Julien Pontabry, What's news here ? I propose to move plugin from my temp dir to digiKam dir now. Like this i can start to implement CMake rule to detect lqr library. Also, if you have not yet implemented something in preview widget about mask creation, i can start this job. What do you think about ? Gilles To Gilles, I finish to implement mask tools. For now, there are no undo/redo tool and pen's size tool. This can be made later. But Lqr doesn't seem to take care of the bias I give. I am working on this now. I will probably attach a patch today. Julien. Great... Today i'm at home and i can review your patch quickly. I will move plugin code to digiKam after that. Next week it's holliday time. I would to finalize this plugin. I will have more free time to do it. Gilles Created attachment 33030 [details]
Patch for mask tools on Digikam's preview widgets
This is the first patch on digikam/libs/widgets/imageplugins/.
Created attachment 33031 [details]
Patch for mask tools on content aware resizing plugin
This is the second patch, on the plugin.
That's really strange because Lqr doesn't seem to use the given bias table. Can you look if I have make any mistakes Gilles ?
Julien
Yes, i review your code now... I will also move plugin to digiKam officialy, including your last patch. It will be more easy to maintain code from core preview widget and plugin... Gilles SVN commit 958074 by cgilles: apply patch #33031 CCBUGS: 149485 M +49 -4 contentawareresizer.cpp M +8 -1 contentawareresizer.h M +163 -30 contentawareresizetool.cpp M +2 -0 contentawareresizetool.h WebSVN link: http://websvn.kde.org/?view=rev&revision=958074 SVN commit 958075 by cgilles: apply patch #33030 CCBUGS: 149485 M +1 -1 imageplugins/CMakeLists.txt M +202 -77 libs/widgets/imageplugins/imageguidewidget.cpp M +11 -4 libs/widgets/imageplugins/imageguidewidget.h M +28 -11 libs/widgets/imageplugins/imagewidget.cpp M +6 -1 libs/widgets/imageplugins/imagewidget.h WebSVN link: http://websvn.kde.org/?view=rev&revision=958075 SVN commit 958077 by cgilles: move Liquid Rescale tool to digiKam core !!! D branches/work/~cgilles/contentawareresizing (directory) A trunk/extragear/graphics/digikam/imageplugins/contentawareresizing (directory) branches/work/~cgilles/contentawareresizing#958076 to Julien Pontabry, Patches applied to svn. Plugin moved to digiKam core. take a care when you update code. Remove of plugin dir. Yes, i confirm, make is never used by lqr. I don't know why. Just checked lqr code : we use last one available from lqr git repository Gilles Julien, Well, it's simple. With my commit #958156 : SVN commit 958156 by cgilles: add debug M +1 -0 contentawareresizer.cpp --- trunk/extragear/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp #958155:958156 @@ -232,6 +232,7 @@ } } + kDebug(50003) << "Set LibLqr mask..." << endl; lqr_carver_bias_add(d->carver, d->bias, 10000); } } ... I never seen debug message in the console about mask stuff... Gilles Julien, With my last commit, i can said : - Mask create is fine. - Mask is passed to LQR. If in void ContentAwareResizer::buildBias() i save mask QImage in local file, all is fine. - Mask is not used with preview and final computation by LQR. Perhaps something is wrong in your loop to compute d->bias ? I recommend to take a look in gimp plugin. Perhaps something is missing to initiate LQR with mask... Gilles That's really strange : adding a red mask on a picture and applying lqr, the result is different than just applying lqr. I'm going to look how is made the mask part of gimp plugin. Created attachment 33051 [details]
Patch for the bug of mask tool problem
Ok, I resolved this bug !
SVN commit 958551 by cgilles: apply patch #33051 CCBUGS: 149485 M +3 -3 contentawareresizer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=958551 To Julien, Well if it work for you, not for me. Nothing is do with preservation mask or suppression mask... The object is not untouched or removed... I will post a screenshot of my settings and my test image. Gilles Created attachment 33052 [details]
preview of liquid rescale using preservation mask (do not work)
Created attachment 33053 [details]
small test image for liquid rescale tool
To Julien, Just test. I doest work in preview and final with my test image. Look screenshot for details. Gilles Hmm, well it's working for me. Note that for now you can't use masks with preview. Created attachment 33058 [details]
Test image before liquid resizing
Created attachment 33059 [details]
Test image after liquid resizing
Ah yes, it's work fine now... With preservation mask. Before : http://farm4.static.flickr.com/3600/3471384222_4dbb60eb8c_o.png And after : http://farm4.static.flickr.com/3620/3471384790_ed0079a15f_o.png Gilles Caulier The question is : Why it's doesn't work with preview... Gilles That's simple : I don't have implemented it yet. It may be implemented soon ;-) Created attachment 33078 [details] New test image to check preservation Mask (taken from Iceland By Gerhard Kulzer) With this new test image, i have play to make 2 preservations zone, and it work fine : Original image: http://farm4.static.flickr.com/3310/3472983544_8f9b337f9b_o.png Settings Liquid Rescale preservation mask: http://farm4.static.flickr.com/3355/3472983788_3148de108d_o.png Target image: http://farm4.static.flickr.com/3404/3472176295_a4f90369e6_o.png Julien, I have see that if scaling horizontally up to 150%, sometime preservation do not work. I don't know why. Other feedback : Suppression mask never work for me. I will post another test image and screenshots... Gilles Created attachment 33079 [details]
New test image to check suppression Mask (taken from Iceland By Gerhard Kulzer)
Created attachment 33080 [details]
Screenshot : suppression mask creation.
Created attachment 33081 [details]
Screenshot : suppression mask result : it doesn't work...
To Gilles, That's normal. Because when you enlarge an image, you don't suppress any pixels, you add some pixels. So to produce the result you want, you have to reduce the width (with the suppression mask) and then you enlarge your image to the width you want. Julien Ok, now i understand. Thanks... But, current behavours can trouble end users. We need to improve it in the future: My proposals : 1/ Switch off suppression mask is users want to expand image size. 2/ Compute all operations require to give suppression mask available if size is expanded: reduce and after expand. This can be more complicated, and i don't know if results will be suitable. What do you think about ? Gilles Caulier Created attachment 33083 [details]
Small patch to factorize code
This small patch fatorize some code. It also disable the mask tools when content aware mix is set to 0%.
Next step to do is to factorize more code between preview and final computation, this would solve the problem about masks feature missing in preview.
About the Gui of masks, I think we have a problem: when the preview is resized the masks should not be resized... and so they do not fit on the preview image. I think the preview masks should be displayed in another tab: One tab for preview image, another tab for mask, and in the future another tab to preview eneregy, and in the future another tab to preview seams. I an a word, it would be nice if preview widget would allow to have several tabs. Another point: If the user want to delete a part of the picture using deletion mask without changing the size of picture, for the time being as Julien said he has to reduce and the enlarge the picture in two steps. Perhaps it would be more convenient to automatize this as it is done in the gimp plugin. But I think it is another feature using CAIR but still another feature, maybe it should appear as another "plugin" ? or another option in the Inpainting plugin. Another point about Gui: Sometime the user wants to get a precise aspect ratio: for that he can either enlarge the width or reduce the height or both (or the opposite depending on aspect ratio). Maybe we should reflect this in the Gui ? what do you think ? Maybe we could display the aspect ratio in the Gui ? This feature could also be integreted in the aspect ratio crop tool. The user could select a region of the picture to crop and if "content aware ratio crop" option is checked, the selected region would be automatically resized to fit the required aspect ratio. What do you think ? Julien To Gilles, I think suppression mask should not be disabled when enlarging, because when enlarging those "red pixels" are those who are choosen in prorority to be duplicated to enlarge the picture. So maybe we should find another name for "suppression mask" because it suppress only when reducing the picture, when enlarging it is more a kind of an "enlarging mask". Julien To Julien and Julien, Please contact LQR library author to : 1/ Include this pedantic fix for next release : http://websvn.kde.org/trunk/extragear/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h?r1=958077&r2=959015 2/ Ask to him if he can join us in this room to talk about LQR. Thanks in advance... Gilles Caulier Julien(s): My blog entry is dedicated for you (:=))) : http://www.digikam.org/node/439 Gilles Caulier SVN commit 959256 by cgilles: apply patch #33083 from Julien Nardoux CCBUGS: 149485 M +37 -60 contentawareresizetool.cpp M +6 -0 contentawareresizetool.h WebSVN link: http://websvn.kde.org/?view=rev&revision=959256 Created attachment 33105 [details]
First draft of skin tone detection
This is a first draft of skin tone detection. This has not been tested and hence should not work. I submit the patch only to prevent duplicated work between Julien Pontabry and me.
Julien
To Julien Nardoux: I cannot apply your last patch #33105: [gilles@localhost contentawareresizing]$ patch -p0 < 2.patch patching file contentawareresizer.cpp patching file contentawareresizetool.h Reversed (or previously applied) patch detected! Assume -R? [n] y patching file contentawareresizer.h patching file contentawareresizetool.cpp Hunk #1 succeeded at 122 (offset 1 line). Hunk #2 succeeded at 266 with fuzz 2 (offset 1 line). Hunk #3 succeeded at 336 (offset 1 line). Hunk #4 succeeded at 395 (offset 1 line). Hunk #5 FAILED at 505. Hunk #6 FAILED at 574. Hunk #7 FAILED at 583. Hunk #8 FAILED at 602. Hunk #9 succeeded at 617 (offset -23 lines). 4 out of 9 hunks FAILED -- saving rejects to file contentawareresizetool.cpp.rej Yesterday evening i have applied patch #33083 and sound like #33105 include it. Please don't forget to update your local reporsitory before to generata a new patch... Gilles Created attachment 33110 [details]
Skin Tone detection: first draft
First draft of Skin Tone detection, not detested yet. Compile fine and do not crash. Submitted only to avoid duplicated work.
This patch also disable some settings at plugin startup if needed.
Julien
SVN commit 959373 by cgilles: apply patch #33110 from Julien Nardoux CCBUGS: 149485 M +49 -3 contentawareresizer.cpp M +3 -1 contentawareresizer.h M +43 -26 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=959373 Created attachment 33114 [details]
Liquid Rescale tool under Windows Vista...
Yes, Liquid Rescale tool compile fine under Windows Vista using MinGW. Look below:
# dir
Le volume dans le lecteur C s'appelle Vista
Le numéro de série du volume est 7488-8C34
Répertoire de C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing
26/04/2009 10:59 <REP> .
26/04/2009 10:59 <REP> ..
26/04/2009 10:59 <REP> CMakeFiles
24/04/2009 08:13 1 450 CMakeLists.txt
26/04/2009 10:34 2 598 cmake_install.cmake
26/04/2009 10:27 9 553 contentawareresizer.cpp
26/04/2009 10:27 2 122 contentawareresizer.h
26/04/2009 10:27 27 571 contentawareresizetool.cpp
25/04/2009 18:38 28 089 contentawareresizetool.cpp~
26/04/2009 10:27 2 194 contentawareresizetool.h
26/04/2009 10:38 3 385 contentawareresizetool.moc
26/04/2009 10:34 431 CTestTestfile.cmake
26/04/2009 10:27 595 digikamimageplugin_contentawareresizing.desktop
26/04/2009 10:38 331 digikamimageplugin_contentawareresizing_automoc.cpp
26/04/2009 10:34 2 997 digikamimageplugin_contentawareresizing_automoc.cpp.files
24/04/2009 08:13 447 digikamimageplugin_contentawareresizing_ui.rc
24/04/2009 08:13 2 733 imageplugin_contentawareresizing.cpp
24/04/2009 08:13 1 625 imageplugin_contentawareresizing.h
26/04/2009 10:37 2 552 imageplugin_contentawareresizing.moc
25/04/2009 18:15 <REP> lqr
26/04/2009 10:34 25 690 Makefile
17 fichier(s) 114 363 octets
4 Rép(s) 7 097 962 496 octets libres
# make clean
# make
Generating imageplugin_contentawareresizing.moc
Generating contentawareresizetool.moc
[ 0%] Built target digikamimageplugin_contentawareresizing_automoc
[ 0%] Built target digikamcore_automoc
[ 91%] Built target digikamcore
[ 91%] Building CXX object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/digi
kamimageplugin_contentawareresizing_automoc.obj
[ 91%] Building CXX object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/imag
eplugin_contentawareresizing.obj
[ 91%] Building CXX object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/cont
entawareresizer.obj
[ 91%] Building CXX object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/cont
entawareresizetool.obj
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp: In member function `virtual void Di
gikamContentAwareResizingImagesPlugin::ContentAwareResizeTool::prepareEffect()':
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp:566: warning: converting to `int' fr
om `double'
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp:567: warning: converting to `int' fr
om `double'
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp:572: warning: converting to `int' fr
om `double'
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp:573: warning: converting to `int' fr
om `double'
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp: In member function `virtual void Di
gikamContentAwareResizingImagesPlugin::ContentAwareResizeTool::prepareFinal()':
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp:599: warning: converting to `int' fr
om `double'
C:\temp\devel\graphics\digikam\imageplugins\contentawareresizing\contentawareresizetool.cpp:600: warning: converting to `int' fr
om `double'
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_carver_bias.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_carver.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_carver_list.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_carver_rigmask.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_cursor.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_gradient.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_progress.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_vmap.obj
[100%] Building C object digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/lqr/lq
r_vmap_list.obj
Linking CXX shared module ..\..\..\bin\digikamimageplugin_contentawareresizing.dll
[100%] Built target digikamimageplugin_contentawareresizing
Created attachment 33115 [details]
Liquid Rescale tool under Windows Vista... The result !
Hi, I'm the LqR team :) thanks for the invitation. Also, I'm really glad you're using the liblqr library in DigiKam. Here are my remarks on what I've read so far: 1) "I have see that if scaling horizontally up to 150%, sometime preservation do not work. I don't know why." I suspect it is due to excessive enlargement. You should use the function lqr_carver_set_enl_step(carver, enl_step) to overcome this. However, no enlargement step is optimal in general. What I did in the GIMP plugin was setting it to 1.5 and adding an option to change it. However, it should be possible to approximately calculate the max amount allowed in order to keep the preserved areas intact, like this: max_enl_step = 2 - (pres_area_max_width / image_width) where pres_area_max_width is the maximum number of preserved pixels in a line. In this case, I still suggest to use a value less than 2 for the enl_step, and do something like: enl_step = min (max_enl_step, 1.5) 2) I also recommend to call lqr_carver_set_side_switch_frequency(carver, switch_frequency) with a small switch frequency (2 to 4 should be fine). 3) Maybe I have missed something in your code, but I think you should free the preservation/suppression mask buffer d->bias after the call to lqr_carver_add_bias. BTW, looking at your code, I have decided that I will add a new function to add a bias on pixel-by-pixel basis, so that you won't need to build a buffer at all and the code will be more readble, I'll keep you posted when it's done 4) I've applied the last patch that Gilles requested 5) I have almost finished building the new framework for the energy computation, therefore it shouldn't take too long before version 0.4 of the library is out. In the meeanwhile, there's a new branch in the git repo called "energy" which is also compatible with the old framework (but documentation is still lacking). It would be nice if someone else besides me tests it. 6) I wanted to ask you if it would be a problem for you to also link to the babl and/or gegl libraries: this is not for the immediate future, but I wanted to take advantage of the facilities which those libraries provide to manage different kinds of color models etc. (I have already addded some preliminary support for CYMK images, but I think using a dedicated library would make more sense and allow for a more general and optimised interface). If it is a problem, I would add some preprocessing directives to the code when I do it, and let the library be compiled with or without it, I'm just afraid it will mess things up. To Julien Nardoux, comment #127: >I think the preview masks should be displayed in another tab: Well, no. I think it's a wrong concept. When i have implemented preview widget for editor tools, some years ago (KDE3), i have tried tabbed preview. It's not suitable and not intuitive. You need to switch to/back to see results/settings. It's better to have all on the same view. >Another point: If the user want to delete a part of the picture using deletion >mask without changing the size of picture, for the time being as Julien said he >has to reduce and the enlarge the picture in two steps. Perhaps it would be >more convenient to automatize this as it is done in the gimp plugin. But I >think it is another feature using CAIR but still another feature, maybe it >should appear as another "plugin" ? or another option in the Inpainting plugin. Another plugin ? Why. It will increase complexity. The gimp way sound fine for me, if all is include in the same tool and automated. Inpainting tool is completly different. It's based onCImg and i plan to add suppresion mask creation in the future (CImg support this feature) >Another point about Gui: Sometime the user wants to get a precise aspect ratio: >for that he can either enlarge the width or reduce the height or both (or the >opposite depending on aspect ratio). Maybe we should reflect this in the Gui ? >what do you think ? Why not. But i recommend to wait more feedback from users when tool will be published. No need to add more and more options at the same time, else ergonomy will be destroyed. >Maybe we could display the aspect ratio in the Gui ? It will increase complexity again of preview widget implementation. Don't forget that we need to merge all preview widget to one common implementation. >This feature could also be integreted in the aspect ratio crop tool. The user >could select a region of the picture to crop and if "content aware ratio crop" >option is checked, the selected region would be automatically resized to fit >the required aspect ratio. What do you think ? Implementation of Aspect Ratio Crop is completely different and separated in another tool. Nothing is common. I will be complex and long to merge both tool. I think it's a dangerous way... sorry... Gilles >Hi, I'm the LqR team :) thanks for the invitation. Great ! >Also, I'm really glad you're >using the liblqr library in DigiKam. >Here are my remarks on what I've read so far: ok >1)"I have see that if scaling horizontally up to 150%, sometime preservation do >not work. I don't know why." >I suspect it is due to excessive enlargement. You should use the function >lqr_carver_set_enl_step(carver, enl_step) to overcome this. However, no >enlargement step is optimal in general. What I did in the GIMP plugin was >setting it to 1.5 and adding an option to change it. However, it should be >possible to approximately calculate the max amount allowed in order to keep the >preserved areas intact, like this: >max_enl_step = 2 - (pres_area_max_width / image_width) >where pres_area_max_width is the maximum number of preserved pixels in a line. >In this case, I still suggest to use a value less than 2 for the enl_step, and >do something like: >enl_step = min (max_enl_step, 1.5) Julien(s), this tip is for you (:=))) >2)I also recommend to call lqr_carver_set_side_switch_frequency(carver, >switch_frequency) with a small switch frequency (2 to 4 should be fine). Idem >3)Maybe I have missed something in your code, but I think you should free the >preservation/suppression mask buffer d->bias after the call to >lqr_carver_add_bias. BTW, looking at your code, I have decided that I will add >a new function to add a bias on pixel-by-pixel basis, so that you won't need to >build a buffer at all and the code will be more readble, I'll keep you posted >when it's done Idem >4)I've applied the last patch that Gilles requested Fine. Patch are done by KDE core team who build whole KDE including digiKam under a lots of different computers, OS, and compilers. >5)I have almost finished building the new framework for the energy computation, >therefore it shouldn't take too long before version 0.4 of the library is out. >In the meeanwhile, there's a new branch in the git repo called "energy" which >is also compatible with the old framework (but documentation is still lacking). >It would be nice if someone else besides me tests it. If you want, i can include this code in digiKam to test. For the moment, including lqr as well in digiKam is the faster way to hack and code. Later, we will add an external depency of course. >6)I wanted to ask you if it would be a problem for you to also link to the babl >and/or gegl libraries: this is not for the immediate future, but I wanted to >take advantage of the facilities which those libraries provide to manage >different kinds of color models etc. Damned, it will increase complexity. Unforget that we work too under windows, and to add more depencies is really a mess under win32. I have fight a lots to add a suitable GLib2 under Vista to compile and test digiKam Liquid Rescale tool. If you want to support more color model, why not to use lcms library ? It's not enough ? >(I have already addded some preliminary >support for CYMK images, but I think using a dedicated library would make more >sense and allow for a more general and optimised interface). If it is a >problem, I would add some preprocessing directives to the code when I do it, >and let the library be compiled with or without it, I'm just afraid it will >mess things up. In digiKam we only support RGBA (8 and 16 bits colors depth) not CYMK... which is enough for 90% of case. CYMK is only for printing i think. Working in RGBA and later convert to printer color model using the right print color profile work fine. Gilles Caulier > If you want, i can include this code in digiKam to test. Actually, I don't think it's a good idea for the moment, as the code is under heavy development. I was just looking for volunteers :) > Damned, it will increase complexity. Unforget that we work too under windows, > and to add more depencies is really a mess under win32. I have fight a lots to > add a suitable GLib2 under Vista to compile and test digiKam Liquid Rescale > tool. Right, I suspected it. I think I will go for the preprocessors then. > If you want to support more color model, why not to use lcms library ? It's > not enough ? The main reason is that GIMP is going to use babl and when it does I think it would be silly to use yet another library and convert back and forth. A minor reason is that I didn't know about lcms ;) > In digiKam we only support RGBA (8 and 16 bits colors depth) not CYMK... which > is enough for 90% of case. CYMK is only for printing i think. Working in RGBA > and later convert to printer color model using the right print color profile > work fine. Yes, there's a loooong ongoing discussion in GIMP about including native CYMK support (there are some circumstances under which doing the conversion leads to problems). Anyway, support for different color models was mainly intended for Imagemagick (which supports CYMK and uses liblqr, too), but since I had to include support for another color model I thought it would be nice to generalise as much as possible. Gilles, >>I think the preview masks should be displayed in another tab: >Well, no. I think it's a wrong concept. When i have implemented preview widget >for editor tools, some years ago (KDE3), i have tried tabbed preview. It's not >suitable and not intuitive. You need to switch to/back to see results/settings. >It's better to have all on the same view. What I meant was just a tab to display either preview or masks, settings would be available all the time as it is now. Julien Yes, Julien. By Settings, i want mean Mask view in fact. How to build mask without to see original image. With preview widget, there is a mode to switch between original and target (see upper button with Curves Adjust tool for ex.) We can use it here... Gilles To Carlo Baldassi : Are you already tried to compile lqr libray under Microsoft MSVC 9 2008 ? Because here, version include to digiKam won't compile. Note that on the same computer, same code compile fine with MinGw... See below error messages from compiler. Sorry it's in French (:=)))) Compilation en cours... cl : Ligne de commande warning D9025 : substitution de '/W3' par '/w' lqr_vmap_list.c .\lqr\lqr_vmap_list.c(72) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(72) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(72) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(72) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap_list.c(72) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(72) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap_list.c(72) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap_list.c(72) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(72) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(72) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(79) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(79) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(79) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(79) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap_list.c(79) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(79) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap_list.c(79) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap_list.c(79) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(79) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(79) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(87) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(87) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(87) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(87) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap_list.c(87) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(87) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap_list.c(87) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap_list.c(87) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(87) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(87) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(95) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(95) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap_list.c(95) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(95) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap_list.c(95) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap_list.c(95) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap_list.c(95) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap_list.c(95) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(95) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap_list.c(95) : error C2059: erreur de syntaxe : ')' lqr_vmap.c .\lqr\lqr_vmap.c(32) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(32) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(32) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(32) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(32) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(32) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(32) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(32) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(32) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(32) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(47) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(47) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(47) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(47) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(47) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(47) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(47) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(47) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(47) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(47) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(55) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(55) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(55) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(55) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(55) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(55) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(55) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(55) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(55) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(55) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(62) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(62) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(62) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(62) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(62) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(62) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(62) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(62) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(62) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(62) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(69) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(69) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(69) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(69) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(69) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(69) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(69) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(69) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(69) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(69) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(76) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(76) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(76) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(76) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(76) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(76) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(76) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(76) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(76) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(76) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(83) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(83) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(83) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(83) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(83) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(83) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(83) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(83) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(83) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(83) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(91) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(91) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(91) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(91) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(91) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(91) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(91) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(91) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(91) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(91) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(150) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(150) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(150) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(150) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(150) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(150) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(150) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(150) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(150) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(150) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(211) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(211) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_vmap.c(211) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(211) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_vmap.c(211) : error C2091: fonction retournée par la fonction .\lqr\lqr_vmap.c(211) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_vmap.c(211) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_vmap.c(211) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(211) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_vmap.c(211) : error C2059: erreur de syntaxe : ')' lqr_progress.c .\lqr\lqr_progress.c(30) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(30) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(30) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(30) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(30) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(30) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(30) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(30) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(30) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(30) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(88) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(88) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(88) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(88) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(88) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(88) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(88) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(88) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(88) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(88) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(96) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(96) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(96) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(96) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(96) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(96) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(96) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(96) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(96) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(96) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(104) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(104) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(104) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(104) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(104) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(104) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(104) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(104) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(104) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(104) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(112) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(112) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(112) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(112) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(112) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(112) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(112) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(112) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(112) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(112) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(120) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(120) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(120) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(120) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(120) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(120) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(120) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(120) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(120) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(120) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(129) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(129) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(129) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(129) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(129) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(129) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(129) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(129) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(129) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(129) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(138) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(138) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(138) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(138) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(138) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(138) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(138) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(138) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(138) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(138) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(147) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(147) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_progress.c(147) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(147) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_progress.c(147) : error C2091: fonction retournée par la fonction .\lqr\lqr_progress.c(147) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_progress.c(147) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_progress.c(147) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(147) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_progress.c(147) : error C2059: erreur de syntaxe : ')' lqr_carver_rigmask.c .\lqr\lqr_carver_rigmask.c(52) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(52) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(52) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(52) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(52) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(52) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(52) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_rigmask.c(52) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(52) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(52) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(95) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(95) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(95) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(95) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(95) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(95) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(95) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_rigmask.c(95) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(95) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(95) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(102) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(102) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(102) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(102) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(102) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(102) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(102) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_rigmask.c(102) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(102) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(102) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(172) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(172) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_rigmask.c(172) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(172) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(172) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_rigmask.c(172) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_rigmask.c(172) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_rigmask.c(172) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(172) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_rigmask.c(172) : error C2059: erreur de syntaxe : ')' lqr_carver_list.c .\lqr\lqr_carver_list.c(73) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(73) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(73) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(73) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_list.c(73) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(73) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_list.c(73) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_list.c(73) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(73) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(73) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(80) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(80) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(80) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(80) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_list.c(80) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(80) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_list.c(80) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_list.c(80) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(80) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(80) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(88) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(88) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(88) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(88) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_list.c(88) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(88) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_list.c(88) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_list.c(88) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(88) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(88) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(96) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(96) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(96) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(96) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_list.c(96) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(96) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_list.c(96) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_list.c(96) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(96) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(96) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(109) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(109) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_list.c(109) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(109) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_list.c(109) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_list.c(109) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_list.c(109) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_list.c(109) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(109) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_list.c(109) : error C2059: erreur de syntaxe : ')' lqr_carver.c .\lqr\lqr_carver.c(102) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(102) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(102) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(102) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(102) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(102) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(102) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(102) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(102) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(102) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(109) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(109) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(109) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(109) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(109) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(109) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(109) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(109) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(109) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(109) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(127) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(127) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(127) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(127) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(127) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(127) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(127) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(127) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(127) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(127) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(163) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(163) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(163) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(163) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(163) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(163) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(163) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(163) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(163) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(163) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(211) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(211) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(211) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(211) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(211) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(211) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(211) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(211) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(211) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(211) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(243) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(243) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(243) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(243) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(243) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(243) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(243) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(243) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(243) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(243) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(260) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(260) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(260) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(260) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(260) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(260) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(260) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(260) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(260) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(260) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(268) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(268) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(268) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(268) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(268) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(268) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(268) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(268) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(268) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(268) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(276) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(276) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(276) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(276) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(276) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(276) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(276) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(276) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(276) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(276) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(284) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(284) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(284) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(284) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver.c(284) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver.c(284) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver.c(284) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver.c(284) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(284) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(284) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver.c(292) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver.c(292) : fatal error C1003: le nombre d'erreurs est supérieur à 100 ; arrêt de la compilation lqr_carver_bias.c .\lqr\lqr_carver_bias.c(31) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(31) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(31) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(31) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_bias.c(31) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(31) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_bias.c(31) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_bias.c(31) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(31) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(31) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(77) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(77) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(77) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(77) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_bias.c(77) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(77) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_bias.c(77) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_bias.c(77) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(77) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(77) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(84) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(84) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(84) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(84) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_bias.c(84) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(84) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_bias.c(84) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_bias.c(84) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(84) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(84) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(153) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(153) : error C2143: erreur de syntaxe : absence de ')' avant '(' .\lqr\lqr_carver_bias.c(153) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(153) : error C2143: erreur de syntaxe : absence de ')' avant 'chaîne' .\lqr\lqr_carver_bias.c(153) : error C2091: fonction retournée par la fonction .\lqr\lqr_carver_bias.c(153) : error C2143: erreur de syntaxe : absence de '{' avant 'chaîne' .\lqr\lqr_carver_bias.c(153) : error C2059: erreur de syntaxe : '<Inconnu>' .\lqr\lqr_carver_bias.c(153) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(153) : error C2059: erreur de syntaxe : ')' .\lqr\lqr_carver_bias.c(153) : error C2059: erreur de syntaxe : ')' Génération de code en cours... Le journal de génération a été enregistré à l'emplacement "file://e:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\digikamimageplugin_contentawareresizing.dir\Debug\BuildLog.htm" digikamimageplugin_contentawareresizing - 462 erreur(s), 1 avertissement(s) It sound like MSVC don't like "LQR_PUBLIC" sentence, as with this one : http://lxr.kde.org/source/extragear/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap_list.c#72 Gilles Caulier To Gilles: no, I don't have MSVC and therefore I only tried with MinGW. The problem is LQR_PUBLIC as you said, which defines to: __attribute__((visibility("default"))) which is specific to the gcc compiler I guess. I use that attribute to tell the compiler that a symbol should be public and hence that it can be used outside the library, while all symbols are hidden by default (at least this is so with the configure file shipped with the library). If someone knows how to achieve the same result with MSVC (and how to detect such compiler) please tell me (or point me to a web page which explains it, I could not find one after a quick search). In the meantime, a quick&dirty solution would be just modifying the file lqr/lqr_base.h line 29 with something like: #ifdef MSVC_COMPILER #define LQR_PUBLIC #else #define LQR_PUBLIC __attribute__((visibility("default"))) #endif /* MSVC_COMPILER */ and pass MSVC_COMPILER to the compiler defines. To Carlo, Look my commit see 10 mn ago (:=))) http://websvn.kde.org/trunk/extragear/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h?r1=959637&r2=959636&pathrev=959637 With this one, all compile fine. No warnings, no error. It's more simple too. Gilles >With this one, all compile fine. No warnings, no error. It's more simple too.
Ah, great. What about this one?
#ifdef _MSC_VER
# define LQR_PUBLIC __declspec(dllexport)
#else
# define LQR_PUBLIC __attribute__((visibility("default")))
#endif /* _MSC_VER */
From a little more search in the web, I think this is how symbol exporting in shared libraries should be done with MSVC. If this is fine too I'll commit this.
Carlo, Yes, _MSC_VER symbol is define MSVC version by M$. It's used by CImg, Lcms, etc.. libraries which compile under Windows. Gilles Gilles: I see, but I was asking if it also works fine with the __declspec(dllexport) definition. You has right. fixed : http://websvn.kde.org/trunk/extragear/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_base.h?r1=959637&r2=959698 Gilles Carlo, Too fast. Your solution doesn't work... I have reverted commit #959698 : ------ Début de la génération : Projet : digikamimageplugin_contentawareresizing, Configuration : Debug Win32 ------ Compilation en cours... cl : Ligne de commande warning D9025 : substitution de '/W3' par '/w' lqr_vmap_list.c .\lqr\lqr_vmap_list.c : error C2471: impossible de mettre à jour la base de données 'e:\devel-msvc\graphics\bin\debug\digikamimageplugin_contentawareresizing.pdb' du programme .\lqr\lqr_vmap_list.c(75) : error C2375: 'lqr_vmap_list_start' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_list_pub.h(41) : voir la déclaration de 'lqr_vmap_list_start' .\lqr\lqr_vmap_list.c(82) : error C2375: 'lqr_vmap_list_next' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_list_pub.h(43) : voir la déclaration de 'lqr_vmap_list_next' .\lqr\lqr_vmap_list.c(90) : error C2375: 'lqr_vmap_list_current' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_list_pub.h(42) : voir la déclaration de 'lqr_vmap_list_current' .\lqr\lqr_vmap_list.c(98) : error C2375: 'lqr_vmap_list_foreach' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_list_pub.h(44) : voir la déclaration de 'lqr_vmap_list_foreach' .\lqr\lqr_vmap_list.c(108) : fatal error C1903: impossible de récupérer à partir des erreurs précédentes ; arrêt de la compilation lqr_vmap.c .\lqr\lqr_vmap.c : error C2471: impossible de mettre à jour la base de données 'e:\devel-msvc\graphics\bin\debug\digikamimageplugin_contentawareresizing.pdb' du programme .\lqr\lqr_vmap.c(35) : error C2375: 'lqr_vmap_new' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(41) : voir la déclaration de 'lqr_vmap_new' .\lqr\lqr_vmap.c(50) : error C2375: 'lqr_vmap_destroy' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(42) : voir la déclaration de 'lqr_vmap_destroy' .\lqr\lqr_vmap.c(58) : error C2375: 'lqr_vmap_get_data' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(44) : voir la déclaration de 'lqr_vmap_get_data' .\lqr\lqr_vmap.c(65) : error C2375: 'lqr_vmap_get_width' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(45) : voir la déclaration de 'lqr_vmap_get_width' .\lqr\lqr_vmap.c(72) : error C2375: 'lqr_vmap_get_height' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(46) : voir la déclaration de 'lqr_vmap_get_height' .\lqr\lqr_vmap.c(79) : error C2375: 'lqr_vmap_get_depth' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(47) : voir la déclaration de 'lqr_vmap_get_depth' .\lqr\lqr_vmap.c(86) : error C2375: 'lqr_vmap_get_orientation' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(48) : voir la déclaration de 'lqr_vmap_get_orientation' .\lqr\lqr_vmap.c(94) : error C2375: 'lqr_vmap_dump' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(51) : voir la déclaration de 'lqr_vmap_dump' .\lqr\lqr_vmap.c(153) : error C2375: 'lqr_vmap_internal_dump' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(50) : voir la déclaration de 'lqr_vmap_internal_dump' .\lqr\lqr_vmap.c(214) : error C2375: 'lqr_vmap_load' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_vmap_pub.h(52) : voir la déclaration de 'lqr_vmap_load' .\lqr\lqr_vmap.c(268) : fatal error C1903: impossible de récupérer à partir des erreurs précédentes ; arrêt de la compilation lqr_progress.c .\lqr\lqr_progress.c : error C2471: impossible de mettre à jour la base de données 'e:\devel-msvc\graphics\bin\debug\digikamimageplugin_contentawareresizing.pdb' du programme .\lqr\lqr_progress.c(33) : error C2375: 'lqr_progress_new' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(41) : voir la déclaration de 'lqr_progress_new' .\lqr\lqr_progress.c(91) : error C2375: 'lqr_progress_set_init' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(45) : voir la déclaration de 'lqr_progress_set_init' .\lqr\lqr_progress.c(99) : error C2375: 'lqr_progress_set_update' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(46) : voir la déclaration de 'lqr_progress_set_update' .\lqr\lqr_progress.c(107) : error C2375: 'lqr_progress_set_end' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(47) : voir la déclaration de 'lqr_progress_set_end' .\lqr\lqr_progress.c(115) : error C2375: 'lqr_progress_set_update_step' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(43) : voir la déclaration de 'lqr_progress_set_update_step' .\lqr\lqr_progress.c(123) : error C2375: 'lqr_progress_set_init_width_message' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(49) : voir la déclaration de 'lqr_progress_set_init_width_message' .\lqr\lqr_progress.c(132) : error C2375: 'lqr_progress_set_init_height_message' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(50) : voir la déclaration de 'lqr_progress_set_init_height_message' .\lqr\lqr_progress.c(141) : error C2375: 'lqr_progress_set_end_width_message' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(51) : voir la déclaration de 'lqr_progress_set_end_width_message' .\lqr\lqr_progress.c(150) : error C2375: 'lqr_progress_set_end_height_message' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_progress_pub.h(52) : voir la déclaration de 'lqr_progress_set_end_height_message' .\lqr\lqr_progress.c(156) : fatal error C1903: impossible de récupérer à partir des erreurs précédentes ; arrêt de la compilation lqr_carver_rigmask.c .\lqr\lqr_carver_rigmask.c : error C2471: impossible de mettre à jour la base de données 'e:\devel-msvc\graphics\bin\debug\digikamimageplugin_contentawareresizing.pdb' du programme .\lqr\lqr_carver_rigmask.c(55) : error C2375: 'lqr_carver_rigmask_add_area' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_rigmask_pub.h(34) : voir la déclaration de 'lqr_carver_rigmask_add_area' .\lqr\lqr_carver_rigmask.c(98) : error C2375: 'lqr_carver_rigmask_add' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_rigmask_pub.h(35) : voir la déclaration de 'lqr_carver_rigmask_add' .\lqr\lqr_carver_rigmask.c(105) : error C2375: 'lqr_carver_rigmask_add_rgb_area' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_rigmask_pub.h(32) : voir la déclaration de 'lqr_carver_rigmask_add_rgb_area' .\lqr\lqr_carver_rigmask.c(175) : error C2375: 'lqr_carver_rigmask_add_rgb' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_rigmask_pub.h(33) : voir la déclaration de 'lqr_carver_rigmask_add_rgb' .\lqr\lqr_carver_rigmask.c(181) : fatal error C1903: impossible de récupérer à partir des erreurs précédentes ; arrêt de la compilation lqr_carver_list.c .\lqr\lqr_carver_list.c : error C2471: impossible de mettre à jour la base de données 'e:\devel-msvc\graphics\bin\debug\digikamimageplugin_contentawareresizing.pdb' du programme .\lqr\lqr_carver_list.c(76) : error C2375: 'lqr_carver_list_start' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_list_pub.h(52) : voir la déclaration de 'lqr_carver_list_start' .\lqr\lqr_carver_list.c(83) : error C2375: 'lqr_carver_list_next' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_list_pub.h(54) : voir la déclaration de 'lqr_carver_list_next' .\lqr\lqr_carver_list.c(91) : error C2375: 'lqr_carver_list_current' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_list_pub.h(53) : voir la déclaration de 'lqr_carver_list_current' .\lqr\lqr_carver_list.c(99) : error C2375: 'lqr_carver_list_foreach' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_list_pub.h(55) : voir la déclaration de 'lqr_carver_list_foreach' .\lqr\lqr_carver_list.c(112) : error C2375: 'lqr_carver_list_foreach_recursive' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_list_pub.h(56) : voir la déclaration de 'lqr_carver_list_foreach_recursive' .\lqr\lqr_carver_list.c(123) : fatal error C1903: impossible de récupérer à partir des erreurs précédentes ; arrêt de la compilation lqr_carver.c .\lqr\lqr_carver.c : error C2471: impossible de mettre à jour la base de données 'e:\devel-msvc\graphics\bin\debug\digikamimageplugin_contentawareresizing.pdb' du programme .\lqr\lqr_carver.c(105) : error C2375: 'lqr_carver_new' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(54) : voir la déclaration de 'lqr_carver_new' .\lqr\lqr_carver.c(112) : error C2375: 'lqr_carver_new_ext' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(55) : voir la déclaration de 'lqr_carver_new_ext' .\lqr\lqr_carver.c(130) : error C2375: 'lqr_carver_destroy' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(56) : voir la déclaration de 'lqr_carver_destroy' .\lqr\lqr_carver.c(166) : error C2375: 'lqr_carver_init' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(59) : voir la déclaration de 'lqr_carver_init' .\lqr\lqr_carver.c(214) : error C2375: 'lqr_carver_set_gradient_function' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(62) : voir la déclaration de 'lqr_carver_set_gradient_function' .\lqr\lqr_carver.c(246) : error C2375: 'lqr_carver_attach' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(68) : voir la déclaration de 'lqr_carver_attach' .\lqr\lqr_carver.c(263) : error C2375: 'lqr_carver_set_dump_vmaps' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(63) : voir la déclaration de 'lqr_carver_set_dump_vmaps' .\lqr\lqr_carver.c(271) : error C2375: 'lqr_carver_set_no_dump_vmaps' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(64) : voir la déclaration de 'lqr_carver_set_no_dump_vmaps' .\lqr\lqr_carver.c(279) : error C2375: 'lqr_carver_set_resize_order' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(65) : voir la déclaration de 'lqr_carver_set_resize_order' .\lqr\lqr_carver.c(287) : error C2375: 'lqr_carver_set_side_switch_frequency' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(66) : voir la déclaration de 'lqr_carver_set_side_switch_frequency' .\lqr\lqr_carver.c(295) : error C2375: 'lqr_carver_set_enl_step' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(67) : voir la déclaration de 'lqr_carver_set_enl_step' .\lqr\lqr_carver.c(306) : error C2375: 'lqr_carver_set_progress' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(69) : voir la déclaration de 'lqr_carver_set_progress' .\lqr\lqr_carver.c(315) : error C2375: 'lqr_carver_set_preserve_input_image' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(70) : voir la déclaration de 'lqr_carver_set_preserve_input_image' .\lqr\lqr_carver.c(1294) : error C2375: 'lqr_carver_flatten' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(74) : voir la déclaration de 'lqr_carver_flatten' .\lqr\lqr_carver.c(1758) : error C2375: 'lqr_carver_resize' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(73) : voir la déclaration de 'lqr_carver_resize' .\lqr\lqr_carver.c(1834) : error C2375: 'lqr_carver_cancel' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(75) : voir la déclaration de 'lqr_carver_cancel' .\lqr\lqr_carver.c(1855) : error C2375: 'lqr_carver_get_width' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(86) : voir la déclaration de 'lqr_carver_get_width' .\lqr\lqr_carver.c(1862) : error C2375: 'lqr_carver_get_height' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(87) : voir la déclaration de 'lqr_carver_get_height' .\lqr\lqr_carver.c(1870) : error C2375: 'lqr_carver_get_ref_width' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(88) : voir la déclaration de 'lqr_carver_get_ref_width' .\lqr\lqr_carver.c(1877) : error C2375: 'lqr_carver_get_ref_height' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(89) : voir la déclaration de 'lqr_carver_get_ref_height' .\lqr\lqr_carver.c(1885) : error C2375: 'lqr_carver_get_channels' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(85) : voir la déclaration de 'lqr_carver_get_channels' .\lqr\lqr_carver.c(1892) : error C2375: 'lqr_carver_get_bpp' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(84) : voir la déclaration de 'lqr_carver_get_bpp' .\lqr\lqr_carver.c(1900) : error C2375: 'lqr_carver_get_col_depth' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(91) : voir la déclaration de 'lqr_carver_get_col_depth' .\lqr\lqr_carver.c(1908) : error C2375: 'lqr_carver_get_enl_step' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(92) : voir la déclaration de 'lqr_carver_get_enl_step' .\lqr\lqr_carver.c(1916) : error C2375: 'lqr_carver_get_orientation' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(90) : voir la déclaration de 'lqr_carver_get_orientation' .\lqr\lqr_carver.c(1924) : error C2375: 'lqr_carver_get_depth' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(93) : voir la déclaration de 'lqr_carver_get_depth' .\lqr\lqr_carver.c(1933) : error C2375: 'lqr_carver_scan_reset' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(78) : voir la déclaration de 'lqr_carver_scan_reset' .\lqr\lqr_carver.c(1959) : error C2375: 'lqr_carver_scan' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(79) : voir la déclaration de 'lqr_carver_scan' .\lqr\lqr_carver.c(1984) : error C2375: 'lqr_carver_scan_ext' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(80) : voir la déclaration de 'lqr_carver_scan_ext' .\lqr\lqr_carver.c(2008) : error C2375: 'lqr_carver_scan_by_row' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(83) : voir la déclaration de 'lqr_carver_scan_by_row' .\lqr\lqr_carver.c(2015) : error C2375: 'lqr_carver_scan_line' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(81) : voir la déclaration de 'lqr_carver_scan_line' .\lqr\lqr_carver.c(2026) : error C2375: 'lqr_carver_scan_line_ext' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_pub.h(82) : voir la déclaration de 'lqr_carver_scan_line_ext' .\lqr\lqr_carver.c(2078) : fatal error C1903: impossible de récupérer à partir des erreurs précédentes ; arrêt de la compilation lqr_carver_bias.c .\lqr\lqr_carver_bias.c : error C2471: impossible de mettre à jour la base de données 'e:\devel-msvc\graphics\bin\debug\digikamimageplugin_contentawareresizing.pdb' du programme .\lqr\lqr_carver_bias.c(34) : error C2375: 'lqr_carver_bias_add_area' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_bias_pub.h(34) : voir la déclaration de 'lqr_carver_bias_add_area' .\lqr\lqr_carver_bias.c(80) : error C2375: 'lqr_carver_bias_add' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_bias_pub.h(35) : voir la déclaration de 'lqr_carver_bias_add' .\lqr\lqr_carver_bias.c(87) : error C2375: 'lqr_carver_bias_add_rgb_area' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_bias_pub.h(32) : voir la déclaration de 'lqr_carver_bias_add_rgb_area' .\lqr\lqr_carver_bias.c(156) : error C2375: 'lqr_carver_bias_add_rgb' : redéfinition ; liaison différente E:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\lqr/lqr_carver_bias_pub.h(33) : voir la déclaration de 'lqr_carver_bias_add_rgb' .\lqr\lqr_carver_bias.c(162) : fatal error C1903: impossible de récupérer à partir des erreurs précédentes ; arrêt de la compilation Génération de code en cours... Le journal de génération a été enregistré à l'emplacement "file://e:\devel-msvc\graphics\digikam\imageplugins\contentawareresizing\digikamimageplugin_contentawareresizing.dir\Debug\BuildLog.htm" digikamimageplugin_contentawareresizing - 82 erreur(s), 1 avertissement(s) Gilles >Too fast. Your solution doesn't work... I have reverted commit #959698 :
I have tried to investigate a little further how exporting and importing symbols to/from DLL's work in the msdn website but the documentation is a _total mess_ (™) and I'm not able to experiment with MSVC.
I think that the sanest option at the moment is to assume that commit #959698 (i.e. disabling all importing/exporting) is fine for now and then if someone wants to build a DLL he/she'll take care write a .def file with the public symbols (which are easily recognizable by the fact that they are declared in headers whose name ends with "_pub.h" and all symbol names start with "lqr_") and whatever else is needed.
Created attachment 33146 [details]
Fix skin tone detection and memory leak
- Now, skin tone detection seems to work.
- A temporary fix for the memory leak reported by Carlos
Julien Narboux
Created attachment 33147 [details]
Screenshot of mask over preview problem
Gilles, Julien,
Here is a screenshot which shows the problem about having the mask over the preview:
1- when the resized has been done the mask is not aligned with the preview anymore (the mask was on the silhouette before resize !)
2- when can draw outside the picture
Gilles, do you see what I mean ?
Julien Narboux
SVN commit 959783 by cgilles: apply patch #33146 from Julien Nardoux CCBUGS: 149485 M +17 -15 contentawareresizer.cpp M +3 -4 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=959783 SVN commit 959789 by cgilles: using inline method, will be faster here. CCBUGS: 149485 M +16 -12 contentawareresizer.cpp M +2 -1 contentawareresizer.h WebSVN link: http://websvn.kde.org/?view=rev&revision=959789 To Julien #154, yes, i know. Preview widget don't know when it must show mask. It must be done only when original image is displayed. It miss a condition in paintEvent. This is why, to enable preview mode (original or target) with Liquid Rescale is fine. But for the moment, using only this both options is not possible. Only all preview mode are available, with all comparison side by side. A new option must be add to ImageGuidewidget to only show Original and Target preview image. It's not very complicated to implement... Gilles Will this plugin be faster some day or is it already at its full speed? Looking at the way Photoshop works: http://www.russellbrown.com/tips_tech.html (Video is named "Content Aware Scaling"), I can see it is so much faster. Are we already using the full power of the library? Not to get me wrong: I don't want to bash the speed :-) But something like Liquid rescale should really work in "live preview mode", so you can see the effect. Maybe we can resize the preview image? Andi, you are right speed should/could be improved. 1- First we should use the Lqr library properly, in the current code each time we resize we rebuild every thing from scratch ! but Lqr library maintains data structures to have a quicker rescale after the first rescale if we use it properly, we simply do not use this for the time being, I will talk about that with Gilles. 2- Second, Lqr implementation of the rigidity option may not be optimal, when rigidity=1 (default value) It may be possible to write specialized code which would be better optimized by gcc. From a post I read comparing ocaml implentation of seamcarving and Lqr, it seems that Carlo is aware of that. 3- Current implementation of Lqr computes the energy then finds the path of least energy, then removes it, then updates energy, then finds again path of least energy and so on... To compute the path of least energy in fact one computes all the paths of least energy, so in fact several seams could be removed at the same time without recomputing the updated energy. When need to study if this leads to too many artefacts. Lqr author may implement this optimization in 0.5. Look at http://liblqr.wikidot.com/forum/t-151301/how-implementation-works 4- Parallel computation: we could compute the paths of minimum energy using several threads. 5- Seamcarving on GPU, it is possible to do I have seen on the web a student who did this, but it is hard IMHO to get something portable. Julien Ok Gilles #157, I understand we just need to have one the preview modes : mouseover and orginal/preview and the mask is displayed only over original. I think it is a good solution. Concerning the name of the plugin, IMHO content aware resizing is easier to grasp then liquid rescale, I suggest using "Content aware resizing". Concerning Skin Tone detection. I would appreciate of people could test and tell me if it works for them. I tested using a few pictures and it seems to me that we should add an option which enlarge the skin tone selection by a given amout of pixels. But maybe it would not help that much and the GUI would get bloated. If skin tone detection works well, we could use it also in the saturation tool to have selective saturation tool which does not saturate skin tones, as the vibrance in some other big software. I also think that the possibility to draw a mask using brush, should become only a particular case of a more general feature for all image effect plugin: add a mask using a brush, a gradient, a circle, a rectangle, a eye detector, a skin tone detector, .... Julien Julien, Concerning the mask painting, it seems to me that it was implemented by cut and paste from draw sketch widget, it is possible to be more modular and juste reuse the code instead of copying ? it would ease implementation of undo/redo and brush size selection. Gilles what do you think ? Julien To Julien #160: >1- First we should use the Lqr library properly, in the current code each time >we resize we rebuild every thing from scratch ! but Lqr library maintains data >structures to have a quicker rescale after the first rescale if we use it >properly, we simply do not use this for the time being, I will talk about that >with Gilles. I'm hear you... (private mail in French ?) >4- Parallel computation: we could compute the paths of minimum energy using >several threads. Real parallel programing can be done using OpenMP standard. Advantage : if you have multi-core cpu, thread are dispatched finelly between core. It supported by GCC and other main compiler. LibRaw use it to parallelize demosaicing operations. Suggestion : use it directly into lqr, if posible of course. >5- Seamcarving on GPU, it is possible to do I have seen on the web a student >who did this, but it is hard IMHO to get something portable. Definitivly a wrong way for me... To Julien #162: >Concerning the mask painting, it seems to me that it was implemented by cut and >paste from draw sketch widget, it is possible to be more modular and juste >reuse the code instead of copying ? it would ease implementation of undo/redo >and brush size selection. >Gilles what do you think ? Not simple. Of course it will be better to use factorized code. But in this case, ImageGuideWidget is already complex code. And unforget that we need to factorize all preview widgets. The only code which can be factored is the non painting stuff i think. painting is delegate to customized method as paintEvent(). Marcel, your viewpoint ? Gilles > Andi, you are right speed should/could be improved. Yes, I don't know how they do it in Photoshop of course (nor which hardware the demos were run onto), but I suspect some approximation with respect to the original algorithm is taken in order to speed up things. Also, lacking some options as the step and rigidity, it can be more optimised as Julien said. It is also possible that the GPU is used, as I've been told that PS can do that. Is there anyone who can make a direct comparison? > 1- First we should use the Lqr library properly, in the current code each time > we resize we rebuild every thing from scratch ! but Lqr library maintains data > structures to have a quicker rescale after the first rescale if we use it > properly, we simply do not use this for the time being, I will talk about that > with Gilles. You can have a look at the interactive code in the GIMP plugin if you wish, which exploits that feature of lqr. And you can ask me of course if in doubt (there are some tricky issues; for example it is not possible to keep the carving information when scaling in 2 directions at the same time - this is a long-standing problem which should be addressed somehow). > 2- Second, Lqr implementation of the rigidity option may not be optimal, when > rigidity=1 (default value) It may be possible to write specialized code which > would be better optimized by gcc. From a post I read comparing ocaml > implentation of seamcarving and Lqr, it seems that Carlo is aware of that. Actually, that discussion was mainly about the step rather than the rigidity (BTW increasing the step slows down everything much more than increasing the rigidity, as you might have noted). Unfortunately, it wouldn't be very useful now to optimise the update function in the way which was considered in that post about the ocaml implementation, because to do that I would need to give away another optimisation I'm using (and which is more general and gives comparable results in terms of computational time). > 3- Current implementation of Lqr computes the energy then finds the path of > least energy, then removes it, then updates energy, then finds again path of > least energy and so on... > To compute the path of least energy in fact one computes all the paths of least > energy, so in fact several seams could be removed at the same time without > recomputing the updated energy. When need to study if this leads to too many > artefacts. Lqr author may implement this optimization in 0.5. > Look at http://liblqr.wikidot.com/forum/t-151301/how-implementation-works This also is a little bit more tricky, as the library does not really compute _all_ the paths of least energy. I hope to come up with a solution to do this efficiently, but as I wrote in the liblqr thread it will need quite some work (+ lots of testing). > 4- Parallel computation: we could compute the paths of minimum energy using > several threads. I like the idea of Gilles to use OpenMP: I know it a little bit and it's amazingly simple to adapt code to use it - if the code is already written in a way which makes it easy to distribute the computation among several cores. The problem here is that the task (finding the path of minimum energy) is a global one in nature. It's still not obvious to me how this could be consistently divided into local parallel computations, but I'm quite confident that this is possible - this is a major future goal for the library development (and any ideas would be very appreciated, of course). That said: I have completed the new framework for the energy computation which allows 1) to use custom energy functions and 2) to get previews of the energy. I have pushed it in the master branch of the git repo, and since it is backwards compatible it can already be uses with the DigiKam code. It is not documented yet, however. I have also written a function to add a bias pixel by pixel, the synopsis is: LqrRetVal lqr_carver_bias_add_xy(LqrCarver * carver, gdouble bias, gint x, gint y) (the usage should be obvious - just keep using values of the order of 10k for the bias) Please, report me any problems you might find, I did a lot of testing (also with valgrind) and everything seems to work fine, but you never know... Carlo (In reply to comment #165) > > Andi, you are right speed should/could be improved. > Yes, I don't know how they do it in Photoshop of course (nor which hardware the > demos were run onto)... It is a normal MacBookPro as far as I know, the same I use here (but with Linux of course, I guess I am the only one in the world who doesn't like the Mac interface :-)) Created attachment 33180 [details]
Clean up bias by using new lqr functions
This patch make use of the latest Lqr function to set bias point by point by coordinates instead of using a buffer.
Julien
@ #162 I tried plugin and results are very interesting. There is one thing which prevents full happiness - mask painting. This is really hard to use - especially if region is bigger than few strokes. I understand desire to simplify code and reuse as much as possible but this needs better solution. I think that digiKam could use not only here but also in many other plugins more advanced tools for selection and mask creating (those rectangles are boring ;). Draw selection like in GIMP or Krita, with modifiers to add/remove areas + bucket to designate region. In the past Gilles and Co. were reluctant to create such tools because if someone needed them (s)he could use aforementioned programs but when in core of digiKam is plugin which desperately needs it and could be reused in other parts? SVN commit 960550 by cgilles: Apply patch #33180 from Julien Nardoux CCBUGS: 149485 M +19 -55 contentawareresizer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=960550 Created attachment 33204 [details]
Digikam - change your pencil's size for mask painting
Hi everybody,
This small patch allows you to choose your pencil's size for mask painting.
Julien
SVN commit 960905 by cgilles: apply patch #33204 from Julien Pontabry CCBUGS: 149485 M +32 -13 imageplugins/contentawareresizing/contentawareresizetool.cpp M +1 -0 imageplugins/contentawareresizing/contentawareresizetool.h M +8 -1 libs/widgets/imageplugins/imageguidewidget.cpp M +1 -0 libs/widgets/imageplugins/imageguidewidget.h M +5 -0 libs/widgets/imageplugins/imagewidget.cpp M +1 -0 libs/widgets/imageplugins/imagewidget.h WebSVN link: http://websvn.kde.org/?view=rev&revision=960905 To Carlo #165, About parallel computation: Let e(x,y) be the energy at the given coordinates. We would like to compute (with step=1): minpath(x,1)=e(x,1) if y > 1 then minpath(x,y)=e(x,y)+min(minpath(x-1,y-1),minpath(x,y-1),minpath(x+1,y-1)) Hence the computation at each line depends on the previous line, but perhaps we can compute each line in parallel using several cores. For example one core could compute the left hand side and another one the right and side of a line. The problem is that the two computations should be performed at the same speed otherwise one thread is stuck waiting for the other one... Julien The new version of the library is now ready and available from the git repo. The documentation and the example files are also updated. Main news with respect to my last comment #165: 1) optimisation which produces a very noticeable performance gain in some cases (@ Julien N.: after all, the crude hack which was considered in the ocaml implementation thread was applicable, but most of the gain comes from a tiny approximation which spares some cycles). 2) possibility to define custom energy functions 3) possibility to output the energy for plotting About the last point, there are 2 ways in which one could provide previews for the energy: 1) use a single LqrCarver object all the time; create it, then allow the user to choose the energy function and plot it, then initialise the carver and do the rescaling 2) create an independent LqrCarver for energy preview purposes only (without initialisation - and using preserv_input_image - it is relatively inexpensive, since it is essentially like "dressing up" a buffer; also, a bias can be added to it). The second way is probably quicker to implement, but in some cases it may be less optimal; the first way would be better if you plan to keep the carving information between trials. Please, report me any bugs/problems you might find, and also if the documentation is not clear or is incomplete etc. I wish to release it by this week-end, so please help me sorting out any possible issue. @ Julien #172: > perhaps we can compute each line in parallel using several cores. For example > one core could compute the left hand side and another one the right and side > of a line. Yes, that is in fact the only possibility given the current implementation. Due to the optimisation, however, the second way (using only 2 cores) would be the only one applicable, and I'm not sure it would provide a great advantage due to the sync overhead (as you pointed out). Before implementing that, I'd rather think about a way to truly distribute the computation, e.g. by using a different representation of the internal states at each pixel. Julien, I looked at the code of the widget. There is a bug, when you resize digikam's window the mask is erased. It should be rescaled instead. Julien Narboux SVN commit 963956 by jnarboux: Set side switch and enlargement steps as suggested by Carlo Baldassi. CCBUGS: 149485 M +4 -0 contentawareresizer.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=963956 SVN commit 964658 by jnarboux: Update Lqr library to Git head. CCBUGS: 149485 M +3 -35 lqr_carver.c M +1 -0 lqr_carver.h M +7 -0 lqr_carver_bias.c M +0 -91 lqr_carver_priv.h M +1 -1 lqr_energy.c M +1 -1 lqr_progress.c WebSVN link: http://websvn.kde.org/?view=rev&revision=964658 SVN commit 964958 by jnarboux: Add a method to set preview mode in plugins. Set mouse over preview mode for content aware resizing. Display mask only if original is displayed. CCBUGS: 149485 M +1 -0 imageplugins/contentawareresizing/contentawareresizetool.cpp M +6 -1 libs/widgets/imageplugins/imageguidewidget.cpp M +1 -0 libs/widgets/imageplugins/imageguidewidget.h WebSVN link: http://websvn.kde.org/?view=rev&revision=964958 The new version of the library is now out in the wild: http://liblqr.wikidot.com/forum/t-154854/version-0-4-0-released I have changed some things in the API with respect to my last message here: 1) LQR_ER_BRIGHT has become LQR_ER_BRIGHTNESS 2) The lqr_carver_get_energy function has a slightly different syntax which makes more sense, and there is also an additional function for plotting directly to an image I have also managed to build DLL's on MinGW and MS VisualC++ and they seem to be working fine in my tests. All the details are in the documentation (README files + manual). Cheers SVN commit 966531 by jnarboux: Update Lqr to 0.4.0. CCBUGS: 149485 M +0 -1 lqr.h M +0 -1 lqr_all.h M +47 -43 lqr_base.h M +1305 -1551 lqr_carver.c M +98 -118 lqr_carver_bias.c M +8 -7 lqr_carver_bias_pub.h M +46 -52 lqr_carver_list.c M +0 -2 lqr_carver_list.h M +5 -9 lqr_carver_list_priv.h M +9 -14 lqr_carver_list_pub.h M +0 -1 lqr_carver_macros_priv.h M +131 -128 lqr_carver_priv.h M +41 -40 lqr_carver_pub.h M +104 -125 lqr_carver_rigmask.c M +1 -2 lqr_carver_rigmask_priv.h M +8 -7 lqr_carver_rigmask_pub.h M +88 -99 lqr_cursor.c M +13 -14 lqr_cursor_priv.h M +1 -1 lqr_cursor_pub.h M +526 -411 lqr_energy.c M +0 -1 lqr_energy.h M +33 -24 lqr_energy_priv.h M +17 -16 lqr_energy_pub.h M +9 -8 lqr_gradient.c M +0 -1 lqr_gradient.h M +3 -4 lqr_gradient_priv.h M +7 -10 lqr_gradient_pub.h M +53 -61 lqr_progress.c M +0 -5 lqr_progress.h M +11 -18 lqr_progress_priv.h M +12 -13 lqr_progress_pub.h M +212 -249 lqr_rwindow.c M +0 -2 lqr_rwindow.h M +24 -27 lqr_rwindow_priv.h M +9 -12 lqr_rwindow_pub.h M +118 -145 lqr_vmap.c M +0 -1 lqr_vmap.h M +38 -43 lqr_vmap_list.c M +0 -2 lqr_vmap_list.h M +5 -9 lqr_vmap_list_priv.h M +4 -6 lqr_vmap_list_pub.h M +6 -8 lqr_vmap_priv.h M +10 -13 lqr_vmap_pub.h WebSVN link: http://websvn.kde.org/?view=rev&revision=966531 SVN commit 966546 by jnarboux: Do not use deprecated gradient function, add the new energy functions of Lqr 0.4.0 in the list. Rename pen size into brush size. CCBUGS: 149485 M +2 -10 contentawareresizer.cpp M +1 -1 contentawareresizer.h M +11 -14 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=966546 SVN commit 967321 by jnarboux: Allow to hide advanced settings. Use new widget built by Gilles and Marcel. CCBUGS: 149485 M +23 -20 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=967321 SVN commit 967392 by jnarboux: Add side switch frequency option. CCBUGS: 149485 M +5 -3 contentawareresizer.cpp M +2 -1 contentawareresizer.h M +16 -4 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=967392 Julien, Do you see that not all settings are saved/restored by saveSettings()/readSettings() ? For ex, pencils size, and Advanced Settings expander state... Gilles Caulier Thanks Gilles, solved in svn. Julien Hi all, Here is a message from Joe Auman the author of CAIR about parallelization of the content aware resizing algorithm: Before I begin, I would like to clarify a few terms so we're all on the same page. The really basic steps to seam carving are generating a representation of the energy of the image, from that representation then generating an energy map and determining the least energy seam, and then removing that seam from the image. The way CAIR (and I believe Liquid Rescale) represents the energy of the image is gradients, ie edge detection. Its a simple process that works very well for seam carving, and can also be done fairly quickly. In your email I think you refer to this as simply “energy”. When you say “seams of minimum energy”, I assume you mean the energy map. (This might help if you haven't seen it before: http://c-a-i-r.wiki.sourceforge.net/Image+Energy) CAIR uses mulithreading in of the steps: calculating gradients, building the energy map, and removing the seam. The general rule for multithreading is: if it takes less time to perform a context switch and handle other threading overhead than it does to actually perform the calculations, then its beneficial to perform mulithreading. For me, I found that even if you only update affected areas, it was still beneficial to multithread. The energy map is obviously the problem. By the very nature of the algorithm, it cannot be easily multithreaded since there is a dependency of values between areas where the threads are working. For CAIR, the way I tackled the problem was to create two threads, one handling the left side of the image and one for the right side. Between them there was a boundary, where one thread would need a value that was maintained by the other thread. I protected each one of these boundary pixels by mutexes. When one thread finished updating a boundary pixel, it unlocked the associated mutex. When it needed a value from the other side of the boundary, it tried to lock that mutex. I have some comments in my code that might explain it a bit better: //=========================================================================================================// //threading procedure for Energy Map //-main signals to start left //-main waits for left to signal locks_done //+left starts and locks mutexes //+left signals main locks_done //+left waits for good_to_go //-main starts and signals start right //-main waits for right to signal locks_done //#right starts and lock mutexes //#right signals main locks_done //#right waits for good_to_go //-main starts and signals good_to_go twice //-main waits for finish twice //+#left and right start and do there thing //#+left and right signal finish when done //+#left and right wait for their start //-main starts and continues on //The reason for the crazy mutex locking is because I need to evenly split the matrix in half for each thread. //So, for the boundry between the two threads, they will try to access a value that the other thread is //managing. For example, the left thread needs the value of an element on the boundry between the left and right threads. //It needs the value of the three pixels above it, one of them, the top-right, is managed by the right thread. //The right thread might not have gotten around to filling that value in, so the Left thread must check. //It does that by trying to lock the mutex on that value. If the right thread already filled that value in, //it'll get it immediately and continue. If not, the left thread will block until the right thread gets around //to filling it in and unlocking the mutex. That means each value along the border has its own mutex. //The thread responsible for those values must lock those mutexes first before the other thread can try. //This limits one thread only getting about 2 rows ahead of the other thread before it finds itself blocked. //=========================================================================================================// My threading was all done in pthreads. Whatever threading scheme you use may not have the problems I ran into with the energy map. It is also possible to have more than two threads dealing with the energy map. Interior threads would have to wait on values from threads on both sides of its working area. My other investigations into how to break the algorithm into more thread-easy methods pretty much failed, though, I would be happy to investigate alternatives. For me, though, the most costly part of the algorithm is the actual seam removal. This is where multithreading helped me considerably. You may want to push Liquid Resize through a performance analyzer to determine the which parts would benefit most. For me, multithreading CAIR worked very well. However, Liquid Resize does things very differently (at least, thats what I can gather from the code). The benefits may or may not be as good as it was for me. Probably the only way to be truly sure is to multithread it and see what kind of performance you get out of it. If you have any other questions, please, don't hesitate to ask. - Joe Auman Hi Joe, Thanks for your explanations of your implementation. For the energy map, I think your solution with mutex is almost equivalent to: - computing each line in the normal order (1 to n) - but distribute the computation for each line to two threads Using OpenMP, maybe we could write something like that: for (i=1; i< height ; i++) #pragma omp parallel private(j) shared(width, e, minpath) { #pragma omp parallel for for (j=0; j< width ; j++) minpath[i][j]=e[i][j]+min(minpath[i-1][j-1],minpath[i-1][j],minpath[i-1][j+1]); } But maybe starting several threads for each line would give too much overhead. Is there any specialist of openmp in the room ? Julien > Here is a message from Joe Auman the author of CAIR about parallelization of > the content aware resizing algorithm: Thanks a lot (to Joe for the interesting explanation and to Julien for reporting it)! About these points: > For me, though, the most costly part of the algorithm is the actual seam > removal. This is where multithreading helped me considerably. You may want to > push Liquid Resize through a performance analyzer to determine the which parts > would benefit most. > > For me, multithreading CAIR worked very well. However, Liquid Resize does > things very differently (at least, thats what I can gather from the code). The > benefits may or may not be as good as it was for me. Probably the only way to > be truly sure is to multithread it and see what kind of performance you get > out of it. > I went through a profiler, of course, and what I could see for large images is that most of the time (~ 70%) was spent in the energy map updating, and almost all the rest (~ 20%) in the actual seam removal. These operations are both O(N^2) per seam (where N is the linear size of the image), while all the rest is O(N) and therefore much less relevant. In LqR the seam operation is extremely simple, however (it's in the function called lqr_carver_carve if you want to have a look). (Note: the energy update takes less than 1% with standard gradients but, since now it is also possible to introduce custom energy functions, computing the energy has also become a potentially expensive task if one uses some computationally heavy function.) Parallelising the the energy computation and the seam removal in LqR can be done right away (a single OpenMP pragma is enough): I have now tried to parallelise the carving operation and, to my surprise, I actually got a performance loss. I have tested this on 2 and 4 core PC's and my results are that more threads -> less performance, suggesting that the overhead cost for this operation is too high. I could still try something a little more sophisticated, though. About the energy map update: it should be indeed possible, with some modification to the algorithm, to adapt the method described by Joe to the way in which this is done by LqR (forcing only 2 threads to be started by OpenMP), but given the above results I'm having doubts about the overhead. The method proposed by Julien should also work, but it doesn't fit within the optimised update function in LqR, because the for loop has variable extremes, and furthermore starting and stopping the multithreading at each row would increase the overhead even more, I guess. I'm still looking for an alternative way to do it which could support more than 2 threads running in parallel and possibly without lockings and the like. I have had some ideas about how to change the representation which could lead to an improvement, but I haven't had the time to check them throughly yet (don't know when I will have, actually). In the case I find out anything useful I'll let you know. P.S.: a note about terminology: here I used "energy map" just as Joe did, but in the LqR documentation "energy map" means just "energy computed over the image". Within the code, the equivalent of the CAIR "energy map" is called "mmap". The relevant portion of the code we're discussing is therefore called "lqr_carver_update_mmap". Carlo Since last update of liblqr, linking faild under windows using MinGw : # make -- Found Qt-Version 4.4.3 (using C:/kde4-mingw/bin/qmake.exe) -- Found kdewin32 library: C:/kde4-mingw/lib/libkdewin32.dll.a -- Phonon Version: 4.3.0 -- Found KDE 4.2 include dir: C:/kde4-mingw/include -- Found KDE 4.2 library dir: C:/kde4-mingw/lib -- Found the KDE4 kconfig_compiler preprocessor: C:/kde4-mingw/bin/kconfig_compiler.exe -- Found automoc4: C:/kde4-mingw/bin/automoc4.exe -- Found Kexiv2 library in cache: C:/kde4-mingw/lib/libkexiv2.dll.a -- Found Kdcraw library in cache: C:/kde4-mingw/lib/libkdcraw.dll.a -- Found Kipi library in cache: C:/kde4-mingw/lib/libkipi.dll.a -- Found lcms version 1.18, C:/kde4-mingw/lib/liblcms-1.dll.a -- Found Kdcraw library in cache: C:/kde4-mingw/lib/libkdcraw.dll.a -- Found Kexiv2 library in cache: C:/kde4-mingw/lib/libkexiv2.dll.a -- Found Kipi library in cache: C:/kde4-mingw/lib/libkipi.dll.a -- Could NOT find LensFun (missing: LENSFUN_INCLUDE_DIRS LENSFUN_LIBRARIES) -- -- ---------------------------------------------------------------------------------- -- digiKam 0.11.0-svn dependencies results <http://www.digikam.org> -- -- Qt4 SQL module found................ YES -- libjpeg library found............... YES -- libtiff library found............... YES -- libpng library found................ YES -- libjasper library found............. YES -- liblcms library found............... YES -- libkipi library found............... YES -- libkexiv2 library found............. YES -- libkdcraw library found............. YES -- -- digiKam will be compiled without GPhoto2 support. -- -- libkdepimlibs library found......... YES (optional) -- libmarblewidget library found....... YES (optional) -- liblensfun library found............ NO (optional) -- -- digiKam will be compiled without lens auto-correction image editor tool. -- -- libglib2 library found.............. YES (optional) -- digiKam will be compiled............ YES -- ---------------------------------------------------------------------------------- -- -- Found Kexiv2 library in cache: C:/kde4-mingw/lib/libkexiv2.dll.a -- Found Kdcraw library in cache: C:/kde4-mingw/lib/libkdcraw.dll.a -- Found Kipi library in cache: C:/kde4-mingw/lib/libkipi.dll.a -- OpenCV root directory: C:/Program Files/OpenCV -- OpenCV Include Directory: C:/Program Files/OpenCV/cv/include;C:/Program Files/OpenCV/cxcore/include;C:/Program Files/OpenCV/c vaux/include;C:/Program Files/OpenCV/otherlibs/highgui -- OpenCV Libraries: C:/Program Files/OpenCV/lib/cv.lib;C:/Program Files/OpenCV/lib/cxcore.lib;C:/Program Files/OpenCV/lib/cvaux .lib;C:/Program Files/OpenCV/lib/highgui.lib -- Could NOT find Gdk (missing: GDK_INCLUDE_DIR GDK_LIBRARIES) -- Found GObject libraries: C:/kde4-mingw/lib/libgobject-2.0.dll.a;C:/kde4-mingw/lib/libgmodule-2.0.dll.a;C:/kde4-mingw/lib/libg thread-2.0.dll.a;C:/kde4-mingw/lib/libglib-2.0.dll.a -- Found GObject includes : C:/kde4-mingw/include/glib-2.0/gobject -- -- ---------------------------------------------------------------------------------- -- kipi-plugins 0.4.0-svn dependencies results <http://www.kipi-plugins.org> -- -- libjpeg library found............... YES -- libtiff library found............... YES -- libpng library found................ YES -- libkipi library found............... YES -- libkexiv2 library found............. YES -- libkdcraw library found............. YES -- libxml2 library found............... YES (optional) -- libxslt library found............... YES (optional) -- libexpat library found.............. YES (optional) -- native threads support found........ YES (optional) -- libopengl library found............. YES (optional) -- libopencv library found............. YES (optional) -- libgpod library found............... NO (optional) -- Gdk library found................... NO (optional) -- libkdepim library found............. YES (optional) -- -- kipi-plugins will be compiled....... YES -- HtmlExport will be compiled......... YES (optional) -- AdvancedSlideshow will be compiled.. YES (optional) -- ImageViewer will be compiled........ YES (optional) -- DNGConverter will be compiled....... YES (optional) -- RemoveRedEyes will be compiled...... YES (optional) -- IpodExport will be compiled......... NO (optional - Look README file for more details about dependencies) -- Calendar will be compiled........... YES (optional) -- ---------------------------------------------------------------------------------- -- -- ----------------------------------------------------------------------------- -- The following external packages were located on your system. -- This installation will have the extra features provided by these packages. + libopengl Congratulations! All external packages have been found. ----------------------------------------------------------------------------- -- Configuring done -- Generating done -- Build files have been written to: C:/temp/devel/graphics [ 0%] Built target digikamimageplugin_contentawareresizing_automoc [ 0%] Built target digikamcore_automoc [ 93%] Built target digikamcore Linking CXX shared module ..\..\..\bin\digikamimageplugin_contentawareresizing.dll CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN7Digikam18DImgThreadedFilter13cle anupFilterEv': C:/temp/devel/graphics/digikam/imageplugins/../libs/dimg/filters/dimgthreadedfilter.h:110: undefined reference to `_imp__lqr_car ver_destroy' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizerD1Ev': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:139: undefined reference to `_imp__lqr_ carver_destroy' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizerD0Ev': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:139: undefined reference to `_imp__lqr_ carver_destroy' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizer11filterImageEv': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:157: undefined reference to `_imp__lqr_ carver_resize' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:161: undefined reference to `_imp__lqr_ carver_get_width' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:162: undefined reference to `_imp__lqr_ carver_get_height' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:166: undefined reference to `_imp__lqr_ carver_scan_reset' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizer11filterImageEv': C:/temp/devel/graphics/digikam/imageplugins/../libs/dimg/dcolor.h:58: undefined reference to `_imp__lqr_carver_scan_ext' C:/temp/devel/graphics/digikam/imageplugins/../libs/dimg/dcolor.h:58: undefined reference to `_imp__lqr_carver_scan_ext' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizer12cancelFilterEv': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:202: undefined reference to `_imp__lqr_ carver_cancel' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizer17buildSkinToneBiasEv': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:231: undefined reference to `_imp__lqr_ carver_bias_add_xy' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizer9buildBiasERK6QImage': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:253: undefined reference to `_imp__lqr_ carver_bias_add_xy' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizerC1EPN7Digikam4DImgEjjidi25_LqrEnergyFuncBuiltinType15_LqrResizeOrderRK6QImagebP7QObject': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:92: undefined reference to `_imp__lqr_c arver_new_ext' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:100: undefined reference to `_imp__lqr_ carver_set_preserve_input_image' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:103: undefined reference to `_imp__lqr_ carver_init' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:106: undefined reference to `_imp__lqr_ progress_new' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:107: undefined reference to `_imp__lqr_ progress_set_init' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:108: undefined reference to `_imp__lqr_ progress_set_update' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:109: undefined reference to `_imp__lqr_ progress_set_end' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:110: undefined reference to `_imp__lqr_ carver_set_progress' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:112: undefined reference to `_imp__lqr_ carver_set_side_switch_frequency' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:115: undefined reference to `_imp__lqr_ carver_set_enl_step' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:118: undefined reference to `_imp__lqr_ carver_set_energy_function_builtin' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:122: undefined reference to `_imp__lqr_ carver_set_resize_order' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:124: undefined reference to `_imp__lqr_ carver_set_resize_order' CMakeFiles\digikamimageplugin_contentawareresizing.dir\contentawareresizer.obj: In function `ZN39DigikamContentAwareResizingImag esPlugin19ContentAwareResizerC2EPN7Digikam4DImgEjjidi25_LqrEnergyFuncBuiltinType15_LqrResizeOrderRK6QImagebP7QObject': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:92: undefined reference to `_imp__lqr_c arver_new_ext' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:100: undefined reference to `_imp__lqr_ carver_set_preserve_input_image' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:103: undefined reference to `_imp__lqr_ carver_init' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:106: undefined reference to `_imp__lqr_ progress_new' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:107: undefined reference to `_imp__lqr_ progress_set_init' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:108: undefined reference to `_imp__lqr_ progress_set_update' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:109: undefined reference to `_imp__lqr_ progress_set_end' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:110: undefined reference to `_imp__lqr_ carver_set_progress' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:112: undefined reference to `_imp__lqr_ carver_set_side_switch_frequency' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:115: undefined reference to `_imp__lqr_ carver_set_enl_step' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:118: undefined reference to `_imp__lqr_ carver_set_energy_function_builtin' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:122: undefined reference to `_imp__lqr_ carver_set_resize_order' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp:124: undefined reference to `_imp__lqr_ carver_set_resize_order' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_bias.obj: In function `lqr_carver_bias_add_xy': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:60: undefined reference to `_imp__lqr_car ver_flatten' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_bias.obj: In function `lqr_carver_bias_add_area': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:94: undefined reference to `_imp__lqr_car ver_flatten' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_bias.obj: In function `lqr_carver_bias_add': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:135: undefined reference to `_imp__lqr_ca rver_get_height' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:135: undefined reference to `_imp__lqr_ca rver_get_width' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_bias.obj: In function `lqr_carver_bias_add_rgb_area': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:154: undefined reference to `_imp__lqr_ca rver_flatten' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_bias.obj: In function `lqr_carver_bias_add_rgb': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:210: undefined reference to `_imp__lqr_ca rver_get_height' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_bias.c:210: undefined reference to `_imp__lqr_ca rver_get_width' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_new_common': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:69: undefined reference to `_imp__lqr_progress _new' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:99: undefined reference to `_imp__lqr_carver_s et_energy_function_builtin' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_set_gradient_function': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:433: undefined reference to `_imp__lqr_carver_ set_energy_function_builtin' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:433: undefined reference to `_imp__lqr_carver_ set_energy_function_builtin' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:433: undefined reference to `_imp__lqr_carver_ set_energy_function_builtin' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:433: undefined reference to `_imp__lqr_carver_ set_energy_function_builtin' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_propagate_vsmap': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1390: undefined reference to `_imp__lqr_carver _list_foreach_recursive' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_scan_reset_all': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:2099: undefined reference to `_imp__lqr_carver _list_foreach' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_set_state': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1960: undefined reference to `_imp__lqr_carver _list_foreach_recursive' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_flatten': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1455: undefined reference to `_imp__lqr_carver _list_foreach' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_transpose': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1600: undefined reference to `_imp__lqr_carver _list_foreach' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_inflate': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:832: undefined reference to `_imp__lqr_carver_ list_foreach' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_build_vsmap': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:787: undefined reference to `_imp__lqr_carver_ list_foreach_recursive' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_resize_height': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1875: undefined reference to `_imp__lqr_carver _list_foreach_recursive' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1880: undefined reference to `_imp__lqr_vmap_i nternal_dump' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_resize_width': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1799: undefined reference to `_imp__lqr_carver _list_foreach_recursive' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:1804: undefined reference to `_imp__lqr_vmap_i nternal_dump' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver.obj: In function `lqr_carver_scan_reset_attached': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver.c:2090: undefined reference to `_imp__lqr_carver _list_foreach' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_list.obj: In function `lqr_carver_list_destroy': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_list.c:66: undefined reference to `_imp__lqr_car ver_destroy' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_rigmask.obj: In function `lqr_carver_rigmask_add_xy': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_rigmask.c:76: undefined reference to `_imp__lqr_ carver_flatten' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_rigmask.obj: In function `lqr_carver_rigmask_add_area': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_rigmask.c:110: undefined reference to `_imp__lqr _carver_flatten' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_carver_rigmask.obj: In function `lqr_carver_rigmask_add_rgb_area' : C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_carver_rigmask.c:170: undefined reference to `_imp__lqr _carver_flatten' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_vmap.obj: In function `lqr_vmap_dump': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap.c:109: undefined reference to `_imp__lqr_carver_ge t_width' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap.c:110: undefined reference to `_imp__lqr_carver_ge t_height' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_vmap.obj: In function `lqr_vmap_internal_dump': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap.c:160: undefined reference to `_imp__lqr_carver_ge t_width' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap.c:161: undefined reference to `_imp__lqr_carver_ge t_height' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_vmap.obj: In function `lqr_vmap_load': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap.c:214: undefined reference to `_imp__lqr_carver_fl atten' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap.c:237: undefined reference to `_imp__lqr_carver_se t_enl_step' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_vmap_list.obj: In function `lqr_vmap_list_destroy': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_vmap_list.c:65: undefined reference to `_imp__lqr_vmap_ destroy' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_energy.obj: In function `lqr_energy_builtin_grad_all': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:331: undefined reference to `_imp__lqr_rwindow _get_read_t' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_energy.obj: In function `lqr_carver_get_energy': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:580: undefined reference to `_imp__lqr_carver_ flatten' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:585: undefined reference to `_imp__lqr_carver_ get_orientation' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:590: undefined reference to `_imp__lqr_carver_ get_width' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:591: undefined reference to `_imp__lqr_carver_ get_height' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_energy.obj: In function `lqr_carver_get_true_energy': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:635: undefined reference to `_imp__lqr_carver_ flatten' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:640: undefined reference to `_imp__lqr_carver_ get_orientation' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:645: undefined reference to `_imp__lqr_carver_ get_width' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:646: undefined reference to `_imp__lqr_carver_ get_height' CMakeFiles\digikamimageplugin_contentawareresizing.dir\lqr\lqr_energy.obj: In function `lqr_carver_get_energy_image': C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:741: undefined reference to `_imp__lqr_carver_ flatten' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:748: undefined reference to `_imp__lqr_carver_ get_orientation' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:753: undefined reference to `_imp__lqr_carver_ get_width' C:/temp/devel/graphics/digikam/imageplugins/contentawareresizing/lqr/lqr_energy.c:754: undefined reference to `_imp__lqr_carver_ get_height' collect2: ld returned 1 exit status make[2]: *** [bin/digikamimageplugin_contentawareresizing.dll] Error 1 make[1]: *** [digikam/imageplugins/contentawareresizing/CMakeFiles/digikamimageplugin_contentawareresizing.dir/all] Error 2 make: *** [all] Error 2 Note : make clean do not solve the problem. Linux version link fine of course. Gilles Caulier Gilles: pass the option -DLQR_DISABLE_DECLSPEC to the compiler when under MinGW and linking statically to the library. Thanks Carlo. Fixed. Compile fine under XP and Vista... Gilles Caulier Julien, I recommend to use DExpanderBox widget in settings aera instead DLabelExpander. Look how it's do in FreeRotation or Ratio crop tools. DExpanderBox can host more than can one DLabelExpander as well. It can read/write expand status of label. It's reduce code and factorize a lots of stuff. Also, i recommend : - to use an icon to label title (at least tool icon). - Reduce horizontal lines (separator). DExpanderBox add it automatically. - Add one or two label for standard settings (currently only advanced settings are hosted with expander container). I will be more clear and more homogenous with the rest of digiKam, because, with Andi, we will use it everywhere when it's possible... Gilles Caulier SVN commit 969414 by jnarboux: Use new DExpanderBox widget. CCBUGS: 149485 M +81 -58 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=969414 SVN commit 969434 by jnarboux: Add help for side switch frequency. CCBUGS: 149485 M +1 -1 contentawareresizetool.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=969434 Created attachment 34153 [details]
Usage of external lqr
The following patch adds support for
- finding an external lqr library, with a check for accepting only lqr >= 0.4 (as Gilles told me)
- in case it is found, use it for the contentawareresizing plugin
In case an external lqr is not found, everything stays as it is now, ie the internal copy of lqr is used.
This wish has now too many messages, let's sum up the TODO list: Known bug: mask is deleted when window is resized Speed: - study how to perform "real time" seamcarving by using Lqr properly - study parallelization of the carving process Implementation: - make the plugin thread safe Gui: - Add picture preview of the seams and of the energy - Mouse wheel should change brush size - Skin tones should be previewed as an orange mask Features: - Add more energy functions (prewit and sobel filter for instance) Julien, Great to see a resume here... I recommend to put a TODO file in svn with implementation plan and priority, especially for 1.0.0 release. Please identify which task need to be done before to close this file. Has you see the patch from Pino in #194 ? This one is important to apply in svn before 1.0.0-beta1 release (planed next Sunday http://www.digikam.org/about/releaseplan). It's for packagers, to be able to use external liblqr and reduce packaging size. Gilles SVN commit 976287 by jnarboux: Apply patch of Pino Toscano to use external Lqr is available. CCBUGS: 149485 M +6 -0 CMakeLists.txt M +34 -21 imageplugins/contentawareresizing/CMakeLists.txt WebSVN link: http://websvn.kde.org/?view=rev&revision=976287 SVN commit 976293 by pino: add cmake module for searching a lqr-1 library CCBUG: 149485 A FindLqr-1.cmake WebSVN link: http://websvn.kde.org/?view=rev&revision=976293 Pino, Why do you use "liblqr-1" and not "liblqr" in you CMake find script ? Gilles > Why do you use "liblqr-1" and not "liblqr" in you CMake find script ?
Because the library is called "lqr-1" (its soname is that one as well).
The trailing -1 smells like its developers will just change it as -2 whenever they break compatibility, but allowing both the old and the new libraries to be installed aside.
Carlo, Sound like there is no version string somewhere in liblqr header files. Right ? As now, we have the way to compile digiKam with an external version of the library, i would to print the version used by digiKam in components info dialog. This dialog contents is used to report bugs. Gilles (In reply to comment #201) > Sound like there is no version string somewhere in liblqr header files. Right ? It seems not, otherwise it would have used it for checking whether the available version was enough; I had to resort doing a compile of a very minimal C++ source using some feature available since lqr 0.4. Carlo, Gilles,
>In case an external lqr is not found, everything stays as it is now, ie the
internal copy of lqr is used.
What is your plan ? you think we should always keep an internal copy of lqr ? or we do it only for beta1 but for beta2 content aware plugin would be compiled only if lqr library is found ? this way gives time to packagers to test.
Julien
(In reply to comment #187) > Parallelising the the energy computation and the seam removal in LqR can be > done right away (a single OpenMP pragma is enough): I have now tried to > parallelise the carving operation and, to my surprise, I actually got a > performance loss. I have tested this on 2 and 4 core PC's and my results are > that more threads -> less performance, suggesting that the overhead cost for > this operation is too high. I could still try something a little more > sophisticated, though. Hi Carlo. Your results kind of alarmed me, so I went back and checked over some things. It's been quite awhile since I multithreaded Energy_Map(), so I rebuilt it running without any threads. To my surprise, I gained a significant performance boost. I hope I haven't wasted too much of your time on this. At this point I'm out of ideas. SVN commit 977062 by jnarboux: Add circle shaped cursor whose diameter is equal to brush size when painting mask. CCBUGS: 149485 M +0 -1 imageplugins/contentawareresizing/TODO M +9 -1 libs/widgets/imageplugins/imageguidewidget.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=977062 SVN commit 977100 by jnarboux: Fix bug: the mask was deleted when window is resized, now it is resized. CCBUGS: 149485 M +0 -2 imageplugins/contentawareresizing/TODO M +2 -4 libs/widgets/imageplugins/imageguidewidget.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=977100 (In reply to comment #200 by Pino) > Because the library is called "lqr-1" (its soname is that one as well). > The trailing -1 smells like its developers will just change it as -2 whenever > they break compatibility, but allowing both the old and the new libraries to > be installed aside. Yes, that was the plan. (In reply to comment #201 by Gilles) > Sound like there is no version string somewhere in liblqr header files. Right > ? Right, following the autoconf (& friends) model the version is put into the config.h header and only used at compile time. After installation the version number is only kept in the pkgconfig file, just as Pino noted. I will try to find a way to include the version info since next release. (In reply to comment #204 by Joe) >I hope I haven't wasted too much of your time on this. No, as I haven't had the time for _anything_ at all lately ;) but thanks for the update. Carlo, We have small problem, the current implementation is not thread safe and we will need a thread safe implementation in the future when lqr resizing is used inside the batch queue manager. The reason it is not thread safe is the presence of static functions for the progress bar. http://lxr.kde.org/source/extragear/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp#42 http://lxr.kde.org/source/extragear/graphics/digikam/imageplugins/contentawareresizing/contentawareresizer.cpp#47 Gilles told me that the solution is to put the static method in the private class: ContentAwareResizerPriv This can not be done right now because Lqr use C style to access those functions. The solution is to add another argument of type void* to send the address of the private class and then do a static cast. In the Gimp Lqr plugin this void* would be NULL as you do not need it becasue it is pure C. You can see how Gilles solved the same problem for another C library here: http://websvn.kde.org/?view=rev&revision=977483 Julien Carlo, Look like we have also fixed a similar problem in libraw with C++ KDE interface libkdcraw. No we use the same way, as you can see there : http://lxr.kde.org/source/KDE/kdegraphics/libs/libkdcraw/libkdcraw/kdcraw.cpp#270 http://lxr.kde.org/source/KDE/kdegraphics/libs/libkdcraw/libkdcraw/kdcraw_p.cpp#35 http://lxr.kde.org/source/KDE/kdegraphics/libs/libkdcraw/libkdcraw/kdcraw_p.cpp#63 http://lxr.kde.org/source/KDE/kdegraphics/libs/libkdcraw/libraw/libraw/libraw_types.h#79 http://lxr.kde.org/source/KDE/kdegraphics/libs/libkdcraw/libraw/libraw /libraw_types.h#81 http://lxr.kde.org/source/KDE/kdegraphics/libs/libkdcraw/libraw/libraw/libraw.h#103 Gilles Caulier SVN commit 977633 by jnarboux: Add a new tool to erase green or red masks. CCBUGS: 149485 M +1 -1 imageplugins/contentawareresizing/TODO M +29 -7 imageplugins/contentawareresizing/contentawareresizetool.cpp M +17 -5 libs/widgets/imageplugins/imageguidewidget.cpp M +3 -2 libs/widgets/imageplugins/imageguidewidget.h M +7 -2 libs/widgets/imageplugins/imagewidget.cpp M +2 -1 libs/widgets/imageplugins/imagewidget.h WebSVN link: http://websvn.kde.org/?view=rev&revision=977633 (in response to Comment #208 from Julien Narboux) > Carlo, > > We have small problem, the current implementation is not thread safe and we > will need a thread safe implementation in the future when lqr resizing is used > inside the batch queue manager. The reason it is not thread safe is the > presence of static functions for the progress bar. I'll have a look at the links that you and Gilles gave me, however I don't have much time in this period (and I have no internet connection at home currently), so I don't know when I will be able to cope with this problem. In the meanwhile: is there a specific reason not to use non-static functions for the progress bar as a temporary fix? The lqr_progress class is really tiny, it wouldn't be a big problem for memory and CPU... Carlo Carlo, We already use a static method to dispatch progress info from liblqr to plugin. It work because plugin use only 1 spearate thread to run liblqr. But in the future, we will move lqr code to digiKam core to be able to run liquid rescale tool in batch with more than one thread at the same time. In this case, the current static method is not thread safe. In fact i think it will not crash, but the progress info will become unsuitable. If i have time, i can try to patch liblqr code (as i have do with libpgf). Let's me hear if you is agree and which code i can use for that... Gilles Caulier Gilles, I understand the problem (well, kind of...), I was in fact suggesting to use non-static functions instead (i.e. to include the progress functions in the ContentAwareResizer class, and pass the class+function pointer to lqr). I'm not sure it would work, though, I was just asking. Anyway, if you want to patch the liblqr code please feel free to do it; you may take the git repo version (which I think is almost the same as 0.4.1) and send me a mail. Carlo >I understand the problem (well, kind of...), I was in fact suggesting to use >non-static functions instead (i.e. to include the progress functions in the >ContentAwareResizer class, and pass the class+function pointer to lqr). I'm not >sure it would work, though, I was just asking. Ah ah, well no it's doesn't work. passing non-static function from C++ don't work. Look here for details : http://www.newty.de/fpt/callback.html#example1 Gilles Caulier To Julien Nardoux, I think this file can be closed now. Future jobs can be done in new file if necessary. Right ? Gilles Caulier Gilles, Yes we can close this bug. Gilles, do you think we should remove the local copy of the Lqr library at some point ? or we keep it to simplify dependencies ? Julien Julien, Last patch from Pino check availablity of liblqr in local system. If it's found, internal liblqr is disable As we must use a recent version of liblqr, i recommend to delay a little the fact to remove internal version to be sure that all distro update liblqr to new version. I think we can do it before 1.0.0 final release. You just need to think about at the right time. Of course, CMake rules need to be fixed too... Gilles Hi, Before string freeze of 1.0.0, we need to make a final decision about the name of this plugin. Some propositions : 1- Liquid rescale 2- Content aware resizing 3- Recompose 1- is the same name as in Gimp 2- is the same name as in the research paper 3- is the same name as in a popular commercial product Julien For me: "Liquid rescale" is fine, not too long. "Content aware resizing" is definitively too long... "Recompose" is short and interesting... Gilles Number 2 is the real name, but Gille is right : it's too long. I think "liquid rescale" is the best, isn't it ? Created attachment 37396 [details]
Right sidebar with small screen size
A plugin name must be short. Why ? look on vertical buttons from right sidebar where the plugin will be plugged. If text is too long, layout become unreadable, especially for small screen...
And what about the name "smart rescale" ? |