FLTK logo

[master] 7f969b5 - Remove static variable, fix gcc warning [-Wclobbered] (#203)

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 7f969b5 - Remove static variable, fix gcc warning [-Wclobbered] (#203) "Albrecht Schlosser" Apr 07, 2021  
 
commit 7f969b54964381f79558b924184f9c2c9afb4a57
Author:     Albrecht Schlosser <albrechts.fltk@online.de>
AuthorDate: Wed Apr 7 10:55:13 2021 +0200
Commit:     Albrecht Schlosser <albrechts.fltk@online.de>
CommitDate: Wed Apr 7 10:55:13 2021 +0200

    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.

 src/Fl_JPEG_Image.cxx | 32 ++++++++++++++++++++++----------
 src/Fl_PNG_Image.cxx  | 22 ++++++++++++++--------
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git src/Fl_JPEG_Image.cxx src/Fl_JPEG_Image.cxx
index b794d38..808461c 100644
--- src/Fl_JPEG_Image.cxx
+++ 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 src/Fl_PNG_Image.cxx src/Fl_PNG_Image.cxx
index 4c9579b..e4584b1 100644
--- src/Fl_PNG_Image.cxx
+++ 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
 }
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.