1 /* ximage-loader.c --- converts image files or data to XImages or Pixmap.
2  * xscreensaver, Copyright (c) 1998-2018 Jamie Zawinski <jwz@jwz.org>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or
10  * implied warranty.
11  */
12 
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16 
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 
21 #ifdef HAVE_JWXYZ
22 # include "jwxyz.h"
23 #else
24 # include <X11/Xlib.h>
25 # include <X11/Xutil.h>
26 #endif
27 
28 #include "ximage-loader.h"
29 
30 #if defined(HAVE_GDK_PIXBUF) || defined(HAVE_COCOA) || defined(HAVE_ANDROID)
31 # undef HAVE_LIBPNG
32 #endif
33 
34 #ifdef HAVE_COCOA
35 # include "grabscreen.h"  /* for osx_load_image_file() */
36 #endif
37 
38 #ifdef HAVE_GDK_PIXBUF
39 # include <gdk-pixbuf/gdk-pixbuf.h>
40 # ifdef HAVE_GTK2
41 #  include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
42 # else  /* !HAVE_GTK2 */
43 #  include <gdk-pixbuf/gdk-pixbuf-xlib.h>
44 # endif /* !HAVE_GTK2 */
45 #endif /* HAVE_GDK_PIXBUF */
46 
47 #ifdef HAVE_LIBPNG
48 # include <png.h>
49 #endif
50 
51 #ifdef HAVE_ANDROID
52  /* So that debug output shows up in logcat... */
53 extern void Log(const char *format, ...);
54 # undef  fprintf
55 # define fprintf(S, ...) Log(__VA_ARGS__)
56 #endif
57 
58 extern char *progname;
59 
60 static Bool
bigendian(void)61 bigendian (void)
62 {
63   union { int i; char c[sizeof(int)]; } u;
64   u.i = 1;
65   return !u.c[0];
66 }
67 
68 
69 #ifdef HAVE_GDK_PIXBUF
70 
71 /* Loads the image to an XImage, RGBA -- GDK Pixbuf version.
72  */
73 static XImage *
make_ximage(Display * dpy,Visual * visual,const char * filename,const unsigned char * image_data,unsigned long data_size)74 make_ximage (Display *dpy, Visual *visual, const char *filename,
75              const unsigned char *image_data, unsigned long data_size)
76 {
77   GdkPixbuf *pb;
78   static int initted = 0;
79 # ifdef HAVE_GTK2
80   GError *gerr = NULL;
81 # endif
82 
83   if (!initted)
84     {
85 # ifdef HAVE_GTK2
86 #  if !GLIB_CHECK_VERSION(2, 36 ,0)
87       g_type_init ();
88 #  endif
89 # endif
90       if (dpy)
91         {
92           /* Turns out gdk-pixbuf works even if you don't have display
93              connection, which is good news for analogtv-cli. */
94           gdk_pixbuf_xlib_init (dpy, DefaultScreen (dpy));
95           xlib_rgb_init (dpy, DefaultScreenOfDisplay (dpy));
96         }
97       initted = 1;
98     }
99 
100   if (filename)
101     {
102 # ifdef HAVE_GTK2
103       pb = gdk_pixbuf_new_from_file (filename, &gerr);
104       if (!pb)
105         {
106           fprintf (stderr, "%s: %s\n", progname, gerr->message);
107           return 0;
108         }
109 # else
110       pb = gdk_pixbuf_new_from_file (filename);
111       if (!pb)
112         {
113           fprintf (stderr, "%s: GDK unable to load %s: %s\n",
114                    progname, filename, (gerr ? gerr->message : "?"));
115           return 0;
116         }
117 # endif /* HAVE_GTK2 */
118     }
119   else
120     {
121 # ifdef HAVE_GTK2
122       GInputStream *s =
123         g_memory_input_stream_new_from_data (image_data, data_size, 0);
124       pb = gdk_pixbuf_new_from_stream (s, 0, &gerr);
125 
126       g_input_stream_close (s, NULL, NULL);
127       /* #### valgrind on xflame says there's a small leak in s? */
128       g_object_unref (s);
129 
130       if (! pb)
131         {
132           /* fprintf (stderr, "%s: GDK unable to parse image data: %s\n",
133                    progname, (gerr ? gerr->message : "?")); */
134           return 0;
135         }
136 # else /* !HAVE_GTK2 */
137       fprintf (stderr, "%s: image loading not supported with GTK 1.x\n",
138                progname);
139       return 0;
140 # endif /* !HAVE_GTK2 */
141     }
142 
143   if (!pb) abort();
144 
145   {
146     XImage *image;
147     int w = gdk_pixbuf_get_width (pb);
148     int h = gdk_pixbuf_get_height (pb);
149     guchar *row = gdk_pixbuf_get_pixels (pb);
150     int stride = gdk_pixbuf_get_rowstride (pb);
151     int chan = gdk_pixbuf_get_n_channels (pb);
152     int x, y;
153 
154     image = XCreateImage (dpy, visual, 32, ZPixmap, 0, 0, w, h, 32, 0);
155     image->data = (char *) malloc(h * image->bytes_per_line);
156 
157     /* Set the bit order in the XImage structure to whatever the
158        local host's native bit order is.
159     */
160     image->bitmap_bit_order =
161       image->byte_order =
162       (bigendian() ? MSBFirst : LSBFirst);
163 
164     if (!image->data)
165       {
166         fprintf (stderr, "%s: out of memory (%d x %d)\n", progname, w, h);
167         return 0;
168       }
169 
170     for (y = 0; y < h; y++)
171       {
172         guchar *i = row;
173         for (x = 0; x < w; x++)
174           {
175             unsigned long rgba = 0;
176             switch (chan) {
177             case 1:
178               rgba = ((0xFF << 24) |
179                       (*i   << 16) |
180                       (*i   <<  8) |
181                        *i);
182               i++;
183               break;
184             case 3:
185               rgba = ((0xFF << 24) |
186                       (i[2] << 16) |
187                       (i[1] <<  8) |
188                       i[0]);
189               i += 3;
190               break;
191             case 4:
192               rgba = ((i[3] << 24) |
193                       (i[2] << 16) |
194                       (i[1] <<  8) |
195                       i[0]);
196               i += 4;
197               break;
198             default:
199               abort();
200               break;
201             }
202             XPutPixel (image, x, y, rgba);
203           }
204         row += stride;
205       }
206 
207     /* #### valgrind on xflame says there's a small leak in pb? */
208     g_object_unref (pb);
209     return image;
210   }
211 }
212 
213 #elif defined(HAVE_JWXYZ) /* MacOS, iOS or Android */
214 
215 /* Loads the image to an XImage, RGBA -- MacOS, iOS or Android version.
216  */
217 static XImage *
make_ximage(Display * dpy,Visual * visual,const char * filename,const unsigned char * image_data,unsigned long data_size)218 make_ximage (Display *dpy, Visual *visual, const char *filename,
219              const unsigned char *image_data, unsigned long data_size)
220 {
221   XImage *ximage = 0;
222 
223   if (filename)
224     {
225 # ifdef HAVE_COCOA  /* MacOS */
226       XRectangle geom;
227       Screen *screen = DefaultScreenOfDisplay (dpy);
228       Window window = RootWindowOfScreen (screen);
229       XWindowAttributes xgwa;
230       XGetWindowAttributes (dpy, window, &xgwa);
231       Pixmap pixmap =
232         XCreatePixmap (dpy, window, xgwa.width, xgwa.height, xgwa.depth);
233       int x, y;
234 
235       if (! osx_load_image_file (screen, window, pixmap, filename, &geom))
236         {
237           fprintf (stderr, "%s: %s failed\n", progname, filename);
238           return 0;
239         }
240 
241       ximage = XGetImage (dpy, pixmap, geom.x, geom.y,
242                           geom.width, geom.height,
243                           ~0L, ZPixmap);
244       if (!ximage) abort();
245 
246       /* Have to convert ABGR to RGBA */
247       for (y = 0; y < ximage->height; y++)
248         for (x = 0; x < ximage->width; x++)
249           {
250             unsigned long p = XGetPixel (ximage, x, y);
251             unsigned long a = (p >> 24) & 0xFF;
252             unsigned long b = (p >> 16) & 0xFF;
253             unsigned long g = (p >>  8) & 0xFF;
254             unsigned long r = (p >>  0) & 0xFF;
255             p = (r << 24) | (g << 16) | (b << 8) | (a << 0);
256             XPutPixel (ximage, x, y, p);
257           }
258 
259       XFreePixmap (dpy, pixmap);
260 
261 # else   /* !HAVE_COCOA -- iOS or Android. */
262       fprintf (stderr, "%s: image file loading not supported\n", progname);
263       return 0;
264 # endif  /* !HAVE_COCOA */
265     }
266   else
267     {
268       ximage = jwxyz_png_to_ximage (dpy, visual, image_data, data_size);
269     }
270 
271   return ximage;
272 }
273 
274 #elif defined(HAVE_LIBPNG)
275 
276 typedef struct {
277   const unsigned char *buf;
278   png_size_t siz, ptr;
279 } png_read_closure;
280 
281 static void
png_reader_fn(png_structp png_ptr,png_bytep buf,png_size_t siz)282 png_reader_fn (png_structp png_ptr, png_bytep buf, png_size_t siz)
283 {
284   png_read_closure *r = png_get_io_ptr (png_ptr);
285   if (siz > r->siz - r->ptr)
286     png_error (png_ptr, "PNG internal read error");
287   memcpy (buf, r->buf + r->ptr, siz);
288   r->ptr += siz;
289 }
290 
291 
292 /* Loads the image to an XImage, RGBA -- libpng version.
293  */
294 static XImage *
make_ximage(Display * dpy,Visual * visual,const char * filename,const unsigned char * image_data,unsigned long data_size)295 make_ximage (Display *dpy, Visual *visual,
296              const char *filename, const unsigned char *image_data,
297              unsigned long data_size)
298 {
299   XImage *image = 0;
300   png_structp png_ptr;
301   png_infop info_ptr;
302   png_infop end_info;
303   png_uint_32 width, height, channels;
304   int bit_depth, color_type, interlace_type;
305   FILE *fp = 0;
306 
307   png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
308   if (!png_ptr) return 0;
309 
310   info_ptr = png_create_info_struct (png_ptr);
311   if (!info_ptr)
312     {
313       png_destroy_read_struct (&png_ptr, 0, 0);
314       return 0;
315     }
316 
317   end_info = png_create_info_struct (png_ptr);
318   if (!end_info)
319     {
320       png_destroy_read_struct (&png_ptr, &info_ptr, 0);
321       return 0;
322     }
323 
324   if (setjmp (png_jmpbuf(png_ptr)))
325     {
326       png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
327       return 0;
328     }
329 
330   if (filename)
331     {
332       fp = fopen (filename, "r");
333       if (! fp)
334         {
335           fprintf (stderr, "%s: unable to read %s\n", progname, filename);
336           return 0;
337         }
338       png_init_io (png_ptr, fp);
339     }
340   else
341     {
342       png_read_closure closure;
343       closure.buf = image_data;
344       closure.siz = data_size;
345       closure.ptr = 0;
346       png_set_read_fn (png_ptr, (void *) &closure, png_reader_fn);
347     }
348 
349   png_read_info (png_ptr, info_ptr);
350   png_get_IHDR (png_ptr, info_ptr,
351                 &width, &height, &bit_depth, &color_type,
352                 &interlace_type, 0, 0);
353 
354   png_set_strip_16 (png_ptr);  /* Truncate 16 bits per component to 8 */
355   png_set_packing (png_ptr);   /* Unpack to 1 pixel per byte */
356 
357 # if 0
358   if (color_type == PNG_COLOR_TYPE_PALETTE)  /* Colormap to RGB */
359     png_set_palette_rgb (png_ptr);
360 
361   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)  /* Mono to 8bit */
362     png_set_gray_1_2_4_to_8 (png_ptr);
363 # endif
364 
365   if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) /* Fix weird alpha */
366     png_set_tRNS_to_alpha (png_ptr);
367 
368   /* At least 8 bits deep */
369   if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
370     png_set_expand (png_ptr);
371 
372    if (bit_depth == 8 &&          /* Convert RGB to RGBA */
373            (color_type == PNG_COLOR_TYPE_RGB ||
374             color_type == PNG_COLOR_TYPE_PALETTE))
375      png_set_filler (png_ptr, 0xFF, PNG_FILLER_AFTER);
376 
377   /* Grayscale to color */
378   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
379     png_set_expand (png_ptr);
380 
381 
382   /* Convert graysale to color */
383   if (color_type == PNG_COLOR_TYPE_GRAY ||
384       color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
385     png_set_gray_to_rgb (png_ptr);
386 
387 # if 0
388   {
389     png_color_16 *bg;
390     if (png_get_bKGD (png_ptr, info_ptr, &bg))
391       png_set_background (png_ptr, bg, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
392   }
393 # endif
394 
395   /* Commit */
396   png_read_update_info (png_ptr, info_ptr);
397 
398   channels = png_get_channels (png_ptr, info_ptr);
399 
400   {
401     png_bytep *rows = png_malloc (png_ptr, height * sizeof(*rows));
402     int x, y;
403     for (y = 0; y < height; y++)
404       rows[y] = png_malloc (png_ptr, png_get_rowbytes (png_ptr, info_ptr));
405     png_read_image (png_ptr, rows);
406     png_read_end (png_ptr, info_ptr);
407 
408     image = XCreateImage (dpy, visual, 32, ZPixmap, 0, 0,
409                           width, height, 32, 0);
410     image->data = (char *) malloc (height * image->bytes_per_line);
411 
412     /* Set the bit order in the XImage structure to whatever the
413        local host's native bit order is.
414      */
415     image->bitmap_bit_order =
416       image->byte_order =
417         (bigendian() ? MSBFirst : LSBFirst);
418 
419     if (!image->data)
420       {
421         fprintf (stderr, "%s: out of memory (%lu x %lu)\n",
422                  progname, (unsigned long)width, (unsigned long)height);
423         return 0;
424       }
425 
426     for (y = 0; y < height; y++)
427       {
428         png_bytep i = rows[y];
429         for (x = 0; x < width; x++)
430           {
431             unsigned long rgba;
432             switch (channels) {
433             case 4:
434               rgba = ((i[3] << 24) |
435                       (i[2] << 16) |
436                       (i[1] << 8)  |
437                        i[0]);
438               break;
439             case 3:
440               rgba = ((0xFF << 24) |
441                       (i[2] << 16) |
442                       (i[1] << 8)  |
443                        i[0]);
444               break;
445             case 2:
446               rgba = ((i[1] << 24) |
447                       (i[0] << 16) |
448                       (i[0] << 8)  |
449                        i[0]);
450               break;
451             case 1:
452               rgba = ((0xFF << 24) |
453                       (i[0] << 16) |
454                       (i[0] << 8)  |
455                        i[0]);
456               break;
457             default:
458               abort();
459             }
460             XPutPixel (image, x, y, rgba);
461             i += channels;
462           }
463         png_free (png_ptr, rows[y]);
464       }
465 
466     png_free (png_ptr, rows);
467   }
468 
469   png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
470   if (fp) fclose (fp);
471 
472   return image;
473 }
474 
475 
476 #else /* No image loaders! */
477 
478 static XImage *
make_ximage(Display * dpy,Visual * visual,const char * filename,const unsigned char * image_data,unsigned long data_size)479 make_ximage (Display *dpy, Visual *visual,
480              const char *filename, const unsigned char *image_data,
481              unsigned long data_size)
482 {
483   fprintf (stderr, "%s: no image loading support!\n", progname);
484   return 0;
485 }
486 
487 #endif /* no loaders */
488 
489 
490 /* Given a bitmask, returns the position and width of the field.
491  */
492 static void
decode_mask(unsigned long mask,unsigned long * pos_ret,unsigned long * size_ret)493 decode_mask (unsigned long mask, unsigned long *pos_ret,
494              unsigned long *size_ret)
495 {
496   int i;
497   for (i = 0; i < 32; i++)
498     if (mask & (1L << i))
499       {
500         int j = 0;
501         *pos_ret = i;
502         for (; i < 32; i++, j++)
503           if (! (mask & (1L << i)))
504             break;
505         *size_ret = j;
506         return;
507       }
508 }
509 
510 
511 /* Loads the image to a Pixmap and optional 1-bit mask.
512  */
513 static Pixmap
make_pixmap(Display * dpy,Window window,const char * filename,const unsigned char * image_data,unsigned long data_size,int * width_ret,int * height_ret,Pixmap * mask_ret)514 make_pixmap (Display *dpy, Window window,
515              const char *filename,
516              const unsigned char *image_data, unsigned long data_size,
517              int *width_ret, int *height_ret, Pixmap *mask_ret)
518 {
519   XWindowAttributes xgwa;
520   XImage *in, *out, *mask = 0;
521   Pixmap pixmap;
522   XGCValues gcv;
523   GC gc;
524   int x, y;
525 
526   unsigned long crpos=0, cgpos=0, cbpos=0, capos=0; /* bitfield positions */
527   unsigned long srpos=0, sgpos=0, sbpos=0;
528   unsigned long srmsk=0, sgmsk=0, sbmsk=0;
529   unsigned long srsiz=0, sgsiz=0, sbsiz=0;
530 
531 # ifdef HAVE_JWXYZ
532   // BlackPixel has alpha: 0xFF000000.
533   unsigned long black = BlackPixelOfScreen (DefaultScreenOfDisplay (dpy));
534 #else
535   unsigned long black = 0;
536 # endif
537 
538   XGetWindowAttributes (dpy, window, &xgwa);
539 
540   in = make_ximage (dpy, xgwa.visual, filename, image_data, data_size);
541   if (!in) return 0;
542 
543   /* Create a new image in the depth and bit-order of the server. */
544   out = XCreateImage (dpy, xgwa.visual, xgwa.depth, ZPixmap, 0, 0,
545                       in->width, in->height, 8, 0);
546 
547   out->bitmap_bit_order = in->bitmap_bit_order;
548   out->byte_order = in->byte_order;
549 
550   out->bitmap_bit_order = BitmapBitOrder (dpy);
551   out->byte_order = ImageByteOrder (dpy);
552 
553   out->data = (char *) malloc (out->height * out->bytes_per_line);
554   if (!out->data) abort();
555 
556   if (mask_ret)
557     {
558       mask = XCreateImage (dpy, xgwa.visual, 1, XYPixmap, 0, 0,
559                            in->width, in->height, 8, 0);
560       mask->byte_order = in->byte_order;
561       mask->data = (char *) malloc (mask->height * mask->bytes_per_line);
562     }
563 
564   /* Find the server's color masks.
565    */
566   srmsk = out->red_mask;
567   sgmsk = out->green_mask;
568   sbmsk = out->blue_mask;
569 
570   if (!(srmsk && sgmsk && sbmsk)) abort();  /* No server color masks? */
571 
572   decode_mask (srmsk, &srpos, &srsiz);
573   decode_mask (sgmsk, &sgpos, &sgsiz);
574   decode_mask (sbmsk, &sbpos, &sbsiz);
575 
576   /* 'in' is RGBA in client endianness.  Convert to what the server wants. */
577   if (bigendian())
578     crpos = 24, cgpos = 16, cbpos =  8, capos =  0;
579   else
580     crpos =  0, cgpos =  8, cbpos = 16, capos = 24;
581 
582   for (y = 0; y < in->height; y++)
583     for (x = 0; x < in->width; x++)
584       {
585         unsigned long p = XGetPixel (in, x, y);
586         unsigned char a = (p >> capos) & 0xFF;
587         unsigned char b = (p >> cbpos) & 0xFF;
588         unsigned char g = (p >> cgpos) & 0xFF;
589         unsigned char r = (p >> crpos) & 0xFF;
590         XPutPixel (out, x, y, ((r << srpos) |
591                                (g << sgpos) |
592                                (b << sbpos) |
593                                black));
594         if (mask)
595           XPutPixel (mask, x, y, (a ? 1 : 0));
596       }
597 
598   XDestroyImage (in);
599   in = 0;
600 
601   pixmap = XCreatePixmap (dpy, window, out->width, out->height, xgwa.depth);
602   gc = XCreateGC (dpy, pixmap, 0, &gcv);
603   XPutImage (dpy, pixmap, gc, out, 0, 0, 0, 0, out->width, out->height);
604   XFreeGC (dpy, gc);
605 
606   if (mask)
607     {
608       Pixmap p2 = XCreatePixmap (dpy, window, mask->width, mask->height, 1);
609       gcv.foreground = 1;
610       gcv.background = 0;
611       gc = XCreateGC (dpy, p2, GCForeground|GCBackground, &gcv);
612       XPutImage (dpy, p2, gc, mask, 0, 0, 0, 0, mask->width, mask->height);
613       XFreeGC (dpy, gc);
614       XDestroyImage (mask);
615       mask = 0;
616       *mask_ret = p2;
617     }
618 
619   if (width_ret)  *width_ret  = out->width;
620   if (height_ret) *height_ret = out->height;
621 
622   XDestroyImage (out);
623 
624   return pixmap;
625 }
626 
627 
628 /* Textures are upside down, so invert XImages before returning them.
629  */
630 static void
flip_ximage(XImage * ximage)631 flip_ximage (XImage *ximage)
632 {
633   char *data2, *in, *out;
634   int y;
635 
636   if (!ximage) return;
637   data2 = malloc (ximage->bytes_per_line * ximage->height);
638   if (!data2) abort();
639   in = ximage->data;
640   out = data2 + ximage->bytes_per_line * (ximage->height - 1);
641   for (y = 0; y < ximage->height; y++)
642     {
643       memcpy (out, in, ximage->bytes_per_line);
644       in  += ximage->bytes_per_line;
645       out -= ximage->bytes_per_line;
646     }
647   free (ximage->data);
648   ximage->data = data2;
649 }
650 
651 
652 Pixmap
image_data_to_pixmap(Display * dpy,Window window,const unsigned char * image_data,unsigned long data_size,int * width_ret,int * height_ret,Pixmap * mask_ret)653 image_data_to_pixmap (Display *dpy, Window window,
654                       const unsigned char *image_data, unsigned long data_size,
655                       int *width_ret, int *height_ret,
656                       Pixmap *mask_ret)
657 {
658   return make_pixmap (dpy, window, 0, image_data, data_size,
659                       width_ret, height_ret, mask_ret);
660 }
661 
662 Pixmap
file_to_pixmap(Display * dpy,Window window,const char * filename,int * width_ret,int * height_ret,Pixmap * mask_ret)663 file_to_pixmap (Display *dpy, Window window, const char *filename,
664                 int *width_ret, int *height_ret,
665                 Pixmap *mask_ret)
666 {
667   return make_pixmap (dpy, window, filename, 0, 0,
668                       width_ret, height_ret, mask_ret);
669 }
670 
671 
672 /* This XImage has RGBA data, which is what OpenGL code typically expects.
673    Also it is upside down: the origin is at the bottom left of the image.
674    X11 typically expects 0RGB as it has no notion of alpha, only 1-bit masks.
675    With X11 code, you should probably use the _pixmap routines instead.
676  */
677 XImage *
image_data_to_ximage(Display * dpy,Visual * visual,const unsigned char * image_data,unsigned long data_size)678 image_data_to_ximage (Display *dpy, Visual *visual,
679                       const unsigned char *image_data,
680                       unsigned long data_size)
681 {
682   XImage *ximage = make_ximage (dpy, visual, 0, image_data, data_size);
683   flip_ximage (ximage);
684   return ximage;
685 }
686 
687 XImage *
file_to_ximage(Display * dpy,Visual * visual,const char * filename)688 file_to_ximage (Display *dpy, Visual *visual, const char *filename)
689 {
690   XImage *ximage = make_ximage (dpy, visual, filename, 0, 0);
691   flip_ximage (ximage);
692   return ximage;
693 }
694