Browse files

avoid using globals when capturing TIFF warnings

  • Loading branch information...
1 parent c9eba72 commit 60715047564977af524f8433701cbaab656c7e05 @tonycoz committed Aug 16, 2012
Showing with 171 additions and 16 deletions.
  1. +6 −0 TIFF/Changes
  2. +1 −1 TIFF/TIFF.pm
  3. +164 −15 TIFF/imtiff.c
View
6 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
=====================
View
2 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);
View
179 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,18 +1444,19 @@ 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);
i_clear_error();
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,26 +1471,30 @@ 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;
}
for (i = 0; i < count; ++i) {
if (!i_writetiff_low(tif, imgs[i])) {
TIFFClose(tif);
TIFFSetErrorHandler(old_handler);
+ tiffio_context_final(&ctx);
return 0;
}
if (!TIFFWriteDirectory(tif)) {
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,18 +1520,19 @@ 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);
i_clear_error();
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,26 +1547,30 @@ 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;
}
for (i = 0; i < count; ++i) {
if (!i_writetiff_low_faxable(tif, imgs[i], fine)) {
TIFFClose(tif);
TIFFSetErrorHandler(old_handler);
+ tiffio_context_final(&ctx);
return 0;
}
if (!TIFFWriteDirectory(tif)) {
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

0 comments on commit 6071504

Please sign in to comment.