TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Dinesh Iyer
Hi team,
I need to do some custom error handling which requires me to pass in the pointer to my class that is doing the TIFF I/O. I need this because I need to deliver warnings/errors to my application through a specific mechanism. 

I noticed that TIFFSetErrorHandlerExt does allow me to pass that as the first argument. I was wondering if it is sufficient to set one of the error handlers or do I have to set both. The same applies for warning handlers as well.

Regards,
Dinesh

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Bob Friesenhahn
On Fri, 17 Mar 2017, Dinesh Iyer wrote:

> Hi team,
> I need to do some custom error handling which requires me to pass in the
> pointer to my class that is doing the TIFF I/O. I need this because I need
> to deliver warnings/errors to my application through a specific mechanism.
>
> I noticed that TIFFSetErrorHandlerExt does allow me to pass that as the
> first argument. I was wondering if it is sufficient to set one of the error
> handlers or do I have to set both. The same applies for warning handlers as
> well.

These functions are redudant and both may be used at once.  If
TIFFSetErrorHandler() was used, then its error handler will be called.
If TIFFSetErrorHandlerExt() was used, then its error handler will be
called.  They are called in succession.

This means that you can just use TIFFSetErrorHandlerExt() and be
happy.

The main problem with these interfaces is that the internal storage
location is shared across threads so threads can't use different
handlers unless they serialize access to libtiff.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Dinesh Iyer
Thanks Bob.

If I understand you correctly, I cannot have multiple threads each with its own handler throwing errors/warnings. i need to ensure that only one thread does the error handling, am I correct?

As a follow up, do i have to set the client_data field with a pointer to my class such that it is accessible in the callbacks?

Regards
Dinesh

On Fri, Mar 17, 2017 at 10:53 AM, Bob Friesenhahn <[hidden email]> wrote:
On Fri, 17 Mar 2017, Dinesh Iyer wrote:

Hi team,
I need to do some custom error handling which requires me to pass in the
pointer to my class that is doing the TIFF I/O. I need this because I need
to deliver warnings/errors to my application through a specific mechanism.

I noticed that TIFFSetErrorHandlerExt does allow me to pass that as the
first argument. I was wondering if it is sufficient to set one of the error
handlers or do I have to set both. The same applies for warning handlers as
well.

These functions are redudant and both may be used at once.  If TIFFSetErrorHandler() was used, then its error handler will be called. If TIFFSetErrorHandlerExt() was used, then its error handler will be called.  They are called in succession.

This means that you can just use TIFFSetErrorHandlerExt() and be happy.

The main problem with these interfaces is that the internal storage location is shared across threads so threads can't use different handlers unless they serialize access to libtiff.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/


_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Dinesh Iyer
Hi Bob,
I am not sure I understand how to pass custom client data into the handler. I was under the assumption that once the TIFFOpen succeeds, I could update the client_data field. However, this does not appear to be possible. Additionally, I am not sure how to handle warnings generated during the TIFFOpen call.

Any help would be appreciated.

Regards,
Dinesh


On Fri, Mar 17, 2017 at 11:53 AM, Dinesh Iyer <[hidden email]> wrote:
Thanks Bob.

If I understand you correctly, I cannot have multiple threads each with its own handler throwing errors/warnings. i need to ensure that only one thread does the error handling, am I correct?

As a follow up, do i have to set the client_data field with a pointer to my class such that it is accessible in the callbacks?

Regards
Dinesh

On Fri, Mar 17, 2017 at 10:53 AM, Bob Friesenhahn <[hidden email]> wrote:
On Fri, 17 Mar 2017, Dinesh Iyer wrote:

Hi team,
I need to do some custom error handling which requires me to pass in the
pointer to my class that is doing the TIFF I/O. I need this because I need
to deliver warnings/errors to my application through a specific mechanism.

I noticed that TIFFSetErrorHandlerExt does allow me to pass that as the
first argument. I was wondering if it is sufficient to set one of the error
handlers or do I have to set both. The same applies for warning handlers as
well.

These functions are redudant and both may be used at once.  If TIFFSetErrorHandler() was used, then its error handler will be called. If TIFFSetErrorHandlerExt() was used, then its error handler will be called.  They are called in succession.

This means that you can just use TIFFSetErrorHandlerExt() and be happy.

