diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2021-04-07 10:55:13 +0200 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2021-04-07 10:55:13 +0200 |
| commit | 7f969b54964381f79558b924184f9c2c9afb4a57 (patch) | |
| tree | 010007779d67d4cd55c610e992bc523346c20261 | |
| parent | 4e086a1cdfea0f26bc663f829a9a70fa748f4260 (diff) | |
Remove static variable, fix gcc warning [-Wclobbered] (#203)
PR #203 "Multithread fix for PNG loading" includes a suggested fix
that moves the variable fp to the Fl_PNG_Image structure.
This commit fixes the threading issue by allocating the variable fp
with new, avoiding the [-Wclobbered] warning w/o using a static var.
The same issue is now also fixed in Fl_JPEG_Image.
| -rw-r--r-- | src/Fl_JPEG_Image.cxx | 32 | ||||
| -rw-r--r-- | src/Fl_PNG_Image.cxx | 22 |
2 files changed, 36 insertions, 18 deletions
diff --git a/src/Fl_JPEG_Image.cxx b/src/Fl_JPEG_Image.cxx index b794d382a..808461c3e 100644 --- a/src/Fl_JPEG_Image.cxx +++ b/src/Fl_JPEG_Image.cxx @@ -4,6 +4,8 @@ // Copyright 1997-2011 by Easy Software Products. // Image support by Matthias Melcher, Copyright 2000-2009. // +// Copyright 2013-2021 by Bill Spitzak and others. +// // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this // file is missing or damaged, see the license at: @@ -212,15 +214,21 @@ static void jpeg_mem_src(j_decompress_ptr cinfo, const unsigned char *data) void Fl_JPEG_Image::load_jpg_(const char *filename, const char *sharename, const unsigned char *data) { #ifdef HAVE_LIBJPEG - FILE *fp = 0L; // File pointer jpeg_decompress_struct dinfo; // Decompressor info fl_jpeg_error_mgr jerr; // Error handler info JSAMPROW row; // Sample row pointer // the following variables are pointers allocating some private space that // is not reset by 'setjmp()' - char* max_finish_decompress_err; // count errors and give up afer a while - char* max_destroy_decompress_err; // to avoid recusion and deadlock + char* max_finish_decompress_err; // count errors and give up after a while + char* max_destroy_decompress_err; // to avoid recursion and deadlock + + // Note: The file pointer fp must not be an automatic (stack) variable + // to avoid potential clobbering by setjmp/longjmp (gcc: [-Wclobbered]). + // Hence the actual 'fp' is allocated with operator new. + + FILE** fp = new FILE*; // always allocate file pointer + *fp = NULL; // Clear data... alloc_array = 0; @@ -228,13 +236,15 @@ void Fl_JPEG_Image::load_jpg_(const char *filename, const char *sharename, const // Open the image file if we read from the file system if (filename) { - if ((fp = fl_fopen(filename, "rb")) == NULL) { + if ((*fp = fl_fopen(filename, "rb")) == NULL) { ld(ERR_FILE_ACCESS); + delete fp; return; } } else { if (data==0L) { ld(ERR_FILE_ACCESS); + delete fp; return; } } @@ -264,8 +274,8 @@ void Fl_JPEG_Image::load_jpg_(const char *filename, const char *sharename, const if ( (*max_destroy_decompress_err)-- > 0) jpeg_destroy_decompress(&dinfo); - if (fp) - fclose(fp); + if (*fp) + fclose(*fp); w(0); h(0); @@ -281,12 +291,13 @@ void Fl_JPEG_Image::load_jpg_(const char *filename, const char *sharename, const free(max_finish_decompress_err); ld(ERR_FORMAT); + delete fp; return; } jpeg_create_decompress(&dinfo); - if (fp) { - jpeg_stdio_src(&dinfo, fp); + if (*fp) { + jpeg_stdio_src(&dinfo, *fp); } else { jpeg_mem_src(&dinfo, data); } @@ -322,12 +333,13 @@ void Fl_JPEG_Image::load_jpg_(const char *filename, const char *sharename, const free(max_destroy_decompress_err); free(max_finish_decompress_err); - if (fp) - fclose(fp); + if (*fp) + fclose(*fp); if (sharename && w() && h()) { Fl_Shared_Image *si = new Fl_Shared_Image(sharename, this); si->add(); } + delete fp; #endif // HAVE_LIBJPEG } diff --git a/src/Fl_PNG_Image.cxx b/src/Fl_PNG_Image.cxx index 4c9579bb8..e4584b188 100644 --- a/src/Fl_PNG_Image.cxx +++ b/src/Fl_PNG_Image.cxx @@ -4,7 +4,7 @@ // Copyright 1997-2012 by Easy Software Products. // Image support by Matthias Melcher, Copyright 2000-2009. // -// Copyright 2013-2017 by Bill Spitzak and others. +// Copyright 2013-2021 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -123,12 +123,15 @@ void Fl_PNG_Image::load_png_(const char *name_png, const unsigned char *buffer_p // Note: The file pointer fp must not be an automatic (stack) variable // to avoid potential clobbering by setjmp/longjmp (gcc: [-Wclobbered]). - static FILE *fp; // intentionally initialized separately below - fp = NULL; // always initialize file pointer + // Hence the actual 'fp' is allocated with operator new. + + FILE** fp = new FILE*; // always allocate file pointer + *fp = NULL; if (!from_memory) { - if ((fp = fl_fopen(name_png, "rb")) == NULL) { + if ((*fp = fl_fopen(name_png, "rb")) == NULL) { ld(ERR_FILE_ACCESS); + delete fp; return; } } @@ -139,17 +142,19 @@ void Fl_PNG_Image::load_png_(const char *name_png, const unsigned char *buffer_p if (pp) info = png_create_info_struct(pp); if (!pp || !info) { if (pp) png_destroy_read_struct(&pp, NULL, NULL); - if (!from_memory) fclose(fp); + if (!from_memory) fclose(*fp); Fl::warning("Cannot allocate memory to read PNG file or data \"%s\".\n", display_name); w(0); h(0); d(0); ld(ERR_FORMAT); + delete fp; return; } if (setjmp(png_jmpbuf(pp))) { png_destroy_read_struct(&pp, &info, NULL); - if (!from_memory) fclose(fp); + if (!from_memory) fclose(*fp); Fl::warning("PNG file or data \"%s\" is too large or contains errors!\n", display_name); w(0); h(0); d(0); ld(ERR_FORMAT); + delete fp; return; } @@ -160,7 +165,7 @@ void Fl_PNG_Image::load_png_(const char *name_png, const unsigned char *buffer_p // Initialize the function pointer to the PNG read "engine"... png_set_read_fn (pp, (png_voidp) &png_mem_data, png_read_data_from_mem); } else { - png_init_io(pp, fp); // Initialize the PNG file read "engine"... + png_init_io(pp, *fp); // Initialize the PNG file read "engine"... } // Get the image dimensions and convert to grayscale or RGB... @@ -225,7 +230,8 @@ void Fl_PNG_Image::load_png_(const char *name_png, const unsigned char *buffer_p si->add(); } } else { - fclose(fp); + fclose(*fp); } + delete fp; #endif // HAVE_LIBPNG && HAVE_LIBZ } |
