#define myGifError(gif) ((gif)->Error)
#define MakeMapObject GifMakeMapObject
#define FreeMapObject GifFreeMapObject
-
+#define gif_mutex_lock(mutex)
+#define gif_mutex_unlock(mutex)
#else
#define PRE_SET_VERSION
static GifFileType *
return result;
}
#define myGifError(gif) GifLastError()
+#define gif_mutex_lock(mutex) i_mutex_lock(mutex)
+#define gif_mutex_unlock(mutex) i_mutex_unlock(mutex)
#endif
InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
+#if !defined(GIFLIB_MAJOR) || GIFLIB_MAJOR < 5
+static i_mutex_t mutex;
+#endif
+
+void
+i_init_gif(void) {
+#if !defined(GIFLIB_MAJOR) || GIFLIB_MAJOR < 5
+ mutex = i_mutex_new();
+#endif
+}
+
static
void
i_colortable_copy(int **colour_table, int *colours, ColorMapObject *colourmap) {
i_readgif_multi_wiol(io_glue *ig, int *count) {
GifFileType *GifFile;
int gif_error;
+ i_img **result;
+
+ gif_mutex_lock(mutex);
i_clear_error();
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_readgif_multi_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return NULL;
}
- return i_readgif_multi_low(GifFile, count, -1);
+ result = i_readgif_multi_low(GifFile, count, -1);
+
+ gif_mutex_unlock(mutex);
+
+ return result;
}
static int
i_readgif_wiol(io_glue *ig, int **color_table, int *colors) {
GifFileType *GifFile;
int gif_error;
+ i_img *result;
+
+ gif_mutex_lock(mutex);
i_clear_error();
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_readgif_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return NULL;
}
- return i_readgif_low(GifFile, color_table, colors);
+ result = i_readgif_low(GifFile, color_table, colors);
+
+ gif_mutex_unlock(mutex);
+
+ return result;
}
/*
i_readgif_single_wiol(io_glue *ig, int page) {
GifFileType *GifFile;
int gif_error;
+ i_img *result;
i_clear_error();
if (page < 0) {
return NULL;
}
+ gif_mutex_lock(mutex);
if ((GifFile = myDGifOpen((void *)ig, io_glue_read_cb, &gif_error )) == NULL) {
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_readgif_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return NULL;
}
- return i_readgif_single_low(GifFile, page);
+ result = i_readgif_single_low(GifFile, page);
+
+ gif_mutex_unlock(mutex);
+
+ return result;
}
/*
int gif_error;
int result;
+ gif_mutex_lock(mutex);
+
i_clear_error();
#ifdef PRE_SET_VERSION
gif_push_error(gif_error);
i_push_error(0, "Cannot create giflib callback object");
mm_log((1,"i_writegif_wiol: Unable to open callback datasource.\n"));
+ gif_mutex_unlock(mutex);
return 0;
}
result = i_writegif_low(quant, GifFile, imgs, count);
+ gif_mutex_unlock(mutex);
+
if (i_io_close(ig))
return 0;
Arnar M. Hrafnkelsson, addi@umich.edu
+Tony Cook <tonyc@cpan.org>
+
=head1 SEE ALSO
perl(1), Imager(3)
--- /dev/null
+#!perl -w
+use strict;
+use threads;
+use Imager;
+
+++$|;
+Imager->preload;
+
+# as a TIFF this file is large, build it from largeish.jpg if it
+# doesn't exist
+unless (-f "bench/largish.gif") {
+ my $im = Imager->new(file => "bench/largish.jpg")
+ or die "Cannot read bench/largish.jpg:", Imager->errstr;
+ $im->write(file => "bench/largish.gif")
+ or die "Cannot write bench/largish.gif:", $im->errstr;
+}
+
+my @tests =
+ (
+ [ "bench/largish.gif", "" ],
+ [ "GIF/testimg/scale.gif", "" ],
+ [ "GIF/testimg/nocmap.gif", "Image does not have a local or a global color map" ],
+ );
+
+my @threads;
+my $name = "A";
+for my $test (@tests) {
+ push @threads,
+ threads->create
+ (
+ sub {
+ my ($file, $result, $name) = @_;
+ for (1 .. 100000) {
+ print $name;
+ my $im = Imager->new(file => $file);
+ if ($result) {
+ $im and die "Expected error from $file, got image";
+ Imager->errstr eq $result
+ or die "Expected error '$result', got '",Imager->errstr, "'"
+ }
+ else {
+ $im or die "Expected image got error '", Imager->errstr, "'";
+ }
+ }
+ return;
+ },
+ @$test,
+ $name
+ );
+ ++$name;
+}
+
+for my $t (@threads) {
+ $t->join();
+}