From: Tony Cook Date: Thu, 16 Aug 2012 09:54:21 +0000 (+1000) Subject: avoid using globals when capturing TIFF warnings X-Git-Tag: v0.92_01~8 X-Git-Url: http://git.imager.perl.org/imager.git/commitdiff_plain/ea4e3231912df83a669c9e8005a9950c47ef06d9?hp=9fdf85c03a6f9b62e10190d2b196cdc69fd88cde avoid using globals when capturing TIFF warnings --- diff --git a/TIFF/Changes b/TIFF/Changes index 37a87074..2c3c19d8 100644 --- a/TIFF/Changes +++ b/TIFF/Changes @@ -1,3 +1,9 @@ +Imager-File-TIFF 0.85 +===================== + + - for libtiff versions that support extended warning handlers (3.8.0 + or later), use them to avoid some global variables. + Imager-File-TIFF 0.83 ===================== diff --git a/TIFF/TIFF.pm b/TIFF/TIFF.pm index 55e3ca9b..4c95a922 100644 --- a/TIFF/TIFF.pm +++ b/TIFF/TIFF.pm @@ -4,7 +4,7 @@ use Imager; use vars qw($VERSION @ISA); BEGIN { - $VERSION = "0.83"; + $VERSION = "0.84"; require XSLoader; XSLoader::load('Imager::File::TIFF', $VERSION); diff --git a/TIFF/imtiff.c b/TIFF/imtiff.c index 832f38d4..1f5aa06c 100644 --- a/TIFF/imtiff.c +++ b/TIFF/imtiff.c @@ -171,12 +171,69 @@ fallback_rgb_channels(TIFF *tif, i_img_dim width, i_img_dim height, int *channel static const int text_tag_count = sizeof(text_tag_names) / sizeof(*text_tag_names); +#if TIFFLIB_VERSION >= 20051230 +#define USE_EXT_WARN_HANDLER +#endif + +#define TIFFIO_MAGIC 0xC6A340CC + static void error_handler(char const *module, char const *fmt, va_list ap) { mm_log((1, "tiff error fmt %s\n", fmt)); i_push_errorvf(0, fmt, ap); } +typedef struct { + unsigned magic; + io_glue *ig; +#ifdef USE_EXT_WARN_HANDLER + char *warn_buffer; + size_t warn_size; +#endif +} tiffio_context_t; + +static void +tiffio_context_init(tiffio_context_t *c, io_glue *ig); +static void +tiffio_context_final(tiffio_context_t *c); + #define WARN_BUFFER_LIMIT 10000 + +#ifdef USE_EXT_WARN_HANDLER + +static void +warn_handler_ex(thandle_t h, const char *module, const char *fmt, va_list ap) { + tiffio_context_t *c = (tiffio_context_t *)h; + char buf[200]; + + if (c->magic != TIFFIO_MAGIC) + return; + + buf[0] = '\0'; +#ifdef IMAGER_VSNPRINTF + vsnprintf(buf, sizeof(buf), fmt, ap); +#else + vsprintf(buf, fmt, ap); +#endif + mm_log((1, "tiff warning %s\n", buf)); + + if (!c->warn_buffer || strlen(c->warn_buffer)+strlen(buf)+2 > c->warn_size) { + size_t new_size = c->warn_size + strlen(buf) + 2; + char *old_buffer = c->warn_buffer; + if (new_size > WARN_BUFFER_LIMIT) { + new_size = WARN_BUFFER_LIMIT; + } + c->warn_buffer = myrealloc(c->warn_buffer, new_size); + if (!old_buffer) c->warn_buffer[0] = '\0'; + c->warn_size = new_size; + } + if (strlen(c->warn_buffer)+strlen(buf)+2 <= c->warn_size) { + strcat(c->warn_buffer, buf); + strcat(c->warn_buffer, "\n"); + } +} + +#else + static char *warn_buffer = NULL; static int warn_buffer_size = 0; @@ -207,6 +264,8 @@ static void warn_handler(char const *module, char const *fmt, va_list ap) { } } +#endif + static int save_tiff_tags(TIFF *tif, i_img *im); static void @@ -233,7 +292,7 @@ Compatability for 64 bit systems like latest freebsd (internal) static toff_t comp_seek(thandle_t h, toff_t o, int w) { - io_glue *ig = (io_glue*)h; + io_glue *ig = ((tiffio_context_t *)h)->ig; return (toff_t) i_io_seek(ig, o, w); } @@ -270,17 +329,17 @@ comp_munmap(thandle_t h, tdata_t p, toff_t off) { static tsize_t comp_read(thandle_t h, tdata_t p, tsize_t size) { - return i_io_read((io_glue *)h, p, size); + return i_io_read(((tiffio_context_t *)h)->ig, p, size); } static tsize_t comp_write(thandle_t h, tdata_t p, tsize_t size) { - return i_io_write((io_glue *)h, p, size); + return i_io_write(((tiffio_context_t *)h)->ig, p, size); } static int comp_close(thandle_t h) { - return i_io_close((io_glue *)h); + return i_io_close(((tiffio_context_t *)h)->ig); } static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) { @@ -520,10 +579,20 @@ static i_img *read_one_tiff(TIFF *tif, int allow_incomplete) { } i_tags_set(&im->tags, "i_format", "tiff", 4); +#ifdef USE_EXT_WARN_HANDLER + { + tiffio_context_t *ctx = TIFFClientdata(tif); + if (ctx->warn_buffer && ctx->warn_buffer[0]) { + i_tags_set(&im->tags, "i_warning", ctx->warn_buffer, -1); + ctx->warn_buffer[0] = '\0'; + } + } +#else if (warn_buffer && *warn_buffer) { i_tags_set(&im->tags, "i_warning", warn_buffer, -1); *warn_buffer = '\0'; } +#endif for (i = 0; i < compress_value_count; ++i) { if (compress_values[i].tag == compress) { @@ -545,23 +614,33 @@ i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) { TIFF* tif; TIFFErrorHandler old_handler; TIFFErrorHandler old_warn_handler; +#ifdef USE_EXT_WARN_HANDLER + TIFFErrorHandlerExt old_ext_warn_handler; +#endif i_img *im; int current_page; + tiffio_context_t ctx; i_clear_error(); old_handler = TIFFSetErrorHandler(error_handler); +#ifdef USE_EXT_WARN_HANDLER + old_warn_handler = TIFFSetWarningHandler(NULL); + old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex); +#else old_warn_handler = TIFFSetWarningHandler(warn_handler); if (warn_buffer) *warn_buffer = '\0'; +#endif /* Add code to get the filename info from the iolayer */ /* Also add code to check for mmapped code */ mm_log((1, "i_readtiff_wiol(ig %p, allow_incomplete %d, page %d)\n", ig, allow_incomplete, page)); + tiffio_context_init(&ctx, ig); tif = TIFFClientOpen("(Iolayer)", "rm", - (thandle_t) ig, + (thandle_t) &ctx, comp_read, comp_write, comp_seek, @@ -575,6 +654,10 @@ i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) { i_push_error(0, "Error opening file"); TIFFSetErrorHandler(old_handler); TIFFSetWarningHandler(old_warn_handler); +#ifdef USE_EXT_WARN_HANDLER + TIFFSetWarningHandlerExt(old_ext_warn_handler); +#endif + tiffio_context_final(&ctx); return NULL; } @@ -584,7 +667,11 @@ i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) { i_push_errorf(0, "could not switch to page %d", page); TIFFSetErrorHandler(old_handler); TIFFSetWarningHandler(old_warn_handler); +#ifdef USE_EXT_WARN_HANDLER + TIFFSetWarningHandlerExt(old_ext_warn_handler); +#endif TIFFClose(tif); + tiffio_context_final(&ctx); return NULL; } } @@ -594,7 +681,12 @@ i_readtiff_wiol(io_glue *ig, int allow_incomplete, int page) { if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n")); TIFFSetErrorHandler(old_handler); TIFFSetWarningHandler(old_warn_handler); +#ifdef USE_EXT_WARN_HANDLER + TIFFSetWarningHandlerExt(old_ext_warn_handler); +#endif TIFFClose(tif); + tiffio_context_final(&ctx); + return im; } @@ -610,14 +702,25 @@ i_readtiff_multi_wiol(io_glue *ig, int *count) { TIFF* tif; TIFFErrorHandler old_handler; TIFFErrorHandler old_warn_handler; +#ifdef USE_EXT_WARN_HANDLER + TIFFErrorHandlerExt old_ext_warn_handler; +#endif i_img **results = NULL; int result_alloc = 0; + tiffio_context_t ctx; i_clear_error(); old_handler = TIFFSetErrorHandler(error_handler); +#ifdef USE_EXT_WARN_HANDLER + old_warn_handler = TIFFSetWarningHandler(NULL); + old_ext_warn_handler = TIFFSetWarningHandlerExt(warn_handler_ex); +#else old_warn_handler = TIFFSetWarningHandler(warn_handler); if (warn_buffer) *warn_buffer = '\0'; +#endif + + tiffio_context_init(&ctx, ig); /* Add code to get the filename info from the iolayer */ /* Also add code to check for mmapped code */ @@ -626,7 +729,7 @@ i_readtiff_multi_wiol(io_glue *ig, int *count) { tif = TIFFClientOpen("(Iolayer)", "rm", - (thandle_t) ig, + (thandle_t) &ctx, comp_read, comp_write, comp_seek, @@ -640,6 +743,10 @@ i_readtiff_multi_wiol(io_glue *ig, int *count) { i_push_error(0, "Error opening file"); TIFFSetErrorHandler(old_handler); TIFFSetWarningHandler(old_warn_handler); +#ifdef USE_EXT_WARN_HANDLER + TIFFSetWarningHandlerExt(old_ext_warn_handler); +#endif + tiffio_context_final(&ctx); return NULL; } @@ -669,7 +776,12 @@ i_readtiff_multi_wiol(io_glue *ig, int *count) { TIFFSetWarningHandler(old_warn_handler); TIFFSetErrorHandler(old_handler); +#ifdef USE_EXT_WARN_HANDLER + TIFFSetWarningHandlerExt(old_ext_warn_handler); +#endif TIFFClose(tif); + tiffio_context_final(&ctx); + return results; } @@ -1332,6 +1444,7 @@ i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) { TIFF* tif; TIFFErrorHandler old_handler; int i; + tiffio_context_t ctx; old_handler = TIFFSetErrorHandler(error_handler); @@ -1339,11 +1452,11 @@ i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) { mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n", ig, imgs, count)); - /* FIXME: Enable the mmap interface */ + tiffio_context_init(&ctx, ig); tif = TIFFClientOpen("No name", "wm", - (thandle_t) ig, + (thandle_t) &ctx, comp_read, comp_write, comp_seek, @@ -1358,6 +1471,7 @@ i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) { mm_log((1, "i_writetiff_multi_wiol: Unable to open tif file for writing\n")); i_push_error(0, "Could not create TIFF object"); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } @@ -1365,6 +1479,7 @@ i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) { if (!i_writetiff_low(tif, imgs[i])) { TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } @@ -1372,12 +1487,14 @@ i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) { i_push_error(0, "Cannot write TIFF directory"); TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } } TIFFSetErrorHandler(old_handler); (void) TIFFClose(tif); + tiffio_context_final(&ctx); if (i_io_close(ig)) return 0; @@ -1403,6 +1520,7 @@ i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) { TIFF* tif; int i; TIFFErrorHandler old_handler; + tiffio_context_t ctx; old_handler = TIFFSetErrorHandler(error_handler); @@ -1410,11 +1528,11 @@ i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) { mm_log((1, "i_writetiff_multi_wiol(ig %p, imgs %p, count %d)\n", ig, imgs, count)); - /* FIXME: Enable the mmap interface */ + tiffio_context_init(&ctx, ig); tif = TIFFClientOpen("No name", "wm", - (thandle_t) ig, + (thandle_t) &ctx, comp_read, comp_write, comp_seek, @@ -1429,6 +1547,7 @@ i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) { mm_log((1, "i_writetiff_mulit_wiol: Unable to open tif file for writing\n")); i_push_error(0, "Could not create TIFF object"); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } @@ -1436,6 +1555,7 @@ i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) { if (!i_writetiff_low_faxable(tif, imgs[i], fine)) { TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } @@ -1443,12 +1563,14 @@ i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) { i_push_error(0, "Cannot write TIFF directory"); TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } } (void) TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); if (i_io_close(ig)) return 0; @@ -1470,17 +1592,18 @@ undef_int i_writetiff_wiol(i_img *img, io_glue *ig) { TIFF* tif; TIFFErrorHandler old_handler; + tiffio_context_t ctx; old_handler = TIFFSetErrorHandler(error_handler); i_clear_error(); mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", img, ig)); - /* FIXME: Enable the mmap interface */ + tiffio_context_init(&ctx, ig); tif = TIFFClientOpen("No name", "wm", - (thandle_t) ig, + (thandle_t) &ctx, comp_read, comp_write, comp_seek, @@ -1494,18 +1617,21 @@ i_writetiff_wiol(i_img *img, io_glue *ig) { if (!tif) { mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n")); i_push_error(0, "Could not create TIFF object"); + tiffio_context_final(&ctx); TIFFSetErrorHandler(old_handler); return 0; } if (!i_writetiff_low(tif, img)) { TIFFClose(tif); + tiffio_context_final(&ctx); TIFFSetErrorHandler(old_handler); return 0; } (void) TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); if (i_io_close(ig)) return 0; @@ -1534,17 +1660,18 @@ undef_int i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) { TIFF* tif; TIFFErrorHandler old_handler; + tiffio_context_t ctx; old_handler = TIFFSetErrorHandler(error_handler); i_clear_error(); mm_log((1, "i_writetiff_wiol(img %p, ig %p)\n", im, ig)); - /* FIXME: Enable the mmap interface */ + tiffio_context_init(&ctx, ig); tif = TIFFClientOpen("No name", "wm", - (thandle_t) ig, + (thandle_t) &ctx, comp_read, comp_write, comp_seek, @@ -1559,17 +1686,20 @@ i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) { mm_log((1, "i_writetiff_wiol: Unable to open tif file for writing\n")); i_push_error(0, "Could not create TIFF object"); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } if (!i_writetiff_low_faxable(tif, im, fine)) { TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); return 0; } (void) TIFFClose(tif); TIFFSetErrorHandler(old_handler); + tiffio_context_final(&ctx); if (i_io_close(ig)) return 0; @@ -1590,7 +1720,7 @@ static int save_tiff_tags(TIFF *tif, i_img *im) { } } } - + return 1; } @@ -2641,6 +2771,25 @@ myTIFFIsCODECConfigured(uint16 scheme) { return TIFFIsCODECConfigured(scheme); } +static void +tiffio_context_init(tiffio_context_t *c, io_glue *ig) { + c->magic = TIFFIO_MAGIC; + c->ig = ig; +#ifdef USE_EXT_WARN_HANDLER + c->warn_buffer = NULL; + c->warn_size = 0; +#endif +} + +static void +tiffio_context_final(tiffio_context_t *c) { + c->magic = TIFFIO_MAGIC; +#ifdef USE_EXT_WARN_HANDLER + if (c->warn_buffer) + myfree(c->warn_buffer); +#endif +} + /* =back