]> git.hungrycats.org Git - xscreensaver/blobdiff - hacks/ximage-loader.c
From https://www.jwz.org/xscreensaver/xscreensaver-6.09.tar.gz
[xscreensaver] / hacks / ximage-loader.c
index f122e3790773768c4cc16959cedd41b9c8ad44f2..9bd79703410975eace8e5f6996aada9a60481407 100644 (file)
@@ -1,5 +1,5 @@
 /* ximage-loader.c --- converts image files or data to XImages or Pixmap.
- * xscreensaver, Copyright (c) 1998-2018 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright © 1998-2022 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  * implied warranty.
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "screenhackI.h"
+#include "ximage-loader.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
-#ifdef HAVE_JWXYZ
-# include "jwxyz.h"
-#else
-# include <X11/Xlib.h>
-# include <X11/Xutil.h>
-#endif
-
-#include "ximage-loader.h"
-
 #if defined(HAVE_GDK_PIXBUF) || defined(HAVE_COCOA) || defined(HAVE_ANDROID)
 # undef HAVE_LIBPNG
 #endif
 
 #ifdef HAVE_COCOA
-# include "grabscreen.h"  /* for osx_load_image_file() */
+# include "grabclient.h"  /* for osx_load_image_file() */
 #endif
 
 #ifdef HAVE_GDK_PIXBUF
+
+# if (__GNUC__ >= 4)   /* Ignore useless warnings generated by GTK headers */
+#  pragma GCC diagnostic push
+#  pragma GCC diagnostic ignored "-Wlong-long"
+#  pragma GCC diagnostic ignored "-Wvariadic-macros"
+#  pragma GCC diagnostic ignored "-Wpedantic"
+# endif
+
 # include <gdk-pixbuf/gdk-pixbuf.h>
-# ifdef HAVE_GTK2
+
+# ifdef HAVE_GDK_PIXBUF_XLIB
 #  include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
-# else  /* !HAVE_GTK2 */
-#  include <gdk-pixbuf/gdk-pixbuf-xlib.h>
-# endif /* !HAVE_GTK2 */
+# endif
+
+# if (__GNUC__ >= 4)
+#  pragma GCC diagnostic pop
+# endif
+
 #endif /* HAVE_GDK_PIXBUF */
 
 #ifdef HAVE_LIBPNG
@@ -55,8 +57,6 @@ extern void Log(const char *format, ...);
 # define fprintf(S, ...) Log(__VA_ARGS__)
 #endif
 
