Trap or suppress warnings when using Exiv2 library?

Added by Hank Barta over 8 years ago

Hi folks,
I'm working on some code that will use Exiv2 to extract EXIF information from digital camera images. During my initial testing, some images produce a warning:

Warning: Directory NikonPreview, entry 0x0201: Data area exceeds data buffer, ignoring it.

Is there some way to programatically trap or suppress warnings like this? I have searched the documentation and this forum for a clue to this and not found anything. Perhaps it is just my search skills...

A pointer in the right direction would be most appreciated!

thanks,
hank


Replies (14)

RE: Trap or suppress warnings when using Exiv2 library? - Added by Andreas Huggel over 8 years ago

Hi Hank,

These warnings are written to standard error and the only control that is available in the library is a compile-time #define SUPPRESS_WARNINGS. So if you have control over the library in your environment you can just compile it with this define set.

There is a long outstanding issue (#614 and the related issue #476, which is even older) for finer control at runtime, exactly what you're asking for, but that's not anywhere near the top of my todo list and I'm not aware of anyone else working on this. If you're willing to take this up yourself, I would be happy to discuss the approach.

Finally, since an application can control standard error, it is still possible to do something about it from your program. IIRC in ufraw Udi controls exiv2 warnings by suppressing or redirecting standard error; take a look at the ufraw source code for details.

Andreas

RE: Trap or suppress warnings when using Exiv2 library? - Added by Steve Wright over 8 years ago

Hank,

If you have the time to do it, please proceed with it. Myself, I'm finding it monotonous to rely on "2>/dev/null" to suppress errors on the command line or in shell scripts. It's only a redirection, after all. And in some scripts, it gets ignored -- either that or I forget which ones have it and which don't and wind up "double-dipping," which as you know produces a reversion to defaults.

Maybe it's time for an .exiv2rc?

S.

RE: Trap or suppress warnings when using Exiv2 library? - Added by Hank Barta over 8 years ago

Hi guys,
Thanks for the suggestions.

I have added -DSUPPRESS_WARNINGS to the compile line and the warning persists, so I interpret that to mean that the library itself has to be built with the switch enabled.

My first consideration on working with that is what sort of can-O-worms it opens for me WRT my system. I am running Ubuntu Desktop. I searched for and did not find a source package for libexiv2. I'm not familiar enough with Linux development to know if I can effectively build and test libraries w/out messing up the rest of my system. I suppose at worst I could set up a VM and develop within that. (I also suppose it is possible to develop and test libraries w/out the need to replace system libraries. To not have that capability would just be silly.)

I guess the next thing to do is ask Andreas to describe what he would like to see done in this regard. While I wait for that response I will examine the issues that Andreas listed above and see about fetching a copy of the source.

thanks,
hank

RE: Trap or suppress warnings when using Exiv2 library? - Added by Robin Mills over 8 years ago

It is quite easy to build exiv2 from source. There are some dependancies (expat and zlib spring to mind - there may be others). However most opensource is easily to build on Ubuntu. You can download the code from the exiv2 web site as a tar bundle, or use svn checkout. Once in the exiv2 directory you issue the terminal commands:

$ make config
$ ./configure
$ make
$ sudo make install

Of course you'll need to install the C++ compiler/development tools. However the Ubuntu Synaptic Package Installer will do this for you. In addition, the Package Installer can install development versions of most of the dependent libraries (such as expat). So you probably won't need to pull down and build them. The good news is that the recipe "make config ; ./configure ; make ; sudo make install" works on most open-source code. So even if you have to build all depenancies, it's not especially onerous.

Building software from source may seem a little painful, however it is the price of admission to this world. It's called 'opensource' because it is source! And the skills learned to build exiv2 can be reused with lots of other projects.

If you feel up to the challenge, it would be great if you could tackle this task and report back your experience (hopefully good). If you'd prefer not to accept the challenge then here's my offer:

I've been asked to look at a pyexiv2/exiv2/phatch issue next week on Lucid alpha-3 (the RC for Ubunut 10-4). I'm off running in the Napa Valley Marathon this weekend, so this will have to wait until one evening next wee. I plan to set up a clean virtual machine and install Lucid. I'll build exiv2 and build from scratch. I'll be happy to list everything I do here.

RE: Trap or suppress warnings when using Exiv2 library? - Added by Hank Barta over 8 years ago

Hi Robin,
Thanks for the tip. It's actually the "make install" part that concerns me as at best, it will clobber the libraries already installed by Ubuntu and at worst, it will install libraries in different (public) locations. I'll have to see what options the config script offers to provide an alternate installation.

No need to sell me on open source. I've been running Ubuntu since their first release and Debian, Slakware and Yggdrasil before that. My open source roots go back to SCO SysV r3.2 and comp.sources.unix.

Good luck in the marathon!

Having looked at the issues listed above (but not the code) I've formulated a tentative plan to refine handling for errors and warnings. I would add virtual functions to the classes that produce errors and warnings that would be called to handle the conditions. Default behavior would be to report the condition as does the existing code. Developers using the libraries could simply subclass those classes and redefine those functions to provide whatever behavior they require.

For the purpose of managing the behavior of applications that already use libexiv2, the default behavior could be enhanced to use environment variables or config file to alter the default behavior.

Now is the time to object if this direction is not suitable or desirable.

thanks,
hank

RE: Trap or suppress warnings when using Exiv2 library? - Added by Robin Mills over 8 years ago

Hank

Well this all sounds quite OK with me. As far as I know, exiv2 installs into /usr/local/{bin|include|lib|man|share} and doesn't install/overwrite anything 'public'. I've never worried about this - so I've never bothered to figure who/what exactly gets done (nor wanted anything other than the default).

I would like to share my thoughts with your about environment strings and configuration files and stuff. However before I offer any further input on this, I'd like Andreas to 'chime in' with his thoughts about the changes you are suggesting.

RE: Trap or suppress warnings when using Exiv2 library? - Added by Andreas Huggel over 8 years ago

From the README:

The default install locations are /usr/local/lib for the library,
/usr/local/bin for the exiv2 utility and /usr/local/include/exiv2 for the
header files. Use the --prefix=directory option of the configure script to
change the default. Run './configure --help' to see a list of all options.

To uninstall Exiv2 from a UNIX-like system, run:

    $ make uninstall

That way you can easily install to a custom directory, say /home/hank/src/exiv2/trunk. The only thing to consider is that you may also need to adjust some environment variables, namely PATH, LD_LIBRARY_PATH and PKG_CONFIG_PATH to tell your system about this choice.

-ahu.

RE: Trap or suppress warnings when using Exiv2 library? - Added by Andreas Huggel over 8 years ago

Having looked at the issues listed above (but not the code) I've formulated a tentative plan to refine handling for errors and warnings. I would add virtual functions to the classes that produce errors and warnings that would be called to handle the conditions. Default behavior would be to report the condition as does the existing code. Developers using the libraries could simply subclass those classes and redefine those functions to provide whatever behavior they require.

For the purpose of managing the behavior of applications that already use libexiv2, the default behavior could be enhanced to use environment variables or config file to alter the default behavior.

Now is the time to object if this direction is not suitable or desirable.

Great! That sounds like someone who is ready to start hacking!

The current library code is very basic. Warnings are simply written out to standard error, like this:

#ifndef SUPPRESS_WARNINGS
            std::cerr << "Warning: " 
                      << "Directory " << tiffGroupName(group())
                      << ", entry 0x" << std::setw(4)
                      << std::setfill('0') << std::hex << tag()
                      << ": Size or data offset value not set, ignoring them.\n";
#endif

There is a bit more code to support exceptions, but most of it is behind the scenes. Library code that throws an exception looks like this:

            if (!ret) throw Error(45, schemaNs);

I think the two can remain independent, i.e., any enhanced logic for warnings doesn't need to touch the Error classes, which are strictly for exceptions. It can go into the same files, though: error.hpp and error.cpp.

The library writes a lot of warnings like the one above (a quick count showed more than 120), and it's easy for a library developer to write warnings like this. Thus it's probably worth implementing something that requires little change of the existing code and is similarly simple to use. What about an Exiv2::Warning class with an output operator, so that the above becomes

            Exiv2::Warning << "Warning: Directory " << tiffGroupName(group()) << ...

And warning levels as requested in #614 could be added using manipulators, like:

            Exiv2::Warning << Exiv2::info << "Directory " << tiffGroupName(group()) << ...

However, if this fancy design requires anything out of the ordinary, in particular, initialization code, e.g., something like an Exiv2::init() function that applications need to call before the library can be used, then I'd rather go for a simpler solution and put up with more changes and less readable warning code in the library (hiding and automagically execute such initialization code is also not an option).

A simpler solution could just be a function that takes a warning level and a string with the warning text, used like this:

            std::ostringstream os;
            os << "Warning: Directory " << tiffGroupName(group()) << ...
            Exiv2::warning(Exiv2::info, os.str());

The basic requirement for an application that wants to implement custom behaviour is that it must be able to do that at runtime and without changing or re-compiling the library. If that can be done by subclassing something, then great; I doubt that is possible though (but would be happy to be shown otherwise). Alternatively, maybe the application can simply register a custom function with the library which is then called to process warnings.

I'm not keen to introduce a config file or the use of environment variables for this functionality. The library should continue to do what it's doing now by default without any initialization and if that behaviour can be configured (e.g., to set the desired warning level for output or to change the output stream or to set a custom output function), then that should be done through function calls.

Whichever way, let's discuss the design in detail and draft it here before you spend time changing a lot of code.

Finally, before you continue, consider that I require the copyright of all contributed code to be assigned to me; contributors get credit as source code authors. If you're not ok with that, please don't proceed.

-ahu.

RE: Trap or suppress warnings when using Exiv2 library? - Added by Hank Barta over 8 years ago

"The library writes a lot of warnings like the one above (a quick count showed more than 120),"

hbarta@cypress:~/Documents/Projects/trunk/C++/Exiv2-dev/trunk$ find .. -name "*.?pp"| xargs grep \"Warning|wc -l
106

These are all in the /src directory. Am I missing some?

I have no difficulty assigning copyright of any changes I make to you.

-hank

RE: Trap or suppress warnings when using Exiv2 library? - Added by Andreas Huggel over 8 years ago

These are all in the /src directory. Am I missing some?

Yes, they are all in the src/ directory, in the *.cpp files. Some say "Error" rather than "Warning" though, in an attempt to indicate the severity. (IIRC I counted SUPPRESS_WARNINGS in all these files.)

-ahu.

RE: Trap or suppress warnings when using Exiv2 library? - Added by Hank Barta over 8 years ago

I have decided to take a different approach based on the pattern demonstrated in the samples found on http://alexvn.freeservers.com/s1/download.html for redirecting cout/cerr. The following code works on a Linux system:

/*
 * Demonstrate redirecting std::cerr to some other location
 */

#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char** argv)
{
    cerr << "Hello World" << endl;
    ofstream    nullstr("/dev/nul"); // open a file stream to /dev/null

    streambuf* os = cerr.rdbuf(nullstr.rdbuf()); // replace cerr's streambuf 
                                                 // with one that goes to 
                                                 // /dev/null, saving the 
                                                 // original streambuf

    cerr << "This should never be seen" << endl;

    cerr.rdbuf(os); // restore cerr's original streambuf to prevent bad 
                    // things on exit.

    cerr << "Goodbye World" << endl;

    return 0;
}

A secondary benefit (at least to me) is that it will work with an unmodified library so I need not go through the difficulty of building and using my own copy of the library side by side with the older version installed as part of my distro.

Unfortunately, it does nothing to move you any closer to solutions for the other issues you listed.

-hank

RE: Trap or suppress warnings when using Exiv2 library? - Added by Steve Wright about 8 years ago

And for those of us for whom Exiv2 is an app more than a library...what options do we have for "quieting" or trapping errors?
Or have I been misreading all of the threads and issue posts on this?

And on top of it all, I forgot which link brings one to the latest manpage edit. I'm betting there's a -q or --quiet option now, but I'd prefer to know for sure before I try it (don't want to get an error G).

Steve W.

RE: Trap or suppress warnings when using Exiv2 library? - Added by Andreas Huggel about 8 years ago

Yes, the exiv2 command line tool now has a -q option which suppresses warnings and errors. It is currently available in the SVN repository and will be released with 0.21. exiv2 -h is a quick way to check what options your version has.

Andreas

RE: Trap or suppress warnings when using Exiv2 library? - Added by Steve Wright about 8 years ago

And after "-q" -- don't forget "file and error" (easy to remember -- just think "Trial & Error")

I think I might have suggested it in another thread: what most annoyed me about Exiv2's error reporting to date wasn't so much the frequency of occurrence but more in what they were missing when invoked in loops in scripts and such: the name of the file that threw the error.

Attached you'll find my script "exivate" which has stood me well for a month as a work-around to this missing element of error reporting. It doesn't do it to stdout, as that might slow down script execution, but I've so far relied on it as a "checker/tester" to see how files will pass muster when other scripts invoking the CLI tool are run on them.

Steve W.

exivate.sh.txt Magnifier (498 Bytes)

(1-14/14)

Redmine Appliance - Powered by TurnKey Linux