/* 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
# define fprintf(S, ...) Log(__VA_ARGS__)
#endif
-extern char *progname;
-
static Bool
bigendian (void)
{
{
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();
row += stride;
}
+ /* #### valgrind on xflame says there's a small leak in pb? */
g_object_unref (pb);
return image;
}
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;
}
else
{
- png_read_closure closure;
closure.buf = image_data;
closure.siz = data_size;
closure.ptr = 0;
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;
char *data2, *in, *out;
int y;
+ if (!ximage) return;
data2 = malloc (ximage->bytes_per_line * ximage->height);
if (!data2) abort();
in = ximage->data;
}
+/* 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,
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)
{