-extern char *progname;
-
 static Bool
 bigendian (void)
 {
@@ -76,58 +76,52 @@ make_ximage (Display *dpy, Visual *visual, const char *filename,
 {
   GdkPixbuf *pb;
   static int initted = 0;
-# ifdef HAVE_GTK2
   GError *gerr = NULL;
-# endif
 
   if (!initted)
     {
-# ifdef HAVE_GTK2
-#  if !GLIB_CHECK_VERSION(2, 36 ,0)
+# if !GLIB_CHECK_VERSION(2, 36 ,0)
       g_type_init ();
-#  endif
 # endif
-      gdk_pixbuf_xlib_init (dpy, DefaultScreen (dpy));
-      xlib_rgb_init (dpy, DefaultScreenOfDisplay (dpy));
+      if (dpy)
+        {
+          /* Turns out gdk-pixbuf works even if you don't have display
+             connection, which is good news for analogtv-cli. */
+# ifdef HAVE_GDK_PIXBUF_XLIB
+          /* Aug 2022: nothing seems to go wrong if we don't do this at all?
+             gtk-2.24.33, gdk-pixbuf 2.42.8. */
+          gdk_pixbuf_xlib_init (dpy, DefaultScreen (dpy));
+          xlib_rgb_init (dpy, DefaultScreenOfDisplay (dpy));
+# endif
+        }
       initted = 1;
     }
 
   if (filename)
     {
-# ifdef HAVE_GTK2
       pb = gdk_pixbuf_new_from_file (filename, &gerr);
       if (!pb)
         {
           fprintf (stderr, "%s: %s\n", progname, gerr->message);
           return 0;
         }
-# else
-      pb = gdk_pixbuf_new_from_file (filename);
-      if (!pb)
-        {
-          fprintf (stderr, "%s: GDK unable to load %s\n", progname, filename);
-          return 0;
-        }
-# endif /* HAVE_GTK2 */
     }
   else
     {
-# ifdef HAVE_GTK2
       GInputStream *s =
         g_memory_input_stream_new_from_data (image_data, data_size, 0);
       pb = gdk_pixbuf_new_from_stream (s, 0, &gerr);
-      /* #### free s? */
+
+      g_input_stream_close (s, NULL, NULL);
+      /* #### valgrind on xflame says there's a small leak in s? */
+      g_object_unref (s);
+
       if (! pb)
         {
-          fprintf (stderr, "%s: GDK unable to parse built-in image data\n",
-                   progname);
+          /* fprintf (stderr, "%s: GDK unable to parse image data: %s\n",
+                   progname, (gerr ? gerr->message : "?")); */
           return 0;
         }
-# else /* !HAVE_GTK2 */
-      fprintf (stderr, "%s: image loading not supported with GTK 1.x\n",
-               progname);
-      return 0;
-# endif /* !HAVE_GTK2 */
     }
 
   if (!pb) abort();
@@ -194,6 +188,7 @@ make_ximage (Display *dpy, Visual *visual, const char *filename,
         row += stride;
       }
 
+    /* #### valgrind on xflame says there's a small leak in pb? */
     g_object_unref (pb);
     return image;
   }
@@ -292,6 +287,8 @@ make_ximage (Display *dpy, Visual *visual,
   png_uint_32 width, height, channels;
   int bit_depth, color_type, interlace_type;
   FILE *fp = 0;
+  /* Must be at top or it goes out of scope in the setjmp! */
+  png_read_closure closure;
 
   png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
   if (!png_ptr) return 0;
@@ -328,7 +325,6 @@ make_ximage (Display *dpy, Visual *visual,
     }
   else
     {
-      png_read_closure closure;
       closure.buf = image_data;
       closure.siz = data_size;
       closure.ptr = 0;
@@ -518,7 +514,7 @@ make_pixmap (Display *dpy, Window window,
   unsigned long srsiz=0, sgsiz=0, sbsiz=0;
 
 # ifdef HAVE_JWXYZ
-  // BlackPixel has alpha: 0xFF000000.
+  /* BlackPixel has alpha: 0xFF000000. */
   unsigned long black = BlackPixelOfScreen (DefaultScreenOfDisplay (dpy));
 #else
   unsigned long black = 0;
@@ -622,6 +618,7 @@ flip_ximage (XImage *ximage)
   char *data2, *in, *out;
   int y;
 
+  if (!ximage) return;
   data2 = malloc (ximage->bytes_per_line * ximage->height);
   if (!data2) abort();
   in = ximage->data;
@@ -657,6 +654,11 @@ file_to_pixmap (Display *dpy, Window window, const char *filename,
 }
 
 
+/* This XImage has RGBA data, which is what OpenGL code typically expects.
+   Also it is upside down: the origin is at the bottom left of the image.
+   X11 typically expects 0RGB as it has no notion of alpha, only 1-bit masks.
+   With X11 code, you should probably use the _pixmap routines instead.
+ */
 XImage *
 image_data_to_ximage (Display *dpy, Visual *visual,
                       const unsigned char *image_data,
@@ -667,10 +669,6 @@ image_data_to_ximage (Display *dpy, Visual *visual,
   return ximage;
 }
 
-/* This XImage has RGBA data, which is what OpenGL code typically expects.
-   X11 typically expects 0RGB as it has no notion of alpha, only 1-bit masks.
-   With X11 code, you should probably use the _pixmap routines instead.
- */
 XImage *
 file_to_ximage (Display *dpy, Visual *visual, const char *filename)
 {