The main problem with these interfaces is that the internal storage location is shared across threads so threads can't use different handlers unless they serialize access to libtiff.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/



_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Dinesh Iyer
Hi Bob,
It look like I need to to use TIFFClientOpen to open the file and pass in my own routines for reading/writing seeking if I need to pass in client data. Am I correct? This appears to be rather wasteful if all I want to do is pass some client data. Is there a way to force the library to use defaults if one is not provided?

Regards,
Dinesh

On Fri, Mar 17, 2017 at 12:07 PM, Dinesh Iyer <[hidden email]> wrote:
Hi Bob,
I am not sure I understand how to pass custom client data into the handler. I was under the assumption that once the TIFFOpen succeeds, I could update the client_data field. However, this does not appear to be possible. Additionally, I am not sure how to handle warnings generated during the TIFFOpen call.

Any help would be appreciated.

Regards,
Dinesh


On Fri, Mar 17, 2017 at 11:53 AM, Dinesh Iyer <[hidden email]> wrote:
Thanks Bob.

If I understand you correctly, I cannot have multiple threads each with its own handler throwing errors/warnings. i need to ensure that only one thread does the error handling, am I correct?

As a follow up, do i have to set the client_data field with a pointer to my class such that it is accessible in the callbacks?

Regards
Dinesh

On Fri, Mar 17, 2017 at 10:53 AM, Bob Friesenhahn <[hidden email]> wrote:
On Fri, 17 Mar 2017, Dinesh Iyer wrote:

Hi team,
I need to do some custom error handling which requires me to pass in the
pointer to my class that is doing the TIFF I/O. I need this because I need
to deliver warnings/errors to my application through a specific mechanism.

I noticed that TIFFSetErrorHandlerExt does allow me to pass that as the
first argument. I was wondering if it is sufficient to set one of the error
handlers or do I have to set both. The same applies for warning handlers as
well.

These functions are redudant and both may be used at once.  If TIFFSetErrorHandler() was used, then its error handler will be called. If TIFFSetErrorHandlerExt() was used, then its error handler will be called.  They are called in succession.

This means that you can just use TIFFSetErrorHandlerExt() and be happy.

The main problem with these interfaces is that the internal storage location is shared across threads so threads can't use different handlers unless they serialize access to libtiff.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/




_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Bob Friesenhahn
In reply to this post by Dinesh Iyer
On Fri, 17 Mar 2017, Dinesh Iyer wrote:

> Thanks Bob.
>
> If I understand you correctly, I cannot have multiple threads each with its
> own handler throwing errors/warnings. i need to ensure that only one thread
> does the error handling, am I correct?

You can only register one error handling function at a time.  The
function will be called under the same context as the thread which
encountered the problem.  Knowing that it is called under the same
execution context can be very useful.

> As a follow up, do i have to set the client_data field with a pointer to my
> class such that it is accessible in the callbacks?

The client_data is for you.  If you use TIFFClientOpen() then it is
provided so that you can use it has a handle for I/O or other
purposes (e.g. also for errors).

In GraphicsMagick I use TIFFSetErrorHandler()/TIFFSetWarningHandler()
and I use thread-specific data (POSIX or Windows) to reconcile between
the error callback data and what the thread was working on.  I don't
use client_data for that purpose.  This approach works if there is
just one thread which ever does libtiff operations for a given handle.

The reason for the approach in GraphicsMagick is that the
implementation pre-dates the addition of TIFFSetErrorHandlerExt() and
it also works for older libtiff.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Bob Friesenhahn
In reply to this post by Dinesh Iyer
On Fri, 17 Mar 2017, Dinesh Iyer wrote:

> Hi Bob,
> It look like I need to to use TIFFClientOpen to open the file and pass in
> my own routines for reading/writing seeking if I need to pass in client
> data. Am I correct? This appears to be rather wasteful if all I want to do
> is pass some client data. Is there a way to force the library to use
> defaults if one is not provided?

I think you are correct, particularly if the problem occurs while
opening the TIFF file.  Consider using thread specific data if is
easier for you than adding an I/O wrapper.

If there is only ever one thread then global data can work as well.

Libtiff API additions could solve these issues.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Yakov Galka
Hi All,

On Fri, Mar 17, 2017 at 7:06 PM, Bob Friesenhahn <[hidden email]> wrote:
Libtiff API additions could solve these issues.

I would like to remind that the additions at [1] and [2] aim to solve those exact problems the OP is facing, specifically by allowing client-data and error-handlers configuration separate from the TIFFOpen call.

[1] http://stannum.co.il/data/tiff-changes.diff
[2] http://stannum.co.il/data/tiff-autorep.diff

Cheers & have a nice day,
--

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

rleigh
In reply to this post by Bob Friesenhahn
On 2017-03-17 17:02, Bob Friesenhahn wrote:

> On Fri, 17 Mar 2017, Dinesh Iyer wrote:
>
>> Thanks Bob.
>>
>> If I understand you correctly, I cannot have multiple threads each
>> with its
>> own handler throwing errors/warnings. i need to ensure that only one
>> thread
>> does the error handling, am I correct?
>
> You can only register one error handling function at a time.  The
> function will be called under the same context as the thread which
> encountered the problem.  Knowing that it is called under the same
> execution context can be very useful.
>
>> As a follow up, do i have to set the client_data field with a pointer
>> to my
>> class such that it is accessible in the callbacks?
>
> The client_data is for you.  If you use TIFFClientOpen() then it is
> provided so that you can use it has a handle for I/O or other
> purposes (e.g. also for errors).
>
> In GraphicsMagick I use TIFFSetErrorHandler()/TIFFSetWarningHandler()
> and I use thread-specific data (POSIX or Windows) to reconcile between
> the error callback data and what the thread was working on.  I don't
> use client_data for that purpose.  This approach works if there is
> just one thread which ever does libtiff operations for a given handle.
>
> The reason for the approach in GraphicsMagick is that the
> implementation pre-dates the addition of TIFFSetErrorHandlerExt() and
> it also works for older libtiff.

Could I suggest a perhaps controversial but useful solution for handling
errors, which might be worth your consideration.

If the libtiff core were to use a C++ TIFF class reporting errors via
exceptions, it would be possible for this to be wrapped by the existing
C API calling the C++ code in a try/catch block and reporting any thrown
errors via the handlers.  Or direct use by C++ code without any of that
overhead--it could use the C++ API directly with exceptions.  This would
permit completely thread-safe use from C++, and it would also permit
multiple C error handling strategies--either with the global handler as
now, a per-TIFF handler or something completely different.  The C API
could simply be a thin wrapper around the C++ core, and remain 100%
backward compatible while also allowing direct use from C++ without
wrapping the C code.

In the OME project I currently work on, we already have a fairly complex
C++ wrapper around the C API.  It works, but due to the need to
synchronise for the context-specific error handler, it's much more
inefficient and complex than it would need to be were it native.  If
using a C++ core would be something worth considering, it's likely I
could dedicate some paid time to working on it, since it would replace a
whole lot of wrapper code we already have to maintain.


Regards,
Roger

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Bob Friesenhahn
On Fri, 17 Mar 2017, [hidden email] wrote:
> Could I suggest a perhaps controversial but useful solution for handling
> errors, which might be worth your consideration.
>
> If the libtiff core were to use a C++ TIFF class reporting errors via
> exceptions, it would be possible for this to be wrapped by the existing
> C API calling the C++ code in a try/catch block and reporting any thrown
> errors via the handlers.  Or direct use by C++ code without any of that

Unfortunately, throwing C++ exceptions through C code is not portable.
It would require that the using program to be linked using the C++
compiler.  The built library would only support one C++ compiler
(perhaps just one of several C++ dialects supported by the same
compiler) due to C++ compiler run-time libraries and name mangling.

I like C++ but libtiff needs to remain a plain C library.

The libtiff API can be improved to make it easier for C++ and threaded
programs to use it more effectively.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

rleigh
On 17/03/2017 21:08, Bob Friesenhahn wrote:

> On Fri, 17 Mar 2017, [hidden email] wrote:
>> Could I suggest a perhaps controversial but useful solution for handling
>> errors, which might be worth your consideration.
>>
>> If the libtiff core were to use a C++ TIFF class reporting errors via
>> exceptions, it would be possible for this to be wrapped by the existing
>> C API calling the C++ code in a try/catch block and reporting any thrown
>> errors via the handlers.  Or direct use by C++ code without any of that
>
> Unfortunately, throwing C++ exceptions through C code is not portable.
> It would require that the using program to be linked using the C++
> compiler.  The built library would only support one C++ compiler
> (perhaps just one of several C++ dialects supported by the same
> compiler) due to C++ compiler run-time libraries and name mangling.
>
> I like C++ but libtiff needs to remain a plain C library.

Note I'm not suggesting that exceptions be thrown through C code;
if the C++ code is wrapped by 'extern "C"' functions, these could
catch and handle the exceptions internally.  This is the approach taken
by e.g. the Mesa OpenGL implementation which has a C ABI but uses C++
internally.

If a C++ ABI was exposed, it would introduce additional linking
requirements if static.  That's something which could be done as a
separate step though--if used internally without using the C++ standard
library, it should be completely self-contained and could have an
identical ABI to the existing implementation.

Keeping libtiff as a plain C library is of course a fine direction; I
just wanted to mention this as a potentially beneficial direction which
could be taken, particularly if you wanted to cater for better usage
from C++ with regard to error handling, and also things like type-safe
field access.


Regards,
Roger

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Paavo Helde
In reply to this post by Bob Friesenhahn

On 17.03.2017 23:08, Bob Friesenhahn wrote:

> On Fri, 17 Mar 2017, [hidden email] wrote:
>> Could I suggest a perhaps controversial but useful solution for handling
>> errors, which might be worth your consideration.
>>
>> If the libtiff core were to use a C++ TIFF class reporting errors via
>> exceptions, it would be possible for this to be wrapped by the existing
>> C API calling the C++ code in a try/catch block and reporting any thrown
>> errors via the handlers.  Or direct use by C++ code without any of that
> Unfortunately, throwing C++ exceptions through C code is not portable.
> It would require that the using program to be linked using the C++
> compiler.  The built library would only support one C++ compiler
> (perhaps just one of several C++ dialects supported by the same
> compiler) due to C++ compiler run-time libraries and name mangling.

A C++ library can have an interface defined purely in extern "C"
functions. This does not help with exceptions (which cannot be passed
through extern "C" functions (portably)), but it gets rid of the
problems of compiler versions and name manglings.

I have developed an extern "C" interface for a large C++ library and I
think this has proved to be quite a success. The error handling is done
by try-catch in each interface function and storing the exception in
thread-local storage. There is a special interface function for
obtaining the last stored error message in the current thread which the
client code is supposed to use in the case of a failing call.

This does not mean libTIFF should be converted to C++. It's just a
general remark that a library does not need to be developed in C in
order to have C interface.

Best
Paavo

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Bob Friesenhahn
On Sat, 18 Mar 2017, Paavo Helde wrote:
>
> This does not mean libTIFF should be converted to C++. It's just a
> general remark that a library does not need to be developed in C in
> order to have C interface.

I agree with what you said, but need to point out that it is still
necessary to link with the C++ compiler to be assured of success.  In
my experience this proves to be painful when dealing with many
platforms and compilers.  Now there are many flavors of C++ and C++
run-times (forward progress of C++ standards and alternative C++
libraries) so there are more things to get right at link-time.

If there is only one target platform, then things are much easier.

The current error reporting is based on a callback and it does not
matter much if the callback is called immediately at the point where
the problem occured, or an exception is thrown, caught, and then the
callback is called just under the called C API.

It is easiest to fix the libtiff C API to be more suitable.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: TIFFSetErrorHandler vs TIFFSetErrorHandlerExt

Yakov Galka
In reply to this post by rleigh

On Fri, Mar 17, 2017 at 11:02 PM, <[hidden email]> wrote:
If the libtiff core were to use a C++ TIFF class reporting errors via
exceptions, it would be possible for this to be wrapped by the existing
C API calling the C++ code in a try/catch block and reporting any thrown
errors via the handlers.

The Error handlers are not the only way libTIFF reports errors. The no. 1 way it reports errors is through return values. The error and warning handlers are used more like a logging facility to output extra information about the cause of the errors and other issues. In particular when one of them gets called it is not supposed to abort the caller execution (either by throw or longjmp), because, among other things, the processing may continue and call the handlers multiple times. Therefore, exceptions are a not a substitute for them even if libTIFF were a C++ library.

--

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Loading...